From 46627a737e281b0432b1297abaa402fafaca51aa Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 14 Oct 2022 16:00:17 +0200 Subject: [PATCH 001/796] add an AdditionalTaintStep class for Ruby --- .../ql/lib/codeql/ruby/dataflow/FlowSteps.qll | 28 +++++++++++++++++++ .../internal/TaintTrackingPrivate.qll | 4 +++ 2 files changed, 32 insertions(+) create mode 100644 ruby/ql/lib/codeql/ruby/dataflow/FlowSteps.qll diff --git a/ruby/ql/lib/codeql/ruby/dataflow/FlowSteps.qll b/ruby/ql/lib/codeql/ruby/dataflow/FlowSteps.qll new file mode 100644 index 00000000000..414d241c9fa --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/dataflow/FlowSteps.qll @@ -0,0 +1,28 @@ +/** + * Provides classes representing various flow steps for taint tracking. + */ + +private import codeql.ruby.DataFlow +private import internal.DataFlowPrivate as DFPrivate + +private class Unit = DFPrivate::Unit; + +/** + * A module importing the frameworks that implement additional flow steps, + * ensuring that they are visible to the taint tracking library. + */ +private module Frameworks { } + +/** + * A unit class for adding additional taint steps. + * + * Extend this class to add additional taint steps that should apply to all + * taint configurations. + */ +class AdditionalTaintStep extends Unit { + /** + * Holds if the step from `node1` to `node2` should be considered a taint + * step for all configurations. + */ + abstract predicate step(DataFlow::Node node1, DataFlow::Node node2); +} diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll index 92eef6e3cfb..bf9fd46ffa0 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll @@ -62,6 +62,8 @@ private CfgNodes::ExprNodes::VariableWriteAccessCfgNode variablesInPattern( cached private module Cached { + private import codeql.ruby.dataflow.FlowSteps as FlowSteps + cached predicate forceCachingInSameStage() { any() } @@ -99,6 +101,8 @@ private module Cached { or FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, false) or + any(FlowSteps::AdditionalTaintStep s).step(nodeFrom, nodeTo) + or // Although flow through collections is modeled precisely using stores/reads, we still // allow flow out of a _tainted_ collection. This is needed in order to support taint- // tracking configurations where the source is a collection. From dbf2673a916b66839ed4711d0be0dce9b69ebe4c Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 14 Oct 2022 16:06:10 +0200 Subject: [PATCH 002/796] add returnsFormatted predicate to PrintfStyleCall (similar to JS) --- .../codeql/ruby/security/TaintedFormatStringSpecific.qll | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/security/TaintedFormatStringSpecific.qll b/ruby/ql/lib/codeql/ruby/security/TaintedFormatStringSpecific.qll index 2f5f6069594..e2c4549133a 100644 --- a/ruby/ql/lib/codeql/ruby/security/TaintedFormatStringSpecific.qll +++ b/ruby/ql/lib/codeql/ruby/security/TaintedFormatStringSpecific.qll @@ -25,6 +25,9 @@ abstract class PrintfStyleCall extends DataFlow::CallNode { * Gets then `n`th formatted argument of this call. */ DataFlow::Node getFormatArgument(int n) { n >= 0 and result = this.getArgument(n + 1) } + + /** Holds if this call returns the formatted string. */ + predicate returnsFormatted() { any() } } /** @@ -50,6 +53,8 @@ class KernelPrintfCall extends PrintfStyleCall { then result = this.getArgument(0) else result = this.getArgument([0, 1]) } + + override predicate returnsFormatted() { none() } } /** @@ -62,6 +67,8 @@ class KernelSprintfCall extends PrintfStyleCall { this.asExpr().getExpr() instanceof UnknownMethodCall and this.getMethodName() = "sprintf" } + + override predicate returnsFormatted() { any() } } /** @@ -71,4 +78,6 @@ class IOPrintfCall extends PrintfStyleCall { IOPrintfCall() { this.getReceiver() instanceof IO::IOInstance and this.getMethodName() = "printf" } + + override predicate returnsFormatted() { none() } } From a2b924bbdf90926dc47e44b4acb081082bc92155 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 17 Oct 2022 12:28:29 +0200 Subject: [PATCH 003/796] move model of printf style calls to StringFormatters.qll --- ruby/ql/lib/codeql/ruby/Frameworks.qll | 1 + .../ruby/frameworks/StringFormatters.qll | 70 +++++++++++++++++ .../security/TaintedFormatStringSpecific.qll | 78 +------------------ 3 files changed, 73 insertions(+), 76 deletions(-) create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll diff --git a/ruby/ql/lib/codeql/ruby/Frameworks.qll b/ruby/ql/lib/codeql/ruby/Frameworks.qll index f89040b1d5d..9896cf23c39 100644 --- a/ruby/ql/lib/codeql/ruby/Frameworks.qll +++ b/ruby/ql/lib/codeql/ruby/Frameworks.qll @@ -23,3 +23,4 @@ private import codeql.ruby.frameworks.HttpClients private import codeql.ruby.frameworks.XmlParsing private import codeql.ruby.frameworks.ActionDispatch private import codeql.ruby.frameworks.PosixSpawn +private import codeql.ruby.frameworks.StringFormatters diff --git a/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll b/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll new file mode 100644 index 00000000000..501411c2558 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll @@ -0,0 +1,70 @@ +/** + * Provides classes for modeling string formatting libraries. + */ + +private import codeql.ruby.ast.Call +private import codeql.ruby.DataFlow +private import codeql.ruby.ApiGraphs +private import codeql.ruby.frameworks.core.IO + +/** + * A call to `printf` or `sprintf`. + */ +abstract class PrintfStyleCall extends DataFlow::CallNode { + // We assume that most printf-like calls have the signature f(format_string, args...) + /** + * Gets the format string of this call. + */ + DataFlow::Node getFormatString() { result = this.getArgument(0) } + + /** + * Gets then `n`th formatted argument of this call. + */ + DataFlow::Node getFormatArgument(int n) { n >= 0 and result = this.getArgument(n + 1) } +} + +/** + * A call to `Kernel.printf`. + */ +class KernelPrintfCall extends PrintfStyleCall { + KernelPrintfCall() { + this = API::getTopLevelMember("Kernel").getAMethodCall("printf") + or + this.asExpr().getExpr() instanceof UnknownMethodCall and + this.getMethodName() = "printf" + } + + // Kernel#printf supports two signatures: + // printf(io, string, ...) + // printf(string, ...) + override DataFlow::Node getFormatString() { + // Because `printf` has two different signatures, we can't be sure which + // argument is the format string, so we use a heuristic: + // If the first argument has a string value, then we assume it is the format string. + // Otherwise we treat both the first and second args as the format string. + if this.getArgument(0).getExprNode().getConstantValue().isString(_) + then result = this.getArgument(0) + else result = this.getArgument([0, 1]) + } +} + +/** + * A call to `Kernel.sprintf`. + */ +class KernelSprintfCall extends PrintfStyleCall { + KernelSprintfCall() { + this = API::getTopLevelMember("Kernel").getAMethodCall("sprintf") + or + this.asExpr().getExpr() instanceof UnknownMethodCall and + this.getMethodName() = "sprintf" + } +} + +/** + * A call to `IO#printf`. + */ +class IOPrintfCall extends PrintfStyleCall { + IOPrintfCall() { + this.getReceiver() instanceof IO::IOInstance and this.getMethodName() = "printf" + } +} diff --git a/ruby/ql/lib/codeql/ruby/security/TaintedFormatStringSpecific.qll b/ruby/ql/lib/codeql/ruby/security/TaintedFormatStringSpecific.qll index e2c4549133a..43f9dff4a25 100644 --- a/ruby/ql/lib/codeql/ruby/security/TaintedFormatStringSpecific.qll +++ b/ruby/ql/lib/codeql/ruby/security/TaintedFormatStringSpecific.qll @@ -2,82 +2,8 @@ * Provides Ruby-specific imports and classes needed for `TaintedFormatStringQuery` and `TaintedFormatStringCustomizations`. */ -import codeql.ruby.AST +import codeql.ruby.frameworks.StringFormatters import codeql.ruby.DataFlow import codeql.ruby.dataflow.RemoteFlowSources -import codeql.ruby.ApiGraphs import codeql.ruby.TaintTracking -private import codeql.ruby.frameworks.Files -private import codeql.ruby.frameworks.core.IO -private import codeql.ruby.controlflow.CfgNodes - -/** - * A call to `printf` or `sprintf`. - */ -abstract class PrintfStyleCall extends DataFlow::CallNode { - // We assume that most printf-like calls have the signature f(format_string, args...) - /** - * Gets the format string of this call. - */ - DataFlow::Node getFormatString() { result = this.getArgument(0) } - - /** - * Gets then `n`th formatted argument of this call. - */ - DataFlow::Node getFormatArgument(int n) { n >= 0 and result = this.getArgument(n + 1) } - - /** Holds if this call returns the formatted string. */ - predicate returnsFormatted() { any() } -} - -/** - * A call to `Kernel.printf`. - */ -class KernelPrintfCall extends PrintfStyleCall { - KernelPrintfCall() { - this = API::getTopLevelMember("Kernel").getAMethodCall("printf") - or - this.asExpr().getExpr() instanceof UnknownMethodCall and - this.getMethodName() = "printf" - } - - // Kernel#printf supports two signatures: - // printf(io, string, ...) - // printf(string, ...) - override DataFlow::Node getFormatString() { - // Because `printf` has two different signatures, we can't be sure which - // argument is the format string, so we use a heuristic: - // If the first argument has a string value, then we assume it is the format string. - // Otherwise we treat both the first and second args as the format string. - if this.getArgument(0).getExprNode().getConstantValue().isString(_) - then result = this.getArgument(0) - else result = this.getArgument([0, 1]) - } - - override predicate returnsFormatted() { none() } -} - -/** - * A call to `Kernel.sprintf`. - */ -class KernelSprintfCall extends PrintfStyleCall { - KernelSprintfCall() { - this = API::getTopLevelMember("Kernel").getAMethodCall("sprintf") - or - this.asExpr().getExpr() instanceof UnknownMethodCall and - this.getMethodName() = "sprintf" - } - - override predicate returnsFormatted() { any() } -} - -/** - * A call to `IO#printf`. - */ -class IOPrintfCall extends PrintfStyleCall { - IOPrintfCall() { - this.getReceiver() instanceof IO::IOInstance and this.getMethodName() = "printf" - } - - override predicate returnsFormatted() { none() } -} +import codeql.ruby.DataFlow From 6de1abcb0ef47ea2b2ef29bfc748275e8f03bfea Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 17 Oct 2022 12:29:07 +0200 Subject: [PATCH 004/796] add a returnsFormatted predicate to the printf model, similar to the JS implementation --- ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll b/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll index 501411c2558..1f58329629f 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll @@ -21,6 +21,9 @@ abstract class PrintfStyleCall extends DataFlow::CallNode { * Gets then `n`th formatted argument of this call. */ DataFlow::Node getFormatArgument(int n) { n >= 0 and result = this.getArgument(n + 1) } + + /** Holds if this call returns the formatted string. */ + predicate returnsFormatted() { any() } } /** @@ -46,6 +49,8 @@ class KernelPrintfCall extends PrintfStyleCall { then result = this.getArgument(0) else result = this.getArgument([0, 1]) } + + override predicate returnsFormatted() { none() } } /** @@ -58,6 +63,8 @@ class KernelSprintfCall extends PrintfStyleCall { this.asExpr().getExpr() instanceof UnknownMethodCall and this.getMethodName() = "sprintf" } + + override predicate returnsFormatted() { any() } } /** @@ -67,4 +74,6 @@ class IOPrintfCall extends PrintfStyleCall { IOPrintfCall() { this.getReceiver() instanceof IO::IOInstance and this.getMethodName() = "printf" } + + override predicate returnsFormatted() { none() } } From f222cc1f3ec1e6bd3de4977bcaa47ef9b9f88ac9 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 17 Oct 2022 12:35:46 +0200 Subject: [PATCH 005/796] refactor the existing taint-step for string interpolation into StringFormatters.qll --- ruby/ql/lib/codeql/ruby/dataflow/FlowSteps.qll | 4 +++- .../dataflow/internal/TaintTrackingPrivate.qll | 4 ---- .../codeql/ruby/frameworks/StringFormatters.qll | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/FlowSteps.qll b/ruby/ql/lib/codeql/ruby/dataflow/FlowSteps.qll index 414d241c9fa..881441fc765 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/FlowSteps.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/FlowSteps.qll @@ -11,7 +11,9 @@ private class Unit = DFPrivate::Unit; * A module importing the frameworks that implement additional flow steps, * ensuring that they are visible to the taint tracking library. */ -private module Frameworks { } +private module Frameworks { + import codeql.ruby.frameworks.StringFormatters +} /** * A unit class for adding additional taint steps. diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll index bf9fd46ffa0..92484e12596 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll @@ -95,10 +95,6 @@ private module Cached { ) ) or - // string interpolation of `nodeFrom` into `nodeTo` - nodeFrom.asExpr() = - nodeTo.asExpr().(CfgNodes::ExprNodes::StringlikeLiteralCfgNode).getAComponent() - or FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, false) or any(FlowSteps::AdditionalTaintStep s).step(nodeFrom, nodeTo) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll b/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll index 1f58329629f..fa284d8f18c 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll @@ -77,3 +77,19 @@ class IOPrintfCall extends PrintfStyleCall { override predicate returnsFormatted() { none() } } + +private import codeql.ruby.dataflow.FlowSteps +private import codeql.ruby.CFG + +/** + * A step for string interpolation of `pred` into `succ`. + * E.g. + * ```rb + * succ = "foo #{pred} bar" + * ``` + */ +private class StringLiteralFormatStep extends AdditionalTaintStep { + override predicate step(DataFlow::Node pred, DataFlow::Node succ) { + pred.asExpr() = succ.asExpr().(CfgNodes::ExprNodes::StringlikeLiteralCfgNode).getAComponent() + } +} From d4919d04ba934f5cb95da3656c29a44694ee8e4f Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 17 Oct 2022 12:43:28 +0200 Subject: [PATCH 006/796] add a taint-step for format-calls --- .../codeql/ruby/frameworks/StringFormatters.qll | 16 ++++++++++++++++ .../security/cwe-079/StoredXSS.expected | 4 ++++ .../cwe-079/app/views/foo/stores/show.html.erb | 5 +++++ 3 files changed, 25 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll b/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll index fa284d8f18c..b7c3fb0d21c 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll @@ -93,3 +93,19 @@ private class StringLiteralFormatStep extends AdditionalTaintStep { pred.asExpr() = succ.asExpr().(CfgNodes::ExprNodes::StringlikeLiteralCfgNode).getAComponent() } } + +/** + * A taint propagating data flow edge arising from string formatting. + */ +private class StringFormattingTaintStep extends AdditionalTaintStep { + override predicate step(DataFlow::Node pred, DataFlow::Node succ) { + exists(PrintfStyleCall call | + call.returnsFormatted() and + succ = call + | + pred = call.getFormatString() + or + pred = call.getFormatArgument(_) + ) + } +} diff --git a/ruby/ql/test/query-tests/security/cwe-079/StoredXSS.expected b/ruby/ql/test/query-tests/security/cwe-079/StoredXSS.expected index a637a8e4d0d..98156ed74c5 100644 --- a/ruby/ql/test/query-tests/security/cwe-079/StoredXSS.expected +++ b/ruby/ql/test/query-tests/security/cwe-079/StoredXSS.expected @@ -11,6 +11,7 @@ edges | app/views/foo/stores/show.html.erb:41:64:41:87 | ... + ... : | app/views/foo/bars/_widget.html.erb:5:9:5:20 | call to display_text | | app/views/foo/stores/show.html.erb:41:64:41:87 | ... + ... : | app/views/foo/bars/_widget.html.erb:8:9:8:36 | ...[...] | | app/views/foo/stores/show.html.erb:41:76:41:87 | call to display_text : | app/views/foo/stores/show.html.erb:41:64:41:87 | ... + ... : | +| app/views/foo/stores/show.html.erb:87:17:87:28 | call to handle : | app/views/foo/stores/show.html.erb:87:3:87:29 | call to sprintf | nodes | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read : | semmle.label | call to read : | | app/controllers/foo/stores_controller.rb:9:22:9:23 | dt : | semmle.label | dt : | @@ -31,6 +32,8 @@ nodes | app/views/foo/stores/show.html.erb:70:3:70:20 | call to raw_name | semmle.label | call to raw_name | | app/views/foo/stores/show.html.erb:80:5:80:22 | call to display_name | semmle.label | call to display_name | | app/views/foo/stores/show.html.erb:83:5:83:24 | @other_user_raw_name | semmle.label | @other_user_raw_name | +| app/views/foo/stores/show.html.erb:87:3:87:29 | call to sprintf | semmle.label | call to sprintf | +| app/views/foo/stores/show.html.erb:87:17:87:28 | call to handle : | semmle.label | call to handle : | subpaths #select | app/views/foo/bars/_widget.html.erb:5:9:5:20 | call to display_text | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read : | app/views/foo/bars/_widget.html.erb:5:9:5:20 | call to display_text | Stored cross-site scripting vulnerability due to $@. | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read | stored value | @@ -46,3 +49,4 @@ subpaths | app/views/foo/stores/show.html.erb:70:3:70:20 | call to raw_name | app/views/foo/stores/show.html.erb:70:3:70:20 | call to raw_name | app/views/foo/stores/show.html.erb:70:3:70:20 | call to raw_name | Stored cross-site scripting vulnerability due to $@. | app/views/foo/stores/show.html.erb:70:3:70:20 | call to raw_name | stored value | | app/views/foo/stores/show.html.erb:80:5:80:22 | call to display_name | app/views/foo/stores/show.html.erb:80:5:80:22 | call to display_name | app/views/foo/stores/show.html.erb:80:5:80:22 | call to display_name | Stored cross-site scripting vulnerability due to $@. | app/views/foo/stores/show.html.erb:80:5:80:22 | call to display_name | stored value | | app/views/foo/stores/show.html.erb:83:5:83:24 | @other_user_raw_name | app/controllers/foo/stores_controller.rb:12:28:12:48 | call to raw_name : | app/views/foo/stores/show.html.erb:83:5:83:24 | @other_user_raw_name | Stored cross-site scripting vulnerability due to $@. | app/controllers/foo/stores_controller.rb:12:28:12:48 | call to raw_name | stored value | +| app/views/foo/stores/show.html.erb:87:3:87:29 | call to sprintf | app/views/foo/stores/show.html.erb:87:17:87:28 | call to handle : | app/views/foo/stores/show.html.erb:87:3:87:29 | call to sprintf | Stored cross-site scripting vulnerability due to $@. | app/views/foo/stores/show.html.erb:87:17:87:28 | call to handle | stored value | diff --git a/ruby/ql/test/query-tests/security/cwe-079/app/views/foo/stores/show.html.erb b/ruby/ql/test/query-tests/security/cwe-079/app/views/foo/stores/show.html.erb index 90b70199767..837e5bccc3d 100644 --- a/ruby/ql/test/query-tests/security/cwe-079/app/views/foo/stores/show.html.erb +++ b/ruby/ql/test/query-tests/security/cwe-079/app/views/foo/stores/show.html.erb @@ -81,3 +81,8 @@ <%# BAD: Indirect to a database value without escaping %> <%= @other_user_raw_name.html_safe %> + +<%# BAD: Kernel.sprintf is a taint-step %> +<%= + sprintf("%s", @user.handle).html_safe +%> From f09e3bd3ac593ccd21654d2271374b3728f3ab77 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 17 Oct 2022 13:51:36 +0200 Subject: [PATCH 007/796] add String#% as a printf like call --- .../ruby/frameworks/StringFormatters.qll | 28 +++++++++++++++++-- .../cwe-134/TaintedFormatString.expected | 12 ++++++++ .../security/cwe-134/tainted_format_string.rb | 6 ++++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll b/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll index b7c3fb0d21c..b11fba8301f 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll @@ -2,7 +2,7 @@ * Provides classes for modeling string formatting libraries. */ -private import codeql.ruby.ast.Call +private import codeql.ruby.AST as Ast private import codeql.ruby.DataFlow private import codeql.ruby.ApiGraphs private import codeql.ruby.frameworks.core.IO @@ -33,7 +33,7 @@ class KernelPrintfCall extends PrintfStyleCall { KernelPrintfCall() { this = API::getTopLevelMember("Kernel").getAMethodCall("printf") or - this.asExpr().getExpr() instanceof UnknownMethodCall and + this.asExpr().getExpr() instanceof Ast::UnknownMethodCall and this.getMethodName() = "printf" } @@ -60,7 +60,7 @@ class KernelSprintfCall extends PrintfStyleCall { KernelSprintfCall() { this = API::getTopLevelMember("Kernel").getAMethodCall("sprintf") or - this.asExpr().getExpr() instanceof UnknownMethodCall and + this.asExpr().getExpr() instanceof Ast::UnknownMethodCall and this.getMethodName() = "sprintf" } @@ -78,6 +78,28 @@ class IOPrintfCall extends PrintfStyleCall { override predicate returnsFormatted() { none() } } +/** + * A call to `String#%`. + */ +class StringPercentCall extends PrintfStyleCall { + StringPercentCall() { this.getMethodName() = "%" } + + override DataFlow::Node getFormatString() { result = this.getReceiver() } + + override DataFlow::Node getFormatArgument(int n) { + exists(DataFlow::CallNode arrCall | + arrCall = this.getArgument(0) and arrCall.getMethodName() = "[]" + | + n = -2 and // -2 is indicates that the index does not make sense in this context + result = arrCall.getKeywordArgument(_) + or + result = arrCall.getArgument(n) + ) + } + + override predicate returnsFormatted() { any() } +} + private import codeql.ruby.dataflow.FlowSteps private import codeql.ruby.CFG diff --git a/ruby/ql/test/query-tests/security/cwe-134/TaintedFormatString.expected b/ruby/ql/test/query-tests/security/cwe-134/TaintedFormatString.expected index 4404c74a8d5..09ac79c910c 100644 --- a/ruby/ql/test/query-tests/security/cwe-134/TaintedFormatString.expected +++ b/ruby/ql/test/query-tests/security/cwe-134/TaintedFormatString.expected @@ -12,6 +12,10 @@ edges | tainted_format_string.rb:33:32:33:46 | ...[...] : | tainted_format_string.rb:33:12:33:46 | ... + ... | | tainted_format_string.rb:36:30:36:35 | call to params : | tainted_format_string.rb:36:30:36:44 | ...[...] : | | tainted_format_string.rb:36:30:36:44 | ...[...] : | tainted_format_string.rb:36:12:36:46 | "A log message: #{...}" | +| tainted_format_string.rb:39:22:39:27 | call to params : | tainted_format_string.rb:39:22:39:36 | ...[...] : | +| tainted_format_string.rb:39:22:39:36 | ...[...] : | tainted_format_string.rb:39:5:39:45 | "A log message #{...} %{foo}" | +| tainted_format_string.rb:42:22:42:27 | call to params : | tainted_format_string.rb:42:22:42:36 | ...[...] : | +| tainted_format_string.rb:42:22:42:36 | ...[...] : | tainted_format_string.rb:42:5:42:43 | "A log message #{...} %08x" | nodes | tainted_format_string.rb:4:12:4:17 | call to params : | semmle.label | call to params : | | tainted_format_string.rb:4:12:4:26 | ...[...] | semmle.label | ...[...] | @@ -37,6 +41,12 @@ nodes | tainted_format_string.rb:36:12:36:46 | "A log message: #{...}" | semmle.label | "A log message: #{...}" | | tainted_format_string.rb:36:30:36:35 | call to params : | semmle.label | call to params : | | tainted_format_string.rb:36:30:36:44 | ...[...] : | semmle.label | ...[...] : | +| tainted_format_string.rb:39:5:39:45 | "A log message #{...} %{foo}" | semmle.label | "A log message #{...} %{foo}" | +| tainted_format_string.rb:39:22:39:27 | call to params : | semmle.label | call to params : | +| tainted_format_string.rb:39:22:39:36 | ...[...] : | semmle.label | ...[...] : | +| tainted_format_string.rb:42:5:42:43 | "A log message #{...} %08x" | semmle.label | "A log message #{...} %08x" | +| tainted_format_string.rb:42:22:42:27 | call to params : | semmle.label | call to params : | +| tainted_format_string.rb:42:22:42:36 | ...[...] : | semmle.label | ...[...] : | subpaths #select | tainted_format_string.rb:4:12:4:26 | ...[...] | tainted_format_string.rb:4:12:4:17 | call to params : | tainted_format_string.rb:4:12:4:26 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:4:12:4:17 | call to params | user-provided value | @@ -50,3 +60,5 @@ subpaths | tainted_format_string.rb:28:19:28:33 | ...[...] | tainted_format_string.rb:28:19:28:24 | call to params : | tainted_format_string.rb:28:19:28:33 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:28:19:28:24 | call to params | user-provided value | | tainted_format_string.rb:33:12:33:46 | ... + ... | tainted_format_string.rb:33:32:33:37 | call to params : | tainted_format_string.rb:33:12:33:46 | ... + ... | Format string depends on a $@. | tainted_format_string.rb:33:32:33:37 | call to params | user-provided value | | tainted_format_string.rb:36:12:36:46 | "A log message: #{...}" | tainted_format_string.rb:36:30:36:35 | call to params : | tainted_format_string.rb:36:12:36:46 | "A log message: #{...}" | Format string depends on a $@. | tainted_format_string.rb:36:30:36:35 | call to params | user-provided value | +| tainted_format_string.rb:39:5:39:45 | "A log message #{...} %{foo}" | tainted_format_string.rb:39:22:39:27 | call to params : | tainted_format_string.rb:39:5:39:45 | "A log message #{...} %{foo}" | Format string depends on a $@. | tainted_format_string.rb:39:22:39:27 | call to params | user-provided value | +| tainted_format_string.rb:42:5:42:43 | "A log message #{...} %08x" | tainted_format_string.rb:42:22:42:27 | call to params : | tainted_format_string.rb:42:5:42:43 | "A log message #{...} %08x" | Format string depends on a $@. | tainted_format_string.rb:42:22:42:27 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/security/cwe-134/tainted_format_string.rb b/ruby/ql/test/query-tests/security/cwe-134/tainted_format_string.rb index 364f0ea1afb..aa66a9aa470 100644 --- a/ruby/ql/test/query-tests/security/cwe-134/tainted_format_string.rb +++ b/ruby/ql/test/query-tests/security/cwe-134/tainted_format_string.rb @@ -34,5 +34,11 @@ class UsersController < ActionController::Base # Taint via string interpolation printf("A log message: #{params[:format]}", arg) # BAD + + # Using String# + "A log message #{params[:format]} %{foo}" % {foo: "foo"} # BAD + + # String# with an array + "A log message #{params[:format]} %08x" % ["foo"] # BAD end end \ No newline at end of file From bb4bc55c6aef1f026e3a6ca19a9477f23c576432 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 17 Oct 2022 15:52:21 +0200 Subject: [PATCH 008/796] update expected output --- .../test/library-tests/dataflow/string-flow/string-flow.expected | 1 + 1 file changed, 1 insertion(+) diff --git a/ruby/ql/test/library-tests/dataflow/string-flow/string-flow.expected b/ruby/ql/test/library-tests/dataflow/string-flow/string-flow.expected index 6cebf219cd6..122a1d8eb1f 100644 --- a/ruby/ql/test/library-tests/dataflow/string-flow/string-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/string-flow/string-flow.expected @@ -12,6 +12,7 @@ edges | string_flow.rb:10:29:10:29 | b : | string_flow.rb:10:10:10:30 | call to try_convert | | string_flow.rb:14:9:14:18 | call to source : | string_flow.rb:15:10:15:17 | ... % ... | | string_flow.rb:14:9:14:18 | call to source : | string_flow.rb:15:17:15:17 | a : | +| string_flow.rb:14:9:14:18 | call to source : | string_flow.rb:16:10:16:29 | ... % ... | | string_flow.rb:14:9:14:18 | call to source : | string_flow.rb:16:28:16:28 | a : | | string_flow.rb:14:9:14:18 | call to source : | string_flow.rb:17:10:17:10 | a : | | string_flow.rb:14:9:14:18 | call to source : | string_flow.rb:17:10:17:18 | ... % ... | From 0051ba1596e6b745be0214896faf062eb38f9403 Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 17 Oct 2022 13:10:56 +0000 Subject: [PATCH 009/796] Python: Add new module resolution implementation A fairly complicated bit of modelling, mostly due to the quirks of how imports are handled in Python. A few notes: - The handling of `__all__` is not actually needed (and perhaps not desirable, as it only pertains to `import *`, though it does match the current behaviour), but it might become useful at a later date, so I left it in. - Ideally, we would represent `foo as bar` in an `import` as a `DefinitionNode` in the CFG. I opted _not_ to do this, as it would also affect points-to, and I did not want to deal with any fallout arising from that. --- .../new/internal/ImportResolution.qll | 262 ++++++++++++++++++ .../dataflow/new/internal/ImportStar.qll | 2 +- 2 files changed, 263 insertions(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll index 0c346fa2dd4..906460d76c1 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -1,14 +1,72 @@ +/** + * INTERNAL. DO NOT USE. + * + * Provides predicates for resolving imports. + */ + private import python private import semmle.python.dataflow.new.DataFlow private import semmle.python.dataflow.new.internal.ImportStar private import semmle.python.dataflow.new.TypeTracker +/** + * Python modules and the way imports are resolved are... complicated. Here's a crash course in how + * it works, as well as some caveats to bear in mind when looking at the implementation in this + * module. + * + * First, let's consider the humble `import` statement: + * ```python + * import foo + * import bar.baz + * import ham.eggs as spam + * ``` + * + * In the AST, all imports are aliased, as in the last import above. That is, `import foo` becomes + * `import foo as foo`, and `import bar.baz` becomes `import bar as bar`. Note that `import` is + * exclusively used to import modules -- if `eggs` is an attribute of the `ham` module (and not a + * submodule of the `ham` package), then the third line above is an error. + * + * Next, we have the `from` statement. This one is a bit more complicated, but still has the same + * aliasing desugaring as above applied to it. Thus, `from foo import bar` becomes + * `from foo import bar as bar`. + * + * In general, `from foo import bar` can mean two different things: + * + * 1. If `foo` is a module, and `bar` is an attribute of `foo`, then `from foo import bar` imports + * the attribute `bar` into the current module (binding it to the name `bar`). + * 2. If `foo` is a package, and `bar` is a submodule of `foo`, then `from foo import bar` first imports + * `foo.bar`, and then attempts to locate the `bar` attribute again. In most cases, that attribute + * will then point to the `bar` submodule. + * + * Now, when in comes to how these imports are represented in the AST, things get a bit complicated. + * First of all, both of the above forms of imports get mapped to the same kind of AST node: + * `Import`. An `Import` node has a sequence of names, each of which is an `Alias` node. This `Alias` + * node represents the `x as y` bit of each imported module. + * + * The same is true for `from` imports. So, how then do we distinguish between the two forms of + * imports? The distinguishing feature is the left hand side of the `as` node. If the left hand side + * is an `ImportExpr`, then it is a plain import. If it is an `ImportMember`, then it is a `from` + * import. (And to confuse matters even more, this `ImportMember` contains another `ImportExpr` for + * the bit between the `from` and `import` keywords.) + * + * Caveats: + * + * - A relative import of the form `from .foo import bar as baz` not only imports `bar` and binds it + * to the name `baz`, but also imports `foo` and binds it to the name `foo`. This only happens with + * relative imports. `from foo import bar as baz` only binds `bar` to `baz`. + * - Modules may also be packages, so e.g. `import foo.bar` may import the `bar` submodule in the `foo` + * package, or the `bar` subpackage of the `foo` package. The practical difference here is the name of + * the module that is imported, as the package `foo.bar` will have the "name" `foo.bar.__init__`, + * corresponding to the fact that the code that is executed is in the `__init__.py` file of the + * `bar` package. + */ module ImportResolution { /** * Holds if the module `m` defines a name `name` by assigning `defn` to it. This is an * overapproximation, as `name` may not in fact be exported (e.g. by defining an `__all__` that does * not include `name`). */ + pragma[nomagic] predicate module_export(Module m, string name, DataFlow::CfgNode defn) { exists(EssaVariable v | v.getName() = name and @@ -18,12 +76,216 @@ module ImportResolution { or defn.getNode() = v.getDefinition().(ArgumentRefinement).getArgument() ) + or + exists(Alias a | + defn.asExpr() = [a.getValue(), a.getValue().(ImportMember).getModule()] and + a.getAsname().(Name).getId() = name and + defn.getScope() = m + ) + } + + /** + * Holds if the module `m` explicitly exports the name `name` by listing it in `__all__`. Only + * handles simple cases where we can statically tell that this is the case. + */ + private predicate all_mentions_name(Module m, string name) { + exists(DefinitionNode def, SequenceNode n | + def.getValue() = n and + def.(NameNode).getId() = "__all__" and + def.getScope() = m and + any(StrConst s | s.getText() = name) = n.getAnElement().getNode() + ) + } + + /** + * Holds if the module `m` either does not set `__all__` (and so implicitly exports anything that + * doesn't start with an underscore), or sets `__all__` in a way that's too complicated for us to + * handle (in which case we _also_ pretend that it just exports all such names). + */ + private predicate no_or_complicated_all(Module m) { + // No mention of `__all__` in the module + not exists(DefinitionNode def | def.getScope() = m and def.(NameNode).getId() = "__all__") + or + // `__all__` is set to a non-sequence value + exists(DefinitionNode def | + def.(NameNode).getId() = "__all__" and + def.getScope() = m and + not def.getValue() instanceof SequenceNode + ) + or + // `__all__` is used in some way that doesn't involve storing a value in it. This usually means + // it is being mutated through `append` or `extend`, which we don't handle. + exists(NameNode n | n.getId() = "__all__" and n.getScope() = m and n.isLoad()) + } + + private predicate potential_module_export(Module m, string name) { + all_mentions_name(m, name) + or + no_or_complicated_all(m) and + ( + exists(NameNode n | n.getId() = name and n.getScope() = m and name.charAt(0) != "_") + or + exists(Alias a | a.getAsname().(Name).getId() = name and a.getValue().getScope() = m) + ) + } + + /** + * Holds if the module `reexporter` exports the module `reexported` under the name + * `reexported_name`. + */ + private predicate module_reexport(Module reexporter, string reexported_name, Module reexported) { + exists(DataFlow::Node ref | + ref = getImmediateModuleReference(reexported) and + module_export(reexporter, reexported_name, ref) and + potential_module_export(reexporter, reexported_name) + ) + } + + /** + * Gets a reference to `sys.modules`. + */ + private DataFlow::Node sys_modules_reference() { + result = + any(DataFlow::AttrRef a | + a.getAttributeName() = "modules" and a.getObject().asExpr().(Name).getId() = "sys" + ) + } + + /** Gets a module that may have been added to `sys.modules`. */ + private Module sys_modules_module_with_name(string name) { + exists(ControlFlowNode n, DataFlow::Node mod | + exists(SubscriptNode sub | + sub.getObject() = sys_modules_reference().asCfgNode() and + sub.getIndex() = n and + n.getNode().(StrConst).getText() = name and + sub.(DefinitionNode).getValue() = mod.asCfgNode() and + mod = getModuleReference(result) + ) + ) } Module getModule(DataFlow::CfgNode node) { exists(ModuleValue mv | node.getNode().pointsTo(mv) and result = mv.getScope() + Module getModuleImportedByImportStar(ImportStar i) { + isPreferredModuleForName(result.getFile(), i.getImportedModuleName()) + } + + /** Gets a data-flow node that may be a reference to a module with the name `module_name`. */ + DataFlow::Node getReferenceToModuleName(string module_name) { + // Regular import statements, e.g. + // import foo # implicitly `import foo as foo` + // import foo as foo_alias + exists(Import i, Alias a | a = i.getAName() | + result.asExpr() = a.getAsname() and + module_name = a.getValue().(ImportExpr).getImportedModuleName() + ) + or + // The module part of a `from ... import ...` statement, e.g. the `..foo.bar` in + // from ..foo.bar import baz # ..foo.bar might point to, say, package.subpackage.foo.bar + exists(ImportMember i | result.asExpr() = i.getModule() | + module_name = i.getModule().(ImportExpr).getImportedModuleName() + ) + or + // Modules (not attributes) imported via `from ... import ... statements`, e.g. + // from foo.bar import baz # imports foo.bar.baz as baz + // from foo.bar import baz as baz_alias # imports foo.bar.baz as baz_alias + exists(Import i, Alias a, ImportMember im | a = i.getAName() and im = a.getValue() | + i.isFromImport() and + result.asExpr() = a.getAsname() and + module_name = im.getModule().(ImportExpr).getImportedModuleName() + "." + im.getName() + ) + or + // For parity with the points-to based solution, the `ImportExpr` and `ImportMember` bits of the + // above cases should _also_ point to the right modules. + result.asExpr() = any(ImportExpr i | i.getImportedModuleName() = module_name) + or + result.asExpr() = + any(ImportMember i | + i.getModule().(ImportExpr).getImportedModuleName() = module_name + or + i.getModule().(ImportExpr).getImportedModuleName() + "." + i.getName() = module_name and + none() + ) + } + + /** Gets a dataflow node that is an immediate reference to the module `m`. */ + DataFlow::Node getImmediateModuleReference(Module m) { + exists(string module_name | result = getReferenceToModuleName(module_name) | + // Depending on whether the referenced module is a package or not, we may need to add a + // trailing `.__init__` to the module name. + isPreferredModuleForName(m.getFile(), module_name + ["", ".__init__"]) + or + // Module defined via `sys.modules` + m = sys_modules_module_with_name(module_name) + ) + or + // Reading an attribute on a module may return a submodule (or subpackage). + exists(DataFlow::AttrRead ar, Module p, string attr_name | + ar.getObject() = getModuleReference(p) and + attr_name = any(Module m0).getFile().getStem() and + ar.getAttributeName() = attr_name and + result = ar + | + isPreferredModuleForName(m.getFile(), p.getPackageName() + "." + attr_name + ["", ".__init__"]) + or + // This is also true for attributes that come from reexports. + module_reexport(p, attr_name, m) + ) + or + // Submodules that are implicitly defined when importing via `from ... import ...` statements. + // In practice, we create a definition for each module in a package, even if it is not imported. + exists(string submodule, Module package | + SsaSource::init_module_submodule_defn(result.asVar().getSourceVariable(), + package.getEntryNode()) and + isPreferredModuleForName(m.getFile(), + package.getPackageName() + "." + submodule + ["", ".__init__"]) ) } + + /** Join-order helper for `getModuleReference`. */ + pragma[nomagic] + private predicate module_name_in_scope(DataFlow::Node node, Scope s, string name, Module m) { + node.getScope() = s and + node.asExpr().(Name).getId() = name and + pragma[only_bind_into](node) = getImmediateModuleReference(pragma[only_bind_into](m)) + } + + /** Join-order helper for `getModuleReference`. */ + pragma[nomagic] + private predicate module_reference_in_scope(DataFlow::Node node, Scope s, string name) { + node.getScope() = s and + exists(Name n | n = node.asExpr() | + n.getId() = name and + pragma[only_bind_into](n).isUse() + ) + } + + /** + * Gets a reference to the module `m` (including through certain kinds of local and global flow). + */ + DataFlow::Node getModuleReference(Module m) { + // Immedate references to the module + result = getImmediateModuleReference(m) + or + // Flow (local or global) forward to a later reference to the module. + exists(DataFlow::Node ref | ref = getModuleReference(m) | + DataFlow::localFlow(ref, result) + or + exists(DataFlow::ModuleVariableNode mv | + mv.getAWrite() = ref and + result = mv.getARead() + ) + ) + or + // A reference to a name that is bound to a module in an enclosing scope. + exists(DataFlow::Node def, Scope def_scope, Scope use_scope, string name | + module_name_in_scope(pragma[only_bind_into](def), pragma[only_bind_into](def_scope), + pragma[only_bind_into](name), pragma[only_bind_into](m)) and + module_reference_in_scope(result, use_scope, name) and + use_scope.getEnclosingScope*() = def_scope + ) + } + } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/ImportStar.qll b/python/ql/lib/semmle/python/dataflow/new/internal/ImportStar.qll index ae115342dba..564630c47db 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportStar.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportStar.qll @@ -76,7 +76,7 @@ module ImportStar { exists(ImportStar i, DataFlow::CfgNode imported_module | imported_module.getNode().getNode() = i.getModule() and i.getScope() = m and - result = ImportResolution::getModule(imported_module) + result = ImportResolution::getModuleImportedByImportStar(i) ) } From 651afaf11b9ee9798a09f670dba1f1b97008d124 Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 17 Oct 2022 13:15:07 +0000 Subject: [PATCH 010/796] Python: Hook up new implementation Left as its own commit, as otherwise the diff would have been very confusing. --- .../semmle/python/dataflow/new/internal/ImportResolution.qll | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll index 906460d76c1..e1e4381519c 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -164,10 +164,6 @@ module ImportResolution { ) } - Module getModule(DataFlow::CfgNode node) { - exists(ModuleValue mv | - node.getNode().pointsTo(mv) and - result = mv.getScope() Module getModuleImportedByImportStar(ImportStar i) { isPreferredModuleForName(result.getFile(), i.getImportedModuleName()) } @@ -288,4 +284,5 @@ module ImportResolution { ) } + Module getModule(DataFlow::CfgNode node) { node = getModuleReference(result) } } From ad13fbaeb6b98d169dcfeac6ff5d95230a5b541d Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 17 Oct 2022 13:42:24 +0000 Subject: [PATCH 011/796] Python: Add tests A slightly complicated test setup. I wanted to both make sure I captured the semantics of Python and also the fact that the kinds of global flow we expect to see are indeed present. The code is executable, and prints out both when the execution reaches certain files, and also what values are assigned to the various attributes that are referenced throughout the program. These values are validated in the test as well. My original version used introspection to avoid referencing attributes directly (thus enabling better error diagnostics), but unfortunately that made it so that the model couldn't follow what was going on. The current setup is a bit clunky (and Python's scoping rules makes it especially so -- cf. the explicit calls to `globals` and `locals`), but I think it does the job okay. --- .../experimental/import-resolution/bar.py | 6 ++ .../experimental/import-resolution/foo.py | 14 ++++ .../import-resolution/importflow.expected | 0 .../import-resolution/importflow.ql | 41 ++++++++++++ .../import-resolution/imports.expected | 0 .../experimental/import-resolution/imports.ql | 49 ++++++++++++++ .../experimental/import-resolution/main.py | 65 +++++++++++++++++++ .../namespace_package/namespace_module.py | 6 ++ .../import-resolution/package/__init__.py | 7 ++ .../package/subpackage/__init__.py | 14 ++++ .../package/subpackage/submodule.py | 7 ++ .../experimental/import-resolution/trace.py | 49 ++++++++++++++ 12 files changed, 258 insertions(+) create mode 100644 python/ql/test/experimental/import-resolution/bar.py create mode 100644 python/ql/test/experimental/import-resolution/foo.py create mode 100644 python/ql/test/experimental/import-resolution/importflow.expected create mode 100644 python/ql/test/experimental/import-resolution/importflow.ql create mode 100644 python/ql/test/experimental/import-resolution/imports.expected create mode 100644 python/ql/test/experimental/import-resolution/imports.ql create mode 100644 python/ql/test/experimental/import-resolution/main.py create mode 100644 python/ql/test/experimental/import-resolution/namespace_package/namespace_module.py create mode 100644 python/ql/test/experimental/import-resolution/package/__init__.py create mode 100644 python/ql/test/experimental/import-resolution/package/subpackage/__init__.py create mode 100644 python/ql/test/experimental/import-resolution/package/subpackage/submodule.py create mode 100644 python/ql/test/experimental/import-resolution/trace.py diff --git a/python/ql/test/experimental/import-resolution/bar.py b/python/ql/test/experimental/import-resolution/bar.py new file mode 100644 index 00000000000..5cb6339be17 --- /dev/null +++ b/python/ql/test/experimental/import-resolution/bar.py @@ -0,0 +1,6 @@ +from trace import * +enter(__file__) + +bar_attr = "bar_attr" + +exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/foo.py b/python/ql/test/experimental/import-resolution/foo.py new file mode 100644 index 00000000000..d112007ad03 --- /dev/null +++ b/python/ql/test/experimental/import-resolution/foo.py @@ -0,0 +1,14 @@ +from trace import * +enter(__file__) + +# A simple attribute. Used in main.py +foo_attr = "foo_attr" + +# A private attribute. Accessible from main.py despite this. +__private_foo_attr = "__private_foo_attr" + +# A reexport of bar under a new name. Used in main.py +import bar as bar_reexported #$ imports=bar as=bar_reexported +check("bar_reexported.bar_attr", bar_reexported.bar_attr, "bar_attr", globals()) #$ prints=bar_attr + +exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/importflow.expected b/python/ql/test/experimental/import-resolution/importflow.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/experimental/import-resolution/importflow.ql b/python/ql/test/experimental/import-resolution/importflow.ql new file mode 100644 index 00000000000..0e7d300d328 --- /dev/null +++ b/python/ql/test/experimental/import-resolution/importflow.ql @@ -0,0 +1,41 @@ +import python +import semmle.python.dataflow.new.DataFlow +import semmle.python.ApiGraphs +import TestUtilities.InlineExpectationsTest + +private class SourceString extends DataFlow::Node { + string contents; + + SourceString() { + this.asExpr().(StrConst).getText() = contents and + this.asExpr().getParent() instanceof Assign + } + + string getContents() { result = contents } +} + +private class ImportConfiguration extends DataFlow::Configuration { + ImportConfiguration() { this = "ImportConfiguration" } + + override predicate isSource(DataFlow::Node source) { source instanceof SourceString } + + override predicate isSink(DataFlow::Node sink) { + sink = API::moduleImport("trace").getMember("check").getACall().getArg(1) + } +} + +class ResolutionTest extends InlineExpectationsTest { + ResolutionTest() { this = "ResolutionTest" } + + override string getARelevantTag() { result = "import" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + exists(DataFlow::PathNode source, DataFlow::PathNode sink, ImportConfiguration config | + config.hasFlowPath(source, sink) and + tag = "prints" and + location = sink.getNode().getLocation() and + value = source.getNode().(SourceString).getContents() and + element = sink.getNode().toString() + ) + } +} diff --git a/python/ql/test/experimental/import-resolution/imports.expected b/python/ql/test/experimental/import-resolution/imports.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/experimental/import-resolution/imports.ql b/python/ql/test/experimental/import-resolution/imports.ql new file mode 100644 index 00000000000..e5d357c5ef4 --- /dev/null +++ b/python/ql/test/experimental/import-resolution/imports.ql @@ -0,0 +1,49 @@ +import python +import TestUtilities.InlineExpectationsTest +import semmle.python.dataflow.new.DataFlow +import semmle.python.dataflow.new.internal.ImportResolution + +private class ImmediateModuleRef extends DataFlow::Node { + Module mod; + string alias; + + ImmediateModuleRef() { + this = ImportResolution::getImmediateModuleReference(mod) and + not mod.getName() in ["__future__", "trace"] and + this.asExpr() = any(Alias a | alias = a.getAsname().(Name).getId()).getAsname() + } + + Module getModule() { result = mod } + + string getAsname() { result = alias } +} + +class ImportTest extends InlineExpectationsTest { + ImportTest() { this = "ImportTest" } + + override string getARelevantTag() { result = "imports" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + exists(ImmediateModuleRef ref | + tag = "imports" and + location = ref.getLocation() and + value = ref.getModule().getName() and + element = ref.toString() + ) + } +} + +class AliasTest extends InlineExpectationsTest { + AliasTest() { this = "AliasTest" } + + override string getARelevantTag() { result = "as" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + exists(ImmediateModuleRef ref | + tag = "as" and + location = ref.getLocation() and + value = ref.getAsname() and + element = ref.toString() + ) + } +} diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py new file mode 100644 index 00000000000..827bb78896b --- /dev/null +++ b/python/ql/test/experimental/import-resolution/main.py @@ -0,0 +1,65 @@ +#! /usr/bin/env python3 + +from __future__ import print_function +import sys +from trace import * +enter(__file__) + +# A simple import. Binds foo to the foo module +import foo #$ imports=foo as=foo +check("foo.foo_attr", foo.foo_attr, "foo_attr", globals()) #$ prints=foo_attr + +# Private attributes are still accessible. +check("foo.__private_foo_attr", foo.__private_foo_attr, "__private_foo_attr", globals()) #$ prints=__private_foo_attr + +# An aliased import, binding foo to foo_alias +import foo as foo_alias #$ imports=foo as=foo_alias +check("foo_alias.foo_attr", foo_alias.foo_attr, "foo_attr", globals()) #$ prints=foo_attr + +# A reference to a reexported module +check("foo.bar_reexported.bar_attr", foo.bar_reexported.bar_attr, "bar_attr", globals()) #$ prints=bar_attr + +# A simple "import from" statement. +from bar import bar_attr +check("bar_attr", bar_attr, "bar_attr", globals()) #$ prints=bar_attr + +# Importing an attribute from a subpackage of a package. +from package.subpackage import subpackage_attr +check("subpackage_attr", subpackage_attr, "subpackage_attr", globals()) #$ prints=subpackage_attr + +# Importing a package attribute under an alias. +from package import package_attr as package_attr_alias +check("package_attr_alias", package_attr_alias, "package_attr", globals()) #$ prints=package_attr + +# Importing a subpackage under an alias. +from package import subpackage as aliased_subpackage #$ imports=package.subpackage.__init__ as=aliased_subpackage +check("aliased_subpackage.subpackage_attr", aliased_subpackage.subpackage_attr, "subpackage_attr", globals()) #$ prints=subpackage_attr + +def local_import(): + # Same as above, but in a local scope. + import package.subpackage as local_subpackage #$ imports=package.subpackage.__init__ as=local_subpackage + check("local_subpackage.subpackage_attr", local_subpackage.subpackage_attr, "subpackage_attr", locals()) #$ prints=subpackage_attr + +local_import() + +# Importing a subpacking using `import` and binding it to a name. +import package.subpackage as aliased_subpackage #$ imports=package.subpackage.__init__ as=aliased_subpackage +check("aliased_subpackage.subpackage_attr", aliased_subpackage.subpackage_attr, "subpackage_attr", globals()) #$ prints=subpackage_attr + +# Importing without binding instead binds the top level name. +import package.subpackage #$ imports=package.__init__ as=package +check("package.package_attr", package.package_attr, "package_attr", globals()) #$ prints=package_attr + +if sys.version_info[0] >= 3: + # Importing from a namespace module. + from namespace_package.namespace_module import namespace_module_attr + check("namespace_module_attr", namespace_module_attr, "namespace_module_attr", globals()) #$ prints=namespace_module_attr + +exit(__file__) + +print() + +if status() == 0: + print("PASS") +else: + print("FAIL") diff --git a/python/ql/test/experimental/import-resolution/namespace_package/namespace_module.py b/python/ql/test/experimental/import-resolution/namespace_package/namespace_module.py new file mode 100644 index 00000000000..2c831662f47 --- /dev/null +++ b/python/ql/test/experimental/import-resolution/namespace_package/namespace_module.py @@ -0,0 +1,6 @@ +from trace import * +enter(__file__) + +namespace_module_attr = "namespace_module_attr" + +exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/package/__init__.py b/python/ql/test/experimental/import-resolution/package/__init__.py new file mode 100644 index 00000000000..ee2e3211a2c --- /dev/null +++ b/python/ql/test/experimental/import-resolution/package/__init__.py @@ -0,0 +1,7 @@ +from trace import * +enter(__file__) + +attr_used_in_subpackage = "attr_used_in_subpackage" +package_attr = "package_attr" + +exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/package/subpackage/__init__.py b/python/ql/test/experimental/import-resolution/package/subpackage/__init__.py new file mode 100644 index 00000000000..86cc92dd37b --- /dev/null +++ b/python/ql/test/experimental/import-resolution/package/subpackage/__init__.py @@ -0,0 +1,14 @@ +from trace import * +enter(__file__) + +subpackage_attr = "subpackage_attr" + +# Importing an attribute from the parent package. +from .. import attr_used_in_subpackage as imported_attr +check("imported_attr", imported_attr, "attr_used_in_subpackage", globals()) #$ prints=attr_used_in_subpackage + +# Importing an irrelevant attribute from a sibling module binds the name to the module. +from .submodule import irrelevant_attr +check("submodule.submodule_attr", submodule.submodule_attr, "submodule_attr", globals()) #$ prints=submodule_attr + +exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/package/subpackage/submodule.py b/python/ql/test/experimental/import-resolution/package/subpackage/submodule.py new file mode 100644 index 00000000000..89f9dd497a4 --- /dev/null +++ b/python/ql/test/experimental/import-resolution/package/subpackage/submodule.py @@ -0,0 +1,7 @@ +from trace import * +enter(__file__) + +submodule_attr = "submodule_attr" +irrelevant_attr = "irrelevant_attr" + +exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/trace.py b/python/ql/test/experimental/import-resolution/trace.py new file mode 100644 index 00000000000..04e847304e9 --- /dev/null +++ b/python/ql/test/experimental/import-resolution/trace.py @@ -0,0 +1,49 @@ +from __future__ import print_function + +_indent_level = 0 + +_print = print + +def print(*args, **kwargs): + _print(" " * _indent_level, end="") + _print(*args, **kwargs) + +def enter(file_name): + global _indent_level + print("Entering {}".format(file_name)) + _indent_level += 1 + +def exit(file_name): + global _indent_level + _indent_level -= 1 + print("Leaving {}".format(file_name)) + +_status = 0 + +def status(): + return _status + +def check(attr_path, actual_value, expected_value, bindings): + parts = attr_path.split(".") + base, parts = parts[0], parts[1:] + if base not in bindings: + print("Error: {} not in bindings".format(base)) + _status = 1 + return + val = bindings[base] + for part in parts: + if not hasattr(val, part): + print("Error: Unknown attribute {}".format(part)) + _status = 1 + return + val = getattr(val, part) + if val != actual_value: + print("Error: Value at path {} and actual value are out of sync! {} != {}".format(attr_path, val, actual_value)) + _status = 1 + if val != expected_value: + print("Error: Expected {} to be {}, got {}".format(attr_path, expected_value, val)) + _status = 1 + return + print("OK: {} = {}".format(attr_path, val)) + +__all__ = ["enter", "exit", "check", "status"] From 58754982cefc5d4b7c2b4082d233a81d06f35066 Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 17 Oct 2022 14:34:10 +0000 Subject: [PATCH 012/796] Python: Update type tracking tests No longer missing! :tada: --- .../experimental/dataflow/typetracking_imports/pkg/use.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/use.py b/python/ql/test/experimental/dataflow/typetracking_imports/pkg/use.py index 023af8684f2..a23ddc54b2d 100644 --- a/python/ql/test/experimental/dataflow/typetracking_imports/pkg/use.py +++ b/python/ql/test/experimental/dataflow/typetracking_imports/pkg/use.py @@ -6,8 +6,8 @@ test_direct_import() def test_alias_problem(): - from .alias_problem import foo # $ MISSING: tracked - print(foo) # $ MISSING: tracked + from .alias_problem import foo # $ tracked + print(foo) # $ tracked test_alias_problem() @@ -34,8 +34,8 @@ test_alias_only_direct() def test_problem_absolute_import(): - from pkg.problem_absolute_import import foo # $ MISSING: tracked - print(foo) # $ MISSING: tracked + from pkg.problem_absolute_import import foo # $ tracked + print(foo) # $ tracked test_problem_absolute_import() From aafef382dca26e28ef6ea6ead252d4019736ebe9 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 24 Oct 2022 18:57:24 +0200 Subject: [PATCH 013/796] refactor StringPercentCall#getFormatArgument --- .../codeql/ruby/frameworks/StringFormatters.qll | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll b/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll index b11fba8301f..da9ce58345e 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll @@ -87,13 +87,15 @@ class StringPercentCall extends PrintfStyleCall { override DataFlow::Node getFormatString() { result = this.getReceiver() } override DataFlow::Node getFormatArgument(int n) { - exists(DataFlow::CallNode arrCall | - arrCall = this.getArgument(0) and arrCall.getMethodName() = "[]" - | - n = -2 and // -2 is indicates that the index does not make sense in this context - result = arrCall.getKeywordArgument(_) + exists(Ast::Call call | call = this.asExpr().getExpr() | + exists(Ast::ArrayLiteral arrLit | arrLit = call.getArgument(0) | + result.asExpr().getExpr() = arrLit.getElement(n) + ) or - result = arrCall.getArgument(n) + exists(Ast::HashLiteral hashLit | hashLit = call.getArgument(0) | + n = -2 and // -2 is indicates that the index does not make sense in this context + result.asExpr().getExpr() = hashLit.getAnElement() + ) ) } From 39081e9c1c6c869401741674f43e535a88c4a9aa Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 31 May 2022 00:35:48 +0200 Subject: [PATCH 014/796] Python: Fix staticmethod datamodel test --- .../dataflow/coverage/dataflow.expected | 35 +++++++++++++------ .../dataflow/coverage/datamodel.py | 9 +++++ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/python/ql/test/experimental/dataflow/coverage/dataflow.expected b/python/ql/test/experimental/dataflow/coverage/dataflow.expected index c7a0294d66a..9321d941ad8 100644 --- a/python/ql/test/experimental/dataflow/coverage/dataflow.expected +++ b/python/ql/test/experimental/dataflow/coverage/dataflow.expected @@ -4,6 +4,7 @@ edges | datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:38:6:38:17 | ControlFlowNode for f() | | datamodel.py:44:22:44:22 | ControlFlowNode for x | datamodel.py:46:16:46:16 | ControlFlowNode for x | | datamodel.py:49:26:49:26 | ControlFlowNode for x | datamodel.py:50:16:50:16 | ControlFlowNode for x | +| datamodel.py:53:22:53:22 | ControlFlowNode for x | datamodel.py:54:16:54:16 | ControlFlowNode for x | | datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:44:22:44:22 | ControlFlowNode for x | | datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | | datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:44:22:44:22 | ControlFlowNode for x | @@ -12,10 +13,14 @@ edges | datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | | datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:49:26:49:26 | ControlFlowNode for x | | datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | -| datamodel.py:152:5:152:8 | [post store] ControlFlowNode for self [Attribute b] | datamodel.py:155:14:155:25 | ControlFlowNode for Customized() [Attribute b] | -| datamodel.py:152:14:152:19 | ControlFlowNode for SOURCE | datamodel.py:152:5:152:8 | [post store] ControlFlowNode for self [Attribute b] | -| datamodel.py:155:14:155:25 | ControlFlowNode for Customized() [Attribute b] | datamodel.py:159:6:159:15 | ControlFlowNode for customized [Attribute b] | -| datamodel.py:159:6:159:15 | ControlFlowNode for customized [Attribute b] | datamodel.py:159:6:159:17 | ControlFlowNode for Attribute | +| datamodel.py:88:21:88:26 | ControlFlowNode for SOURCE | datamodel.py:53:22:53:22 | ControlFlowNode for x | +| datamodel.py:88:21:88:26 | ControlFlowNode for SOURCE | datamodel.py:88:6:88:27 | ControlFlowNode for Attribute() | +| datamodel.py:89:21:89:26 | ControlFlowNode for SOURCE | datamodel.py:53:22:53:22 | ControlFlowNode for x | +| datamodel.py:89:21:89:26 | ControlFlowNode for SOURCE | datamodel.py:89:6:89:27 | ControlFlowNode for Attribute() | +| datamodel.py:161:5:161:8 | [post store] ControlFlowNode for self [Attribute b] | datamodel.py:164:14:164:25 | ControlFlowNode for Customized() [Attribute b] | +| datamodel.py:161:14:161:19 | ControlFlowNode for SOURCE | datamodel.py:161:5:161:8 | [post store] ControlFlowNode for self [Attribute b] | +| datamodel.py:164:14:164:25 | ControlFlowNode for Customized() [Attribute b] | datamodel.py:168:6:168:15 | ControlFlowNode for customized [Attribute b] | +| datamodel.py:168:6:168:15 | ControlFlowNode for customized [Attribute b] | datamodel.py:168:6:168:17 | ControlFlowNode for Attribute | | test.py:42:10:42:26 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:43:9:43:9 | ControlFlowNode for x [Tuple element at index 1] | | test.py:42:21:42:26 | ControlFlowNode for SOURCE | test.py:42:10:42:26 | ControlFlowNode for Tuple [Tuple element at index 1] | | test.py:43:9:43:9 | ControlFlowNode for x [Tuple element at index 1] | test.py:43:9:43:12 | ControlFlowNode for Subscript | @@ -396,6 +401,8 @@ nodes | datamodel.py:46:16:46:16 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | | datamodel.py:49:26:49:26 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | | datamodel.py:50:16:50:16 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| datamodel.py:53:22:53:22 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| datamodel.py:54:16:54:16 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | @@ -404,11 +411,15 @@ nodes | datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| datamodel.py:152:5:152:8 | [post store] ControlFlowNode for self [Attribute b] | semmle.label | [post store] ControlFlowNode for self [Attribute b] | -| datamodel.py:152:14:152:19 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| datamodel.py:155:14:155:25 | ControlFlowNode for Customized() [Attribute b] | semmle.label | ControlFlowNode for Customized() [Attribute b] | -| datamodel.py:159:6:159:15 | ControlFlowNode for customized [Attribute b] | semmle.label | ControlFlowNode for customized [Attribute b] | -| datamodel.py:159:6:159:17 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| datamodel.py:88:6:88:27 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| datamodel.py:88:21:88:26 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| datamodel.py:89:6:89:27 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| datamodel.py:89:21:89:26 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| datamodel.py:161:5:161:8 | [post store] ControlFlowNode for self [Attribute b] | semmle.label | [post store] ControlFlowNode for self [Attribute b] | +| datamodel.py:161:14:161:19 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| datamodel.py:164:14:164:25 | ControlFlowNode for Customized() [Attribute b] | semmle.label | ControlFlowNode for Customized() [Attribute b] | +| datamodel.py:168:6:168:15 | ControlFlowNode for customized [Attribute b] | semmle.label | ControlFlowNode for customized [Attribute b] | +| datamodel.py:168:6:168:17 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:42:10:42:26 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] | | test.py:42:21:42:26 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | | test.py:43:9:43:9 | ControlFlowNode for x [Tuple element at index 1] | semmle.label | ControlFlowNode for x [Tuple element at index 1] | @@ -845,6 +856,8 @@ subpaths | datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:44:22:44:22 | ControlFlowNode for x | datamodel.py:46:16:46:16 | ControlFlowNode for x | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | | datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:49:26:49:26 | ControlFlowNode for x | datamodel.py:50:16:50:16 | ControlFlowNode for x | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | | datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:49:26:49:26 | ControlFlowNode for x | datamodel.py:50:16:50:16 | ControlFlowNode for x | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | +| datamodel.py:88:21:88:26 | ControlFlowNode for SOURCE | datamodel.py:53:22:53:22 | ControlFlowNode for x | datamodel.py:54:16:54:16 | ControlFlowNode for x | datamodel.py:88:6:88:27 | ControlFlowNode for Attribute() | +| datamodel.py:89:21:89:26 | ControlFlowNode for SOURCE | datamodel.py:53:22:53:22 | ControlFlowNode for x | datamodel.py:54:16:54:16 | ControlFlowNode for x | datamodel.py:89:6:89:27 | ControlFlowNode for Attribute() | | test.py:380:28:380:33 | ControlFlowNode for SOURCE | test.py:375:15:375:15 | ControlFlowNode for b | test.py:376:12:376:12 | ControlFlowNode for b | test.py:380:10:380:34 | ControlFlowNode for second() | | test.py:388:30:388:35 | ControlFlowNode for SOURCE | test.py:375:15:375:15 | ControlFlowNode for b | test.py:376:12:376:12 | ControlFlowNode for b | test.py:388:10:388:36 | ControlFlowNode for second() | | test.py:396:10:396:43 | KwUnpacked b | test.py:375:15:375:15 | ControlFlowNode for b | test.py:376:12:376:12 | ControlFlowNode for b | test.py:396:10:396:43 | ControlFlowNode for second() | @@ -862,7 +875,9 @@ subpaths | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | Flow found | | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | Flow found | | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | Flow found | -| datamodel.py:159:6:159:17 | ControlFlowNode for Attribute | datamodel.py:152:14:152:19 | ControlFlowNode for SOURCE | datamodel.py:159:6:159:17 | ControlFlowNode for Attribute | Flow found | +| datamodel.py:88:6:88:27 | ControlFlowNode for Attribute() | datamodel.py:88:21:88:26 | ControlFlowNode for SOURCE | datamodel.py:88:6:88:27 | ControlFlowNode for Attribute() | Flow found | +| datamodel.py:89:6:89:27 | ControlFlowNode for Attribute() | datamodel.py:89:21:89:26 | ControlFlowNode for SOURCE | datamodel.py:89:6:89:27 | ControlFlowNode for Attribute() | Flow found | +| datamodel.py:168:6:168:17 | ControlFlowNode for Attribute | datamodel.py:161:14:161:19 | ControlFlowNode for SOURCE | datamodel.py:168:6:168:17 | ControlFlowNode for Attribute | Flow found | | test.py:44:10:44:10 | ControlFlowNode for y | test.py:42:21:42:26 | ControlFlowNode for SOURCE | test.py:44:10:44:10 | ControlFlowNode for y | Flow found | | test.py:56:10:56:10 | ControlFlowNode for x | test.py:55:9:55:14 | ControlFlowNode for SOURCE | test.py:56:10:56:10 | ControlFlowNode for x | Flow found | | test.py:62:10:62:10 | ControlFlowNode for x | test.py:61:9:61:16 | ControlFlowNode for Str | test.py:62:10:62:10 | ControlFlowNode for x | Flow found | diff --git a/python/ql/test/experimental/dataflow/coverage/datamodel.py b/python/ql/test/experimental/dataflow/coverage/datamodel.py index f165e3d67e1..55a21410368 100644 --- a/python/ql/test/experimental/dataflow/coverage/datamodel.py +++ b/python/ql/test/experimental/dataflow/coverage/datamodel.py @@ -81,6 +81,15 @@ SINK(c.classmethod(SOURCE)) #$ flow="SOURCE -> c.classmethod(..)" SINK(C.classmethod(SOURCE)) #$ flow="SOURCE -> C.classmethod(..)" SINK(c_func_obj(C, SOURCE)) #$ MISSING: flow="SOURCE -> c_func_obj(..)" +# When an instance method object is created by retrieving a class method object from a class or instance, its __self__ attribute is the class itself, and its __func__ attribute is the function object underlying the class method. +s_func_obj = C.staticmethod.__func__ + +# When an instance method object is derived from a class method object, the “class instance” stored in __self__ will actually be the class itself, so that calling either x.f(1) or C.f(1) is equivalent to calling f(C,1) where f is the underlying function. +SINK(c.staticmethod(SOURCE)) #$ flow="SOURCE -> c.staticmethod(..)" +SINK(C.staticmethod(SOURCE)) #$ flow="SOURCE -> C.staticmethod(..)" +SINK(s_func_obj(SOURCE)) #$ MISSING: flow="SOURCE -> s_func_obj(..)" + + # Generator functions # A function or method which uses the yield statement (see section The yield statement) is called a generator function. Such a function, when called, always returns an iterator object which can be used to execute the body of the function: calling the iterator’s iterator.__next__() method will cause the function to execute until it provides a value using the yield statement. When the function executes a return statement or falls off the end, a StopIteration exception is raised and the iterator will have reached the end of the set of values to be returned. def gen(x, count): From 609a4cfd42dccf4728eefcd973022fa2b12eacfc Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 22 Jun 2022 14:42:22 +0200 Subject: [PATCH 015/796] Python: validate tests in `datamodel.py` And adopt argument passing tests as well. turns out that `C.staticmethod.__func__` doesn't actually work :O --- .../dataflow/coverage/datamodel.py | 88 +++++++++++++------ .../test/experimental/dataflow/validTest.py | 1 + 2 files changed, 62 insertions(+), 27 deletions(-) diff --git a/python/ql/test/experimental/dataflow/coverage/datamodel.py b/python/ql/test/experimental/dataflow/coverage/datamodel.py index 55a21410368..364dbb299d7 100644 --- a/python/ql/test/experimental/dataflow/coverage/datamodel.py +++ b/python/ql/test/experimental/dataflow/coverage/datamodel.py @@ -8,15 +8,30 @@ # Intended sources should be the variable `SOURCE` and intended sinks should be # arguments to the function `SINK` (see python/ql/test/experimental/dataflow/testConfig.qll). +import sys +import os +import functools + +sys.path.append(os.path.dirname(os.path.dirname((__file__)))) +from testlib import expects + # These are defined so that we can evaluate the test code. NONSOURCE = "not a source" SOURCE = "source" +arg1 = "source1" +arg2 = "source2" +arg3 = "source3" +arg4 = "source4" +arg5 = "source5" +arg6 = "source6" +arg7 = "source7" + def is_source(x): return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j -def SINK(x): - if is_source(x): +def SINK(x, expected=SOURCE): + if is_source(x) or x == expected: print("OK") else: print("Unexpected flow", x) @@ -27,6 +42,14 @@ def SINK_F(x): else: print("OK") +SINK1 = functools.partial(SINK, expected=arg1) +SINK2 = functools.partial(SINK, expected=arg2) +SINK3 = functools.partial(SINK, expected=arg3) +SINK4 = functools.partial(SINK, expected=arg4) +SINK5 = functools.partial(SINK, expected=arg5) +SINK6 = functools.partial(SINK, expected=arg6) +SINK7 = functools.partial(SINK, expected=arg7) + # Callable types # These are the types to which the function call operation (see section Calls) can be applied: @@ -41,17 +64,19 @@ SINK(f(SOURCE, 3)) #$ flow="SOURCE -> f(..)" # An instance method object combines a class, a class instance and any callable object (normally a user-defined function). class C(object): - def method(self, x, cls): - assert cls is self.__class__ - return x + def method(self, x, y): + SINK1(x) + SINK2(y) @classmethod - def classmethod(cls, x): - return x + def classmethod(cls, x, y): + SINK1(x) + SINK2(y) @staticmethod - def staticmethod(x): - return x + def staticmethod(x, y): + SINK1(x) + SINK2(y) def gen(self, x, count): n = count @@ -64,30 +89,39 @@ class C(object): c = C() -# When an instance method object is created by retrieving a user-defined function object from a class via one of its instances, its __self__ attribute is the instance, and the method object is said to be bound. The new method’s __func__ attribute is the original function object. -func_obj = c.method.__func__ +@expects(6) +def test_method_call(): + # When an instance method object is created by retrieving a user-defined function object from a class via one of its instances, its __self__ attribute is the instance, and the method object is said to be bound. The new method’s __func__ attribute is the original function object. + func_obj = c.method.__func__ -# When an instance method object is called, the underlying function (__func__) is called, inserting the class instance (__self__) in front of the argument list. For instance, when C is a class which contains a definition for a function f(), and x is an instance of C, calling x.f(1) is equivalent to calling C.f(x, 1). -SINK(c.method(SOURCE, C)) #$ flow="SOURCE -> c.method(..)" -SINK(C.method(c, SOURCE, C)) #$ flow="SOURCE -> C.method(..)" -SINK(func_obj(c, SOURCE, C)) #$ MISSING: flow="SOURCE -> func_obj(..)" + # When an instance method object is called, the underlying function (__func__) is called, inserting the class instance (__self__) in front of the argument list. For instance, when C is a class which contains a definition for a function f(), and x is an instance of C, calling x.f(1) is equivalent to calling C.f(x, 1). + c.method(arg1, arg2) # $ func=C.method arg1 arg2 + C.method(c, arg1, arg2) # $ func=C.method arg1 arg2 + func_obj(c, arg1, arg2) # $ MISSING: func=C.method arg1 arg2 -# When an instance method object is created by retrieving a class method object from a class or instance, its __self__ attribute is the class itself, and its __func__ attribute is the function object underlying the class method. -c_func_obj = C.classmethod.__func__ +@expects(6) +def test_classmethod_call(): + # When an instance method object is created by retrieving a class method object from a class or instance, its __self__ attribute is the class itself, and its __func__ attribute is the function object underlying the class method. + c_func_obj = C.classmethod.__func__ -# When an instance method object is derived from a class method object, the “class instance” stored in __self__ will actually be the class itself, so that calling either x.f(1) or C.f(1) is equivalent to calling f(C,1) where f is the underlying function. -SINK(c.classmethod(SOURCE)) #$ flow="SOURCE -> c.classmethod(..)" -SINK(C.classmethod(SOURCE)) #$ flow="SOURCE -> C.classmethod(..)" -SINK(c_func_obj(C, SOURCE)) #$ MISSING: flow="SOURCE -> c_func_obj(..)" + # When an instance method object is derived from a class method object, the “class instance” stored in __self__ will actually be the class itself, so that calling either x.f(1) or C.f(1) is equivalent to calling f(C,1) where f is the underlying function. + c.classmethod(arg1, arg2) # $ func=C.classmethod arg1 arg2 + C.classmethod(arg1, arg2) # $ func=C.classmethod arg1 arg2 + c_func_obj(C, arg1, arg2) # $ MISSING: func=C.classmethod arg1 arg2 -# When an instance method object is created by retrieving a class method object from a class or instance, its __self__ attribute is the class itself, and its __func__ attribute is the function object underlying the class method. -s_func_obj = C.staticmethod.__func__ -# When an instance method object is derived from a class method object, the “class instance” stored in __self__ will actually be the class itself, so that calling either x.f(1) or C.f(1) is equivalent to calling f(C,1) where f is the underlying function. -SINK(c.staticmethod(SOURCE)) #$ flow="SOURCE -> c.staticmethod(..)" -SINK(C.staticmethod(SOURCE)) #$ flow="SOURCE -> C.staticmethod(..)" -SINK(s_func_obj(SOURCE)) #$ MISSING: flow="SOURCE -> s_func_obj(..)" +@expects(5) +def test_staticmethod_call(): + # staticmethods does not have a __func__ attribute + try: + C.staticmethod.__func__ + except AttributeError: + print("OK") + + # When an instance method object is derived from a class method object, the “class instance” stored in __self__ will actually be the class itself, so that calling either x.f(1) or C.f(1) is equivalent to calling f(C,1) where f is the underlying function. + c.staticmethod(arg1, arg2) # $ func=C.staticmethod arg1 arg2 + C.staticmethod(arg1, arg2) # $ func=C.staticmethod arg1 arg2 # Generator functions diff --git a/python/ql/test/experimental/dataflow/validTest.py b/python/ql/test/experimental/dataflow/validTest.py index 86336af05ba..edfe685c266 100644 --- a/python/ql/test/experimental/dataflow/validTest.py +++ b/python/ql/test/experimental/dataflow/validTest.py @@ -55,6 +55,7 @@ if __name__ == "__main__": check_tests_valid("coverage.classes") check_tests_valid("coverage.test") check_tests_valid("coverage.argumentPassing") + check_tests_valid("coverage.datamodel") check_tests_valid("variable-capture.in") check_tests_valid("variable-capture.nonlocal") check_tests_valid("variable-capture.dict") From 7d8c0c663f39ef8d2e15ea894b4723105810d1ec Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Fri, 3 Jun 2022 18:33:44 +0200 Subject: [PATCH 016/796] Python: Remove `dataflow/coverage/dataflow.ql` The selected edges is covered by `NormalDataflowTest.ql` now... and reading the test-output changes in `edges` is just going to make commits larger while not providing any real value. --- .../dataflow/coverage/dataflow.expected | 985 ------------------ .../dataflow/coverage/dataflow.ql | 11 - 2 files changed, 996 deletions(-) delete mode 100644 python/ql/test/experimental/dataflow/coverage/dataflow.expected delete mode 100644 python/ql/test/experimental/dataflow/coverage/dataflow.ql diff --git a/python/ql/test/experimental/dataflow/coverage/dataflow.expected b/python/ql/test/experimental/dataflow/coverage/dataflow.expected deleted file mode 100644 index 9321d941ad8..00000000000 --- a/python/ql/test/experimental/dataflow/coverage/dataflow.expected +++ /dev/null @@ -1,985 +0,0 @@ -edges -| datamodel.py:35:7:35:7 | ControlFlowNode for a | datamodel.py:36:10:36:10 | ControlFlowNode for a | -| datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:35:7:35:7 | ControlFlowNode for a | -| datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:38:6:38:17 | ControlFlowNode for f() | -| datamodel.py:44:22:44:22 | ControlFlowNode for x | datamodel.py:46:16:46:16 | ControlFlowNode for x | -| datamodel.py:49:26:49:26 | ControlFlowNode for x | datamodel.py:50:16:50:16 | ControlFlowNode for x | -| datamodel.py:53:22:53:22 | ControlFlowNode for x | datamodel.py:54:16:54:16 | ControlFlowNode for x | -| datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:44:22:44:22 | ControlFlowNode for x | -| datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | -| datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:44:22:44:22 | ControlFlowNode for x | -| datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | -| datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:49:26:49:26 | ControlFlowNode for x | -| datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | -| datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:49:26:49:26 | ControlFlowNode for x | -| datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | -| datamodel.py:88:21:88:26 | ControlFlowNode for SOURCE | datamodel.py:53:22:53:22 | ControlFlowNode for x | -| datamodel.py:88:21:88:26 | ControlFlowNode for SOURCE | datamodel.py:88:6:88:27 | ControlFlowNode for Attribute() | -| datamodel.py:89:21:89:26 | ControlFlowNode for SOURCE | datamodel.py:53:22:53:22 | ControlFlowNode for x | -| datamodel.py:89:21:89:26 | ControlFlowNode for SOURCE | datamodel.py:89:6:89:27 | ControlFlowNode for Attribute() | -| datamodel.py:161:5:161:8 | [post store] ControlFlowNode for self [Attribute b] | datamodel.py:164:14:164:25 | ControlFlowNode for Customized() [Attribute b] | -| datamodel.py:161:14:161:19 | ControlFlowNode for SOURCE | datamodel.py:161:5:161:8 | [post store] ControlFlowNode for self [Attribute b] | -| datamodel.py:164:14:164:25 | ControlFlowNode for Customized() [Attribute b] | datamodel.py:168:6:168:15 | ControlFlowNode for customized [Attribute b] | -| datamodel.py:168:6:168:15 | ControlFlowNode for customized [Attribute b] | datamodel.py:168:6:168:17 | ControlFlowNode for Attribute | -| test.py:42:10:42:26 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:43:9:43:9 | ControlFlowNode for x [Tuple element at index 1] | -| test.py:42:21:42:26 | ControlFlowNode for SOURCE | test.py:42:10:42:26 | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:43:9:43:9 | ControlFlowNode for x [Tuple element at index 1] | test.py:43:9:43:12 | ControlFlowNode for Subscript | -| test.py:43:9:43:12 | ControlFlowNode for Subscript | test.py:44:10:44:10 | ControlFlowNode for y | -| test.py:55:9:55:14 | ControlFlowNode for SOURCE | test.py:56:10:56:10 | ControlFlowNode for x | -| test.py:61:9:61:16 | ControlFlowNode for Str | test.py:62:10:62:10 | ControlFlowNode for x | -| test.py:66:9:66:17 | ControlFlowNode for Str | test.py:67:10:67:10 | ControlFlowNode for x | -| test.py:71:9:71:10 | ControlFlowNode for IntegerLiteral | test.py:72:10:72:10 | ControlFlowNode for x | -| test.py:76:9:76:12 | ControlFlowNode for FloatLiteral | test.py:77:10:77:10 | ControlFlowNode for x | -| test.py:87:10:87:15 | ControlFlowNode for SOURCE | test.py:88:10:88:10 | ControlFlowNode for x | -| test.py:93:9:93:16 | ControlFlowNode for List [List element] | test.py:94:10:94:10 | ControlFlowNode for x [List element] | -| test.py:93:10:93:15 | ControlFlowNode for SOURCE | test.py:93:9:93:16 | ControlFlowNode for List [List element] | -| test.py:94:10:94:10 | ControlFlowNode for x [List element] | test.py:94:10:94:13 | ControlFlowNode for Subscript | -| test.py:103:9:103:37 | ControlFlowNode for ListComp [List element] | test.py:104:10:104:10 | ControlFlowNode for x [List element] | -| test.py:103:10:103:15 | ControlFlowNode for SOURCE | test.py:103:9:103:37 | ControlFlowNode for ListComp [List element] | -| test.py:104:10:104:10 | ControlFlowNode for x [List element] | test.py:104:10:104:13 | ControlFlowNode for Subscript | -| test.py:108:9:108:29 | ControlFlowNode for ListComp [List element] | test.py:109:10:109:10 | ControlFlowNode for x [List element] | -| test.py:108:10:108:10 | ControlFlowNode for y | test.py:108:9:108:29 | ControlFlowNode for ListComp [List element] | -| test.py:108:16:108:16 | SSA variable y | test.py:108:10:108:10 | ControlFlowNode for y | -| test.py:108:21:108:28 | ControlFlowNode for List [List element] | test.py:108:16:108:16 | SSA variable y | -| test.py:108:22:108:27 | ControlFlowNode for SOURCE | test.py:108:21:108:28 | ControlFlowNode for List [List element] | -| test.py:109:10:109:10 | ControlFlowNode for x [List element] | test.py:109:10:109:13 | ControlFlowNode for Subscript | -| test.py:113:9:113:16 | ControlFlowNode for List [List element] | test.py:114:21:114:21 | ControlFlowNode for l [List element] | -| test.py:113:10:113:15 | ControlFlowNode for SOURCE | test.py:113:9:113:16 | ControlFlowNode for List [List element] | -| test.py:114:9:114:22 | ControlFlowNode for ListComp [List element] | test.py:115:10:115:10 | ControlFlowNode for x [List element] | -| test.py:114:10:114:10 | ControlFlowNode for y | test.py:114:9:114:22 | ControlFlowNode for ListComp [List element] | -| test.py:114:16:114:16 | SSA variable y | test.py:114:10:114:10 | ControlFlowNode for y | -| test.py:114:21:114:21 | ControlFlowNode for l [List element] | test.py:114:16:114:16 | SSA variable y | -| test.py:115:10:115:10 | ControlFlowNode for x [List element] | test.py:115:10:115:13 | ControlFlowNode for Subscript | -| test.py:125:9:125:16 | ControlFlowNode for Set [Set element] | test.py:126:10:126:10 | ControlFlowNode for x [Set element] | -| test.py:125:10:125:15 | ControlFlowNode for SOURCE | test.py:125:9:125:16 | ControlFlowNode for Set [Set element] | -| test.py:126:10:126:10 | ControlFlowNode for x [Set element] | test.py:126:10:126:16 | ControlFlowNode for Attribute() | -| test.py:130:9:130:37 | ControlFlowNode for SetComp [Set element] | test.py:131:10:131:10 | ControlFlowNode for x [Set element] | -| test.py:130:10:130:15 | ControlFlowNode for SOURCE | test.py:130:9:130:37 | ControlFlowNode for SetComp [Set element] | -| test.py:131:10:131:10 | ControlFlowNode for x [Set element] | test.py:131:10:131:16 | ControlFlowNode for Attribute() | -| test.py:135:9:135:29 | ControlFlowNode for SetComp [Set element] | test.py:136:10:136:10 | ControlFlowNode for x [Set element] | -| test.py:135:10:135:10 | ControlFlowNode for y | test.py:135:9:135:29 | ControlFlowNode for SetComp [Set element] | -| test.py:135:16:135:16 | SSA variable y | test.py:135:10:135:10 | ControlFlowNode for y | -| test.py:135:21:135:28 | ControlFlowNode for List [List element] | test.py:135:16:135:16 | SSA variable y | -| test.py:135:22:135:27 | ControlFlowNode for SOURCE | test.py:135:21:135:28 | ControlFlowNode for List [List element] | -| test.py:136:10:136:10 | ControlFlowNode for x [Set element] | test.py:136:10:136:16 | ControlFlowNode for Attribute() | -| test.py:140:9:140:16 | ControlFlowNode for Set [Set element] | test.py:141:21:141:21 | ControlFlowNode for l [Set element] | -| test.py:140:10:140:15 | ControlFlowNode for SOURCE | test.py:140:9:140:16 | ControlFlowNode for Set [Set element] | -| test.py:141:9:141:22 | ControlFlowNode for SetComp [Set element] | test.py:142:10:142:10 | ControlFlowNode for x [Set element] | -| test.py:141:10:141:10 | ControlFlowNode for y | test.py:141:9:141:22 | ControlFlowNode for SetComp [Set element] | -| test.py:141:16:141:16 | SSA variable y | test.py:141:10:141:10 | ControlFlowNode for y | -| test.py:141:21:141:21 | ControlFlowNode for l [Set element] | test.py:141:16:141:16 | SSA variable y | -| test.py:142:10:142:10 | ControlFlowNode for x [Set element] | test.py:142:10:142:16 | ControlFlowNode for Attribute() | -| test.py:152:9:152:21 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:153:10:153:10 | ControlFlowNode for x [Dictionary element at key s] | -| test.py:152:15:152:20 | ControlFlowNode for SOURCE | test.py:152:9:152:21 | ControlFlowNode for Dict [Dictionary element at key s] | -| test.py:153:10:153:10 | ControlFlowNode for x [Dictionary element at key s] | test.py:153:10:153:15 | ControlFlowNode for Subscript | -| test.py:157:9:157:21 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:158:10:158:10 | ControlFlowNode for x [Dictionary element at key s] | -| test.py:157:15:157:20 | ControlFlowNode for SOURCE | test.py:157:9:157:21 | ControlFlowNode for Dict [Dictionary element at key s] | -| test.py:158:10:158:10 | ControlFlowNode for x [Dictionary element at key s] | test.py:158:10:158:19 | ControlFlowNode for Attribute() | -| test.py:183:9:183:42 | ControlFlowNode for ListComp [List element] | test.py:184:10:184:10 | ControlFlowNode for x [List element] | -| test.py:183:10:183:10 | ControlFlowNode for y | test.py:183:9:183:42 | ControlFlowNode for ListComp [List element] | -| test.py:183:16:183:16 | SSA variable z [List element] | test.py:183:41:183:41 | ControlFlowNode for z [List element] | -| test.py:183:21:183:30 | ControlFlowNode for List [List element, List element] | test.py:183:16:183:16 | SSA variable z [List element] | -| test.py:183:22:183:29 | ControlFlowNode for List [List element] | test.py:183:21:183:30 | ControlFlowNode for List [List element, List element] | -| test.py:183:23:183:28 | ControlFlowNode for SOURCE | test.py:183:22:183:29 | ControlFlowNode for List [List element] | -| test.py:183:36:183:36 | SSA variable y | test.py:183:10:183:10 | ControlFlowNode for y | -| test.py:183:41:183:41 | ControlFlowNode for z [List element] | test.py:183:36:183:36 | SSA variable y | -| test.py:184:10:184:10 | ControlFlowNode for x [List element] | test.py:184:10:184:13 | ControlFlowNode for Subscript | -| test.py:188:9:188:68 | ControlFlowNode for ListComp [List element] | test.py:189:10:189:10 | ControlFlowNode for x [List element] | -| test.py:188:10:188:10 | ControlFlowNode for y | test.py:188:9:188:68 | ControlFlowNode for ListComp [List element] | -| test.py:188:16:188:16 | SSA variable v [List element, List element, List element] | test.py:188:45:188:45 | ControlFlowNode for v [List element, List element, List element] | -| test.py:188:21:188:34 | ControlFlowNode for List [List element, List element, List element, List element] | test.py:188:16:188:16 | SSA variable v [List element, List element, List element] | -| test.py:188:22:188:33 | ControlFlowNode for List [List element, List element, List element] | test.py:188:21:188:34 | ControlFlowNode for List [List element, List element, List element, List element] | -| test.py:188:23:188:32 | ControlFlowNode for List [List element, List element] | test.py:188:22:188:33 | ControlFlowNode for List [List element, List element, List element] | -| test.py:188:24:188:31 | ControlFlowNode for List [List element] | test.py:188:23:188:32 | ControlFlowNode for List [List element, List element] | -| test.py:188:25:188:30 | ControlFlowNode for SOURCE | test.py:188:24:188:31 | ControlFlowNode for List [List element] | -| test.py:188:40:188:40 | SSA variable u [List element, List element] | test.py:188:56:188:56 | ControlFlowNode for u [List element, List element] | -| test.py:188:45:188:45 | ControlFlowNode for v [List element, List element, List element] | test.py:188:40:188:40 | SSA variable u [List element, List element] | -| test.py:188:51:188:51 | SSA variable z [List element] | test.py:188:67:188:67 | ControlFlowNode for z [List element] | -| test.py:188:56:188:56 | ControlFlowNode for u [List element, List element] | test.py:188:51:188:51 | SSA variable z [List element] | -| test.py:188:62:188:62 | SSA variable y | test.py:188:10:188:10 | ControlFlowNode for y | -| test.py:188:67:188:67 | ControlFlowNode for z [List element] | test.py:188:62:188:62 | SSA variable y | -| test.py:189:10:189:10 | ControlFlowNode for x [List element] | test.py:189:10:189:13 | ControlFlowNode for Subscript | -| test.py:199:9:199:42 | ControlFlowNode for ListComp [List element] | test.py:200:10:200:10 | ControlFlowNode for x [List element] | -| test.py:199:10:199:10 | ControlFlowNode for y | test.py:199:9:199:42 | ControlFlowNode for ListComp [List element] | -| test.py:199:16:199:16 | SSA variable y | test.py:199:10:199:10 | ControlFlowNode for y | -| test.py:199:22:199:22 | ControlFlowNode for z | test.py:199:22:199:40 | ControlFlowNode for GeneratorExp [List element] | -| test.py:199:22:199:40 | ControlFlowNode for GeneratorExp [List element] | test.py:199:16:199:16 | SSA variable y | -| test.py:199:28:199:28 | SSA variable z | test.py:199:22:199:22 | ControlFlowNode for z | -| test.py:199:33:199:40 | ControlFlowNode for List [List element] | test.py:199:28:199:28 | SSA variable z | -| test.py:199:34:199:39 | ControlFlowNode for SOURCE | test.py:199:33:199:40 | ControlFlowNode for List [List element] | -| test.py:200:10:200:10 | ControlFlowNode for x [List element] | test.py:200:10:200:13 | ControlFlowNode for Subscript | -| test.py:205:9:205:47 | ControlFlowNode for ListComp [List element] | test.py:206:10:206:10 | ControlFlowNode for x [List element] | -| test.py:205:10:205:10 | ControlFlowNode for a | test.py:205:9:205:47 | ControlFlowNode for ListComp [List element] | -| test.py:205:17:205:17 | SSA variable a | test.py:205:10:205:10 | ControlFlowNode for a | -| test.py:205:17:205:20 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:205:17:205:17 | SSA variable a | -| test.py:205:17:205:20 | IterableSequence [Tuple element at index 0] | test.py:205:17:205:20 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:205:26:205:46 | ControlFlowNode for List [List element, Tuple element at index 0] | test.py:205:17:205:20 | IterableSequence [Tuple element at index 0] | -| test.py:205:28:205:33 | ControlFlowNode for SOURCE | test.py:205:28:205:44 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:205:28:205:44 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:205:26:205:46 | ControlFlowNode for List [List element, Tuple element at index 0] | -| test.py:206:10:206:10 | ControlFlowNode for x [List element] | test.py:206:10:206:13 | ControlFlowNode for Subscript | -| test.py:210:9:210:51 | ControlFlowNode for ListComp [List element] | test.py:211:10:211:10 | ControlFlowNode for x [List element] | -| test.py:210:10:210:10 | ControlFlowNode for a [List element] | test.py:210:10:210:13 | ControlFlowNode for Subscript | -| test.py:210:10:210:13 | ControlFlowNode for Subscript | test.py:210:9:210:51 | ControlFlowNode for ListComp [List element] | -| test.py:210:20:210:21 | IterableElement | test.py:210:20:210:21 | SSA variable a [List element] | -| test.py:210:20:210:21 | SSA variable a [List element] | test.py:210:10:210:10 | ControlFlowNode for a [List element] | -| test.py:210:20:210:24 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:210:20:210:21 | IterableElement | -| test.py:210:20:210:24 | IterableSequence [Tuple element at index 0] | test.py:210:20:210:24 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:210:30:210:50 | ControlFlowNode for List [List element, Tuple element at index 0] | test.py:210:20:210:24 | IterableSequence [Tuple element at index 0] | -| test.py:210:32:210:37 | ControlFlowNode for SOURCE | test.py:210:32:210:48 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:210:32:210:48 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:210:30:210:50 | ControlFlowNode for List [List element, Tuple element at index 0] | -| test.py:211:10:211:10 | ControlFlowNode for x [List element] | test.py:211:10:211:13 | ControlFlowNode for Subscript | -| test.py:349:11:349:16 | ControlFlowNode for SOURCE | test.py:349:11:349:17 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:349:11:349:17 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:349:10:349:21 | ControlFlowNode for Subscript | -| test.py:353:10:353:17 | ControlFlowNode for List [List element] | test.py:353:10:353:20 | ControlFlowNode for Subscript | -| test.py:353:11:353:16 | ControlFlowNode for SOURCE | test.py:353:10:353:17 | ControlFlowNode for List [List element] | -| test.py:357:10:357:22 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:357:10:357:27 | ControlFlowNode for Subscript | -| test.py:357:16:357:21 | ControlFlowNode for SOURCE | test.py:357:10:357:22 | ControlFlowNode for Dict [Dictionary element at key s] | -| test.py:375:15:375:15 | ControlFlowNode for b | test.py:376:12:376:12 | ControlFlowNode for b | -| test.py:380:28:380:33 | ControlFlowNode for SOURCE | test.py:375:15:375:15 | ControlFlowNode for b | -| test.py:380:28:380:33 | ControlFlowNode for SOURCE | test.py:380:10:380:34 | ControlFlowNode for second() | -| test.py:388:30:388:35 | ControlFlowNode for SOURCE | test.py:375:15:375:15 | ControlFlowNode for b | -| test.py:388:30:388:35 | ControlFlowNode for SOURCE | test.py:388:10:388:36 | ControlFlowNode for second() | -| test.py:396:10:396:43 | KwUnpacked b | test.py:375:15:375:15 | ControlFlowNode for b | -| test.py:396:10:396:43 | KwUnpacked b | test.py:396:10:396:43 | ControlFlowNode for second() | -| test.py:396:30:396:42 | ControlFlowNode for Dict [Dictionary element at key b] | test.py:396:10:396:43 | KwUnpacked b | -| test.py:396:36:396:41 | ControlFlowNode for SOURCE | test.py:396:30:396:42 | ControlFlowNode for Dict [Dictionary element at key b] | -| test.py:399:21:399:21 | ControlFlowNode for b [Tuple element at index 0] | test.py:400:12:400:12 | ControlFlowNode for b [Tuple element at index 0] | -| test.py:400:12:400:12 | ControlFlowNode for b [Tuple element at index 0] | test.py:400:12:400:15 | ControlFlowNode for Subscript | -| test.py:404:10:404:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:399:21:399:21 | ControlFlowNode for b [Tuple element at index 0] | -| test.py:404:10:404:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:404:10:404:39 | ControlFlowNode for f_extra_pos() | -| test.py:404:33:404:38 | ControlFlowNode for SOURCE | test.py:404:10:404:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | -| test.py:407:26:407:26 | ControlFlowNode for b [Dictionary element at key b] | test.py:408:12:408:12 | ControlFlowNode for b [Dictionary element at key b] | -| test.py:408:12:408:12 | ControlFlowNode for b [Dictionary element at key b] | test.py:408:12:408:17 | ControlFlowNode for Subscript | -| test.py:412:10:412:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:407:26:407:26 | ControlFlowNode for b [Dictionary element at key b] | -| test.py:412:10:412:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:412:10:412:45 | ControlFlowNode for f_extra_keyword() | -| test.py:412:39:412:44 | ControlFlowNode for SOURCE | test.py:412:10:412:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | -| test.py:429:15:429:20 | ControlFlowNode for SOURCE | test.py:429:10:429:20 | ControlFlowNode for BoolExpr | -| test.py:434:16:434:21 | ControlFlowNode for SOURCE | test.py:434:10:434:21 | ControlFlowNode for BoolExpr | -| test.py:445:10:445:15 | ControlFlowNode for SOURCE | test.py:445:10:445:38 | ControlFlowNode for IfExp | -| test.py:453:34:453:39 | ControlFlowNode for SOURCE | test.py:453:10:453:39 | ControlFlowNode for IfExp | -| test.py:474:11:474:11 | ControlFlowNode for x | test.py:475:16:475:16 | ControlFlowNode for x | -| test.py:477:12:477:17 | ControlFlowNode for SOURCE | test.py:474:11:474:11 | ControlFlowNode for x | -| test.py:477:12:477:17 | ControlFlowNode for SOURCE | test.py:477:10:477:18 | ControlFlowNode for f() | -| test.py:481:19:481:19 | ControlFlowNode for b | test.py:482:16:482:16 | ControlFlowNode for b | -| test.py:484:28:484:33 | ControlFlowNode for SOURCE | test.py:481:19:481:19 | ControlFlowNode for b | -| test.py:484:28:484:33 | ControlFlowNode for SOURCE | test.py:484:10:484:34 | ControlFlowNode for second() | -| test.py:495:19:495:19 | ControlFlowNode for b | test.py:496:16:496:16 | ControlFlowNode for b | -| test.py:498:30:498:35 | ControlFlowNode for SOURCE | test.py:495:19:495:19 | ControlFlowNode for b | -| test.py:498:30:498:35 | ControlFlowNode for SOURCE | test.py:498:10:498:36 | ControlFlowNode for second() | -| test.py:509:19:509:19 | ControlFlowNode for b | test.py:510:16:510:16 | ControlFlowNode for b | -| test.py:512:10:512:43 | KwUnpacked b | test.py:509:19:509:19 | ControlFlowNode for b | -| test.py:512:10:512:43 | KwUnpacked b | test.py:512:10:512:43 | ControlFlowNode for second() | -| test.py:512:30:512:42 | ControlFlowNode for Dict [Dictionary element at key b] | test.py:512:10:512:43 | KwUnpacked b | -| test.py:512:36:512:41 | ControlFlowNode for SOURCE | test.py:512:30:512:42 | ControlFlowNode for Dict [Dictionary element at key b] | -| test.py:516:30:516:30 | ControlFlowNode for b [Tuple element at index 0] | test.py:516:33:516:33 | ControlFlowNode for b [Tuple element at index 0] | -| test.py:516:33:516:33 | ControlFlowNode for b [Tuple element at index 0] | test.py:516:33:516:36 | ControlFlowNode for Subscript | -| test.py:517:10:517:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:516:30:516:30 | ControlFlowNode for b [Tuple element at index 0] | -| test.py:517:10:517:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:517:10:517:39 | ControlFlowNode for f_extra_pos() | -| test.py:517:33:517:38 | ControlFlowNode for SOURCE | test.py:517:10:517:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | -| test.py:521:35:521:35 | ControlFlowNode for b [Dictionary element at key b] | test.py:521:38:521:38 | ControlFlowNode for b [Dictionary element at key b] | -| test.py:521:38:521:38 | ControlFlowNode for b [Dictionary element at key b] | test.py:521:38:521:43 | ControlFlowNode for Subscript | -| test.py:522:10:522:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:521:35:521:35 | ControlFlowNode for b [Dictionary element at key b] | -| test.py:522:10:522:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:522:10:522:45 | ControlFlowNode for f_extra_keyword() | -| test.py:522:39:522:44 | ControlFlowNode for SOURCE | test.py:522:10:522:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | -| test.py:534:9:534:14 | ControlFlowNode for SOURCE | test.py:536:10:536:10 | ControlFlowNode for a | -| test.py:534:9:534:14 | ControlFlowNode for SOURCE | test.py:541:10:541:10 | ControlFlowNode for b | -| test.py:546:10:546:15 | ControlFlowNode for SOURCE | test.py:546:10:546:26 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:546:10:546:26 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:547:5:547:8 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:547:5:547:5 | SSA variable a | test.py:548:10:548:10 | ControlFlowNode for a | -| test.py:547:5:547:8 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:547:5:547:5 | SSA variable a | -| test.py:554:10:554:15 | ControlFlowNode for SOURCE | test.py:554:10:554:36 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:554:10:554:36 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:555:5:555:13 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:554:10:554:36 | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 1] | test.py:555:5:555:13 | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 1] | -| test.py:554:19:554:35 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:554:10:554:36 | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 1] | -| test.py:554:30:554:35 | ControlFlowNode for SOURCE | test.py:554:19:554:35 | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:555:5:555:5 | SSA variable a | test.py:556:10:556:10 | ControlFlowNode for a | -| test.py:555:5:555:13 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:555:5:555:5 | SSA variable a | -| test.py:555:5:555:13 | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 1] | test.py:555:9:555:12 | IterableSequence [Tuple element at index 1] | -| test.py:555:9:555:12 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:555:12:555:12 | SSA variable c | -| test.py:555:9:555:12 | IterableSequence [Tuple element at index 1] | test.py:555:9:555:12 | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:555:12:555:12 | SSA variable c | test.py:558:10:558:10 | ControlFlowNode for c | -| test.py:563:9:563:33 | ControlFlowNode for List [List element, List element, List element, List element] | test.py:564:5:564:14 | IterableSequence [List element, List element, List element, List element] | -| test.py:563:10:563:21 | ControlFlowNode for List [List element, List element, List element] | test.py:563:9:563:33 | ControlFlowNode for List [List element, List element, List element, List element] | -| test.py:563:11:563:20 | ControlFlowNode for List [List element, List element] | test.py:563:10:563:21 | ControlFlowNode for List [List element, List element, List element] | -| test.py:563:12:563:19 | ControlFlowNode for List [List element] | test.py:563:11:563:20 | ControlFlowNode for List [List element, List element] | -| test.py:563:13:563:18 | ControlFlowNode for SOURCE | test.py:563:12:563:19 | ControlFlowNode for List [List element] | -| test.py:564:5:564:11 | ControlFlowNode for List [Tuple element at index 0, List element, List element] | test.py:564:6:564:10 | IterableSequence [List element, List element] | -| test.py:564:5:564:11 | IterableElement [List element, List element] | test.py:564:5:564:11 | ControlFlowNode for List [Tuple element at index 0, List element, List element] | -| test.py:564:5:564:11 | IterableSequence [List element, List element, List element] | test.py:564:5:564:11 | IterableElement [List element, List element] | -| test.py:564:5:564:14 | ControlFlowNode for Tuple [Tuple element at index 0, List element, List element, List element] | test.py:564:5:564:11 | IterableSequence [List element, List element, List element] | -| test.py:564:5:564:14 | IterableElement [List element, List element, List element] | test.py:564:5:564:14 | ControlFlowNode for Tuple [Tuple element at index 0, List element, List element, List element] | -| test.py:564:5:564:14 | IterableSequence [List element, List element, List element, List element] | test.py:564:5:564:14 | IterableElement [List element, List element, List element] | -| test.py:564:6:564:10 | ControlFlowNode for List [Tuple element at index 0, List element] | test.py:564:7:564:9 | IterableSequence [List element] | -| test.py:564:6:564:10 | IterableElement [List element] | test.py:564:6:564:10 | ControlFlowNode for List [Tuple element at index 0, List element] | -| test.py:564:6:564:10 | IterableSequence [List element, List element] | test.py:564:6:564:10 | IterableElement [List element] | -| test.py:564:7:564:9 | ControlFlowNode for List [Tuple element at index 0] | test.py:564:8:564:8 | SSA variable a | -| test.py:564:7:564:9 | IterableElement | test.py:564:7:564:9 | ControlFlowNode for List [Tuple element at index 0] | -| test.py:564:7:564:9 | IterableSequence [List element] | test.py:564:7:564:9 | IterableElement | -| test.py:564:8:564:8 | SSA variable a | test.py:565:10:565:10 | ControlFlowNode for a | -| test.py:571:10:571:15 | ControlFlowNode for SOURCE | test.py:571:10:571:34 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:571:10:571:34 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:572:5:572:12 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:571:10:571:34 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:572:5:572:12 | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:571:18:571:23 | ControlFlowNode for SOURCE | test.py:571:10:571:34 | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:572:5:572:5 | SSA variable a | test.py:573:10:573:10 | ControlFlowNode for a | -| test.py:572:5:572:12 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:572:5:572:5 | SSA variable a | -| test.py:572:5:572:12 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:572:8:572:9 | IterableElement | -| test.py:572:5:572:12 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:572:12:572:12 | SSA variable c | -| test.py:572:8:572:9 | IterableElement | test.py:572:8:572:9 | SSA variable b [List element] | -| test.py:572:8:572:9 | SSA variable b [List element] | test.py:575:10:575:10 | ControlFlowNode for b [List element] | -| test.py:572:12:572:12 | SSA variable c | test.py:576:12:576:12 | ControlFlowNode for c | -| test.py:575:10:575:10 | ControlFlowNode for b [List element] | test.py:575:10:575:13 | ControlFlowNode for Subscript | -| test.py:581:10:581:15 | ControlFlowNode for SOURCE | test.py:581:10:581:23 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:581:10:581:23 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:582:5:582:12 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:581:10:581:23 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:582:5:582:12 | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:581:18:581:23 | ControlFlowNode for SOURCE | test.py:581:10:581:23 | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:582:5:582:5 | SSA variable a | test.py:583:10:583:10 | ControlFlowNode for a | -| test.py:582:5:582:12 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:582:5:582:5 | SSA variable a | -| test.py:582:5:582:12 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:582:12:582:12 | SSA variable c | -| test.py:582:12:582:12 | SSA variable c | test.py:585:10:585:10 | ControlFlowNode for c | -| test.py:590:10:590:61 | ControlFlowNode for List [List element, List element] | test.py:593:6:593:23 | IterableSequence [List element, List element] | -| test.py:590:10:590:61 | ControlFlowNode for List [List element, List element] | test.py:601:5:601:24 | IterableSequence [List element, List element] | -| test.py:590:10:590:61 | ControlFlowNode for List [List element, List element] | test.py:609:6:609:23 | IterableSequence [List element, List element] | -| test.py:590:11:590:37 | ControlFlowNode for List [List element] | test.py:590:10:590:61 | ControlFlowNode for List [List element, List element] | -| test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:590:11:590:37 | ControlFlowNode for List [List element] | -| test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:590:11:590:37 | ControlFlowNode for List [List element] | -| test.py:590:40:590:47 | ControlFlowNode for List [List element] | test.py:590:10:590:61 | ControlFlowNode for List [List element, List element] | -| test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:590:40:590:47 | ControlFlowNode for List [List element] | -| test.py:593:6:593:23 | ControlFlowNode for Tuple [Tuple element at index 0, List element] | test.py:593:7:593:16 | IterableSequence [List element] | -| test.py:593:6:593:23 | IterableElement [List element] | test.py:593:6:593:23 | ControlFlowNode for Tuple [Tuple element at index 0, List element] | -| test.py:593:6:593:23 | IterableSequence [List element, List element] | test.py:593:6:593:23 | IterableElement [List element] | -| test.py:593:7:593:8 | SSA variable a1 | test.py:594:10:594:11 | ControlFlowNode for a1 | -| test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:593:7:593:8 | SSA variable a1 | -| test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:593:11:593:12 | SSA variable a2 | -| test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 2] | test.py:593:15:593:16 | SSA variable a3 | -| test.py:593:7:593:16 | IterableElement | test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:593:7:593:16 | IterableElement | test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:593:7:593:16 | IterableElement | test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 2] | -| test.py:593:7:593:16 | IterableSequence [List element] | test.py:593:7:593:16 | IterableElement | -| test.py:593:11:593:12 | SSA variable a2 | test.py:595:12:595:13 | ControlFlowNode for a2 | -| test.py:593:15:593:16 | SSA variable a3 | test.py:596:10:596:11 | ControlFlowNode for a3 | -| test.py:601:5:601:24 | ControlFlowNode for List [Tuple element at index 0, List element] | test.py:601:7:601:16 | IterableSequence [List element] | -| test.py:601:5:601:24 | IterableElement [List element] | test.py:601:5:601:24 | ControlFlowNode for List [Tuple element at index 0, List element] | -| test.py:601:5:601:24 | IterableSequence [List element, List element] | test.py:601:5:601:24 | IterableElement [List element] | -| test.py:601:7:601:8 | SSA variable a1 | test.py:602:10:602:11 | ControlFlowNode for a1 | -| test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:601:7:601:8 | SSA variable a1 | -| test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:601:11:601:12 | SSA variable a2 | -| test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 2] | test.py:601:15:601:16 | SSA variable a3 | -| test.py:601:7:601:16 | IterableElement | test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:601:7:601:16 | IterableElement | test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:601:7:601:16 | IterableElement | test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 2] | -| test.py:601:7:601:16 | IterableSequence [List element] | test.py:601:7:601:16 | IterableElement | -| test.py:601:11:601:12 | SSA variable a2 | test.py:603:12:603:13 | ControlFlowNode for a2 | -| test.py:601:15:601:16 | SSA variable a3 | test.py:604:10:604:11 | ControlFlowNode for a3 | -| test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 0] | test.py:609:7:609:8 | SSA variable a1 | -| test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 1] | test.py:609:11:609:12 | SSA variable a2 | -| test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 2] | test.py:609:15:609:16 | SSA variable a3 | -| test.py:609:6:609:17 | IterableElement | test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 0] | -| test.py:609:6:609:17 | IterableElement | test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 1] | -| test.py:609:6:609:17 | IterableElement | test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 2] | -| test.py:609:6:609:17 | IterableSequence [List element] | test.py:609:6:609:17 | IterableElement | -| test.py:609:6:609:23 | ControlFlowNode for Tuple [Tuple element at index 0, List element] | test.py:609:6:609:17 | IterableSequence [List element] | -| test.py:609:6:609:23 | IterableElement [List element] | test.py:609:6:609:23 | ControlFlowNode for Tuple [Tuple element at index 0, List element] | -| test.py:609:6:609:23 | IterableSequence [List element, List element] | test.py:609:6:609:23 | IterableElement [List element] | -| test.py:609:7:609:8 | SSA variable a1 | test.py:610:10:610:11 | ControlFlowNode for a1 | -| test.py:609:11:609:12 | SSA variable a2 | test.py:611:12:611:13 | ControlFlowNode for a2 | -| test.py:609:15:609:16 | SSA variable a3 | test.py:612:10:612:11 | ControlFlowNode for a3 | -| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | test.py:621:5:621:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 0] | -| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | test.py:630:6:630:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | -| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | test.py:639:5:639:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 0] | -| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | test.py:648:6:648:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | -| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | test.py:621:5:621:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 2] | -| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | test.py:630:6:630:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | -| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | test.py:639:5:639:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 2] | -| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | test.py:648:6:648:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | -| test.py:618:12:618:17 | ControlFlowNode for SOURCE | test.py:618:12:618:36 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:618:12:618:36 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | -| test.py:618:12:618:36 | ControlFlowNode for Tuple [Tuple element at index 2] | test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | -| test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:618:12:618:36 | ControlFlowNode for Tuple [Tuple element at index 2] | -| test.py:621:5:621:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 0] | test.py:621:6:621:14 | IterableSequence [Tuple element at index 0] | -| test.py:621:5:621:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 2] | test.py:621:6:621:14 | IterableSequence [Tuple element at index 2] | -| test.py:621:6:621:14 | ControlFlowNode for List [Tuple element at index 0] | test.py:621:7:621:8 | SSA variable a1 | -| test.py:621:6:621:14 | ControlFlowNode for List [Tuple element at index 2] | test.py:621:11:621:13 | IterableElement | -| test.py:621:6:621:14 | IterableSequence [Tuple element at index 0] | test.py:621:6:621:14 | ControlFlowNode for List [Tuple element at index 0] | -| test.py:621:6:621:14 | IterableSequence [Tuple element at index 2] | test.py:621:6:621:14 | ControlFlowNode for List [Tuple element at index 2] | -| test.py:621:7:621:8 | SSA variable a1 | test.py:622:10:622:11 | ControlFlowNode for a1 | -| test.py:621:11:621:13 | IterableElement | test.py:621:11:621:13 | SSA variable a2 [List element] | -| test.py:621:11:621:13 | SSA variable a2 [List element] | test.py:624:12:624:13 | ControlFlowNode for a2 [List element] | -| test.py:621:11:621:13 | SSA variable a2 [List element] | test.py:625:10:625:11 | ControlFlowNode for a2 [List element] | -| test.py:624:12:624:13 | ControlFlowNode for a2 [List element] | test.py:624:12:624:16 | ControlFlowNode for Subscript | -| test.py:625:10:625:11 | ControlFlowNode for a2 [List element] | test.py:625:10:625:14 | ControlFlowNode for Subscript | -| test.py:630:6:630:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | test.py:630:7:630:13 | IterableSequence [Tuple element at index 0] | -| test.py:630:6:630:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | test.py:630:7:630:13 | IterableSequence [Tuple element at index 2] | -| test.py:630:7:630:8 | SSA variable a1 | test.py:631:10:631:11 | ControlFlowNode for a1 | -| test.py:630:7:630:13 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:630:7:630:8 | SSA variable a1 | -| test.py:630:7:630:13 | ControlFlowNode for Tuple [Tuple element at index 2] | test.py:630:11:630:13 | IterableElement | -| test.py:630:7:630:13 | IterableSequence [Tuple element at index 0] | test.py:630:7:630:13 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:630:7:630:13 | IterableSequence [Tuple element at index 2] | test.py:630:7:630:13 | ControlFlowNode for Tuple [Tuple element at index 2] | -| test.py:630:11:630:13 | IterableElement | test.py:630:11:630:13 | SSA variable a2 [List element] | -| test.py:630:11:630:13 | SSA variable a2 [List element] | test.py:633:12:633:13 | ControlFlowNode for a2 [List element] | -| test.py:630:11:630:13 | SSA variable a2 [List element] | test.py:634:10:634:11 | ControlFlowNode for a2 [List element] | -| test.py:633:12:633:13 | ControlFlowNode for a2 [List element] | test.py:633:12:633:16 | ControlFlowNode for Subscript | -| test.py:634:10:634:11 | ControlFlowNode for a2 [List element] | test.py:634:10:634:14 | ControlFlowNode for Subscript | -| test.py:639:5:639:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 0] | test.py:639:7:639:13 | IterableSequence [Tuple element at index 0] | -| test.py:639:5:639:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 2] | test.py:639:7:639:13 | IterableSequence [Tuple element at index 2] | -| test.py:639:7:639:8 | SSA variable a1 | test.py:640:10:640:11 | ControlFlowNode for a1 | -| test.py:639:7:639:13 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:639:7:639:8 | SSA variable a1 | -| test.py:639:7:639:13 | ControlFlowNode for Tuple [Tuple element at index 2] | test.py:639:11:639:13 | IterableElement | -| test.py:639:7:639:13 | IterableSequence [Tuple element at index 0] | test.py:639:7:639:13 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:639:7:639:13 | IterableSequence [Tuple element at index 2] | test.py:639:7:639:13 | ControlFlowNode for Tuple [Tuple element at index 2] | -| test.py:639:11:639:13 | IterableElement | test.py:639:11:639:13 | SSA variable a2 [List element] | -| test.py:639:11:639:13 | SSA variable a2 [List element] | test.py:642:12:642:13 | ControlFlowNode for a2 [List element] | -| test.py:639:11:639:13 | SSA variable a2 [List element] | test.py:643:10:643:11 | ControlFlowNode for a2 [List element] | -| test.py:642:12:642:13 | ControlFlowNode for a2 [List element] | test.py:642:12:642:16 | ControlFlowNode for Subscript | -| test.py:643:10:643:11 | ControlFlowNode for a2 [List element] | test.py:643:10:643:14 | ControlFlowNode for Subscript | -| test.py:648:6:648:14 | ControlFlowNode for List [Tuple element at index 0] | test.py:648:7:648:8 | SSA variable a1 | -| test.py:648:6:648:14 | ControlFlowNode for List [Tuple element at index 2] | test.py:648:11:648:13 | IterableElement | -| test.py:648:6:648:14 | IterableSequence [Tuple element at index 0] | test.py:648:6:648:14 | ControlFlowNode for List [Tuple element at index 0] | -| test.py:648:6:648:14 | IterableSequence [Tuple element at index 2] | test.py:648:6:648:14 | ControlFlowNode for List [Tuple element at index 2] | -| test.py:648:6:648:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | test.py:648:6:648:14 | IterableSequence [Tuple element at index 0] | -| test.py:648:6:648:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | test.py:648:6:648:14 | IterableSequence [Tuple element at index 2] | -| test.py:648:7:648:8 | SSA variable a1 | test.py:649:10:649:11 | ControlFlowNode for a1 | -| test.py:648:11:648:13 | IterableElement | test.py:648:11:648:13 | SSA variable a2 [List element] | -| test.py:648:11:648:13 | SSA variable a2 [List element] | test.py:651:12:651:13 | ControlFlowNode for a2 [List element] | -| test.py:648:11:648:13 | SSA variable a2 [List element] | test.py:652:10:652:11 | ControlFlowNode for a2 [List element] | -| test.py:651:12:651:13 | ControlFlowNode for a2 [List element] | test.py:651:12:651:16 | ControlFlowNode for Subscript | -| test.py:652:10:652:11 | ControlFlowNode for a2 [List element] | test.py:652:10:652:14 | ControlFlowNode for Subscript | -| test.py:659:19:659:24 | ControlFlowNode for SOURCE | test.py:660:10:660:10 | ControlFlowNode for a | -| test.py:667:10:667:51 | ControlFlowNode for List [List element, Tuple element at index 0] | test.py:668:16:668:17 | ControlFlowNode for tl [List element, Tuple element at index 0] | -| test.py:667:12:667:17 | ControlFlowNode for SOURCE | test.py:667:12:667:28 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:667:12:667:28 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:667:10:667:51 | ControlFlowNode for List [List element, Tuple element at index 0] | -| test.py:667:33:667:38 | ControlFlowNode for SOURCE | test.py:667:33:667:49 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:667:33:667:49 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:667:10:667:51 | ControlFlowNode for List [List element, Tuple element at index 0] | -| test.py:668:9:668:9 | SSA variable x | test.py:669:14:669:14 | ControlFlowNode for x | -| test.py:668:9:668:11 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:668:9:668:9 | SSA variable x | -| test.py:668:9:668:11 | IterableSequence [Tuple element at index 0] | test.py:668:9:668:11 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:668:16:668:17 | ControlFlowNode for tl [List element, Tuple element at index 0] | test.py:668:9:668:11 | IterableSequence [Tuple element at index 0] | -| test.py:675:10:675:51 | ControlFlowNode for List [List element, Tuple element at index 0] | test.py:676:17:676:18 | ControlFlowNode for tl [List element, Tuple element at index 0] | -| test.py:675:12:675:17 | ControlFlowNode for SOURCE | test.py:675:12:675:28 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:675:12:675:28 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:675:10:675:51 | ControlFlowNode for List [List element, Tuple element at index 0] | -| test.py:675:33:675:38 | ControlFlowNode for SOURCE | test.py:675:33:675:49 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:675:33:675:49 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:675:10:675:51 | ControlFlowNode for List [List element, Tuple element at index 0] | -| test.py:676:9:676:10 | IterableElement | test.py:676:9:676:10 | SSA variable x [List element] | -| test.py:676:9:676:10 | SSA variable x [List element] | test.py:678:14:678:14 | ControlFlowNode for x [List element] | -| test.py:676:9:676:12 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:676:9:676:10 | IterableElement | -| test.py:676:9:676:12 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:676:12:676:12 | SSA variable y | -| test.py:676:9:676:12 | IterableSequence [Tuple element at index 0] | test.py:676:9:676:12 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:676:12:676:12 | SSA variable y | test.py:679:16:679:16 | ControlFlowNode for y | -| test.py:676:17:676:18 | ControlFlowNode for tl [List element, Tuple element at index 0] | test.py:676:9:676:12 | IterableSequence [Tuple element at index 0] | -| test.py:678:14:678:14 | ControlFlowNode for x [List element] | test.py:678:14:678:17 | ControlFlowNode for Subscript | -| test.py:684:10:684:51 | ControlFlowNode for List [List element, Tuple element at index 0] | test.py:685:19:685:20 | ControlFlowNode for tl [List element, Tuple element at index 0] | -| test.py:684:12:684:17 | ControlFlowNode for SOURCE | test.py:684:12:684:28 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:684:12:684:28 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:684:10:684:51 | ControlFlowNode for List [List element, Tuple element at index 0] | -| test.py:684:33:684:38 | ControlFlowNode for SOURCE | test.py:684:33:684:49 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:684:33:684:49 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:684:10:684:51 | ControlFlowNode for List [List element, Tuple element at index 0] | -| test.py:685:9:685:9 | SSA variable x | test.py:686:14:686:14 | ControlFlowNode for x | -| test.py:685:9:685:14 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:685:9:685:9 | SSA variable x | -| test.py:685:9:685:14 | IterableSequence [Tuple element at index 0] | test.py:685:9:685:14 | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:685:19:685:20 | ControlFlowNode for tl [List element, Tuple element at index 0] | test.py:685:9:685:14 | IterableSequence [Tuple element at index 0] | -| test.py:690:39:690:42 | ControlFlowNode for args [Tuple element at index 0] | test.py:691:14:691:17 | ControlFlowNode for args [Tuple element at index 0] | -| test.py:690:39:690:42 | ControlFlowNode for args [Tuple element at index 1] | test.py:691:14:691:17 | ControlFlowNode for args [Tuple element at index 1] | -| test.py:691:7:691:9 | SSA variable arg | test.py:692:10:692:12 | ControlFlowNode for arg | -| test.py:691:14:691:17 | ControlFlowNode for args [Tuple element at index 0] | test.py:691:7:691:9 | SSA variable arg | -| test.py:691:14:691:17 | ControlFlowNode for args [Tuple element at index 1] | test.py:691:7:691:9 | SSA variable arg | -| test.py:697:7:697:12 | ControlFlowNode for SOURCE | test.py:698:51:698:51 | ControlFlowNode for s | -| test.py:698:3:698:52 | PosOverflowNode for iterate_star_args() [Tuple element at index 0] | test.py:690:39:690:42 | ControlFlowNode for args [Tuple element at index 0] | -| test.py:698:3:698:52 | PosOverflowNode for iterate_star_args() [Tuple element at index 1] | test.py:690:39:690:42 | ControlFlowNode for args [Tuple element at index 1] | -| test.py:698:43:698:48 | ControlFlowNode for SOURCE | test.py:698:3:698:52 | PosOverflowNode for iterate_star_args() [Tuple element at index 0] | -| test.py:698:51:698:51 | ControlFlowNode for s | test.py:698:3:698:52 | PosOverflowNode for iterate_star_args() [Tuple element at index 1] | -| test.py:769:16:769:21 | ControlFlowNode for SOURCE | test.py:772:10:772:36 | ControlFlowNode for return_from_inner_scope() | -| test.py:807:35:807:35 | ControlFlowNode for x | test.py:808:10:808:10 | ControlFlowNode for x | -| test.py:807:37:807:42 | ControlFlowNode for SOURCE | test.py:807:35:807:35 | ControlFlowNode for x | -| test.py:807:48:807:48 | ControlFlowNode for y | test.py:809:10:809:10 | ControlFlowNode for y | -| test.py:807:50:807:55 | ControlFlowNode for SOURCE | test.py:807:48:807:48 | ControlFlowNode for y | -| test.py:807:61:807:61 | ControlFlowNode for z | test.py:810:10:810:10 | ControlFlowNode for z | -| test.py:807:63:807:68 | ControlFlowNode for SOURCE | test.py:807:61:807:61 | ControlFlowNode for z | -nodes -| datamodel.py:35:7:35:7 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | -| datamodel.py:36:10:36:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | -| datamodel.py:38:6:38:17 | ControlFlowNode for f() | semmle.label | ControlFlowNode for f() | -| datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| datamodel.py:44:22:44:22 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| datamodel.py:46:16:46:16 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| datamodel.py:49:26:49:26 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| datamodel.py:50:16:50:16 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| datamodel.py:53:22:53:22 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| datamodel.py:54:16:54:16 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| datamodel.py:88:6:88:27 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| datamodel.py:88:21:88:26 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| datamodel.py:89:6:89:27 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| datamodel.py:89:21:89:26 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| datamodel.py:161:5:161:8 | [post store] ControlFlowNode for self [Attribute b] | semmle.label | [post store] ControlFlowNode for self [Attribute b] | -| datamodel.py:161:14:161:19 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| datamodel.py:164:14:164:25 | ControlFlowNode for Customized() [Attribute b] | semmle.label | ControlFlowNode for Customized() [Attribute b] | -| datamodel.py:168:6:168:15 | ControlFlowNode for customized [Attribute b] | semmle.label | ControlFlowNode for customized [Attribute b] | -| datamodel.py:168:6:168:17 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:42:10:42:26 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:42:21:42:26 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:43:9:43:9 | ControlFlowNode for x [Tuple element at index 1] | semmle.label | ControlFlowNode for x [Tuple element at index 1] | -| test.py:43:9:43:12 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:44:10:44:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | -| test.py:55:9:55:14 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:56:10:56:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:61:9:61:16 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str | -| test.py:62:10:62:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:66:9:66:17 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str | -| test.py:67:10:67:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:71:9:71:10 | ControlFlowNode for IntegerLiteral | semmle.label | ControlFlowNode for IntegerLiteral | -| test.py:72:10:72:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:76:9:76:12 | ControlFlowNode for FloatLiteral | semmle.label | ControlFlowNode for FloatLiteral | -| test.py:77:10:77:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:87:10:87:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:88:10:88:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:93:9:93:16 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | -| test.py:93:10:93:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:94:10:94:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] | -| test.py:94:10:94:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:103:9:103:37 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] | -| test.py:103:10:103:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:104:10:104:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] | -| test.py:104:10:104:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:108:9:108:29 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] | -| test.py:108:10:108:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | -| test.py:108:16:108:16 | SSA variable y | semmle.label | SSA variable y | -| test.py:108:21:108:28 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | -| test.py:108:22:108:27 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:109:10:109:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] | -| test.py:109:10:109:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:113:9:113:16 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | -| test.py:113:10:113:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:114:9:114:22 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] | -| test.py:114:10:114:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | -| test.py:114:16:114:16 | SSA variable y | semmle.label | SSA variable y | -| test.py:114:21:114:21 | ControlFlowNode for l [List element] | semmle.label | ControlFlowNode for l [List element] | -| test.py:115:10:115:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] | -| test.py:115:10:115:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:125:9:125:16 | ControlFlowNode for Set [Set element] | semmle.label | ControlFlowNode for Set [Set element] | -| test.py:125:10:125:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:126:10:126:10 | ControlFlowNode for x [Set element] | semmle.label | ControlFlowNode for x [Set element] | -| test.py:126:10:126:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| test.py:130:9:130:37 | ControlFlowNode for SetComp [Set element] | semmle.label | ControlFlowNode for SetComp [Set element] | -| test.py:130:10:130:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:131:10:131:10 | ControlFlowNode for x [Set element] | semmle.label | ControlFlowNode for x [Set element] | -| test.py:131:10:131:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| test.py:135:9:135:29 | ControlFlowNode for SetComp [Set element] | semmle.label | ControlFlowNode for SetComp [Set element] | -| test.py:135:10:135:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | -| test.py:135:16:135:16 | SSA variable y | semmle.label | SSA variable y | -| test.py:135:21:135:28 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | -| test.py:135:22:135:27 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:136:10:136:10 | ControlFlowNode for x [Set element] | semmle.label | ControlFlowNode for x [Set element] | -| test.py:136:10:136:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| test.py:140:9:140:16 | ControlFlowNode for Set [Set element] | semmle.label | ControlFlowNode for Set [Set element] | -| test.py:140:10:140:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:141:9:141:22 | ControlFlowNode for SetComp [Set element] | semmle.label | ControlFlowNode for SetComp [Set element] | -| test.py:141:10:141:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | -| test.py:141:16:141:16 | SSA variable y | semmle.label | SSA variable y | -| test.py:141:21:141:21 | ControlFlowNode for l [Set element] | semmle.label | ControlFlowNode for l [Set element] | -| test.py:142:10:142:10 | ControlFlowNode for x [Set element] | semmle.label | ControlFlowNode for x [Set element] | -| test.py:142:10:142:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| test.py:152:9:152:21 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] | -| test.py:152:15:152:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:153:10:153:10 | ControlFlowNode for x [Dictionary element at key s] | semmle.label | ControlFlowNode for x [Dictionary element at key s] | -| test.py:153:10:153:15 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:157:9:157:21 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] | -| test.py:157:15:157:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:158:10:158:10 | ControlFlowNode for x [Dictionary element at key s] | semmle.label | ControlFlowNode for x [Dictionary element at key s] | -| test.py:158:10:158:19 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| test.py:183:9:183:42 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] | -| test.py:183:10:183:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | -| test.py:183:16:183:16 | SSA variable z [List element] | semmle.label | SSA variable z [List element] | -| test.py:183:21:183:30 | ControlFlowNode for List [List element, List element] | semmle.label | ControlFlowNode for List [List element, List element] | -| test.py:183:22:183:29 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | -| test.py:183:23:183:28 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:183:36:183:36 | SSA variable y | semmle.label | SSA variable y | -| test.py:183:41:183:41 | ControlFlowNode for z [List element] | semmle.label | ControlFlowNode for z [List element] | -| test.py:184:10:184:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] | -| test.py:184:10:184:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:188:9:188:68 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] | -| test.py:188:10:188:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | -| test.py:188:16:188:16 | SSA variable v [List element, List element, List element] | semmle.label | SSA variable v [List element, List element, List element] | -| test.py:188:21:188:34 | ControlFlowNode for List [List element, List element, List element, List element] | semmle.label | ControlFlowNode for List [List element, List element, List element, List element] | -| test.py:188:22:188:33 | ControlFlowNode for List [List element, List element, List element] | semmle.label | ControlFlowNode for List [List element, List element, List element] | -| test.py:188:23:188:32 | ControlFlowNode for List [List element, List element] | semmle.label | ControlFlowNode for List [List element, List element] | -| test.py:188:24:188:31 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | -| test.py:188:25:188:30 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:188:40:188:40 | SSA variable u [List element, List element] | semmle.label | SSA variable u [List element, List element] | -| test.py:188:45:188:45 | ControlFlowNode for v [List element, List element, List element] | semmle.label | ControlFlowNode for v [List element, List element, List element] | -| test.py:188:51:188:51 | SSA variable z [List element] | semmle.label | SSA variable z [List element] | -| test.py:188:56:188:56 | ControlFlowNode for u [List element, List element] | semmle.label | ControlFlowNode for u [List element, List element] | -| test.py:188:62:188:62 | SSA variable y | semmle.label | SSA variable y | -| test.py:188:67:188:67 | ControlFlowNode for z [List element] | semmle.label | ControlFlowNode for z [List element] | -| test.py:189:10:189:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] | -| test.py:189:10:189:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:199:9:199:42 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] | -| test.py:199:10:199:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | -| test.py:199:16:199:16 | SSA variable y | semmle.label | SSA variable y | -| test.py:199:22:199:22 | ControlFlowNode for z | semmle.label | ControlFlowNode for z | -| test.py:199:22:199:40 | ControlFlowNode for GeneratorExp [List element] | semmle.label | ControlFlowNode for GeneratorExp [List element] | -| test.py:199:28:199:28 | SSA variable z | semmle.label | SSA variable z | -| test.py:199:33:199:40 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | -| test.py:199:34:199:39 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:200:10:200:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] | -| test.py:200:10:200:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:205:9:205:47 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] | -| test.py:205:10:205:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | -| test.py:205:17:205:17 | SSA variable a | semmle.label | SSA variable a | -| test.py:205:17:205:20 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:205:17:205:20 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] | -| test.py:205:26:205:46 | ControlFlowNode for List [List element, Tuple element at index 0] | semmle.label | ControlFlowNode for List [List element, Tuple element at index 0] | -| test.py:205:28:205:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:205:28:205:44 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:206:10:206:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] | -| test.py:206:10:206:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:210:9:210:51 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] | -| test.py:210:10:210:10 | ControlFlowNode for a [List element] | semmle.label | ControlFlowNode for a [List element] | -| test.py:210:10:210:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:210:20:210:21 | IterableElement | semmle.label | IterableElement | -| test.py:210:20:210:21 | SSA variable a [List element] | semmle.label | SSA variable a [List element] | -| test.py:210:20:210:24 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:210:20:210:24 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] | -| test.py:210:30:210:50 | ControlFlowNode for List [List element, Tuple element at index 0] | semmle.label | ControlFlowNode for List [List element, Tuple element at index 0] | -| test.py:210:32:210:37 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:210:32:210:48 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:211:10:211:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] | -| test.py:211:10:211:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:349:10:349:21 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:349:11:349:16 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:349:11:349:17 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:353:10:353:17 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | -| test.py:353:10:353:20 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:353:11:353:16 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:357:10:357:22 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] | -| test.py:357:10:357:27 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:357:16:357:21 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:375:15:375:15 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | -| test.py:376:12:376:12 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | -| test.py:380:10:380:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() | -| test.py:380:28:380:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:388:10:388:36 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() | -| test.py:388:30:388:35 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:396:10:396:43 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() | -| test.py:396:10:396:43 | KwUnpacked b | semmle.label | KwUnpacked b | -| test.py:396:30:396:42 | ControlFlowNode for Dict [Dictionary element at key b] | semmle.label | ControlFlowNode for Dict [Dictionary element at key b] | -| test.py:396:36:396:41 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:399:21:399:21 | ControlFlowNode for b [Tuple element at index 0] | semmle.label | ControlFlowNode for b [Tuple element at index 0] | -| test.py:400:12:400:12 | ControlFlowNode for b [Tuple element at index 0] | semmle.label | ControlFlowNode for b [Tuple element at index 0] | -| test.py:400:12:400:15 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:404:10:404:39 | ControlFlowNode for f_extra_pos() | semmle.label | ControlFlowNode for f_extra_pos() | -| test.py:404:10:404:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | semmle.label | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | -| test.py:404:33:404:38 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:407:26:407:26 | ControlFlowNode for b [Dictionary element at key b] | semmle.label | ControlFlowNode for b [Dictionary element at key b] | -| test.py:408:12:408:12 | ControlFlowNode for b [Dictionary element at key b] | semmle.label | ControlFlowNode for b [Dictionary element at key b] | -| test.py:408:12:408:17 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:412:10:412:45 | ControlFlowNode for f_extra_keyword() | semmle.label | ControlFlowNode for f_extra_keyword() | -| test.py:412:10:412:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | semmle.label | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | -| test.py:412:39:412:44 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:429:10:429:20 | ControlFlowNode for BoolExpr | semmle.label | ControlFlowNode for BoolExpr | -| test.py:429:15:429:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:434:10:434:21 | ControlFlowNode for BoolExpr | semmle.label | ControlFlowNode for BoolExpr | -| test.py:434:16:434:21 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:445:10:445:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:445:10:445:38 | ControlFlowNode for IfExp | semmle.label | ControlFlowNode for IfExp | -| test.py:453:10:453:39 | ControlFlowNode for IfExp | semmle.label | ControlFlowNode for IfExp | -| test.py:453:34:453:39 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:474:11:474:11 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:475:16:475:16 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:477:10:477:18 | ControlFlowNode for f() | semmle.label | ControlFlowNode for f() | -| test.py:477:12:477:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:481:19:481:19 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | -| test.py:482:16:482:16 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | -| test.py:484:10:484:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() | -| test.py:484:28:484:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:495:19:495:19 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | -| test.py:496:16:496:16 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | -| test.py:498:10:498:36 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() | -| test.py:498:30:498:35 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:509:19:509:19 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | -| test.py:510:16:510:16 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | -| test.py:512:10:512:43 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() | -| test.py:512:10:512:43 | KwUnpacked b | semmle.label | KwUnpacked b | -| test.py:512:30:512:42 | ControlFlowNode for Dict [Dictionary element at key b] | semmle.label | ControlFlowNode for Dict [Dictionary element at key b] | -| test.py:512:36:512:41 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:516:30:516:30 | ControlFlowNode for b [Tuple element at index 0] | semmle.label | ControlFlowNode for b [Tuple element at index 0] | -| test.py:516:33:516:33 | ControlFlowNode for b [Tuple element at index 0] | semmle.label | ControlFlowNode for b [Tuple element at index 0] | -| test.py:516:33:516:36 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:517:10:517:39 | ControlFlowNode for f_extra_pos() | semmle.label | ControlFlowNode for f_extra_pos() | -| test.py:517:10:517:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | semmle.label | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | -| test.py:517:33:517:38 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:521:35:521:35 | ControlFlowNode for b [Dictionary element at key b] | semmle.label | ControlFlowNode for b [Dictionary element at key b] | -| test.py:521:38:521:38 | ControlFlowNode for b [Dictionary element at key b] | semmle.label | ControlFlowNode for b [Dictionary element at key b] | -| test.py:521:38:521:43 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:522:10:522:45 | ControlFlowNode for f_extra_keyword() | semmle.label | ControlFlowNode for f_extra_keyword() | -| test.py:522:10:522:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | semmle.label | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | -| test.py:522:39:522:44 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:534:9:534:14 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:536:10:536:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | -| test.py:541:10:541:10 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | -| test.py:546:10:546:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:546:10:546:26 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:547:5:547:5 | SSA variable a | semmle.label | SSA variable a | -| test.py:547:5:547:8 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:548:10:548:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | -| test.py:554:10:554:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:554:10:554:36 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:554:10:554:36 | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 1] | -| test.py:554:19:554:35 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:554:30:554:35 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:555:5:555:5 | SSA variable a | semmle.label | SSA variable a | -| test.py:555:5:555:13 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:555:5:555:13 | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 1] | -| test.py:555:9:555:12 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:555:9:555:12 | IterableSequence [Tuple element at index 1] | semmle.label | IterableSequence [Tuple element at index 1] | -| test.py:555:12:555:12 | SSA variable c | semmle.label | SSA variable c | -| test.py:556:10:556:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | -| test.py:558:10:558:10 | ControlFlowNode for c | semmle.label | ControlFlowNode for c | -| test.py:563:9:563:33 | ControlFlowNode for List [List element, List element, List element, List element] | semmle.label | ControlFlowNode for List [List element, List element, List element, List element] | -| test.py:563:10:563:21 | ControlFlowNode for List [List element, List element, List element] | semmle.label | ControlFlowNode for List [List element, List element, List element] | -| test.py:563:11:563:20 | ControlFlowNode for List [List element, List element] | semmle.label | ControlFlowNode for List [List element, List element] | -| test.py:563:12:563:19 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | -| test.py:563:13:563:18 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:564:5:564:11 | ControlFlowNode for List [Tuple element at index 0, List element, List element] | semmle.label | ControlFlowNode for List [Tuple element at index 0, List element, List element] | -| test.py:564:5:564:11 | IterableElement [List element, List element] | semmle.label | IterableElement [List element, List element] | -| test.py:564:5:564:11 | IterableSequence [List element, List element, List element] | semmle.label | IterableSequence [List element, List element, List element] | -| test.py:564:5:564:14 | ControlFlowNode for Tuple [Tuple element at index 0, List element, List element, List element] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, List element, List element, List element] | -| test.py:564:5:564:14 | IterableElement [List element, List element, List element] | semmle.label | IterableElement [List element, List element, List element] | -| test.py:564:5:564:14 | IterableSequence [List element, List element, List element, List element] | semmle.label | IterableSequence [List element, List element, List element, List element] | -| test.py:564:6:564:10 | ControlFlowNode for List [Tuple element at index 0, List element] | semmle.label | ControlFlowNode for List [Tuple element at index 0, List element] | -| test.py:564:6:564:10 | IterableElement [List element] | semmle.label | IterableElement [List element] | -| test.py:564:6:564:10 | IterableSequence [List element, List element] | semmle.label | IterableSequence [List element, List element] | -| test.py:564:7:564:9 | ControlFlowNode for List [Tuple element at index 0] | semmle.label | ControlFlowNode for List [Tuple element at index 0] | -| test.py:564:7:564:9 | IterableElement | semmle.label | IterableElement | -| test.py:564:7:564:9 | IterableSequence [List element] | semmle.label | IterableSequence [List element] | -| test.py:564:8:564:8 | SSA variable a | semmle.label | SSA variable a | -| test.py:565:10:565:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | -| test.py:571:10:571:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:571:10:571:34 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:571:10:571:34 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:571:18:571:23 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:572:5:572:5 | SSA variable a | semmle.label | SSA variable a | -| test.py:572:5:572:12 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:572:5:572:12 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:572:8:572:9 | IterableElement | semmle.label | IterableElement | -| test.py:572:8:572:9 | SSA variable b [List element] | semmle.label | SSA variable b [List element] | -| test.py:572:12:572:12 | SSA variable c | semmle.label | SSA variable c | -| test.py:573:10:573:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | -| test.py:575:10:575:10 | ControlFlowNode for b [List element] | semmle.label | ControlFlowNode for b [List element] | -| test.py:575:10:575:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:576:12:576:12 | ControlFlowNode for c | semmle.label | ControlFlowNode for c | -| test.py:581:10:581:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:581:10:581:23 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:581:10:581:23 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:581:18:581:23 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:582:5:582:5 | SSA variable a | semmle.label | SSA variable a | -| test.py:582:5:582:12 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:582:5:582:12 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:582:12:582:12 | SSA variable c | semmle.label | SSA variable c | -| test.py:583:10:583:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | -| test.py:585:10:585:10 | ControlFlowNode for c | semmle.label | ControlFlowNode for c | -| test.py:590:10:590:61 | ControlFlowNode for List [List element, List element] | semmle.label | ControlFlowNode for List [List element, List element] | -| test.py:590:11:590:37 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | -| test.py:590:12:590:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:590:31:590:36 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:590:40:590:47 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | -| test.py:590:41:590:46 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:593:6:593:23 | ControlFlowNode for Tuple [Tuple element at index 0, List element] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, List element] | -| test.py:593:6:593:23 | IterableElement [List element] | semmle.label | IterableElement [List element] | -| test.py:593:6:593:23 | IterableSequence [List element, List element] | semmle.label | IterableSequence [List element, List element] | -| test.py:593:7:593:8 | SSA variable a1 | semmle.label | SSA variable a1 | -| test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 2] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 2] | -| test.py:593:7:593:16 | IterableElement | semmle.label | IterableElement | -| test.py:593:7:593:16 | IterableSequence [List element] | semmle.label | IterableSequence [List element] | -| test.py:593:11:593:12 | SSA variable a2 | semmle.label | SSA variable a2 | -| test.py:593:15:593:16 | SSA variable a3 | semmle.label | SSA variable a3 | -| test.py:594:10:594:11 | ControlFlowNode for a1 | semmle.label | ControlFlowNode for a1 | -| test.py:595:12:595:13 | ControlFlowNode for a2 | semmle.label | ControlFlowNode for a2 | -| test.py:596:10:596:11 | ControlFlowNode for a3 | semmle.label | ControlFlowNode for a3 | -| test.py:601:5:601:24 | ControlFlowNode for List [Tuple element at index 0, List element] | semmle.label | ControlFlowNode for List [Tuple element at index 0, List element] | -| test.py:601:5:601:24 | IterableElement [List element] | semmle.label | IterableElement [List element] | -| test.py:601:5:601:24 | IterableSequence [List element, List element] | semmle.label | IterableSequence [List element, List element] | -| test.py:601:7:601:8 | SSA variable a1 | semmle.label | SSA variable a1 | -| test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] | -| test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 2] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 2] | -| test.py:601:7:601:16 | IterableElement | semmle.label | IterableElement | -| test.py:601:7:601:16 | IterableSequence [List element] | semmle.label | IterableSequence [List element] | -| test.py:601:11:601:12 | SSA variable a2 | semmle.label | SSA variable a2 | -| test.py:601:15:601:16 | SSA variable a3 | semmle.label | SSA variable a3 | -| test.py:602:10:602:11 | ControlFlowNode for a1 | semmle.label | ControlFlowNode for a1 | -| test.py:603:12:603:13 | ControlFlowNode for a2 | semmle.label | ControlFlowNode for a2 | -| test.py:604:10:604:11 | ControlFlowNode for a3 | semmle.label | ControlFlowNode for a3 | -| test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 0] | semmle.label | ControlFlowNode for List [Tuple element at index 0] | -| test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 1] | semmle.label | ControlFlowNode for List [Tuple element at index 1] | -| test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 2] | semmle.label | ControlFlowNode for List [Tuple element at index 2] | -| test.py:609:6:609:17 | IterableElement | semmle.label | IterableElement | -| test.py:609:6:609:17 | IterableSequence [List element] | semmle.label | IterableSequence [List element] | -| test.py:609:6:609:23 | ControlFlowNode for Tuple [Tuple element at index 0, List element] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, List element] | -| test.py:609:6:609:23 | IterableElement [List element] | semmle.label | IterableElement [List element] | -| test.py:609:6:609:23 | IterableSequence [List element, List element] | semmle.label | IterableSequence [List element, List element] | -| test.py:609:7:609:8 | SSA variable a1 | semmle.label | SSA variable a1 | -| test.py:609:11:609:12 | SSA variable a2 | semmle.label | SSA variable a2 | -| test.py:609:15:609:16 | SSA variable a3 | semmle.label | SSA variable a3 | -| test.py:610:10:610:11 | ControlFlowNode for a1 | semmle.label | ControlFlowNode for a1 | -| test.py:611:12:611:13 | ControlFlowNode for a2 | semmle.label | ControlFlowNode for a2 | -| test.py:612:10:612:11 | ControlFlowNode for a3 | semmle.label | ControlFlowNode for a3 | -| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | -| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | -| test.py:618:12:618:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:618:12:618:36 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:618:12:618:36 | ControlFlowNode for Tuple [Tuple element at index 2] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 2] | -| test.py:618:31:618:36 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:621:5:621:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 0] | semmle.label | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 0] | -| test.py:621:5:621:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 2] | semmle.label | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 2] | -| test.py:621:6:621:14 | ControlFlowNode for List [Tuple element at index 0] | semmle.label | ControlFlowNode for List [Tuple element at index 0] | -| test.py:621:6:621:14 | ControlFlowNode for List [Tuple element at index 2] | semmle.label | ControlFlowNode for List [Tuple element at index 2] | -| test.py:621:6:621:14 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] | -| test.py:621:6:621:14 | IterableSequence [Tuple element at index 2] | semmle.label | IterableSequence [Tuple element at index 2] | -| test.py:621:7:621:8 | SSA variable a1 | semmle.label | SSA variable a1 | -| test.py:621:11:621:13 | IterableElement | semmle.label | IterableElement | -| test.py:621:11:621:13 | SSA variable a2 [List element] | semmle.label | SSA variable a2 [List element] | -| test.py:622:10:622:11 | ControlFlowNode for a1 | semmle.label | ControlFlowNode for a1 | -| test.py:624:12:624:13 | ControlFlowNode for a2 [List element] | semmle.label | ControlFlowNode for a2 [List element] | -| test.py:624:12:624:16 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:625:10:625:11 | ControlFlowNode for a2 [List element] | semmle.label | ControlFlowNode for a2 [List element] | -| test.py:625:10:625:14 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:630:6:630:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | -| test.py:630:6:630:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | -| test.py:630:7:630:8 | SSA variable a1 | semmle.label | SSA variable a1 | -| test.py:630:7:630:13 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:630:7:630:13 | ControlFlowNode for Tuple [Tuple element at index 2] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 2] | -| test.py:630:7:630:13 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] | -| test.py:630:7:630:13 | IterableSequence [Tuple element at index 2] | semmle.label | IterableSequence [Tuple element at index 2] | -| test.py:630:11:630:13 | IterableElement | semmle.label | IterableElement | -| test.py:630:11:630:13 | SSA variable a2 [List element] | semmle.label | SSA variable a2 [List element] | -| test.py:631:10:631:11 | ControlFlowNode for a1 | semmle.label | ControlFlowNode for a1 | -| test.py:633:12:633:13 | ControlFlowNode for a2 [List element] | semmle.label | ControlFlowNode for a2 [List element] | -| test.py:633:12:633:16 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:634:10:634:11 | ControlFlowNode for a2 [List element] | semmle.label | ControlFlowNode for a2 [List element] | -| test.py:634:10:634:14 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:639:5:639:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 0] | semmle.label | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 0] | -| test.py:639:5:639:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 2] | semmle.label | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 2] | -| test.py:639:7:639:8 | SSA variable a1 | semmle.label | SSA variable a1 | -| test.py:639:7:639:13 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:639:7:639:13 | ControlFlowNode for Tuple [Tuple element at index 2] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 2] | -| test.py:639:7:639:13 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] | -| test.py:639:7:639:13 | IterableSequence [Tuple element at index 2] | semmle.label | IterableSequence [Tuple element at index 2] | -| test.py:639:11:639:13 | IterableElement | semmle.label | IterableElement | -| test.py:639:11:639:13 | SSA variable a2 [List element] | semmle.label | SSA variable a2 [List element] | -| test.py:640:10:640:11 | ControlFlowNode for a1 | semmle.label | ControlFlowNode for a1 | -| test.py:642:12:642:13 | ControlFlowNode for a2 [List element] | semmle.label | ControlFlowNode for a2 [List element] | -| test.py:642:12:642:16 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:643:10:643:11 | ControlFlowNode for a2 [List element] | semmle.label | ControlFlowNode for a2 [List element] | -| test.py:643:10:643:14 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:648:6:648:14 | ControlFlowNode for List [Tuple element at index 0] | semmle.label | ControlFlowNode for List [Tuple element at index 0] | -| test.py:648:6:648:14 | ControlFlowNode for List [Tuple element at index 2] | semmle.label | ControlFlowNode for List [Tuple element at index 2] | -| test.py:648:6:648:14 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] | -| test.py:648:6:648:14 | IterableSequence [Tuple element at index 2] | semmle.label | IterableSequence [Tuple element at index 2] | -| test.py:648:6:648:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | -| test.py:648:6:648:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | -| test.py:648:7:648:8 | SSA variable a1 | semmle.label | SSA variable a1 | -| test.py:648:11:648:13 | IterableElement | semmle.label | IterableElement | -| test.py:648:11:648:13 | SSA variable a2 [List element] | semmle.label | SSA variable a2 [List element] | -| test.py:649:10:649:11 | ControlFlowNode for a1 | semmle.label | ControlFlowNode for a1 | -| test.py:651:12:651:13 | ControlFlowNode for a2 [List element] | semmle.label | ControlFlowNode for a2 [List element] | -| test.py:651:12:651:16 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:652:10:652:11 | ControlFlowNode for a2 [List element] | semmle.label | ControlFlowNode for a2 [List element] | -| test.py:652:10:652:14 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:659:19:659:24 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:660:10:660:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | -| test.py:667:10:667:51 | ControlFlowNode for List [List element, Tuple element at index 0] | semmle.label | ControlFlowNode for List [List element, Tuple element at index 0] | -| test.py:667:12:667:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:667:12:667:28 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:667:33:667:38 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:667:33:667:49 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:668:9:668:9 | SSA variable x | semmle.label | SSA variable x | -| test.py:668:9:668:11 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:668:9:668:11 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] | -| test.py:668:16:668:17 | ControlFlowNode for tl [List element, Tuple element at index 0] | semmle.label | ControlFlowNode for tl [List element, Tuple element at index 0] | -| test.py:669:14:669:14 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:675:10:675:51 | ControlFlowNode for List [List element, Tuple element at index 0] | semmle.label | ControlFlowNode for List [List element, Tuple element at index 0] | -| test.py:675:12:675:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:675:12:675:28 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:675:33:675:38 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:675:33:675:49 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:676:9:676:10 | IterableElement | semmle.label | IterableElement | -| test.py:676:9:676:10 | SSA variable x [List element] | semmle.label | SSA variable x [List element] | -| test.py:676:9:676:12 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:676:9:676:12 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] | -| test.py:676:12:676:12 | SSA variable y | semmle.label | SSA variable y | -| test.py:676:17:676:18 | ControlFlowNode for tl [List element, Tuple element at index 0] | semmle.label | ControlFlowNode for tl [List element, Tuple element at index 0] | -| test.py:678:14:678:14 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] | -| test.py:678:14:678:17 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| test.py:679:16:679:16 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | -| test.py:684:10:684:51 | ControlFlowNode for List [List element, Tuple element at index 0] | semmle.label | ControlFlowNode for List [List element, Tuple element at index 0] | -| test.py:684:12:684:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:684:12:684:28 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:684:33:684:38 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:684:33:684:49 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:685:9:685:9 | SSA variable x | semmle.label | SSA variable x | -| test.py:685:9:685:14 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | -| test.py:685:9:685:14 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] | -| test.py:685:19:685:20 | ControlFlowNode for tl [List element, Tuple element at index 0] | semmle.label | ControlFlowNode for tl [List element, Tuple element at index 0] | -| test.py:686:14:686:14 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:690:39:690:42 | ControlFlowNode for args [Tuple element at index 0] | semmle.label | ControlFlowNode for args [Tuple element at index 0] | -| test.py:690:39:690:42 | ControlFlowNode for args [Tuple element at index 1] | semmle.label | ControlFlowNode for args [Tuple element at index 1] | -| test.py:691:7:691:9 | SSA variable arg | semmle.label | SSA variable arg | -| test.py:691:14:691:17 | ControlFlowNode for args [Tuple element at index 0] | semmle.label | ControlFlowNode for args [Tuple element at index 0] | -| test.py:691:14:691:17 | ControlFlowNode for args [Tuple element at index 1] | semmle.label | ControlFlowNode for args [Tuple element at index 1] | -| test.py:692:10:692:12 | ControlFlowNode for arg | semmle.label | ControlFlowNode for arg | -| test.py:697:7:697:12 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:698:3:698:52 | PosOverflowNode for iterate_star_args() [Tuple element at index 0] | semmle.label | PosOverflowNode for iterate_star_args() [Tuple element at index 0] | -| test.py:698:3:698:52 | PosOverflowNode for iterate_star_args() [Tuple element at index 1] | semmle.label | PosOverflowNode for iterate_star_args() [Tuple element at index 1] | -| test.py:698:43:698:48 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:698:51:698:51 | ControlFlowNode for s | semmle.label | ControlFlowNode for s | -| test.py:769:16:769:21 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:772:10:772:36 | ControlFlowNode for return_from_inner_scope() | semmle.label | ControlFlowNode for return_from_inner_scope() | -| test.py:807:35:807:35 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:807:37:807:42 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:807:48:807:48 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | -| test.py:807:50:807:55 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:807:61:807:61 | ControlFlowNode for z | semmle.label | ControlFlowNode for z | -| test.py:807:63:807:68 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | -| test.py:808:10:808:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:809:10:809:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | -| test.py:810:10:810:10 | ControlFlowNode for z | semmle.label | ControlFlowNode for z | -subpaths -| datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:35:7:35:7 | ControlFlowNode for a | datamodel.py:36:10:36:10 | ControlFlowNode for a | datamodel.py:38:6:38:17 | ControlFlowNode for f() | -| datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:44:22:44:22 | ControlFlowNode for x | datamodel.py:46:16:46:16 | ControlFlowNode for x | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | -| datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:44:22:44:22 | ControlFlowNode for x | datamodel.py:46:16:46:16 | ControlFlowNode for x | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | -| datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:49:26:49:26 | ControlFlowNode for x | datamodel.py:50:16:50:16 | ControlFlowNode for x | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | -| datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:49:26:49:26 | ControlFlowNode for x | datamodel.py:50:16:50:16 | ControlFlowNode for x | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | -| datamodel.py:88:21:88:26 | ControlFlowNode for SOURCE | datamodel.py:53:22:53:22 | ControlFlowNode for x | datamodel.py:54:16:54:16 | ControlFlowNode for x | datamodel.py:88:6:88:27 | ControlFlowNode for Attribute() | -| datamodel.py:89:21:89:26 | ControlFlowNode for SOURCE | datamodel.py:53:22:53:22 | ControlFlowNode for x | datamodel.py:54:16:54:16 | ControlFlowNode for x | datamodel.py:89:6:89:27 | ControlFlowNode for Attribute() | -| test.py:380:28:380:33 | ControlFlowNode for SOURCE | test.py:375:15:375:15 | ControlFlowNode for b | test.py:376:12:376:12 | ControlFlowNode for b | test.py:380:10:380:34 | ControlFlowNode for second() | -| test.py:388:30:388:35 | ControlFlowNode for SOURCE | test.py:375:15:375:15 | ControlFlowNode for b | test.py:376:12:376:12 | ControlFlowNode for b | test.py:388:10:388:36 | ControlFlowNode for second() | -| test.py:396:10:396:43 | KwUnpacked b | test.py:375:15:375:15 | ControlFlowNode for b | test.py:376:12:376:12 | ControlFlowNode for b | test.py:396:10:396:43 | ControlFlowNode for second() | -| test.py:404:10:404:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:399:21:399:21 | ControlFlowNode for b [Tuple element at index 0] | test.py:400:12:400:15 | ControlFlowNode for Subscript | test.py:404:10:404:39 | ControlFlowNode for f_extra_pos() | -| test.py:412:10:412:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:407:26:407:26 | ControlFlowNode for b [Dictionary element at key b] | test.py:408:12:408:17 | ControlFlowNode for Subscript | test.py:412:10:412:45 | ControlFlowNode for f_extra_keyword() | -| test.py:477:12:477:17 | ControlFlowNode for SOURCE | test.py:474:11:474:11 | ControlFlowNode for x | test.py:475:16:475:16 | ControlFlowNode for x | test.py:477:10:477:18 | ControlFlowNode for f() | -| test.py:484:28:484:33 | ControlFlowNode for SOURCE | test.py:481:19:481:19 | ControlFlowNode for b | test.py:482:16:482:16 | ControlFlowNode for b | test.py:484:10:484:34 | ControlFlowNode for second() | -| test.py:498:30:498:35 | ControlFlowNode for SOURCE | test.py:495:19:495:19 | ControlFlowNode for b | test.py:496:16:496:16 | ControlFlowNode for b | test.py:498:10:498:36 | ControlFlowNode for second() | -| test.py:512:10:512:43 | KwUnpacked b | test.py:509:19:509:19 | ControlFlowNode for b | test.py:510:16:510:16 | ControlFlowNode for b | test.py:512:10:512:43 | ControlFlowNode for second() | -| test.py:517:10:517:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:516:30:516:30 | ControlFlowNode for b [Tuple element at index 0] | test.py:516:33:516:36 | ControlFlowNode for Subscript | test.py:517:10:517:39 | ControlFlowNode for f_extra_pos() | -| test.py:522:10:522:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:521:35:521:35 | ControlFlowNode for b [Dictionary element at key b] | test.py:521:38:521:43 | ControlFlowNode for Subscript | test.py:522:10:522:45 | ControlFlowNode for f_extra_keyword() | -#select -| datamodel.py:38:6:38:17 | ControlFlowNode for f() | datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:38:6:38:17 | ControlFlowNode for f() | Flow found | -| datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | Flow found | -| datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | Flow found | -| datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | Flow found | -| datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | Flow found | -| datamodel.py:88:6:88:27 | ControlFlowNode for Attribute() | datamodel.py:88:21:88:26 | ControlFlowNode for SOURCE | datamodel.py:88:6:88:27 | ControlFlowNode for Attribute() | Flow found | -| datamodel.py:89:6:89:27 | ControlFlowNode for Attribute() | datamodel.py:89:21:89:26 | ControlFlowNode for SOURCE | datamodel.py:89:6:89:27 | ControlFlowNode for Attribute() | Flow found | -| datamodel.py:168:6:168:17 | ControlFlowNode for Attribute | datamodel.py:161:14:161:19 | ControlFlowNode for SOURCE | datamodel.py:168:6:168:17 | ControlFlowNode for Attribute | Flow found | -| test.py:44:10:44:10 | ControlFlowNode for y | test.py:42:21:42:26 | ControlFlowNode for SOURCE | test.py:44:10:44:10 | ControlFlowNode for y | Flow found | -| test.py:56:10:56:10 | ControlFlowNode for x | test.py:55:9:55:14 | ControlFlowNode for SOURCE | test.py:56:10:56:10 | ControlFlowNode for x | Flow found | -| test.py:62:10:62:10 | ControlFlowNode for x | test.py:61:9:61:16 | ControlFlowNode for Str | test.py:62:10:62:10 | ControlFlowNode for x | Flow found | -| test.py:67:10:67:10 | ControlFlowNode for x | test.py:66:9:66:17 | ControlFlowNode for Str | test.py:67:10:67:10 | ControlFlowNode for x | Flow found | -| test.py:72:10:72:10 | ControlFlowNode for x | test.py:71:9:71:10 | ControlFlowNode for IntegerLiteral | test.py:72:10:72:10 | ControlFlowNode for x | Flow found | -| test.py:77:10:77:10 | ControlFlowNode for x | test.py:76:9:76:12 | ControlFlowNode for FloatLiteral | test.py:77:10:77:10 | ControlFlowNode for x | Flow found | -| test.py:88:10:88:10 | ControlFlowNode for x | test.py:87:10:87:15 | ControlFlowNode for SOURCE | test.py:88:10:88:10 | ControlFlowNode for x | Flow found | -| test.py:94:10:94:13 | ControlFlowNode for Subscript | test.py:93:10:93:15 | ControlFlowNode for SOURCE | test.py:94:10:94:13 | ControlFlowNode for Subscript | Flow found | -| test.py:104:10:104:13 | ControlFlowNode for Subscript | test.py:103:10:103:15 | ControlFlowNode for SOURCE | test.py:104:10:104:13 | ControlFlowNode for Subscript | Flow found | -| test.py:109:10:109:13 | ControlFlowNode for Subscript | test.py:108:22:108:27 | ControlFlowNode for SOURCE | test.py:109:10:109:13 | ControlFlowNode for Subscript | Flow found | -| test.py:115:10:115:13 | ControlFlowNode for Subscript | test.py:113:10:113:15 | ControlFlowNode for SOURCE | test.py:115:10:115:13 | ControlFlowNode for Subscript | Flow found | -| test.py:126:10:126:16 | ControlFlowNode for Attribute() | test.py:125:10:125:15 | ControlFlowNode for SOURCE | test.py:126:10:126:16 | ControlFlowNode for Attribute() | Flow found | -| test.py:131:10:131:16 | ControlFlowNode for Attribute() | test.py:130:10:130:15 | ControlFlowNode for SOURCE | test.py:131:10:131:16 | ControlFlowNode for Attribute() | Flow found | -| test.py:136:10:136:16 | ControlFlowNode for Attribute() | test.py:135:22:135:27 | ControlFlowNode for SOURCE | test.py:136:10:136:16 | ControlFlowNode for Attribute() | Flow found | -| test.py:142:10:142:16 | ControlFlowNode for Attribute() | test.py:140:10:140:15 | ControlFlowNode for SOURCE | test.py:142:10:142:16 | ControlFlowNode for Attribute() | Flow found | -| test.py:153:10:153:15 | ControlFlowNode for Subscript | test.py:152:15:152:20 | ControlFlowNode for SOURCE | test.py:153:10:153:15 | ControlFlowNode for Subscript | Flow found | -| test.py:158:10:158:19 | ControlFlowNode for Attribute() | test.py:157:15:157:20 | ControlFlowNode for SOURCE | test.py:158:10:158:19 | ControlFlowNode for Attribute() | Flow found | -| test.py:184:10:184:13 | ControlFlowNode for Subscript | test.py:183:23:183:28 | ControlFlowNode for SOURCE | test.py:184:10:184:13 | ControlFlowNode for Subscript | Flow found | -| test.py:189:10:189:13 | ControlFlowNode for Subscript | test.py:188:25:188:30 | ControlFlowNode for SOURCE | test.py:189:10:189:13 | ControlFlowNode for Subscript | Flow found | -| test.py:200:10:200:13 | ControlFlowNode for Subscript | test.py:199:34:199:39 | ControlFlowNode for SOURCE | test.py:200:10:200:13 | ControlFlowNode for Subscript | Flow found | -| test.py:206:10:206:13 | ControlFlowNode for Subscript | test.py:205:28:205:33 | ControlFlowNode for SOURCE | test.py:206:10:206:13 | ControlFlowNode for Subscript | Flow found | -| test.py:211:10:211:13 | ControlFlowNode for Subscript | test.py:210:32:210:37 | ControlFlowNode for SOURCE | test.py:211:10:211:13 | ControlFlowNode for Subscript | Flow found | -| test.py:349:10:349:21 | ControlFlowNode for Subscript | test.py:349:11:349:16 | ControlFlowNode for SOURCE | test.py:349:10:349:21 | ControlFlowNode for Subscript | Flow found | -| test.py:353:10:353:20 | ControlFlowNode for Subscript | test.py:353:11:353:16 | ControlFlowNode for SOURCE | test.py:353:10:353:20 | ControlFlowNode for Subscript | Flow found | -| test.py:357:10:357:27 | ControlFlowNode for Subscript | test.py:357:16:357:21 | ControlFlowNode for SOURCE | test.py:357:10:357:27 | ControlFlowNode for Subscript | Flow found | -| test.py:380:10:380:34 | ControlFlowNode for second() | test.py:380:28:380:33 | ControlFlowNode for SOURCE | test.py:380:10:380:34 | ControlFlowNode for second() | Flow found | -| test.py:388:10:388:36 | ControlFlowNode for second() | test.py:388:30:388:35 | ControlFlowNode for SOURCE | test.py:388:10:388:36 | ControlFlowNode for second() | Flow found | -| test.py:396:10:396:43 | ControlFlowNode for second() | test.py:396:36:396:41 | ControlFlowNode for SOURCE | test.py:396:10:396:43 | ControlFlowNode for second() | Flow found | -| test.py:404:10:404:39 | ControlFlowNode for f_extra_pos() | test.py:404:33:404:38 | ControlFlowNode for SOURCE | test.py:404:10:404:39 | ControlFlowNode for f_extra_pos() | Flow found | -| test.py:412:10:412:45 | ControlFlowNode for f_extra_keyword() | test.py:412:39:412:44 | ControlFlowNode for SOURCE | test.py:412:10:412:45 | ControlFlowNode for f_extra_keyword() | Flow found | -| test.py:429:10:429:20 | ControlFlowNode for BoolExpr | test.py:429:15:429:20 | ControlFlowNode for SOURCE | test.py:429:10:429:20 | ControlFlowNode for BoolExpr | Flow found | -| test.py:434:10:434:21 | ControlFlowNode for BoolExpr | test.py:434:16:434:21 | ControlFlowNode for SOURCE | test.py:434:10:434:21 | ControlFlowNode for BoolExpr | Flow found | -| test.py:445:10:445:38 | ControlFlowNode for IfExp | test.py:445:10:445:15 | ControlFlowNode for SOURCE | test.py:445:10:445:38 | ControlFlowNode for IfExp | Flow found | -| test.py:453:10:453:39 | ControlFlowNode for IfExp | test.py:453:34:453:39 | ControlFlowNode for SOURCE | test.py:453:10:453:39 | ControlFlowNode for IfExp | Flow found | -| test.py:477:10:477:18 | ControlFlowNode for f() | test.py:477:12:477:17 | ControlFlowNode for SOURCE | test.py:477:10:477:18 | ControlFlowNode for f() | Flow found | -| test.py:484:10:484:34 | ControlFlowNode for second() | test.py:484:28:484:33 | ControlFlowNode for SOURCE | test.py:484:10:484:34 | ControlFlowNode for second() | Flow found | -| test.py:498:10:498:36 | ControlFlowNode for second() | test.py:498:30:498:35 | ControlFlowNode for SOURCE | test.py:498:10:498:36 | ControlFlowNode for second() | Flow found | -| test.py:512:10:512:43 | ControlFlowNode for second() | test.py:512:36:512:41 | ControlFlowNode for SOURCE | test.py:512:10:512:43 | ControlFlowNode for second() | Flow found | -| test.py:517:10:517:39 | ControlFlowNode for f_extra_pos() | test.py:517:33:517:38 | ControlFlowNode for SOURCE | test.py:517:10:517:39 | ControlFlowNode for f_extra_pos() | Flow found | -| test.py:522:10:522:45 | ControlFlowNode for f_extra_keyword() | test.py:522:39:522:44 | ControlFlowNode for SOURCE | test.py:522:10:522:45 | ControlFlowNode for f_extra_keyword() | Flow found | -| test.py:536:10:536:10 | ControlFlowNode for a | test.py:534:9:534:14 | ControlFlowNode for SOURCE | test.py:536:10:536:10 | ControlFlowNode for a | Flow found | -| test.py:541:10:541:10 | ControlFlowNode for b | test.py:534:9:534:14 | ControlFlowNode for SOURCE | test.py:541:10:541:10 | ControlFlowNode for b | Flow found | -| test.py:548:10:548:10 | ControlFlowNode for a | test.py:546:10:546:15 | ControlFlowNode for SOURCE | test.py:548:10:548:10 | ControlFlowNode for a | Flow found | -| test.py:556:10:556:10 | ControlFlowNode for a | test.py:554:10:554:15 | ControlFlowNode for SOURCE | test.py:556:10:556:10 | ControlFlowNode for a | Flow found | -| test.py:558:10:558:10 | ControlFlowNode for c | test.py:554:30:554:35 | ControlFlowNode for SOURCE | test.py:558:10:558:10 | ControlFlowNode for c | Flow found | -| test.py:565:10:565:10 | ControlFlowNode for a | test.py:563:13:563:18 | ControlFlowNode for SOURCE | test.py:565:10:565:10 | ControlFlowNode for a | Flow found | -| test.py:573:10:573:10 | ControlFlowNode for a | test.py:571:10:571:15 | ControlFlowNode for SOURCE | test.py:573:10:573:10 | ControlFlowNode for a | Flow found | -| test.py:575:10:575:13 | ControlFlowNode for Subscript | test.py:571:18:571:23 | ControlFlowNode for SOURCE | test.py:575:10:575:13 | ControlFlowNode for Subscript | Flow found | -| test.py:576:12:576:12 | ControlFlowNode for c | test.py:571:18:571:23 | ControlFlowNode for SOURCE | test.py:576:12:576:12 | ControlFlowNode for c | Flow found | -| test.py:583:10:583:10 | ControlFlowNode for a | test.py:581:10:581:15 | ControlFlowNode for SOURCE | test.py:583:10:583:10 | ControlFlowNode for a | Flow found | -| test.py:585:10:585:10 | ControlFlowNode for c | test.py:581:18:581:23 | ControlFlowNode for SOURCE | test.py:585:10:585:10 | ControlFlowNode for c | Flow found | -| test.py:594:10:594:11 | ControlFlowNode for a1 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:594:10:594:11 | ControlFlowNode for a1 | Flow found | -| test.py:594:10:594:11 | ControlFlowNode for a1 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:594:10:594:11 | ControlFlowNode for a1 | Flow found | -| test.py:594:10:594:11 | ControlFlowNode for a1 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:594:10:594:11 | ControlFlowNode for a1 | Flow found | -| test.py:595:12:595:13 | ControlFlowNode for a2 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:595:12:595:13 | ControlFlowNode for a2 | Flow found | -| test.py:595:12:595:13 | ControlFlowNode for a2 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:595:12:595:13 | ControlFlowNode for a2 | Flow found | -| test.py:595:12:595:13 | ControlFlowNode for a2 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:595:12:595:13 | ControlFlowNode for a2 | Flow found | -| test.py:596:10:596:11 | ControlFlowNode for a3 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:596:10:596:11 | ControlFlowNode for a3 | Flow found | -| test.py:596:10:596:11 | ControlFlowNode for a3 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:596:10:596:11 | ControlFlowNode for a3 | Flow found | -| test.py:596:10:596:11 | ControlFlowNode for a3 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:596:10:596:11 | ControlFlowNode for a3 | Flow found | -| test.py:602:10:602:11 | ControlFlowNode for a1 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:602:10:602:11 | ControlFlowNode for a1 | Flow found | -| test.py:602:10:602:11 | ControlFlowNode for a1 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:602:10:602:11 | ControlFlowNode for a1 | Flow found | -| test.py:602:10:602:11 | ControlFlowNode for a1 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:602:10:602:11 | ControlFlowNode for a1 | Flow found | -| test.py:603:12:603:13 | ControlFlowNode for a2 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:603:12:603:13 | ControlFlowNode for a2 | Flow found | -| test.py:603:12:603:13 | ControlFlowNode for a2 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:603:12:603:13 | ControlFlowNode for a2 | Flow found | -| test.py:603:12:603:13 | ControlFlowNode for a2 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:603:12:603:13 | ControlFlowNode for a2 | Flow found | -| test.py:604:10:604:11 | ControlFlowNode for a3 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:604:10:604:11 | ControlFlowNode for a3 | Flow found | -| test.py:604:10:604:11 | ControlFlowNode for a3 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:604:10:604:11 | ControlFlowNode for a3 | Flow found | -| test.py:604:10:604:11 | ControlFlowNode for a3 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:604:10:604:11 | ControlFlowNode for a3 | Flow found | -| test.py:610:10:610:11 | ControlFlowNode for a1 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:610:10:610:11 | ControlFlowNode for a1 | Flow found | -| test.py:610:10:610:11 | ControlFlowNode for a1 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:610:10:610:11 | ControlFlowNode for a1 | Flow found | -| test.py:610:10:610:11 | ControlFlowNode for a1 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:610:10:610:11 | ControlFlowNode for a1 | Flow found | -| test.py:611:12:611:13 | ControlFlowNode for a2 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:611:12:611:13 | ControlFlowNode for a2 | Flow found | -| test.py:611:12:611:13 | ControlFlowNode for a2 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:611:12:611:13 | ControlFlowNode for a2 | Flow found | -| test.py:611:12:611:13 | ControlFlowNode for a2 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:611:12:611:13 | ControlFlowNode for a2 | Flow found | -| test.py:612:10:612:11 | ControlFlowNode for a3 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:612:10:612:11 | ControlFlowNode for a3 | Flow found | -| test.py:612:10:612:11 | ControlFlowNode for a3 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:612:10:612:11 | ControlFlowNode for a3 | Flow found | -| test.py:612:10:612:11 | ControlFlowNode for a3 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:612:10:612:11 | ControlFlowNode for a3 | Flow found | -| test.py:622:10:622:11 | ControlFlowNode for a1 | test.py:618:12:618:17 | ControlFlowNode for SOURCE | test.py:622:10:622:11 | ControlFlowNode for a1 | Flow found | -| test.py:624:12:624:16 | ControlFlowNode for Subscript | test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:624:12:624:16 | ControlFlowNode for Subscript | Flow found | -| test.py:625:10:625:14 | ControlFlowNode for Subscript | test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:625:10:625:14 | ControlFlowNode for Subscript | Flow found | -| test.py:631:10:631:11 | ControlFlowNode for a1 | test.py:618:12:618:17 | ControlFlowNode for SOURCE | test.py:631:10:631:11 | ControlFlowNode for a1 | Flow found | -| test.py:633:12:633:16 | ControlFlowNode for Subscript | test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:633:12:633:16 | ControlFlowNode for Subscript | Flow found | -| test.py:634:10:634:14 | ControlFlowNode for Subscript | test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:634:10:634:14 | ControlFlowNode for Subscript | Flow found | -| test.py:640:10:640:11 | ControlFlowNode for a1 | test.py:618:12:618:17 | ControlFlowNode for SOURCE | test.py:640:10:640:11 | ControlFlowNode for a1 | Flow found | -| test.py:642:12:642:16 | ControlFlowNode for Subscript | test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:642:12:642:16 | ControlFlowNode for Subscript | Flow found | -| test.py:643:10:643:14 | ControlFlowNode for Subscript | test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:643:10:643:14 | ControlFlowNode for Subscript | Flow found | -| test.py:649:10:649:11 | ControlFlowNode for a1 | test.py:618:12:618:17 | ControlFlowNode for SOURCE | test.py:649:10:649:11 | ControlFlowNode for a1 | Flow found | -| test.py:651:12:651:16 | ControlFlowNode for Subscript | test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:651:12:651:16 | ControlFlowNode for Subscript | Flow found | -| test.py:652:10:652:14 | ControlFlowNode for Subscript | test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:652:10:652:14 | ControlFlowNode for Subscript | Flow found | -| test.py:660:10:660:10 | ControlFlowNode for a | test.py:659:19:659:24 | ControlFlowNode for SOURCE | test.py:660:10:660:10 | ControlFlowNode for a | Flow found | -| test.py:669:14:669:14 | ControlFlowNode for x | test.py:667:12:667:17 | ControlFlowNode for SOURCE | test.py:669:14:669:14 | ControlFlowNode for x | Flow found | -| test.py:669:14:669:14 | ControlFlowNode for x | test.py:667:33:667:38 | ControlFlowNode for SOURCE | test.py:669:14:669:14 | ControlFlowNode for x | Flow found | -| test.py:678:14:678:17 | ControlFlowNode for Subscript | test.py:675:12:675:17 | ControlFlowNode for SOURCE | test.py:678:14:678:17 | ControlFlowNode for Subscript | Flow found | -| test.py:678:14:678:17 | ControlFlowNode for Subscript | test.py:675:33:675:38 | ControlFlowNode for SOURCE | test.py:678:14:678:17 | ControlFlowNode for Subscript | Flow found | -| test.py:679:16:679:16 | ControlFlowNode for y | test.py:675:12:675:17 | ControlFlowNode for SOURCE | test.py:679:16:679:16 | ControlFlowNode for y | Flow found | -| test.py:679:16:679:16 | ControlFlowNode for y | test.py:675:33:675:38 | ControlFlowNode for SOURCE | test.py:679:16:679:16 | ControlFlowNode for y | Flow found | -| test.py:686:14:686:14 | ControlFlowNode for x | test.py:684:12:684:17 | ControlFlowNode for SOURCE | test.py:686:14:686:14 | ControlFlowNode for x | Flow found | -| test.py:686:14:686:14 | ControlFlowNode for x | test.py:684:33:684:38 | ControlFlowNode for SOURCE | test.py:686:14:686:14 | ControlFlowNode for x | Flow found | -| test.py:692:10:692:12 | ControlFlowNode for arg | test.py:697:7:697:12 | ControlFlowNode for SOURCE | test.py:692:10:692:12 | ControlFlowNode for arg | Flow found | -| test.py:692:10:692:12 | ControlFlowNode for arg | test.py:698:43:698:48 | ControlFlowNode for SOURCE | test.py:692:10:692:12 | ControlFlowNode for arg | Flow found | -| test.py:772:10:772:36 | ControlFlowNode for return_from_inner_scope() | test.py:769:16:769:21 | ControlFlowNode for SOURCE | test.py:772:10:772:36 | ControlFlowNode for return_from_inner_scope() | Flow found | -| test.py:808:10:808:10 | ControlFlowNode for x | test.py:807:37:807:42 | ControlFlowNode for SOURCE | test.py:808:10:808:10 | ControlFlowNode for x | Flow found | -| test.py:809:10:809:10 | ControlFlowNode for y | test.py:807:50:807:55 | ControlFlowNode for SOURCE | test.py:809:10:809:10 | ControlFlowNode for y | Flow found | -| test.py:810:10:810:10 | ControlFlowNode for z | test.py:807:63:807:68 | ControlFlowNode for SOURCE | test.py:810:10:810:10 | ControlFlowNode for z | Flow found | diff --git a/python/ql/test/experimental/dataflow/coverage/dataflow.ql b/python/ql/test/experimental/dataflow/coverage/dataflow.ql deleted file mode 100644 index 868f24a598f..00000000000 --- a/python/ql/test/experimental/dataflow/coverage/dataflow.ql +++ /dev/null @@ -1,11 +0,0 @@ -/** - * @kind path-problem - */ - -import python -import experimental.dataflow.testConfig -import DataFlow::PathGraph - -from TestConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "Flow found" From 0f34752f8f25821fe61b52a292256ba5fb04a307 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Fri, 1 Jul 2022 11:56:50 +0200 Subject: [PATCH 017/796] Python: Delete `classesCallGraph.ql` I don't see the value from this, so just going to outright delete it. (it actually stayed alive for quite some time in the original git history, but never seemed to be that useful.) --- .../coverage/classesCallGraph.expected | 80 ------------------- .../dataflow/coverage/classesCallGraph.ql | 37 --------- 2 files changed, 117 deletions(-) delete mode 100644 python/ql/test/experimental/dataflow/coverage/classesCallGraph.expected delete mode 100644 python/ql/test/experimental/dataflow/coverage/classesCallGraph.ql diff --git a/python/ql/test/experimental/dataflow/coverage/classesCallGraph.expected b/python/ql/test/experimental/dataflow/coverage/classesCallGraph.expected deleted file mode 100644 index f297c4be6e3..00000000000 --- a/python/ql/test/experimental/dataflow/coverage/classesCallGraph.expected +++ /dev/null @@ -1,80 +0,0 @@ -| classes.py:14:17:14:60 | ControlFlowNode for Attribute() | classes.py:14:17:14:60 | ControlFlowNode for Attribute() | -| classes.py:45:16:45:35 | ControlFlowNode for Attribute() | classes.py:45:16:45:35 | ControlFlowNode for Attribute() | -| classes.py:60:17:60:27 | [pre objCreate] ControlFlowNode for With_init() | classes.py:54:18:54:21 | ControlFlowNode for self | -| classes.py:242:9:242:24 | ControlFlowNode for set() | classes.py:242:9:242:24 | ControlFlowNode for set() | -| classes.py:247:9:247:30 | ControlFlowNode for frozenset() | classes.py:247:9:247:30 | ControlFlowNode for frozenset() | -| classes.py:252:9:252:28 | ControlFlowNode for dict() | classes.py:252:9:252:28 | ControlFlowNode for dict() | -| classes.py:559:16:559:17 | ControlFlowNode for Str | classes.py:565:5:565:22 | ControlFlowNode for Subscript | -| classes.py:565:5:565:16 | ControlFlowNode for with_getitem | classes.py:555:21:555:24 | ControlFlowNode for self | -| classes.py:565:18:565:21 | ControlFlowNode for arg2 | classes.py:555:27:555:29 | ControlFlowNode for key | -| classes.py:581:5:581:16 | ControlFlowNode for with_setitem | classes.py:570:21:570:24 | ControlFlowNode for self | -| classes.py:581:18:581:21 | ControlFlowNode for arg2 | classes.py:570:27:570:29 | ControlFlowNode for key | -| classes.py:581:26:581:29 | ControlFlowNode for arg3 | classes.py:570:32:570:36 | ControlFlowNode for value | -| classes.py:595:9:595:20 | ControlFlowNode for with_delitem | classes.py:586:21:586:24 | ControlFlowNode for self | -| classes.py:595:22:595:25 | ControlFlowNode for arg2 | classes.py:586:27:586:29 | ControlFlowNode for key | -| classes.py:618:16:618:28 | ControlFlowNode for Attribute() | classes.py:618:16:618:28 | ControlFlowNode for Attribute() | -| classes.py:659:15:659:18 | ControlFlowNode for self | classes.py:667:5:667:19 | ControlFlowNode for BinaryExpr | -| classes.py:661:16:661:19 | ControlFlowNode for self | classes.py:667:5:667:19 | ControlFlowNode for BinaryExpr | -| classes.py:667:5:667:12 | ControlFlowNode for with_add | classes.py:657:17:657:20 | ControlFlowNode for self | -| classes.py:667:5:667:12 | ControlFlowNode for with_add | classes.py:667:5:667:19 | ControlFlowNode for BinaryExpr | -| classes.py:667:16:667:19 | ControlFlowNode for arg2 | classes.py:657:23:657:27 | ControlFlowNode for other | -| classes.py:674:15:674:18 | ControlFlowNode for self | classes.py:682:5:682:19 | ControlFlowNode for BinaryExpr | -| classes.py:676:16:676:19 | ControlFlowNode for self | classes.py:682:5:682:19 | ControlFlowNode for BinaryExpr | -| classes.py:682:5:682:12 | ControlFlowNode for with_sub | classes.py:672:17:672:20 | ControlFlowNode for self | -| classes.py:682:5:682:12 | ControlFlowNode for with_sub | classes.py:682:5:682:19 | ControlFlowNode for BinaryExpr | -| classes.py:682:16:682:19 | ControlFlowNode for arg2 | classes.py:672:23:672:27 | ControlFlowNode for other | -| classes.py:689:15:689:18 | ControlFlowNode for self | classes.py:697:5:697:19 | ControlFlowNode for BinaryExpr | -| classes.py:691:16:691:19 | ControlFlowNode for self | classes.py:697:5:697:19 | ControlFlowNode for BinaryExpr | -| classes.py:697:5:697:12 | ControlFlowNode for with_mul | classes.py:687:17:687:20 | ControlFlowNode for self | -| classes.py:697:5:697:12 | ControlFlowNode for with_mul | classes.py:697:5:697:19 | ControlFlowNode for BinaryExpr | -| classes.py:697:16:697:19 | ControlFlowNode for arg2 | classes.py:687:23:687:27 | ControlFlowNode for other | -| classes.py:704:15:704:18 | ControlFlowNode for self | classes.py:712:5:712:22 | ControlFlowNode for BinaryExpr | -| classes.py:706:16:706:19 | ControlFlowNode for self | classes.py:712:5:712:22 | ControlFlowNode for BinaryExpr | -| classes.py:712:5:712:15 | ControlFlowNode for with_matmul | classes.py:702:20:702:23 | ControlFlowNode for self | -| classes.py:712:5:712:15 | ControlFlowNode for with_matmul | classes.py:712:5:712:22 | ControlFlowNode for BinaryExpr | -| classes.py:712:19:712:22 | ControlFlowNode for arg2 | classes.py:702:26:702:30 | ControlFlowNode for other | -| classes.py:719:15:719:18 | ControlFlowNode for self | classes.py:727:5:727:23 | ControlFlowNode for BinaryExpr | -| classes.py:721:16:721:19 | ControlFlowNode for self | classes.py:727:5:727:23 | ControlFlowNode for BinaryExpr | -| classes.py:727:5:727:16 | ControlFlowNode for with_truediv | classes.py:717:21:717:24 | ControlFlowNode for self | -| classes.py:727:5:727:16 | ControlFlowNode for with_truediv | classes.py:727:5:727:23 | ControlFlowNode for BinaryExpr | -| classes.py:727:20:727:23 | ControlFlowNode for arg2 | classes.py:717:27:717:31 | ControlFlowNode for other | -| classes.py:734:15:734:18 | ControlFlowNode for self | classes.py:742:5:742:25 | ControlFlowNode for BinaryExpr | -| classes.py:736:16:736:19 | ControlFlowNode for self | classes.py:742:5:742:25 | ControlFlowNode for BinaryExpr | -| classes.py:742:5:742:17 | ControlFlowNode for with_floordiv | classes.py:732:22:732:25 | ControlFlowNode for self | -| classes.py:742:5:742:17 | ControlFlowNode for with_floordiv | classes.py:742:5:742:25 | ControlFlowNode for BinaryExpr | -| classes.py:742:22:742:25 | ControlFlowNode for arg2 | classes.py:732:28:732:32 | ControlFlowNode for other | -| classes.py:749:15:749:18 | ControlFlowNode for self | classes.py:757:5:757:19 | ControlFlowNode for BinaryExpr | -| classes.py:751:16:751:19 | ControlFlowNode for self | classes.py:757:5:757:19 | ControlFlowNode for BinaryExpr | -| classes.py:757:5:757:12 | ControlFlowNode for with_mod | classes.py:747:17:747:20 | ControlFlowNode for self | -| classes.py:757:5:757:12 | ControlFlowNode for with_mod | classes.py:757:5:757:19 | ControlFlowNode for BinaryExpr | -| classes.py:757:16:757:19 | ControlFlowNode for arg2 | classes.py:747:23:747:27 | ControlFlowNode for other | -| classes.py:779:15:779:18 | ControlFlowNode for self | classes.py:793:5:793:20 | ControlFlowNode for BinaryExpr | -| classes.py:781:16:781:19 | ControlFlowNode for self | classes.py:793:5:793:20 | ControlFlowNode for BinaryExpr | -| classes.py:793:5:793:12 | ControlFlowNode for with_pow | classes.py:777:17:777:20 | ControlFlowNode for self | -| classes.py:793:5:793:12 | ControlFlowNode for with_pow | classes.py:793:5:793:20 | ControlFlowNode for BinaryExpr | -| classes.py:793:17:793:20 | ControlFlowNode for arg2 | classes.py:777:23:777:27 | ControlFlowNode for other | -| classes.py:800:15:800:18 | ControlFlowNode for self | classes.py:808:5:808:23 | ControlFlowNode for BinaryExpr | -| classes.py:802:16:802:19 | ControlFlowNode for self | classes.py:808:5:808:23 | ControlFlowNode for BinaryExpr | -| classes.py:808:5:808:15 | ControlFlowNode for with_lshift | classes.py:798:20:798:23 | ControlFlowNode for self | -| classes.py:808:5:808:15 | ControlFlowNode for with_lshift | classes.py:808:5:808:23 | ControlFlowNode for BinaryExpr | -| classes.py:808:20:808:23 | ControlFlowNode for arg2 | classes.py:798:26:798:30 | ControlFlowNode for other | -| classes.py:815:15:815:18 | ControlFlowNode for self | classes.py:823:5:823:23 | ControlFlowNode for BinaryExpr | -| classes.py:817:16:817:19 | ControlFlowNode for self | classes.py:823:5:823:23 | ControlFlowNode for BinaryExpr | -| classes.py:823:5:823:15 | ControlFlowNode for with_rshift | classes.py:813:20:813:23 | ControlFlowNode for self | -| classes.py:823:5:823:15 | ControlFlowNode for with_rshift | classes.py:823:5:823:23 | ControlFlowNode for BinaryExpr | -| classes.py:823:20:823:23 | ControlFlowNode for arg2 | classes.py:813:26:813:30 | ControlFlowNode for other | -| classes.py:830:15:830:18 | ControlFlowNode for self | classes.py:838:5:838:19 | ControlFlowNode for BinaryExpr | -| classes.py:832:16:832:19 | ControlFlowNode for self | classes.py:838:5:838:19 | ControlFlowNode for BinaryExpr | -| classes.py:838:5:838:12 | ControlFlowNode for with_and | classes.py:828:17:828:20 | ControlFlowNode for self | -| classes.py:838:5:838:12 | ControlFlowNode for with_and | classes.py:838:5:838:19 | ControlFlowNode for BinaryExpr | -| classes.py:838:16:838:19 | ControlFlowNode for arg2 | classes.py:828:23:828:27 | ControlFlowNode for other | -| classes.py:845:15:845:18 | ControlFlowNode for self | classes.py:853:5:853:19 | ControlFlowNode for BinaryExpr | -| classes.py:847:16:847:19 | ControlFlowNode for self | classes.py:853:5:853:19 | ControlFlowNode for BinaryExpr | -| classes.py:853:5:853:12 | ControlFlowNode for with_xor | classes.py:843:17:843:20 | ControlFlowNode for self | -| classes.py:853:5:853:12 | ControlFlowNode for with_xor | classes.py:853:5:853:19 | ControlFlowNode for BinaryExpr | -| classes.py:853:16:853:19 | ControlFlowNode for arg2 | classes.py:843:23:843:27 | ControlFlowNode for other | -| classes.py:860:15:860:18 | ControlFlowNode for self | classes.py:868:5:868:18 | ControlFlowNode for BinaryExpr | -| classes.py:862:16:862:19 | ControlFlowNode for self | classes.py:868:5:868:18 | ControlFlowNode for BinaryExpr | -| classes.py:868:5:868:11 | ControlFlowNode for with_or | classes.py:858:16:858:19 | ControlFlowNode for self | -| classes.py:868:5:868:11 | ControlFlowNode for with_or | classes.py:868:5:868:18 | ControlFlowNode for BinaryExpr | -| classes.py:868:15:868:18 | ControlFlowNode for arg2 | classes.py:858:22:858:26 | ControlFlowNode for other | diff --git a/python/ql/test/experimental/dataflow/coverage/classesCallGraph.ql b/python/ql/test/experimental/dataflow/coverage/classesCallGraph.ql deleted file mode 100644 index c1b66d0f323..00000000000 --- a/python/ql/test/experimental/dataflow/coverage/classesCallGraph.ql +++ /dev/null @@ -1,37 +0,0 @@ -import semmle.python.dataflow.new.DataFlow -private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPrivate - -/** - * A configuration to find the call graph edges. - */ -class CallGraphConfig extends DataFlow::Configuration { - CallGraphConfig() { this = "CallGraphConfig" } - - override predicate isSource(DataFlow::Node node) { - node instanceof DataFlowPrivate::ReturnNode - or - // These sources should allow for the non-standard call syntax - node instanceof DataFlow::ArgumentNode - } - - override predicate isSink(DataFlow::Node node) { - node instanceof DataFlowPrivate::OutNode - or - node instanceof DataFlow::ParameterNode and - // exclude parameters to the SINK-functions - not exists(DataFlowPrivate::DataFlowCallable c | - c.getParameter(_) = node.asCfgNode() and - c.getName().matches("SINK_") - ) - } -} - -from DataFlow::Node source, DataFlow::Node sink -where - source.getLocation().getFile().getBaseName() = "classes.py" and - sink.getLocation().getFile().getBaseName() = "classes.py" and - exists(CallGraphConfig cfg | cfg.hasFlow(source, sink)) -select source, sink -// Ideally, we would just have 1-step paths either from argument to parameter -// or from return to call. This gives a bit more, so should be rewritten. -// We should also consider splitting this into two, one for each direction. From c1b256159817c5d7e400a942577d328a099df620 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 22 Jun 2022 15:06:21 +0200 Subject: [PATCH 018/796] Python: Extend fieldflow tests with bound method call --- .../experimental/dataflow/fieldflow/test.py | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/python/ql/test/experimental/dataflow/fieldflow/test.py b/python/ql/test/experimental/dataflow/fieldflow/test.py index d8d4b5f6fe0..c7a2bc50a14 100644 --- a/python/ql/test/experimental/dataflow/fieldflow/test.py +++ b/python/ql/test/experimental/dataflow/fieldflow/test.py @@ -160,6 +160,40 @@ def test_nested_obj_method(): a.getObj().foo = x SINK(a.obj.foo) # $ flow="SOURCE, l:-3 -> a.obj.foo" +# ------------------------------------------------------------------------------ +# Bound Method calls +# ------------------------------------------------------------------------------ + +class Foo: + def __init__(self, x): + self.x = x + + def update_x(self, x): + self.x = x + +@expects(7) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) +def test_bound_method_call(): + # direct assignment + foo = Foo(None) + SINK_F(foo.x) + foo.x = SOURCE + SINK(foo.x) # $ flow="SOURCE, l:-1 -> foo.x" + foo.x = None + SINK_F(foo.x) + + # assignment through function + foo = Foo(SOURCE) + SINK(foo.x) # $ flow="SOURCE, l:-1 -> foo.x" + foo.update_x(None) + SINK_F(foo.x) # $ flow="SOURCE, l:-3 -> foo.x" + + # assignment through bound-method calls + foo = Foo(SOURCE) + ux = foo.update_x + SINK(foo.x) # $ flow="SOURCE, l:-2 -> foo.x" + ux(None) + SINK_F(foo.x) # $ SPURIOUS: flow="SOURCE, l:-4 -> foo.x" + # ------------------------------------------------------------------------------ # Global scope # ------------------------------------------------------------------------------ From 6577281bed5a7c9bc4696f01f07362b5fe4c8ede Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 28 Jul 2022 10:57:08 +0200 Subject: [PATCH 019/796] Python: Add crosstalk fieldflow test --- .../experimental/dataflow/fieldflow/test.py | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/python/ql/test/experimental/dataflow/fieldflow/test.py b/python/ql/test/experimental/dataflow/fieldflow/test.py index c7a2bc50a14..70db8554241 100644 --- a/python/ql/test/experimental/dataflow/fieldflow/test.py +++ b/python/ql/test/experimental/dataflow/fieldflow/test.py @@ -194,6 +194,128 @@ def test_bound_method_call(): ux(None) SINK_F(foo.x) # $ SPURIOUS: flow="SOURCE, l:-4 -> foo.x" + +# ------------------------------------------------------------------------------ +# Crosstalk test -- using different function based on conditional +# ------------------------------------------------------------------------------ + +class CrosstalkTestX: + def __init__(self): + self.x = None + self.y = None + + def setx(self, value): + self.x = value + + def setvalue(self, value): + self.x = value + + +class CrosstalkTestY: + def __init__(self): + self.x = None + self.y = None + + def sety(self ,value): + self.y = value + + def setvalue(self, value): + self.y = value + + +@expects(8) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) +def test_no_crosstalk_reference(cond=True): + objx = CrosstalkTestX() + SINK_F(objx.x) + SINK_F(objx.y) + + objy = CrosstalkTestY() + SINK_F(objy.x) + SINK_F(objy.y) + + if cond: + objx.setvalue(SOURCE) + else: + objy.setvalue(SOURCE) + + SINK(objx.x) # $ flow="SOURCE, l:-4 -> objx.x" + SINK_F(objx.y) + SINK_F(objy.x) + SINK_F(objy.y) # $ flow="SOURCE, l:-5 -> objy.y" + + +@expects(8) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) +def test_potential_crosstalk_different_name(cond=True): + objx = CrosstalkTestX() + SINK_F(objx.x) + SINK_F(objx.y) + + objy = CrosstalkTestY() + SINK_F(objy.x) + SINK_F(objy.y) + + if cond: + func = objx.setx + else: + func = objy.sety + + func(SOURCE) + + SINK(objx.x) # $ MISSING: flow="SOURCE, l:-2 -> objx.x" + SINK_F(objx.y) + SINK_F(objy.x) + SINK_F(objy.y) # $ MISSING: flow="SOURCE, l:-5 -> objy.y" + + +@expects(8) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) +def test_potential_crosstalk_same_name(cond=True): + objx = CrosstalkTestX() + SINK_F(objx.x) + SINK_F(objx.y) + + objy = CrosstalkTestY() + SINK_F(objy.x) + SINK_F(objy.y) + + if cond: + func = objx.setvalue + else: + func = objy.setvalue + + func(SOURCE) + + SINK(objx.x) # $ MISSING: flow="SOURCE, l:-2 -> objx.x" + SINK_F(objx.y) + SINK_F(objy.x) + SINK_F(objy.y) # $ MISSING: flow="SOURCE, l:-5 -> objy.y" + + +@expects(10) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) +def test_potential_crosstalk_same_name_object_reference(cond=True): + objx = CrosstalkTestX() + SINK_F(objx.x) + SINK_F(objx.y) + + objy = CrosstalkTestY() + SINK_F(objy.x) + SINK_F(objy.y) + + if cond: + obj = objx + else: + obj = objy + + obj.setvalue(SOURCE) + + SINK(objx.x) # $ MISSING: flow="SOURCE, l:-2 -> objx.x" + SINK_F(objx.y) + SINK_F(objy.x) + SINK_F(objy.y) # $ MISSING: flow="SOURCE, l:-5 -> objy.y" + + SINK(obj.x) # $ flow="SOURCE, l:-7 -> obj.x" + SINK_F(obj.y) # $ flow="SOURCE, l:-8 -> obj.y" + + # ------------------------------------------------------------------------------ # Global scope # ------------------------------------------------------------------------------ From e8fdff7a3bea1c12d87ae5e33958f8aaf71ef534 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 16 Aug 2022 14:48:41 +0200 Subject: [PATCH 020/796] Python: Expand ExternalAPIs test We never had a showcase of how keyword arguments were handled --- .../ExternalAPIsUsedWithUntrustedData.expected | 2 +- .../UntrustedDataToExternalAPI.expected | 7 +++++++ .../Security/CWE-020-ExternalAPIs/test.py | 12 ++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected index c070169615c..7438c415858 100644 --- a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected +++ b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected @@ -1 +1 @@ -| hmac.new [param 1] | 1 | 1 | +| hmac.new [param 1] | 2 | 1 | diff --git a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected index c64a6943813..e024ef20cba 100644 --- a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected +++ b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected @@ -1,9 +1,12 @@ edges | test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:13:16:13:22 | ControlFlowNode for request | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:23:16:23:22 | ControlFlowNode for request | | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:5:26:5:32 | GSSA Variable request | | test.py:5:26:5:32 | GSSA Variable request | test.py:0:0:0:0 | ModuleVariableNode for test.request | | test.py:13:16:13:22 | ControlFlowNode for request | test.py:13:16:13:27 | ControlFlowNode for Attribute | | test.py:13:16:13:27 | ControlFlowNode for Attribute | test.py:15:36:15:39 | ControlFlowNode for data | +| test.py:23:16:23:22 | ControlFlowNode for request | test.py:23:16:23:27 | ControlFlowNode for Attribute | +| test.py:23:16:23:27 | ControlFlowNode for Attribute | test.py:25:44:25:47 | ControlFlowNode for data | nodes | test.py:0:0:0:0 | ModuleVariableNode for test.request | semmle.label | ModuleVariableNode for test.request | | test.py:5:26:5:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | @@ -11,6 +14,10 @@ nodes | test.py:13:16:13:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test.py:13:16:13:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:15:36:15:39 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | +| test.py:23:16:23:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test.py:23:16:23:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:25:44:25:47 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | subpaths #select | test.py:15:36:15:39 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:15:36:15:39 | ControlFlowNode for data | Call to hmac.new [param 1] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | +| test.py:25:44:25:47 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:25:44:25:47 | ControlFlowNode for data | Call to hmac.new [param 1] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | diff --git a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/test.py b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/test.py index b88748fbb29..ca4191ded85 100644 --- a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/test.py +++ b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/test.py @@ -18,11 +18,22 @@ def hmac_example(): return "ok" +@app.route("/hmac-example2") +def hmac_example2(): + data_raw = request.args.get("data").encode('utf-8') + data = base64.decodebytes(data_raw) + my_hmac = hmac.new(key=SECRET_KEY, msg=data, digestmod=hashlib.sha256) + digest = my_hmac.digest() + print(digest) + return "ok" + + @app.route("/unknown-lib-1") def unknown_lib_1(): from unknown.lib import func data = request.args.get("data") func(data) # TODO: currently not recognized + func(kw=data) # TODO: currently not recognized @app.route("/unknown-lib-2") @@ -30,6 +41,7 @@ def unknown_lib_2(): import unknown.lib data = request.args.get("data") unknown.lib.func(data) # TODO: currently not recognized + unknown.lib.func(kw=data) # TODO: currently not recognized if __name__ == "__main__": From 08bc14f59806387599cfe38463367a2761f13cf1 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 1 Nov 2022 22:50:13 +0100 Subject: [PATCH 021/796] add failing test --- .../CWE-400/ReDoS/PolynomialBackTracking.expected | 2 ++ .../Security/CWE-400/ReDoS/PolynomialReDoS.expected | 9 +++++++++ .../test/query-tests/Security/CWE-400/ReDoS/lib/lib.js | 9 ++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialBackTracking.expected b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialBackTracking.expected index e1ad3adb91c..6ed2af353f5 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialBackTracking.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialBackTracking.expected @@ -33,6 +33,8 @@ | lib/lib.js:8:3:8:4 | f* | Strings with many repetitions of 'f' can start matching anywhere after the start of the preceeding f*g | | lib/lib.js:28:3:28:4 | f* | Strings with many repetitions of 'f' can start matching anywhere after the start of the preceeding f*g | | lib/lib.js:36:3:36:4 | f* | Strings with many repetitions of 'f' can start matching anywhere after the start of the preceeding f*g | +| lib/lib.js:42:29:42:30 | f* | Strings with many repetitions of 'f' can start matching anywhere after the start of the preceeding f*g | +| lib/lib.js:45:29:45:30 | f* | Strings with many repetitions of 'f' can start matching anywhere after the start of the preceeding f*g | | lib/moduleLib/moduleLib.js:2:3:2:4 | a* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding a*b | | lib/otherLib/js/src/index.js:2:3:2:4 | a* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding a*b | | lib/snapdragon.js:7:28:7:29 | a* | Strings starting with 'a' and with many repetitions of 'a' can start matching anywhere after the start of the preceeding aa*$ | diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected index 3df7db24964..c4076c927cd 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected @@ -28,6 +28,10 @@ nodes | lib/lib.js:35:28:35:31 | name | | lib/lib.js:36:13:36:16 | name | | lib/lib.js:36:13:36:16 | name | +| lib/lib.js:41:32:41:35 | name | +| lib/lib.js:41:32:41:35 | name | +| lib/lib.js:42:17:42:20 | name | +| lib/lib.js:42:17:42:20 | name | | lib/moduleLib/moduleLib.js:1:28:1:31 | name | | lib/moduleLib/moduleLib.js:1:28:1:31 | name | | lib/moduleLib/moduleLib.js:2:13:2:16 | name | @@ -249,6 +253,10 @@ edges | lib/lib.js:35:1:37:1 | 'arguments' object of function usedWithArguments | lib/lib.js:35:28:35:31 | name | | lib/lib.js:35:28:35:31 | name | lib/lib.js:36:13:36:16 | name | | lib/lib.js:35:28:35:31 | name | lib/lib.js:36:13:36:16 | name | +| lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | +| lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | +| lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | +| lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | | lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name | | lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name | | lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name | @@ -440,6 +448,7 @@ edges | lib/lib.js:4:2:4:18 | regexp.test(name) | lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'a'. | lib/lib.js:1:15:1:16 | a* | regular expression | lib/lib.js:3:28:3:31 | name | library input | | lib/lib.js:8:2:8:17 | /f*g/.test(name) | lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/lib.js:8:3:8:4 | f* | regular expression | lib/lib.js:7:19:7:22 | name | library input | | lib/lib.js:36:2:36:17 | /f*g/.test(name) | lib/lib.js:32:32:32:40 | arguments | lib/lib.js:36:13:36:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/lib.js:36:3:36:4 | f* | regular expression | lib/lib.js:32:32:32:40 | arguments | library input | +| lib/lib.js:42:17:42:33 | name.match(/f*g/) | lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/lib.js:42:29:42:30 | f* | regular expression | lib/lib.js:41:32:41:35 | name | library input | | lib/moduleLib/moduleLib.js:2:2:2:17 | /a*b/.test(name) | lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'a'. | lib/moduleLib/moduleLib.js:2:3:2:4 | a* | regular expression | lib/moduleLib/moduleLib.js:1:28:1:31 | name | library input | | lib/otherLib/js/src/index.js:2:2:2:17 | /a*b/.test(name) | lib/otherLib/js/src/index.js:1:28:1:31 | name | lib/otherLib/js/src/index.js:2:13:2:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'a'. | lib/otherLib/js/src/index.js:2:3:2:4 | a* | regular expression | lib/otherLib/js/src/index.js:1:28:1:31 | name | library input | | lib/snapdragon.js:7:15:7:32 | this.match(/aa*$/) | lib/snapdragon.js:3:34:3:38 | input | lib/snapdragon.js:7:15:7:18 | this | This $@ that depends on $@ may run slow on strings starting with 'a' and with many repetitions of 'a'. | lib/snapdragon.js:7:28:7:29 | a* | regular expression | lib/snapdragon.js:3:34:3:38 | input | library input | diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/lib/lib.js b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/lib/lib.js index 5c892f328a3..87b7e8292d2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/lib/lib.js +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/lib/lib.js @@ -36,4 +36,11 @@ function usedWithArguments(name) { /f*g/.test(name); // NOT OK } -module.exports.snapdragon = require("./snapdragon") \ No newline at end of file +module.exports.snapdragon = require("./snapdragon") + +module.exports.foo = function (name) { + var data1 = name.match(/f*g/); // NOT OK + + name = name.substr(1); + var data2 = name.match(/f*g/); // NOT OK - but not flagged +} \ No newline at end of file From 851d53d56b69254efcb2c1898b0e47d9fe53daa8 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 1 Nov 2022 22:51:07 +0100 Subject: [PATCH 022/796] don't sanitize calls through substring calls that just remove the start --- .../regexp/PolynomialReDoSCustomizations.qll | 3 ++- .../Security/CWE-400/ReDoS/PolynomialReDoS.expected | 12 ++++++++++++ .../query-tests/Security/CWE-400/ReDoS/lib/lib.js | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSCustomizations.qll index 87f9437196f..508eaf40e2c 100644 --- a/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSCustomizations.qll @@ -90,7 +90,8 @@ module PolynomialReDoS { isCharClassLike(root) ) or - this.(DataFlow::MethodCallNode).getMethodName() = StringOps::substringMethodName() + this.(DataFlow::MethodCallNode).getMethodName() = StringOps::substringMethodName() and + not this.(DataFlow::MethodCallNode).getNumArgument() = 1 // with one argument it just slices off the beginning } } diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected index c4076c927cd..04bf2cbad36 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected @@ -32,6 +32,11 @@ nodes | lib/lib.js:41:32:41:35 | name | | lib/lib.js:42:17:42:20 | name | | lib/lib.js:42:17:42:20 | name | +| lib/lib.js:44:5:44:25 | name | +| lib/lib.js:44:12:44:15 | name | +| lib/lib.js:44:12:44:25 | name.substr(1) | +| lib/lib.js:45:17:45:20 | name | +| lib/lib.js:45:17:45:20 | name | | lib/moduleLib/moduleLib.js:1:28:1:31 | name | | lib/moduleLib/moduleLib.js:1:28:1:31 | name | | lib/moduleLib/moduleLib.js:2:13:2:16 | name | @@ -257,6 +262,12 @@ edges | lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | | lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | | lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | +| lib/lib.js:41:32:41:35 | name | lib/lib.js:44:12:44:15 | name | +| lib/lib.js:41:32:41:35 | name | lib/lib.js:44:12:44:15 | name | +| lib/lib.js:44:5:44:25 | name | lib/lib.js:45:17:45:20 | name | +| lib/lib.js:44:5:44:25 | name | lib/lib.js:45:17:45:20 | name | +| lib/lib.js:44:12:44:15 | name | lib/lib.js:44:12:44:25 | name.substr(1) | +| lib/lib.js:44:12:44:25 | name.substr(1) | lib/lib.js:44:5:44:25 | name | | lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name | | lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name | | lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name | @@ -449,6 +460,7 @@ edges | lib/lib.js:8:2:8:17 | /f*g/.test(name) | lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/lib.js:8:3:8:4 | f* | regular expression | lib/lib.js:7:19:7:22 | name | library input | | lib/lib.js:36:2:36:17 | /f*g/.test(name) | lib/lib.js:32:32:32:40 | arguments | lib/lib.js:36:13:36:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/lib.js:36:3:36:4 | f* | regular expression | lib/lib.js:32:32:32:40 | arguments | library input | | lib/lib.js:42:17:42:33 | name.match(/f*g/) | lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/lib.js:42:29:42:30 | f* | regular expression | lib/lib.js:41:32:41:35 | name | library input | +| lib/lib.js:45:17:45:33 | name.match(/f*g/) | lib/lib.js:41:32:41:35 | name | lib/lib.js:45:17:45:20 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/lib.js:45:29:45:30 | f* | regular expression | lib/lib.js:41:32:41:35 | name | library input | | lib/moduleLib/moduleLib.js:2:2:2:17 | /a*b/.test(name) | lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'a'. | lib/moduleLib/moduleLib.js:2:3:2:4 | a* | regular expression | lib/moduleLib/moduleLib.js:1:28:1:31 | name | library input | | lib/otherLib/js/src/index.js:2:2:2:17 | /a*b/.test(name) | lib/otherLib/js/src/index.js:1:28:1:31 | name | lib/otherLib/js/src/index.js:2:13:2:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'a'. | lib/otherLib/js/src/index.js:2:3:2:4 | a* | regular expression | lib/otherLib/js/src/index.js:1:28:1:31 | name | library input | | lib/snapdragon.js:7:15:7:32 | this.match(/aa*$/) | lib/snapdragon.js:3:34:3:38 | input | lib/snapdragon.js:7:15:7:18 | this | This $@ that depends on $@ may run slow on strings starting with 'a' and with many repetitions of 'a'. | lib/snapdragon.js:7:28:7:29 | a* | regular expression | lib/snapdragon.js:3:34:3:38 | input | library input | diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/lib/lib.js b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/lib/lib.js index 87b7e8292d2..73700dfbc6b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/lib/lib.js +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/lib/lib.js @@ -42,5 +42,5 @@ module.exports.foo = function (name) { var data1 = name.match(/f*g/); // NOT OK name = name.substr(1); - var data2 = name.match(/f*g/); // NOT OK - but not flagged + var data2 = name.match(/f*g/); // NOT OK } \ No newline at end of file From 33cca29a8e8cfb7c22381caef10cf0a9149f091f Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 2 Nov 2022 11:23:01 +0100 Subject: [PATCH 023/796] drop down to the CFG instead of the AST to better support de-sugaring --- .../ruby/frameworks/StringFormatters.qll | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll b/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll index da9ce58345e..479507dd0e6 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/StringFormatters.qll @@ -87,15 +87,15 @@ class StringPercentCall extends PrintfStyleCall { override DataFlow::Node getFormatString() { result = this.getReceiver() } override DataFlow::Node getFormatArgument(int n) { - exists(Ast::Call call | call = this.asExpr().getExpr() | - exists(Ast::ArrayLiteral arrLit | arrLit = call.getArgument(0) | - result.asExpr().getExpr() = arrLit.getElement(n) - ) - or - exists(Ast::HashLiteral hashLit | hashLit = call.getArgument(0) | - n = -2 and // -2 is indicates that the index does not make sense in this context - result.asExpr().getExpr() = hashLit.getAnElement() - ) + exists(CfgNodes::ExprNodes::ArrayLiteralCfgNode arrLit | arrLit = this.getArgument(0).asExpr() | + result.asExpr() = arrLit.getArgument(n) + ) + or + exists(CfgNodes::ExprNodes::HashLiteralCfgNode hashLit | + hashLit = this.getArgument(0).asExpr() + | + n = -2 and // -2 is indicates that the index does not make sense in this context + result.asExpr() = hashLit.getAKeyValuePair().getValue() ) } From 1e3adcd14e172aff3a0a03c89181ca31ca091080 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 2 Nov 2022 11:37:37 +0100 Subject: [PATCH 024/796] Revert "Revert "SSA: Turn consistency predicates into `query` predicates"" --- .../ql/consistency-queries/SsaConsistency.ql | 12 ++--------- ruby/ql/consistency-queries/SsaConsistency.ql | 12 ++--------- shared/ssa/codeql/ssa/Ssa.qll | 20 +++++++++++-------- 3 files changed, 16 insertions(+), 28 deletions(-) diff --git a/csharp/ql/consistency-queries/SsaConsistency.ql b/csharp/ql/consistency-queries/SsaConsistency.ql index 71f88bf2ab0..bd666a71e49 100644 --- a/csharp/ql/consistency-queries/SsaConsistency.ql +++ b/csharp/ql/consistency-queries/SsaConsistency.ql @@ -1,8 +1,8 @@ import csharp -import semmle.code.csharp.dataflow.internal.SsaImpl::Consistency as Consistency +import semmle.code.csharp.dataflow.internal.SsaImpl::Consistency import Ssa -class MyRelevantDefinition extends Consistency::RelevantDefinition, Ssa::Definition { +class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition { override predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { @@ -10,14 +10,6 @@ class MyRelevantDefinition extends Consistency::RelevantDefinition, Ssa::Definit } } -query predicate nonUniqueDef = Consistency::nonUniqueDef/4; - -query predicate readWithoutDef = Consistency::readWithoutDef/3; - -query predicate deadDef = Consistency::deadDef/2; - -query predicate notDominatedByDef = Consistency::notDominatedByDef/4; - query predicate localDeclWithSsaDef(LocalVariableDeclExpr d) { // Local variables in C# must be initialized before every use, so uninitialized // local variables should not have an SSA definition, as that would imply that diff --git a/ruby/ql/consistency-queries/SsaConsistency.ql b/ruby/ql/consistency-queries/SsaConsistency.ql index 54c1b149ab2..7ba9262baa4 100644 --- a/ruby/ql/consistency-queries/SsaConsistency.ql +++ b/ruby/ql/consistency-queries/SsaConsistency.ql @@ -1,18 +1,10 @@ import codeql.ruby.dataflow.SSA -import codeql.ruby.dataflow.internal.SsaImpl::Consistency as Consistency +import codeql.ruby.dataflow.internal.SsaImpl::Consistency -class MyRelevantDefinition extends Consistency::RelevantDefinition, Ssa::Definition { +class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition { override predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) } } - -query predicate nonUniqueDef = Consistency::nonUniqueDef/4; - -query predicate readWithoutDef = Consistency::readWithoutDef/3; - -query predicate deadDef = Consistency::deadDef/2; - -query predicate notDominatedByDef = Consistency::notDominatedByDef/4; diff --git a/shared/ssa/codeql/ssa/Ssa.qll b/shared/ssa/codeql/ssa/Ssa.qll index 886e4128e26..19f31f7c8bb 100644 --- a/shared/ssa/codeql/ssa/Ssa.qll +++ b/shared/ssa/codeql/ssa/Ssa.qll @@ -9,7 +9,10 @@ signature module InputSig { * A basic block, that is, a maximal straight-line sequence of control flow nodes * without branches or joins. */ - class BasicBlock; + class BasicBlock { + /** Gets a textual representation of this basic block. */ + string toString(); + } /** * Gets the basic block that immediately dominates basic block `bb`, if any. @@ -43,7 +46,10 @@ signature module InputSig { class ExitBasicBlock extends BasicBlock; /** A variable that can be SSA converted. */ - class SourceVariable; + class SourceVariable { + /** Gets a textual representation of this variable. */ + string toString(); + } /** * Holds if the `i`th node of basic block `bb` is a (potential) write to source @@ -846,8 +852,6 @@ module Make { } /** Provides a set of consistency queries. */ - // TODO: Make these `query` predicates once class signatures are supported - // (`SourceVariable` and `BasicBlock` must have `toString`) module Consistency { /** A definition that is relevant for the consistency queries. */ abstract class RelevantDefinition extends Definition { @@ -858,19 +862,19 @@ module Make { } /** Holds if a read can be reached from multiple definitions. */ - predicate nonUniqueDef(RelevantDefinition def, SourceVariable v, BasicBlock bb, int i) { + query predicate nonUniqueDef(RelevantDefinition def, SourceVariable v, BasicBlock bb, int i) { ssaDefReachesRead(v, def, bb, i) and not exists(unique(Definition def0 | ssaDefReachesRead(v, def0, bb, i))) } /** Holds if a read cannot be reached from a definition. */ - predicate readWithoutDef(SourceVariable v, BasicBlock bb, int i) { + query predicate readWithoutDef(SourceVariable v, BasicBlock bb, int i) { variableRead(bb, i, v, _) and not ssaDefReachesRead(v, _, bb, i) } /** Holds if a definition cannot reach a read. */ - predicate deadDef(RelevantDefinition def, SourceVariable v) { + query predicate deadDef(RelevantDefinition def, SourceVariable v) { v = def.getSourceVariable() and not ssaDefReachesRead(_, def, _, _) and not phiHasInputFromBlock(_, def, _) and @@ -878,7 +882,7 @@ module Make { } /** Holds if a read is not dominated by a definition. */ - predicate notDominatedByDef(RelevantDefinition def, SourceVariable v, BasicBlock bb, int i) { + query predicate notDominatedByDef(RelevantDefinition def, SourceVariable v, BasicBlock bb, int i) { exists(BasicBlock bbDef, int iDef | def.definesAt(v, bbDef, iDef) | ssaDefReachesReadWithinBlock(v, def, bb, i) and (bb != bbDef or i < iDef) From 5c905c42b268ed3f499033eb9605f7090c3081e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Wed, 26 Oct 2022 20:23:58 +0200 Subject: [PATCH 025/796] Swift: Initial UnsafeJsEval query --- .../queries/Security/CWE-094/UnsafeJsEval.ql | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql diff --git a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql new file mode 100644 index 00000000000..ced918a64d4 --- /dev/null +++ b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql @@ -0,0 +1,119 @@ +/** + * @name JavaScript Injection + * @description Evaluating JavaScript code containing a substring from a remote source may lead to remote code execution. + * @kind path-problem + * @problem.severity warning + * @security-severity 6.1 + * @precision high + * @id swift/unsafe-js-eval + * @tags security + * external/cwe/cwe-094 + * external/cwe/cwe-095 + * external/cwe/cwe-749 + */ + +import swift +import codeql.swift.dataflow.DataFlow +import codeql.swift.dataflow.TaintTracking +import codeql.swift.dataflow.FlowSources +import DataFlow::PathGraph + +/** + * A source of untrusted, user-controlled data. + * TODO: Extend to more (non-remote) sources in the future. + */ +class Source = RemoteFlowSource; + +/** + * A sink that evaluates a string of JavaScript code. + */ +abstract class Sink extends DataFlow::Node { } + +class WKWebView extends Sink { + WKWebView() { + any(CallExpr ce | + ce.getStaticTarget() = + getMethodWithQualifiedName("WKWebView", + [ + "evaluateJavaScript(_:completionHandler:)", + "evaluateJavaScript(_:in:in:completionHandler:)", + "evaluateJavaScript(_:in:contentWorld:)", + "callAsyncJavaScript(_:arguments:in:in:completionHandler:)", + "callAsyncJavaScript(_:arguments:in:contentWorld:)" + ]) + ).getArgument(0).getExpr() = this.asExpr() + } +} + +class WKUserContentController extends Sink { + WKUserContentController() { + any(CallExpr ce | + ce.getStaticTarget() = + getMethodWithQualifiedName("WKUserContentController", "addUserScript(_:)") + ).getArgument(0).getExpr() = this.asExpr() + } +} + +class UIWebView extends Sink { + UIWebView() { + any(CallExpr ce | + ce.getStaticTarget() = + getMethodWithQualifiedName(["UIWebView", "WebView"], "stringByEvaluatingJavaScript(from:)") + ).getArgument(0).getExpr() = this.asExpr() + } +} + +class JSContext extends Sink { + JSContext() { + any(CallExpr ce | + ce.getStaticTarget() = + getMethodWithQualifiedName("JSContext", + ["evaluateScript(_:)", "evaluateScript(_:withSourceURL:)"]) + ).getArgument(0).getExpr() = this.asExpr() + } +} + +class JSEvaluateScript extends Sink { + JSEvaluateScript() { + any(CallExpr ce | + ce.getStaticTarget() = getFunctionWithQualifiedName("JSEvaluateScript(_:_:_:_:_:_:)") + ).getArgument(1).getExpr() = this.asExpr() + } +} + +// TODO: Consider moving the following to the library, e.g. +// - Decl.hasQualifiedName(moduleName?, declaringDeclName?, declName) +// - parentDecl = memberDecl.getDeclaringDecl() <=> parentDecl.getAMember() = memberDecl +IterableDeclContext getDeclaringDeclOf(Decl member) { result.getAMember() = member } + +MethodDecl getMethodWithQualifiedName(string className, string methodName) { + result.getName() = methodName and + getDeclaringDeclOf(result).(NominalTypeDecl).getName() = className +} + +AbstractFunctionDecl getFunctionWithQualifiedName(string funcName) { + result.getName() = funcName and + not result.hasSelfParam() +} + +/** + * A taint configuration from taint sources to sinks for this query. + */ +class UnsafeJsEvalConfig extends TaintTracking::Configuration { + UnsafeJsEvalConfig() { this = "UnsafeJsEvalConfig" } + + override predicate isSource(DataFlow::Node node) { node instanceof Source } + + override predicate isSink(DataFlow::Node node) { node instanceof Sink } + + override predicate isSanitizer(DataFlow::Node node) { + none() // TODO: A conversion to a primitive type or an enum + } +} + +from + UnsafeJsEvalConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode, Sink sink +where + config.hasFlowPath(sourceNode, sinkNode) and + sink = sinkNode.getNode() +select sink, sourceNode, sinkNode, "Evaluation of uncontrolled JavaScript from a remote source." From 7b599f5fefecf3e4798c4ed2211a8d2c7d692c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Thu, 27 Oct 2022 11:42:22 +0200 Subject: [PATCH 026/796] Swift: Add async varant of WKWebView evaluateJavaScript(_:) See concurrency note here: https://developer.apple.com/documentation/webkit/wkwebview/1415017-evaluatejavascript See also https://developer.apple.com/documentation/swift/calling-objective-c-apis-asynchronously --- swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql index ced918a64d4..53891e2c03d 100644 --- a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql +++ b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql @@ -35,7 +35,7 @@ class WKWebView extends Sink { ce.getStaticTarget() = getMethodWithQualifiedName("WKWebView", [ - "evaluateJavaScript(_:completionHandler:)", + "evaluateJavaScript(_:)", "evaluateJavaScript(_:completionHandler:)", "evaluateJavaScript(_:in:in:completionHandler:)", "evaluateJavaScript(_:in:contentWorld:)", "callAsyncJavaScript(_:arguments:in:in:completionHandler:)", From 28b7f0884f6d88f3e7f81d7f9a531ed4b22c0b64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Wed, 2 Nov 2022 12:49:59 +0100 Subject: [PATCH 027/796] Swift: UnsafeJsEval test finally compiles --- .../Security/CWE-094/UnsafeJsEval.expected | 0 .../Security/CWE-094/UnsafeJsEval.qlref | 1 + .../Security/CWE-094/UnsafeJsEval.swift | 299 ++++++++++++++++++ 3 files changed, 300 insertions(+) create mode 100644 swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected create mode 100644 swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.qlref create mode 100644 swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.swift diff --git a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.qlref b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.qlref new file mode 100644 index 00000000000..b8c11cee30d --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.qlref @@ -0,0 +1 @@ +queries/Security/CWE-094/UnsafeJsEval.ql diff --git a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.swift b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.swift new file mode 100644 index 00000000000..51914bd97e1 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.swift @@ -0,0 +1,299 @@ + +// --- stubs --- + +class NSObject {} + +@MainActor class UIResponder : NSObject {} +@MainActor class UIView : UIResponder {} + +@MainActor class NSResponder : NSObject {} +class NSView : NSResponder {} + +class WKFrameInfo : NSObject {} +class WKContentWorld : NSObject { + class var defaultClient: WKContentWorld { WKContentWorld() } +} + +class WKWebView : UIView { + + func evaluateJavaScript( + _ javaScriptString: String + ) async throws -> Any { "" } + + func evaluateJavaScript( + _ javaScriptString: String, + completionHandler: ((Any?, Error?) -> Void)? = nil + ) { + completionHandler?(nil, nil) + } + + @MainActor func evaluateJavaScript( + _ javaScript: String, + in frame: WKFrameInfo? = nil, + in contentWorld: WKContentWorld, + completionHandler: ((Result) -> Void)? = nil + ) { + completionHandler?(.success("")) + } + + @MainActor func evaluateJavaScript( + _ javaScript: String, + in frame: WKFrameInfo? = nil, + contentWorld: WKContentWorld + ) async throws -> Any? { nil } + + @MainActor func callAsyncJavaScript( + _ functionBody: String, + arguments: [String : Any] = [:], + in frame: WKFrameInfo? = nil, + in contentWorld: WKContentWorld, + completionHandler: ((Result) -> Void)? = nil + ) { + completionHandler?(.success("")) + } + + @MainActor func callAsyncJavaScript( + _ functionBody: String, + arguments: [String : Any] = [:], + in frame: WKFrameInfo? = nil, + contentWorld: WKContentWorld + ) async throws -> Any? { nil } +} + +enum WKUserScriptInjectionTime : Int, @unchecked Sendable { + case atDocumentStart, atDocumentEnd +} + +class WKUserScript : NSObject { + init( + source: String, + injectionTime: WKUserScriptInjectionTime, + forMainFrameOnly: Bool + ) {} + + init( + source: String, + injectionTime: WKUserScriptInjectionTime, + forMainFrameOnly: Bool, + in contentWorld: WKContentWorld + ) {} +} + +class WKUserContentController : NSObject { + func addUserScript(_ userScript: WKUserScript) {} +} + +class UIWebView : UIView { + // deprecated + func stringByEvaluatingJavaScript(from script: String) -> String? { nil } +} + +class WebView : NSView { + // deprecated + func stringByEvaluatingJavaScript(from script: String!) -> String! { "" } +} + +class JSValue : NSObject {} + +class JSContext { + func evaluateScript(_ script: String!) -> JSValue! { return JSValue() } + func evaluateScript( + _ script: String!, + withSourceURL sourceURL: URL! + ) -> JSValue! { return JSValue() } +} + +typealias JSContextRef = OpaquePointer +typealias JSStringRef = OpaquePointer +typealias JSObjectRef = OpaquePointer +typealias JSValueRef = OpaquePointer +typealias JSChar = UInt16 + +func JSStringCreateWithCharacters( + _ chars: UnsafePointer!, + _ numChars: Int +) -> JSStringRef! { + return chars.withMemoryRebound(to: CChar.self, capacity: numChars) { + cchars in OpaquePointer(cchars) + } +} +func JSStringCreateWithUTF8CString(_ string: UnsafePointer!) -> JSStringRef! { + return OpaquePointer(string) +} +func JSStringRetain(_ string: JSStringRef!) -> JSStringRef! { return string } +func JSStringRelease(_ string: JSStringRef!) { } + +func JSEvaluateScript( + _ ctx: JSContextRef!, + _ script: JSStringRef!, + _ thisObject: JSObjectRef!, + _ sourceURL: JSStringRef!, + _ startingLineNumber: Int32, + _ exception: UnsafeMutablePointer! +) -> JSValueRef! { return OpaquePointer(bitPattern: 0) } + +@frozen +public struct Data: Collection { + public typealias Index = Int + public typealias Element = UInt8 + public subscript(x: Index) -> Element { 0 } + public var startIndex: Index { 0 } + public var endIndex: Index { 0 } + public func index(after i: Index) -> Index { i + 1 } + init(_ elements: S) {} +} + +struct URL { + init?(string: String) {} + init?(string: String, relativeTo: URL?) {} +} + +extension String { + init(contentsOf: URL) throws { + let data = "" + // ... + self.init(data) + } +} + +// --- tests --- + +func getRemoteData() -> String { + let url = URL(string: "http://example.com/") + do { + return try String(contentsOf: url!) + } catch { + return "" + } +} + +func testUsage(_ sink: @escaping (String) async throws -> ()) { + Task { + let localString = "console.log('localString')" + let localStringFragment = "'localStringFragment'" + let remoteString = getRemoteData() + + try! await sink(localString) // GOOD: the HTML data is local + try! await sink(getRemoteData()) // BAD: HTML contains remote input, may access local secrets + try! await sink(remoteString) // BAD + + try! await sink("console.log(" + localStringFragment + ")") // GOOD: the HTML data is local + try! await sink("console.log(" + remoteString + ")") // BAD + + let localData = Data(localString.utf8) + let remoteData = Data(remoteString.utf8) + + try! await sink(String(decoding: localData, as: UTF8.self)) // GOOD: the data is local + try! await sink(String(decoding: remoteData, as: UTF8.self)) // BAD: the data is remote + + try! await sink("console.log(" + String(Int(localStringFragment) ?? 0) + ")") // GOOD: Primitive conversion + try! await sink("console.log(" + String(Int(remoteString) ?? 0) + ")") // GOOD: Primitive conversion + + try! await sink("console.log(" + (localStringFragment.count != 0 ? "1" : "0") + ")") // GOOD: Primitive conversion + try! await sink("console.log(" + (remoteString.count != 0 ? "1" : "0") + ")") // GOOD: Primitive conversion + } +} + +func testUIWebView() { + let webview = UIWebView() + + testUsage { string in + _ = await webview.stringByEvaluatingJavaScript(from: string) + } +} + +func testWebView() { + let webview = WebView() + + testUsage { string in + _ = await webview.stringByEvaluatingJavaScript(from: string) + } +} + +func testWKWebView() { + let webview = WKWebView() + + testUsage { string in + _ = try await webview.evaluateJavaScript(string) + } + testUsage { string in + await webview.evaluateJavaScript(string) { _, _ in } + } + testUsage { string in + await webview.evaluateJavaScript(string, in: nil, in: WKContentWorld.defaultClient) { _ in } + } + testUsage { string in + _ = try await webview.evaluateJavaScript(string, contentWorld: .defaultClient) + } + testUsage { string in + await webview.callAsyncJavaScript(string, in: nil, in: .defaultClient) { _ in () } + } + testUsage { string in + _ = try await webview.callAsyncJavaScript(string, contentWorld: WKContentWorld.defaultClient) + } +} + +func testWKUserContentController() { + let ctrl = WKUserContentController() + + testUsage { string in + ctrl.addUserScript(WKUserScript(source: string, injectionTime: .atDocumentStart, forMainFrameOnly: false)) + } + testUsage { string in + ctrl.addUserScript(WKUserScript(source: string, injectionTime: .atDocumentEnd, forMainFrameOnly: true, in: .defaultClient)) + } +} + +func testJSContext() { + let ctx = JSContext() + + testUsage { string in + _ = ctx.evaluateScript(string) + } + testUsage { string in + _ = ctx.evaluateScript(string, withSourceURL: URL(string: "https://example.com")) + } +} + +func testJSEvaluateScript() { + testUsage { string in + string.utf16.withContiguousStorageIfAvailable { stringBytes in + let jsstr = JSStringRetain(JSStringCreateWithCharacters(stringBytes.baseAddress, string.count)) + defer { JSStringRelease(jsstr) } + _ = JSEvaluateScript( + /*ctx:*/ OpaquePointer(bitPattern: 0), + /*script:*/ jsstr, + /*thisObject:*/ OpaquePointer(bitPattern: 0), + /*sourceURL:*/ OpaquePointer(bitPattern: 0), + /*startingLineNumber:*/ 0, + /*exception:*/ UnsafeMutablePointer(bitPattern: 0) + ) + } + } + testUsage { string in + string.utf8CString.withUnsafeBufferPointer { stringBytes in + let jsstr = JSStringRetain(JSStringCreateWithUTF8CString(stringBytes.baseAddress)) + defer { JSStringRelease(jsstr) } + _ = JSEvaluateScript( + /*ctx:*/ OpaquePointer(bitPattern: 0), + /*script:*/ jsstr, + /*thisObject:*/ OpaquePointer(bitPattern: 0), + /*sourceURL:*/ OpaquePointer(bitPattern: 0), + /*startingLineNumber:*/ 0, + /*exception:*/ UnsafeMutablePointer(bitPattern: 0) + ) + } + } +} + +func testQHelpExamples() { + +} + +testUIWebView() +testWebView() +testWKWebView() +testWKUserContentController() +testJSContext() +testJSEvaluateScript() +testQHelpExamples() From 3d24e0a2ebb187ad93cf04e0ef74297e717a92db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Thu, 3 Nov 2022 11:12:41 +0100 Subject: [PATCH 028/796] Swift: enable VSCode to build extractor via CMake The `-arch=x86_64` from `swift/rules.bzl` turns out to be unnecessary, even on Arm-based Macs. --- .vscode/settings.json | 4 +++- swift/CMakeLists.txt | 4 ++++ swift/rules.bzl | 6 +----- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 8b22c91bb77..1050c79b825 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,5 @@ { - "omnisharp.autoStart": false + "omnisharp.autoStart": false, + "cmake.sourceDirectory": "${workspaceFolder}/swift", + "cmake.buildDirectory": "${workspaceFolder}/bazel-cmake-build" } diff --git a/swift/CMakeLists.txt b/swift/CMakeLists.txt index ad431e49a17..fbc55187567 100644 --- a/swift/CMakeLists.txt +++ b/swift/CMakeLists.txt @@ -9,6 +9,10 @@ set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_C_COMPILER clang) set(CMAKE_CXX_COMPILER clang++) +if(APPLE) + set(CMAKE_OSX_ARCHITECTURES x86_64) # temporary until we can build a Universal Binary +endif() + project(codeql) include(../misc/bazel/cmake/setup.cmake) diff --git a/swift/rules.bzl b/swift/rules.bzl index 29a1a704f02..ba9e4b0e8bf 100644 --- a/swift/rules.bzl +++ b/swift/rules.bzl @@ -5,11 +5,7 @@ def _wrap_cc(rule, kwargs): _add_args(kwargs, "copts", [ # Required by LLVM/Swift "-fno-rtti", - ] + select({ - # temporary, before we do universal merging and have an arm prebuilt package, we make arm build x86 - "@platforms//os:macos": ["-arch=x86_64"], - "//conditions:default": [], - })) + ]) _add_args(kwargs, "features", [ # temporary, before we do universal merging "-universal_binaries", From dc6f60a5015bf6b81a8c98c537cf449ea90bc5bf Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Wed, 2 Nov 2022 16:10:29 +0100 Subject: [PATCH 029/796] Add new XXE query Only XMLParser sinks for the time being --- .../codeql/swift/dataflow/ExternalFlow.qll | 2 + .../swift/frameworks/StandardLibrary/Data.qll | 6 ++ .../StandardLibrary/InputStream.qll | 8 +++ swift/ql/lib/codeql/swift/security/XXE.qll | 67 +++++++++++++++++++ .../ql/lib/codeql/swift/security/XXEQuery.qll | 27 ++++++++ .../ql/src/queries/Security/CWE-611/XXE.qhelp | 57 ++++++++++++++++ swift/ql/src/queries/Security/CWE-611/XXE.ql | 24 +++++++ .../src/queries/Security/CWE-611/XXEBad.swift | 2 + .../queries/Security/CWE-611/XXEGood.swift | 2 + .../Security/CWE-611/XXETest.expected | 0 .../query-tests/Security/CWE-611/XXETest.ql | 20 ++++++ .../Security/CWE-611/testXXE.swift | 58 ++++++++++++++++ 12 files changed, 273 insertions(+) create mode 100644 swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Data.qll create mode 100644 swift/ql/lib/codeql/swift/frameworks/StandardLibrary/InputStream.qll create mode 100644 swift/ql/lib/codeql/swift/security/XXE.qll create mode 100644 swift/ql/lib/codeql/swift/security/XXEQuery.qll create mode 100644 swift/ql/src/queries/Security/CWE-611/XXE.qhelp create mode 100644 swift/ql/src/queries/Security/CWE-611/XXE.ql create mode 100644 swift/ql/src/queries/Security/CWE-611/XXEBad.swift create mode 100644 swift/ql/src/queries/Security/CWE-611/XXEGood.swift create mode 100644 swift/ql/test/query-tests/Security/CWE-611/XXETest.expected create mode 100644 swift/ql/test/query-tests/Security/CWE-611/XXETest.ql create mode 100644 swift/ql/test/query-tests/Security/CWE-611/testXXE.swift diff --git a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll index 28e783c8047..4d563525830 100644 --- a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll +++ b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll @@ -79,6 +79,8 @@ private import internal.FlowSummaryImplSpecific */ private module Frameworks { private import codeql.swift.frameworks.StandardLibrary.CustomUrlSchemes + private import codeql.swift.frameworks.StandardLibrary.Data + private import codeql.swift.frameworks.StandardLibrary.InputStream private import codeql.swift.frameworks.StandardLibrary.String private import codeql.swift.frameworks.StandardLibrary.Url private import codeql.swift.frameworks.StandardLibrary.UrlSession diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Data.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Data.qll new file mode 100644 index 00000000000..740fc8874b6 --- /dev/null +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Data.qll @@ -0,0 +1,6 @@ +import swift +private import codeql.swift.dataflow.ExternalFlow + +private class DataSummaries extends SummaryModelCsv { + override predicate row(string row) { row = ";Data;true;init(_:);;;Argument[0];ReturnValue;taint" } +} diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/InputStream.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/InputStream.qll new file mode 100644 index 00000000000..60b61bec294 --- /dev/null +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/InputStream.qll @@ -0,0 +1,8 @@ +import swift +private import codeql.swift.dataflow.ExternalFlow + +private class InputStreamSummaries extends SummaryModelCsv { + override predicate row(string row) { + row = ";InputStream;true;init(data:);;;Argument[0];ReturnValue;taint" + } +} diff --git a/swift/ql/lib/codeql/swift/security/XXE.qll b/swift/ql/lib/codeql/swift/security/XXE.qll new file mode 100644 index 00000000000..eecbd147041 --- /dev/null +++ b/swift/ql/lib/codeql/swift/security/XXE.qll @@ -0,0 +1,67 @@ +/** Provides classes and predicates to reason about XML external entities (XXE) vulnerabilities. */ + +import swift +private import codeql.swift.dataflow.DataFlow +private import codeql.swift.dataflow.internal.DataFlowPrivate + +/** A data flow sink for XML external entities (XXE) vulnerabilities. */ +abstract class XxeSink extends DataFlow::Node { } + +/** A sanitizer for XML external entities (XXE) vulnerabilities. */ +abstract class XxeSanitizer extends DataFlow::Node { } + +/** + * A unit class for adding additional taint steps. + * + * Extend this class to add additional taint steps that should apply to paths related to + * XML external entities (XXE) vulnerabilities. + */ +class XxeAdditionalTaintStep extends Unit { + abstract predicate step(DataFlow::Node n1, DataFlow::Node n2); +} + +/** The XML argument of a `XMLParser` vulnerable to XXE. */ +private class DefaultXxeSink extends XxeSink { + DefaultXxeSink() { + this.asExpr() = any(Argument a | a.getApplyExpr() instanceof VulnerableParser).getExpr() + } +} + +/** The construction of a `XMLParser` that enables external entities. */ +private class VulnerableParser extends CallExpr { + VulnerableParser() { + resolvesExternalEntities(this) and this.getFunction() instanceof ConstructorRefCallExpr + } +} + +/** Holds if there is an access of `ref` that sets `shouldResolveExternalEntities` to `true`. */ +private predicate resolvesExternalEntities(XmlParserRef ref) { + exists(XmlParserRef base | + DataFlow::localExprFlow(ref, base) or DataFlow::localExprFlow(base, ref) + | + exists(AssignExpr assign, ShouldResolveExternalEntities s, BooleanLiteralExpr b | + s.getBase() = base and + assign.getDest() = s and + b.getValue() = true and + DataFlow::localExprFlow(b, assign.getSource()) + ) + ) +} + +/** A reference to the field `XMLParser.shouldResolveExternalEntities`. */ +private class ShouldResolveExternalEntities extends MemberRefExpr { + ShouldResolveExternalEntities() { + this.getMember().(FieldDecl).getName() = "shouldResolveExternalEntities" and + this.getBase() instanceof XmlParserRef + } +} + +/** An expression of type `XMLParser`. */ +private class XmlParserRef extends Expr { + XmlParserRef() { this.getType() instanceof XmlParserType } +} + +/** The type `XMLParser`. */ +private class XmlParserType extends NominalType { + XmlParserType() { this.getFullName() = "XMLParser" } +} diff --git a/swift/ql/lib/codeql/swift/security/XXEQuery.qll b/swift/ql/lib/codeql/swift/security/XXEQuery.qll new file mode 100644 index 00000000000..2b5dc5ea3ea --- /dev/null +++ b/swift/ql/lib/codeql/swift/security/XXEQuery.qll @@ -0,0 +1,27 @@ +/** + * Provides a taint-tracking configuration for reasoning about XML external entities + * (XXE) vulnerabilities. + */ + +import swift +import codeql.swift.dataflow.DataFlow +import codeql.swift.dataflow.FlowSources +import codeql.swift.dataflow.TaintTracking +import codeql.swift.security.XXE + +/** + * A taint-tracking configuration for XML external entities (XXE) vulnerabilities. + */ +class XxeConfiguration extends TaintTracking::Configuration { + XxeConfiguration() { this = "XxeConfiguration" } + + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { sink instanceof XxeSink } + + override predicate isSanitizer(DataFlow::Node sanitizer) { sanitizer instanceof XxeSanitizer } + + override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { + any(XxeAdditionalTaintStep s).step(n1, n2) + } +} diff --git a/swift/ql/src/queries/Security/CWE-611/XXE.qhelp b/swift/ql/src/queries/Security/CWE-611/XXE.qhelp new file mode 100644 index 00000000000..0aca8ac474b --- /dev/null +++ b/swift/ql/src/queries/Security/CWE-611/XXE.qhelp @@ -0,0 +1,57 @@ + + + + +

+Parsing untrusted XML files with a weakly configured XML parser may lead to an XML External Entity (XXE) attack. This type of attack +uses external entity references to access arbitrary files on a system, carry out denial of service, or server side +request forgery. Even when the result of parsing is not returned to the user, out-of-band +data retrieval techniques may allow attackers to steal sensitive data. Denial of services can also be +carried out in this situation. +

+
+ + +

+The easiest way to prevent XXE attacks is to disable external entity handling when +parsing untrusted data. How this is done depends on the library being used. Note that some +libraries, such as recent versions of XMLParser, disable entity expansion by default, +so unless you have explicitly enabled entity expansion, no further action needs to be taken. +

+
+ + +

+The following example uses the XMLParser class to parse a string data. +If that string is from an untrusted source, this code may be vulnerable to an XXE attack, since +the parser is also setting its shouldResolveExternalEntities option to true: +

+ + +

+To guard against XXE attacks, the shouldResolveExternalEntities option should be +left unset or explicitly set to false. +

+ + +
+ + +
  • +OWASP: +XML External Entity (XXE) Processing. +
  • +
  • +OWASP: +XML External Entity Prevention Cheat Sheet. +
  • +
  • +Timothy Morgen: +XML Schema, DTD, and Entity Attacks. +
  • +
  • +Timur Yunusov, Alexey Osipov: +XML Out-Of-Band Data Retrieval. +
  • +
    +
    diff --git a/swift/ql/src/queries/Security/CWE-611/XXE.ql b/swift/ql/src/queries/Security/CWE-611/XXE.ql new file mode 100644 index 00000000000..288da0aad9d --- /dev/null +++ b/swift/ql/src/queries/Security/CWE-611/XXE.ql @@ -0,0 +1,24 @@ +/** + * @name Resolving XML external entity in user-controlled data + * @description Parsing user-controlled XML documents and allowing expansion of external entity + * references may lead to disclosure of confidential data or denial of service. + * @kind path-problem + * @problem.severity error + * @security-severity 9.1 + * @precision high + * @id swift/xxe + * @tags security + * external/cwe/cwe-611 + * external/cwe/cwe-776 + * external/cwe/cwe-827 + */ + +import swift +import codeql.swift.dataflow.DataFlow +import codeql.swift.security.XXEQuery +import DataFlow::PathGraph + +from DataFlow::PathNode source, DataFlow::PathNode sink +where any(XxeConfiguration c).hasFlowPath(source, sink) +select sink.getNode(), source, sink, "XML parser with enabled external entities depends on $@.", + source.getNode(), "user input" diff --git a/swift/ql/src/queries/Security/CWE-611/XXEBad.swift b/swift/ql/src/queries/Security/CWE-611/XXEBad.swift new file mode 100644 index 00000000000..19ff4a7383d --- /dev/null +++ b/swift/ql/src/queries/Security/CWE-611/XXEBad.swift @@ -0,0 +1,2 @@ +let parser = XMLParser(data: remoteData) // BAD (parser explicitly enables external entities) +parser.shouldResolveExternalEntities = true diff --git a/swift/ql/src/queries/Security/CWE-611/XXEGood.swift b/swift/ql/src/queries/Security/CWE-611/XXEGood.swift new file mode 100644 index 00000000000..5552186c759 --- /dev/null +++ b/swift/ql/src/queries/Security/CWE-611/XXEGood.swift @@ -0,0 +1,2 @@ +let parser = XMLParser(data: remoteData) // GOOD (parser explicitly disables external entities) +parser.shouldResolveExternalEntities = false diff --git a/swift/ql/test/query-tests/Security/CWE-611/XXETest.expected b/swift/ql/test/query-tests/Security/CWE-611/XXETest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/query-tests/Security/CWE-611/XXETest.ql b/swift/ql/test/query-tests/Security/CWE-611/XXETest.ql new file mode 100644 index 00000000000..817f55678ad --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-611/XXETest.ql @@ -0,0 +1,20 @@ +import swift +import codeql.swift.security.XXEQuery +import TestUtilities.InlineExpectationsTest + +class XxeTest extends InlineExpectationsTest { + XxeTest() { this = "XxeTest" } + + override string getARelevantTag() { result = "hasXXE" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + exists(XxeConfiguration config, DataFlow::Node source, DataFlow::Node sink, Expr sinkExpr | + config.hasFlow(source, sink) and + sinkExpr = sink.asExpr() and + location = sinkExpr.getLocation() and + element = sinkExpr.toString() and + tag = "hasXXE" and + value = source.asExpr().getLocation().getStartLine().toString() + ) + } +} diff --git a/swift/ql/test/query-tests/Security/CWE-611/testXXE.swift b/swift/ql/test/query-tests/Security/CWE-611/testXXE.swift new file mode 100644 index 00000000000..b98385463ab --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-611/testXXE.swift @@ -0,0 +1,58 @@ +// --- stubs --- + +class Data { + init(_ elements: S) {} +} + +struct URL { + init?(string: String) {} +} + +class InputStream { + init(data: Data) {} +} + +extension String { + init(contentsOf: URL) { + let data = "" + self.init(data) + } +} + +class XMLParser { + var shouldResolveExternalEntities: Bool { get { return false } set {} } + init?(contentsOf: URL) {} + init(data: Data) {} + init(stream: InputStream) {} +} + +// --- tests --- + +func testData() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + let parser = XMLParser(data: remoteData) // $ hasXXE=32 + parser.shouldResolveExternalEntities = true +} + +func testInputStream() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + let remoteStream = InputStream(data: remoteData) + let parser = XMLParser(stream: remoteStream) // $ hasXXE=39 + parser.shouldResolveExternalEntities = true + +} + +func testDataSafe() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + let _ = XMLParser(data: remoteData) // NO XXE: parser doesn't enable external entities +} + +func testInputStreamSafe() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + let remoteStream = InputStream(data: remoteData) + let _ = XMLParser(stream: remoteStream) // NO XXE: parser doesn't enable external entities +} \ No newline at end of file From f4047e016cb5831769081c6def3a0cd11fad886b Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Wed, 2 Nov 2022 16:21:17 +0100 Subject: [PATCH 030/796] Address QL-for-QL alert Use an alert message consistent with the other languages --- swift/ql/src/queries/Security/CWE-611/XXE.ql | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-611/XXE.ql b/swift/ql/src/queries/Security/CWE-611/XXE.ql index 288da0aad9d..04c27949c11 100644 --- a/swift/ql/src/queries/Security/CWE-611/XXE.ql +++ b/swift/ql/src/queries/Security/CWE-611/XXE.ql @@ -20,5 +20,6 @@ import DataFlow::PathGraph from DataFlow::PathNode source, DataFlow::PathNode sink where any(XxeConfiguration c).hasFlowPath(source, sink) -select sink.getNode(), source, sink, "XML parser with enabled external entities depends on $@.", - source.getNode(), "user input" +select sink.getNode(), source, sink, + "XML parsing depends on a $@ without guarding against external entity expansion.", + source.getNode(), "user-provided value" From 0c6957ea785be63235d1cb8f61d86526681ec172 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Wed, 2 Nov 2022 17:05:55 +0100 Subject: [PATCH 031/796] Adjust test expectations of a query affected by new summaries --- .../Security/CWE-311/CleartextTransmission.expected | 11 +++++++++++ .../test/query-tests/Security/CWE-311/testSend.swift | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) 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 de02d0db461..5580af94d22 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected @@ -1,4 +1,8 @@ edges +| testSend.swift:5:5:5:29 | [summary param] 0 in init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | +| testSend.swift:33:14:33:32 | call to init(_:) : | testSend.swift:37:19:37:19 | data2 | +| testSend.swift:33:19:33:19 | passwordPlain : | testSend.swift:5:5:5:29 | [summary param] 0 in init(_:) : | +| testSend.swift:33:19:33:19 | passwordPlain : | testSend.swift:33:14:33:32 | call to init(_:) : | | testSend.swift:41:10:41:18 | data : | testSend.swift:41:45:41:45 | data : | | testSend.swift:45:13:45:13 | password : | testSend.swift:52:27:52:27 | str1 | | testSend.swift:46:13:46:13 | password : | testSend.swift:53:27:53:27 | str2 | @@ -8,7 +12,12 @@ edges | testURL.swift:13:54:13:54 | passwd : | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | | testURL.swift:16:55:16:55 | credit_card_no : | testURL.swift:16:22:16:55 | ... .+(_:_:) ... | nodes +| file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | semmle.label | [summary] to write: return (return) in init(_:) : | +| testSend.swift:5:5:5:29 | [summary param] 0 in init(_:) : | semmle.label | [summary param] 0 in init(_:) : | | testSend.swift:29:19:29:19 | passwordPlain | semmle.label | passwordPlain | +| testSend.swift:33:14:33:32 | call to init(_:) : | semmle.label | call to init(_:) : | +| testSend.swift:33:19:33:19 | passwordPlain : | semmle.label | passwordPlain : | +| testSend.swift:37:19:37:19 | data2 | semmle.label | data2 | | testSend.swift:41:10:41:18 | data : | semmle.label | data : | | testSend.swift:41:45:41:45 | data : | semmle.label | data : | | testSend.swift:45:13:45:13 | password : | semmle.label | password : | @@ -24,9 +33,11 @@ nodes | testURL.swift:16:55:16:55 | credit_card_no : | semmle.label | credit_card_no : | | testURL.swift:20:22:20:22 | passwd | semmle.label | passwd | subpaths +| testSend.swift:33:19:33:19 | passwordPlain : | testSend.swift:5:5:5:29 | [summary param] 0 in init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | testSend.swift:33:14:33:32 | call to init(_:) : | | testSend.swift:47:17:47:17 | password : | testSend.swift:41:10:41:18 | data : | testSend.swift:41:45:41:45 | data : | testSend.swift:47:13:47:25 | call to pad(_:) : | #select | testSend.swift:29:19:29:19 | passwordPlain | testSend.swift:29:19:29:19 | passwordPlain | testSend.swift:29:19:29:19 | passwordPlain | This operation transmits 'passwordPlain', which may contain unencrypted sensitive data from $@. | testSend.swift:29:19:29:19 | passwordPlain | passwordPlain | +| testSend.swift:37:19:37:19 | data2 | testSend.swift:33:19:33:19 | passwordPlain : | testSend.swift:37:19:37:19 | data2 | This operation transmits 'data2', which may contain unencrypted sensitive data from $@. | testSend.swift:33:19:33:19 | passwordPlain : | passwordPlain | | testSend.swift:52:27:52:27 | str1 | testSend.swift:45:13:45:13 | password : | testSend.swift:52:27:52:27 | str1 | This operation transmits 'str1', which may contain unencrypted sensitive data from $@. | testSend.swift:45:13:45:13 | password : | password | | testSend.swift:53:27:53:27 | str2 | testSend.swift:46:13:46:13 | password : | testSend.swift:53:27:53:27 | str2 | This operation transmits 'str2', which may contain unencrypted sensitive data from $@. | testSend.swift:46:13:46:13 | password : | password | | testSend.swift:54:27:54:27 | str3 | testSend.swift:47:17:47:17 | password : | testSend.swift:54:27:54:27 | str3 | This operation transmits 'str3', which may contain unencrypted sensitive data from $@. | testSend.swift:47:17:47:17 | password : | password | diff --git a/swift/ql/test/query-tests/Security/CWE-311/testSend.swift b/swift/ql/test/query-tests/Security/CWE-311/testSend.swift index 506b3a921e3..aaf2e3487f2 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/testSend.swift +++ b/swift/ql/test/query-tests/Security/CWE-311/testSend.swift @@ -34,7 +34,7 @@ func test1(passwordPlain : String, passwordHash : String) { let data3 = Data(passwordHash) nw.send(content: data1, completion: .idempotent) // GOOD (not sensitive) - nw.send(content: data2, completion: .idempotent) // BAD [NOT DETECTED] + nw.send(content: data2, completion: .idempotent) // BAD nw.send(content: data3, completion: .idempotent) // GOOD (not sensitive) } From fe138dc0a176bc8535ecb00bd00d5ad4139dd4d2 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Thu, 3 Nov 2022 09:29:57 +0100 Subject: [PATCH 032/796] Add explicitly safe test cases --- .../query-tests/Security/CWE-611/testXXE.swift | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/swift/ql/test/query-tests/Security/CWE-611/testXXE.swift b/swift/ql/test/query-tests/Security/CWE-611/testXXE.swift index b98385463ab..63244e082e9 100644 --- a/swift/ql/test/query-tests/Security/CWE-611/testXXE.swift +++ b/swift/ql/test/query-tests/Security/CWE-611/testXXE.swift @@ -50,9 +50,25 @@ func testDataSafe() { let _ = XMLParser(data: remoteData) // NO XXE: parser doesn't enable external entities } +func testDataSafeExplicit() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + let parser = XMLParser(data: remoteData) // NO XXE: parser disables external entities + parser.shouldResolveExternalEntities = false + +} + func testInputStreamSafe() { let remoteString = String(contentsOf: URL(string: "http://example.com/")!) let remoteData = Data(remoteString) let remoteStream = InputStream(data: remoteData) let _ = XMLParser(stream: remoteStream) // NO XXE: parser doesn't enable external entities +} + +func testInputStreamSafeExplicit() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + let remoteStream = InputStream(data: remoteData) + let parser = XMLParser(stream: remoteStream) // NO XXE: parser disables external entities + parser.shouldResolveExternalEntities = false } \ No newline at end of file From 3e1819f25de28bf4bf44d8ccddd3f44a60206b00 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Thu, 3 Nov 2022 09:49:13 +0100 Subject: [PATCH 033/796] Model XMLParser constructor init(contentsOf:) --- swift/ql/lib/codeql/swift/security/XXE.qll | 5 ++++- .../Security/CWE-611/testXXE.swift | 20 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/XXE.qll b/swift/ql/lib/codeql/swift/security/XXE.qll index eecbd147041..c3139ed974b 100644 --- a/swift/ql/lib/codeql/swift/security/XXE.qll +++ b/swift/ql/lib/codeql/swift/security/XXE.qll @@ -58,7 +58,10 @@ private class ShouldResolveExternalEntities extends MemberRefExpr { /** An expression of type `XMLParser`. */ private class XmlParserRef extends Expr { - XmlParserRef() { this.getType() instanceof XmlParserType } + XmlParserRef() { + this.getType() instanceof XmlParserType or + this.getType() = any(OptionalType t | t.getBaseType() instanceof XmlParserType) + } } /** The type `XMLParser`. */ diff --git a/swift/ql/test/query-tests/Security/CWE-611/testXXE.swift b/swift/ql/test/query-tests/Security/CWE-611/testXXE.swift index 63244e082e9..75538f014f9 100644 --- a/swift/ql/test/query-tests/Security/CWE-611/testXXE.swift +++ b/swift/ql/test/query-tests/Security/CWE-611/testXXE.swift @@ -41,7 +41,13 @@ func testInputStream() { let remoteStream = InputStream(data: remoteData) let parser = XMLParser(stream: remoteStream) // $ hasXXE=39 parser.shouldResolveExternalEntities = true +} +func testUrl() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteUrl = URL(string: remoteString)! + let parser = XMLParser(contentsOf: remoteUrl) // $ hasXXE=47 + parser?.shouldResolveExternalEntities = true } func testDataSafe() { @@ -55,7 +61,6 @@ func testDataSafeExplicit() { let remoteData = Data(remoteString) let parser = XMLParser(data: remoteData) // NO XXE: parser disables external entities parser.shouldResolveExternalEntities = false - } func testInputStreamSafe() { @@ -71,4 +76,17 @@ func testInputStreamSafeExplicit() { let remoteStream = InputStream(data: remoteData) let parser = XMLParser(stream: remoteStream) // NO XXE: parser disables external entities parser.shouldResolveExternalEntities = false +} + +func testUrlSafe() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteUrl = URL(string: remoteString)! + let _ = XMLParser(contentsOf: remoteUrl) // NO XXE: parser doesn't enable external entities +} + +func testUrlSafeExplicit() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteUrl = URL(string: remoteString)! + let parser = XMLParser(contentsOf: remoteUrl) // NO XXE: parser disables external entities + parser?.shouldResolveExternalEntities = false } \ No newline at end of file From da67b1059cca6fa83849252ca8fc2ab56587f8fc Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Thu, 3 Nov 2022 12:38:45 +0100 Subject: [PATCH 034/796] Remove (now unnecessary) import --- swift/ql/lib/codeql/swift/security/XXE.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/security/XXE.qll b/swift/ql/lib/codeql/swift/security/XXE.qll index c3139ed974b..506225f54a1 100644 --- a/swift/ql/lib/codeql/swift/security/XXE.qll +++ b/swift/ql/lib/codeql/swift/security/XXE.qll @@ -2,7 +2,6 @@ import swift private import codeql.swift.dataflow.DataFlow -private import codeql.swift.dataflow.internal.DataFlowPrivate /** A data flow sink for XML external entities (XXE) vulnerabilities. */ abstract class XxeSink extends DataFlow::Node { } From fdd7d76ffd0760315d313cd9570f213abce4e581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Thu, 3 Nov 2022 16:14:43 +0100 Subject: [PATCH 035/796] Swift: use FreeFunctionDecl/.has(Qualified)Name Instead of hand-rolled predicates. --- .../queries/Security/CWE-094/UnsafeJsEval.ql | 52 +++++++------------ 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql index 53891e2c03d..fff05671313 100644 --- a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql +++ b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql @@ -32,15 +32,16 @@ abstract class Sink extends DataFlow::Node { } class WKWebView extends Sink { WKWebView() { any(CallExpr ce | - ce.getStaticTarget() = - getMethodWithQualifiedName("WKWebView", - [ - "evaluateJavaScript(_:)", "evaluateJavaScript(_:completionHandler:)", - "evaluateJavaScript(_:in:in:completionHandler:)", - "evaluateJavaScript(_:in:contentWorld:)", - "callAsyncJavaScript(_:arguments:in:in:completionHandler:)", - "callAsyncJavaScript(_:arguments:in:contentWorld:)" - ]) + ce.getStaticTarget() + .(MethodDecl) + .hasQualifiedName("WKWebView", + [ + "evaluateJavaScript(_:)", "evaluateJavaScript(_:completionHandler:)", + "evaluateJavaScript(_:in:in:completionHandler:)", + "evaluateJavaScript(_:in:contentWorld:)", + "callAsyncJavaScript(_:arguments:in:in:completionHandler:)", + "callAsyncJavaScript(_:arguments:in:contentWorld:)" + ]) ).getArgument(0).getExpr() = this.asExpr() } } @@ -48,8 +49,9 @@ class WKWebView extends Sink { class WKUserContentController extends Sink { WKUserContentController() { any(CallExpr ce | - ce.getStaticTarget() = - getMethodWithQualifiedName("WKUserContentController", "addUserScript(_:)") + ce.getStaticTarget() + .(MethodDecl) + .hasQualifiedName("WKUserContentController", "addUserScript(_:)") ).getArgument(0).getExpr() = this.asExpr() } } @@ -57,8 +59,9 @@ class WKUserContentController extends Sink { class UIWebView extends Sink { UIWebView() { any(CallExpr ce | - ce.getStaticTarget() = - getMethodWithQualifiedName(["UIWebView", "WebView"], "stringByEvaluatingJavaScript(from:)") + ce.getStaticTarget() + .(MethodDecl) + .hasQualifiedName(["UIWebView", "WebView"], "stringByEvaluatingJavaScript(from:)") ).getArgument(0).getExpr() = this.asExpr() } } @@ -66,9 +69,9 @@ class UIWebView extends Sink { class JSContext extends Sink { JSContext() { any(CallExpr ce | - ce.getStaticTarget() = - getMethodWithQualifiedName("JSContext", - ["evaluateScript(_:)", "evaluateScript(_:withSourceURL:)"]) + ce.getStaticTarget() + .(MethodDecl) + .hasQualifiedName("JSContext", ["evaluateScript(_:)", "evaluateScript(_:withSourceURL:)"]) ).getArgument(0).getExpr() = this.asExpr() } } @@ -76,26 +79,11 @@ class JSContext extends Sink { class JSEvaluateScript extends Sink { JSEvaluateScript() { any(CallExpr ce | - ce.getStaticTarget() = getFunctionWithQualifiedName("JSEvaluateScript(_:_:_:_:_:_:)") + ce.getStaticTarget().(FreeFunctionDecl).hasName("JSEvaluateScript(_:_:_:_:_:_:)") ).getArgument(1).getExpr() = this.asExpr() } } -// TODO: Consider moving the following to the library, e.g. -// - Decl.hasQualifiedName(moduleName?, declaringDeclName?, declName) -// - parentDecl = memberDecl.getDeclaringDecl() <=> parentDecl.getAMember() = memberDecl -IterableDeclContext getDeclaringDeclOf(Decl member) { result.getAMember() = member } - -MethodDecl getMethodWithQualifiedName(string className, string methodName) { - result.getName() = methodName and - getDeclaringDeclOf(result).(NominalTypeDecl).getName() = className -} - -AbstractFunctionDecl getFunctionWithQualifiedName(string funcName) { - result.getName() = funcName and - not result.hasSelfParam() -} - /** * A taint configuration from taint sources to sinks for this query. */ From d7f1491f419ca32b0197125755e77bf502bae58b Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 4 Nov 2022 17:19:42 +0100 Subject: [PATCH 036/796] fix non-attached annotations for newtype branches --- ql/ql/src/codeql_ql/ast/Ast.qll | 4 +++ ql/ql/test/printAst/Foo.qll | 4 +++ ql/ql/test/printAst/printAst.expected | 46 ++++++++++++++++++--------- 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll index d6a5039a3c7..577fae69947 100644 --- a/ql/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/ql/src/codeql_ql/ast/Ast.qll @@ -983,6 +983,8 @@ class NewTypeBranch extends TNewTypeBranch, Predicate, TypeDeclaration { override NewTypeBranchType getReturnType() { result.getDeclaration() = this } + override Annotation getAnAnnotation() { toQL(this).getAFieldOrChild() = toQL(result) } + override Type getParameterType(int i) { result = this.getField(i).getType() } override int getArity() { result = count(this.getField(_)) } @@ -2397,6 +2399,8 @@ private class AnnotationArg extends TAnnotationArg, AstNode { } override string toString() { result = this.getValue() } + + override string getAPrimaryQlClass() { result = "AnnotationArg" } } private class NoInlineArg extends AnnotationArg { diff --git a/ql/ql/test/printAst/Foo.qll b/ql/ql/test/printAst/Foo.qll index 17e4a4d636d..461402cd2eb 100644 --- a/ql/ql/test/printAst/Foo.qll +++ b/ql/ql/test/printAst/Foo.qll @@ -25,3 +25,7 @@ predicate calls(Foo f) { or true = false } + +newtype TPathNode = + pragma[assume_small_delta] + TPathNodeMid() diff --git a/ql/ql/test/printAst/printAst.expected b/ql/ql/test/printAst/printAst.expected index 333b42332e7..e53f9112569 100644 --- a/ql/ql/test/printAst/printAst.expected +++ b/ql/ql/test/printAst/printAst.expected @@ -1,8 +1,8 @@ nodes | Foo.qll:1:1:1:17 | Import | semmle.label | [Import] Import | | Foo.qll:1:1:1:17 | Import | semmle.order | 1 | -| Foo.qll:1:1:27:2 | TopLevel | semmle.label | [TopLevel] TopLevel | -| Foo.qll:1:1:27:2 | TopLevel | semmle.order | 1 | +| Foo.qll:1:1:31:17 | TopLevel | semmle.label | [TopLevel] TopLevel | +| Foo.qll:1:1:31:17 | TopLevel | semmle.order | 1 | | Foo.qll:1:8:1:17 | javascript | semmle.label | [ModuleExpr] javascript | | Foo.qll:1:8:1:17 | javascript | semmle.order | 3 | | Foo.qll:3:7:3:9 | Class Foo | semmle.label | [Class] Class Foo | @@ -153,6 +153,14 @@ nodes | Foo.qll:26:3:26:14 | ComparisonFormula | semmle.order | 75 | | Foo.qll:26:10:26:14 | Boolean | semmle.label | [Boolean] Boolean | | Foo.qll:26:10:26:14 | Boolean | semmle.order | 77 | +| Foo.qll:29:9:29:17 | NewType TPathNode | semmle.label | [NewType] NewType TPathNode | +| Foo.qll:29:9:29:17 | NewType TPathNode | semmle.order | 78 | +| Foo.qll:30:3:30:28 | annotation | semmle.label | [Annotation] annotation | +| Foo.qll:30:3:30:28 | annotation | semmle.order | 79 | +| Foo.qll:30:10:30:27 | assume_small_delta | semmle.label | [AnnotationArg] assume_small_delta | +| Foo.qll:30:10:30:27 | assume_small_delta | semmle.order | 80 | +| Foo.qll:31:3:31:14 | NewTypeBranch TPathNodeMid | semmle.label | [NewTypeBranch] NewTypeBranch TPathNodeMid | +| Foo.qll:31:3:31:14 | NewTypeBranch TPathNodeMid | semmle.order | 81 | | file://:0:0:0:0 | abs | semmle.label | [BuiltinPredicate] abs | | file://:0:0:0:0 | abs | semmle.label | [BuiltinPredicate] abs | | file://:0:0:0:0 | acos | semmle.label | [BuiltinPredicate] acos | @@ -235,22 +243,24 @@ nodes | file://:0:0:0:0 | trim | semmle.label | [BuiltinPredicate] trim | | file://:0:0:0:0 | ulp | semmle.label | [BuiltinPredicate] ulp | | printAst.ql:1:1:1:28 | Import | semmle.label | [Import] Import | -| printAst.ql:1:1:1:28 | Import | semmle.order | 78 | +| printAst.ql:1:1:1:28 | Import | semmle.order | 82 | | printAst.ql:1:1:1:29 | TopLevel | semmle.label | [TopLevel] TopLevel | -| printAst.ql:1:1:1:29 | TopLevel | semmle.order | 78 | +| printAst.ql:1:1:1:29 | TopLevel | semmle.order | 82 | | printAst.ql:1:18:1:28 | printAstAst | semmle.label | [ModuleExpr] printAstAst | -| printAst.ql:1:18:1:28 | printAstAst | semmle.order | 80 | +| printAst.ql:1:18:1:28 | printAstAst | semmle.order | 84 | edges | Foo.qll:1:1:1:17 | Import | Foo.qll:1:8:1:17 | javascript | semmle.label | getModuleExpr() | | Foo.qll:1:1:1:17 | Import | Foo.qll:1:8:1:17 | javascript | semmle.order | 3 | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.label | getAnImport() | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.order | 1 | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:7:3:9 | Class Foo | semmle.label | getAClass() | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:7:3:9 | Class Foo | semmle.order | 4 | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.label | getAPredicate() | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.order | 16 | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.label | getAPredicate() | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.order | 32 | +| Foo.qll:1:1:31:17 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.label | getAnImport() | +| Foo.qll:1:1:31:17 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.order | 1 | +| Foo.qll:1:1:31:17 | TopLevel | Foo.qll:3:7:3:9 | Class Foo | semmle.label | getAClass() | +| Foo.qll:1:1:31:17 | TopLevel | Foo.qll:3:7:3:9 | Class Foo | semmle.order | 4 | +| Foo.qll:1:1:31:17 | TopLevel | Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.label | getAPredicate() | +| Foo.qll:1:1:31:17 | TopLevel | Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.order | 16 | +| Foo.qll:1:1:31:17 | TopLevel | Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.label | getAPredicate() | +| Foo.qll:1:1:31:17 | TopLevel | Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.order | 32 | +| Foo.qll:1:1:31:17 | TopLevel | Foo.qll:29:9:29:17 | NewType TPathNode | semmle.label | getANewType() | +| Foo.qll:1:1:31:17 | TopLevel | Foo.qll:29:9:29:17 | NewType TPathNode | semmle.order | 78 | | Foo.qll:3:7:3:9 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.label | getASuperType() | | Foo.qll:3:7:3:9 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.order | 5 | | Foo.qll:3:7:3:9 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.label | getCharPred() | @@ -393,9 +403,15 @@ edges | Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:3:26:6 | Boolean | semmle.order | 75 | | Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:10:26:14 | Boolean | semmle.label | getRightOperand() | | Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:10:26:14 | Boolean | semmle.order | 77 | +| Foo.qll:29:9:29:17 | NewType TPathNode | Foo.qll:31:3:31:14 | NewTypeBranch TPathNodeMid | semmle.label | getABranch() | +| Foo.qll:29:9:29:17 | NewType TPathNode | Foo.qll:31:3:31:14 | NewTypeBranch TPathNodeMid | semmle.order | 81 | +| Foo.qll:30:3:30:28 | annotation | Foo.qll:30:10:30:27 | assume_small_delta | semmle.label | getArgs(_) | +| Foo.qll:30:3:30:28 | annotation | Foo.qll:30:10:30:27 | assume_small_delta | semmle.order | 80 | +| Foo.qll:31:3:31:14 | NewTypeBranch TPathNodeMid | Foo.qll:30:3:30:28 | annotation | semmle.label | getAnAnnotation() | +| Foo.qll:31:3:31:14 | NewTypeBranch TPathNodeMid | Foo.qll:30:3:30:28 | annotation | semmle.order | 79 | | printAst.ql:1:1:1:28 | Import | printAst.ql:1:18:1:28 | printAstAst | semmle.label | getModuleExpr() | -| printAst.ql:1:1:1:28 | Import | printAst.ql:1:18:1:28 | printAstAst | semmle.order | 80 | +| printAst.ql:1:1:1:28 | Import | printAst.ql:1:18:1:28 | printAstAst | semmle.order | 84 | | printAst.ql:1:1:1:29 | TopLevel | printAst.ql:1:1:1:28 | Import | semmle.label | getAnImport() | -| printAst.ql:1:1:1:29 | TopLevel | printAst.ql:1:1:1:28 | Import | semmle.order | 78 | +| printAst.ql:1:1:1:29 | TopLevel | printAst.ql:1:1:1:28 | Import | semmle.order | 82 | graphProperties | semmle.graphKind | tree | From bc5b7455cf879ed3a7ad381d7e8835d7f12dda15 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 2 Nov 2022 13:55:39 +0100 Subject: [PATCH 037/796] add failing test --- .../UnsafeShellCommandConstruction/lib/subLib/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/subLib/index.js b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/subLib/index.js index 9e105338669..fe6eaa449ae 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/subLib/index.js +++ b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/subLib/index.js @@ -8,4 +8,8 @@ module.exports.foo = function (name) { cp.exec("rm -rf " + name); // NOT OK - this is being called explicitly from child_process-test.js }; -module.exports.amd = require("./amd.js"); \ No newline at end of file +module.exports.amd = require("./amd.js"); + +module.exports.arrToShell = function (cmd, arr) { + cp.spawn("echo", arr, {shell: true}); // NOT OK - but not flagged [INCONSISTENCY] +} \ No newline at end of file From 40032f295ae1625c51eba9075b905bdb6f3ce1df Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 2 Nov 2022 14:06:57 +0100 Subject: [PATCH 038/796] treat arrays that gets executed with shell:true as a sink for `js/shell-command-constructed-from-input` --- ...ShellCommandConstructionCustomizations.qll | 24 +++++++++++++------ .../UnsafeShellCommandConstruction.expected | 23 ++++++++++++++++++ .../lib/subLib/index.js | 2 +- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll index 0b4923de179..ca6920db466 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll @@ -156,14 +156,9 @@ module UnsafeShellCommandConstruction { } /** - * Gets a node that ends up in an array that is ultimately executed as a shell script by `sys`. + * Holds if the arguments array given to `sys` is joined as a string because `shell` is set to true. */ - private DataFlow::SourceNode endsInShellExecutedArray( - DataFlow::TypeBackTracker t, SystemCommandExecution sys - ) { - t.start() and - result = sys.getArgumentList().getALocalSource() and - // the array gets joined to a string when `shell` is set to true. + predicate executesArrayAsShell(SystemCommandExecution sys) { sys.getOptionsArg() .getALocalSource() .getAPropertyWrite("shell") @@ -171,6 +166,17 @@ module UnsafeShellCommandConstruction { .asExpr() .(BooleanLiteral) .getValue() = "true" + } + + /** + * Gets a node that ends up in an array that is ultimately executed as a shell script by `sys`. + */ + private DataFlow::SourceNode endsInShellExecutedArray( + DataFlow::TypeBackTracker t, SystemCommandExecution sys + ) { + t.start() and + result = sys.getArgumentList().getALocalSource() and + executesArrayAsShell(sys) or exists(DataFlow::TypeBackTracker t2 | result = endsInShellExecutedArray(t2, sys).backtrack(t2, t) @@ -193,6 +199,10 @@ module UnsafeShellCommandConstruction { or this = arr.getAMethodCall(["push", "unshift"]).getAnArgument() ) + or + this = sys.getArgumentList() and + not this instanceof DataFlow::ArrayCreationNode and + executesArrayAsShell(sys) } override string getSinkType() { result = "shell argument" } diff --git a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected index 4cf79a4aedd..9cf2707f58f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected @@ -223,8 +223,14 @@ nodes | lib/lib.js:420:29:420:32 | name | | lib/lib.js:424:24:424:27 | name | | lib/lib.js:424:24:424:27 | name | +| lib/lib.js:425:6:425:13 | arr | +| lib/lib.js:425:12:425:13 | [] | | lib/lib.js:426:11:426:14 | name | | lib/lib.js:426:11:426:14 | name | +| lib/lib.js:427:14:427:16 | arr | +| lib/lib.js:427:14:427:16 | arr | +| lib/lib.js:428:14:428:58 | build(" ... + '-') | +| lib/lib.js:428:14:428:58 | build(" ... + '-') | | lib/lib.js:428:28:428:51 | (name ? ... ' : '') | | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | | lib/lib.js:428:29:428:50 | name ? ... :' : '' | @@ -302,6 +308,10 @@ nodes | 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:13:44:13:46 | arr | +| lib/subLib/index.js:13:44:13:46 | arr | +| lib/subLib/index.js:14:22:14:24 | arr | +| lib/subLib/index.js:14:22:14:24 | arr | edges | lib/isImported.js:5:49:5:52 | name | lib/isImported.js:6:22:6:25 | name | | lib/isImported.js:5:49:5:52 | name | lib/isImported.js:6:22:6:25 | name | @@ -575,7 +585,13 @@ edges | lib/lib.js:414:40:414:43 | name | lib/lib.js:426:11:426:14 | name | | lib/lib.js:414:40:414:43 | name | lib/lib.js:428:36:428:39 | name | | lib/lib.js:414:40:414:43 | name | lib/lib.js:428:36:428:39 | name | +| lib/lib.js:425:6:425:13 | arr | lib/lib.js:427:14:427:16 | arr | +| lib/lib.js:425:6:425:13 | arr | lib/lib.js:427:14:427:16 | arr | +| lib/lib.js:425:12:425:13 | [] | lib/lib.js:425:6:425:13 | arr | +| lib/lib.js:426:11:426:14 | name | lib/lib.js:425:12:425:13 | [] | | lib/lib.js:428:28:428:51 | (name ? ... ' : '') | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | +| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:428:14:428:58 | build(" ... + '-') | +| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:428:14:428:58 | build(" ... + '-') | | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:431:23:431:26 | last | | lib/lib.js:428:29:428:50 | name ? ... :' : '' | lib/lib.js:428:28:428:51 | (name ? ... ' : '') | | lib/lib.js:428:36:428:39 | name | lib/lib.js:428:36:428:45 | name + ':' | @@ -663,6 +679,10 @@ edges | lib/subLib/index.js:7:32:7:35 | name | lib/subLib/index.js:8:22:8:25 | name | | lib/subLib/index.js:7:32:7:35 | name | lib/subLib/index.js:8:22:8:25 | name | | lib/subLib/index.js:7:32:7:35 | name | lib/subLib/index.js:8:22:8:25 | name | +| lib/subLib/index.js:13:44:13:46 | arr | lib/subLib/index.js:14:22:14:24 | arr | +| lib/subLib/index.js:13:44:13:46 | arr | lib/subLib/index.js:14:22:14:24 | arr | +| lib/subLib/index.js:13:44:13:46 | arr | lib/subLib/index.js:14:22:14:24 | arr | +| lib/subLib/index.js:13:44:13:46 | arr | lib/subLib/index.js:14:22:14:24 | arr | #select | lib/isImported.js:6:10:6:25 | "rm -rf " + name | lib/isImported.js:5:49:5:52 | name | lib/isImported.js:6:22:6:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/isImported.js:5:49:5:52 | name | library input | lib/isImported.js:6:2:6:26 | cp.exec ... + name) | shell command | | lib/lib2.js:4:10:4:25 | "rm -rf " + name | lib/lib2.js:3:28:3:31 | name | lib/lib2.js:4:22:4:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib2.js:3:28:3:31 | name | library input | lib/lib2.js:4:2:4:26 | cp.exec ... + name) | shell command | @@ -729,6 +749,8 @@ edges | lib/lib.js:420:29:420:32 | name | lib/lib.js:414:40:414:43 | name | lib/lib.js:420:29:420:32 | name | This shell argument which depends on $@ is later used in a $@. | lib/lib.js:414:40:414:43 | name | library input | lib/lib.js:420:2:420:49 | cp.spaw ... true}) | shell command | | lib/lib.js:424:24:424:27 | name | lib/lib.js:414:40:414:43 | name | lib/lib.js:424:24:424:27 | name | This shell argument which depends on $@ is later used in a $@. | lib/lib.js:414:40:414:43 | name | library input | lib/lib.js:424:2:424:40 | spawn(" ... WN_OPT) | shell command | | lib/lib.js:426:11:426:14 | name | lib/lib.js:414:40:414:43 | name | lib/lib.js:426:11:426:14 | name | This shell argument which depends on $@ is later used in a $@. | lib/lib.js:414:40:414:43 | name | library input | lib/lib.js:427:2:427:28 | spawn(" ... WN_OPT) | shell command | +| lib/lib.js:427:14:427:16 | arr | lib/lib.js:414:40:414:43 | name | lib/lib.js:427:14:427:16 | arr | This shell argument which depends on $@ is later used in a $@. | lib/lib.js:414:40:414:43 | name | library input | lib/lib.js:427:2:427:28 | spawn(" ... WN_OPT) | shell command | +| lib/lib.js:428:14:428:58 | build(" ... + '-') | lib/lib.js:414:40:414:43 | name | lib/lib.js:428:14:428:58 | build(" ... + '-') | This shell argument which depends on $@ is later used in a $@. | lib/lib.js:414:40:414:43 | name | library input | lib/lib.js:428:2:428:70 | spawn(" ... WN_OPT) | shell command | | lib/lib.js:436:19:436:22 | last | lib/lib.js:414:40:414:43 | name | lib/lib.js:436:19:436:22 | last | This shell argument which depends on $@ is later used in a $@. | lib/lib.js:414:40:414:43 | name | library input | lib/lib.js:428:2:428:70 | spawn(" ... WN_OPT) | shell command | | lib/lib.js:442:12:442:27 | "rm -rf " + name | lib/lib.js:441:39:441:42 | name | lib/lib.js:442:24:442:27 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:441:39:441:42 | name | library input | lib/lib.js:442:2:442:28 | asyncEx ... + name) | shell command | | lib/lib.js:447:13:447:28 | "rm -rf " + name | lib/lib.js:446:20:446:23 | name | lib/lib.js:447:25:447:28 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:446:20:446:23 | name | library input | lib/lib.js:447:3:447:29 | asyncEx ... + name) | shell command | @@ -750,3 +772,4 @@ edges | 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 | This string concatenation which depends on $@ is later used in a $@. | 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 | This string concatenation which depends on $@ is later used in a $@. | 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 | This string concatenation which depends on $@ is later used in a $@. | lib/subLib/index.js:7:32:7:35 | name | library input | lib/subLib/index.js:8:2:8:26 | cp.exec ... + name) | shell command | +| lib/subLib/index.js:14:22:14:24 | arr | lib/subLib/index.js:13:44:13:46 | arr | lib/subLib/index.js:14:22:14:24 | arr | This shell argument which depends on $@ is later used in a $@. | lib/subLib/index.js:13:44:13:46 | arr | library input | lib/subLib/index.js:14:5:14:40 | cp.spaw ... true}) | shell command | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/subLib/index.js b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/subLib/index.js index fe6eaa449ae..6e7d3498723 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/subLib/index.js +++ b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/subLib/index.js @@ -11,5 +11,5 @@ module.exports.foo = function (name) { module.exports.amd = require("./amd.js"); module.exports.arrToShell = function (cmd, arr) { - cp.spawn("echo", arr, {shell: true}); // NOT OK - but not flagged [INCONSISTENCY] + cp.spawn("echo", arr, {shell: true}); // NOT OK } \ No newline at end of file From 74ee1015923b025efd1da565c7797920bb37dd2b Mon Sep 17 00:00:00 2001 From: JarLob Date: Mon, 7 Nov 2022 13:05:37 +0100 Subject: [PATCH 039/796] Extend `Constant Condition` query with `String.IsNullOrEmpty`. --- .../Control-Flow/ConstantCondition.ql | 25 ++++++++ .../2022-11-07-constant-expression.md | 4 ++ .../ConstantCondition.expected | 4 ++ .../ConstantIsNullOrEmpty.cs | 60 +++++++++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 csharp/ql/src/change-notes/released/2022-11-07-constant-expression.md create mode 100644 csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantIsNullOrEmpty.cs diff --git a/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql b/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql index a0542a94735..cb53d103f47 100644 --- a/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql +++ b/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql @@ -15,6 +15,7 @@ import csharp import semmle.code.csharp.commons.Assertions import semmle.code.csharp.commons.Constants +private import semmle.code.csharp.frameworks.System /** A constant condition. */ abstract class ConstantCondition extends Expr { @@ -72,6 +73,30 @@ class ConstantIfCondition extends ConstantBooleanCondition { } } +/** A constant return value from a function with constant input expression. */ +class ConstantReturnValueCondition extends ConstantCondition { + boolean b; + + ConstantReturnValueCondition() { + exists(Method m, Call c, Expr expr | + m = any(SystemStringClass s).getIsNullOrEmptyMethod() and + c.getTarget() = m and + this = c and + expr = c.getArgument(0) and + expr.hasValue() and + if expr.getValue().length() > 0 and not expr instanceof NullLiteral + then b = false + else b = true + ) + } + + override string getMessage() { + if b = true + then result = "Expression is always 'true'." + else result = "Expression is always 'false'." + } +} + /** A constant loop condition. */ class ConstantLoopCondition extends ConstantBooleanCondition { ConstantLoopCondition() { this = any(LoopStmt ls).getCondition() } diff --git a/csharp/ql/src/change-notes/released/2022-11-07-constant-expression.md b/csharp/ql/src/change-notes/released/2022-11-07-constant-expression.md new file mode 100644 index 00000000000..9e2d667d2eb --- /dev/null +++ b/csharp/ql/src/change-notes/released/2022-11-07-constant-expression.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `Constant Condition` query was extended to catch cases when `String.IsNullOrEmpty` returns a constant value. \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantCondition.expected b/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantCondition.expected index 17a51125c4c..064837e8552 100644 --- a/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantCondition.expected +++ b/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantCondition.expected @@ -19,6 +19,10 @@ | ConstantIfCondition.cs:11:17:11:29 | ... == ... | Condition always evaluates to 'true'. | | ConstantIfCondition.cs:14:17:14:21 | false | Condition always evaluates to 'false'. | | ConstantIfCondition.cs:17:17:17:26 | ... == ... | Condition always evaluates to 'true'. | +| ConstantIsNullOrEmpty.cs:10:21:10:54 | call to method IsNullOrEmpty | Expression is always 'false'. | +| ConstantIsNullOrEmpty.cs:46:21:46:46 | call to method IsNullOrEmpty | Expression is always 'true'. | +| ConstantIsNullOrEmpty.cs:50:21:50:44 | call to method IsNullOrEmpty | Expression is always 'true'. | +| ConstantIsNullOrEmpty.cs:54:21:54:45 | call to method IsNullOrEmpty | Expression is always 'false'. | | ConstantNullCoalescingLeftHandOperand.cs:11:24:11:34 | access to constant NULL_OBJECT | Expression is never 'null'. | | ConstantNullCoalescingLeftHandOperand.cs:12:24:12:27 | null | Expression is always 'null'. | | ConstantWhileCondition.cs:12:20:12:32 | ... == ... | Condition always evaluates to 'true'. | diff --git a/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantIsNullOrEmpty.cs b/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantIsNullOrEmpty.cs new file mode 100644 index 00000000000..5cad2e818ab --- /dev/null +++ b/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantIsNullOrEmpty.cs @@ -0,0 +1,60 @@ +using System.Threading.Tasks; + +namespace ConstantIsNullOrEmpty +{ + internal class Program + { + static void Main(string[] args) + { + { + if (string.IsNullOrEmpty(nameof(args))) // bad: always false + { + } + + string? x = null; + if (string.IsNullOrEmpty(x)) // would be nice... bad: always true + { + } + + string y = ""; + if (string.IsNullOrEmpty(y)) // would be nice... bad: always true + { + } + + if (args[1] != null) + y = "b"; + if (string.IsNullOrEmpty(y)) // good: non-constant + { + } + + string z = " "; + if (string.IsNullOrEmpty(z)) // would be nice... bad: always false + { + } + + string a = "a"; + if (string.IsNullOrEmpty(a)) // would be nice... bad: always false + { + } + + if (args[1] != null) + a = ""; + if (string.IsNullOrEmpty(a)) // good: non-constant + { + } + + if (string.IsNullOrEmpty(null)) // bad: always true + { + } + + if (string.IsNullOrEmpty("")) // bad: always true + { + } + + if (string.IsNullOrEmpty(" ")) // bad: always false + { + } + } + } + } +} \ No newline at end of file From e122f94c1c5b2cbf87c2c2b8a9473db2cdc035a8 Mon Sep 17 00:00:00 2001 From: JarLob Date: Mon, 7 Nov 2022 13:38:05 +0100 Subject: [PATCH 040/796] Move to isBooleanConstant --- .../controlflow/internal/Completion.qll | 11 +++++++++ .../Control-Flow/ConstantCondition.ql | 24 ------------------- .../ConstantCondition.expected | 8 +++---- 3 files changed, 15 insertions(+), 28 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Completion.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Completion.qll index bda14e0b4ae..2b4adad031f 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Completion.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Completion.qll @@ -199,6 +199,17 @@ private predicate isBooleanConstant(Expr e, boolean value) { value = false or isConstantComparison(e, value) + or + exists(Method m, Call c, Expr expr | + m = any(SystemStringClass s).getIsNullOrEmptyMethod() and + c.getTarget() = m and + e = c and + expr = c.getArgument(0) and + expr.hasValue() and + if expr.getValue().length() > 0 and not expr instanceof NullLiteral + then value = false + else value = true + ) ) } diff --git a/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql b/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql index cb53d103f47..4d9fedb3633 100644 --- a/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql +++ b/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql @@ -73,30 +73,6 @@ class ConstantIfCondition extends ConstantBooleanCondition { } } -/** A constant return value from a function with constant input expression. */ -class ConstantReturnValueCondition extends ConstantCondition { - boolean b; - - ConstantReturnValueCondition() { - exists(Method m, Call c, Expr expr | - m = any(SystemStringClass s).getIsNullOrEmptyMethod() and - c.getTarget() = m and - this = c and - expr = c.getArgument(0) and - expr.hasValue() and - if expr.getValue().length() > 0 and not expr instanceof NullLiteral - then b = false - else b = true - ) - } - - override string getMessage() { - if b = true - then result = "Expression is always 'true'." - else result = "Expression is always 'false'." - } -} - /** A constant loop condition. */ class ConstantLoopCondition extends ConstantBooleanCondition { ConstantLoopCondition() { this = any(LoopStmt ls).getCondition() } diff --git a/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantCondition.expected b/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantCondition.expected index 064837e8552..397d77531b2 100644 --- a/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantCondition.expected +++ b/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantCondition.expected @@ -19,10 +19,10 @@ | ConstantIfCondition.cs:11:17:11:29 | ... == ... | Condition always evaluates to 'true'. | | ConstantIfCondition.cs:14:17:14:21 | false | Condition always evaluates to 'false'. | | ConstantIfCondition.cs:17:17:17:26 | ... == ... | Condition always evaluates to 'true'. | -| ConstantIsNullOrEmpty.cs:10:21:10:54 | call to method IsNullOrEmpty | Expression is always 'false'. | -| ConstantIsNullOrEmpty.cs:46:21:46:46 | call to method IsNullOrEmpty | Expression is always 'true'. | -| ConstantIsNullOrEmpty.cs:50:21:50:44 | call to method IsNullOrEmpty | Expression is always 'true'. | -| ConstantIsNullOrEmpty.cs:54:21:54:45 | call to method IsNullOrEmpty | Expression is always 'false'. | +| ConstantIsNullOrEmpty.cs:10:21:10:54 | call to method IsNullOrEmpty | Condition always evaluates to 'false'. | +| ConstantIsNullOrEmpty.cs:46:21:46:46 | call to method IsNullOrEmpty | Condition always evaluates to 'true'. | +| ConstantIsNullOrEmpty.cs:50:21:50:44 | call to method IsNullOrEmpty | Condition always evaluates to 'true'. | +| ConstantIsNullOrEmpty.cs:54:21:54:45 | call to method IsNullOrEmpty | Condition always evaluates to 'false'. | | ConstantNullCoalescingLeftHandOperand.cs:11:24:11:34 | access to constant NULL_OBJECT | Expression is never 'null'. | | ConstantNullCoalescingLeftHandOperand.cs:12:24:12:27 | null | Expression is always 'null'. | | ConstantWhileCondition.cs:12:20:12:32 | ... == ... | Condition always evaluates to 'true'. | From d865f2ecf5d54ee6792c8a5abcdca4914b5ab87a Mon Sep 17 00:00:00 2001 From: JarLob Date: Mon, 7 Nov 2022 14:19:24 +0100 Subject: [PATCH 041/796] Remove import --- csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql | 1 - 1 file changed, 1 deletion(-) diff --git a/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql b/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql index 4d9fedb3633..a0542a94735 100644 --- a/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql +++ b/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql @@ -15,7 +15,6 @@ import csharp import semmle.code.csharp.commons.Assertions import semmle.code.csharp.commons.Constants -private import semmle.code.csharp.frameworks.System /** A constant condition. */ abstract class ConstantCondition extends Expr { From 5ec22bc180da321822f694b00a5f9614e6220071 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 1 Nov 2022 09:52:31 +0100 Subject: [PATCH 042/796] add a shared regex pack --- .../2022-09-26-initial-version.md | 4 + shared/regex/codeql-pack.lock.yml | 4 + .../codeql/regex/OverlyLargeRangeQuery.qll | 300 ++++ shared/regex/codeql/regex/RegexTreeView.qll | 451 ++++++ .../codeql/regex/nfa/BadTagFilterQuery.qll | 177 +++ .../regex/nfa/ExponentialBackTracking.qll | 355 +++++ shared/regex/codeql/regex/nfa/NfaUtils.qll | 1378 +++++++++++++++++ .../regex/codeql/regex/nfa/RegexpMatching.qll | 176 +++ .../regex/nfa/SuperlinearBackTracking.qll | 440 ++++++ shared/regex/qlpack.yml | 5 + 10 files changed, 3290 insertions(+) create mode 100644 shared/regex/change-notes/2022-09-26-initial-version.md create mode 100644 shared/regex/codeql-pack.lock.yml create mode 100644 shared/regex/codeql/regex/OverlyLargeRangeQuery.qll create mode 100644 shared/regex/codeql/regex/RegexTreeView.qll create mode 100644 shared/regex/codeql/regex/nfa/BadTagFilterQuery.qll create mode 100644 shared/regex/codeql/regex/nfa/ExponentialBackTracking.qll create mode 100644 shared/regex/codeql/regex/nfa/NfaUtils.qll create mode 100644 shared/regex/codeql/regex/nfa/RegexpMatching.qll create mode 100644 shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll create mode 100644 shared/regex/qlpack.yml diff --git a/shared/regex/change-notes/2022-09-26-initial-version.md b/shared/regex/change-notes/2022-09-26-initial-version.md new file mode 100644 index 00000000000..e4d6e0490c2 --- /dev/null +++ b/shared/regex/change-notes/2022-09-26-initial-version.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Initial release. Extracted common regex related code, including the ReDoS analysis, into a library pack to share code between languages. diff --git a/shared/regex/codeql-pack.lock.yml b/shared/regex/codeql-pack.lock.yml new file mode 100644 index 00000000000..a046f6d9786 --- /dev/null +++ b/shared/regex/codeql-pack.lock.yml @@ -0,0 +1,4 @@ +--- +dependencies: {} +compiled: false +lockVersion: 1.0.0 \ No newline at end of file diff --git a/shared/regex/codeql/regex/OverlyLargeRangeQuery.qll b/shared/regex/codeql/regex/OverlyLargeRangeQuery.qll new file mode 100644 index 00000000000..8d3a0b9c0ff --- /dev/null +++ b/shared/regex/codeql/regex/OverlyLargeRangeQuery.qll @@ -0,0 +1,300 @@ +/** + * Classes and predicates for working with suspicious character ranges. + */ + +private import RegexTreeView + +/** + * Classes and predicates implementing an analysis detecting suspicious character ranges. + */ +module Make { + private import TreeImpl + + /** + * Gets a rank for `range` that is unique for ranges in the same file. + * Prioritizes ranges that match more characters. + */ + int rankRange(RegExpCharacterRange range) { + range = + rank[result](RegExpCharacterRange r, int startline, int startcolumn, int low, int high | + r.hasLocationInfo(_, startline, startcolumn, _, _) and + isRange(r, low, high) + | + r order by (high - low) desc, startline, startcolumn + ) + } + + /** Holds if `range` spans from the unicode code points `low` to `high` (both inclusive). */ + predicate isRange(RegExpCharacterRange range, int low, int high) { + exists(string lowc, string highc | + range.isRange(lowc, highc) and + low.toUnicode() = lowc and + high.toUnicode() = highc + ) + } + + /** Holds if `char` is an alpha-numeric character. */ + predicate isAlphanumeric(string char) { + // written like this to avoid having a bindingset for the predicate + char = [[48 .. 57], [65 .. 90], [97 .. 122]].toUnicode() // 0-9, A-Z, a-z + } + + /** + * Holds if the given ranges are from the same character class + * and there exists at least one character matched by both ranges. + */ + predicate overlap(RegExpCharacterRange a, RegExpCharacterRange b) { + exists(RegExpCharacterClass clz | + a = clz.getAChild() and + b = clz.getAChild() and + a != b + | + exists(int alow, int ahigh, int blow, int bhigh | + isRange(a, alow, ahigh) and + isRange(b, blow, bhigh) and + alow <= bhigh and + blow <= ahigh + ) + ) + } + + /** + * Holds if `range` overlaps with the char class `escape` from the same character class. + */ + predicate overlapsWithCharEscape(RegExpCharacterRange range, RegExpCharacterClassEscape escape) { + exists(RegExpCharacterClass clz, string low, string high | + range = clz.getAChild() and + escape = clz.getAChild() and + range.isRange(low, high) + | + escape.getValue() = "w" and + getInRange(low, high).regexpMatch("\\w") + or + escape.getValue() = "d" and + getInRange(low, high).regexpMatch("\\d") + or + escape.getValue() = "s" and + getInRange(low, high).regexpMatch("\\s") + ) + } + + /** Gets the unicode code point for a `char`. */ + bindingset[char] + int toCodePoint(string char) { result.toUnicode() = char } + + /** A character range that appears to be overly wide. */ + class OverlyWideRange instanceof RegExpCharacterRange { + OverlyWideRange() { + exists(int low, int high, int numChars | + isRange(this, low, high) and + numChars = (1 + high - low) and + this.getRootTerm().isUsedAsRegExp() and + numChars >= 10 + | + // across the Z-a range (which includes backticks) + toCodePoint("Z") >= low and + toCodePoint("a") <= high + or + // across the 9-A range (which includes e.g. ; and ?) + toCodePoint("9") >= low and + toCodePoint("A") <= high + or + // a non-alphanumeric char as part of the range boundaries + exists(int bound | bound = [low, high] | not isAlphanumeric(bound.toUnicode())) and + // while still being ascii + low < 128 and + high < 128 + ) and + // allowlist for known ranges + not this = allowedWideRanges() + } + + /** Gets a string representation of a character class that matches the same chars as this range. */ + string printEquivalent() { result = RangePrinter::printEquivalentCharClass(this) } + + /** Gets a string representation of this range. */ + string toString() { result = super.toString() } + + /** Holds if `lo` is the lower bound of this character range and `hi` the upper bound. */ + predicate isRange(string lo, string hi) { super.isRange(lo, hi) } + } + + /** Gets a range that should not be reported as an overly wide range. */ + RegExpCharacterRange allowedWideRanges() { + // ~ is the last printable ASCII character, it's used right in various wide ranges. + result.isRange(_, "~") + or + // the same with " " and "!". " " is the first printable character, and "!" is the first non-white-space printable character. + result.isRange([" ", "!"], _) + or + // the `[@-_]` range is intentional + result.isRange("@", "_") + or + // starting from the zero byte is a good indication that it's purposely matching a large range. + result.isRange(0.toUnicode(), _) + } + + /** Gets a char between (and including) `low` and `high`. */ + bindingset[low, high] + private string getInRange(string low, string high) { + result = [toCodePoint(low) .. toCodePoint(high)].toUnicode() + } + + /** A module computing an equivalent character class for an overly wide range. */ + module RangePrinter { + bindingset[char] + bindingset[result] + private string next(string char) { + exists(int prev, int next | + prev.toUnicode() = char and + next.toUnicode() = result and + next = prev + 1 + ) + } + + /** Gets the points where the parts of the pretty printed range should be cut off. */ + private string cutoffs() { result = ["A", "Z", "a", "z", "0", "9"] } + + /** Gets the char to use in the low end of a range for a given `cut` */ + private string lowCut(string cut) { + cut = ["A", "a", "0"] and + result = cut + or + cut = ["Z", "z", "9"] and + result = next(cut) + } + + /** Gets the char to use in the high end of a range for a given `cut` */ + private string highCut(string cut) { + cut = ["Z", "z", "9"] and + result = cut + or + cut = ["A", "a", "0"] and + next(result) = cut + } + + /** Gets the cutoff char used for a given `part` of a range when pretty-printing it. */ + private string cutoff(OverlyWideRange range, int part) { + exists(int low, int high | isRange(range, low, high) | + result = + rank[part + 1](string cut | + cut = cutoffs() and low < toCodePoint(cut) and toCodePoint(cut) < high + | + cut order by toCodePoint(cut) + ) + ) + } + + /** Gets the number of parts we should print for a given `range`. */ + private int parts(OverlyWideRange range) { result = 1 + count(cutoff(range, _)) } + + /** Holds if the given part of a range should span from `low` to `high`. */ + private predicate part(OverlyWideRange range, int part, string low, string high) { + // first part. + part = 0 and + ( + range.isRange(low, high) and + parts(range) = 1 + or + parts(range) >= 2 and + range.isRange(low, _) and + high = highCut(cutoff(range, part)) + ) + or + // middle + part >= 1 and + part < parts(range) - 1 and + low = lowCut(cutoff(range, part - 1)) and + high = highCut(cutoff(range, part)) + or + // last. + part = parts(range) - 1 and + low = lowCut(cutoff(range, part - 1)) and + range.isRange(_, high) + } + + /** Gets an escaped `char` for use in a character class. */ + bindingset[char] + private string escape(string char) { + exists(string reg | reg = "(\\[|\\]|\\\\|-|/)" | + if char.regexpMatch(reg) then result = "\\" + char else result = char + ) + } + + /** Gets a part of the equivalent range. */ + private string printEquivalentCharClass(OverlyWideRange range, int part) { + exists(string low, string high | part(range, part, low, high) | + if + isAlphanumeric(low) and + isAlphanumeric(high) + then result = low + "-" + high + else + result = + strictconcat(string char | char = getInRange(low, high) | escape(char) order by char) + ) + } + + /** Gets the entire pretty printed equivalent range. */ + string printEquivalentCharClass(OverlyWideRange range) { + result = + strictconcat(string r, int part | + r = "[" and part = -1 and exists(range) + or + r = printEquivalentCharClass(range, part) + or + r = "]" and part = parts(range) + | + r order by part + ) + } + } + + /** Gets a char range that is overly large because of `reason`. */ + RegExpCharacterRange getABadRange(string reason, int priority) { + result instanceof OverlyWideRange and + priority = 0 and + exists(string equiv | equiv = result.(OverlyWideRange).printEquivalent() | + if equiv.length() <= 50 + then reason = "is equivalent to " + equiv + else reason = "is equivalent to " + equiv.substring(0, 50) + "..." + ) + or + priority = 1 and + exists(RegExpCharacterRange other | + reason = "overlaps with " + other + " in the same character class" and + rankRange(result) < rankRange(other) and + overlap(result, other) + ) + or + priority = 2 and + exists(RegExpCharacterClassEscape escape | + reason = "overlaps with " + escape + " in the same character class" and + overlapsWithCharEscape(result, escape) + ) + or + reason = "is empty" and + priority = 3 and + exists(int low, int high | + isRange(result, low, high) and + low > high + ) + } + + /** Holds if `range` matches suspiciously many characters. */ + predicate problem(RegExpCharacterRange range, string reason) { + reason = + strictconcat(string m, int priority | + range = getABadRange(m, priority) + | + m, ", and " order by priority desc + ) and + // specifying a range using an escape is usually OK. + not range.getAChild() instanceof RegExpEscape and + // Unicode escapes in strings are interpreted before it turns into a regexp, + // so e.g. [\u0001-\uFFFF] will just turn up as a range between two constants. + // We therefore exclude these ranges. + range.getRootTerm().getParent() instanceof RegExpLiteral and + // is used as regexp (mostly for JS where regular expressions are parsed eagerly) + range.getRootTerm().isUsedAsRegExp() + } +} diff --git a/shared/regex/codeql/regex/RegexTreeView.qll b/shared/regex/codeql/regex/RegexTreeView.qll new file mode 100644 index 00000000000..f805bd83185 --- /dev/null +++ b/shared/regex/codeql/regex/RegexTreeView.qll @@ -0,0 +1,451 @@ +/** + * This file contains a `RegexTreeViewSig` module describing the syntax tree of regular expressions. + */ + +/** + * A signature describing the syntax tree of regular expressions. + */ +signature module RegexTreeViewSig { + /** + * An element used in some way as or in a regular expression. + * This class exists to have a common supertype that all languages can agree on. + */ + class Top; + + /** + * An element containing a regular expression term, that is, either + * a string literal (parsed as a regular expression; the root of the parse tree) + * or another regular expression term (a descendant of the root). + */ + class RegExpParent extends Top; + + /** + * A regular expression literal. + * + * Note that this class does not cover regular expressions constructed by calling the built-in + * `RegExp` function. + * + * Example: + * + * ``` + * /(?i)ab*c(d|e)$/ + * ``` + */ + class RegExpLiteral extends RegExpParent; + + /** + * A regular expression term, that is, a syntactic part of a regular expression. + * These are the tree nodes that form the parse tree of a regular expression literal. + */ + class RegExpTerm extends Top { + /** Gets a child term of this term. */ + RegExpTerm getAChild(); + + /** + * Holds if this is the root term of a regular expression. + */ + predicate isRootTerm(); + + /** + * Gets the parent term of this regular expression term, or the + * regular expression literal if this is the root term. + */ + RegExpParent getParent(); + + /** + * Holds if this term is part of a regular expression literal, or a string literal + * that is interpreted as a regular expression. + */ + predicate isUsedAsRegExp(); + + /** Gets the outermost term of this regular expression. */ + RegExpTerm getRootTerm(); + + /** Gets the raw source text of this term. */ + string getRawValue(); + + /** Gets the `i`th child term of this term. */ + RegExpTerm getChild(int i); + + /** Gets the number of child terms of this term. */ + int getNumChild(); + + /** Gets the regular expression term that is matched (textually) after this one, if any. */ + RegExpTerm getSuccessor(); + + string toString(); + + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ); + } + + /** + * A quantified regular expression term. + * + * Example: + * + * ``` + * ((ECMA|Java)[sS]cript)* + * ``` + */ + class RegExpQuantifier extends RegExpTerm; + + /** + * A star-quantified term. + * + * Example: + * + * ``` + * \w* + * ``` + */ + class RegExpStar extends RegExpQuantifier; + + /** + * An optional term. + * + * Example: + * + * ``` + * ;? + * ``` + */ + class RegExpOpt extends RegExpQuantifier; + + /** + * A plus-quantified term. + * + * Example: + * + * ``` + * \w+ + * ``` + */ + class RegExpPlus extends RegExpQuantifier; + + /** + * A range-quantified term + * + * Examples: + * + * ``` + * \w{2,4} + * \w{2,} + * \w{2} + * ``` + */ + class RegExpRange extends RegExpQuantifier { + /** Gets the lower bound of the range. */ + int getLowerBound(); + + /** + * Gets the upper bound of the range, if any. + * + * If there is no upper bound, any number of repetitions is allowed. + * For a term of the form `r{lo}`, both the lower and the upper bound + * are `lo`. + */ + int getUpperBound(); + } + + /** + * An escaped regular expression term, that is, a regular expression + * term starting with a backslash. + * + * Example: + * + * ``` + * \. + * \w + * ``` + */ + class RegExpEscape extends RegExpTerm; + + /** + * A character class escape in a regular expression. + * + * Examples: + * + * ``` + * \w + * \S + * ``` + */ + class RegExpCharacterClassEscape extends RegExpEscape { + /** Gets the name of the character class; for example, `w` for `\w`. */ + string getValue(); + } + + /** + * An alternative term, that is, a term of the form `a|b`. + * + * Example: + * + * ``` + * ECMA|Java + * ``` + */ + class RegExpAlt extends RegExpTerm; + + /** + * A grouped regular expression. + * + * Examples: + * + * ``` + * (ECMA|Java) + * (?:ECMA|Java) + * (?['"]) + * ``` + */ + class RegExpGroup extends RegExpTerm { + /** + * Gets the index of this capture group within the enclosing regular + * expression literal. + * + * For example, in the regular expression `/((a?).)(?:b)/`, the + * group `((a?).)` has index 1, the group `(a?)` nested inside it + * has index 2, and the group `(?:b)` has no index, since it is + * not a capture group. + */ + int getNumber(); + } + + /** + * A back reference, that is, a term of the form `\i` or `\k` + * in a regular expression. + * + * Examples: + * + * ``` + * \1 + * \k + * ``` + */ + class RegExpBackRef extends RegExpTerm { + /** Gets the capture group this back reference refers to. */ + RegExpGroup getGroup(); + } + + /** + * A sequence term. + * + * Example: + * + * ``` + * (ECMA|Java)Script + * ``` + * + * This is a sequence with the elements `(ECMA|Java)` and `Script`. + */ + class RegExpSequence extends RegExpTerm; + + /** + * A zero-width lookahead or lookbehind assertion. + * + * Examples: + * + * ``` + * (?=\w) + * (?!\n) + * (?<=\.) + * (?&] + * ``` + */ + class RegExpCharacterClass extends RegExpTerm { + /** + * Holds if this character class matches any character. + */ + predicate isUniversalClass(); + + /** Holds if this is an inverted character class, that is, a term of the form `[^...]`. */ + predicate isInverted(); + } + + /** + * A character range in a character class in a regular expression. + * + * Example: + * + * ``` + * a-z + * ``` + */ + class RegExpCharacterRange extends RegExpTerm { + /** Holds if `lo` is the lower bound of this character range and `hi` the upper bound. */ + predicate isRange(string lo, string hi); + } + + /** + * A dot regular expression. + * + * Example: + * + * ``` + * . + * ``` + */ + class RegExpDot extends RegExpTerm; + + /** + * A dollar assertion `$` matching the end of a line. + * + * Example: + * + * ``` + * $ + * ``` + */ + class RegExpDollar extends RegExpTerm; + + /** + * A caret assertion `^` matching the beginning of a line. + * + * Example: + * + * ``` + * ^ + * ``` + */ + class RegExpCaret extends RegExpTerm; + + /** + * A word boundary assertion. + * + * Example: + * + * ``` + * \b + * ``` + */ + class RegExpWordBoundary extends RegExpTerm; + + /** + * A regular expression term that permits unlimited repetitions. + */ + class InfiniteRepetitionQuantifier extends RegExpQuantifier; + + /** + * Holds if the regular expression should not be considered. + * + * For javascript we make the pragmatic performance optimization to ignore minified files. + */ + predicate isExcluded(RegExpParent parent); + + /** + * Holds if `term` is a possessive quantifier. + * As javascript's regexes do not support possessive quantifiers, this never holds, but is used by the shared library. + */ + predicate isPossessive(RegExpQuantifier term); + + /** + * Holds if the regex that `term` is part of is used in a way that ignores any leading prefix of the input it's matched against. + * Not yet implemented for JavaScript. + */ + predicate matchesAnyPrefix(RegExpTerm term); + + /** + * Holds if the regex that `term` is part of is used in a way that ignores any trailing suffix of the input it's matched against. + * Not yet implemented for JavaScript. + */ + predicate matchesAnySuffix(RegExpTerm term); + + /** + * Holds if `term` is an escape class representing e.g. `\d`. + * `clazz` is which character class it represents, e.g. "d" for `\d`. + */ + predicate isEscapeClass(RegExpTerm term, string clazz); + + /** + * Holds if `root` has the `i` flag for case-insensitive matching. + */ + predicate isIgnoreCase(RegExpTerm root); + + /** + * Holds if `root` has the `s` flag for multi-line matching. + */ + predicate isDotAll(RegExpTerm root); +} diff --git a/shared/regex/codeql/regex/nfa/BadTagFilterQuery.qll b/shared/regex/codeql/regex/nfa/BadTagFilterQuery.qll new file mode 100644 index 00000000000..c9c254fe990 --- /dev/null +++ b/shared/regex/codeql/regex/nfa/BadTagFilterQuery.qll @@ -0,0 +1,177 @@ +/** + * Provides predicates for reasoning about bad tag filter vulnerabilities. + */ + +private import NfaUtils as NfaUtils +private import RegexpMatching as RM +private import codeql.regex.RegexTreeView + +/** + * Module implementing classes and predicates reasoing about bad tag filter vulnerabilities. + */ +module Make { + private import TreeImpl + import RM::Make + + /** + * Holds if the regexp `root` should be tested against `str`. + * Implements the `isRegexpMatchingCandidateSig` signature from `RegexpMatching`. + * `ignorePrefix` toggles whether the regular expression should be treated as accepting any prefix if it's unanchored. + * `testWithGroups` toggles whether it's tested which groups are filled by a given input string. + */ + private predicate isBadTagFilterCandidate( + RootTerm root, string str, boolean ignorePrefix, boolean testWithGroups + ) { + // the regexp must mention "<" and ">" explicitly. + forall(string angleBracket | angleBracket = ["<", ">"] | + any(RegExpConstant term | term.getValue().matches("%" + angleBracket + "%")).getRootTerm() = + root + ) and + ignorePrefix = true and + ( + str = ["", "", "", "", "", + "", "", "", "", + "", "", + "", "", "", + "", "", + "", "", + "") and + regexp.matches("") and + not regexp.matches("") and + ( + not regexp.matches("") and + msg = "This regular expression matches , but not " + or + not regexp.matches("") and + msg = "This regular expression matches , but not " + ) + or + regexp.matches("") and + regexp.matches("") and + not regexp.matches("") and + not regexp.matches("") and + msg = + "This regular expression does not match script tags where the attribute uses single-quotes." + or + regexp.matches("") and + regexp.matches("") and + not regexp.matches("") and + not regexp.matches("") and + msg = + "This regular expression does not match script tags where the attribute uses double-quotes." + or + regexp.matches("") and + regexp.matches("") and + not regexp.matches("") and + not regexp.matches("") and + not regexp.matches("") and + msg = + "This regular expression does not match script tags where tabs are used between attributes." + or + regexp.matches("") and + not isIgnoreCase(regexp) and + not regexp.matches("") and + not regexp.matches("") and + ( + not regexp.matches("") and + msg = "This regular expression does not match upper case ") and + regexp.matches("") and + msg = "This regular expression does not match mixed case ") and + not regexp.matches("") and + not regexp.matches("") and + ( + not regexp.matches("") and + msg = "This regular expression does not match script end tags like ." + or + not regexp.matches("") and + msg = "This regular expression does not match script end tags like ." + or + not regexp.matches("", - "", "", "", "", - "", "", - "", "", "", - "", "", "", - "", "") and - regexp.matches("") and - not regexp.matches("") and - ( - not regexp.matches("") and - msg = "This regular expression matches , but not " - or - not regexp.matches("") and - msg = "This regular expression matches , but not " - ) - or - regexp.matches("") and - regexp.matches("") and - not regexp.matches("") and - not regexp.matches("") and - msg = "This regular expression does not match script tags where the attribute uses single-quotes." - or - regexp.matches("") and - regexp.matches("") and - not regexp.matches("") and - not regexp.matches("") and - msg = "This regular expression does not match script tags where the attribute uses double-quotes." - or - regexp.matches("") and - regexp.matches("") and - not regexp.matches("") and - not regexp.matches("") and - not regexp.matches("") and - msg = "This regular expression does not match script tags where tabs are used between attributes." - or - regexp.matches("") and - not RegExpFlags::isIgnoreCase(regexp) and - not regexp.matches("") and - not regexp.matches("") and - ( - not regexp.matches("") and - msg = "This regular expression does not match upper case ") and - regexp.matches("") and - msg = "This regular expression does not match mixed case ") and - not regexp.matches("") and - not regexp.matches("") and - ( - not regexp.matches("") and - msg = "This regular expression does not match script end tags like ." - or - not regexp.matches("") and - msg = "This regular expression does not match script end tags like ." - or - not regexp.matches("", - "", "", "", "", - "", "", - "", "", "", - "", "", "", - "", "") and - regexp.matches("") and - not regexp.matches("") and - ( - not regexp.matches("") and - msg = "This regular expression matches , but not " - or - not regexp.matches("") and - msg = "This regular expression matches , but not " - ) - or - regexp.matches("") and - regexp.matches("") and - not regexp.matches("") and - not regexp.matches("") and - msg = "This regular expression does not match script tags where the attribute uses single-quotes." - or - regexp.matches("") and - regexp.matches("") and - not regexp.matches("") and - not regexp.matches("") and - msg = "This regular expression does not match script tags where the attribute uses double-quotes." - or - regexp.matches("") and - regexp.matches("") and - not regexp.matches("") and - not regexp.matches("") and - not regexp.matches("") and - msg = "This regular expression does not match script tags where tabs are used between attributes." - or - regexp.matches("") and - not RegExpFlags::isIgnoreCase(regexp) and - not regexp.matches("") and - not regexp.matches("") and - ( - not regexp.matches("") and - msg = "This regular expression does not match upper case ") and - regexp.matches("") and - msg = "This regular expression does not match mixed case ") and - not regexp.matches("") and - not regexp.matches("") and - ( - not regexp.matches("") and - msg = "This regular expression does not match script end tags like ." - or - not regexp.matches("") and - msg = "This regular expression does not match script end tags like ." - or - not regexp.matches(" diff --git a/javascript/extractor/tests/vue/output/trap/rails.erb.trap b/javascript/extractor/tests/vue/output/trap/rails.erb.trap new file mode 100644 index 00000000000..76af8c5c8d3 --- /dev/null +++ b/javascript/extractor/tests/vue/output/trap/rails.erb.trap @@ -0,0 +1,137 @@ +#10000=@"/rails.erb;sourcefile" +files(#10000,"/rails.erb") +#10001=@"/;folder" +folders(#10001,"/") +containerparent(#10001,#10000) +#10002=@"loc,{#10000},0,0,0,0" +locations_default(#10002,#10000,0,0,0,0) +hasLocation(#10000,#10002) +#20000=@"global_scope" +scopes(#20000,0) +#20001=* +#20002=@"script;{#10000},1,9" +#20003=* +lines(#20003,#20002,""," +") +#20004=@"loc,{#10000},1,9,1,8" +locations_default(#20004,#10000,1,9,1,8) +hasLocation(#20003,#20004) +#20005=* +lines(#20005,#20002," console.log(""FOO"");"," +") +#20006=@"loc,{#10000},2,1,2,21" +locations_default(#20006,#10000,2,1,2,21) +hasLocation(#20005,#20006) +indentation(#10000,2," ",2) +numlines(#20002,2,1,0) +#20007=* +tokeninfo(#20007,6,#20002,0,"console") +#20008=@"loc,{#10000},2,3,2,9" +locations_default(#20008,#10000,2,3,2,9) +hasLocation(#20007,#20008) +#20009=* +tokeninfo(#20009,8,#20002,1,".") +#20010=@"loc,{#10000},2,10,2,10" +locations_default(#20010,#10000,2,10,2,10) +hasLocation(#20009,#20010) +#20011=* +tokeninfo(#20011,6,#20002,2,"log") +#20012=@"loc,{#10000},2,11,2,13" +locations_default(#20012,#10000,2,11,2,13) +hasLocation(#20011,#20012) +#20013=* +tokeninfo(#20013,8,#20002,3,"(") +#20014=@"loc,{#10000},2,14,2,14" +locations_default(#20014,#10000,2,14,2,14) +hasLocation(#20013,#20014) +#20015=* +tokeninfo(#20015,4,#20002,4,"""FOO""") +#20016=@"loc,{#10000},2,15,2,19" +locations_default(#20016,#10000,2,15,2,19) +hasLocation(#20015,#20016) +#20017=* +tokeninfo(#20017,8,#20002,5,")") +#20018=@"loc,{#10000},2,20,2,20" +locations_default(#20018,#10000,2,20,2,20) +hasLocation(#20017,#20018) +#20019=* +tokeninfo(#20019,8,#20002,6,";") +#20020=@"loc,{#10000},2,21,2,21" +locations_default(#20020,#10000,2,21,2,21) +hasLocation(#20019,#20020) +#20021=* +tokeninfo(#20021,0,#20002,7,"") +#20022=@"loc,{#10000},3,1,3,0" +locations_default(#20022,#10000,3,1,3,0) +hasLocation(#20021,#20022) +toplevels(#20002,1) +#20023=@"loc,{#10000},1,9,3,0" +locations_default(#20023,#10000,1,9,3,0) +hasLocation(#20002,#20023) +#20024=* +stmts(#20024,2,#20002,0,"console.log(""FOO"");") +#20025=@"loc,{#10000},2,3,2,21" +locations_default(#20025,#10000,2,3,2,21) +hasLocation(#20024,#20025) +stmt_containers(#20024,#20002) +#20026=* +exprs(#20026,13,#20024,0,"console.log(""FOO"")") +#20027=@"loc,{#10000},2,3,2,20" +locations_default(#20027,#10000,2,3,2,20) +hasLocation(#20026,#20027) +enclosing_stmt(#20026,#20024) +expr_containers(#20026,#20002) +#20028=* +exprs(#20028,14,#20026,-1,"console.log") +#20029=@"loc,{#10000},2,3,2,13" +locations_default(#20029,#10000,2,3,2,13) +hasLocation(#20028,#20029) +enclosing_stmt(#20028,#20024) +expr_containers(#20028,#20002) +#20030=* +exprs(#20030,79,#20028,0,"console") +hasLocation(#20030,#20008) +enclosing_stmt(#20030,#20024) +expr_containers(#20030,#20002) +literals("console","console",#20030) +#20031=@"var;{console};{#20000}" +variables(#20031,"console",#20000) +bind(#20030,#20031) +#20032=* +exprs(#20032,0,#20028,1,"log") +hasLocation(#20032,#20012) +enclosing_stmt(#20032,#20024) +expr_containers(#20032,#20002) +literals("log","log",#20032) +#20033=* +exprs(#20033,4,#20026,0,"""FOO""") +hasLocation(#20033,#20016) +enclosing_stmt(#20033,#20024) +expr_containers(#20033,#20002) +literals("FOO","""FOO""",#20033) +#20034=* +regexpterm(#20034,14,#20033,0,"FOO") +#20035=@"loc,{#10000},2,16,2,18" +locations_default(#20035,#10000,2,16,2,18) +hasLocation(#20034,#20035) +regexp_const_value(#20034,"FOO") +#20036=* +entry_cfg_node(#20036,#20002) +hasLocation(#20036,#20004) +#20037=* +exit_cfg_node(#20037,#20002) +hasLocation(#20037,#20022) +successor(#20024,#20030) +successor(#20033,#20026) +successor(#20032,#20028) +successor(#20030,#20032) +successor(#20028,#20033) +successor(#20026,#20037) +successor(#20036,#20024) +toplevel_parent_xml_node(#20002,#20001) +xmlElements(#20001,"script",#10000,0,#10000) +#20038=@"loc,{#10000},1,1,3,9" +locations_default(#20038,#10000,1,1,3,9) +xmllocations(#20001,#20038) +numlines(#10000,3,1,0) +filetype(#10000,"html") From 5940f17b8394c6a641740080cb37a6f1d444f0e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Wed, 9 Nov 2022 13:10:08 +0100 Subject: [PATCH 097/796] Swift: Docs + doctests --- .../Security/CWE-094/UnsafeJsEval.qhelp | 32 ++++ .../Security/CWE-094/UnsafeJsEvalBad.swift | 6 + .../Security/CWE-094/UnsafeJsEvalGood.swift | 10 + .../Security/CWE-094/UnsafeJsEval.expected | 176 +++++++++--------- .../Security/CWE-094/UnsafeJsEval.swift | 20 +- 5 files changed, 152 insertions(+), 92 deletions(-) create mode 100644 swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.qhelp create mode 100644 swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalBad.swift create mode 100644 swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalGood.swift diff --git a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.qhelp b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.qhelp new file mode 100644 index 00000000000..26eae7ff91b --- /dev/null +++ b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.qhelp @@ -0,0 +1,32 @@ + + + +

    Evaluating JavaScript that contains a substring from a remote origin may lead to remote code execution. Code under control of an attacker can execute arbitrary unauthorized actions, including exfiltration of local data by sending it to a third party web service.

    + +
    + + +

    When loading JavaScript into a web view, evaluate only known, locally-defined source code. If a part of the input does come from a remote source, instead of injecting it into the JavaScript code to be evaluated, prefer sending it as data to the web view using an API such as WKWebView.callAsyncJavaScript with the arguments dictionary to pass remote data objects.

    + +
    + + +

    In the following example, a call to WKWebView.evaluateJavaScript evaluates JavaScript source code that is tainted with remote data, potentially introducing a code injection vulnerability.

    + + + +

    To fix the problem, we sanitize the remote data by passing it using the arguments dictionary of WKWebView.callAsyncJavaScript. This ensures that untrusted data cannot be evaluated as JavaScript source code.

    + + + +
    + + +
  • + Apple Developer Documentation - WKWebView.callAsyncJavaScript(_:arguments:in:contentWorld:) +
  • + +
    +
    diff --git a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalBad.swift b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalBad.swift new file mode 100644 index 00000000000..2e5b0233e79 --- /dev/null +++ b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalBad.swift @@ -0,0 +1,6 @@ +let webview: WKWebView +let remoteData = try String(contentsOf: URL(string: "http://example.com/evil.json")!) + +... + +_ = try await webview.evaluateJavaScript("alert(" + remoteData + ")") // BAD diff --git a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalGood.swift b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalGood.swift new file mode 100644 index 00000000000..a51ffd60b63 --- /dev/null +++ b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalGood.swift @@ -0,0 +1,10 @@ +let webview: WKWebView +let remoteData = try String(contentsOf: URL(string: "http://example.com/evil.json")!) + +... + +_ = try await webview.callAsyncJavaScript( + "alert(JSON.parse(data))", + arguments: ["data": remoteData], // GOOD + contentWorld: .page +) diff --git a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected index c9c794bbbb1..05881a11eb5 100644 --- a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected +++ b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected @@ -1,92 +1,92 @@ edges -| UnsafeJsEval.swift:123:21:123:42 | string : | UnsafeJsEval.swift:123:70:123:70 | string : | -| UnsafeJsEval.swift:164:10:164:37 | try ... : | UnsafeJsEval.swift:200:21:200:35 | call to getRemoteData() : | -| UnsafeJsEval.swift:164:10:164:37 | try ... : | UnsafeJsEval.swift:203:7:203:21 | call to getRemoteData() : | -| UnsafeJsEval.swift:164:14:164:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:164:10:164:37 | try ... : | -| UnsafeJsEval.swift:200:21:200:35 | call to getRemoteData() : | UnsafeJsEval.swift:204:7:204:7 | remoteString : | -| UnsafeJsEval.swift:200:21:200:35 | call to getRemoteData() : | UnsafeJsEval.swift:207:7:207:39 | ... .+(_:_:) ... : | -| UnsafeJsEval.swift:200:21:200:35 | call to getRemoteData() : | UnsafeJsEval.swift:213:7:213:49 | call to init(decoding:as:) : | -| UnsafeJsEval.swift:203:7:203:21 | call to getRemoteData() : | UnsafeJsEval.swift:264:13:264:13 | string : | -| UnsafeJsEval.swift:203:7:203:21 | call to getRemoteData() : | UnsafeJsEval.swift:267:13:267:13 | string : | -| UnsafeJsEval.swift:203:7:203:21 | call to getRemoteData() : | UnsafeJsEval.swift:275:13:275:13 | string : | -| UnsafeJsEval.swift:203:7:203:21 | call to getRemoteData() : | UnsafeJsEval.swift:278:13:278:13 | string : | -| UnsafeJsEval.swift:203:7:203:21 | call to getRemoteData() : | UnsafeJsEval.swift:284:13:284:13 | string : | -| UnsafeJsEval.swift:203:7:203:21 | call to getRemoteData() : | UnsafeJsEval.swift:298:13:298:13 | string : | -| UnsafeJsEval.swift:204:7:204:7 | remoteString : | UnsafeJsEval.swift:264:13:264:13 | string : | -| UnsafeJsEval.swift:204:7:204:7 | remoteString : | UnsafeJsEval.swift:267:13:267:13 | string : | -| UnsafeJsEval.swift:204:7:204:7 | remoteString : | UnsafeJsEval.swift:275:13:275:13 | string : | -| UnsafeJsEval.swift:204:7:204:7 | remoteString : | UnsafeJsEval.swift:278:13:278:13 | string : | -| UnsafeJsEval.swift:204:7:204:7 | remoteString : | UnsafeJsEval.swift:284:13:284:13 | string : | -| UnsafeJsEval.swift:204:7:204:7 | remoteString : | UnsafeJsEval.swift:298:13:298:13 | string : | -| UnsafeJsEval.swift:207:7:207:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:264:13:264:13 | string : | -| UnsafeJsEval.swift:207:7:207:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:267:13:267:13 | string : | -| UnsafeJsEval.swift:207:7:207:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:275:13:275:13 | string : | -| UnsafeJsEval.swift:207:7:207:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:278:13:278:13 | string : | -| UnsafeJsEval.swift:207:7:207:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:284:13:284:13 | string : | -| UnsafeJsEval.swift:207:7:207:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:298:13:298:13 | string : | -| UnsafeJsEval.swift:213:7:213:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:264:13:264:13 | string : | -| UnsafeJsEval.swift:213:7:213:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:267:13:267:13 | string : | -| UnsafeJsEval.swift:213:7:213:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:275:13:275:13 | string : | -| UnsafeJsEval.swift:213:7:213:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:278:13:278:13 | string : | -| UnsafeJsEval.swift:213:7:213:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:284:13:284:13 | string : | -| UnsafeJsEval.swift:213:7:213:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:298:13:298:13 | string : | -| UnsafeJsEval.swift:264:13:264:13 | string : | UnsafeJsEval.swift:265:22:265:107 | call to init(source:injectionTime:forMainFrameOnly:) | -| UnsafeJsEval.swift:267:13:267:13 | string : | UnsafeJsEval.swift:268:22:268:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | -| UnsafeJsEval.swift:275:13:275:13 | string : | UnsafeJsEval.swift:276:26:276:26 | string | -| UnsafeJsEval.swift:278:13:278:13 | string : | UnsafeJsEval.swift:279:26:279:26 | string | -| UnsafeJsEval.swift:284:13:284:13 | string : | UnsafeJsEval.swift:285:3:285:10 | .utf16 : | -| UnsafeJsEval.swift:285:3:285:10 | .utf16 : | UnsafeJsEval.swift:285:51:285:51 | stringBytes : | -| UnsafeJsEval.swift:285:51:285:51 | stringBytes : | UnsafeJsEval.swift:286:31:286:97 | call to JSStringCreateWithCharacters(_:_:) : | -| UnsafeJsEval.swift:285:51:285:51 | stringBytes : | UnsafeJsEval.swift:290:17:290:17 | jsstr | -| UnsafeJsEval.swift:286:16:286:98 | call to JSStringRetain(_:) : | UnsafeJsEval.swift:290:17:290:17 | jsstr | -| UnsafeJsEval.swift:286:31:286:97 | call to JSStringCreateWithCharacters(_:_:) : | UnsafeJsEval.swift:123:21:123:42 | string : | -| UnsafeJsEval.swift:286:31:286:97 | call to JSStringCreateWithCharacters(_:_:) : | UnsafeJsEval.swift:286:16:286:98 | call to JSStringRetain(_:) : | -| UnsafeJsEval.swift:286:31:286:97 | call to JSStringCreateWithCharacters(_:_:) : | UnsafeJsEval.swift:290:17:290:17 | jsstr | -| UnsafeJsEval.swift:298:13:298:13 | string : | UnsafeJsEval.swift:299:3:299:10 | .utf8CString : | -| UnsafeJsEval.swift:299:3:299:10 | .utf8CString : | UnsafeJsEval.swift:299:48:299:48 | stringBytes : | -| UnsafeJsEval.swift:299:48:299:48 | stringBytes : | UnsafeJsEval.swift:300:31:300:84 | call to JSStringCreateWithUTF8CString(_:) : | -| UnsafeJsEval.swift:299:48:299:48 | stringBytes : | UnsafeJsEval.swift:304:17:304:17 | jsstr | -| UnsafeJsEval.swift:300:16:300:85 | call to JSStringRetain(_:) : | UnsafeJsEval.swift:304:17:304:17 | jsstr | -| UnsafeJsEval.swift:300:31:300:84 | call to JSStringCreateWithUTF8CString(_:) : | UnsafeJsEval.swift:123:21:123:42 | string : | -| UnsafeJsEval.swift:300:31:300:84 | call to JSStringCreateWithUTF8CString(_:) : | UnsafeJsEval.swift:300:16:300:85 | call to JSStringRetain(_:) : | -| UnsafeJsEval.swift:300:31:300:84 | call to JSStringCreateWithUTF8CString(_:) : | UnsafeJsEval.swift:304:17:304:17 | jsstr | +| UnsafeJsEval.swift:124:21:124:42 | string : | UnsafeJsEval.swift:124:70:124:70 | string : | +| UnsafeJsEval.swift:165:10:165:37 | try ... : | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | +| UnsafeJsEval.swift:165:10:165:37 | try ... : | UnsafeJsEval.swift:204:7:204:21 | call to getRemoteData() : | +| UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:165:10:165:37 | try ... : | +| UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | UnsafeJsEval.swift:205:7:205:7 | remoteString : | +| UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | +| UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | +| UnsafeJsEval.swift:204:7:204:21 | call to getRemoteData() : | UnsafeJsEval.swift:265:13:265:13 | string : | +| UnsafeJsEval.swift:204:7:204:21 | call to getRemoteData() : | UnsafeJsEval.swift:268:13:268:13 | string : | +| UnsafeJsEval.swift:204:7:204:21 | call to getRemoteData() : | UnsafeJsEval.swift:276:13:276:13 | string : | +| UnsafeJsEval.swift:204:7:204:21 | call to getRemoteData() : | UnsafeJsEval.swift:279:13:279:13 | string : | +| UnsafeJsEval.swift:204:7:204:21 | call to getRemoteData() : | UnsafeJsEval.swift:285:13:285:13 | string : | +| UnsafeJsEval.swift:204:7:204:21 | call to getRemoteData() : | UnsafeJsEval.swift:299:13:299:13 | string : | +| UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:265:13:265:13 | string : | +| UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:268:13:268:13 | string : | +| UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:276:13:276:13 | string : | +| UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:279:13:279:13 | string : | +| UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:285:13:285:13 | string : | +| UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:299:13:299:13 | string : | +| UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:265:13:265:13 | string : | +| UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:268:13:268:13 | string : | +| UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:276:13:276:13 | string : | +| UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:279:13:279:13 | string : | +| UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:285:13:285:13 | string : | +| UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:299:13:299:13 | string : | +| UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:265:13:265:13 | string : | +| UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:268:13:268:13 | string : | +| UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:276:13:276:13 | string : | +| UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:279:13:279:13 | string : | +| UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:285:13:285:13 | string : | +| UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:299:13:299:13 | string : | +| UnsafeJsEval.swift:265:13:265:13 | string : | UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | +| UnsafeJsEval.swift:268:13:268:13 | string : | UnsafeJsEval.swift:269:22:269:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | +| UnsafeJsEval.swift:276:13:276:13 | string : | UnsafeJsEval.swift:277:26:277:26 | string | +| UnsafeJsEval.swift:279:13:279:13 | string : | UnsafeJsEval.swift:280:26:280:26 | string | +| UnsafeJsEval.swift:285:13:285:13 | string : | UnsafeJsEval.swift:286:3:286:10 | .utf16 : | +| UnsafeJsEval.swift:286:3:286:10 | .utf16 : | UnsafeJsEval.swift:286:51:286:51 | stringBytes : | +| UnsafeJsEval.swift:286:51:286:51 | stringBytes : | UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) : | +| UnsafeJsEval.swift:286:51:286:51 | stringBytes : | UnsafeJsEval.swift:291:17:291:17 | jsstr | +| UnsafeJsEval.swift:287:16:287:98 | call to JSStringRetain(_:) : | UnsafeJsEval.swift:291:17:291:17 | jsstr | +| UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) : | UnsafeJsEval.swift:124:21:124:42 | string : | +| UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) : | UnsafeJsEval.swift:287:16:287:98 | call to JSStringRetain(_:) : | +| UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) : | UnsafeJsEval.swift:291:17:291:17 | jsstr | +| UnsafeJsEval.swift:299:13:299:13 | string : | UnsafeJsEval.swift:300:3:300:10 | .utf8CString : | +| UnsafeJsEval.swift:300:3:300:10 | .utf8CString : | UnsafeJsEval.swift:300:48:300:48 | stringBytes : | +| UnsafeJsEval.swift:300:48:300:48 | stringBytes : | UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) : | +| UnsafeJsEval.swift:300:48:300:48 | stringBytes : | UnsafeJsEval.swift:305:17:305:17 | jsstr | +| UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) : | UnsafeJsEval.swift:305:17:305:17 | jsstr | +| UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) : | UnsafeJsEval.swift:124:21:124:42 | string : | +| UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) : | UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) : | +| UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) : | UnsafeJsEval.swift:305:17:305:17 | jsstr | nodes -| UnsafeJsEval.swift:123:21:123:42 | string : | semmle.label | string : | -| UnsafeJsEval.swift:123:70:123:70 | string : | semmle.label | string : | -| UnsafeJsEval.swift:164:10:164:37 | try ... : | semmle.label | try ... : | -| UnsafeJsEval.swift:164:14:164:37 | call to init(contentsOf:) : | semmle.label | call to init(contentsOf:) : | -| UnsafeJsEval.swift:200:21:200:35 | call to getRemoteData() : | semmle.label | call to getRemoteData() : | -| UnsafeJsEval.swift:203:7:203:21 | call to getRemoteData() : | semmle.label | call to getRemoteData() : | -| UnsafeJsEval.swift:204:7:204:7 | remoteString : | semmle.label | remoteString : | -| UnsafeJsEval.swift:207:7:207:39 | ... .+(_:_:) ... : | semmle.label | ... .+(_:_:) ... : | -| UnsafeJsEval.swift:213:7:213:49 | call to init(decoding:as:) : | semmle.label | call to init(decoding:as:) : | -| UnsafeJsEval.swift:264:13:264:13 | string : | semmle.label | string : | -| UnsafeJsEval.swift:265:22:265:107 | call to init(source:injectionTime:forMainFrameOnly:) | semmle.label | call to init(source:injectionTime:forMainFrameOnly:) | -| UnsafeJsEval.swift:267:13:267:13 | string : | semmle.label | string : | -| UnsafeJsEval.swift:268:22:268:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | semmle.label | call to init(source:injectionTime:forMainFrameOnly:in:) | -| UnsafeJsEval.swift:275:13:275:13 | string : | semmle.label | string : | -| UnsafeJsEval.swift:276:26:276:26 | string | semmle.label | string | -| UnsafeJsEval.swift:278:13:278:13 | string : | semmle.label | string : | -| UnsafeJsEval.swift:279:26:279:26 | string | semmle.label | string | -| UnsafeJsEval.swift:284:13:284:13 | string : | semmle.label | string : | -| UnsafeJsEval.swift:285:3:285:10 | .utf16 : | semmle.label | .utf16 : | -| UnsafeJsEval.swift:285:51:285:51 | stringBytes : | semmle.label | stringBytes : | -| UnsafeJsEval.swift:286:16:286:98 | call to JSStringRetain(_:) : | semmle.label | call to JSStringRetain(_:) : | -| UnsafeJsEval.swift:286:31:286:97 | call to JSStringCreateWithCharacters(_:_:) : | semmle.label | call to JSStringCreateWithCharacters(_:_:) : | -| UnsafeJsEval.swift:290:17:290:17 | jsstr | semmle.label | jsstr | -| UnsafeJsEval.swift:298:13:298:13 | string : | semmle.label | string : | -| UnsafeJsEval.swift:299:3:299:10 | .utf8CString : | semmle.label | .utf8CString : | -| UnsafeJsEval.swift:299:48:299:48 | stringBytes : | semmle.label | stringBytes : | -| UnsafeJsEval.swift:300:16:300:85 | call to JSStringRetain(_:) : | semmle.label | call to JSStringRetain(_:) : | -| UnsafeJsEval.swift:300:31:300:84 | call to JSStringCreateWithUTF8CString(_:) : | semmle.label | call to JSStringCreateWithUTF8CString(_:) : | -| UnsafeJsEval.swift:304:17:304:17 | jsstr | semmle.label | jsstr | +| UnsafeJsEval.swift:124:21:124:42 | string : | semmle.label | string : | +| UnsafeJsEval.swift:124:70:124:70 | string : | semmle.label | string : | +| UnsafeJsEval.swift:165:10:165:37 | try ... : | semmle.label | try ... : | +| UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | semmle.label | call to init(contentsOf:) : | +| UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | semmle.label | call to getRemoteData() : | +| UnsafeJsEval.swift:204:7:204:21 | call to getRemoteData() : | semmle.label | call to getRemoteData() : | +| UnsafeJsEval.swift:205:7:205:7 | remoteString : | semmle.label | remoteString : | +| UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | semmle.label | ... .+(_:_:) ... : | +| UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | semmle.label | call to init(decoding:as:) : | +| UnsafeJsEval.swift:265:13:265:13 | string : | semmle.label | string : | +| UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | semmle.label | call to init(source:injectionTime:forMainFrameOnly:) | +| UnsafeJsEval.swift:268:13:268:13 | string : | semmle.label | string : | +| UnsafeJsEval.swift:269:22:269:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | semmle.label | call to init(source:injectionTime:forMainFrameOnly:in:) | +| UnsafeJsEval.swift:276:13:276:13 | string : | semmle.label | string : | +| UnsafeJsEval.swift:277:26:277:26 | string | semmle.label | string | +| UnsafeJsEval.swift:279:13:279:13 | string : | semmle.label | string : | +| UnsafeJsEval.swift:280:26:280:26 | string | semmle.label | string | +| UnsafeJsEval.swift:285:13:285:13 | string : | semmle.label | string : | +| UnsafeJsEval.swift:286:3:286:10 | .utf16 : | semmle.label | .utf16 : | +| UnsafeJsEval.swift:286:51:286:51 | stringBytes : | semmle.label | stringBytes : | +| UnsafeJsEval.swift:287:16:287:98 | call to JSStringRetain(_:) : | semmle.label | call to JSStringRetain(_:) : | +| UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) : | semmle.label | call to JSStringCreateWithCharacters(_:_:) : | +| UnsafeJsEval.swift:291:17:291:17 | jsstr | semmle.label | jsstr | +| UnsafeJsEval.swift:299:13:299:13 | string : | semmle.label | string : | +| UnsafeJsEval.swift:300:3:300:10 | .utf8CString : | semmle.label | .utf8CString : | +| UnsafeJsEval.swift:300:48:300:48 | stringBytes : | semmle.label | stringBytes : | +| UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) : | semmle.label | call to JSStringRetain(_:) : | +| UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) : | semmle.label | call to JSStringCreateWithUTF8CString(_:) : | +| UnsafeJsEval.swift:305:17:305:17 | jsstr | semmle.label | jsstr | subpaths -| UnsafeJsEval.swift:286:31:286:97 | call to JSStringCreateWithCharacters(_:_:) : | UnsafeJsEval.swift:123:21:123:42 | string : | UnsafeJsEval.swift:123:70:123:70 | string : | UnsafeJsEval.swift:286:16:286:98 | call to JSStringRetain(_:) : | -| UnsafeJsEval.swift:300:31:300:84 | call to JSStringCreateWithUTF8CString(_:) : | UnsafeJsEval.swift:123:21:123:42 | string : | UnsafeJsEval.swift:123:70:123:70 | string : | UnsafeJsEval.swift:300:16:300:85 | call to JSStringRetain(_:) : | +| UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) : | UnsafeJsEval.swift:124:21:124:42 | string : | UnsafeJsEval.swift:124:70:124:70 | string : | UnsafeJsEval.swift:287:16:287:98 | call to JSStringRetain(_:) : | +| UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) : | UnsafeJsEval.swift:124:21:124:42 | string : | UnsafeJsEval.swift:124:70:124:70 | string : | UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) : | #select -| UnsafeJsEval.swift:265:22:265:107 | call to init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:164:14:164:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:265:22:265:107 | call to init(source:injectionTime:forMainFrameOnly:) | Evaluation of uncontrolled JavaScript from a remote source. | -| UnsafeJsEval.swift:268:22:268:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | UnsafeJsEval.swift:164:14:164:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:268:22:268:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | Evaluation of uncontrolled JavaScript from a remote source. | -| UnsafeJsEval.swift:276:26:276:26 | string | UnsafeJsEval.swift:164:14:164:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:276:26:276:26 | string | Evaluation of uncontrolled JavaScript from a remote source. | -| UnsafeJsEval.swift:279:26:279:26 | string | UnsafeJsEval.swift:164:14:164:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:279:26:279:26 | string | Evaluation of uncontrolled JavaScript from a remote source. | -| UnsafeJsEval.swift:290:17:290:17 | jsstr | UnsafeJsEval.swift:164:14:164:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:290:17:290:17 | jsstr | Evaluation of uncontrolled JavaScript from a remote source. | -| UnsafeJsEval.swift:304:17:304:17 | jsstr | UnsafeJsEval.swift:164:14:164:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:304:17:304:17 | jsstr | Evaluation of uncontrolled JavaScript from a remote source. | +| UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | Evaluation of uncontrolled JavaScript from a remote source. | +| UnsafeJsEval.swift:269:22:269:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:269:22:269:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | Evaluation of uncontrolled JavaScript from a remote source. | +| UnsafeJsEval.swift:277:26:277:26 | string | UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:277:26:277:26 | string | Evaluation of uncontrolled JavaScript from a remote source. | +| UnsafeJsEval.swift:280:26:280:26 | string | UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:280:26:280:26 | string | Evaluation of uncontrolled JavaScript from a remote source. | +| UnsafeJsEval.swift:291:17:291:17 | jsstr | UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:291:17:291:17 | jsstr | Evaluation of uncontrolled JavaScript from a remote source. | +| UnsafeJsEval.swift:305:17:305:17 | jsstr | UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:305:17:305:17 | jsstr | Evaluation of uncontrolled JavaScript from a remote source. | diff --git a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.swift b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.swift index 98f34e9826f..36cee943b66 100644 --- a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.swift +++ b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.swift @@ -12,6 +12,7 @@ class NSView : NSResponder {} class WKFrameInfo : NSObject {} class WKContentWorld : NSObject { class var defaultClient: WKContentWorld { WKContentWorld() } + class var page: WKContentWorld { WKContentWorld() } } class WKWebView : UIView { @@ -174,17 +175,17 @@ func testAsync(_ sink: @escaping (String) async throws -> ()) { let remoteString = getRemoteData() try! await sink(localString) // GOOD: the HTML data is local - try! await sink(getRemoteData()) // BAD: HTML contains remote input, may access local secrets - try! await sink(remoteString) // BAD + try! await sink(getRemoteData()) // BAD [NOT DETECTED - TODO: extract Callables of @MainActor method calls]: HTML contains remote input, may access local secrets + try! await sink(remoteString) // BAD [NOT DETECTED - TODO: extract Callables of @MainActor method calls] try! await sink("console.log(" + localStringFragment + ")") // GOOD: the HTML data is local - try! await sink("console.log(" + remoteString + ")") // BAD + try! await sink("console.log(" + remoteString + ")") // BAD [NOT DETECTED - TODO: extract Callables of @MainActor method calls] let localData = Data(localString.utf8) let remoteData = Data(remoteString.utf8) try! await sink(String(decoding: localData, as: UTF8.self)) // GOOD: the data is local - try! await sink(String(decoding: remoteData, as: UTF8.self)) // BAD: the data is remote + try! await sink(String(decoding: remoteData, as: UTF8.self)) // BAD [NOT DETECTED - TODO: extract Callables of @MainActor method calls]: the data is remote try! await sink("console.log(" + String(Int(localStringFragment) ?? 0) + ")") // GOOD: Primitive conversion try! await sink("console.log(" + String(Int(remoteString) ?? 0) + ")") // GOOD: Primitive conversion @@ -312,7 +313,18 @@ func testJSEvaluateScript() { } func testQHelpExamples() { + Task { + let webview = WKWebView() + let remoteData = try String(contentsOf: URL(string: "http://example.com/evil.json")!) + _ = try await webview.evaluateJavaScript("alert(" + remoteData + ")") // BAD [NOT DETECTED - TODO: extract Callables of @MainActor method calls] + + _ = try await webview.callAsyncJavaScript( + "alert(JSON.parse(data))", + arguments: ["data": remoteData], // GOOD + contentWorld: .page + ) + } } testUIWebView() From ade83b3cfe8f0e9689cf42ac86f2dd1160a454bc Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 9 Nov 2022 12:52:33 +0100 Subject: [PATCH 098/796] Dataflow: Introduce support for src/sink grouping in path results. --- .../java/dataflow/internal/DataFlowImpl.qll | 114 +++++++++++++++++- 1 file changed, 111 insertions(+), 3 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration From b3b77111494f43ad6da643aafaf5ebbcdaa3870d Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 9 Nov 2022 14:23:15 +0100 Subject: [PATCH 099/796] Dataflow: Sync. --- .../cpp/ir/dataflow/internal/DataFlowImpl.qll | 114 +++++++++++++++++- .../ir/dataflow/internal/DataFlowImpl2.qll | 114 +++++++++++++++++- .../ir/dataflow/internal/DataFlowImpl3.qll | 114 +++++++++++++++++- .../ir/dataflow/internal/DataFlowImpl4.qll | 114 +++++++++++++++++- .../cpp/dataflow/internal/DataFlowImpl.qll | 114 +++++++++++++++++- .../cpp/dataflow/internal/DataFlowImpl2.qll | 114 +++++++++++++++++- .../cpp/dataflow/internal/DataFlowImpl3.qll | 114 +++++++++++++++++- .../cpp/dataflow/internal/DataFlowImpl4.qll | 114 +++++++++++++++++- .../dataflow/internal/DataFlowImplLocal.qll | 114 +++++++++++++++++- .../cpp/ir/dataflow/internal/DataFlowImpl.qll | 114 +++++++++++++++++- .../ir/dataflow/internal/DataFlowImpl2.qll | 114 +++++++++++++++++- .../ir/dataflow/internal/DataFlowImpl3.qll | 114 +++++++++++++++++- .../ir/dataflow/internal/DataFlowImpl4.qll | 114 +++++++++++++++++- .../csharp/dataflow/internal/DataFlowImpl.qll | 114 +++++++++++++++++- .../dataflow/internal/DataFlowImpl2.qll | 114 +++++++++++++++++- .../dataflow/internal/DataFlowImpl3.qll | 114 +++++++++++++++++- .../dataflow/internal/DataFlowImpl4.qll | 114 +++++++++++++++++- .../dataflow/internal/DataFlowImpl5.qll | 114 +++++++++++++++++- .../DataFlowImplForContentDataFlow.qll | 114 +++++++++++++++++- .../java/dataflow/internal/DataFlowImpl2.qll | 114 +++++++++++++++++- .../java/dataflow/internal/DataFlowImpl3.qll | 114 +++++++++++++++++- .../java/dataflow/internal/DataFlowImpl4.qll | 114 +++++++++++++++++- .../java/dataflow/internal/DataFlowImpl5.qll | 114 +++++++++++++++++- .../java/dataflow/internal/DataFlowImpl6.qll | 114 +++++++++++++++++- .../DataFlowImplForOnActivityResult.qll | 114 +++++++++++++++++- .../DataFlowImplForSerializability.qll | 114 +++++++++++++++++- .../dataflow/new/internal/DataFlowImpl.qll | 114 +++++++++++++++++- .../dataflow/new/internal/DataFlowImpl2.qll | 114 +++++++++++++++++- .../dataflow/new/internal/DataFlowImpl3.qll | 114 +++++++++++++++++- .../dataflow/new/internal/DataFlowImpl4.qll | 114 +++++++++++++++++- .../ruby/dataflow/internal/DataFlowImpl.qll | 114 +++++++++++++++++- .../ruby/dataflow/internal/DataFlowImpl2.qll | 114 +++++++++++++++++- .../DataFlowImplForHttpClientLibraries.qll | 114 +++++++++++++++++- .../internal/DataFlowImplForPathname.qll | 114 +++++++++++++++++- .../internal/DataFlowImplForRegExp.qll | 114 +++++++++++++++++- .../swift/dataflow/internal/DataFlowImpl.qll | 114 +++++++++++++++++- 36 files changed, 3996 insertions(+), 108 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration From 6cb01a210fdf8886c82f410ffed1faf11c9df49c Mon Sep 17 00:00:00 2001 From: Tiferet Gazit Date: Wed, 9 Nov 2022 12:53:52 -0800 Subject: [PATCH 100/796] Apply suggestions from code review Co-authored-by: Stephan Brandauer --- .../adaptivethreatmodeling/EndpointCharacteristics.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index ce99a62f24c..58c9bb6d3bd 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -36,9 +36,9 @@ abstract class EndpointCharacteristic extends string { * isPositiveIndicator: If true, this characteristic indicates that this endpoint _is_ a member of the class; if * false, it indicates that it _isn't_ a member of the class. * confidence: A float in [0, 1], which tells us how strong an indicator this characteristic is for the endpoint - * belonging / not belonging to the given class. A confidence near zero means this characterestic is a very weak + * belonging / not belonging to the given class. A confidence near zero means this characteristic is a very weak * indicator of whether or not the endpoint belongs to the class. A confidence of 1 means that all endpoints with - * this characteristic difinitively do/don't belong to the class. + * this characteristic definitively do/don't belong to the class. */ abstract predicate getImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence From 243980ef73d14e2099e6d4fb98abc7a7904f5e66 Mon Sep 17 00:00:00 2001 From: tiferet Date: Wed, 9 Nov 2022 13:04:16 -0800 Subject: [PATCH 101/796] Documentation improvements --- .../adaptivethreatmodeling/EndpointCharacteristics.qll | 5 +++-- .../experimental/adaptivethreatmodeling/EndpointTypes.qll | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index 58c9bb6d3bd..4756f645a95 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -31,8 +31,9 @@ abstract class EndpointCharacteristic extends string { * This predicate describes what the characteristic tells us about an endpoint. * * Params: - * endpointClass: Class 0 is the negative class, containing non-sink endpoints. Each positive int corresponds to a - * single sink type. + * endpointClass: The sink type. Each EndpointType has a predicate getEncoding, which specifies the classifier + * class for this sink type. Class 0 is the negative class (non-sink). Each positive int corresponds to a single + * sink type. * isPositiveIndicator: If true, this characteristic indicates that this endpoint _is_ a member of the class; if * false, it indicates that it _isn't_ a member of the class. * confidence: A float in [0, 1], which tells us how strong an indicator this characteristic is for the endpoint diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointTypes.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointTypes.qll index aa625b12862..093ed9f3437 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointTypes.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointTypes.qll @@ -16,6 +16,11 @@ newtype TEndpointType = abstract class EndpointType extends TEndpointType { abstract string getDescription(); + /** + * The integer representation of this endpoint type. This integer representation specifies the class number used + * by the endpoint scoring model (the classifier) to represent this endpoint type. Class 0 is the negative class + * (non-sink). Each positive int corresponds to a single sink type. + */ abstract int getEncoding(); string toString() { result = getDescription() } From b6532fa9a0b3de49b7ad045cca35562b873850d2 Mon Sep 17 00:00:00 2001 From: tiferet Date: Wed, 9 Nov 2022 13:10:54 -0800 Subject: [PATCH 102/796] Fix QLDoc style warning --- .../experimental/adaptivethreatmodeling/EndpointTypes.qll | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointTypes.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointTypes.qll index 093ed9f3437..d2cc37b1b33 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointTypes.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointTypes.qll @@ -17,9 +17,9 @@ abstract class EndpointType extends TEndpointType { abstract string getDescription(); /** - * The integer representation of this endpoint type. This integer representation specifies the class number used - * by the endpoint scoring model (the classifier) to represent this endpoint type. Class 0 is the negative class - * (non-sink). Each positive int corresponds to a single sink type. + * Gets the integer representation of this endpoint type. This integer representation specifies the class number + * used by the endpoint scoring model (the classifier) to represent this endpoint type. Class 0 is the negative + * class (non-sink). Each positive int corresponds to a single sink type. */ abstract int getEncoding(); From dbcdc2209e556484408971a0188e63fbed2377ae Mon Sep 17 00:00:00 2001 From: tiferet Date: Wed, 9 Nov 2022 14:25:08 -0800 Subject: [PATCH 103/796] Use names constants for confidence levels --- .../adaptivethreatmodeling/ATMConfig.qll | 3 +- .../EndpointCharacteristics.qll | 28 +++++++++++++++---- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index ba555b0de5b..55d75ad2e4d 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -50,7 +50,8 @@ abstract class AtmConfig extends string { // known sink for the class. exists(EndpointCharacteristic characteristic | characteristic.getEndpoints(sink) and - characteristic.getImplications(this.getASinkEndpointType(), true, 1.0) + characteristic + .getImplications(this.getASinkEndpointType(), true, characteristic.maximalConfidence()) ) } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index 4756f645a95..33cd559503c 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -44,6 +44,14 @@ abstract class EndpointCharacteristic extends string { abstract predicate getImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ); + + // The following are some confidence values that are used in practice by the subclasses. They are defined as named + // constants here to make it easier to change them in the future. + final float maximalConfidence() { result = 1.0 } + + final float highConfidence() { result = 0.9 } + + final float mediumConfidence() { result = 0.6 } } /* @@ -63,7 +71,9 @@ private class DomBasedXssSinkCharacteristic extends EndpointCharacteristic { override predicate getImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { - endpointClass instanceof XssSinkType and isPositiveIndicator = true and confidence = 1.0 + endpointClass instanceof XssSinkType and + isPositiveIndicator = true and + confidence = maximalConfidence() } } @@ -79,7 +89,9 @@ private class TaintedPathSinkCharacteristic extends EndpointCharacteristic { override predicate getImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { - endpointClass instanceof TaintedPathSinkType and isPositiveIndicator = true and confidence = 1.0 + endpointClass instanceof TaintedPathSinkType and + isPositiveIndicator = true and + confidence = maximalConfidence() } } @@ -97,7 +109,7 @@ private class SqlInjectionSinkCharacteristic extends EndpointCharacteristic { ) { endpointClass instanceof SqlInjectionSinkType and isPositiveIndicator = true and - confidence = 1.0 + confidence = maximalConfidence() } } @@ -115,7 +127,7 @@ private class NosqlInjectionSinkCharacteristic extends EndpointCharacteristic { ) { endpointClass instanceof NosqlInjectionSinkType and isPositiveIndicator = true and - confidence = 1.0 + confidence = maximalConfidence() } } @@ -151,7 +163,9 @@ abstract private class NotASinkCharacteristic extends OtherModeledArgumentCharac override predicate getImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { - endpointClass instanceof NegativeType and isPositiveIndicator = true and confidence = 0.9 + endpointClass instanceof NegativeType and + isPositiveIndicator = true and + confidence = highConfidence() } } @@ -168,7 +182,9 @@ abstract class LikelyNotASinkCharacteristic extends OtherModeledArgumentCharacte override predicate getImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { - endpointClass instanceof NegativeType and isPositiveIndicator = true and confidence = 0.6 + endpointClass instanceof NegativeType and + isPositiveIndicator = true and + confidence = mediumConfidence() } } From a8b0d298ffd0f14aae5952a7612e1044aa038e71 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Thu, 10 Nov 2022 16:38:09 +1300 Subject: [PATCH 104/796] Ruby: More string comparison guards Recognise if statements with conditionals made up or logical `and` or `or` clauses as barrier guards. --- .../codeql/ruby/dataflow/BarrierGuards.qll | 25 ++++++++++ .../dataflow/barrier-guards/barrier-guards.rb | 46 +++++++++++++++++-- 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll index f42ca8155b2..b2827e53255 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll @@ -25,6 +25,31 @@ private predicate stringConstCompare(CfgNodes::AstCfgNode guard, CfgNode testedN ) or stringConstCaseCompare(guard, testedNode, branch) + or + stringConstCompareOr(guard, testedNode, branch) + or + stringConstCompareAnd(guard, testedNode, branch) +} + +private predicate stringConstCompareOr( + CfgNodes::ExprNodes::BinaryOperationCfgNode guard, CfgNode testedNode, boolean branch +) { + guard.getExpr() instanceof LogicalOrExpr and + branch = true and + exists(Ssa::Definition def | + forall(CfgNode innerGuard | innerGuard = guard.getAnOperand() | + stringConstCompare(innerGuard, def.getARead(), branch) + ) and + testedNode = any(CfgNode node | stringConstCompare(guard.getAnOperand(), node, _)) + ) +} + +private predicate stringConstCompareAnd( + CfgNodes::ExprNodes::BinaryOperationCfgNode guard, CfgNode testedNode, boolean branch +) { + guard.getExpr() instanceof LogicalAndExpr and + branch = true and + stringConstCompare(guard.getAnOperand(), testedNode, branch) } /** diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb index 926cb4a06c5..26c5da44798 100644 --- a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb @@ -136,10 +136,10 @@ when "bar" end case foo -when "foo", "bar" # $ MISSING: guarded - foo -when "baz", "quux" # $ MISSING: guarded - foo +when "foo", "bar" + foo # $ MISSING: guarded +when "baz", "quux" + foo # $ MISSING: guarded else foo end @@ -189,7 +189,43 @@ when *FOO_AND_X # not a guard - includes non-constant element `x` end if foo == "foo" or foo == "bar" - foo # $ MISSING: guarded + foo # $ guarded +end + +if foo == "foo" or foo == "bar" or foo == "baz" + foo # $ guarded +end + +if foo == "foo" or foo == "bar" or foo == x + foo +end + +if foo == "foo" or bar == "bar" or foo == "baz" + foo +end + +if foo == "foo" and x + foo # $ guarded +end + +if x and foo == "foo" + foo # $ guarded +end + +if x and y and foo == "foo" + foo # $ guarded +end + +if foo == "foo" and foo == "bar" # $ guarded (second `foo` is guarded by the first comparison) + foo # $ guarded +end + +if x and y + foo +end + +if foo == "foo" and y + bar end case From ee02265ac2fd18bfaa8cd1eafa857fc354db7f6c Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Thu, 10 Nov 2022 12:24:39 +0100 Subject: [PATCH 105/796] Add property `params` to `RequestInputAccess` --- javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll index 18790d979c2..4c7dd3e5a49 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll @@ -134,7 +134,7 @@ module Hapi { kind = "parameter" and exists(DataFlow::PropRead query | // `request.query.name` - query.accesses(request, "query") and + query.accesses(request, ["query", "params"]) and this.(DataFlow::PropRead).accesses(query, _) ) or From 4a98ef064ea0aba1ce83e2107c6c0460d0ad4c6c Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Thu, 10 Nov 2022 11:51:47 +0000 Subject: [PATCH 106/796] Ruby: use the 'customizations' pattern for the SQL injection query --- .../security/SqlInjectionCustomizations.qll | 45 +++++++++++++++++++ .../ruby/security/SqlInjectionQuery.qll | 18 ++++++++ .../queries/security/cwe-089/SqlInjection.ql | 21 +-------- 3 files changed, 65 insertions(+), 19 deletions(-) create mode 100644 ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll create mode 100644 ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll diff --git a/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll new file mode 100644 index 00000000000..68f053109f5 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll @@ -0,0 +1,45 @@ +/** + * Provides default sources, sinks and sanitizers for detecting SQL injection + * vulnerabilities, as well as extension points for adding your own. + */ + +private import codeql.ruby.Concepts +private import codeql.ruby.DataFlow +private import codeql.ruby.dataflow.BarrierGuards +private import codeql.ruby.dataflow.RemoteFlowSources + +/** + * Provides default sources, sinks and sanitizers for detecting SQL injection + * vulnerabilities, as well as extension points for adding your own. + */ +module SqlInjection { + abstract class Source extends DataFlow::Node { } + + abstract class Sink extends DataFlow::Node { } + + abstract class Sanitizer extends DataFlow::Node { } + + /** + * A source of remote user input, considered as a flow source. + */ + private class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { } + + /** + * A SQL statement of a SQL execution, considered as a flow sink. + */ + private class SqlExecutionAsSink extends Sink { + SqlExecutionAsSink() { this = any(SqlExecution e).getSql() } + } + + /** + * A comparison with a constant string, considered as a sanitizer-guard. + */ + private class StringConstCompareAsSanitizerGuard extends Sanitizer, StringConstCompareBarrier { } + + /** + * An inclusion check against an array of constant strings, considered as a + * sanitizer-guard. + */ + class StringConstArrayInclusionCallAsSanitizer extends Sanitizer, + StringConstArrayInclusionCallBarrier { } +} diff --git a/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll new file mode 100644 index 00000000000..e2dd327ccbd --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll @@ -0,0 +1,18 @@ +/** + * Provides default sources, sinks and sanitizers for detecting SQL injection + * vulnerabilities, as well as extension points for adding your own. + */ + +private import codeql.ruby.DataFlow +private import codeql.ruby.TaintTracking +import SqlInjectionCustomizations::SqlInjection + +class Configuration extends TaintTracking::Configuration { + Configuration() { this = "SqlInjectionConfiguration" } + + override predicate isSource(DataFlow::Node source) { source instanceof Source } + + override predicate isSink(DataFlow::Node source) { source instanceof Sink } + + override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } +} diff --git a/ruby/ql/src/queries/security/cwe-089/SqlInjection.ql b/ruby/ql/src/queries/security/cwe-089/SqlInjection.ql index fa7bc13402c..28be96deb7d 100644 --- a/ruby/ql/src/queries/security/cwe-089/SqlInjection.ql +++ b/ruby/ql/src/queries/security/cwe-089/SqlInjection.ql @@ -11,28 +11,11 @@ * external/cwe/cwe-089 */ -import codeql.ruby.AST -import codeql.ruby.Concepts import codeql.ruby.DataFlow -import codeql.ruby.dataflow.BarrierGuards -import codeql.ruby.dataflow.RemoteFlowSources -import codeql.ruby.TaintTracking +import codeql.ruby.security.SqlInjectionQuery import DataFlow::PathGraph -class SqlInjectionConfiguration extends TaintTracking::Configuration { - SqlInjectionConfiguration() { this = "SQLInjectionConfiguration" } - - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - - override predicate isSink(DataFlow::Node sink) { sink instanceof SqlExecution } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof StringConstCompareBarrier or - node instanceof StringConstArrayInclusionCallBarrier - } -} - -from SqlInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "This SQL query depends on a $@.", source.getNode(), "user-provided value" From 9f31ef851fead59ba63a2bf594da622bacf8cd7f Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Thu, 10 Nov 2022 11:52:47 +0000 Subject: [PATCH 107/796] Python: fix spelling of SqlExecution class in comment --- python/ql/lib/semmle/python/Concepts.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/semmle/python/Concepts.qll b/python/ql/lib/semmle/python/Concepts.qll index fe091f84e9c..861e4e7ca81 100644 --- a/python/ql/lib/semmle/python/Concepts.qll +++ b/python/ql/lib/semmle/python/Concepts.qll @@ -311,7 +311,7 @@ module CodeExecution { * Often, it is worthy of an alert if an SQL statement is constructed such that * executing it would be a security risk. * - * If it is important that the SQL statement is indeed executed, then use `SQLExecution`. + * If it is important that the SQL statement is indeed executed, then use `SqlExecution`. * * Extend this class to refine existing API models. If you want to model new APIs, * extend `SqlConstruction::Range` instead. @@ -329,7 +329,7 @@ module SqlConstruction { * Often, it is worthy of an alert if an SQL statement is constructed such that * executing it would be a security risk. * - * If it is important that the SQL statement is indeed executed, then use `SQLExecution`. + * If it is important that the SQL statement is indeed executed, then use `SqlExecution`. * * Extend this class to model new APIs. If you want to refine existing API models, * extend `SqlConstruction` instead. From c9d34947b76d702a9e709cd2232dd799c33e9a92 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Thu, 10 Nov 2022 12:17:56 +0000 Subject: [PATCH 108/796] Ruby: add SqlConstruction concept --- ruby/ql/lib/codeql/ruby/Concepts.qll | 41 +++++++++++++++++++ .../security/SqlInjectionCustomizations.qll | 9 +++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/Concepts.qll b/ruby/ql/lib/codeql/ruby/Concepts.qll index 2d70cc31796..a42fa354660 100644 --- a/ruby/ql/lib/codeql/ruby/Concepts.qll +++ b/ruby/ql/lib/codeql/ruby/Concepts.qll @@ -11,9 +11,47 @@ private import codeql.ruby.Frameworks private import codeql.ruby.dataflow.RemoteFlowSources private import codeql.ruby.ApiGraphs +/** + * A data-flow node that constructs a SQL statement. + * + * Often, it is worthy of an alert if a SQL statement is constructed such that + * executing it would be a security risk. + * + * If it is important that the SQL statement is indeed executed, use `SqlExecution`. + * + * Extend this class to refine existing API models. If you want to model new APIs, + * extend `SqlConstruction::Range` instead. + */ +class SqlConstruction extends DataFlow::Node instanceof SqlConstruction::Range { + /** Gets the argument that specifies the SQL statements to be constructed. */ + DataFlow::Node getSql() { result = super.getSql() } +} + +/** Provides a class for modeling new SQL execution APIs. */ +module SqlConstruction { + /** + * A data-flow node that constructs a SQL statement. + * + * Often, it is worthy of an alert if a SQL statement is constructed such that + * executing it would be a security risk. + * + * If it is important that the SQL statement is indeed executed, use `SqlExecution`. + * + * Extend this class to model new APIs. If you want to refine existing API models, + * extend `SqlConstruction` instead. + */ + abstract class Range extends DataFlow::Node { + /** Gets the argument that specifies the SQL statements to be constructed. */ + abstract DataFlow::Node getSql(); + } +} + /** * A data-flow node that executes SQL statements. * + * If the context of interest is such that merely constructing a SQL statement + * would be valuable to report, consider using `SqlConstruction`. + * * Extend this class to refine existing API models. If you want to model new APIs, * extend `SqlExecution::Range` instead. */ @@ -27,6 +65,9 @@ module SqlExecution { /** * A data-flow node that executes SQL statements. * + * If the context of interest is such that merely constructing a SQL + * statement would be valuable to report, consider using `SqlConstruction`. + * * Extend this class to model new APIs. If you want to refine existing API models, * extend `SqlExecution` instead. */ diff --git a/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll index 68f053109f5..175d0935fad 100644 --- a/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll @@ -25,12 +25,19 @@ module SqlInjection { private class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { } /** - * A SQL statement of a SQL execution, considered as a flow sink. + * An SQL statement of a SQL execution, considered as a flow sink. */ private class SqlExecutionAsSink extends Sink { SqlExecutionAsSink() { this = any(SqlExecution e).getSql() } } + /** + * An SQL statement of a SQL construction, considered as a flow sink. + */ + private class SqlConstructionAsSink extends Sink { + SqlConstructionAsSink() { this = any(SqlConstruction e).getSql() } + } + /** * A comparison with a constant string, considered as a sanitizer-guard. */ From 5a15558355feefe79590df04b259b51eac3a0a26 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Thu, 10 Nov 2022 12:53:58 +0000 Subject: [PATCH 109/796] Ruby: treat an Arel.sql call as a SqlConstruction --- ruby/ql/lib/codeql/ruby/frameworks/Arel.qll | 12 ++++++++++++ .../frameworks/arel/SqlConstruction.expected | 2 ++ .../library-tests/frameworks/arel/SqlConstruction.ql | 4 ++++ .../query-tests/security/cwe-089/ArelInjection.rb | 8 ++++++++ .../security/cwe-089/SqlInjection.expected | 6 ++++++ 5 files changed, 32 insertions(+) create mode 100644 ruby/ql/test/library-tests/frameworks/arel/SqlConstruction.expected create mode 100644 ruby/ql/test/library-tests/frameworks/arel/SqlConstruction.ql create mode 100644 ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Arel.qll b/ruby/ql/lib/codeql/ruby/frameworks/Arel.qll index 9fa17f4e5a5..00f45507cfc 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Arel.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Arel.qll @@ -6,6 +6,8 @@ private import codeql.ruby.ApiGraphs private import codeql.ruby.dataflow.FlowSummary +private import codeql.ruby.Concepts +private import codeql.ruby.DataFlow /** * Provides modeling for Arel, a low level SQL library that powers ActiveRecord. @@ -28,4 +30,14 @@ module Arel { input = "Argument[0]" and output = "ReturnValue" and preservesValue = false } } + + /** A call to `Arel.sql`, considered as a SQL construction. */ + private class ArelSqlConstruction extends SqlConstruction::Range, DataFlow::CallNode { + ArelSqlConstruction() { + this = DataFlow::getConstant("Arel").getAMethodCall() and + this.getMethodName() = "sql" + } + + override DataFlow::Node getSql() { result = this.getArgument(0) } + } } diff --git a/ruby/ql/test/library-tests/frameworks/arel/SqlConstruction.expected b/ruby/ql/test/library-tests/frameworks/arel/SqlConstruction.expected new file mode 100644 index 00000000000..b25b2b387ca --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/arel/SqlConstruction.expected @@ -0,0 +1,2 @@ +| arel.rb:3:8:3:18 | call to sql | arel.rb:3:17:3:17 | x | +| arel.rb:8:8:8:18 | call to sql | arel.rb:8:17:8:17 | x | diff --git a/ruby/ql/test/library-tests/frameworks/arel/SqlConstruction.ql b/ruby/ql/test/library-tests/frameworks/arel/SqlConstruction.ql new file mode 100644 index 00000000000..2b2920918e5 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/arel/SqlConstruction.ql @@ -0,0 +1,4 @@ +import codeql.ruby.Concepts +import codeql.ruby.DataFlow + +query predicate sqlConstructions(SqlConstruction c, DataFlow::Node sql) { sql = c.getSql() } diff --git a/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb b/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb new file mode 100644 index 00000000000..a1efb3adabb --- /dev/null +++ b/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb @@ -0,0 +1,8 @@ + +class PotatoController < ActionController::Base + def unsafe_action + name = params[:user_name] + # BAD: SQL statement constructed from user input + sql = Arel.sql("SELECT * FROM users WHERE name = #{name}") + end +end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected index d78b2675f25..d664bad4293 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected @@ -33,6 +33,8 @@ edges | ActiveRecordInjection.rb:137:21:137:44 | ...[...] : | ActiveRecordInjection.rb:20:22:20:30 | condition : | | ActiveRecordInjection.rb:151:59:151:64 | call to params : | ActiveRecordInjection.rb:151:59:151:74 | ...[...] : | | ActiveRecordInjection.rb:151:59:151:74 | ...[...] : | ActiveRecordInjection.rb:151:27:151:76 | "this is an unsafe annotation:..." | +| ArelInjection.rb:4:12:4:17 | call to params : | ArelInjection.rb:4:12:4:29 | ...[...] : | +| ArelInjection.rb:4:12:4:29 | ...[...] : | ArelInjection.rb:6:20:6:61 | "SELECT * FROM users WHERE nam..." | nodes | ActiveRecordInjection.rb:8:25:8:28 | name : | semmle.label | name : | | ActiveRecordInjection.rb:8:31:8:34 | pass : | semmle.label | pass : | @@ -85,6 +87,9 @@ nodes | ActiveRecordInjection.rb:151:27:151:76 | "this is an unsafe annotation:..." | semmle.label | "this is an unsafe annotation:..." | | ActiveRecordInjection.rb:151:59:151:64 | call to params : | semmle.label | call to params : | | ActiveRecordInjection.rb:151:59:151:74 | ...[...] : | semmle.label | ...[...] : | +| ArelInjection.rb:4:12:4:17 | call to params : | semmle.label | call to params : | +| ArelInjection.rb:4:12:4:29 | ...[...] : | semmle.label | ...[...] : | +| ArelInjection.rb:6:20:6:61 | "SELECT * FROM users WHERE nam..." | semmle.label | "SELECT * FROM users WHERE nam..." | subpaths #select | ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | ActiveRecordInjection.rb:70:23:70:28 | call to params : | ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:70:23:70:28 | call to params | user-provided value | @@ -105,3 +110,4 @@ subpaths | ActiveRecordInjection.rb:92:21:92:35 | ...[...] | ActiveRecordInjection.rb:92:21:92:26 | call to params : | ActiveRecordInjection.rb:92:21:92:35 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:92:21:92:26 | call to params | user-provided value | | ActiveRecordInjection.rb:104:20:104:32 | ... + ... | ActiveRecordInjection.rb:98:10:98:15 | call to params : | ActiveRecordInjection.rb:104:20:104:32 | ... + ... | This SQL query depends on a $@. | ActiveRecordInjection.rb:98:10:98:15 | call to params | user-provided value | | ActiveRecordInjection.rb:151:27:151:76 | "this is an unsafe annotation:..." | ActiveRecordInjection.rb:151:59:151:64 | call to params : | ActiveRecordInjection.rb:151:27:151:76 | "this is an unsafe annotation:..." | This SQL query depends on a $@. | ActiveRecordInjection.rb:151:59:151:64 | call to params | user-provided value | +| ArelInjection.rb:6:20:6:61 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:4:12:4:17 | call to params : | ArelInjection.rb:6:20:6:61 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:4:12:4:17 | call to params | user-provided value | From 0337ccb93a2f6d5304756df20d786a807a028693 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Thu, 10 Nov 2022 13:00:29 +0000 Subject: [PATCH 110/796] Ruby: add change notes for Arel.sql / SqlConstruction changes --- ruby/ql/lib/change-notes/2022-11-10-arel-sql.md | 5 +++++ ruby/ql/src/change-notes/2022-11-10-arel-sql.md | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 ruby/ql/lib/change-notes/2022-11-10-arel-sql.md create mode 100644 ruby/ql/src/change-notes/2022-11-10-arel-sql.md diff --git a/ruby/ql/lib/change-notes/2022-11-10-arel-sql.md b/ruby/ql/lib/change-notes/2022-11-10-arel-sql.md new file mode 100644 index 00000000000..e803d0e0895 --- /dev/null +++ b/ruby/ql/lib/change-notes/2022-11-10-arel-sql.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* The `codeql.ruby.Concepts` library now has a `SqlConstruction` class, in addition to the existing `SqlExecution` class. +* Calls to `Arel.sql` are now modeled as instances of the new `SqlConstruction` concept. diff --git a/ruby/ql/src/change-notes/2022-11-10-arel-sql.md b/ruby/ql/src/change-notes/2022-11-10-arel-sql.md new file mode 100644 index 00000000000..918e46a9d9b --- /dev/null +++ b/ruby/ql/src/change-notes/2022-11-10-arel-sql.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `rb/sql-injection` query now considers consider SQL constructions, such as calls to `Arel.sql`, as sinks. From 511fb9727343d8c46ad2c980a1728ffa460eac4b Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Thu, 10 Nov 2022 14:30:06 +0000 Subject: [PATCH 111/796] Ruby: remove redundant import --- ruby/ql/lib/codeql/ruby/frameworks/Arel.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Arel.qll b/ruby/ql/lib/codeql/ruby/frameworks/Arel.qll index 00f45507cfc..f57fa41c740 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Arel.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Arel.qll @@ -7,7 +7,6 @@ private import codeql.ruby.ApiGraphs private import codeql.ruby.dataflow.FlowSummary private import codeql.ruby.Concepts -private import codeql.ruby.DataFlow /** * Provides modeling for Arel, a low level SQL library that powers ActiveRecord. From 23ff3769aca3646e64ecbe5af45e57a82f31a538 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 31 Oct 2022 18:24:13 +0000 Subject: [PATCH 112/796] Swift: Add Alamofire tests for swift/cleartext-transmission. --- .../Security/CWE-311/SensitiveExprs.expected | 10 + .../Security/CWE-311/testAlamofire.swift | 218 ++++++++++++++++++ 2 files changed, 228 insertions(+) create mode 100644 swift/ql/test/query-tests/Security/CWE-311/testAlamofire.swift diff --git a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected index 9e359b62e27..3c61ec86e95 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected @@ -1,3 +1,13 @@ +| testAlamofire.swift:150:45:150:45 | password | label:password, type:credential | +| testAlamofire.swift:152:51:152:51 | password | label:password, type:credential | +| testAlamofire.swift:154:38:154:38 | email | label:email, type:private information | +| testAlamofire.swift:159:26:159:26 | email | label:email, type:private information | +| testAlamofire.swift:171:35:171:35 | email | label:email, type:private information | +| testAlamofire.swift:177:35:177:35 | email | label:email, type:private information | +| testAlamofire.swift:187:65:187:65 | password | label:password, type:credential | +| testAlamofire.swift:195:64:195:64 | password | label:password, type:credential | +| testAlamofire.swift:205:62:205:62 | password | label:password, type:credential | +| testAlamofire.swift:213:65:213:65 | password | label:password, type:credential | | testCoreData.swift:48:15:48:15 | password | label:password, type:credential | | testCoreData.swift:51:24:51:24 | password | label:password, type:credential | | testCoreData.swift:58:15:58:15 | password | label:password, type:credential | diff --git a/swift/ql/test/query-tests/Security/CWE-311/testAlamofire.swift b/swift/ql/test/query-tests/Security/CWE-311/testAlamofire.swift new file mode 100644 index 00000000000..9056eebdbf1 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-311/testAlamofire.swift @@ -0,0 +1,218 @@ + +// --- Foundation stubs --- + +class NSObject { +} + +struct URL { +} + +struct URLRequest { +} + +class URLResponse: NSObject { +} + +class HTTPURLResponse : URLResponse { +} + +// --- Alamofire stubs --- + +protocol URLConvertible { +} + +extension String: URLConvertible { +} + +struct HTTPMethod { + static let get = HTTPMethod(rawValue: "GET") + static let post = HTTPMethod(rawValue: "POST") + + init(rawValue: String) {} +} + +struct HTTPHeaders { + init(_ dictionary: [String: String]) {} + + mutating func add(name: String, value: String) {} + mutating func update(name: String, value: String) {} +} + +extension HTTPHeaders: ExpressibleByDictionaryLiteral { + public init(dictionaryLiteral elements: (String, String)...) {} +} + +typealias Parameters = [String: Any] + +protocol ParameterEncoding { +} + +struct URLEncoding: ParameterEncoding { + static var `default`: URLEncoding { URLEncoding() } +} + +protocol ParameterEncoder { +} + +class URLEncodedFormParameterEncoder: ParameterEncoder { + static var `default`: URLEncodedFormParameterEncoder { URLEncodedFormParameterEncoder() } +} + +protocol RequestInterceptor { +} + +class Request { +} + +class DataRequest: Request { +} + +final class DataStreamRequest: Request { +} + +class DownloadRequest: Request { + struct Options: OptionSet { + let rawValue: Int + + init(rawValue: Int) { + self.rawValue = rawValue + } + } + + typealias Destination = + (_ temporaryURL: URL, _ response: HTTPURLResponse) -> + (destinationURL: URL, options: Options) +} + +class Session { + static let `default` = Session() + + typealias RequestModifier = (inout URLRequest) throws -> Void + + func request( + _ convertible: URLConvertible, + method: HTTPMethod = .get, + parameters: Parameters? = nil, + encoding: ParameterEncoding = URLEncoding.default, + headers: HTTPHeaders? = nil, + interceptor: RequestInterceptor? = nil, + requestModifier: RequestModifier? = nil) -> DataRequest { + return DataRequest() + } + + func request( + _ convertible: URLConvertible, + method: HTTPMethod = .get, + parameters: Parameters? = nil, + encoder: ParameterEncoder = URLEncodedFormParameterEncoder.default, + headers: HTTPHeaders? = nil, + interceptor: RequestInterceptor? = nil, + requestModifier: RequestModifier? = nil) -> DataRequest { + return DataRequest() + } + + func streamRequest( + _ convertible: URLConvertible, + method: HTTPMethod = .get, + headers: HTTPHeaders? = nil, + automaticallyCancelOnStreamError: Bool = false, + interceptor: RequestInterceptor? = nil, + requestModifier: RequestModifier? = nil) -> DataStreamRequest { + return DataStreamRequest() + } + + func download( + _ convertible: URLConvertible, + method: HTTPMethod = .get, + parameters: Parameters? = nil, + encoding: ParameterEncoding = URLEncoding.default, + headers: HTTPHeaders? = nil, + interceptor: RequestInterceptor? = nil, + requestModifier: RequestModifier? = nil, + to destination: DownloadRequest.Destination? = nil) -> DownloadRequest { + return DownloadRequest() + } + + // (there are many more variants of `request`, `streamRequest` and `download`) +} + +let AF = Session.default + +// --- tests --- + +struct MyEncodable: Encodable { + let value: String +} + +func test1(username: String, password: String, email: String, harmless: String) { + // sensitive data in URL + + AF.request("http://example.com/login?p=" + password) // BAD [NOT DETECTED] + AF.request("http://example.com/login?h=" + harmless) // GOOD (not sensitive) + AF.streamRequest("http://example.com/login?p=" + password) // BAD [NOT DETECTED] + AF.streamRequest("http://example.com/login?h=" + harmless) // GOOD (not sensitive) + AF.download("http://example.com/" + email + ".html") // BAD [NOT DETECTED] + AF.download("http://example.com/" + harmless + ".html") // GOOD (not sensitive) + + // sensitive data in parameters + + let params1 = ["value": email] + let params2 = ["value": harmless] + + AF.request("http://example.com/", parameters: params1) // BAD [NOT DETECTED] + AF.request("http://example.com/", parameters: params2) // GOOD (not sensitive) + AF.request("http://example.com/", parameters: params1, encoding: URLEncoding.default) // BAD [NOT DETECTED] + AF.request("http://example.com/", parameters: params2, encoding: URLEncoding.default) // GOOD (not sensitive) + AF.request("http://example.com/", parameters: params1, encoder: URLEncodedFormParameterEncoder.default) // BAD [NOT DETECTED] + AF.request("http://example.com/", parameters: params2, encoder: URLEncodedFormParameterEncoder.default) // GOOD (not sensitive) + AF.download("http://example.com/", parameters: params1) // BAD [NOT DETECTED] + AF.download("http://example.com/", parameters: params2) // GOOD (not sensitive) + + let params3 = ["values": ["...", email, "..."]] + let params4 = ["values": ["...", harmless, "..."]] + + AF.request("http://example.com/", method:.post, parameters: params3) // BAD [NOT DETECTED] + AF.request("http://example.com/", method:.post, parameters: params4) // GOOD (not sensitive) + + let params5 = MyEncodable(value: email) + let params6 = MyEncodable(value: harmless) + + AF.request("http://example.com/", parameters: params5) // BAD [NOT DETECTED] + AF.request("http://example.com/", parameters: params6) // GOOD (not sensitive) + + // request headers + // - in real usage a password here would normally be base64 encoded for transmission + // - the risk is greatly reduced (but not eliminated) if HTTPS is used + + let headers1: HTTPHeaders = ["Authorization": username + ":" + password] + let headers2: HTTPHeaders = ["Value": harmless] + + AF.request("http://example.com/", headers: headers1) // BAD [NOT DETECTED] + AF.request("http://example.com/", headers: headers2) // GOOD (not sensitive) + AF.streamRequest("http://example.com/", headers: headers1) // BAD [NOT DETECTED] + AF.streamRequest("http://example.com/", headers: headers2) // GOOD (not sensitive) + + let headers3 = HTTPHeaders(["Authorization": username + ":" + password]) + let headers4 = HTTPHeaders(["Value": harmless]) + + AF.request("http://example.com/", headers: headers3) // BAD [NOT DETECTED] + AF.request("http://example.com/", headers: headers4) // GOOD (not sensitive) + AF.download("http://example.com/", headers: headers1) // BAD [NOT DETECTED] + AF.download("http://example.com/", headers: headers2) // GOOD (not sensitive) + + var headers5 = HTTPHeaders([:]) + var headers6 = HTTPHeaders([:]) + headers5.add(name: "Authorization", value: username + ":" + password) + headers6.add(name: "Data", value: harmless) + + AF.request("http://example.com/", headers: headers5) // BAD [NOT DETECTED] + AF.request("http://example.com/", headers: headers6) // GOOD (not sensitive) + + var headers7 = HTTPHeaders([:]) + var headers8 = HTTPHeaders([:]) + headers7.update(name: "Authorization", value: username + ":" + password) + headers8.update(name: "Data", value: harmless) + + AF.request("http://example.com/", headers: headers7) // BAD [NOT DETECTED] + AF.request("http://example.com/", headers: headers8) // GOOD (not sensitive) +} From 012fb28e258f91011d78630dc2384b9e983ee06d Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 10 Nov 2022 15:38:51 +0100 Subject: [PATCH 113/796] only extract .html.erb files instead of all .erb files --- javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java | 2 +- .../extractor/src/com/semmle/js/extractor/FileExtractor.java | 2 +- .../extractor/tests/vue/input/{rails.erb => rails.html.erb} | 0 .../vue/output/trap/{rails.erb.trap => rails.html.erb.trap} | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename javascript/extractor/tests/vue/input/{rails.erb => rails.html.erb} (100%) rename javascript/extractor/tests/vue/output/trap/{rails.erb.trap => rails.html.erb.trap} (100%) diff --git a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java index 9d5a4c3b52b..7f28d93a183 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java +++ b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java @@ -141,7 +141,7 @@ import com.semmle.util.trap.TrapWriter; *
  • All JavaScript files, that is, files with one of the extensions supported by {@link * FileType#JS} (currently ".js", ".jsx", ".mjs", ".cjs", ".es6", ".es"). *
  • All HTML files, that is, files with with one of the extensions supported by {@link - * FileType#HTML} (currently ".htm", ".html", ".xhtm", ".xhtml", ".vue", ".erb"). + * FileType#HTML} (currently ".htm", ".html", ".xhtm", ".xhtml", ".vue", ".html.erb"). *
  • All YAML files, that is, files with one of the extensions supported by {@link * FileType#YAML} (currently ".raml", ".yaml", ".yml"). *
  • Files with base name "package.json" or "tsconfig.json", and files whose base name diff --git a/javascript/extractor/src/com/semmle/js/extractor/FileExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/FileExtractor.java index 77871a95fbe..45bd48bf408 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/FileExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/FileExtractor.java @@ -104,7 +104,7 @@ public class FileExtractor { /** Information about supported file types. */ public static enum FileType { - HTML(".htm", ".html", ".xhtm", ".xhtml", ".vue", ".hbs", ".ejs", ".njk", ".erb") { + HTML(".htm", ".html", ".xhtm", ".xhtml", ".vue", ".hbs", ".ejs", ".njk", ".html.erb") { @Override public IExtractor mkExtractor(ExtractorConfig config, ExtractorState state) { return new HTMLExtractor(config, state); diff --git a/javascript/extractor/tests/vue/input/rails.erb b/javascript/extractor/tests/vue/input/rails.html.erb similarity index 100% rename from javascript/extractor/tests/vue/input/rails.erb rename to javascript/extractor/tests/vue/input/rails.html.erb diff --git a/javascript/extractor/tests/vue/output/trap/rails.erb.trap b/javascript/extractor/tests/vue/output/trap/rails.html.erb.trap similarity index 100% rename from javascript/extractor/tests/vue/output/trap/rails.erb.trap rename to javascript/extractor/tests/vue/output/trap/rails.html.erb.trap From b91b3148a4854bf8a47169f42fce044c027fdcc2 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Thu, 10 Nov 2022 15:26:42 +0000 Subject: [PATCH 114/796] Ruby: add missing qldoc comments for SQL injection query --- .../ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll | 3 +++ ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll | 3 +++ 2 files changed, 6 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll index 175d0935fad..66d3b0d4afd 100644 --- a/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll @@ -13,10 +13,13 @@ private import codeql.ruby.dataflow.RemoteFlowSources * vulnerabilities, as well as extension points for adding your own. */ module SqlInjection { + /** A data flow source for SQL injection vulnerabilities. */ abstract class Source extends DataFlow::Node { } + /** A data flow sink for SQL injection vulnerabilities. */ abstract class Sink extends DataFlow::Node { } + /** A sanitizer for SQL injection vulnerabilities. */ abstract class Sanitizer extends DataFlow::Node { } /** diff --git a/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll index e2dd327ccbd..f74e919ffe5 100644 --- a/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll @@ -7,6 +7,9 @@ private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking import SqlInjectionCustomizations::SqlInjection +/** + * A taint-tracking configuration for detecting SQL injection vulnerabilities. + */ class Configuration extends TaintTracking::Configuration { Configuration() { this = "SqlInjectionConfiguration" } From d97682991df5a8ac0b5b72c654fe5e4ea8cea767 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 1 Nov 2022 15:35:50 +0000 Subject: [PATCH 115/796] Swift: Add Alamofire sink for cpp/cleartext-transmission. --- .../codeql/swift/elements/expr/ApplyExpr.qll | 8 ++++++++ .../Security/CWE-311/CleartextTransmission.ql | 19 +++++++++++++++++++ .../CWE-311/CleartextTransmission.expected | 12 ++++++++++++ .../Security/CWE-311/testAlamofire.swift | 6 +++--- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/swift/ql/lib/codeql/swift/elements/expr/ApplyExpr.qll b/swift/ql/lib/codeql/swift/elements/expr/ApplyExpr.qll index 14bc6302c2b..cf11158df92 100644 --- a/swift/ql/lib/codeql/swift/elements/expr/ApplyExpr.qll +++ b/swift/ql/lib/codeql/swift/elements/expr/ApplyExpr.qll @@ -19,6 +19,14 @@ class ApplyExpr extends Generated::ApplyExpr { /** Gets the method qualifier, if this is applying a method */ Expr getQualifier() { none() } + /** + * Gets the argument of this `ApplyExpr` called `label` (if any). + */ + final Argument getArgumentWithLabel(string label) { + result = getAnArgument() and + result.getLabel() = label + } + override string toString() { result = "call to " + this.getStaticTarget().toString() or diff --git a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql index 92977f5cfd5..21c1c538462 100644 --- a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql +++ b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql @@ -54,6 +54,25 @@ class Url extends Transmitted { } } +/** + * An `Expr` that transmitted through the Alamofire library. + */ +class AlamofireTransmitted extends Transmitted { + AlamofireTransmitted() { + // sinks are the first argument containing the URL, and the `parameters` + // and `headers` arguments to appropriate methods of `Session`. + exists(CallExpr call, string fName | + call.getStaticTarget().(MethodDecl).hasQualifiedName("Session", fName) and + fName.regexpMatch("(request|streamRequest|download)\\(.*") and + ( + call.getArgument(0).getExpr() = this or + call.getArgumentWithLabel("parameters").getExpr() = this or + call.getArgumentWithLabel("headers").getExpr() = this + ) + ) + } +} + /** * A taint configuration from sensitive information to expressions that are * transmitted over a network. 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 de02d0db461..d8328252a1c 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected @@ -1,4 +1,7 @@ edges +| testAlamofire.swift:150:45:150:45 | password : | testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | +| testAlamofire.swift:152:51:152:51 | password : | testAlamofire.swift:152:19:152:51 | ... .+(_:_:) ... | +| testAlamofire.swift:154:38:154:38 | email : | testAlamofire.swift:154:14:154:46 | ... .+(_:_:) ... | | testSend.swift:41:10:41:18 | data : | testSend.swift:41:45:41:45 | data : | | testSend.swift:45:13:45:13 | password : | testSend.swift:52:27:52:27 | str1 | | testSend.swift:46:13:46:13 | password : | testSend.swift:53:27:53:27 | str2 | @@ -8,6 +11,12 @@ edges | testURL.swift:13:54:13:54 | passwd : | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | | testURL.swift:16:55:16:55 | credit_card_no : | testURL.swift:16:22:16:55 | ... .+(_:_:) ... | nodes +| testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | +| testAlamofire.swift:150:45:150:45 | password : | semmle.label | password : | +| testAlamofire.swift:152:19:152:51 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | +| testAlamofire.swift:152:51:152:51 | password : | semmle.label | password : | +| testAlamofire.swift:154:14:154:46 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | +| testAlamofire.swift:154:38:154:38 | email : | semmle.label | email : | | testSend.swift:29:19:29:19 | passwordPlain | semmle.label | passwordPlain | | testSend.swift:41:10:41:18 | data : | semmle.label | data : | | testSend.swift:41:45:41:45 | data : | semmle.label | data : | @@ -26,6 +35,9 @@ nodes subpaths | testSend.swift:47:17:47:17 | password : | testSend.swift:41:10:41:18 | data : | testSend.swift:41:45:41:45 | data : | testSend.swift:47:13:47:25 | call to pad(_:) : | #select +| testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | testAlamofire.swift:150:45:150:45 | password : | testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testAlamofire.swift:150:45:150:45 | password : | password | +| testAlamofire.swift:152:19:152:51 | ... .+(_:_:) ... | testAlamofire.swift:152:51:152:51 | password : | testAlamofire.swift:152:19:152:51 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testAlamofire.swift:152:51:152:51 | password : | password | +| testAlamofire.swift:154:14:154:46 | ... .+(_:_:) ... | testAlamofire.swift:154:38:154:38 | email : | testAlamofire.swift:154:14:154:46 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testAlamofire.swift:154:38:154:38 | email : | email | | testSend.swift:29:19:29:19 | passwordPlain | testSend.swift:29:19:29:19 | passwordPlain | testSend.swift:29:19:29:19 | passwordPlain | This operation transmits 'passwordPlain', which may contain unencrypted sensitive data from $@. | testSend.swift:29:19:29:19 | passwordPlain | passwordPlain | | testSend.swift:52:27:52:27 | str1 | testSend.swift:45:13:45:13 | password : | testSend.swift:52:27:52:27 | str1 | This operation transmits 'str1', which may contain unencrypted sensitive data from $@. | testSend.swift:45:13:45:13 | password : | password | | testSend.swift:53:27:53:27 | str2 | testSend.swift:46:13:46:13 | password : | testSend.swift:53:27:53:27 | str2 | This operation transmits 'str2', which may contain unencrypted sensitive data from $@. | testSend.swift:46:13:46:13 | password : | password | diff --git a/swift/ql/test/query-tests/Security/CWE-311/testAlamofire.swift b/swift/ql/test/query-tests/Security/CWE-311/testAlamofire.swift index 9056eebdbf1..3a50c2cf249 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/testAlamofire.swift +++ b/swift/ql/test/query-tests/Security/CWE-311/testAlamofire.swift @@ -147,11 +147,11 @@ struct MyEncodable: Encodable { func test1(username: String, password: String, email: String, harmless: String) { // sensitive data in URL - AF.request("http://example.com/login?p=" + password) // BAD [NOT DETECTED] + AF.request("http://example.com/login?p=" + password) // BAD AF.request("http://example.com/login?h=" + harmless) // GOOD (not sensitive) - AF.streamRequest("http://example.com/login?p=" + password) // BAD [NOT DETECTED] + AF.streamRequest("http://example.com/login?p=" + password) // BAD AF.streamRequest("http://example.com/login?h=" + harmless) // GOOD (not sensitive) - AF.download("http://example.com/" + email + ".html") // BAD [NOT DETECTED] + AF.download("http://example.com/" + email + ".html") // BAD AF.download("http://example.com/" + harmless + ".html") // GOOD (not sensitive) // sensitive data in parameters From 887d1893e755c38c1f834b5e45126b707fb1c3e6 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 10 Nov 2022 15:51:02 +0000 Subject: [PATCH 116/796] Swift: Make ql-for-ql happy. --- swift/ql/lib/codeql/swift/elements/expr/ApplyExpr.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/elements/expr/ApplyExpr.qll b/swift/ql/lib/codeql/swift/elements/expr/ApplyExpr.qll index cf11158df92..5c82dc32afa 100644 --- a/swift/ql/lib/codeql/swift/elements/expr/ApplyExpr.qll +++ b/swift/ql/lib/codeql/swift/elements/expr/ApplyExpr.qll @@ -23,7 +23,7 @@ class ApplyExpr extends Generated::ApplyExpr { * Gets the argument of this `ApplyExpr` called `label` (if any). */ final Argument getArgumentWithLabel(string label) { - result = getAnArgument() and + result = this.getAnArgument() and result.getLabel() = label } From 4caaa3a396c65f75a3268d5e1405dbfe7bf9f0cf Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Fri, 24 Jun 2022 16:00:40 +0200 Subject: [PATCH 117/796] Python: Rewrite call-graph tests to be inline expectation (1/2) This adds inline expectations, next commit will remove old annotations code... but I thought it would be easier to review like this. --- .../CallGraph/InlineCallGraphTest.expected | 4 ++ .../CallGraph/InlineCallGraphTest.ql | 49 +++++++++++++++++++ .../CallGraph/code/class_simple.py | 10 ++-- .../CallGraph/code/runtime_decision.py | 4 +- .../library-tests/CallGraph/code/simple.py | 8 +-- .../code/underscore_prefix_func_name.py | 6 +-- 6 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected create mode 100644 python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.ql diff --git a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected new file mode 100644 index 00000000000..2ff4aeb6865 --- /dev/null +++ b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected @@ -0,0 +1,4 @@ +failures +debug_callableNotUnique +| code/class_advanced.py:18:5:18:18 | Function arg | Qualified function name 'B.arg' is not unique. Please fix. | +| code/class_advanced.py:23:5:23:25 | Function arg | Qualified function name 'B.arg' is not unique. Please fix. | diff --git a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.ql b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.ql new file mode 100644 index 00000000000..6b59751e43b --- /dev/null +++ b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.ql @@ -0,0 +1,49 @@ +import python +import TestUtilities.InlineExpectationsTest + +/** Holds when `call` is resolved to `callable` using points-to based call-graph. */ +predicate pointsToCallEdge(CallNode call, Function callable) { + exists(PythonFunctionValue funcValue | + funcValue.getScope() = callable and + call = funcValue.getACall() + ) +} + +/** Holds when `call` is resolved to `callable` using type-tracking based call-graph. */ +predicate typeTrackerCallEdge(CallNode call, Function callable) { none() } + +class CallGraphTest extends InlineExpectationsTest { + CallGraphTest() { this = "CallGraphTest" } + + override string getARelevantTag() { result in ["pt", "tt"] } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + exists(location.getFile().getRelativePath()) and + exists(CallNode call, Function target | + tag = "tt" and + typeTrackerCallEdge(call, target) + or + tag = "pt" and + pointsToCallEdge(call, target) + | + location = call.getLocation() and + element = call.toString() and + ( + // note: `target.getQualifiedName` for Lambdas is just "lambda", so is not very useful :| + not target.isLambda() and + value = target.getQualifiedName() + or + target.isLambda() and + value = + "lambda[" + target.getLocation().getFile().getShortName() + ":" + + target.getLocation().getStartLine() + ":" + target.getLocation().getStartColumn() + "]" + ) + ) + } +} + +query predicate debug_callableNotUnique(Function callable, string message) { + exists(Function f | f != callable and f.getQualifiedName() = callable.getQualifiedName()) and + message = + "Qualified function name '" + callable.getQualifiedName() + "' is not unique. Please fix." +} diff --git a/python/ql/test/experimental/library-tests/CallGraph/code/class_simple.py b/python/ql/test/experimental/library-tests/CallGraph/code/class_simple.py index 7309620b3ec..a679cc5e25c 100644 --- a/python/ql/test/experimental/library-tests/CallGraph/code/class_simple.py +++ b/python/ql/test/experimental/library-tests/CallGraph/code/class_simple.py @@ -25,13 +25,13 @@ class A(object): a = A(42) # calls:A.some_method -a.some_method() +a.some_method() # $ pt=A.some_method # calls:A.some_staticmethod -a.some_staticmethod() +a.some_staticmethod() # $ pt=A.some_staticmethod # calls:A.some_classmethod -a.some_classmethod() +a.some_classmethod() # $ pt=A.some_classmethod # calls:A.some_staticmethod -A.some_staticmethod() +A.some_staticmethod() # $ pt=A.some_staticmethod # calls:A.some_classmethod -A.some_classmethod() +A.some_classmethod() # $ pt=A.some_classmethod diff --git a/python/ql/test/experimental/library-tests/CallGraph/code/runtime_decision.py b/python/ql/test/experimental/library-tests/CallGraph/code/runtime_decision.py index fd2f7773ced..a271cbd9a6f 100644 --- a/python/ql/test/experimental/library-tests/CallGraph/code/runtime_decision.py +++ b/python/ql/test/experimental/library-tests/CallGraph/code/runtime_decision.py @@ -18,7 +18,7 @@ else: func = rd_bar # calls:rd_foo calls:rd_bar -func() +func() # $ pt=rd_foo pt=rd_bar # Random doesn't work with points-to :O if random.random() < 0.5: @@ -27,4 +27,4 @@ else: func2 = rd_bar # calls:rd_foo calls:rd_bar -func2() +func2() # $ pt=rd_foo pt=rd_bar diff --git a/python/ql/test/experimental/library-tests/CallGraph/code/simple.py b/python/ql/test/experimental/library-tests/CallGraph/code/simple.py index d3c39e42fd5..210df4f209e 100644 --- a/python/ql/test/experimental/library-tests/CallGraph/code/simple.py +++ b/python/ql/test/experimental/library-tests/CallGraph/code/simple.py @@ -16,12 +16,12 @@ lam = lambda: print("lambda called") # calls:foo -foo() +foo() # $ pt=foo # calls:foo -indirect_foo() +indirect_foo() # $ pt=foo # calls:bar -bar() +bar() # $ pt=bar # calls:lam -lam() +lam() # $ pt=lambda[simple.py:15:7] # python -m trace --trackcalls simple.py diff --git a/python/ql/test/experimental/library-tests/CallGraph/code/underscore_prefix_func_name.py b/python/ql/test/experimental/library-tests/CallGraph/code/underscore_prefix_func_name.py index 1ec87efd757..1a1efe9d7b6 100644 --- a/python/ql/test/experimental/library-tests/CallGraph/code/underscore_prefix_func_name.py +++ b/python/ql/test/experimental/library-tests/CallGraph/code/underscore_prefix_func_name.py @@ -18,11 +18,11 @@ def _ignored(): def _works_since_called(): print('_works_since_called') # calls:some_function - some_function() + some_function() # $ pt=some_function def works_even_though_not_called(): # calls:some_function - some_function() + some_function() # $ pt=some_function globals()['_ignored']() -_works_since_called() +_works_since_called() # $ pt=_works_since_called From d0dfb4926bce116f96320eb4aa53134fa85e010e Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Wed, 9 Nov 2022 16:09:47 +0000 Subject: [PATCH 118/796] Kotlin/Java: Add compilation_info table --- java/ql/lib/config/semmlecode.dbscheme | 6 ++++++ java/ql/lib/semmle/code/java/Compilation.qll | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/java/ql/lib/config/semmlecode.dbscheme b/java/ql/lib/config/semmlecode.dbscheme index 709f1d1fd04..44d61b266be 100644 --- a/java/ql/lib/config/semmlecode.dbscheme +++ b/java/ql/lib/config/semmlecode.dbscheme @@ -31,6 +31,12 @@ compilation_started( int id : @compilation ref ) +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + /** * The arguments that were passed to the extractor for a compiler * invocation. If `id` is for the compiler invocation diff --git a/java/ql/lib/semmle/code/java/Compilation.qll b/java/ql/lib/semmle/code/java/Compilation.qll index f38dc8ddb6b..c4b846edade 100644 --- a/java/ql/lib/semmle/code/java/Compilation.qll +++ b/java/ql/lib/semmle/code/java/Compilation.qll @@ -143,4 +143,9 @@ class Compilation extends @compilation { * Holds if the extractor encountered non-recoverable errors. */ predicate nonRecoverableErrors() { compilation_finished(this, _, _, 2) } + + /** + * Gets the piece of compilation information with the given key, if any. + */ + string getInfo(string key) { compilation_info(this, key, result) } } From 2fb78565a723fa78cefd3544062d48492e6ca5bd Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Wed, 9 Nov 2022 17:05:49 +0000 Subject: [PATCH 119/796] Kotlin: Write version information to the database --- java/kotlin-extractor/build.py | 4 ++++ .../src/main/kotlin/KotlinExtractorExtension.kt | 2 ++ 2 files changed, 6 insertions(+) diff --git a/java/kotlin-extractor/build.py b/java/kotlin-extractor/build.py index 9525522869b..497e6da049e 100755 --- a/java/kotlin-extractor/build.py +++ b/java/kotlin-extractor/build.py @@ -185,6 +185,10 @@ def compile(jars, java_jars, dependency_folder, transform_to_embeddable, output, include_version_folder = tmp_src_dir + '/main/kotlin/utils/versions/to_include' os.makedirs(include_version_folder) + with open(tmp_src_dir + '/main/kotlin/utils/ExtractorName.kt', 'w') as f: + f.write('package com.github.codeql\n') + f.write('val extractor_name: String = "' + output + '"\n') + parsed_current_version = kotlin_plugin_versions.version_string_to_tuple( current_version) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt b/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt index c11d8569ae4..2ffef600476 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt @@ -131,6 +131,8 @@ class KotlinExtractorExtension( // The interceptor has already defined #compilation = * val compilation: Label = StringLabel("compilation") tw.writeCompilation_started(compilation) + tw.writeCompilation_info(compilation, "Kotlin Compiler Version", KotlinCompilerVersion.getVersion() ?: "") + tw.writeCompilation_info(compilation, "Kotlin Extractor Name", extractor_name) if (compilationStartTime != null) { tw.writeCompilation_compiler_times(compilation, -1.0, (System.currentTimeMillis()-compilationStartTime)/1000.0) } From a6b8f4b674a6215ebddec9bfdef7316dfeabe9f2 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Thu, 10 Nov 2022 11:13:13 +0000 Subject: [PATCH 120/796] Java/Kotlin: Update stats --- java/ql/lib/config/semmlecode.dbscheme.stats | 8805 +++++++++--------- 1 file changed, 4613 insertions(+), 4192 deletions(-) diff --git a/java/ql/lib/config/semmlecode.dbscheme.stats b/java/ql/lib/config/semmlecode.dbscheme.stats index 21f4ae2aa28..7ebc6e0b93e 100644 --- a/java/ql/lib/config/semmlecode.dbscheme.stats +++ b/java/ql/lib/config/semmlecode.dbscheme.stats @@ -6,11 +6,11 @@ @kotlincompilation - 6806 + 7683 @diagnostic - 631661 + 61632 @externalDataElement @@ -26,27 +26,27 @@ @file - 7997871 + 9158642 @folder - 1275575 + 1415670 @location_default - 430051334 + 602747369 @package - 611241 - - - @modifier - 13613 + 580098 @primitive - 12252 + 17287 + + + @modifier + 26891 @errortype @@ -54,87 +54,87 @@ @class - 12548830 + 12618104 @kt_nullable_type - 1361 + 1920 @kt_notnull_type - 191419 + 172391 @kt_type_alias - 2060 + 1821 @interface - 21501109 + 23200100 @fielddecl - 398872 + 199475 @field - 27509955 + 19350704 @constructor - 6869320 + 8006128 @method - 93308954 + 109719302 @param - 101015498 + 120852585 @exception - 1228169 + 1232644 @typevariable - 5105024 + 6288883 @wildcard - 3629331 + 3338447 @typebound - 4383514 + 4229725 @array - 1116298 + 1375332 @import - 368532 + 368550 @block - 845392 + 756817 @ifstmt - 188296 + 188285 @forstmt - 52508 + 52504 @enhancedforstmt - 18506 + 18520 @whilestmt - 21684 + 13266 @dostmt @@ -142,7 +142,7 @@ @trystmt - 58627 + 58624 @switchstmt @@ -150,19 +150,19 @@ @synchronizedstmt - 18703 + 18206 @returnstmt - 674863 + 532846 @throwstmt - 35919 + 35917 @breakstmt - 35331 + 35329 @continuestmt @@ -170,23 +170,23 @@ @emptystmt - 1562 + 1561 @exprstmt - 942161 + 942102 @assertstmt - 10816 + 10815 @localvariabledeclstmt - 318709 + 318689 @localtypedeclstmt - 4057 + 3841 @constructorinvocationstmt @@ -194,19 +194,19 @@ @superconstructorinvocationstmt - 223641 + 201354 @case - 107943 + 107945 @catchclause - 55205 + 55201 @labeledstmt - 2560 + 2342 @yieldstmt @@ -218,27 +218,27 @@ @whenbranch - 234276 + 225101 @arrayaccess - 409706 + 409681 @arraycreationexpr - 69251 + 69247 @arrayinit - 405408 + 405405 @assignexpr - 465437 + 465407 @assignaddexpr - 17017 + 17016 @assignsubexpr @@ -258,63 +258,63 @@ @assignorexpr - 14529 + 14528 @booleanliteral - 589884 + 589912 @integerliteral - 1151527 + 1151458 @longliteral - 185903 + 185904 @floatingpointliteral - 2825166 + 2824996 @doubleliteral - 486650 + 486619 @characterliteral - 40018 + 40016 @stringliteral - 1262892 + 1262818 @nullliteral - 355828 + 434113 @mulexpr - 204593 + 204580 @divexpr - 36267 + 36264 @remexpr - 3896 + 3904 @addexpr - 176997 + 176986 @subexpr - 84390 + 84385 @lshiftexpr - 8737 + 8736 @rshiftexpr @@ -326,11 +326,11 @@ @andbitexpr - 29091 + 110212 @orbitexpr - 8626 + 12590 @xorbitexpr @@ -338,47 +338,47 @@ @andlogicalexpr - 41339 + 36742 @orlogicalexpr - 31152 + 31150 @ltexpr - 66254 + 66249 @gtexpr - 17204 + 17203 @leexpr - 10530 + 10529 @geexpr - 13412 + 13411 @eqexpr - 104281 + 128429 @neexpr - 60978 + 60975 @postincexpr - 29634 + 29632 @postdecexpr - 11684 + 11683 @preincexpr - 23716 + 23714 @predecexpr @@ -386,75 +386,75 @@ @minusexpr - 744431 + 744386 @plusexpr - 53010 + 53007 @bitnotexpr - 8187 + 8186 @lognotexpr - 40113 + 40111 @castexpr - 93193 + 93187 @newexpr - 252099 + 252083 @conditionalexpr - 16048 + 16047 @instanceofexpr - 31040 + 29542 @localvariabledeclexpr - 385297 + 385272 @typeliteral - 148289 + 144350 @thisaccess - 949960 + 756915 @superaccess - 22195 + 99884 @varaccess - 2434432 + 2434277 @methodaccess - 1578817 + 1512385 @unannotatedtypeaccess - 2861937 + 2608638 @arraytypeaccess - 120735 + 120727 @wildcardtypeaccess - 63960 + 64091 @declannotation - 6745248 + 6740832 @assignremexpr @@ -462,7 +462,7 @@ @assignxorexpr - 1101 + 1102 @assignlshiftexpr @@ -490,19 +490,19 @@ @lambdaexpr - 183936 + 167982 @memberref - 23858 + 23859 @annotatedtypeaccess - 1280 + 1281 @typeannotation - 1280 + 1281 @intersectiontypeaccess @@ -518,43 +518,43 @@ @whenexpr - 172064 + 152111 @getclassexpr - 1361 + 1920 @safecastexpr - 6932 + 6402 @implicitcastexpr - 32918 + 30316 @implicitnotnullexpr - 241262 + 216630 @implicitcoerciontounitexpr - 91329 + 81396 @notinstanceofexpr - 19576 + 17306 @stmtexpr - 57687 + 55704 @stringtemplateexpr - 55814 + 59546 @notnullexpr - 20290 + 18820 @unsafecoerceexpr @@ -562,23 +562,23 @@ @valueeqexpr - 102712 + 93060 @valueneexpr - 108184 + 95639 @propertyref - 9642 + 8878 @localvar - 385297 + 385272 @module - 7964 + 7965 @requires @@ -586,7 +586,7 @@ @exports - 35011 + 35013 @opens @@ -594,7 +594,7 @@ @uses - 10785 + 10786 @provides @@ -602,15 +602,15 @@ @javadoc - 985153 + 985091 @javadocTag - 335830 + 335808 @javadocText - 2503007 + 2502848 @xmldtd @@ -618,23 +618,23 @@ @xmlelement - 106507143 + 150282022 @xmlattribute - 129551904 + 182798274 @xmlnamespace - 8168 + 11525 @xmlcomment - 107198704 + 151257816 @xmlcharacters - 101302741 + 142938589 @config @@ -650,15 +650,15 @@ @ktcomment - 133411 + 188243 @ktcommentsection - 59896 + 52611 @kt_property - 30236718 + 21895839 @@ -880,30 +880,146 @@ compilation_started - 6806 + 7683 id - 6806 + 7683 - compilation_args - 157915 + compilation_info + 15366 id - 6806 + 7683 + + + info_key + 3841 + + + info_value + 3841 + + + + + id + info_key + + + 12 + + + 2 + 3 + 7683 + + + + + + + id + info_value + + + 12 + + + 2 + 3 + 7683 + + + + + + + info_key + id + + + 12 + + + 4 + 5 + 3841 + + + + + + + info_key + info_value + + + 12 + + + 1 + 2 + 3841 + + + + + + + info_value + id + + + 12 + + + 4 + 5 + 3841 + + + + + + + info_value + info_key + + + 12 + + + 1 + 2 + 3841 + + + + + + + + + compilation_args + 169035 + + + id + 7683 num - 38117 + 48021 arg - 89848 + 90280 @@ -917,22 +1033,17 @@ 20 21 - 2722 + 3841 23 24 - 1361 + 1920 25 26 - 1361 - - - 28 - 29 - 1361 + 1920 @@ -948,22 +1059,17 @@ 20 21 - 2722 + 3841 23 24 - 1361 + 1920 25 26 - 1361 - - - 27 - 28 - 1361 + 1920 @@ -979,22 +1085,17 @@ 1 2 - 4084 + 3841 2 3 - 2722 + 5762 - 3 - 4 - 4084 - - - 5 - 6 - 27226 + 4 + 5 + 38417 @@ -1010,27 +1111,22 @@ 1 2 - 8168 + 9604 2 3 - 5445 + 17287 3 4 - 10890 + 11525 4 5 - 6806 - - - 5 - 6 - 6806 + 9604 @@ -1046,22 +1142,17 @@ 1 2 - 69428 + 61467 2 3 - 2722 + 3841 4 5 - 6806 - - - 5 - 6 - 10890 + 24971 @@ -1077,17 +1168,17 @@ 1 2 - 72151 + 67229 2 3 - 14974 + 19208 - 4 - 5 - 2722 + 3 + 4 + 3841 @@ -1097,19 +1188,19 @@ compilation_compiling_files - 61119 + 59495 id - 2337 + 2275 num - 18035 + 17556 file - 51099 + 49742 @@ -1123,22 +1214,22 @@ 1 2 - 333 + 325 2 3 - 667 + 650 35 36 - 667 + 650 54 55 - 667 + 650 @@ -1154,22 +1245,22 @@ 1 2 - 333 + 325 2 3 - 667 + 650 35 36 - 667 + 650 54 55 - 667 + 650 @@ -1185,17 +1276,17 @@ 2 3 - 6345 + 6177 4 5 - 11021 + 10728 6 8 - 667 + 650 @@ -1211,17 +1302,17 @@ 2 3 - 6345 + 6177 3 4 - 10019 + 9753 4 8 - 1669 + 1625 @@ -1237,12 +1328,12 @@ 1 2 - 41080 + 39989 2 3 - 10019 + 9753 @@ -1258,7 +1349,7 @@ 1 2 - 51099 + 49742 @@ -1268,19 +1359,19 @@ compilation_compiling_files_completed - 61119 + 59495 id - 2337 + 2275 num - 18035 + 17556 result - 667 + 325 @@ -1294,22 +1385,22 @@ 1 2 - 333 + 325 2 3 - 667 + 650 35 36 - 667 + 650 54 55 - 667 + 650 @@ -1325,12 +1416,7 @@ 1 2 - 1669 - - - 2 - 3 - 667 + 2275 @@ -1346,17 +1432,17 @@ 2 3 - 6345 + 6177 4 5 - 11021 + 10728 6 8 - 667 + 650 @@ -1372,12 +1458,7 @@ 1 2 - 17701 - - - 2 - 3 - 333 + 17556 @@ -1390,15 +1471,10 @@ 12 - - 2 - 3 - 333 - 7 8 - 333 + 325 @@ -1411,15 +1487,10 @@ 12 - - 1 - 2 - 333 - 54 55 - 333 + 325 @@ -1429,7 +1500,7 @@ compilation_time - 196462 + 196471 id @@ -1437,7 +1508,7 @@ num - 5143 + 5144 kind @@ -1445,7 +1516,7 @@ seconds - 89768 + 89772 @@ -1658,7 +1729,7 @@ 4 5 - 5143 + 5144 @@ -1793,7 +1864,7 @@ 1 2 - 89602 + 89606 52 @@ -1814,7 +1885,7 @@ 1 2 - 89602 + 89606 31 @@ -1835,7 +1906,7 @@ 1 2 - 89602 + 89606 3 @@ -1850,23 +1921,23 @@ diagnostic_for - 631661 + 61632 diagnostic - 631661 + 61632 compilation - 6806 + 574 file_number - 8168 + 14797 file_number_diagnostic_number - 59898 + 2154 @@ -1880,7 +1951,7 @@ 1 2 - 631661 + 61632 @@ -1896,7 +1967,7 @@ 1 2 - 631661 + 61632 @@ -1912,7 +1983,7 @@ 1 2 - 631661 + 61632 @@ -1926,24 +1997,24 @@ 12 - 73 - 74 - 1361 + 14 + 15 + 143 - 84 - 85 - 1361 + 28 + 29 + 143 - 100 - 101 - 2722 + 123 + 124 + 143 - 107 - 108 - 1361 + 264 + 265 + 143 @@ -1957,24 +2028,24 @@ 12 - 3 - 4 - 2722 + 7 + 8 + 143 - 4 - 5 - 1361 + 14 + 15 + 143 - 5 - 6 - 1361 + 45 + 46 + 143 - 6 - 7 - 1361 + 103 + 104 + 143 @@ -1988,29 +2059,19 @@ 12 - 29 - 30 - 1361 + 2 + 3 + 287 - 34 - 35 - 1361 + 14 + 15 + 143 - 40 - 41 - 1361 - - - 42 - 43 - 1361 - - - 44 - 45 - 1361 + 15 + 16 + 143 @@ -2019,47 +2080,6 @@ file_number diagnostic - - - 12 - - - 6 - 7 - 1361 - - - 35 - 36 - 1361 - - - 49 - 50 - 1361 - - - 101 - 102 - 1361 - - - 129 - 130 - 1361 - - - 144 - 145 - 1361 - - - - - - - file_number - compilation 12 @@ -2067,22 +2087,73 @@ 1 2 - 1361 + 143 2 3 - 1361 + 6464 3 4 - 1361 + 718 + + + 4 + 5 + 3160 5 6 - 4084 + 1292 + + + 6 + 8 + 1149 + + + 8 + 11 + 1292 + + + 12 + 21 + 574 + + + + + + + file_number + compilation + + + 12 + + + 1 + 2 + 8332 + + + 2 + 3 + 4453 + + + 3 + 4 + 1005 + + + 4 + 5 + 1005 @@ -2096,34 +2167,34 @@ 12 - 6 - 7 - 1361 + 1 + 2 + 143 - 15 + 2 + 3 + 10056 + + + 3 + 4 + 2011 + + + 4 + 5 + 1005 + + + 5 + 8 + 1149 + + + 10 16 - 1361 - - - 34 - 35 - 1361 - - - 40 - 41 - 1361 - - - 42 - 43 - 1361 - - - 44 - 45 - 1361 + 430 @@ -2138,58 +2209,53 @@ 1 - 3 - 5445 + 2 + 143 - 4 - 5 - 6806 + 2 + 3 + 574 + + + 3 + 4 + 430 5 6 - 1361 + 143 7 8 - 6806 + 143 - 8 - 9 - 4084 - - - 9 - 10 - 9529 - - - 10 - 14 - 5445 - - - 15 - 16 - 2722 - - - 16 - 17 - 8168 + 11 + 12 + 143 18 - 20 - 4084 + 19 + 143 - 20 - 22 - 5445 + 33 + 34 + 143 + + + 168 + 169 + 143 + + + 169 + 170 + 143 @@ -2204,23 +2270,18 @@ 1 - 3 - 5445 + 2 + 143 - 3 - 4 - 8168 + 2 + 3 + 1723 4 5 - 6806 - - - 5 - 6 - 39478 + 287 @@ -2235,28 +2296,53 @@ 1 + 2 + 143 + + + 2 3 - 5445 + 574 3 4 - 8168 - - - 4 - 5 - 25865 + 430 5 6 - 12252 + 143 - 6 - 7 - 8168 + 7 + 8 + 143 + + + 11 + 12 + 143 + + + 18 + 19 + 143 + + + 32 + 33 + 143 + + + 102 + 103 + 143 + + + 103 + 104 + 143 @@ -2266,19 +2352,19 @@ compilation_compiler_times - 6806 + 7683 id - 6806 + 7683 cpu_seconds - 1361 + 1920 elapsed_seconds - 6806 + 7683 @@ -2292,7 +2378,7 @@ 1 2 - 6806 + 7683 @@ -2308,7 +2394,7 @@ 1 2 - 6806 + 7683 @@ -2322,9 +2408,9 @@ 12 - 5 - 6 - 1361 + 4 + 5 + 1920 @@ -2338,9 +2424,9 @@ 12 - 5 - 6 - 1361 + 4 + 5 + 1920 @@ -2356,7 +2442,7 @@ 1 2 - 6806 + 7683 @@ -2372,7 +2458,7 @@ 1 2 - 6806 + 7683 @@ -2598,35 +2684,35 @@ diagnostics - 631661 + 61632 id - 631661 + 61632 generated_by - 1361 + 143 severity - 1361 + 143 error_tag - 1361 + 143 error_message - 96655 + 1580 full_error_message - 520031 + 40944 location - 1361 + 143 @@ -2640,7 +2726,7 @@ 1 2 - 631661 + 61632 @@ -2656,7 +2742,7 @@ 1 2 - 631661 + 61632 @@ -2672,7 +2758,7 @@ 1 2 - 631661 + 61632 @@ -2688,7 +2774,7 @@ 1 2 - 631661 + 61632 @@ -2704,7 +2790,7 @@ 1 2 - 631661 + 61632 @@ -2720,7 +2806,7 @@ 1 2 - 631661 + 61632 @@ -2734,9 +2820,9 @@ 12 - 464 - 465 - 1361 + 429 + 430 + 143 @@ -2752,7 +2838,7 @@ 1 2 - 1361 + 143 @@ -2768,7 +2854,7 @@ 1 2 - 1361 + 143 @@ -2782,9 +2868,9 @@ 12 - 71 - 72 - 1361 + 11 + 12 + 143 @@ -2798,9 +2884,9 @@ 12 - 382 - 383 - 1361 + 285 + 286 + 143 @@ -2816,7 +2902,7 @@ 1 2 - 1361 + 143 @@ -2830,9 +2916,9 @@ 12 - 464 - 465 - 1361 + 429 + 430 + 143 @@ -2848,7 +2934,7 @@ 1 2 - 1361 + 143 @@ -2864,7 +2950,7 @@ 1 2 - 1361 + 143 @@ -2878,9 +2964,9 @@ 12 - 71 - 72 - 1361 + 11 + 12 + 143 @@ -2894,9 +2980,9 @@ 12 - 382 - 383 - 1361 + 285 + 286 + 143 @@ -2912,7 +2998,7 @@ 1 2 - 1361 + 143 @@ -2926,9 +3012,9 @@ 12 - 464 - 465 - 1361 + 429 + 430 + 143 @@ -2944,7 +3030,7 @@ 1 2 - 1361 + 143 @@ -2960,7 +3046,7 @@ 1 2 - 1361 + 143 @@ -2974,9 +3060,9 @@ 12 - 71 - 72 - 1361 + 11 + 12 + 143 @@ -2990,9 +3076,9 @@ 12 - 382 - 383 - 1361 + 285 + 286 + 143 @@ -3008,7 +3094,7 @@ 1 2 - 1361 + 143 @@ -3024,62 +3110,47 @@ 1 2 - 19058 + 143 2 3 - 5445 + 143 3 4 - 12252 - - - 4 - 5 - 5445 - - - 5 - 6 - 5445 + 143 6 7 - 8168 - - - 7 - 8 - 2722 - - - 8 - 9 - 9529 + 143 9 10 - 6806 + 143 - 10 - 11 - 8168 + 12 + 13 + 287 - 14 - 17 - 6806 + 24 + 25 + 143 - 17 - 21 - 6806 + 28 + 29 + 143 + + + 166 + 167 + 287 @@ -3095,7 +3166,7 @@ 1 2 - 96655 + 1580 @@ -3111,7 +3182,7 @@ 1 2 - 96655 + 1580 @@ -3127,7 +3198,7 @@ 1 2 - 96655 + 1580 @@ -3143,57 +3214,52 @@ 1 2 - 21781 + 143 2 3 - 5445 + 143 3 4 - 12252 - - - 4 - 5 - 5445 - - - 5 - 6 - 4084 + 143 6 7 - 8168 - - - 7 - 8 - 12252 - - - 8 - 9 - 6806 + 143 9 - 11 - 8168 - - - 11 - 12 - 6806 + 10 + 143 12 - 14 - 5445 + 13 + 287 + + + 22 + 23 + 143 + + + 24 + 25 + 143 + + + 28 + 29 + 143 + + + 166 + 167 + 143 @@ -3209,7 +3275,7 @@ 1 2 - 96655 + 1580 @@ -3225,17 +3291,12 @@ 1 2 - 441074 + 38358 2 - 3 - 51730 - - - 3 - 5 - 27226 + 25 + 2585 @@ -3251,7 +3312,7 @@ 1 2 - 520031 + 40944 @@ -3267,7 +3328,7 @@ 1 2 - 520031 + 40944 @@ -3283,7 +3344,7 @@ 1 2 - 520031 + 40944 @@ -3299,7 +3360,7 @@ 1 2 - 520031 + 40944 @@ -3315,7 +3376,7 @@ 1 2 - 520031 + 40944 @@ -3329,9 +3390,9 @@ 12 - 464 - 465 - 1361 + 429 + 430 + 143 @@ -3347,7 +3408,7 @@ 1 2 - 1361 + 143 @@ -3363,7 +3424,7 @@ 1 2 - 1361 + 143 @@ -3379,7 +3440,7 @@ 1 2 - 1361 + 143 @@ -3393,9 +3454,9 @@ 12 - 71 - 72 - 1361 + 11 + 12 + 143 @@ -3409,9 +3470,9 @@ 12 - 382 - 383 - 1361 + 285 + 286 + 143 @@ -3576,11 +3637,11 @@ sourceLocationPrefix - 1361 + 1920 prefix - 1361 + 1920 @@ -4867,31 +4928,31 @@ locations_default - 430051334 + 602747369 id - 430051334 + 602747369 file - 7997871 + 9158642 beginLine - 2794830 + 3943517 beginColumn - 175612 + 247790 endLine - 2796191 + 3945438 endColumn - 619409 + 873989 @@ -4905,7 +4966,7 @@ 1 2 - 430051334 + 602747369 @@ -4921,7 +4982,7 @@ 1 2 - 430051334 + 602747369 @@ -4937,7 +4998,7 @@ 1 2 - 430051334 + 602747369 @@ -4953,7 +5014,7 @@ 1 2 - 430051334 + 602747369 @@ -4969,7 +5030,7 @@ 1 2 - 430051334 + 602747369 @@ -4985,17 +5046,17 @@ 1 2 - 7159286 + 7986919 2 - 20 - 603073 + 11 + 714558 - 20 + 11 3605 - 235511 + 457163 @@ -5011,17 +5072,17 @@ 1 2 - 7159286 + 7986919 2 - 15 - 600350 + 9 + 712637 - 15 + 9 1830 - 238234 + 459084 @@ -5037,17 +5098,17 @@ 1 2 - 7159286 + 7986919 2 - 7 - 627577 + 5 + 776025 - 7 + 5 105 - 211007 + 395696 @@ -5063,17 +5124,17 @@ 1 2 - 7159286 + 7986919 2 - 18 - 600350 + 10 + 693429 - 18 + 10 1834 - 238234 + 478293 @@ -5089,17 +5150,17 @@ 1 2 - 7159286 + 7986919 2 - 15 - 603073 + 9 + 695349 - 15 + 9 205 - 235511 + 476372 @@ -5115,67 +5176,67 @@ 1 14 - 221898 + 313099 14 125 - 215091 + 301574 125 142 - 215091 + 307336 142 152 - 223259 + 316941 152 159 - 249125 + 359200 159 - 165 - 257293 + 164 + 272761 - 165 - 170 - 225982 + 164 + 169 + 343833 - 170 - 174 - 216453 + 169 + 173 + 299653 - 174 - 179 - 228705 + 173 + 178 + 332308 - 179 - 185 - 213730 + 178 + 184 + 347674 - 185 - 194 - 221898 + 184 + 193 + 316941 - 194 - 215 - 215091 + 193 + 211 + 297732 - 215 - 5876 - 91209 + 211 + 4769 + 134459 @@ -5191,67 +5252,72 @@ 1 7 - 228705 + 322703 7 65 - 212369 + 299653 65 73 - 216453 + 307336 73 78 - 206923 + 295811 78 81 - 190587 + 265078 81 84 - 249125 + 357279 84 86 - 215091 + 299653 86 - 88 - 257293 + 87 + 188243 - 88 - 90 - 221898 + 87 + 89 + 357279 - 90 - 93 - 247763 + 89 + 91 + 259315 - 93 - 97 - 217814 + 91 + 94 + 324624 - 97 - 106 - 213730 + 94 + 99 + 328466 - 106 - 5876 - 117075 + 99 + 141 + 295811 + + + 141 + 4769 + 42258 @@ -5267,62 +5333,62 @@ 1 5 - 221898 + 313099 5 17 - 196032 + 280444 17 19 - 167444 + 251632 19 20 - 213730 + 309257 20 21 - 268183 + 403379 21 22 - 283158 + 420667 22 23 - 329444 + 476372 23 24 - 303578 + 457163 24 25 - 235511 + 339991 25 26 - 170167 + 213215 26 - 28 - 212369 + 29 + 361120 - 28 - 45 - 193310 + 29 + 40 + 117172 @@ -5338,32 +5404,32 @@ 1 2 - 902568 + 1273527 2 3 - 894400 + 1265844 3 4 - 481914 + 674220 4 5 - 211007 + 299653 5 11 - 220537 + 307336 11 97 - 84403 + 122934 @@ -5379,72 +5445,72 @@ 1 13 - 219175 + 309257 13 60 - 209646 + 307336 60 64 - 223259 + 311178 64 66 - 209646 + 311178 66 68 - 258654 + 353437 68 69 - 130688 + 194006 69 70 - 155192 + 217056 70 - 71 - 134772 + 72 + 359200 - 71 - 73 - 235511 + 72 + 74 + 322703 - 73 - 75 - 212369 + 74 + 76 + 245869 - 75 - 78 - 234150 + 76 + 79 + 330387 - 78 - 82 - 251847 + 79 + 83 + 295811 - 82 - 89 - 213730 + 83 + 91 + 316941 - 89 - 104 - 106184 + 91 + 103 + 69150 @@ -5460,67 +5526,67 @@ 1 11 - 14974 + 21129 15 - 34 - 14974 + 24 + 21129 - 36 - 58 - 13613 + 28 + 57 + 19208 - 63 - 88 - 13613 + 57 + 79 + 19208 - 89 - 132 - 13613 + 87 + 119 + 19208 - 141 - 196 - 14974 + 130 + 177 + 19208 - 210 - 285 - 13613 + 195 + 269 + 19208 - 316 - 468 - 13613 + 270 + 436 + 19208 - 496 - 853 - 13613 + 443 + 835 + 19208 - 899 - 1420 - 13613 + 844 + 1367 + 19208 - 1472 - 2256 - 13613 + 1419 + 2155 + 19208 - 2300 - 2526 - 13613 + 2252 + 2517 + 19208 - 2589 - 226687 - 8168 + 2521 + 226452 + 13445 @@ -5536,72 +5602,72 @@ 1 9 - 9529 + 17287 9 11 - 13613 + 21129 - 12 - 16 - 8168 + 11 + 15 + 15366 - 16 + 15 19 - 13613 + 21129 - 19 - 31 - 13613 + 23 + 68 + 19208 - 35 - 73 - 13613 + 69 + 78 + 19208 - 73 - 83 - 13613 + 79 + 100 + 13445 - 85 + 100 104 - 14974 + 21129 104 - 110 - 10890 + 109 + 19208 - 110 - 114 - 14974 + 109 + 112 + 13445 + + + 112 + 115 + 19208 115 - 119 - 13613 + 117 + 19208 - 119 - 121 - 12252 + 117 + 123 + 19208 - 121 - 126 - 13613 - - - 126 - 5876 - 9529 + 145 + 4769 + 9604 @@ -5617,67 +5683,67 @@ 1 10 - 14974 + 21129 10 - 29 - 13613 + 22 + 21129 - 29 - 43 - 13613 + 23 + 39 + 19208 - 45 + 41 58 - 13613 + 19208 58 - 85 - 13613 + 84 + 19208 - 86 + 84 106 - 13613 + 19208 108 - 167 - 13613 + 166 + 19208 - 171 - 227 - 13613 + 167 + 225 + 19208 - 231 - 379 - 13613 + 230 + 376 + 19208 - 383 - 650 - 13613 + 381 + 647 + 19208 - 651 - 891 - 13613 + 657 + 941 + 19208 - 940 - 1086 - 13613 + 941 + 1090 + 19208 - 1093 + 1102 2051 - 10890 + 13445 @@ -5693,67 +5759,67 @@ 1 10 - 14974 + 21129 10 - 30 - 13613 + 22 + 21129 - 30 - 43 - 13613 + 23 + 39 + 19208 - 46 + 41 59 - 13613 + 19208 - 60 - 87 - 13613 + 59 + 86 + 19208 - 87 + 86 109 - 13613 + 19208 - 115 - 173 - 13613 + 114 + 168 + 19208 - 174 - 226 - 13613 + 170 + 224 + 19208 - 230 - 380 - 13613 + 229 + 379 + 19208 - 383 - 650 - 13613 + 382 + 647 + 19208 - 653 - 892 - 13613 + 658 + 941 + 19208 - 940 - 1084 - 13613 + 941 + 1089 + 19208 - 1092 + 1102 2051 - 10890 + 13445 @@ -5769,72 +5835,67 @@ 1 8 - 14974 + 21129 8 - 17 - 13613 + 16 + 21129 - 18 - 25 - 10890 + 16 + 23 + 21129 - 25 - 30 - 13613 + 24 + 31 + 21129 - 30 - 36 - 13613 + 32 + 37 + 21129 - 36 - 44 - 13613 + 37 + 50 + 19208 - 45 - 56 - 12252 + 50 + 60 + 19208 - 57 - 64 - 13613 + 60 + 68 + 19208 - 64 - 73 - 13613 + 68 + 80 + 19208 - 73 - 86 - 13613 + 81 + 101 + 19208 - 86 - 106 - 13613 + 101 + 121 + 19208 - 107 - 129 - 13613 + 126 + 158 + 19208 - 129 - 197 - 13613 - - - 392 + 159 393 - 1361 + 7683 @@ -5850,67 +5911,67 @@ 1 14 - 220537 + 309257 14 124 - 215091 + 305416 124 143 - 217814 + 309257 143 152 - 235511 + 334228 152 159 - 223259 + 322703 159 - 165 - 257293 + 164 + 299653 - 165 - 170 - 239595 + 164 + 169 + 341912 - 170 - 174 - 221898 + 169 + 173 + 309257 - 174 - 179 - 221898 + 173 + 178 + 338070 - 179 - 185 - 211007 + 178 + 184 + 305416 - 185 - 194 - 216453 + 184 + 193 + 315020 - 194 - 217 - 212369 + 193 + 212 + 301574 - 217 - 5876 - 103461 + 212 + 4769 + 153668 @@ -5926,67 +5987,67 @@ 1 7 - 231427 + 324624 7 66 - 224621 + 318862 66 74 - 227343 + 320782 74 80 - 250486 + 355358 80 83 - 240957 + 339991 83 85 - 185142 + 268919 85 87 - 246402 + 343833 87 89 - 246402 + 355358 89 91 - 187864 + 266999 91 94 - 247763 + 345754 94 99 - 225982 + 324624 99 - 127 - 212369 + 130 + 301574 - 127 - 5876 - 69428 + 131 + 4769 + 78755 @@ -6002,32 +6063,32 @@ 1 2 - 709258 + 1000766 2 3 - 986971 + 1392620 3 4 - 642552 + 908564 4 6 - 236873 + 336149 6 - 18 - 212369 + 19 + 299653 - 18 + 19 22 - 8168 + 7683 @@ -6043,62 +6104,62 @@ 1 5 - 219175 + 309257 5 17 - 198755 + 284286 17 19 - 163360 + 232423 19 20 - 191948 + 280444 20 21 - 280436 + 420667 21 22 - 272267 + 407221 22 23 - 329444 + 482134 23 24 - 306301 + 437955 24 25 - 224621 + 334228 25 26 - 183780 + 259315 26 - 28 - 223259 + 29 + 363041 - 28 - 44 - 202839 + 29 + 39 + 134459 @@ -6114,72 +6175,72 @@ 1 13 - 221898 + 313099 13 - 61 - 250486 + 60 + 305416 - 61 + 60 64 - 172890 + 305416 64 66 - 217814 + 303495 66 68 - 250486 + 357279 68 69 - 137495 + 197848 69 70 - 137495 + 201689 70 71 - 157915 + 218977 71 73 - 231427 + 326545 73 75 - 191948 + 263157 75 77 - 183780 + 257394 77 80 - 211007 + 299653 80 85 - 227343 + 318862 85 119 - 204200 + 276603 @@ -6195,57 +6256,57 @@ 1 2 - 145663 + 205531 2 3 - 63982 + 90280 3 5 - 50369 + 71071 5 13 - 50369 + 71071 13 53 - 47646 + 67229 53 - 146 - 47646 + 138 + 67229 - 146 - 351 - 47646 + 142 + 346 + 67229 357 - 997 - 47646 + 967 + 67229 - 1053 - 2396 - 47646 + 1050 + 2386 + 67229 - 2407 - 4957 - 47646 + 2392 + 4902 + 67229 - 5022 - 5934 - 23142 + 4949 + 5933 + 32654 @@ -6261,57 +6322,57 @@ 1 2 - 151108 + 213215 2 3 - 61260 + 86438 3 5 - 53092 + 74913 5 13 - 50369 + 71071 13 42 - 47646 + 67229 42 77 - 47646 + 67229 77 - 103 - 51730 + 102 + 69150 - 103 - 116 - 47646 + 102 + 114 + 67229 - 116 - 144 - 49008 + 114 + 139 + 67229 - 144 - 181 - 47646 + 139 + 169 + 69150 - 181 - 5876 - 12252 + 173 + 4769 + 21129 @@ -6327,57 +6388,57 @@ 1 2 - 153831 + 217056 2 3 - 62621 + 88359 3 5 - 49008 + 69150 5 13 - 49008 + 69150 13 - 52 - 49008 + 50 + 67229 - 52 - 115 - 47646 + 50 + 113 + 67229 - 123 - 271 - 47646 + 114 + 266 + 67229 - 272 - 658 - 47646 + 269 + 636 + 67229 - 669 - 1200 - 47646 + 648 + 1197 + 67229 - 1219 + 1198 1635 - 47646 + 69150 1639 1722 - 17697 + 24971 @@ -6393,47 +6454,47 @@ 1 2 - 194671 + 274682 2 3 - 74873 + 105647 3 6 - 54453 + 76834 6 14 - 54453 + 76834 14 - 26 - 47646 + 25 + 74913 - 26 + 25 36 - 49008 + 71071 36 47 - 49008 + 67229 47 - 55 - 47646 + 54 + 67229 - 55 - 68 - 47646 + 54 + 65 + 59546 @@ -6449,57 +6510,57 @@ 1 2 - 153831 + 217056 2 3 - 61260 + 86438 3 5 - 49008 + 69150 5 13 - 49008 + 69150 13 - 53 - 50369 + 51 + 67229 - 53 - 115 - 47646 + 51 + 112 + 67229 - 123 - 271 - 47646 + 112 + 262 + 67229 - 280 - 656 - 47646 + 262 + 630 + 67229 - 669 - 1200 - 47646 + 637 + 1186 + 67229 - 1217 - 1638 - 47646 + 1197 + 1625 + 67229 - 1640 + 1632 1722 - 17697 + 28812 @@ -6509,15 +6570,15 @@ hasLocation - 316413492 + 340930835 locatableid - 316270551 + 340658074 id - 11518296 + 12195515 @@ -6531,12 +6592,12 @@ 1 2 - 316127611 + 340385312 2 3 - 142940 + 272761 @@ -6552,62 +6613,57 @@ 1 2 - 2084211 + 2091812 2 3 - 996500 + 1333074 3 4 - 716064 + 772184 4 6 - 984248 + 1085283 6 - 7 - 771879 + 8 + 1062233 - 7 - 9 - 1014198 + 8 + 11 + 1100650 - 9 - 12 - 848114 + 11 + 15 + 1048787 - 12 - 16 - 928433 + 15 + 21 + 964269 - 16 - 23 - 868534 + 21 + 32 + 916248 - 23 - 39 - 894400 + 32 + 64 + 920090 - 39 - 89 - 873980 - - - 89 - 9992 - 537729 + 64 + 9549 + 900881 @@ -6617,23 +6673,23 @@ numlines - 214506316 + 303305105 element_id - 214506316 + 303305105 num_lines - 431544 + 618515 num_code - 432906 + 612753 num_comment - 1342281 + 1893964 @@ -6647,7 +6703,7 @@ 1 2 - 214506316 + 303305105 @@ -6663,7 +6719,7 @@ 1 2 - 214506316 + 303305105 @@ -6679,7 +6735,7 @@ 1 2 - 214506316 + 303305105 @@ -6695,37 +6751,37 @@ 1 2 - 231427 + 320782 2 3 - 53092 + 78755 3 4 - 44924 + 61467 4 7 - 34033 + 49942 7 14 - 32672 + 48021 15 - 839 - 32672 + 194 + 48021 - 3519 - 149603 - 2722 + 320 + 149659 + 11525 @@ -6741,12 +6797,17 @@ 1 2 - 422015 + 509026 2 3 - 9529 + 69150 + + + 3 + 6 + 40337 @@ -6762,27 +6823,27 @@ 1 2 - 273629 + 380329 2 3 - 69428 + 97963 3 4 - 36756 + 51863 4 6 - 34033 + 53783 6 987 - 17697 + 34575 @@ -6798,37 +6859,37 @@ 1 2 - 231427 + 316941 2 3 - 53092 + 78755 3 4 - 44924 + 61467 4 7 - 34033 + 51863 7 - 14 - 32672 + 15 + 46100 - 15 - 468 - 32672 + 16 + 214 + 46100 - 495 + 325 78746 - 4084 + 11525 @@ -6844,12 +6905,17 @@ 1 2 - 431544 + 516710 - 7 + 2 + 3 + 51863 + + + 3 8 - 1361 + 44179 @@ -6865,27 +6931,27 @@ 1 2 - 273629 + 370725 2 3 - 69428 + 101805 3 4 - 36756 + 53783 4 6 - 34033 + 46100 6 987 - 19058 + 40337 @@ -6901,77 +6967,77 @@ 1 7 - 108907 + 153668 7 49 - 100739 + 142143 49 71 - 104823 + 147905 71 78 - 107545 + 151747 78 83 - 103461 + 145985 83 87 - 115713 + 163272 87 89 - 99377 + 140222 89 91 - 95293 + 134459 91 92 - 57176 + 80675 92 93 - 68066 + 96042 93 94 - 74873 + 105647 94 95 - 69428 + 97963 95 97 - 108907 + 151747 97 119 - 100739 + 144064 - 119 - 75115 - 27226 + 120 + 75134 + 38417 @@ -6987,22 +7053,22 @@ 1 2 - 1101323 + 1550130 2 3 - 114352 + 165193 3 - 6 - 102100 + 7 + 145985 - 6 + 7 120 - 24504 + 32654 @@ -7018,22 +7084,22 @@ 1 2 - 1101323 + 1550130 2 3 - 114352 + 165193 3 - 6 - 100739 + 7 + 145985 - 6 - 121 - 25865 + 7 + 122 + 32654 @@ -7043,15 +7109,15 @@ files - 7997871 + 9158642 id - 7997871 + 9158642 name - 7997871 + 9158642 @@ -7065,7 +7131,7 @@ 1 2 - 7997871 + 9158642 @@ -7081,7 +7147,7 @@ 1 2 - 7997871 + 9158642 @@ -7091,15 +7157,15 @@ folders - 1275575 + 1415670 id - 1275575 + 1415670 name - 1275575 + 1415670 @@ -7113,7 +7179,7 @@ 1 2 - 1275575 + 1415670 @@ -7129,7 +7195,7 @@ 1 2 - 1275575 + 1415670 @@ -7139,15 +7205,15 @@ containerparent - 9270724 + 10570471 parent - 1316415 + 1463692 child - 9270724 + 10570471 @@ -7161,37 +7227,32 @@ 1 2 - 710619 + 843255 2 3 - 140218 + 149826 3 - 4 - 78957 + 5 + 128697 - 4 - 7 - 112991 + 5 + 11 + 124855 - 7 - 14 - 111629 + 11 + 21 + 113330 - 14 - 29 - 102100 - - - 29 + 21 194 - 59898 + 103726 @@ -7207,7 +7268,7 @@ 1 2 - 9270724 + 10570471 @@ -7217,15 +7278,15 @@ cupackage - 7140227 + 7979236 id - 7140227 + 7979236 packageid - 609880 + 576256 @@ -7239,7 +7300,7 @@ 1 2 - 7140227 + 7979236 @@ -7255,52 +7316,52 @@ 1 2 - 148386 + 121013 2 3 - 80319 + 80675 3 4 - 55814 + 42258 4 - 5 - 42201 + 6 + 49942 - 5 - 7 - 46285 + 6 + 9 + 49942 - 7 - 10 - 50369 + 9 + 12 + 51863 - 10 - 15 - 50369 + 12 + 17 + 48021 - 15 - 21 - 49008 + 17 + 23 + 46100 - 21 - 36 - 47646 + 24 + 43 + 44179 - 39 + 43 187 - 39478 + 42258 @@ -7310,19 +7371,19 @@ jarManifestMain - 172733 + 172742 fileid - 13274 + 13275 keyName - 12610 + 12611 value - 89768 + 89772 @@ -7407,7 +7468,7 @@ 5 6 - 2488 + 2489 6 @@ -7473,7 +7534,7 @@ 1 2 - 5143 + 5144 2 @@ -7580,7 +7641,7 @@ 1 2 - 75996 + 75999 2 @@ -7611,7 +7672,7 @@ 1 2 - 75664 + 75668 2 @@ -7621,7 +7682,7 @@ 3 6 - 5309 + 5310 @@ -7844,7 +7905,7 @@ 1 2 - 30112 + 30113 2 @@ -7886,7 +7947,7 @@ 1 2 - 30124 + 30125 3 @@ -8005,7 +8066,7 @@ 1 2 - 30161 + 30162 2 @@ -8026,7 +8087,7 @@ 1 2 - 30161 + 30162 11 @@ -8062,15 +8123,15 @@ packages - 611241 + 580098 id - 611241 + 580098 nodeName - 611241 + 580098 @@ -8084,7 +8145,7 @@ 1 2 - 611241 + 580098 @@ -8100,7 +8161,7 @@ 1 2 - 611241 + 580098 @@ -8110,15 +8171,15 @@ primitives - 12252 + 17287 id - 12252 + 17287 nodeName - 12252 + 17287 @@ -8132,7 +8193,7 @@ 1 2 - 12252 + 17287 @@ -8148,7 +8209,7 @@ 1 2 - 12252 + 17287 @@ -8158,15 +8219,15 @@ modifiers - 13613 + 26891 id - 13613 + 26891 nodeName - 13613 + 26891 @@ -8180,7 +8241,7 @@ 1 2 - 13613 + 26891 @@ -8196,7 +8257,7 @@ 1 2 - 13613 + 26891 @@ -8217,23 +8278,23 @@ classes - 12548830 + 12618104 id - 12548830 + 12618104 nodeName - 6855707 + 6732600 parentid - 442435 + 455242 sourceid - 4506034 + 5253541 @@ -8247,7 +8308,7 @@ 1 2 - 12548830 + 12618104 @@ -8263,7 +8324,7 @@ 1 2 - 12548830 + 12618104 @@ -8279,7 +8340,7 @@ 1 2 - 12548830 + 12618104 @@ -8295,17 +8356,17 @@ 1 2 - 5728517 + 5601216 2 3 - 741930 + 726083 3 - 236 - 385259 + 204 + 405300 @@ -8321,17 +8382,17 @@ 1 2 - 6243104 + 5950812 2 3 - 544535 + 731846 3 52 - 68066 + 49942 @@ -8347,17 +8408,17 @@ 1 2 - 6219961 + 5921999 2 3 - 533645 + 714558 3 160 - 102100 + 96042 @@ -8373,57 +8434,62 @@ 1 2 - 107545 + 94121 2 3 - 54453 + 46100 3 4 - 32672 + 30733 4 5 - 29949 + 26891 5 - 7 - 34033 + 6 + 24971 - 7 - 11 - 40840 + 6 + 8 + 40337 - 11 - 17 - 34033 + 8 + 12 + 32654 - 17 + 12 + 18 + 38417 + + + 18 23 - 34033 + 34575 23 40 - 36756 + 36496 40 - 707 - 34033 + 76 + 34575 - 1013 - 1414 - 4084 + 83 + 891 + 15366 @@ -8439,52 +8505,57 @@ 1 2 - 107545 + 96042 2 3 - 54453 + 46100 3 4 - 35394 + 34575 4 5 - 34033 + 28812 5 - 7 - 38117 + 6 + 36496 - 7 - 11 - 40840 + 6 + 9 + 40337 - 11 - 17 - 36756 + 9 + 13 + 40337 - 17 - 23 - 34033 + 13 + 18 + 26891 - 23 - 40 - 35394 + 18 + 25 + 38417 - 40 - 830 - 25865 + 26 + 41 + 36496 + + + 41 + 479 + 30733 @@ -8500,52 +8571,57 @@ 1 2 - 118436 + 99884 2 3 - 63982 + 57625 3 4 - 36756 + 36496 4 5 - 34033 + 32654 5 - 7 - 35394 + 6 + 32654 - 7 - 11 - 40840 + 6 + 8 + 34575 - 11 - 17 - 34033 + 8 + 12 + 38417 - 17 - 26 - 34033 + 12 + 18 + 32654 - 26 - 56 - 34033 + 18 + 25 + 34575 - 64 + 25 + 47 + 34575 + + + 51 138 - 10890 + 21129 @@ -8561,17 +8637,17 @@ 1 2 - 4040456 + 4694572 2 11 - 341696 + 407221 11 - 1358 - 123881 + 426 + 151747 @@ -8587,17 +8663,17 @@ 1 2 - 4040456 + 4694572 2 6 - 359393 + 426430 6 - 783 - 106184 + 224 + 132539 @@ -8613,7 +8689,7 @@ 1 2 - 4506034 + 5253541 @@ -8623,26 +8699,26 @@ file_class - 14974 + 17287 id - 14974 + 17287 class_object - 122520 + 163272 id - 122520 + 163272 instance - 122520 + 163272 @@ -8656,7 +8732,7 @@ 1 2 - 122520 + 163272 @@ -8672,7 +8748,7 @@ 1 2 - 122520 + 163272 @@ -8682,19 +8758,19 @@ type_companion_object - 217814 + 307336 id - 217814 + 307336 instance - 217814 + 307336 companion_object - 217814 + 307336 @@ -8708,7 +8784,7 @@ 1 2 - 217814 + 307336 @@ -8724,7 +8800,7 @@ 1 2 - 217814 + 307336 @@ -8740,7 +8816,7 @@ 1 2 - 217814 + 307336 @@ -8756,7 +8832,7 @@ 1 2 - 217814 + 307336 @@ -8772,7 +8848,7 @@ 1 2 - 217814 + 307336 @@ -8788,7 +8864,7 @@ 1 2 - 217814 + 307336 @@ -8798,15 +8874,15 @@ kt_nullable_types - 1361 + 1920 id - 1361 + 1920 classid - 1361 + 1920 @@ -8820,7 +8896,7 @@ 1 2 - 1361 + 1920 @@ -8836,7 +8912,7 @@ 1 2 - 1361 + 1920 @@ -8846,15 +8922,15 @@ kt_notnull_types - 191419 + 172391 id - 191419 + 172391 classid - 191419 + 172391 @@ -8868,7 +8944,7 @@ 1 2 - 191419 + 172391 @@ -8884,7 +8960,7 @@ 1 2 - 191419 + 172391 @@ -8894,19 +8970,19 @@ kt_type_alias - 2060 + 1821 id - 2060 + 1821 name - 2060 + 1821 kttypeid - 1030 + 910 @@ -8920,7 +8996,7 @@ 1 2 - 2060 + 1821 @@ -8936,7 +9012,7 @@ 1 2 - 2060 + 1821 @@ -8952,7 +9028,7 @@ 1 2 - 2060 + 1821 @@ -8968,7 +9044,7 @@ 1 2 - 2060 + 1821 @@ -8984,7 +9060,7 @@ 2 3 - 1030 + 910 @@ -9000,7 +9076,7 @@ 2 3 - 1030 + 910 @@ -9021,23 +9097,23 @@ interfaces - 21501109 + 23200100 id - 21501109 + 23200100 nodeName - 5448969 + 8705320 parentid - 350 + 430271 sourceid - 2074 + 2787162 @@ -9051,7 +9127,7 @@ 1 2 - 21501109 + 23200100 @@ -9067,7 +9143,7 @@ 1 2 - 21501109 + 23200100 @@ -9083,7 +9159,7 @@ 1 2 - 21501109 + 23200100 @@ -9099,27 +9175,22 @@ 1 2 - 3495545 + 6834406 2 3 - 811460 + 1079521 3 - 5 - 410487 + 25 + 655011 - 5 - 12 - 426139 - - - 12 - 9655 - 305336 + 25 + 345 + 136380 @@ -9135,231 +9206,221 @@ 1 2 - 5448745 + 7996524 2 - 3 - 224 - - - - - - - nodeName - sourceid - - - 12 - - - 1 - 2 - 5448653 - - - 2 - 6 - 316 - - - - - - - parentid - id - - - 12 - - - 1 - 2 - 57 - - - 2 - 3 - 34 - - - 3 4 - 28 + 695349 4 - 6 - 28 - - - 6 - 9 - 28 - - - 10 - 16 - 28 - - - 16 - 20 - 28 - - - 21 - 212 - 28 - - - 288 - 1113 - 28 - - - 1315 - 27761 - 28 - - - 36093 - 2073873 - 28 - - - - - - - parentid - nodeName - - - 12 - - - 1 - 2 - 57 - - - 2 - 3 - 34 - - - 3 - 4 - 28 - - - 4 - 5 - 5 - - - 5 - 6 - 28 - - - 6 - 11 - 28 - - - 11 - 14 - 28 - - - 15 - 20 - 28 - - - 21 - 107 - 28 - - - 153 - 381 - 28 - - - 3060 - 15096 - 28 - - - 36080 - 500307 - 22 - - - - - - - parentid - sourceid - - - 12 - - - 1 - 2 - 97 - - - 2 - 3 - 40 - - - 3 - 4 - 34 - - - 4 - 6 - 28 - - - 6 7 - 11 + 13445 + + + + + + + nodeName + sourceid + + + 12 + + + 1 + 2 + 7967711 - 7 + 2 + 4 + 718400 + + + 4 + 7 + 19208 + + + + + + + parentid + id + + + 12 + + + 1 + 2 + 113330 + + + 2 + 3 + 55704 + + + 3 + 4 + 48021 + + + 4 + 5 + 26891 + + + 5 8 - 40 + 36496 8 + 13 + 34575 + + + 13 + 18 + 34575 + + + 18 + 41 + 32654 + + + 42 + 182 + 32654 + + + 187 + 4152 + 15366 + + + + + + + parentid + nodeName + + + 12 + + + 1 + 2 + 113330 + + + 2 + 3 + 55704 + + + 3 + 4 + 48021 + + + 4 + 5 + 38417 + + + 5 + 7 + 24971 + + + 7 10 - 22 + 32654 10 - 11 - 28 - - - 11 15 - 28 + 36496 - 19 - 40 - 17 + 15 + 28 + 32654 + + + 30 + 94 + 32654 + + + 100 + 1213 + 15366 + + + + + + + parentid + sourceid + + + 12 + + + 1 + 2 + 140222 + + + 2 + 3 + 65309 + + + 3 + 4 + 44179 + + + 4 + 5 + 34575 + + + 5 + 7 + 28812 + + + 7 + 9 + 34575 + + + 9 + 14 + 34575 + + + 14 + 26 + 32654 + + + 26 + 160 + 15366 @@ -9375,32 +9436,17 @@ 1 2 - 1292 + 2391465 2 - 7 - 166 + 11 + 213215 - 7 - 53 - 160 - - - 55 - 289 - 166 - - - 353 - 3260 - 160 - - - 3665 - 450913 - 126 + 11 + 1565 + 182481 @@ -9416,32 +9462,17 @@ 1 2 - 1292 + 2391465 2 6 - 172 + 217056 6 - 31 - 160 - - - 31 - 110 - 160 - - - 115 - 1202 - 160 - - - 1336 - 101026 - 126 + 492 + 178639 @@ -9457,7 +9488,7 @@ 1 2 - 2074 + 2787162 @@ -9467,15 +9498,15 @@ fielddecls - 398872 + 199475 id - 398872 + 199475 parentid - 59898 + 25503 @@ -9489,7 +9520,7 @@ 1 2 - 398872 + 199475 @@ -9505,32 +9536,57 @@ 1 2 - 29949 + 4554 2 3 - 13613 + 5465 3 4 - 5445 + 1821 4 - 5 - 2722 + 6 + 1821 6 - 16 - 5445 + 7 + 2732 - 40 - 159 - 2722 + 7 + 9 + 1821 + + + 9 + 10 + 910 + + + 10 + 11 + 1821 + + + 13 + 18 + 1821 + + + 19 + 20 + 1821 + + + 57 + 58 + 910 @@ -9540,19 +9596,19 @@ fieldDeclaredIn - 398872 + 199475 fieldId - 398872 + 199475 fieldDeclId - 398872 + 199475 pos - 1361 + 910 @@ -9566,7 +9622,7 @@ 1 2 - 398872 + 199475 @@ -9582,7 +9638,7 @@ 1 2 - 398872 + 199475 @@ -9598,7 +9654,7 @@ 1 2 - 398872 + 199475 @@ -9614,7 +9670,7 @@ 1 2 - 398872 + 199475 @@ -9628,9 +9684,9 @@ 12 - 293 - 294 - 1361 + 219 + 220 + 910 @@ -9644,9 +9700,9 @@ 12 - 293 - 294 - 1361 + 219 + 220 + 910 @@ -9656,27 +9712,27 @@ fields - 27509955 + 19350704 id - 27509955 + 19350704 nodeName - 10900247 + 13628474 typeid - 2728125 + 3038794 parentid - 3851230 + 4089502 sourceid - 27509955 + 19350704 @@ -9690,7 +9746,7 @@ 1 2 - 27509955 + 19350704 @@ -9706,7 +9762,7 @@ 1 2 - 27509955 + 19350704 @@ -9722,7 +9778,7 @@ 1 2 - 27509955 + 19350704 @@ -9738,7 +9794,7 @@ 1 2 - 27509955 + 19350704 @@ -9754,22 +9810,17 @@ 1 2 - 8061854 + 12016876 2 3 - 1433490 + 1123700 3 - 11 - 760988 - - - 11 - 828 - 643913 + 722 + 487897 @@ -9785,17 +9836,17 @@ 1 2 - 9875159 + 12416414 2 - 4 - 850837 + 5 + 1085283 - 4 + 5 160 - 174251 + 126776 @@ -9811,22 +9862,17 @@ 1 2 - 8061854 + 12016876 2 3 - 1433490 + 1123700 3 - 11 - 760988 - - - 11 - 828 - 643913 + 722 + 487897 @@ -9842,22 +9888,17 @@ 1 2 - 8061854 + 12016876 2 3 - 1433490 + 1123700 3 - 11 - 760988 - - - 11 - 828 - 643913 + 722 + 487897 @@ -9873,32 +9914,27 @@ 1 2 - 1732985 + 2059157 2 3 - 338973 + 320782 3 4 - 175612 + 213215 4 - 7 - 208284 + 8 + 245869 - 7 - 24 - 205562 - - - 24 - 7479 - 66705 + 8 + 2588 + 199769 @@ -9914,27 +9950,27 @@ 1 2 - 1894985 + 2120625 2 3 - 302217 + 299653 3 4 - 183780 + 199769 4 9 - 212369 + 255473 9 - 2335 - 134772 + 2016 + 163272 @@ -9950,17 +9986,17 @@ 1 2 - 2326529 + 2706486 2 4 - 228705 + 251632 4 - 1392 - 172890 + 1014 + 80675 @@ -9976,32 +10012,27 @@ 1 2 - 1732985 + 2059157 2 3 - 338973 + 320782 3 4 - 175612 + 213215 4 - 7 - 208284 + 8 + 245869 - 7 - 24 - 205562 - - - 24 - 7479 - 66705 + 8 + 2588 + 199769 @@ -10017,37 +10048,32 @@ 1 2 - 1937186 + 2427962 2 3 - 484636 + 478293 3 4 - 303578 + 303495 4 6 - 341696 + 338070 6 - 10 - 300856 + 13 + 330387 - 10 - 27 - 291326 - - - 27 + 13 1610 - 191948 + 211294 @@ -10063,37 +10089,32 @@ 1 2 - 1937186 + 2427962 2 3 - 484636 + 478293 3 4 - 303578 + 303495 4 6 - 341696 + 338070 6 - 10 - 300856 + 13 + 330387 - 10 - 27 - 291326 - - - 27 + 13 1610 - 191948 + 211294 @@ -10109,27 +10130,22 @@ 1 2 - 2499419 + 3031110 2 3 - 623493 + 595465 3 - 4 - 243679 + 5 + 347674 - 4 - 7 - 338973 - - - 7 + 5 76 - 145663 + 115251 @@ -10145,37 +10161,32 @@ 1 2 - 1937186 + 2427962 2 3 - 484636 + 478293 3 4 - 303578 + 303495 4 6 - 341696 + 338070 6 - 10 - 300856 + 13 + 330387 - 10 - 27 - 291326 - - - 27 + 13 1610 - 191948 + 211294 @@ -10191,7 +10202,7 @@ 1 2 - 27509955 + 19350704 @@ -10207,7 +10218,7 @@ 1 2 - 27509955 + 19350704 @@ -10223,7 +10234,7 @@ 1 2 - 27509955 + 19350704 @@ -10239,7 +10250,7 @@ 1 2 - 27509955 + 19350704 @@ -10249,15 +10260,15 @@ fieldsKotlinType - 27509955 + 19350704 id - 27509955 + 19350704 kttypeid - 1361 + 1920 @@ -10271,7 +10282,7 @@ 1 2 - 27509955 + 19350704 @@ -10285,9 +10296,9 @@ 12 - 20208 - 20209 - 1361 + 10074 + 10075 + 1920 @@ -10297,31 +10308,31 @@ constrs - 6869320 + 8006128 id - 6869320 + 8006128 nodeName - 3746407 + 4333451 signature - 5871458 + 6803672 typeid - 2722 + 3841 parentid - 4835479 + 5639633 sourceid - 5054654 + 5720309 @@ -10335,7 +10346,7 @@ 1 2 - 6869320 + 8006128 @@ -10351,7 +10362,7 @@ 1 2 - 6869320 + 8006128 @@ -10367,7 +10378,7 @@ 1 2 - 6869320 + 8006128 @@ -10383,7 +10394,7 @@ 1 2 - 6869320 + 8006128 @@ -10399,7 +10410,7 @@ 1 2 - 6869320 + 8006128 @@ -10415,22 +10426,58 @@ 1 2 - 2361924 + 2623889 2 3 - 835862 + 1085283 + + + 3 + 4 + 259315 + + + 4 + 11 + 326545 + + + 11 + 36 + 38417 + + + + + + + nodeName + signature + + + 12 + + + 1 + 2 + 2977327 + + + 2 + 3 + 868226 3 5 - 345780 + 341912 5 - 42 - 202839 + 19 + 145985 @@ -10438,7 +10485,7 @@ nodeName - signature + typeid 12 @@ -10446,95 +10493,64 @@ 1 2 - 2628747 + 4333451 + + + + + + + nodeName + parentid + + + 12 + + + 1 + 2 + 3764878 2 3 - 683392 + 401458 + + + 3 + 36 + 167114 + + + + + + + nodeName + sourceid + + + 12 + + + 1 + 2 + 2737220 + + + 2 + 3 + 1083362 3 5 - 302217 + 353437 5 - 19 - 132049 - - - - - - - nodeName - typeid - - - 12 - - - 1 - 2 - 3746407 - - - - - - - nodeName - parentid - - - 12 - - - 1 - 2 - 3287635 - - - 2 - 3 - 314469 - - - 3 - 42 - 144302 - - - - - - - nodeName - sourceid - - - 12 - - - 1 - 2 - 2453134 - - - 2 - 3 - 827694 - - - 3 - 5 - 318553 - - - 5 - 38 - 147024 + 32 + 159431 @@ -10550,12 +10566,12 @@ 1 2 - 5461695 + 6302329 2 - 42 - 409763 + 36 + 501343 @@ -10571,7 +10587,7 @@ 1 2 - 5871458 + 6803672 @@ -10587,7 +10603,7 @@ 1 2 - 5871458 + 6803672 @@ -10603,12 +10619,12 @@ 1 2 - 5461695 + 6302329 2 - 42 - 409763 + 36 + 501343 @@ -10624,12 +10640,12 @@ 1 2 - 5591022 + 6461760 2 - 32 - 280436 + 23 + 341912 @@ -10643,14 +10659,14 @@ 12 - 31 - 32 - 1361 + 22 + 23 + 1920 - 5015 - 5016 - 1361 + 4146 + 4147 + 1920 @@ -10666,12 +10682,12 @@ 1 2 - 1361 + 1920 - 2751 - 2752 - 1361 + 2255 + 2256 + 1920 @@ -10687,12 +10703,12 @@ 1 2 - 1361 + 1920 - 4312 - 4313 - 1361 + 3541 + 3542 + 1920 @@ -10706,14 +10722,14 @@ 12 - 31 - 32 - 1361 + 22 + 23 + 1920 - 3521 - 3522 - 1361 + 2914 + 2915 + 1920 @@ -10727,14 +10743,14 @@ 12 - 31 - 32 - 1361 + 22 + 23 + 1920 - 3682 - 3683 - 1361 + 2956 + 2957 + 1920 @@ -10750,22 +10766,22 @@ 1 2 - 3676978 + 4256617 2 3 - 737846 + 895118 3 6 - 366200 + 434113 6 19 - 54453 + 53783 @@ -10781,7 +10797,7 @@ 1 2 - 4835479 + 5639633 @@ -10797,22 +10813,22 @@ 1 2 - 3676978 + 4256617 2 3 - 737846 + 895118 3 6 - 366200 + 434113 6 19 - 54453 + 53783 @@ -10828,7 +10844,7 @@ 1 2 - 4835479 + 5639633 @@ -10844,22 +10860,22 @@ 1 2 - 3676978 + 4256617 2 3 - 737846 + 895118 3 6 - 366200 + 434113 6 19 - 54453 + 53783 @@ -10875,12 +10891,12 @@ 1 2 - 4742907 + 5357267 2 - 259 - 311746 + 209 + 363041 @@ -10896,12 +10912,12 @@ 1 2 - 4742907 + 5357267 2 - 212 - 311746 + 172 + 363041 @@ -10917,12 +10933,12 @@ 1 2 - 4742907 + 5357267 2 - 212 - 311746 + 172 + 363041 @@ -10938,7 +10954,7 @@ 1 2 - 5054654 + 5720309 @@ -10954,12 +10970,12 @@ 1 2 - 4742907 + 5357267 2 - 259 - 311746 + 209 + 363041 @@ -10969,15 +10985,15 @@ constrsKotlinType - 6869320 + 8006128 id - 6869320 + 8006128 kttypeid - 1361 + 1920 @@ -10991,7 +11007,7 @@ 1 2 - 6869320 + 8006128 @@ -11005,9 +11021,9 @@ 12 - 5046 - 5047 - 1361 + 4168 + 4169 + 1920 @@ -11017,31 +11033,31 @@ methods - 93308954 + 109719302 id - 93308954 + 109719302 nodeName - 20326164 + 22908130 signature - 29772501 + 33369112 typeid - 11583640 + 13338425 parentid - 11270532 + 12810189 sourceid - 58543057 + 67091663 @@ -11055,7 +11071,7 @@ 1 2 - 93308954 + 109719302 @@ -11071,7 +11087,7 @@ 1 2 - 93308954 + 109719302 @@ -11087,7 +11103,7 @@ 1 2 - 93308954 + 109719302 @@ -11103,7 +11119,7 @@ 1 2 - 93308954 + 109719302 @@ -11119,7 +11135,7 @@ 1 2 - 93308954 + 109719302 @@ -11135,32 +11151,32 @@ 1 2 - 11834127 + 13324979 2 3 - 3821280 + 4070294 3 4 - 1315054 + 1573181 4 7 - 1792884 + 2026503 7 - 271 - 1524700 + 56 + 1719166 - 276 - 2134 - 38117 + 57 + 1769 + 194006 @@ -11176,17 +11192,17 @@ 1 2 - 16853387 + 19150935 2 3 - 2115522 + 2228193 3 - 361 - 1357255 + 298 + 1529001 @@ -11202,22 +11218,22 @@ 1 2 - 17082092 + 19179748 2 3 - 1678532 + 1872834 3 - 52 - 1524700 + 25 + 1726849 - 52 - 845 - 40840 + 25 + 741 + 128697 @@ -11233,27 +11249,27 @@ 1 2 - 12555637 + 14028012 2 3 - 3596659 + 3889733 3 4 - 1245625 + 1502109 4 7 - 1577792 + 1817129 7 - 1278 - 1350449 + 1099 + 1671144 @@ -11269,27 +11285,27 @@ 1 2 - 12213940 + 13743725 2 3 - 3951969 + 4283509 3 4 - 1297356 + 1544368 4 7 - 1656750 + 1857467 7 - 928 - 1206147 + 800 + 1479059 @@ -11305,22 +11321,27 @@ 1 2 - 20356114 + 22735253 2 3 - 4957999 + 5434102 3 5 - 2363285 + 2635414 5 - 1275 - 2095101 + 157 + 2502875 + + + 157 + 1096 + 61467 @@ -11336,7 +11357,7 @@ 1 2 - 29772501 + 33369112 @@ -11352,17 +11373,17 @@ 1 2 - 26733991 + 29957672 2 5 - 2383706 + 2650781 5 - 843 - 654804 + 739 + 760659 @@ -11378,22 +11399,27 @@ 1 2 - 20360198 + 22741015 2 3 - 4956638 + 5432181 3 5 - 2361924 + 2631572 5 - 1275 - 2093740 + 157 + 2502875 + + + 157 + 1096 + 61467 @@ -11409,22 +11435,22 @@ 1 2 - 20978246 + 23365294 2 3 - 5076436 + 5656921 3 6 - 2533453 + 2900492 6 - 923 - 1184365 + 795 + 1446404 @@ -11440,32 +11466,32 @@ 1 2 - 5684955 + 6603903 2 3 - 2449050 + 2729536 3 4 - 1089071 + 1208218 4 6 - 925711 + 1119859 6 - 14 - 875341 + 15 + 1019974 - 14 - 11667 - 559510 + 15 + 10335 + 656932 @@ -11481,22 +11507,22 @@ 1 2 - 7613973 + 8714924 2 3 - 2218983 + 2620047 3 6 - 1060483 + 1167880 6 - 3940 - 690199 + 2888 + 835572 @@ -11512,27 +11538,22 @@ 1 2 - 7370293 + 8565097 2 3 - 2274798 + 2602760 3 - 5 - 875341 + 6 + 1210139 - 5 - 17 - 882148 - - - 17 - 5689 - 181058 + 6 + 4142 + 960428 @@ -11548,27 +11569,27 @@ 1 2 - 6786279 + 7714158 2 3 - 2466747 + 2869759 3 4 - 1003307 + 1108333 4 - 9 - 916181 + 8 + 1069916 - 9 - 3420 - 411124 + 8 + 2865 + 576256 @@ -11584,32 +11605,32 @@ 1 2 - 6180482 + 7166714 2 3 - 2262546 + 2524004 3 4 - 985610 + 1096808 4 6 - 910736 + 1094888 6 16 - 890316 + 1016132 16 - 8855 - 353948 + 6435 + 439876 @@ -11625,52 +11646,52 @@ 1 2 - 3190980 + 3630418 2 3 - 1287827 + 1456008 3 4 - 1029172 + 1164038 4 5 - 744652 + 735687 5 7 - 924349 + 1021895 7 10 - 952937 + 1106413 10 13 - 997862 + 1146751 13 - 19 - 908013 + 21 + 1181326 - 19 - 38 - 909375 + 21 + 40 + 1021895 - 38 + 40 319 - 325360 + 345754 @@ -11686,52 +11707,52 @@ 1 2 - 3244072 + 3678439 2 3 - 1308247 + 1457929 3 4 - 1109491 + 1231268 4 5 - 785493 + 791392 5 7 - 887593 + 960428 7 10 - 1015559 + 1183247 10 13 - 942047 + 1102571 13 - 17 - 875341 + 18 + 849018 - 17 - 35 - 848114 + 18 + 26 + 968111 - 35 + 26 290 - 254570 + 587781 @@ -11747,52 +11768,52 @@ 1 2 - 3190980 + 3630418 2 3 - 1287827 + 1456008 3 4 - 1029172 + 1164038 4 5 - 744652 + 735687 5 7 - 924349 + 1021895 7 10 - 952937 + 1106413 10 13 - 997862 + 1146751 13 - 19 - 908013 + 21 + 1181326 - 19 - 38 - 909375 + 21 + 40 + 1021895 - 38 + 40 319 - 325360 + 345754 @@ -11808,47 +11829,52 @@ 1 2 - 3887986 + 4348818 2 3 - 1615910 + 1757583 3 4 - 1327306 + 1436800 4 5 - 786854 + 922010 5 6 - 637107 + 743371 6 7 - 498250 + 564731 7 - 9 - 1033256 + 8 + 879752 - 9 - 13 - 882148 + 8 + 11 + 1160197 - 13 + 11 + 31 + 964269 + + + 33 78 - 601712 + 32654 @@ -11864,52 +11890,52 @@ 1 2 - 3190980 + 3630418 2 3 - 1287827 + 1456008 3 4 - 1029172 + 1164038 4 5 - 744652 + 735687 5 7 - 924349 + 1021895 7 10 - 952937 + 1106413 10 13 - 997862 + 1146751 13 - 19 - 908013 + 21 + 1181326 - 19 - 38 - 909375 + 21 + 40 + 1021895 - 38 + 40 319 - 325360 + 345754 @@ -11925,12 +11951,17 @@ 1 2 - 54190854 + 61836200 2 - 349 - 4352203 + 50 + 5032643 + + + 52 + 286 + 222819 @@ -11946,7 +11977,7 @@ 1 2 - 58543057 + 67091663 @@ -11962,12 +11993,12 @@ 1 2 - 58259899 + 66767038 2 - 347 - 283158 + 284 + 324624 @@ -11983,12 +12014,12 @@ 1 2 - 56848189 + 65030584 2 - 259 - 1694868 + 209 + 2061078 @@ -12004,12 +12035,17 @@ 1 2 - 54190854 + 61836200 2 - 349 - 4352203 + 50 + 5032643 + + + 52 + 286 + 222819 @@ -12019,15 +12055,15 @@ methodsKotlinType - 93308954 + 109719302 id - 93308954 + 109719302 kttypeid - 1361 + 1920 @@ -12041,7 +12077,7 @@ 1 2 - 93308954 + 109719302 @@ -12055,9 +12091,9 @@ 12 - 68542 - 68543 - 1361 + 57120 + 57121 + 1920 @@ -12067,27 +12103,27 @@ params - 101015498 + 120852585 id - 101015498 + 120852585 typeid - 11171154 + 12833239 pos - 29949 + 42258 parentid - 56251922 + 65007534 sourceid - 61310661 + 73639861 @@ -12101,7 +12137,7 @@ 1 2 - 101015498 + 120852585 @@ -12117,7 +12153,7 @@ 1 2 - 101015498 + 120852585 @@ -12133,7 +12169,7 @@ 1 2 - 101015498 + 120852585 @@ -12149,7 +12185,7 @@ 1 2 - 101015498 + 120852585 @@ -12165,32 +12201,37 @@ 1 2 - 5943609 + 6763334 2 3 - 1712565 + 1945827 3 4 - 869896 + 948902 4 6 - 970635 + 1148671 6 12 - 867173 + 1018053 12 - 7469 - 807274 + 326 + 966190 + + + 343 + 6738 + 42258 @@ -12206,17 +12247,22 @@ 1 2 - 9232606 + 10436011 2 3 - 1157138 + 1342678 3 + 8 + 964269 + + + 8 17 - 781409 + 90280 @@ -12232,32 +12278,32 @@ 1 2 - 6134197 + 7005362 2 3 - 1677170 + 1895885 3 4 - 888954 + 975794 4 6 - 917543 + 1087204 6 13 - 867173 + 1008449 13 - 5265 - 686115 + 4326 + 860543 @@ -12273,32 +12319,32 @@ 1 2 - 6337036 + 7216656 2 3 - 1569624 + 1788317 3 4 - 901206 + 996924 4 6 - 947492 + 1117938 6 13 - 856282 + 1002686 13 - 6292 - 559510 + 5757 + 710716 @@ -12314,57 +12360,57 @@ 1 2 - 2722 + 3841 - 53 - 56 - 2722 + 50 + 53 + 3841 - 110 - 112 - 2722 + 104 + 106 + 3841 - 165 - 172 - 2722 + 157 + 165 + 3841 - 224 - 242 - 2722 + 214 + 231 + 3841 - 305 - 330 - 2722 + 291 + 315 + 3841 - 524 - 666 - 2722 + 485 + 606 + 3841 - 880 - 1142 - 2722 + 804 + 1067 + 3841 - 1517 - 2090 - 2722 + 1445 + 2015 + 3841 - 3299 - 5949 - 2722 + 3084 + 5199 + 3841 - 15053 - 41322 - 2722 + 12689 + 33844 + 3841 @@ -12380,57 +12426,57 @@ 1 2 - 2722 + 3841 2 5 - 2722 + 3841 6 7 - 2722 + 3841 - 10 - 12 - 2722 + 11 + 14 + 3841 - 13 - 19 - 2722 + 15 + 20 + 3841 - 26 - 38 - 2722 + 27 + 37 + 3841 57 - 76 - 2722 + 75 + 3841 - 99 - 159 - 2722 + 97 + 153 + 3841 - 212 - 306 - 2722 + 201 + 289 + 3841 - 452 - 889 - 2722 + 403 + 777 + 3841 - 2370 - 6264 - 2722 + 1979 + 5089 + 3841 @@ -12446,57 +12492,57 @@ 1 2 - 2722 + 3841 - 53 - 56 - 2722 + 50 + 53 + 3841 - 110 - 112 - 2722 + 104 + 106 + 3841 - 165 - 172 - 2722 + 157 + 165 + 3841 - 224 - 242 - 2722 + 214 + 231 + 3841 - 305 - 330 - 2722 + 291 + 315 + 3841 - 524 - 666 - 2722 + 485 + 606 + 3841 - 880 - 1142 - 2722 + 804 + 1067 + 3841 - 1517 - 2090 - 2722 + 1445 + 2015 + 3841 - 3299 - 5949 - 2722 + 3084 + 5199 + 3841 - 15053 - 41322 - 2722 + 12689 + 33844 + 3841 @@ -12512,57 +12558,57 @@ 1 2 - 2722 + 3841 2 5 - 2722 + 3841 6 8 - 2722 + 3841 - 10 - 13 - 2722 + 11 + 15 + 3841 - 14 - 28 - 2722 + 16 + 29 + 3841 - 38 + 39 63 - 2722 + 3841 - 98 - 138 - 2722 + 101 + 144 + 3841 - 193 - 344 - 2722 + 210 + 386 + 3841 - 556 - 966 - 2722 + 628 + 1069 + 3841 - 1954 - 4172 - 2722 + 1955 + 3748 + 3841 - 10056 - 26381 - 2722 + 8555 + 21355 + 3841 @@ -12578,27 +12624,27 @@ 1 2 - 35759674 + 40633790 2 3 - 12394999 + 14389133 3 4 - 3606189 + 4060689 4 - 15 - 4258270 + 10 + 4992305 - 15 + 10 23 - 232789 + 931615 @@ -12614,17 +12660,17 @@ 1 2 - 39751122 + 45326442 2 3 - 12655015 + 14805959 3 23 - 3845785 + 4875132 @@ -12640,27 +12686,27 @@ 1 2 - 35759674 + 40633790 2 3 - 12394999 + 14389133 3 4 - 3606189 + 4060689 4 - 15 - 4258270 + 10 + 4992305 - 15 + 10 23 - 232789 + 931615 @@ -12676,27 +12722,27 @@ 1 2 - 35759674 + 40633790 2 3 - 12394999 + 14389133 3 4 - 3606189 + 4060689 4 - 15 - 4258270 + 10 + 4992305 - 15 + 10 23 - 232789 + 931615 @@ -12712,12 +12758,12 @@ 1 2 - 56891752 + 68584168 2 - 349 - 4418909 + 286 + 5055693 @@ -12733,12 +12779,12 @@ 1 2 - 59772347 + 71932220 2 - 349 - 1538314 + 286 + 1707641 @@ -12754,7 +12800,7 @@ 1 2 - 61310661 + 73639861 @@ -12770,12 +12816,12 @@ 1 2 - 56891752 + 68584168 2 - 349 - 4418909 + 286 + 5055693 @@ -12785,15 +12831,15 @@ paramsKotlinType - 101015498 + 120852585 id - 101015498 + 120852585 kttypeid - 1361 + 1920 @@ -12807,7 +12853,7 @@ 1 2 - 101015498 + 120852585 @@ -12821,9 +12867,9 @@ 12 - 74203 - 74204 - 1361 + 62916 + 62917 + 1920 @@ -12833,15 +12879,15 @@ paramName - 10331207 + 15639610 id - 10331207 + 15639610 nodeName - 1662195 + 2335761 @@ -12855,7 +12901,7 @@ 1 2 - 10331207 + 15639610 @@ -12871,37 +12917,37 @@ 1 2 - 717426 + 998845 2 3 - 328082 + 451401 3 4 - 174251 + 249711 4 5 - 129327 + 170956 5 - 9 - 137495 + 8 + 182481 - 9 - 25 - 130688 + 8 + 18 + 176718 - 25 - 517 - 44924 + 18 + 769 + 105647 @@ -12911,30 +12957,30 @@ isVarargsParam - 1003307 + 945061 param - 1003307 + 945061 exceptions - 1228169 + 1232644 id - 1228169 + 1232644 typeid - 36993 + 36990 parentid - 982877 + 987367 @@ -12948,7 +12994,7 @@ 1 2 - 1228169 + 1232644 @@ -12964,7 +13010,7 @@ 1 2 - 1228169 + 1232644 @@ -12980,7 +13026,7 @@ 1 2 - 11951 + 11950 2 @@ -13010,17 +13056,17 @@ 20 35 - 3414 - - - 49 - 107 2845 - 187 + 41 + 93 + 2845 + + + 106 813 - 1707 + 2276 @@ -13036,7 +13082,7 @@ 1 2 - 11951 + 11950 2 @@ -13066,17 +13112,17 @@ 20 35 - 3414 - - - 49 - 107 2845 - 187 + 41 + 93 + 2845 + + + 106 813 - 1707 + 2276 @@ -13092,12 +13138,12 @@ 1 2 - 750674 + 755179 2 3 - 224234 + 224220 3 @@ -13118,12 +13164,12 @@ 1 2 - 750674 + 755179 2 3 - 224234 + 224220 3 @@ -13138,41 +13184,41 @@ isAnnotType - 30058 + 29260 interfaceid - 30058 + 29260 isAnnotElem - 61062 + 61065 methodid - 61062 + 61065 annotValue - 1574849 + 1574925 parentid - 568147 + 568174 id2 - 52102 + 52104 value - 1574849 + 1574925 @@ -13186,32 +13232,32 @@ 1 2 - 153486 + 153493 2 3 - 252712 + 252724 3 4 - 48949 + 48951 4 6 - 26548 + 26550 6 7 - 35177 + 35179 7 9 - 46626 + 46628 9 @@ -13232,37 +13278,37 @@ 1 2 - 138054 + 138061 2 3 - 268144 + 268157 3 4 - 47290 + 47292 4 6 - 26051 + 26052 6 8 - 39657 + 39659 8 10 - 44137 + 44139 10 13 - 4811 + 4812 @@ -13278,22 +13324,22 @@ 1 2 - 17090 + 17091 2 3 - 5143 + 5144 3 4 - 2654 + 2655 4 6 - 4811 + 4812 6 @@ -13339,7 +13385,7 @@ 1 2 - 15265 + 15266 2 @@ -13364,7 +13410,7 @@ 8 10 - 4811 + 4812 10 @@ -13400,7 +13446,7 @@ 1 2 - 1574849 + 1574925 @@ -13416,7 +13462,7 @@ 1 2 - 1574849 + 1574925 @@ -13426,49 +13472,49 @@ isEnumType - 349864 + 397617 classid - 349864 + 397617 isEnumConst - 321905 + 3081053 fieldid - 321905 + 3081053 typeVars - 5105024 + 6288883 id - 5105024 + 6288883 nodeName - 70789 + 86438 pos - 5445 + 7683 kind - 1361 + 1920 parentid - 3715096 + 4444861 @@ -13482,7 +13528,7 @@ 1 2 - 5105024 + 6288883 @@ -13498,7 +13544,7 @@ 1 2 - 5105024 + 6288883 @@ -13514,7 +13560,7 @@ 1 2 - 5105024 + 6288883 @@ -13530,7 +13576,7 @@ 1 2 - 5105024 + 6288883 @@ -13546,47 +13592,47 @@ 1 2 - 20420 + 21129 2 3 - 10890 + 11525 3 4 - 6806 + 9604 4 7 - 5445 + 7683 7 10 - 5445 + 7683 10 28 - 5445 + 7683 - 37 - 71 - 5445 + 36 + 69 + 7683 71 - 253 - 5445 + 412 + 7683 - 459 - 951 - 5445 + 603 + 710 + 5762 @@ -13602,22 +13648,22 @@ 1 2 - 44924 + 51863 2 3 - 16336 + 23050 3 4 - 8168 + 9604 4 5 - 1361 + 1920 @@ -13633,7 +13679,7 @@ 1 2 - 70789 + 86438 @@ -13649,47 +13695,47 @@ 1 2 - 20420 + 21129 2 3 - 10890 + 11525 3 4 - 6806 + 9604 4 7 - 5445 + 7683 7 10 - 5445 + 7683 10 28 - 5445 + 7683 - 37 - 71 - 5445 + 36 + 69 + 7683 71 - 253 - 5445 + 412 + 7683 - 459 - 951 - 5445 + 603 + 710 + 5762 @@ -13705,22 +13751,22 @@ 6 7 - 1361 + 1920 - 94 - 95 - 1361 + 89 + 90 + 1920 - 921 - 922 - 1361 + 865 + 866 + 1920 - 2729 - 2730 - 1361 + 2314 + 2315 + 1920 @@ -13736,22 +13782,22 @@ 2 3 - 1361 + 1920 13 14 - 1361 + 1920 - 23 - 24 - 1361 + 21 + 22 + 1920 - 41 - 42 - 1361 + 34 + 35 + 1920 @@ -13767,7 +13813,7 @@ 1 2 - 5445 + 7683 @@ -13783,22 +13829,22 @@ 6 7 - 1361 + 1920 - 94 - 95 - 1361 + 89 + 90 + 1920 - 921 - 922 - 1361 + 865 + 866 + 1920 - 2729 - 2730 - 1361 + 2314 + 2315 + 1920 @@ -13812,9 +13858,9 @@ 12 - 3750 - 3751 - 1361 + 3274 + 3275 + 1920 @@ -13828,9 +13874,9 @@ 12 - 52 - 53 - 1361 + 45 + 46 + 1920 @@ -13846,7 +13892,7 @@ 4 5 - 1361 + 1920 @@ -13860,9 +13906,9 @@ 12 - 2729 - 2730 - 1361 + 2314 + 2315 + 1920 @@ -13878,17 +13924,17 @@ 1 2 - 2461302 + 2783320 2 3 - 1125828 + 1490584 3 5 - 127965 + 170956 @@ -13904,17 +13950,17 @@ 1 2 - 2461302 + 2783320 2 3 - 1125828 + 1490584 3 5 - 127965 + 170956 @@ -13930,17 +13976,17 @@ 1 2 - 2461302 + 2783320 2 3 - 1125828 + 1490584 3 5 - 127965 + 170956 @@ -13956,7 +14002,7 @@ 1 2 - 3715096 + 4444861 @@ -13966,19 +14012,19 @@ wildcards - 3629331 + 3338447 id - 3629331 + 3338447 nodeName - 980164 + 533998 kind - 2722 + 3841 @@ -13992,7 +14038,7 @@ 1 2 - 3629331 + 3338447 @@ -14008,7 +14054,7 @@ 1 2 - 3629331 + 3338447 @@ -14024,17 +14070,22 @@ 1 2 - 789577 + 397617 2 3 - 119797 + 55704 3 - 214 - 70789 + 7 + 44179 + + + 7 + 170 + 36496 @@ -14050,7 +14101,7 @@ 1 2 - 980164 + 533998 @@ -14064,14 +14115,14 @@ 12 - 1027 - 1028 - 1361 + 791 + 792 + 1920 - 1639 - 1640 - 1361 + 947 + 948 + 1920 @@ -14085,14 +14136,14 @@ 12 - 222 - 223 - 1361 + 91 + 92 + 1920 - 498 - 499 - 1361 + 187 + 188 + 1920 @@ -14102,23 +14153,23 @@ typeBounds - 4383514 + 4229725 id - 4383514 + 4229725 typeid - 3184173 + 2852471 pos - 1361 + 1920 parentid - 4383514 + 4229725 @@ -14132,7 +14183,7 @@ 1 2 - 4383514 + 4229725 @@ -14148,7 +14199,7 @@ 1 2 - 4383514 + 4229725 @@ -14164,7 +14215,7 @@ 1 2 - 4383514 + 4229725 @@ -14180,17 +14231,17 @@ 1 2 - 2506226 + 2091812 2 3 - 601712 + 695349 3 52 - 76235 + 65309 @@ -14206,7 +14257,7 @@ 1 2 - 3184173 + 2852471 @@ -14222,17 +14273,17 @@ 1 2 - 2506226 + 2091812 2 3 - 601712 + 695349 3 52 - 76235 + 65309 @@ -14246,9 +14297,9 @@ 12 - 3220 - 3221 - 1361 + 2202 + 2203 + 1920 @@ -14262,9 +14313,9 @@ 12 - 2339 - 2340 - 1361 + 1485 + 1486 + 1920 @@ -14278,9 +14329,9 @@ 12 - 3220 - 3221 - 1361 + 2202 + 2203 + 1920 @@ -14296,7 +14347,7 @@ 1 2 - 4383514 + 4229725 @@ -14312,7 +14363,7 @@ 1 2 - 4383514 + 4229725 @@ -14328,7 +14379,7 @@ 1 2 - 4383514 + 4229725 @@ -14338,11 +14389,11 @@ typeArgs - 53913162 + 53854237 argumentid - 1429292 + 1430551 pos @@ -14350,7 +14401,7 @@ parentid - 22268245 + 22244248 @@ -14364,17 +14415,17 @@ 1 2 - 866127 + 865848 2 3 - 469332 + 470615 3 11 - 93832 + 94087 @@ -14390,57 +14441,57 @@ 1 2 - 62430 + 64071 2 3 - 435425 + 433698 3 5 - 100353 + 100595 5 6 - 35320 + 35547 6 7 - 201035 + 201249 7 11 - 37958 + 39437 11 12 - 218221 + 218178 12 15 - 111144 + 111421 15 29 - 108553 + 108138 29 - 324 - 107243 + 341 + 107450 - 324 - 762773 - 11606 + 341 + 757580 + 10762 @@ -14459,48 +14510,48 @@ 5 - 598 - 599 + 597 + 598 5 - 889 - 890 + 887 + 888 5 - 1132 - 1133 + 1129 + 1130 5 - 1762 - 1763 + 1758 + 1759 5 - 3890 - 3891 + 3885 + 3886 5 - 4033 - 4034 + 4027 + 4028 5 - 51900 - 51901 + 51686 + 51687 5 - 143023 - 143024 + 142042 + 142043 5 - 161995 - 161996 + 161580 + 161581 5 @@ -14525,43 +14576,43 @@ 5 - 3896 - 3897 + 3895 + 3896 5 - 8697 - 8698 + 8694 + 8695 5 - 19018 - 19019 + 19012 + 19013 5 - 85642 - 85643 + 85622 + 85623 5 - 103285 - 103286 + 103257 + 103258 5 - 1458897 - 1458898 + 1447294 + 1447295 5 - 3827033 - 3827034 + 3800219 + 3800220 5 - 3875440 - 3875441 + 3848466 + 3848467 5 @@ -14578,22 +14629,22 @@ 1 2 - 295332 + 296162 2 3 - 13673753 + 13666793 3 4 - 7771091 + 7750153 4 11 - 528068 + 531138 @@ -14609,22 +14660,22 @@ 1 2 - 278146 + 278869 2 3 - 13607289 + 13599976 3 4 - 7789335 + 7768574 4 11 - 593474 + 596828 @@ -14634,37 +14685,37 @@ isParameterized - 25111274 + 27045654 memberid - 25111274 + 27045654 isRaw - 641191 + 731846 memberid - 641191 + 731846 erasure - 25752465 + 27777500 memberid - 25752465 + 27777500 erasureid - 865812 + 954665 @@ -14678,7 +14729,7 @@ 1 2 - 25752465 + 27777500 @@ -14694,57 +14745,62 @@ 1 2 - 144302 + 142143 2 3 - 133411 + 138301 3 4 - 88487 + 86438 4 5 - 54453 + 57625 5 6 - 50369 + 65309 6 8 - 63982 + 69150 8 - 11 - 78957 + 10 + 61467 - 11 - 19 - 70789 + 10 + 15 + 72992 - 19 - 33 - 70789 + 15 + 22 + 76834 - 33 - 93 - 65344 + 22 + 44 + 74913 - 97 - 1848 - 44924 + 46 + 124 + 72992 + + + 169 + 1564 + 36496 @@ -14754,15 +14810,15 @@ isAnonymClass - 192667 + 174213 classid - 192667 + 174213 parent - 192667 + 174213 @@ -14776,7 +14832,7 @@ 1 2 - 192667 + 174213 @@ -14792,7 +14848,7 @@ 1 2 - 192667 + 174213 @@ -14802,15 +14858,15 @@ isLocalClassOrInterface - 4057 + 3841 typeid - 4057 + 3841 parent - 4057 + 3841 @@ -14824,7 +14880,7 @@ 1 2 - 4057 + 3841 @@ -14840,7 +14896,7 @@ 1 2 - 4057 + 3841 @@ -14850,26 +14906,26 @@ isDefConstr - 139100 + 139383 constructorid - 139100 + 139383 lambdaKind - 183936 + 167982 exprId - 183936 + 167982 bodyKind - 15 + 13 @@ -14883,7 +14939,7 @@ 1 2 - 183936 + 167982 @@ -14897,9 +14953,9 @@ 12 - 11651 - 11652 - 15 + 12267 + 12268 + 13 @@ -14909,27 +14965,27 @@ arrays - 1116298 + 1375332 id - 1116298 + 1375332 nodeName - 687476 + 831730 elementtypeid - 1109491 + 1365728 dimension - 2722 + 3841 componenttypeid - 1116298 + 1375332 @@ -14943,7 +14999,7 @@ 1 2 - 1116298 + 1375332 @@ -14959,7 +15015,7 @@ 1 2 - 1116298 + 1375332 @@ -14975,7 +15031,7 @@ 1 2 - 1116298 + 1375332 @@ -14991,7 +15047,7 @@ 1 2 - 1116298 + 1375332 @@ -15007,17 +15063,17 @@ 1 2 - 562233 + 664616 2 3 - 99377 + 140222 3 - 95 - 25865 + 87 + 26891 @@ -15033,17 +15089,17 @@ 1 2 - 562233 + 664616 2 3 - 99377 + 140222 3 - 95 - 25865 + 87 + 26891 @@ -15059,7 +15115,7 @@ 1 2 - 687476 + 831730 @@ -15075,17 +15131,17 @@ 1 2 - 562233 + 664616 2 3 - 99377 + 140222 3 - 95 - 25865 + 87 + 26891 @@ -15101,12 +15157,12 @@ 1 2 - 1102685 + 1356124 2 3 - 6806 + 9604 @@ -15122,12 +15178,12 @@ 1 2 - 1102685 + 1356124 2 3 - 6806 + 9604 @@ -15143,12 +15199,12 @@ 1 2 - 1102685 + 1356124 2 3 - 6806 + 9604 @@ -15164,12 +15220,12 @@ 1 2 - 1102685 + 1356124 2 3 - 6806 + 9604 @@ -15185,12 +15241,12 @@ 5 6 - 1361 + 1920 - 815 - 816 - 1361 + 711 + 712 + 1920 @@ -15206,12 +15262,12 @@ 5 6 - 1361 + 1920 - 500 - 501 - 1361 + 428 + 429 + 1920 @@ -15227,12 +15283,12 @@ 5 6 - 1361 + 1920 - 815 - 816 - 1361 + 711 + 712 + 1920 @@ -15248,12 +15304,12 @@ 5 6 - 1361 + 1920 - 815 - 816 - 1361 + 711 + 712 + 1920 @@ -15269,7 +15325,7 @@ 1 2 - 1116298 + 1375332 @@ -15285,7 +15341,7 @@ 1 2 - 1116298 + 1375332 @@ -15301,7 +15357,7 @@ 1 2 - 1116298 + 1375332 @@ -15317,7 +15373,7 @@ 1 2 - 1116298 + 1375332 @@ -15327,15 +15383,15 @@ enclInReftype - 3410156 + 4051085 child - 3410156 + 4051085 parent - 929795 + 1125621 @@ -15349,7 +15405,7 @@ 1 2 - 3410156 + 4051085 @@ -15365,32 +15421,32 @@ 1 2 - 551342 + 666537 2 3 - 148386 + 176718 3 4 - 70789 + 86438 4 - 7 - 81680 + 6 + 82596 - 7 - 51 - 70789 + 6 + 17 + 84517 - 54 - 279 - 6806 + 17 + 265 + 28812 @@ -15400,15 +15456,15 @@ extendsReftype - 47868792 + 34389087 id1 - 34023966 + 33104034 id2 - 14017716 + 13251986 @@ -15422,22 +15478,12 @@ 1 2 - 26145892 + 32118635 2 - 3 - 3141972 - - - 3 - 4 - 3633415 - - - 4 10 - 1102685 + 985399 @@ -15453,17 +15499,17 @@ 1 2 - 11930782 + 12030322 2 - 3 - 1425322 + 5 + 1023816 - 3 - 12285 - 661611 + 5 + 8715 + 197848 @@ -15473,15 +15519,15 @@ implInterface - 3048147 + 14423708 id1 - 756277 + 8255839 id2 - 2271707 + 4487119 @@ -15495,37 +15541,27 @@ 1 2 - 209615 + 4223962 2 3 - 50204 + 2829421 3 4 - 67386 + 276603 4 5 - 61962 + 920090 5 - 6 - 19294 - - - 6 7 - 305429 - - - 7 - 10 - 42384 + 5762 @@ -15541,12 +15577,17 @@ 1 2 - 2196440 + 4003064 2 - 63781 - 75267 + 4 + 366883 + + + 4 + 2275 + 117172 @@ -15556,15 +15597,15 @@ permits - 177 + 129 id1 - 43 + 31 id2 - 177 + 129 @@ -15578,17 +15619,17 @@ 1 2 - 1 + 2 2 3 - 13 + 8 3 4 - 9 + 6 4 @@ -15598,25 +15639,20 @@ 5 6 - 5 + 2 6 - 7 - 4 - - - 7 8 2 8 9 - 1 + 2 - 10 + 9 11 2 @@ -15634,7 +15670,7 @@ 1 2 - 177 + 129 @@ -15644,15 +15680,15 @@ hasModifier - 249133355 + 270713939 id1 - 166385675 + 180180147 id2 - 13613 + 26891 @@ -15666,17 +15702,17 @@ 1 2 - 84119910 + 90230296 2 3 - 81783851 + 89365911 3 4 - 481914 + 583940 @@ -15690,54 +15726,74 @@ 12 - 31 - 32 - 1361 + 4 + 5 + 1920 + + + 14 + 15 + 1920 + + + 20 + 21 + 1920 + + + 21 + 22 + 1920 34 35 - 1361 + 1920 + + + 50 + 51 + 1920 109 110 - 1361 + 1920 - 267 - 268 - 1361 + 219 + 220 + 1920 - 500 - 501 - 1361 + 3864 + 3865 + 1920 - 8143 - 8144 - 1361 + 7193 + 7194 + 1920 - 18034 - 18035 - 1361 + 9195 + 9196 + 1920 - 18282 - 18283 - 1361 + 14706 + 14707 + 1920 - 20694 - 20695 - 1361 + 18810 + 18811 + 1920 - 116912 - 116913 - 1361 + 86695 + 86696 + 1920 @@ -15747,15 +15803,15 @@ imports - 368532 + 368550 id - 368532 + 368550 holder - 58075 + 58078 name @@ -15777,7 +15833,7 @@ 1 2 - 368532 + 368550 @@ -15793,7 +15849,7 @@ 1 2 - 368532 + 368550 @@ -15809,7 +15865,7 @@ 1 2 - 368532 + 368550 @@ -15825,7 +15881,7 @@ 1 2 - 28374 + 28375 2 @@ -15871,7 +15927,7 @@ 1 2 - 54591 + 54593 2 @@ -15892,7 +15948,7 @@ 1 2 - 55089 + 55091 2 @@ -15954,7 +16010,7 @@ 1 2 - 7300 + 7301 2 @@ -16078,27 +16134,27 @@ stmts - 2530730 + 2441387 id - 2530730 + 2441387 kind - 13613 + 9674 parent - 1783355 + 1353860 idx - 216453 + 15934 bodydecl - 703812 + 367630 @@ -16112,7 +16168,7 @@ 1 2 - 2530730 + 2441387 @@ -16128,7 +16184,7 @@ 1 2 - 2530730 + 2441387 @@ -16144,7 +16200,7 @@ 1 2 - 2530730 + 2441387 @@ -16160,7 +16216,7 @@ 1 2 - 2530730 + 2441387 @@ -16169,57 +16225,6 @@ kind id - - - 12 - - - 2 - 3 - 4084 - - - 4 - 5 - 1361 - - - 72 - 73 - 1361 - - - 96 - 97 - 1361 - - - 162 - 163 - 1361 - - - 373 - 374 - 1361 - - - 525 - 526 - 1361 - - - 621 - 622 - 1361 - - - - - - - kind - parent 12 @@ -16227,88 +16232,224 @@ 1 2 - 1361 - - - 2 - 3 - 2722 - - - 4 - 5 - 1361 - - - 53 - 54 - 1361 - - - 72 - 73 - 1361 - - - 98 - 99 - 1361 - - - 233 - 234 - 1361 - - - 373 - 374 - 1361 - - - 621 - 622 - 1361 - - - - - - - kind - idx - - - 12 - - - 1 - 2 - 5445 - - - 2 - 3 - 1361 - - - 5 - 6 - 1361 + 1707 6 7 - 1361 + 569 7 8 - 2722 + 569 - 158 - 159 - 1361 + 17 + 18 + 569 + + + 20 + 21 + 569 + + + 23 + 24 + 569 + + + 33 + 34 + 569 + + + 83 + 84 + 569 + + + 91 + 92 + 569 + + + 97 + 98 + 569 + + + 265 + 266 + 569 + + + 312 + 313 + 569 + + + 560 + 561 + 569 + + + 1243 + 1244 + 569 + + + 1530 + 1531 + 569 + + + + + + + kind + parent + + + 12 + + + 1 + 2 + 2276 + + + 7 + 8 + 569 + + + 12 + 13 + 569 + + + 17 + 18 + 569 + + + 21 + 22 + 569 + + + 33 + 34 + 569 + + + 71 + 72 + 569 + + + 81 + 82 + 569 + + + 91 + 92 + 569 + + + 246 + 247 + 569 + + + 265 + 266 + 569 + + + 271 + 272 + 569 + + + 716 + 717 + 569 + + + 1192 + 1193 + 569 + + + + + + + kind + idx + + + 12 + + + 1 + 2 + 2276 + + + 3 + 4 + 569 + + + 4 + 5 + 569 + + + 6 + 7 + 1138 + + + 7 + 8 + 569 + + + 8 + 9 + 1138 + + + 10 + 11 + 1138 + + + 13 + 14 + 569 + + + 17 + 18 + 569 + + + 21 + 22 + 569 + + + 26 + 27 + 569 @@ -16324,42 +16465,67 @@ 1 2 - 1361 + 2276 - 2 - 3 - 4084 + 7 + 8 + 1138 - 25 - 26 - 1361 + 17 + 18 + 569 - 71 - 72 - 1361 + 20 + 21 + 569 - 72 - 73 - 1361 + 21 + 22 + 569 + + + 53 + 54 + 569 + + + 54 + 55 + 569 + + + 91 + 92 + 569 119 120 - 1361 + 569 - 371 - 372 - 1361 + 179 + 180 + 569 - 517 - 518 - 1361 + 211 + 212 + 569 + + + 431 + 432 + 569 + + + 646 + 647 + 569 @@ -16375,17 +16541,22 @@ 1 2 - 1501557 + 989074 2 3 - 198755 + 191782 3 - 159 - 83041 + 6 + 107557 + + + 6 + 27 + 65445 @@ -16401,17 +16572,17 @@ 1 2 - 1587322 + 1081267 2 3 - 189226 + 194058 3 - 4 - 6806 + 6 + 78534 @@ -16427,17 +16598,22 @@ 1 2 - 1501557 + 989074 2 3 - 198755 + 191782 3 - 159 - 83041 + 6 + 107557 + + + 6 + 27 + 65445 @@ -16453,7 +16629,7 @@ 1 2 - 1783355 + 1353860 @@ -16466,25 +16642,70 @@ 12 - - 1 - 2 - 160638 - - - 2 - 3 - 34033 - 3 - 24 - 16336 + 5 + 1138 - 34 - 1213 - 5445 + 5 + 6 + 1138 + + + 6 + 7 + 2276 + + + 10 + 15 + 1138 + + + 15 + 16 + 1138 + + + 17 + 20 + 1138 + + + 24 + 32 + 1138 + + + 40 + 43 + 1138 + + + 55 + 72 + 1138 + + + 83 + 94 + 1138 + + + 115 + 160 + 1138 + + + 204 + 386 + 1138 + + + 939 + 1919 + 1138 @@ -16500,157 +16721,332 @@ 1 2 - 204200 - - - 2 - 9 - 12252 - - - - - - - idx - parent - - - 12 - - - 1 - 2 - 160638 + 2276 2 3 - 34033 + 3983 3 - 24 - 16336 + 5 + 1138 - 34 - 1213 - 5445 - - - - - - - idx - bodydecl - - - 12 - - - 1 - 2 - 160638 + 5 + 6 + 2276 - 2 - 3 - 34033 - - - 3 - 19 - 16336 - - - 29 - 518 - 5445 - - - - - - - bodydecl - id - - - 12 - - - 2 - 3 - 544535 - - - 3 - 4 - 58537 - - - 4 + 6 7 - 53092 + 2276 7 - 162 - 47646 - - - - - - - bodydecl - kind - - - 12 - - - 2 - 3 - 575846 - - - 3 - 4 - 81680 - - - 4 - 7 - 46285 - - - - - - - bodydecl - parent - - - 12 - - - 2 - 3 - 630300 - - - 3 - 8 - 57176 + 9 + 1138 9 - 47 - 16336 + 10 + 1138 + + + 12 + 14 + 1138 + + + 16 + 17 + 569 + + + + + + + idx + parent + + + 12 + + + 3 + 5 + 1138 + + + 5 + 6 + 1138 + + + 6 + 7 + 2276 + + + 10 + 15 + 1138 + + + 15 + 16 + 1138 + + + 17 + 20 + 1138 + + + 24 + 32 + 1138 + + + 40 + 43 + 1138 + + + 55 + 72 + 1138 + + + 83 + 94 + 1138 + + + 115 + 160 + 1138 + + + 204 + 386 + 1138 + + + 939 + 1919 + 1138 + + + + + + + idx + bodydecl + + + 12 + + + 3 + 5 + 1138 + + + 5 + 6 + 1138 + + + 6 + 7 + 2276 + + + 10 + 15 + 1138 + + + 15 + 16 + 1138 + + + 17 + 20 + 1138 + + + 24 + 32 + 1138 + + + 40 + 43 + 1138 + + + 54 + 56 + 1138 + + + 68 + 87 + 1138 + + + 104 + 138 + 1138 + + + 167 + 226 + 1138 + + + 337 + 647 + 1138 + + + + + + + bodydecl + id + + + 12 + + + 1 + 2 + 17641 + + + 2 + 3 + 157637 + + + 3 + 4 + 38128 + + + 4 + 5 + 33576 + + + 5 + 7 + 24470 + + + 7 + 10 + 29023 + + + 10 + 16 + 30730 + + + 16 + 34 + 27885 + + + 34 + 131 + 8536 + + + + + + + bodydecl + kind + + + 12 + + + 1 + 2 + 17641 + + + 2 + 3 + 193489 + + + 3 + 4 + 77965 + + + 4 + 5 + 29592 + + + 5 + 7 + 33007 + + + 7 + 11 + 15934 + + + + + + + bodydecl + parent + + + 12 + + + 1 + 2 + 17641 + + + 2 + 3 + 261780 + + + 4 + 5 + 33576 + + + 5 + 10 + 31299 + + + 10 + 88 + 23332 @@ -16666,22 +17062,37 @@ 1 2 - 544535 + 175279 2 3 - 92571 + 63737 3 + 4 + 27885 + + + 4 + 5 + 18210 + + + 5 7 - 54453 + 30161 7 - 159 - 12252 + 11 + 29592 + + + 11 + 28 + 22763 @@ -16691,11 +17102,11 @@ exprs - 7411134 + 7410663 id - 7411134 + 7410663 kind @@ -16703,11 +17114,11 @@ typeid - 115983 + 115976 parent - 5075960 + 5075638 idx @@ -16725,7 +17136,7 @@ 1 2 - 7411134 + 7410663 @@ -16741,7 +17152,7 @@ 1 2 - 7411134 + 7410663 @@ -16757,7 +17168,7 @@ 1 2 - 7411134 + 7410663 @@ -16773,7 +17184,7 @@ 1 2 - 7411134 + 7410663 @@ -17028,7 +17439,7 @@ 1 2 - 48884 + 48881 2 @@ -17038,7 +17449,7 @@ 3 6 - 10698 + 10697 6 @@ -17048,12 +17459,12 @@ 10 17 - 9272 + 9271 17 32 - 8723 + 8722 32 @@ -17079,32 +17490,32 @@ 1 2 - 57854 + 57851 2 3 - 18544 + 18543 3 4 - 8915 + 8914 4 5 - 14456 + 14455 5 6 - 9738 + 9737 6 32 - 6474 + 6473 @@ -17120,12 +17531,12 @@ 1 2 - 49048 + 49045 2 3 - 13414 + 13413 3 @@ -17135,7 +17546,7 @@ 5 8 - 8531 + 8530 8 @@ -17155,7 +17566,7 @@ 57 851 - 8723 + 8722 890 @@ -17176,22 +17587,22 @@ 1 2 - 58677 + 58673 2 3 - 18379 + 18378 3 4 - 14731 + 14730 4 5 - 19120 + 19119 5 @@ -17212,17 +17623,17 @@ 1 2 - 3222415 + 3222211 2 3 - 1522711 + 1522614 3 48 - 330833 + 330812 @@ -17238,17 +17649,17 @@ 1 2 - 3525515 + 3525291 2 3 - 1385549 + 1385461 3 8 - 164895 + 164884 @@ -17264,17 +17675,17 @@ 1 2 - 4085819 + 4085559 2 3 - 832130 + 832078 3 10 - 158009 + 157999 @@ -17290,17 +17701,17 @@ 1 2 - 3222415 + 3222211 2 3 - 1522711 + 1522614 3 48 - 330833 + 330812 @@ -17554,15 +17965,15 @@ exprsKotlinType - 7411134 + 7410663 id - 7411134 + 7410663 kttypeid - 12363 + 10930 @@ -17576,7 +17987,7 @@ 1 2 - 7411134 + 7410663 @@ -17592,17 +18003,17 @@ 1 2 - 9272 + 8197 2 3 - 2060 + 1821 - 7180 - 7181 - 1030 + 8123 + 8124 + 910 @@ -17612,15 +18023,15 @@ callableEnclosingExpr - 7299509 + 7299071 id - 7299509 + 7299071 callable_id - 19878 + 19877 @@ -17634,7 +18045,7 @@ 1 2 - 7299509 + 7299071 @@ -17705,7 +18116,7 @@ 73 177 - 1496 + 1495 179 @@ -17725,15 +18136,15 @@ statementEnclosingExpr - 7259150 + 7258714 id - 7259150 + 7258714 statement_id - 525810 + 525778 @@ -17747,7 +18158,7 @@ 1 2 - 7259150 + 7258714 @@ -17763,57 +18174,57 @@ 1 3 - 29127 + 29126 3 5 - 47080 + 47077 5 7 - 48477 + 48474 7 8 - 36044 + 36042 8 9 - 38147 + 38145 9 10 - 50450 + 50447 10 11 - 29214 + 29212 11 12 - 127057 + 127049 12 35 - 35324 + 35322 35 40 - 44626 + 44623 40 81 - 40224 + 40222 82 @@ -17828,11 +18239,11 @@ isParenthesized - 94658 + 94652 id - 94658 + 94652 parentheses @@ -17850,7 +18261,7 @@ 1 2 - 94658 + 94652 @@ -17881,37 +18292,37 @@ when_if - 83383 + 74334 id - 83383 + 74334 when_branch_else - 79912 + 76075 id - 79912 + 76075 callableBinding - 1832402 + 1832520 callerid - 1832402 + 1832520 callee - 263395 + 264311 @@ -17925,7 +18336,7 @@ 1 2 - 1832402 + 1832520 @@ -17941,32 +18352,32 @@ 1 2 - 162234 + 162993 2 3 - 33023 + 33137 3 4 - 16214 + 16271 4 7 - 22259 + 22271 7 20 - 19911 + 19902 20 46115 - 9751 + 9734 @@ -17976,15 +18387,15 @@ memberRefBinding - 23206 + 23208 id - 23206 + 23208 callable - 11196 + 11197 @@ -17998,7 +18409,7 @@ 1 2 - 23206 + 23208 @@ -18014,12 +18425,12 @@ 1 2 - 7861 + 7862 2 3 - 2074 + 2075 3 @@ -18039,15 +18450,15 @@ propertyRefGetBinding - 9639 + 8876 id - 9639 + 8876 getter - 5826 + 5366 @@ -18061,7 +18472,7 @@ 1 2 - 9639 + 8876 @@ -18077,17 +18488,17 @@ 1 2 - 2117 + 1951 2 3 - 3615 + 3328 3 6 - 94 + 86 @@ -18145,15 +18556,15 @@ propertyRefSetBinding - 2671 + 2600 id - 2671 + 2600 setter - 1335 + 1300 @@ -18167,7 +18578,7 @@ 1 2 - 2671 + 2600 @@ -18183,7 +18594,7 @@ 2 3 - 1335 + 1300 @@ -18193,15 +18604,15 @@ variableBinding - 2434432 + 2434277 expr - 2434432 + 2434277 variable - 572564 + 572528 @@ -18215,7 +18626,7 @@ 1 2 - 2434432 + 2434277 @@ -18231,37 +18642,37 @@ 1 2 - 205804 + 205791 2 3 - 120953 + 120945 3 4 - 85027 + 85022 4 5 - 45970 + 45967 5 7 - 40061 + 40059 7 14 - 43075 + 43072 14 464 - 31671 + 31669 @@ -18271,23 +18682,23 @@ localvars - 385297 + 385272 id - 385297 + 385272 nodeName - 140004 + 139995 typeid - 49513 + 49510 parentid - 385297 + 385272 @@ -18301,7 +18712,7 @@ 1 2 - 385297 + 385272 @@ -18317,7 +18728,7 @@ 1 2 - 385297 + 385272 @@ -18333,7 +18744,7 @@ 1 2 - 385297 + 385272 @@ -18349,22 +18760,22 @@ 1 2 - 83661 + 83655 2 3 - 26179 + 26178 3 5 - 10244 + 10243 5 9 - 11951 + 11950 9 @@ -18385,7 +18796,7 @@ 1 2 - 124638 + 124630 2 @@ -18411,22 +18822,22 @@ 1 2 - 83661 + 83655 2 3 - 26179 + 26178 3 5 - 10244 + 10243 5 9 - 11951 + 11950 9 @@ -18447,7 +18858,7 @@ 1 2 - 16504 + 16503 2 @@ -18462,7 +18873,7 @@ 5 6 - 5122 + 5121 6 @@ -18503,7 +18914,7 @@ 1 2 - 23334 + 23332 2 @@ -18513,7 +18924,7 @@ 3 4 - 6260 + 6259 4 @@ -18544,7 +18955,7 @@ 1 2 - 16504 + 16503 2 @@ -18559,7 +18970,7 @@ 5 6 - 5122 + 5121 6 @@ -18600,7 +19011,7 @@ 1 2 - 385297 + 385272 @@ -18616,7 +19027,7 @@ 1 2 - 385297 + 385272 @@ -18632,7 +19043,7 @@ 1 2 - 385297 + 385272 @@ -18642,15 +19053,15 @@ localvarsKotlinType - 227691 + 240107 id - 227691 + 240107 kttypeid - 154 + 1920 @@ -18664,7 +19075,7 @@ 1 2 - 227691 + 240107 @@ -18678,9 +19089,9 @@ 12 - 1470 - 1471 - 154 + 125 + 126 + 1920 @@ -18690,19 +19101,19 @@ namestrings - 4022677 + 4022436 name - 23386 + 23384 value - 22167 + 22166 parent - 4022677 + 4022436 @@ -18716,7 +19127,7 @@ 1 2 - 23386 + 23384 @@ -18732,7 +19143,7 @@ 1 2 - 9605 + 9604 2 @@ -18783,7 +19194,7 @@ 1 2 - 21560 + 21559 2 @@ -18804,7 +19215,7 @@ 1 2 - 9119 + 9118 2 @@ -18855,7 +19266,7 @@ 1 2 - 4022677 + 4022436 @@ -18871,7 +19282,7 @@ 1 2 - 4022677 + 4022436 @@ -18881,15 +19292,15 @@ modules - 7964 + 7965 id - 7964 + 7965 name - 7964 + 7965 @@ -18903,7 +19314,7 @@ 1 2 - 7964 + 7965 @@ -18919,7 +19330,7 @@ 1 2 - 7964 + 7965 @@ -18940,11 +19351,11 @@ cumodule - 247568 + 247580 fileId - 247568 + 247580 moduleId @@ -18962,7 +19373,7 @@ 1 2 - 247568 + 247580 @@ -19013,7 +19424,7 @@ directives - 50277 + 50279 id @@ -19021,7 +19432,7 @@ directive - 50277 + 50279 @@ -19081,7 +19492,7 @@ 1 2 - 50277 + 50279 @@ -19171,15 +19582,15 @@ exports - 35011 + 35013 id - 35011 + 35013 target - 35011 + 35013 @@ -19193,7 +19604,7 @@ 1 2 - 35011 + 35013 @@ -19209,7 +19620,7 @@ 1 2 - 35011 + 35013 @@ -19219,15 +19630,15 @@ exportsTo - 28706 + 28707 id - 12278 + 12279 target - 7466 + 7467 @@ -19241,7 +19652,7 @@ 1 2 - 7300 + 7301 2 @@ -19423,15 +19834,15 @@ uses - 10785 + 10786 id - 10785 + 10786 serviceInterface - 10785 + 10786 @@ -19445,7 +19856,7 @@ 1 2 - 10785 + 10786 @@ -19461,7 +19872,7 @@ 1 2 - 10785 + 10786 @@ -19519,7 +19930,7 @@ providesWith - 5309 + 5310 id @@ -19527,7 +19938,7 @@ serviceImpl - 5309 + 5310 @@ -19572,7 +19983,7 @@ 1 2 - 5309 + 5310 @@ -19582,48 +19993,48 @@ javadoc - 985153 + 985091 id - 985153 + 985091 isNormalComment - 649939 + 649898 commentid - 649939 + 649898 isEolComment - 610101 + 610062 commentid - 610101 + 610062 hasJavadoc - 435379 + 435352 documentableid - 368223 + 368199 javadocid - 435379 + 435352 @@ -19637,12 +20048,12 @@ 1 2 - 320416 + 320396 2 3 - 44960 + 44957 3 @@ -19663,7 +20074,7 @@ 1 2 - 435379 + 435352 @@ -19673,19 +20084,19 @@ javadocTag - 335830 + 335808 id - 335830 + 335808 name - 578 + 577 parentid - 114117 + 114110 idx @@ -19703,7 +20114,7 @@ 1 2 - 335830 + 335808 @@ -19719,7 +20130,7 @@ 1 2 - 335830 + 335808 @@ -19735,7 +20146,7 @@ 1 2 - 335830 + 335808 @@ -19884,37 +20295,37 @@ 1 2 - 33194 + 33192 2 3 - 24937 + 24935 3 4 - 18661 + 18660 4 5 - 13129 + 13128 5 6 - 9991 + 9990 6 7 - 7679 + 7678 7 11 - 6523 + 6522 @@ -19930,22 +20341,22 @@ 1 2 - 39966 + 39963 2 3 - 38644 + 38642 3 4 - 21139 + 21137 4 5 - 12221 + 12220 5 @@ -19966,37 +20377,37 @@ 1 2 - 33194 + 33192 2 3 - 24937 + 24935 3 4 - 18661 + 18660 4 5 - 13129 + 13128 5 6 - 9991 + 9990 6 7 - 7679 + 7678 7 11 - 6523 + 6522 @@ -20184,23 +20595,23 @@ javadocText - 2503007 + 2502848 id - 2503007 + 2502848 text - 1370450 + 1370363 parentid - 1169550 + 1169475 idx - 42115 + 42112 @@ -20214,7 +20625,7 @@ 1 2 - 2503007 + 2502848 @@ -20230,7 +20641,7 @@ 1 2 - 2503007 + 2502848 @@ -20246,7 +20657,7 @@ 1 2 - 2503007 + 2502848 @@ -20262,17 +20673,17 @@ 1 2 - 1139386 + 1139314 2 3 - 149679 + 149670 3 147 - 81384 + 81379 @@ -20288,17 +20699,17 @@ 1 2 - 1140524 + 1140452 2 3 - 149110 + 149101 3 88 - 80815 + 80810 @@ -20314,12 +20725,12 @@ 1 2 - 1346547 + 1346462 2 32 - 23903 + 23901 @@ -20335,22 +20746,22 @@ 1 2 - 870190 + 870135 2 3 - 159354 + 159344 3 12 - 83092 + 83086 12 75 - 56912 + 56908 @@ -20366,22 +20777,22 @@ 1 2 - 870190 + 870135 2 3 - 159354 + 159344 3 12 - 84230 + 84225 12 67 - 55774 + 55770 @@ -20397,22 +20808,22 @@ 1 2 - 870190 + 870135 2 3 - 159354 + 159344 3 12 - 83092 + 83086 12 75 - 56912 + 56908 @@ -20428,7 +20839,7 @@ 2 3 - 21057 + 21056 3 @@ -20484,7 +20895,7 @@ 2 3 - 20488 + 20487 3 @@ -20535,7 +20946,7 @@ 2 3 - 21057 + 21056 3 @@ -20580,15 +20991,15 @@ xmlEncoding - 800467 + 1129463 id - 800467 + 1129463 encoding - 1361 + 1920 @@ -20602,7 +21013,7 @@ 1 2 - 800467 + 1129463 @@ -20618,7 +21029,7 @@ 588 589 - 1361 + 1920 @@ -20976,27 +21387,27 @@ xmlElements - 106507143 + 150282022 id - 106507143 + 150282022 name - 337612 + 476372 parentid - 2747183 + 3876287 idx - 1207508 + 1703799 fileid - 800467 + 1129463 @@ -21010,7 +21421,7 @@ 1 2 - 106507143 + 150282022 @@ -21026,7 +21437,7 @@ 1 2 - 106507143 + 150282022 @@ -21042,7 +21453,7 @@ 1 2 - 106507143 + 150282022 @@ -21058,7 +21469,7 @@ 1 2 - 106507143 + 150282022 @@ -21074,57 +21485,57 @@ 1 2 - 106184 + 149826 2 3 - 40840 + 57625 3 4 - 16336 + 23050 4 6 - 29949 + 42258 6 8 - 24504 + 34575 8 9 - 12252 + 17287 9 10 - 23142 + 32654 10 18 - 28588 + 40337 18 48 - 25865 + 36496 52 250 - 25865 + 36496 342 73380 - 4084 + 5762 @@ -21140,52 +21551,52 @@ 1 2 - 123881 + 174797 2 3 - 46285 + 65309 3 4 - 17697 + 24971 4 5 - 14974 + 21129 5 6 - 19058 + 26891 6 8 - 28588 + 40337 8 10 - 28588 + 40337 10 21 - 27226 + 38417 22 128 - 25865 + 36496 130 229 - 5445 + 7683 @@ -21201,37 +21612,37 @@ 1 2 - 186503 + 263157 2 3 - 49008 + 69150 3 4 - 24504 + 34575 4 6 - 20420 + 28812 6 9 - 20420 + 28812 9 38 - 25865 + 36496 45 888 - 10890 + 15366 @@ -21247,42 +21658,42 @@ 1 2 - 183780 + 259315 2 3 - 36756 + 51863 3 4 - 17697 + 24971 4 5 - 13613 + 19208 5 7 - 29949 + 42258 7 16 - 25865 + 36496 17 114 - 27226 + 38417 118 131 - 2722 + 3841 @@ -21298,32 +21709,32 @@ 1 2 - 1671725 + 2358811 2 3 - 428822 + 605069 3 4 - 178335 + 251632 4 8 - 213730 + 301574 8 777 - 224621 + 316941 777 888 - 29949 + 42258 @@ -21339,17 +21750,17 @@ 1 2 - 2267992 + 3200146 2 3 - 291326 + 411063 3 17 - 187864 + 265078 @@ -21365,32 +21776,32 @@ 1 2 - 1671725 + 2358811 2 3 - 428822 + 605069 3 4 - 178335 + 251632 4 8 - 213730 + 301574 8 777 - 224621 + 316941 777 888 - 29949 + 42258 @@ -21406,7 +21817,7 @@ 1 2 - 2747183 + 3876287 @@ -21422,67 +21833,67 @@ 2 8 - 102100 + 144064 9 76 - 96655 + 136380 76 82 - 91209 + 128697 82 89 - 87125 + 122934 89 92 - 78957 + 111409 92 95 - 95293 + 134459 95 97 - 106184 + 149826 97 98 - 149747 + 211294 98 99 - 92571 + 130618 99 104 - 110268 + 155589 104 106 - 92571 + 130618 106 159 - 91209 + 128697 162 2019 - 13613 + 19208 @@ -21498,22 +21909,22 @@ 1 2 - 978803 + 1381095 2 5 - 89848 + 126776 5 9 - 103461 + 145985 9 150 - 35394 + 49942 @@ -21529,67 +21940,67 @@ 2 8 - 102100 + 144064 9 76 - 96655 + 136380 76 82 - 91209 + 128697 82 89 - 87125 + 122934 89 92 - 78957 + 111409 92 95 - 95293 + 134459 95 97 - 106184 + 149826 97 98 - 149747 + 211294 98 99 - 92571 + 130618 99 104 - 110268 + 155589 104 106 - 92571 + 130618 106 159 - 91209 + 128697 162 2019 - 13613 + 19208 @@ -21605,67 +22016,67 @@ 2 8 - 102100 + 144064 9 76 - 96655 + 136380 76 82 - 91209 + 128697 82 89 - 87125 + 122934 89 92 - 78957 + 111409 92 95 - 95293 + 134459 95 97 - 106184 + 149826 97 98 - 149747 + 211294 98 99 - 92571 + 130618 99 104 - 110268 + 155589 104 106 - 92571 + 130618 106 139 - 91209 + 128697 141 589 - 13613 + 19208 @@ -21681,57 +22092,57 @@ 1 2 - 58537 + 82596 2 3 - 134772 + 190164 3 4 - 176974 + 249711 4 5 - 74873 + 105647 5 7 - 59898 + 84517 7 10 - 66705 + 94121 10 31 - 62621 + 88359 35 694 - 61260 + 86438 738 776 - 20420 + 28812 777 779 - 65344 + 92201 788 889 - 19058 + 26891 @@ -21747,37 +22158,37 @@ 1 2 - 58537 + 82596 2 3 - 398872 + 562810 3 4 - 138856 + 195927 4 5 - 65344 + 92201 5 6 - 61260 + 86438 6 9 - 65344 + 92201 9 69 - 12252 + 17287 @@ -21793,27 +22204,27 @@ 1 2 - 58537 + 82596 2 3 - 567678 + 800997 3 4 - 57176 + 80675 4 6 - 58537 + 82596 6 165 - 58537 + 82596 @@ -21829,42 +22240,42 @@ 1 2 - 202839 + 286207 2 3 - 219175 + 309257 3 4 - 88487 + 124855 4 7 - 66705 + 94121 7 17 - 66705 + 94121 18 763 - 61260 + 86438 764 777 - 65344 + 92201 777 888 - 29949 + 42258 @@ -21874,31 +22285,31 @@ xmlAttrs - 129551904 + 182798274 id - 129551904 + 182798274 elementid - 105600491 + 149002731 name - 511863 + 722241 value - 8184375 + 11548187 idx - 31310 + 44179 fileid - 799106 + 1127542 @@ -21912,7 +22323,7 @@ 1 2 - 129551904 + 182798274 @@ -21928,7 +22339,7 @@ 1 2 - 129551904 + 182798274 @@ -21944,7 +22355,7 @@ 1 2 - 129551904 + 182798274 @@ -21960,7 +22371,7 @@ 1 2 - 129551904 + 182798274 @@ -21976,7 +22387,7 @@ 1 2 - 129551904 + 182798274 @@ -21992,17 +22403,17 @@ 1 2 - 96634707 + 136351973 2 6 - 7940695 + 11204353 6 24 - 1025088 + 1446404 @@ -22018,17 +22429,17 @@ 1 2 - 96634707 + 136351973 2 6 - 7954308 + 11223562 6 23 - 1011475 + 1427196 @@ -22044,17 +22455,17 @@ 1 2 - 96687799 + 136426886 2 6 - 7993787 + 11279267 6 21 - 918904 + 1296577 @@ -22070,17 +22481,17 @@ 1 2 - 96634707 + 136351973 2 6 - 7940695 + 11204353 6 24 - 1025088 + 1446404 @@ -22096,7 +22507,7 @@ 1 2 - 105600491 + 149002731 @@ -22112,62 +22523,62 @@ 1 2 - 106184 + 149826 2 3 - 55814 + 78755 3 4 - 31310 + 44179 4 5 - 17697 + 24971 5 6 - 29949 + 42258 6 8 - 36756 + 51863 8 11 - 42201 + 59546 11 22 - 39478 + 55704 23 38 - 40840 + 57625 38 79 - 40840 + 57625 81 168 - 39478 + 55704 168 74700 - 31310 + 44179 @@ -22183,62 +22594,62 @@ 1 2 - 106184 + 149826 2 3 - 55814 + 78755 3 4 - 31310 + 44179 4 5 - 17697 + 24971 5 6 - 29949 + 42258 6 8 - 36756 + 51863 8 11 - 46285 + 65309 11 25 - 43562 + 61467 25 39 - 42201 + 59546 43 91 - 40840 + 57625 91 227 - 39478 + 55704 227 74700 - 21781 + 30733 @@ -22254,42 +22665,42 @@ 1 2 - 215091 + 303495 2 3 - 80319 + 113330 3 4 - 34033 + 48021 4 5 - 36756 + 51863 5 9 - 42201 + 59546 9 21 - 39478 + 55704 22 64 - 42201 + 59546 68 2100 - 21781 + 30733 @@ -22305,37 +22716,37 @@ 1 2 - 201478 + 284286 2 3 - 95293 + 134459 3 4 - 49008 + 69150 4 5 - 54453 + 76834 5 7 - 32672 + 46100 7 10 - 40840 + 57625 10 21 - 38117 + 53783 @@ -22351,52 +22762,52 @@ 1 2 - 178335 + 251632 2 3 - 53092 + 74913 3 4 - 27226 + 38417 4 5 - 24504 + 34575 5 6 - 38117 + 53783 6 9 - 42201 + 59546 9 17 - 44924 + 63388 17 34 - 39478 + 55704 36 91 - 39478 + 55704 91 223 - 24504 + 34575 @@ -22412,37 +22823,37 @@ 1 2 - 4470639 + 6308091 2 3 - 1210231 + 1707641 3 5 - 627577 + 885514 5 31 - 616686 + 870147 31 91 - 643913 + 908564 91 1111 - 613964 + 866306 3397 3398 - 1361 + 1920 @@ -22458,32 +22869,32 @@ 1 2 - 4560488 + 6434868 2 3 - 1153054 + 1626965 3 5 - 635745 + 897039 5 33 - 645275 + 910485 33 93 - 631661 + 891277 93 3398 - 558149 + 787551 @@ -22499,17 +22910,17 @@ 1 2 - 7427470 + 10480191 2 4 - 658888 + 929694 4 53 - 98016 + 138301 @@ -22525,17 +22936,17 @@ 1 2 - 6778110 + 9563942 2 3 - 989694 + 1396462 3 20 - 416569 + 587781 @@ -22551,32 +22962,32 @@ 1 2 - 5268385 + 7433713 2 3 - 887593 + 1252398 3 10 - 635745 + 897039 10 83 - 622132 + 877831 83 99 - 624854 + 881672 99 182 - 145663 + 205531 @@ -22592,62 +23003,62 @@ 1 6 - 2722 + 3841 12 14 - 2722 + 3841 17 26 - 2722 + 3841 39 56 - 2722 + 3841 83 110 - 2722 + 3841 153 232 - 2722 + 3841 316 400 - 2722 + 3841 468 545 - 2722 + 3841 626 754 - 2722 + 3841 951 1491 - 2722 + 3841 4718 6587 - 2722 + 3841 77571 77572 - 1361 + 1920 @@ -22663,62 +23074,62 @@ 1 6 - 2722 + 3841 12 14 - 2722 + 3841 17 26 - 2722 + 3841 39 56 - 2722 + 3841 83 110 - 2722 + 3841 153 232 - 2722 + 3841 316 400 - 2722 + 3841 468 545 - 2722 + 3841 626 754 - 2722 + 3841 951 1491 - 2722 + 3841 4718 6587 - 2722 + 3841 77571 77572 - 1361 + 1920 @@ -22734,62 +23145,62 @@ 1 4 - 2722 + 3841 7 10 - 2722 + 3841 11 17 - 2722 + 3841 18 23 - 2722 + 3841 26 38 - 2722 + 3841 39 49 - 2722 + 3841 57 67 - 2722 + 3841 72 79 - 2722 + 3841 95 101 - 2722 + 3841 105 106 - 2722 + 3841 106 132 - 2722 + 3841 140 141 - 1361 + 1920 @@ -22805,62 +23216,62 @@ 1 5 - 2722 + 3841 7 10 - 2722 + 3841 11 18 - 2722 + 3841 22 32 - 2722 + 3841 46 63 - 2722 + 3841 85 119 - 2722 + 3841 142 185 - 2722 + 3841 212 228 - 2722 + 3841 253 275 - 2722 + 3841 307 423 - 2722 + 3841 580 1324 - 2722 + 3841 3579 3580 - 1361 + 1920 @@ -22876,62 +23287,62 @@ 1 6 - 2722 + 3841 7 8 - 2722 + 3841 10 19 - 2722 + 3841 23 36 - 2722 + 3841 45 59 - 2722 + 3841 73 97 - 2722 + 3841 115 131 - 2722 + 3841 140 148 - 2722 + 3841 168 181 - 2722 + 3841 248 363 - 2722 + 3841 473 530 - 2722 + 3841 587 588 - 1361 + 1920 @@ -22947,72 +23358,72 @@ 1 3 - 59898 + 84517 3 5 - 61260 + 86438 5 6 - 36756 + 51863 6 7 - 61260 + 86438 7 8 - 51730 + 72992 8 10 - 58537 + 82596 10 15 - 65344 + 92201 15 27 - 61260 + 86438 27 41 - 61260 + 86438 41 65 - 61260 + 86438 65 157 - 65344 + 92201 162 817 - 61260 + 86438 818 832 - 66705 + 94121 832 1187 - 27226 + 38417 @@ -23028,52 +23439,52 @@ 1 2 - 91209 + 128697 2 3 - 187864 + 265078 3 4 - 112991 + 159431 4 5 - 77596 + 109488 5 8 - 72151 + 101805 8 14 - 61260 + 86438 14 295 - 61260 + 86438 330 775 - 50369 + 71071 776 778 - 65344 + 92201 787 888 - 19058 + 26891 @@ -23089,62 +23500,62 @@ 1 2 - 50369 + 71071 2 3 - 65344 + 92201 3 4 - 50369 + 71071 4 5 - 66705 + 94121 5 6 - 121159 + 170956 6 7 - 114352 + 161351 7 8 - 50369 + 71071 8 12 - 61260 + 86438 12 18 - 69428 + 97963 18 24 - 68066 + 96042 24 37 - 62621 + 88359 37 55 - 19058 + 26891 @@ -23160,67 +23571,67 @@ 1 3 - 69428 + 97963 3 4 - 39478 + 55704 4 5 - 73512 + 103726 5 6 - 88487 + 124855 6 8 - 62621 + 88359 8 12 - 70789 + 99884 12 19 - 61260 + 86438 19 27 - 69428 + 97963 27 41 - 61260 + 86438 42 170 - 61260 + 86438 205 780 - 57176 + 80675 781 783 - 65344 + 92201 791 893 - 19058 + 26891 @@ -23236,47 +23647,47 @@ 1 2 - 78957 + 111409 2 3 - 76235 + 107567 3 4 - 151108 + 213215 4 5 - 155192 + 218977 5 6 - 92571 + 130618 6 10 - 68066 + 96042 10 12 - 46285 + 65309 12 15 - 69428 + 97963 15 24 - 61260 + 86438 @@ -23286,23 +23697,23 @@ xmlNs - 1283743 + 1811367 id - 8168 + 11525 prefixName - 9529 + 13445 URI - 8168 + 11525 fileid - 747375 + 1054550 @@ -23316,12 +23727,12 @@ 1 2 - 6806 + 9604 2 3 - 1361 + 1920 @@ -23337,7 +23748,7 @@ 1 2 - 8168 + 11525 @@ -23353,32 +23764,32 @@ 2 3 - 1361 + 1920 20 21 - 1361 + 1920 88 89 - 1361 + 1920 167 168 - 1361 + 1920 213 214 - 1361 + 1920 453 454 - 1361 + 1920 @@ -23394,7 +23805,7 @@ 1 2 - 9529 + 13445 @@ -23410,7 +23821,7 @@ 1 2 - 9529 + 13445 @@ -23426,37 +23837,37 @@ 1 2 - 1361 + 1920 2 3 - 1361 + 1920 20 21 - 1361 + 1920 88 89 - 1361 + 1920 166 167 - 1361 + 1920 213 214 - 1361 + 1920 453 454 - 1361 + 1920 @@ -23472,7 +23883,7 @@ 1 2 - 8168 + 11525 @@ -23488,12 +23899,12 @@ 1 2 - 6806 + 9604 2 3 - 1361 + 1920 @@ -23509,32 +23920,32 @@ 2 3 - 1361 + 1920 20 21 - 1361 + 1920 88 89 - 1361 + 1920 167 168 - 1361 + 1920 213 214 - 1361 + 1920 453 454 - 1361 + 1920 @@ -23550,17 +23961,17 @@ 1 2 - 333528 + 470609 2 3 - 291326 + 411063 3 4 - 122520 + 172877 @@ -23576,17 +23987,17 @@ 1 2 - 333528 + 470609 2 3 - 291326 + 411063 3 4 - 122520 + 172877 @@ -23602,17 +24013,17 @@ 1 2 - 333528 + 470609 2 3 - 291326 + 411063 3 4 - 122520 + 172877 @@ -23622,19 +24033,19 @@ xmlHasNs - 25896767 + 36540446 elementId - 25896767 + 36540446 nsId - 8168 + 11525 fileid - 743291 + 1048787 @@ -23648,7 +24059,7 @@ 1 2 - 25896767 + 36540446 @@ -23664,7 +24075,7 @@ 1 2 - 25896767 + 36540446 @@ -23680,32 +24091,32 @@ 13 14 - 1361 + 1920 84 85 - 1361 + 1920 2426 2427 - 1361 + 1920 2733 2734 - 1361 + 1920 3704 3705 - 1361 + 1920 10063 10064 - 1361 + 1920 @@ -23721,32 +24132,32 @@ 2 3 - 1361 + 1920 20 21 - 1361 + 1920 86 87 - 1361 + 1920 164 165 - 1361 + 1920 209 210 - 1361 + 1920 453 454 - 1361 + 1920 @@ -23762,77 +24173,77 @@ 1 3 - 44924 + 63388 3 5 - 62621 + 88359 5 6 - 34033 + 48021 6 7 - 65344 + 92201 7 8 - 49008 + 69150 8 10 - 61260 + 86438 10 15 - 65344 + 92201 15 25 - 55814 + 78755 25 36 - 57176 + 80675 36 49 - 58537 + 82596 49 54 - 14974 + 21129 54 55 - 58537 + 82596 55 81 - 57176 + 80675 81 298 - 55814 + 78755 298 833 - 2722 + 3841 @@ -23848,17 +24259,17 @@ 1 2 - 334889 + 472530 2 3 - 288604 + 407221 3 4 - 119797 + 169035 @@ -23868,23 +24279,23 @@ xmlComments - 107198704 + 151257816 id - 107198704 + 151257816 text - 1692145 + 2387624 parentid - 839946 + 1185168 fileid - 785493 + 1108333 @@ -23898,7 +24309,7 @@ 1 2 - 107198704 + 151257816 @@ -23914,7 +24325,7 @@ 1 2 - 107198704 + 151257816 @@ -23930,7 +24341,7 @@ 1 2 - 107198704 + 151257816 @@ -23946,67 +24357,67 @@ 1 2 - 232789 + 328466 2 7 - 138856 + 195927 7 32 - 140218 + 197848 32 61 - 127965 + 180560 61 76 - 127965 + 180560 76 84 - 136133 + 192085 84 90 - 125243 + 176718 90 94 - 111629 + 157510 94 95 - 59898 + 84517 95 96 - 100739 + 142143 96 98 - 140218 + 197848 98 100 - 126604 + 178639 100 460 - 123881 + 174797 @@ -24022,67 +24433,67 @@ 1 2 - 235511 + 332308 2 6 - 134772 + 190164 6 32 - 142940 + 201689 32 61 - 129327 + 182481 61 75 - 132049 + 186323 75 84 - 148386 + 209373 84 90 - 122520 + 172877 90 94 - 119797 + 169035 94 95 - 66705 + 94121 95 96 - 103461 + 145985 96 98 - 142940 + 201689 98 100 - 134772 + 190164 100 460 - 78957 + 111409 @@ -24098,67 +24509,67 @@ 1 2 - 246402 + 347674 2 7 - 133411 + 188243 7 32 - 133411 + 188243 32 61 - 129327 + 182481 61 75 - 132049 + 186323 75 84 - 148386 + 209373 84 90 - 122520 + 172877 90 94 - 119797 + 169035 94 95 - 66705 + 94121 95 96 - 103461 + 145985 96 98 - 142940 + 201689 98 100 - 134772 + 190164 100 460 - 78957 + 111409 @@ -24174,22 +24585,22 @@ 1 2 - 668417 + 943140 2 724 - 63982 + 90280 726 830 - 77596 + 109488 831 941 - 29949 + 42258 @@ -24205,27 +24616,27 @@ 1 2 - 668417 + 943140 2 697 - 63982 + 90280 697 795 - 34033 + 48021 795 827 - 63982 + 90280 838 899 - 9529 + 13445 @@ -24241,7 +24652,7 @@ 1 2 - 839946 + 1185168 @@ -24257,27 +24668,27 @@ 1 2 - 600350 + 847097 2 549 - 59898 + 84517 579 829 - 40840 + 57625 829 832 - 65344 + 92201 834 941 - 19058 + 26891 @@ -24293,27 +24704,27 @@ 1 2 - 600350 + 847097 2 536 - 59898 + 84517 560 795 - 51730 + 72992 795 812 - 59898 + 84517 819 899 - 13613 + 19208 @@ -24329,12 +24740,12 @@ 1 2 - 746014 + 1052629 2 6 - 39478 + 55704 @@ -24344,31 +24755,31 @@ xmlChars - 101302741 + 142938589 id - 101302741 + 142938589 text - 77797848 + 109773086 parentid - 101302741 + 142938589 idx - 1361 + 1920 isCDATA - 2722 + 3841 fileid - 176974 + 249711 @@ -24382,7 +24793,7 @@ 1 2 - 101302741 + 142938589 @@ -24398,7 +24809,7 @@ 1 2 - 101302741 + 142938589 @@ -24414,7 +24825,7 @@ 1 2 - 101302741 + 142938589 @@ -24430,7 +24841,7 @@ 1 2 - 101302741 + 142938589 @@ -24446,7 +24857,7 @@ 1 2 - 101302741 + 142938589 @@ -24462,17 +24873,17 @@ 1 2 - 66568156 + 93927944 2 3 - 6991841 + 9865517 3 128 - 4237850 + 5979625 @@ -24488,17 +24899,17 @@ 1 2 - 66568156 + 93927944 2 3 - 6991841 + 9865517 3 128 - 4237850 + 5979625 @@ -24514,7 +24925,7 @@ 1 2 - 77797848 + 109773086 @@ -24530,7 +24941,7 @@ 1 2 - 77797848 + 109773086 @@ -24546,12 +24957,12 @@ 1 2 - 74436700 + 105030493 2 76 - 3361148 + 4742593 @@ -24567,7 +24978,7 @@ 1 2 - 101302741 + 142938589 @@ -24583,7 +24994,7 @@ 1 2 - 101302741 + 142938589 @@ -24599,7 +25010,7 @@ 1 2 - 101302741 + 142938589 @@ -24615,7 +25026,7 @@ 1 2 - 101302741 + 142938589 @@ -24631,7 +25042,7 @@ 1 2 - 101302741 + 142938589 @@ -24647,7 +25058,7 @@ 74414 74415 - 1361 + 1920 @@ -24663,7 +25074,7 @@ 57148 57149 - 1361 + 1920 @@ -24679,7 +25090,7 @@ 74414 74415 - 1361 + 1920 @@ -24695,7 +25106,7 @@ 2 3 - 1361 + 1920 @@ -24711,7 +25122,7 @@ 130 131 - 1361 + 1920 @@ -24727,12 +25138,12 @@ 518 519 - 1361 + 1920 73896 73897 - 1361 + 1920 @@ -24748,12 +25159,12 @@ 492 493 - 1361 + 1920 56656 56657 - 1361 + 1920 @@ -24769,12 +25180,12 @@ 518 519 - 1361 + 1920 73896 73897 - 1361 + 1920 @@ -24790,7 +25201,7 @@ 1 2 - 2722 + 3841 @@ -24806,12 +25217,12 @@ 98 99 - 1361 + 1920 130 131 - 1361 + 1920 @@ -24827,57 +25238,57 @@ 1 2 - 14974 + 21129 2 23 - 13613 + 19208 24 243 - 13613 + 19208 294 566 - 13613 + 19208 610 686 - 13613 + 19208 691 764 - 13613 + 19208 765 775 - 13613 + 19208 775 776 - 4084 + 5762 776 777 - 49008 + 69150 777 803 - 13613 + 19208 807 888 - 13613 + 19208 @@ -24893,67 +25304,67 @@ 1 2 - 14974 + 21129 2 21 - 13613 + 19208 22 188 - 13613 + 19208 208 492 - 13613 + 19208 525 589 - 13613 + 19208 590 638 - 13613 + 19208 639 651 - 13613 + 19208 652 656 - 12252 + 17287 656 659 - 16336 + 23050 659 663 - 14974 + 21129 663 667 - 13613 + 19208 667 701 - 13613 + 19208 702 744 - 9529 + 13445 @@ -24969,57 +25380,57 @@ 1 2 - 14974 + 21129 2 23 - 13613 + 19208 24 243 - 13613 + 19208 294 566 - 13613 + 19208 610 686 - 13613 + 19208 691 764 - 13613 + 19208 765 775 - 13613 + 19208 775 776 - 4084 + 5762 776 777 - 49008 + 69150 777 803 - 13613 + 19208 807 888 - 13613 + 19208 @@ -25035,7 +25446,7 @@ 1 2 - 176974 + 249711 @@ -25051,12 +25462,12 @@ 1 2 - 43562 + 61467 2 3 - 133411 + 188243 @@ -25066,15 +25477,15 @@ xmllocations - 446644705 + 630217533 xmlElement - 445369130 + 628417691 location - 418533038 + 590551854 @@ -25088,12 +25499,12 @@ 1 2 - 445360961 + 628406166 2 454 - 8168 + 11525 @@ -25109,12 +25520,12 @@ 1 2 - 409045860 + 577165407 2 25 - 9487177 + 13386446 @@ -25355,19 +25766,19 @@ ktComments - 133411 + 188243 id - 133411 + 188243 kind - 4084 + 5762 text - 96655 + 136380 @@ -25381,7 +25792,7 @@ 1 2 - 133411 + 188243 @@ -25397,7 +25808,7 @@ 1 2 - 133411 + 188243 @@ -25413,17 +25824,17 @@ 16 17 - 1361 + 1920 22 23 - 1361 + 1920 60 61 - 1361 + 1920 @@ -25439,17 +25850,17 @@ 1 2 - 1361 + 1920 16 17 - 1361 + 1920 54 55 - 1361 + 1920 @@ -25465,12 +25876,12 @@ 1 2 - 92571 + 130618 4 23 - 4084 + 5762 @@ -25486,7 +25897,7 @@ 1 2 - 96655 + 136380 @@ -25496,19 +25907,19 @@ ktCommentSections - 59896 + 52611 id - 59896 + 52611 comment - 54765 + 48161 content - 50913 + 44765 @@ -25522,7 +25933,7 @@ 1 2 - 59896 + 52611 @@ -25538,7 +25949,7 @@ 1 2 - 59896 + 52611 @@ -25554,12 +25965,12 @@ 1 2 - 52697 + 46367 2 18 - 2068 + 1793 @@ -25575,12 +25986,12 @@ 1 2 - 52697 + 46367 2 18 - 2068 + 1793 @@ -25596,17 +26007,17 @@ 1 2 - 45040 + 39616 2 3 - 4909 + 4313 3 63 - 963 + 835 @@ -25622,17 +26033,17 @@ 1 2 - 45151 + 39712 2 3 - 4815 + 4231 3 56 - 947 + 821 @@ -25642,15 +26053,15 @@ ktCommentSectionNames - 5130 + 4450 id - 5130 + 4450 name - 15 + 13 @@ -25664,7 +26075,7 @@ 1 2 - 5130 + 4450 @@ -25680,7 +26091,7 @@ 325 326 - 15 + 13 @@ -25690,15 +26101,15 @@ ktCommentSectionSubjectNames - 5130 + 4450 id - 5130 + 4450 subjectname - 3362 + 2916 @@ -25712,7 +26123,7 @@ 1 2 - 5130 + 4450 @@ -25728,22 +26139,22 @@ 1 2 - 2557 + 2218 2 3 - 505 + 438 3 9 - 252 + 219 10 16 - 47 + 41 @@ -25753,15 +26164,15 @@ ktCommentOwners - 85377 + 75329 id - 54008 + 47914 owner - 83356 + 73508 @@ -25775,22 +26186,22 @@ 1 2 - 34510 + 30838 2 3 - 12361 + 10872 3 4 - 4641 + 4025 4 6 - 2494 + 2177 @@ -25806,12 +26217,12 @@ 1 2 - 81335 + 71701 2 - 3 - 2020 + 4 + 1807 @@ -25821,19 +26232,19 @@ ktExtensionFunctions - 702451 + 1206297 id - 702451 + 1206297 typeid - 84403 + 97963 kttypeid - 1361 + 1920 @@ -25847,7 +26258,7 @@ 1 2 - 702451 + 1206297 @@ -25863,7 +26274,7 @@ 1 2 - 702451 + 1206297 @@ -25879,37 +26290,37 @@ 1 2 - 53092 + 55704 2 3 - 5445 + 5762 3 4 - 2722 - - - 4 - 5 - 6806 + 3841 5 - 12 - 6806 + 6 + 13445 - 12 - 69 - 6806 + 7 + 16 + 7683 - 84 - 174 - 2722 + 20 + 87 + 7683 + + + 109 + 227 + 3841 @@ -25925,7 +26336,7 @@ 1 2 - 84403 + 97963 @@ -25939,9 +26350,9 @@ 12 - 516 - 517 - 1361 + 628 + 629 + 1920 @@ -25955,9 +26366,9 @@ 12 - 62 - 63 - 1361 + 51 + 52 + 1920 @@ -25967,15 +26378,15 @@ ktProperties - 30236718 + 21895839 id - 30236718 + 21895839 nodeName - 10667458 + 13542035 @@ -25989,7 +26400,7 @@ 1 2 - 30236718 + 21895839 @@ -26005,22 +26416,17 @@ 1 2 - 7868544 + 11824790 2 - 3 - 1212953 + 4 + 1142909 - 3 - 8 - 807274 - - - 8 - 554 - 778686 + 4 + 352 + 574335 @@ -26030,15 +26436,15 @@ ktPropertyGetters - 4557765 + 5985387 id - 4557765 + 5985387 getter - 4557765 + 5985387 @@ -26052,7 +26458,7 @@ 1 2 - 4557765 + 5985387 @@ -26068,7 +26474,7 @@ 1 2 - 4557765 + 5985387 @@ -26078,15 +26484,15 @@ ktPropertySetters - 264099 + 366883 id - 264099 + 366883 setter - 264099 + 366883 @@ -26100,7 +26506,7 @@ 1 2 - 264099 + 366883 @@ -26116,7 +26522,7 @@ 1 2 - 264099 + 366883 @@ -26126,15 +26532,15 @@ ktPropertyBackingFields - 23552540 + 14423708 id - 23552540 + 14423708 backingField - 23552540 + 14423708 @@ -26148,7 +26554,7 @@ 1 2 - 23552540 + 14423708 @@ -26164,7 +26570,7 @@ 1 2 - 23552540 + 14423708 @@ -26174,15 +26580,15 @@ ktSyntheticBody - 10303 + 9108 id - 10303 + 9108 kind - 2060 + 1821 @@ -26196,7 +26602,7 @@ 1 2 - 10303 + 9108 @@ -26212,7 +26618,7 @@ 5 6 - 2060 + 1821 @@ -26222,37 +26628,37 @@ ktLocalFunction - 2722 + 3841 id - 2722 + 3841 ktInitializerAssignment - 392065 + 199475 id - 392065 + 199475 ktPropertyDelegates - 5650 + 5201 id - 5650 + 5201 variableId - 5650 + 5201 @@ -26266,7 +26672,7 @@ 1 2 - 5650 + 5201 @@ -26282,7 +26688,7 @@ 1 2 - 5650 + 5201 @@ -26292,15 +26698,15 @@ compiler_generated - 533645 + 1467534 id - 533645 + 1467534 kind - 5445 + 13445 @@ -26314,7 +26720,7 @@ 1 2 - 533645 + 1467534 @@ -26328,24 +26734,39 @@ 12 - 2 - 3 - 1361 + 1 + 2 + 1920 8 9 - 1361 + 1920 + + + 38 + 39 + 1920 81 82 - 1361 + 1920 - 301 - 302 - 1361 + 85 + 86 + 1920 + + + 236 + 237 + 1920 + + + 315 + 316 + 1920 @@ -26355,15 +26776,15 @@ ktFunctionOriginalNames - 1215676 + 1586627 id - 1215676 + 1586627 name - 138856 + 186323 @@ -26377,7 +26798,7 @@ 1 2 - 1215676 + 1586627 @@ -26393,22 +26814,22 @@ 1 2 - 111629 + 147905 2 - 7 - 10890 + 4 + 13445 - 7 - 31 - 10890 + 6 + 16 + 15366 - 92 - 380 - 5445 + 22 + 339 + 9604 @@ -26418,11 +26839,11 @@ ktDataClasses - 80319 + 113330 id - 80319 + 113330 From fac839f481708075d8b27dd6f55debd3eff6ebd6 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Thu, 10 Nov 2022 17:31:31 +0000 Subject: [PATCH 121/796] Java/Kotlin: Add a changenote for Compilation.getInfo --- java/ql/lib/change-notes/2022-11-10-getInfo.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2022-11-10-getInfo.md diff --git a/java/ql/lib/change-notes/2022-11-10-getInfo.md b/java/ql/lib/change-notes/2022-11-10-getInfo.md new file mode 100644 index 00000000000..7a113ca3459 --- /dev/null +++ b/java/ql/lib/change-notes/2022-11-10-getInfo.md @@ -0,0 +1,4 @@ +--- +category: feature +--- +* The new `string Compilation.getInfo(string)` provides access to some information about compilations. From e00f87045e27e57660431de4dcd7c7786e73d74b Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Thu, 10 Nov 2022 20:31:13 +0000 Subject: [PATCH 122/796] Java: Add up/downgrade scripts --- .../old.dbscheme | 1246 +++++++++++++++++ .../semmlecode.dbscheme | 1240 ++++++++++++++++ .../upgrade.properties | 3 + .../old.dbscheme | 1240 ++++++++++++++++ .../semmlecode.dbscheme | 1246 +++++++++++++++++ .../upgrade.properties | 2 + 6 files changed, 4977 insertions(+) create mode 100644 java/downgrades/44d61b266bebf261cb027872646262e645efa059/old.dbscheme create mode 100644 java/downgrades/44d61b266bebf261cb027872646262e645efa059/semmlecode.dbscheme create mode 100644 java/downgrades/44d61b266bebf261cb027872646262e645efa059/upgrade.properties create mode 100644 java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/old.dbscheme create mode 100644 java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/semmlecode.dbscheme create mode 100644 java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/upgrade.properties diff --git a/java/downgrades/44d61b266bebf261cb027872646262e645efa059/old.dbscheme b/java/downgrades/44d61b266bebf261cb027872646262e645efa059/old.dbscheme new file mode 100644 index 00000000000..44d61b266be --- /dev/null +++ b/java/downgrades/44d61b266bebf261cb027872646262e645efa059/old.dbscheme @@ -0,0 +1,1246 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes( + unique int id: @class, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @class ref +); + +file_class( + int id: @class ref +); + +class_object( + unique int id: @class ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @class ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isRecord( + unique int id: @class ref +); + +interfaces( + unique int id: @interface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @interface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @interface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @class ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @class ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @interface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @class | @interface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterface = @interface | @class; +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @class | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @class | @interface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @class | @interface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @class ref +) diff --git a/java/downgrades/44d61b266bebf261cb027872646262e645efa059/semmlecode.dbscheme b/java/downgrades/44d61b266bebf261cb027872646262e645efa059/semmlecode.dbscheme new file mode 100644 index 00000000000..709f1d1fd04 --- /dev/null +++ b/java/downgrades/44d61b266bebf261cb027872646262e645efa059/semmlecode.dbscheme @@ -0,0 +1,1240 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes( + unique int id: @class, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @class ref +); + +file_class( + int id: @class ref +); + +class_object( + unique int id: @class ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @class ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isRecord( + unique int id: @class ref +); + +interfaces( + unique int id: @interface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @interface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @interface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @class ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @class ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @interface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @class | @interface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterface = @interface | @class; +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @class | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @class | @interface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @class | @interface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @class ref +) diff --git a/java/downgrades/44d61b266bebf261cb027872646262e645efa059/upgrade.properties b/java/downgrades/44d61b266bebf261cb027872646262e645efa059/upgrade.properties new file mode 100644 index 00000000000..8d5b41b6e56 --- /dev/null +++ b/java/downgrades/44d61b266bebf261cb027872646262e645efa059/upgrade.properties @@ -0,0 +1,3 @@ +description: Remove compilation_info +compatibility: full +compilation_info.rel: delete diff --git a/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/old.dbscheme b/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/old.dbscheme new file mode 100644 index 00000000000..709f1d1fd04 --- /dev/null +++ b/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/old.dbscheme @@ -0,0 +1,1240 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes( + unique int id: @class, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @class ref +); + +file_class( + int id: @class ref +); + +class_object( + unique int id: @class ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @class ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isRecord( + unique int id: @class ref +); + +interfaces( + unique int id: @interface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @interface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @interface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @class ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @class ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @interface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @class | @interface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterface = @interface | @class; +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @class | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @class | @interface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @class | @interface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @class ref +) diff --git a/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/semmlecode.dbscheme b/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/semmlecode.dbscheme new file mode 100644 index 00000000000..44d61b266be --- /dev/null +++ b/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/semmlecode.dbscheme @@ -0,0 +1,1246 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes( + unique int id: @class, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @class ref +); + +file_class( + int id: @class ref +); + +class_object( + unique int id: @class ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @class ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isRecord( + unique int id: @class ref +); + +interfaces( + unique int id: @interface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @interface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @interface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @class ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @class ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @interface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @class | @interface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterface = @interface | @class; +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @class | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @class | @interface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @class | @interface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @class ref +) diff --git a/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/upgrade.properties b/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/upgrade.properties new file mode 100644 index 00000000000..1c05ac39dbe --- /dev/null +++ b/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/upgrade.properties @@ -0,0 +1,2 @@ +description: Add compilation_info +compatibility: backwards From e25e192ef33b74ae388b1bbc593c1c5963c15ecf Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Thu, 10 Nov 2022 18:42:04 +1300 Subject: [PATCH 123/796] Ruby: Change the CFG for while clauses The `when` node now acts as a join point for patterns in the when clause, with match/no-match completions. This is similar to how `or` expressions work. The result of this is that the `when` clause "controls" the body of the `when`, which allows us to model barrier guards for multi-pattern when clauses. For this code case x when 1, 2 y end The old CFG was x --> when --> 1 --no-match--> 2 ---no-match---> case \ \ ^ \ \ | \ --match----+ | \ | | \ | | ------match---------> y --+ The new CFG is x --> 1 --no-match--> 2 --no-match--> [no-match] when --no-match--> case \ \ ^ \ \ | \ --match--> [match] when --match--> y -----+ \ / \ / -------match----- i.e. all patterns flow to the `when` node, which is split based on whether the pattern matched or not. The body of the when clause then has a single predecessor `[match] when`, which acts as condition block that controls `y`. --- .../lib/codeql/ruby/controlflow/CfgNodes.qll | 2 +- .../ruby/controlflow/internal/Completion.qll | 8 +- .../internal/ControlFlowGraphImpl.qll | 21 +++-- .../ruby/controlflow/internal/Splitting.qll | 7 ++ .../codeql/ruby/dataflow/BarrierGuards.qll | 2 +- .../controlflow/graph/Cfg.expected | 76 ++++++++++++------- .../dataflow/barrier-guards/barrier-guards.rb | 4 +- 7 files changed, 79 insertions(+), 41 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll b/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll index 4417891a66a..31898e0a652 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll @@ -446,7 +446,7 @@ module ExprNodes { final ExprCfgNode getBody() { e.hasCfgChild(e.getBody(), this, result) } /** Gets the `i`th pattern this `when`-clause. */ - final ExprCfgNode getPattern(int i) { e.hasCfgChild(e.getPattern(i), this, result) } + final ExprCfgNode getPattern(int i) { result.getExpr() = e.getPattern(i) } } /** A control-flow node that wraps a `CasePattern`. */ diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll index fe4cca24d69..d727b99d6cf 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll @@ -233,8 +233,12 @@ private predicate inMatchingContext(AstNode n) { or exists(CaseExpr c, WhenClause w | exists(c.getValue()) and - c.getABranch() = w and - w.getPattern(_) = n + ( + c.getABranch() = w and + w.getPattern(_) = n + or + w = n + ) ) or n instanceof CasePattern diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll index bdd67d2a693..1ca24d43ab8 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll @@ -400,7 +400,7 @@ module Trees { c instanceof SimpleCompletion or exists(int i, WhenTree branch | branch = this.getBranch(i) | - last(branch.getLastPattern(), pred, c) and + pred = branch and first(this.getBranch(i + 1), succ) and c.(ConditionalCompletion).getValue() = false ) @@ -1397,7 +1397,7 @@ module Trees { final override ControlFlowTree getChildElement(int i) { result = this.getMethodName(i) } } - private class WhenTree extends PreOrderTree, WhenClause { + private class WhenTree extends ControlFlowTree, WhenClause { final override predicate propagatesAbnormal(AstNode child) { child = this.getAPattern() } final Expr getLastPattern() { @@ -1407,17 +1407,21 @@ module Trees { ) } + final override predicate first(AstNode first) { first(this.getPattern(0), first) } + final override predicate last(AstNode last, Completion c) { - last(this.getLastPattern(), last, c) and + last = this and c.(ConditionalCompletion).getValue() = false or - last(this.getBody(), last, c) + last(this.getBody(), last, c) and + c instanceof NormalCompletion } final override predicate succ(AstNode pred, AstNode succ, Completion c) { pred = this and - first(this.getPattern(0), succ) and - c instanceof SimpleCompletion + c.isValidFor(this) and + c.(ConditionalCompletion).getValue() = true and + first(this.getBody(), succ) or exists(int i, Expr p, boolean b | p = this.getPattern(i) and @@ -1425,10 +1429,13 @@ module Trees { b = c.(ConditionalCompletion).getValue() | b = true and - first(this.getBody(), succ) + succ = this or b = false and first(this.getPattern(i + 1), succ) + or + not exists(this.getPattern(i + 1)) and + succ = this ) } } diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/Splitting.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/Splitting.qll index 9581b45a95e..5e24616ac4a 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/internal/Splitting.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/Splitting.qll @@ -85,7 +85,14 @@ private module ConditionalCompletionSplitting { or last(succ.(ConditionalExpr).getBranch(_), pred, c) and completion = c + or + last(succ.(WhenClause).getAPattern(), pred, c) and completion = c ) + or + succ(pred, succ, c) and + succ(succ, _, completion) and + succ instanceof WhenClause and + completion = c } override predicate hasEntryScope(CfgScope scope, AstNode succ) { none() } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll index b2827e53255..e80495ab2f3 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll @@ -186,8 +186,8 @@ private predicate stringConstCaseCompare( case.getValue() = testedNode and ( exists(CfgNodes::ExprNodes::WhenClauseCfgNode branchNode | + guard = branchNode and branchNode = case.getBranch(_) and - guard = branchNode.getPattern(_) and // For simplicity, consider patterns that contain only string literals or arrays of string literals forall(ExprCfgNode pattern | pattern = branchNode.getPattern(_) | // when "foo" diff --git a/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected b/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected index 9c26785029e..69e4cc294de 100644 --- a/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -526,17 +526,20 @@ case.rb: #-----| -> exit if_in_case (normal) # 2| call to x1 -#-----| -> when ... +#-----| -> 1 # 2| self #-----| -> call to x1 -# 3| when ... -#-----| -> 1 +# 3| [match] when ... +#-----| match -> self + +# 3| [no-match] when ... +#-----| no-match -> 2 # 3| 1 -#-----| match -> self -#-----| no-match -> when ... +#-----| match -> [match] when ... +#-----| no-match -> [no-match] when ... # 3| then ... #-----| -> case ... @@ -569,12 +572,15 @@ case.rb: # 3| x2 #-----| -> "x2" -# 4| when ... -#-----| -> 2 +# 4| [match] when ... +#-----| match -> self + +# 4| [no-match] when ... +#-----| no-match -> case ... # 4| 2 -#-----| no-match -> case ... -#-----| match -> self +#-----| match -> [match] when ... +#-----| no-match -> [no-match] when ... # 4| then ... #-----| -> case ... @@ -1826,17 +1832,20 @@ cfg.rb: #-----| -> call to puts # 41| case ... -#-----| -> when ... +#-----| -> b # 41| 10 -#-----| -> when ... - -# 42| when ... #-----| -> 1 -# 42| 1 +# 42| [match] when ... #-----| match -> self -#-----| no-match -> when ... + +# 42| [no-match] when ... +#-----| no-match -> 2 + +# 42| 1 +#-----| match -> [match] when ... +#-----| no-match -> [no-match] when ... # 42| then ... #-----| -> case ... @@ -1853,20 +1862,23 @@ cfg.rb: # 42| one #-----| -> "one" -# 43| when ... -#-----| -> 2 +# 43| [match] when ... +#-----| match -> self + +# 43| [no-match] when ... +#-----| no-match -> self # 43| 2 +#-----| match -> [match] when ... #-----| no-match -> 3 -#-----| match -> self # 43| 3 +#-----| match -> [match] when ... #-----| no-match -> 4 -#-----| match -> self # 43| 4 -#-----| match -> self -#-----| no-match -> self +#-----| match -> [match] when ... +#-----| no-match -> [no-match] when ... # 43| then ... #-----| -> case ... @@ -1901,15 +1913,19 @@ cfg.rb: # 47| case ... #-----| -> chained +# 48| [false] when ... +#-----| false -> b + # 48| when ... -#-----| -> b +#-----| match -> self +#-----| no-match -> b # 48| b #-----| -> 1 # 48| ... == ... -#-----| true -> self -#-----| false -> when ... +#-----| false -> [false] when ... +#-----| true -> when ... # 48| 1 #-----| -> ... == ... @@ -1929,15 +1945,19 @@ cfg.rb: # 48| one #-----| -> "one" +# 49| [false] when ... +#-----| false -> case ... + # 49| when ... -#-----| -> b +#-----| no-match -> case ... +#-----| match -> self # 49| b #-----| -> 0 # 49| ... == ... +#-----| true -> when ... #-----| false -> b -#-----| true -> self # 49| 0 #-----| -> ... == ... @@ -1946,8 +1966,8 @@ cfg.rb: #-----| -> 1 # 49| ... > ... -#-----| false -> case ... -#-----| true -> self +#-----| false -> [false] when ... +#-----| true -> when ... # 49| 1 #-----| -> ... > ... diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb index 26c5da44798..6323a5224b6 100644 --- a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb @@ -137,9 +137,9 @@ end case foo when "foo", "bar" - foo # $ MISSING: guarded + foo # $ guarded when "baz", "quux" - foo # $ MISSING: guarded + foo # $ guarded else foo end From 62ea1f0a05fb6166a679a578518d71a8e781390a Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Fri, 11 Nov 2022 18:24:20 +1300 Subject: [PATCH 124/796] Ruby: Fix performance of string comparison guard The `or` case ran extremely slowly before this change. Also exclude string interpolations from consideration, for correctness, and add some more tests. --- .../codeql/ruby/dataflow/BarrierGuards.qll | 39 +++++++++++++++---- .../dataflow/barrier-guards/barrier-guards.rb | 17 ++++++++ 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll index e80495ab2f3..01b42a520bf 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll @@ -7,12 +7,16 @@ private import codeql.ruby.controlflow.CfgNodes private import codeql.ruby.dataflow.SSA private import codeql.ruby.ast.internal.Constant private import codeql.ruby.InclusionTests +private import codeql.ruby.ast.internal.Literal private predicate stringConstCompare(CfgNodes::AstCfgNode guard, CfgNode testedNode, boolean branch) { exists(CfgNodes::ExprNodes::ComparisonOperationCfgNode c | c = guard and exists(CfgNodes::ExprNodes::StringLiteralCfgNode strLitNode | - c.getExpr() instanceof EqExpr and branch = true + // Only consider strings without any interpolations + not exists(StringInterpolationComponent comp | comp = strLitNode.getExpr().getComponent(_)) and + c.getExpr() instanceof EqExpr and + branch = true or c.getExpr() instanceof CaseEqExpr and branch = true or @@ -26,24 +30,43 @@ private predicate stringConstCompare(CfgNodes::AstCfgNode guard, CfgNode testedN or stringConstCaseCompare(guard, testedNode, branch) or - stringConstCompareOr(guard, testedNode, branch) + exists(Ssa::Definition def, CfgNodes::ExprNodes::BinaryOperationCfgNode g | + g = guard and + stringConstCompareOr(guard, def, branch) and + stringConstCompare(g.getLeftOperand(), testedNode, _) + ) or stringConstCompareAnd(guard, testedNode, branch) } +/** + * Holds if `guard` is an `or` expression whose operands are string comparison guards that test the same SSA variable. + * `testedNode` is an arbitrary node that is tested by one of the guards. + * For example: + * + * ```rb + * x == "foo" or x == "bar" + * ``` + */ private predicate stringConstCompareOr( - CfgNodes::ExprNodes::BinaryOperationCfgNode guard, CfgNode testedNode, boolean branch + CfgNodes::ExprNodes::BinaryOperationCfgNode guard, Ssa::Definition def, boolean branch ) { guard.getExpr() instanceof LogicalOrExpr and branch = true and - exists(Ssa::Definition def | - forall(CfgNode innerGuard | innerGuard = guard.getAnOperand() | - stringConstCompare(innerGuard, def.getARead(), branch) - ) and - testedNode = any(CfgNode node | stringConstCompare(guard.getAnOperand(), node, _)) + forall(CfgNode innerGuard | innerGuard = guard.getAnOperand() | + stringConstCompare(innerGuard, def.getARead(), branch) ) } +/** + * Holds if guard is an `and` expression containing a string comparison guard in either operand. + * For example: + * + * ```rb + * x == "foo" and other_condition() + * other_condition() and x == "foo" + * ``` + */ private predicate stringConstCompareAnd( CfgNodes::ExprNodes::BinaryOperationCfgNode guard, CfgNode testedNode, boolean branch ) { diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb index 6323a5224b6..1946be36275 100644 --- a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb @@ -250,3 +250,20 @@ case bar in "foo" foo end + +if foo == "#{some_method()}" + foo +end + +F = "foo" +if foo == "#{F}" + foo # $ MISSING: guarded +end + +f = "foo" +if foo == "#{f}" + foo # $ MISSING: guarded +end + +foo == "foo" && foo # $ guarded +foo && foo == "foo" \ No newline at end of file From b16cecc8db1c678b4b5d4300ebcec1030fc902bc Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Fri, 11 Nov 2022 18:29:07 +1300 Subject: [PATCH 125/796] Ruby: Add missing doc --- ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll | 1 + ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll b/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll index 31898e0a652..b411c766f03 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll @@ -878,6 +878,7 @@ module ExprNodes { final override SplatExpr getExpr() { result = super.getExpr() } + /** Gets the operand of this splat expression. */ final ExprCfgNode getOperand() { e.hasCfgChild(e.getOperand(), this, result) } } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll index 01b42a520bf..16e965f6657 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll @@ -14,7 +14,7 @@ private predicate stringConstCompare(CfgNodes::AstCfgNode guard, CfgNode testedN c = guard and exists(CfgNodes::ExprNodes::StringLiteralCfgNode strLitNode | // Only consider strings without any interpolations - not exists(StringInterpolationComponent comp | comp = strLitNode.getExpr().getComponent(_)) and + not strLitNode.getExpr().getComponent(_) instanceof StringInterpolationComponent and c.getExpr() instanceof EqExpr and branch = true or @@ -40,8 +40,7 @@ private predicate stringConstCompare(CfgNodes::AstCfgNode guard, CfgNode testedN } /** - * Holds if `guard` is an `or` expression whose operands are string comparison guards that test the same SSA variable. - * `testedNode` is an arbitrary node that is tested by one of the guards. + * Holds if `guard` is an `or` expression whose operands are string comparison guards that test `def`. * For example: * * ```rb @@ -59,7 +58,7 @@ private predicate stringConstCompareOr( } /** - * Holds if guard is an `and` expression containing a string comparison guard in either operand. + * Holds if `guard` is an `and` expression containing a string comparison guard in either operand. * For example: * * ```rb From 2b4217b8a41536b5b550ba56e4f911743bc976fd Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Fri, 11 Nov 2022 18:41:51 +1300 Subject: [PATCH 126/796] Ruby: Update test fixture --- .../barrier-guards/barrier-guards.expected | 217 ++++++++++++++++-- 1 file changed, 195 insertions(+), 22 deletions(-) diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected index 05c515edebf..7804824ffb6 100644 --- a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected @@ -10,8 +10,15 @@ oldStyleBarrierGuards | barrier-guards.rb:43:4:43:15 | ... == ... | barrier-guards.rb:45:9:45:11 | foo | barrier-guards.rb:43:4:43:6 | foo | true | | barrier-guards.rb:70:4:70:21 | call to include? | barrier-guards.rb:71:5:71:7 | foo | barrier-guards.rb:70:18:70:20 | foo | true | | barrier-guards.rb:82:4:82:25 | ... != ... | barrier-guards.rb:83:5:83:7 | foo | barrier-guards.rb:82:15:82:17 | foo | true | -| barrier-guards.rb:196:6:196:17 | ... == ... | barrier-guards.rb:197:5:197:7 | foo | barrier-guards.rb:196:6:196:8 | foo | true | -| barrier-guards.rb:201:6:201:17 | ... == ... | barrier-guards.rb:201:24:201:26 | foo | barrier-guards.rb:201:6:201:8 | foo | true | +| barrier-guards.rb:207:4:207:15 | ... == ... | barrier-guards.rb:208:5:208:7 | foo | barrier-guards.rb:207:4:207:6 | foo | true | +| barrier-guards.rb:211:10:211:21 | ... == ... | barrier-guards.rb:212:5:212:7 | foo | barrier-guards.rb:211:10:211:12 | foo | true | +| barrier-guards.rb:215:16:215:27 | ... == ... | barrier-guards.rb:216:5:216:7 | foo | barrier-guards.rb:215:16:215:18 | foo | true | +| barrier-guards.rb:219:4:219:15 | ... == ... | barrier-guards.rb:219:21:219:23 | foo | barrier-guards.rb:219:4:219:6 | foo | true | +| barrier-guards.rb:219:4:219:15 | ... == ... | barrier-guards.rb:220:5:220:7 | foo | barrier-guards.rb:219:4:219:6 | foo | true | +| barrier-guards.rb:219:21:219:32 | ... == ... | barrier-guards.rb:220:5:220:7 | foo | barrier-guards.rb:219:21:219:23 | foo | true | +| barrier-guards.rb:232:6:232:17 | ... == ... | barrier-guards.rb:233:5:233:7 | foo | barrier-guards.rb:232:6:232:8 | foo | true | +| barrier-guards.rb:237:6:237:17 | ... == ... | barrier-guards.rb:237:24:237:26 | foo | barrier-guards.rb:237:6:237:8 | foo | true | +| barrier-guards.rb:268:1:268:12 | ... == ... | barrier-guards.rb:268:17:268:19 | foo | barrier-guards.rb:268:1:268:3 | foo | true | newStyleBarrierGuards | barrier-guards.rb:4:5:4:7 | foo | | barrier-guards.rb:10:5:10:7 | foo | @@ -26,13 +33,23 @@ newStyleBarrierGuards | barrier-guards.rb:126:5:126:7 | foo | | barrier-guards.rb:133:5:133:7 | foo | | barrier-guards.rb:135:5:135:7 | foo | +| barrier-guards.rb:140:5:140:7 | foo | +| barrier-guards.rb:142:5:142:7 | foo | | barrier-guards.rb:149:5:149:7 | foo | | barrier-guards.rb:154:5:154:7 | foo | | barrier-guards.rb:159:5:159:7 | foo | | barrier-guards.rb:164:5:164:7 | foo | -| barrier-guards.rb:197:5:197:7 | foo | -| barrier-guards.rb:201:24:201:26 | foo | +| barrier-guards.rb:192:5:192:7 | foo | +| barrier-guards.rb:196:5:196:7 | foo | | barrier-guards.rb:208:5:208:7 | foo | +| barrier-guards.rb:212:5:212:7 | foo | +| barrier-guards.rb:216:5:216:7 | foo | +| barrier-guards.rb:219:21:219:23 | foo | +| barrier-guards.rb:220:5:220:7 | foo | +| barrier-guards.rb:233:5:233:7 | foo | +| barrier-guards.rb:237:24:237:26 | foo | +| barrier-guards.rb:244:5:244:7 | foo | +| barrier-guards.rb:268:17:268:19 | foo | controls | barrier-guards.rb:3:4:3:15 | ... == ... | barrier-guards.rb:4:5:4:7 | foo | true | | barrier-guards.rb:3:4:3:15 | ... == ... | barrier-guards.rb:6:5:6:7 | foo | false | @@ -80,48 +97,204 @@ controls | barrier-guards.rb:118:8:118:8 | call to x | barrier-guards.rb:118:4:118:8 | [true] not ... | false | | barrier-guards.rb:118:8:118:8 | call to x | barrier-guards.rb:119:5:119:7 | foo | false | | barrier-guards.rb:118:8:118:8 | call to x | barrier-guards.rb:121:5:121:8 | bars | true | +| barrier-guards.rb:125:1:126:19 | [match] when ... | barrier-guards.rb:126:5:126:7 | foo | match | +| barrier-guards.rb:125:1:126:19 | [no-match] when ... | barrier-guards.rb:128:5:128:7 | foo | no-match | +| barrier-guards.rb:125:6:125:10 | "foo" | barrier-guards.rb:125:1:126:19 | [match] when ... | match | +| barrier-guards.rb:125:6:125:10 | "foo" | barrier-guards.rb:125:1:126:19 | [no-match] when ... | no-match | | barrier-guards.rb:125:6:125:10 | "foo" | barrier-guards.rb:126:5:126:7 | foo | match | | barrier-guards.rb:125:6:125:10 | "foo" | barrier-guards.rb:128:5:128:7 | foo | no-match | +| barrier-guards.rb:132:1:133:19 | [match] when ... | barrier-guards.rb:133:5:133:7 | foo | match | +| barrier-guards.rb:132:1:133:19 | [no-match] when ... | barrier-guards.rb:134:1:135:19 | [match] when ... | no-match | +| barrier-guards.rb:132:1:133:19 | [no-match] when ... | barrier-guards.rb:134:1:135:19 | [no-match] when ... | no-match | +| barrier-guards.rb:132:1:133:19 | [no-match] when ... | barrier-guards.rb:134:7:134:9 | bar | no-match | +| barrier-guards.rb:132:1:133:19 | [no-match] when ... | barrier-guards.rb:135:5:135:7 | foo | no-match | +| barrier-guards.rb:132:6:132:10 | "foo" | barrier-guards.rb:132:1:133:19 | [match] when ... | match | +| barrier-guards.rb:132:6:132:10 | "foo" | barrier-guards.rb:132:1:133:19 | [no-match] when ... | no-match | | barrier-guards.rb:132:6:132:10 | "foo" | barrier-guards.rb:133:5:133:7 | foo | match | -| barrier-guards.rb:132:6:132:10 | "foo" | barrier-guards.rb:134:1:135:19 | when ... | no-match | +| barrier-guards.rb:132:6:132:10 | "foo" | barrier-guards.rb:134:1:135:19 | [match] when ... | no-match | +| barrier-guards.rb:132:6:132:10 | "foo" | barrier-guards.rb:134:1:135:19 | [no-match] when ... | no-match | +| barrier-guards.rb:132:6:132:10 | "foo" | barrier-guards.rb:134:7:134:9 | bar | no-match | | barrier-guards.rb:132:6:132:10 | "foo" | barrier-guards.rb:135:5:135:7 | foo | no-match | +| barrier-guards.rb:134:1:135:19 | [match] when ... | barrier-guards.rb:135:5:135:7 | foo | match | +| barrier-guards.rb:134:6:134:10 | "bar" | barrier-guards.rb:134:1:135:19 | [match] when ... | match | +| barrier-guards.rb:134:6:134:10 | "bar" | barrier-guards.rb:134:1:135:19 | [no-match] when ... | no-match | | barrier-guards.rb:134:6:134:10 | "bar" | barrier-guards.rb:135:5:135:7 | foo | match | +| barrier-guards.rb:139:1:140:19 | [match] when ... | barrier-guards.rb:140:5:140:7 | foo | match | +| barrier-guards.rb:139:1:140:19 | [no-match] when ... | barrier-guards.rb:141:1:142:19 | [match] when ... | no-match | +| barrier-guards.rb:139:1:140:19 | [no-match] when ... | barrier-guards.rb:141:1:142:19 | [no-match] when ... | no-match | +| barrier-guards.rb:139:1:140:19 | [no-match] when ... | barrier-guards.rb:141:7:141:9 | baz | no-match | +| barrier-guards.rb:139:1:140:19 | [no-match] when ... | barrier-guards.rb:141:14:141:17 | quux | no-match | +| barrier-guards.rb:139:1:140:19 | [no-match] when ... | barrier-guards.rb:142:5:142:7 | foo | no-match | +| barrier-guards.rb:139:1:140:19 | [no-match] when ... | barrier-guards.rb:144:5:144:7 | foo | no-match | +| barrier-guards.rb:139:6:139:10 | "foo" | barrier-guards.rb:139:1:140:19 | [no-match] when ... | no-match | | barrier-guards.rb:139:6:139:10 | "foo" | barrier-guards.rb:139:14:139:16 | bar | no-match | -| barrier-guards.rb:139:6:139:10 | "foo" | barrier-guards.rb:141:1:142:7 | when ... | no-match | +| barrier-guards.rb:139:6:139:10 | "foo" | barrier-guards.rb:141:1:142:19 | [match] when ... | no-match | +| barrier-guards.rb:139:6:139:10 | "foo" | barrier-guards.rb:141:1:142:19 | [no-match] when ... | no-match | +| barrier-guards.rb:139:6:139:10 | "foo" | barrier-guards.rb:141:7:141:9 | baz | no-match | | barrier-guards.rb:139:6:139:10 | "foo" | barrier-guards.rb:141:14:141:17 | quux | no-match | | barrier-guards.rb:139:6:139:10 | "foo" | barrier-guards.rb:142:5:142:7 | foo | no-match | | barrier-guards.rb:139:6:139:10 | "foo" | barrier-guards.rb:144:5:144:7 | foo | no-match | -| barrier-guards.rb:139:13:139:17 | "bar" | barrier-guards.rb:141:1:142:7 | when ... | no-match | +| barrier-guards.rb:139:13:139:17 | "bar" | barrier-guards.rb:139:1:140:19 | [no-match] when ... | no-match | +| barrier-guards.rb:139:13:139:17 | "bar" | barrier-guards.rb:141:1:142:19 | [match] when ... | no-match | +| barrier-guards.rb:139:13:139:17 | "bar" | barrier-guards.rb:141:1:142:19 | [no-match] when ... | no-match | +| barrier-guards.rb:139:13:139:17 | "bar" | barrier-guards.rb:141:7:141:9 | baz | no-match | | barrier-guards.rb:139:13:139:17 | "bar" | barrier-guards.rb:141:14:141:17 | quux | no-match | | barrier-guards.rb:139:13:139:17 | "bar" | barrier-guards.rb:142:5:142:7 | foo | no-match | | barrier-guards.rb:139:13:139:17 | "bar" | barrier-guards.rb:144:5:144:7 | foo | no-match | +| barrier-guards.rb:141:1:142:19 | [match] when ... | barrier-guards.rb:142:5:142:7 | foo | match | +| barrier-guards.rb:141:1:142:19 | [no-match] when ... | barrier-guards.rb:144:5:144:7 | foo | no-match | +| barrier-guards.rb:141:6:141:10 | "baz" | barrier-guards.rb:141:1:142:19 | [no-match] when ... | no-match | | barrier-guards.rb:141:6:141:10 | "baz" | barrier-guards.rb:141:14:141:17 | quux | no-match | | barrier-guards.rb:141:6:141:10 | "baz" | barrier-guards.rb:144:5:144:7 | foo | no-match | +| barrier-guards.rb:141:13:141:18 | "quux" | barrier-guards.rb:141:1:142:19 | [no-match] when ... | no-match | | barrier-guards.rb:141:13:141:18 | "quux" | barrier-guards.rb:144:5:144:7 | foo | no-match | +| barrier-guards.rb:148:1:149:19 | [match] when ... | barrier-guards.rb:149:5:149:7 | foo | match | +| barrier-guards.rb:148:6:148:20 | * ... | barrier-guards.rb:148:1:149:19 | [match] when ... | match | +| barrier-guards.rb:148:6:148:20 | * ... | barrier-guards.rb:148:1:149:19 | [no-match] when ... | no-match | | barrier-guards.rb:148:6:148:20 | * ... | barrier-guards.rb:149:5:149:7 | foo | match | +| barrier-guards.rb:153:1:154:19 | [match] when ... | barrier-guards.rb:154:5:154:7 | foo | match | +| barrier-guards.rb:153:6:153:17 | * ... | barrier-guards.rb:153:1:154:19 | [match] when ... | match | +| barrier-guards.rb:153:6:153:17 | * ... | barrier-guards.rb:153:1:154:19 | [no-match] when ... | no-match | | barrier-guards.rb:153:6:153:17 | * ... | barrier-guards.rb:154:5:154:7 | foo | match | +| barrier-guards.rb:158:1:159:19 | [match] when ... | barrier-guards.rb:159:5:159:7 | foo | match | +| barrier-guards.rb:158:6:158:9 | * ... | barrier-guards.rb:158:1:159:19 | [match] when ... | match | +| barrier-guards.rb:158:6:158:9 | * ... | barrier-guards.rb:158:1:159:19 | [no-match] when ... | no-match | | barrier-guards.rb:158:6:158:9 | * ... | barrier-guards.rb:159:5:159:7 | foo | match | +| barrier-guards.rb:163:1:164:19 | [match] when ... | barrier-guards.rb:164:5:164:7 | foo | match | +| barrier-guards.rb:163:6:163:10 | * ... | barrier-guards.rb:163:1:164:19 | [match] when ... | match | +| barrier-guards.rb:163:6:163:10 | * ... | barrier-guards.rb:163:1:164:19 | [no-match] when ... | no-match | | barrier-guards.rb:163:6:163:10 | * ... | barrier-guards.rb:164:5:164:7 | foo | match | +| barrier-guards.rb:168:1:169:7 | [match] when ... | barrier-guards.rb:169:5:169:7 | foo | match | +| barrier-guards.rb:168:6:168:16 | * ... | barrier-guards.rb:168:1:169:7 | [match] when ... | match | +| barrier-guards.rb:168:6:168:16 | * ... | barrier-guards.rb:168:1:169:7 | [no-match] when ... | no-match | | barrier-guards.rb:168:6:168:16 | * ... | barrier-guards.rb:169:5:169:7 | foo | match | +| barrier-guards.rb:173:1:174:7 | [match] when ... | barrier-guards.rb:174:5:174:7 | foo | match | +| barrier-guards.rb:173:6:173:10 | "foo" | barrier-guards.rb:173:1:174:7 | [no-match] when ... | no-match | | barrier-guards.rb:173:6:173:10 | "foo" | barrier-guards.rb:173:13:173:13 | self | no-match | +| barrier-guards.rb:173:13:173:13 | call to x | barrier-guards.rb:173:1:174:7 | [no-match] when ... | no-match | +| barrier-guards.rb:180:1:181:7 | [match] when ... | barrier-guards.rb:181:5:181:7 | foo | match | +| barrier-guards.rb:180:6:180:15 | * ... | barrier-guards.rb:180:1:181:7 | [match] when ... | match | +| barrier-guards.rb:180:6:180:15 | * ... | barrier-guards.rb:180:1:181:7 | [no-match] when ... | no-match | | barrier-guards.rb:180:6:180:15 | * ... | barrier-guards.rb:181:5:181:7 | foo | match | +| barrier-guards.rb:187:1:188:7 | [match] when ... | barrier-guards.rb:188:5:188:7 | foo | match | +| barrier-guards.rb:187:6:187:15 | * ... | barrier-guards.rb:187:1:188:7 | [match] when ... | match | +| barrier-guards.rb:187:6:187:15 | * ... | barrier-guards.rb:187:1:188:7 | [no-match] when ... | no-match | | barrier-guards.rb:187:6:187:15 | * ... | barrier-guards.rb:188:5:188:7 | foo | match | | barrier-guards.rb:191:4:191:15 | ... == ... | barrier-guards.rb:191:4:191:31 | [false] ... or ... | false | | barrier-guards.rb:191:4:191:15 | ... == ... | barrier-guards.rb:191:20:191:22 | foo | false | | barrier-guards.rb:191:4:191:31 | [true] ... or ... | barrier-guards.rb:192:5:192:7 | foo | true | | barrier-guards.rb:191:20:191:31 | ... == ... | barrier-guards.rb:191:4:191:31 | [false] ... or ... | false | -| barrier-guards.rb:196:6:196:17 | ... == ... | barrier-guards.rb:197:5:197:7 | foo | true | -| barrier-guards.rb:201:6:201:17 | ... == ... | barrier-guards.rb:201:24:201:26 | foo | true | -| barrier-guards.rb:201:6:201:17 | ... == ... | barrier-guards.rb:202:1:202:26 | when ... | false | -| barrier-guards.rb:201:6:201:17 | ... == ... | barrier-guards.rb:202:24:202:26 | foo | false | -| barrier-guards.rb:201:6:201:17 | ... == ... | barrier-guards.rb:203:1:203:22 | when ... | false | -| barrier-guards.rb:201:6:201:17 | ... == ... | barrier-guards.rb:203:20:203:22 | foo | false | -| barrier-guards.rb:202:6:202:17 | ... == ... | barrier-guards.rb:202:24:202:26 | foo | true | -| barrier-guards.rb:202:6:202:17 | ... == ... | barrier-guards.rb:203:1:203:22 | when ... | false | -| barrier-guards.rb:202:6:202:17 | ... == ... | barrier-guards.rb:203:20:203:22 | foo | false | -| barrier-guards.rb:203:6:203:13 | ... == ... | barrier-guards.rb:203:20:203:22 | foo | true | -| barrier-guards.rb:207:4:207:8 | "foo" | barrier-guards.rb:208:5:208:7 | foo | match | -| barrier-guards.rb:207:4:207:8 | "foo" | barrier-guards.rb:209:1:210:7 | in ... then ... | no-match | -| barrier-guards.rb:207:4:207:8 | "foo" | barrier-guards.rb:210:5:210:7 | foo | no-match | -| barrier-guards.rb:209:4:209:4 | x | barrier-guards.rb:210:5:210:7 | foo | match | -| barrier-guards.rb:214:4:214:8 | "foo" | barrier-guards.rb:215:5:215:7 | foo | match | +| barrier-guards.rb:195:4:195:15 | ... == ... | barrier-guards.rb:195:4:195:31 | [false] ... or ... | false | +| barrier-guards.rb:195:4:195:15 | ... == ... | barrier-guards.rb:195:4:195:47 | [false] ... or ... | false | +| barrier-guards.rb:195:4:195:15 | ... == ... | barrier-guards.rb:195:20:195:22 | foo | false | +| barrier-guards.rb:195:4:195:15 | ... == ... | barrier-guards.rb:195:36:195:38 | foo | false | +| barrier-guards.rb:195:4:195:31 | [false] ... or ... | barrier-guards.rb:195:4:195:47 | [false] ... or ... | false | +| barrier-guards.rb:195:4:195:31 | [false] ... or ... | barrier-guards.rb:195:36:195:38 | foo | false | +| barrier-guards.rb:195:4:195:47 | [true] ... or ... | barrier-guards.rb:196:5:196:7 | foo | true | +| barrier-guards.rb:195:20:195:31 | ... == ... | barrier-guards.rb:195:4:195:31 | [false] ... or ... | false | +| barrier-guards.rb:195:20:195:31 | ... == ... | barrier-guards.rb:195:4:195:47 | [false] ... or ... | false | +| barrier-guards.rb:195:20:195:31 | ... == ... | barrier-guards.rb:195:36:195:38 | foo | false | +| barrier-guards.rb:195:36:195:47 | ... == ... | barrier-guards.rb:195:4:195:47 | [false] ... or ... | false | +| barrier-guards.rb:199:4:199:15 | ... == ... | barrier-guards.rb:199:4:199:31 | [false] ... or ... | false | +| barrier-guards.rb:199:4:199:15 | ... == ... | barrier-guards.rb:199:4:199:43 | [false] ... or ... | false | +| barrier-guards.rb:199:4:199:15 | ... == ... | barrier-guards.rb:199:20:199:22 | foo | false | +| barrier-guards.rb:199:4:199:15 | ... == ... | barrier-guards.rb:199:36:199:38 | foo | false | +| barrier-guards.rb:199:4:199:31 | [false] ... or ... | barrier-guards.rb:199:4:199:43 | [false] ... or ... | false | +| barrier-guards.rb:199:4:199:31 | [false] ... or ... | barrier-guards.rb:199:36:199:38 | foo | false | +| barrier-guards.rb:199:4:199:43 | [true] ... or ... | barrier-guards.rb:200:5:200:7 | foo | true | +| barrier-guards.rb:199:20:199:31 | ... == ... | barrier-guards.rb:199:4:199:31 | [false] ... or ... | false | +| barrier-guards.rb:199:20:199:31 | ... == ... | barrier-guards.rb:199:4:199:43 | [false] ... or ... | false | +| barrier-guards.rb:199:20:199:31 | ... == ... | barrier-guards.rb:199:36:199:38 | foo | false | +| barrier-guards.rb:199:36:199:43 | ... == ... | barrier-guards.rb:199:4:199:43 | [false] ... or ... | false | +| barrier-guards.rb:203:4:203:15 | ... == ... | barrier-guards.rb:203:4:203:31 | [false] ... or ... | false | +| barrier-guards.rb:203:4:203:15 | ... == ... | barrier-guards.rb:203:4:203:47 | [false] ... or ... | false | +| barrier-guards.rb:203:4:203:15 | ... == ... | barrier-guards.rb:203:20:203:22 | self | false | +| barrier-guards.rb:203:4:203:15 | ... == ... | barrier-guards.rb:203:36:203:38 | foo | false | +| barrier-guards.rb:203:4:203:31 | [false] ... or ... | barrier-guards.rb:203:4:203:47 | [false] ... or ... | false | +| barrier-guards.rb:203:4:203:31 | [false] ... or ... | barrier-guards.rb:203:36:203:38 | foo | false | +| barrier-guards.rb:203:4:203:47 | [true] ... or ... | barrier-guards.rb:204:5:204:7 | foo | true | +| barrier-guards.rb:203:20:203:31 | ... == ... | barrier-guards.rb:203:4:203:31 | [false] ... or ... | false | +| barrier-guards.rb:203:20:203:31 | ... == ... | barrier-guards.rb:203:4:203:47 | [false] ... or ... | false | +| barrier-guards.rb:203:20:203:31 | ... == ... | barrier-guards.rb:203:36:203:38 | foo | false | +| barrier-guards.rb:203:36:203:47 | ... == ... | barrier-guards.rb:203:4:203:47 | [false] ... or ... | false | +| barrier-guards.rb:207:4:207:15 | ... == ... | barrier-guards.rb:207:4:207:21 | [true] ... and ... | true | +| barrier-guards.rb:207:4:207:15 | ... == ... | barrier-guards.rb:207:21:207:21 | self | true | +| barrier-guards.rb:207:4:207:15 | ... == ... | barrier-guards.rb:208:5:208:7 | foo | true | +| barrier-guards.rb:207:4:207:21 | [true] ... and ... | barrier-guards.rb:208:5:208:7 | foo | true | +| barrier-guards.rb:207:21:207:21 | call to x | barrier-guards.rb:207:4:207:21 | [true] ... and ... | true | +| barrier-guards.rb:207:21:207:21 | call to x | barrier-guards.rb:208:5:208:7 | foo | true | +| barrier-guards.rb:211:4:211:4 | call to x | barrier-guards.rb:211:4:211:21 | [true] ... and ... | true | +| barrier-guards.rb:211:4:211:4 | call to x | barrier-guards.rb:211:10:211:12 | foo | true | +| barrier-guards.rb:211:4:211:4 | call to x | barrier-guards.rb:212:5:212:7 | foo | true | +| barrier-guards.rb:211:4:211:21 | [true] ... and ... | barrier-guards.rb:212:5:212:7 | foo | true | +| barrier-guards.rb:211:10:211:21 | ... == ... | barrier-guards.rb:211:4:211:21 | [true] ... and ... | true | +| barrier-guards.rb:211:10:211:21 | ... == ... | barrier-guards.rb:212:5:212:7 | foo | true | +| barrier-guards.rb:215:4:215:4 | call to x | barrier-guards.rb:215:4:215:10 | [true] ... and ... | true | +| barrier-guards.rb:215:4:215:4 | call to x | barrier-guards.rb:215:4:215:27 | [true] ... and ... | true | +| barrier-guards.rb:215:4:215:4 | call to x | barrier-guards.rb:215:10:215:10 | self | true | +| barrier-guards.rb:215:4:215:4 | call to x | barrier-guards.rb:215:16:215:18 | foo | true | +| barrier-guards.rb:215:4:215:4 | call to x | barrier-guards.rb:216:5:216:7 | foo | true | +| barrier-guards.rb:215:4:215:10 | [true] ... and ... | barrier-guards.rb:215:4:215:27 | [true] ... and ... | true | +| barrier-guards.rb:215:4:215:10 | [true] ... and ... | barrier-guards.rb:215:16:215:18 | foo | true | +| barrier-guards.rb:215:4:215:10 | [true] ... and ... | barrier-guards.rb:216:5:216:7 | foo | true | +| barrier-guards.rb:215:4:215:27 | [true] ... and ... | barrier-guards.rb:216:5:216:7 | foo | true | +| barrier-guards.rb:215:10:215:10 | call to y | barrier-guards.rb:215:4:215:10 | [true] ... and ... | true | +| barrier-guards.rb:215:10:215:10 | call to y | barrier-guards.rb:215:4:215:27 | [true] ... and ... | true | +| barrier-guards.rb:215:10:215:10 | call to y | barrier-guards.rb:215:16:215:18 | foo | true | +| barrier-guards.rb:215:10:215:10 | call to y | barrier-guards.rb:216:5:216:7 | foo | true | +| barrier-guards.rb:215:16:215:27 | ... == ... | barrier-guards.rb:215:4:215:27 | [true] ... and ... | true | +| barrier-guards.rb:215:16:215:27 | ... == ... | barrier-guards.rb:216:5:216:7 | foo | true | +| barrier-guards.rb:219:4:219:15 | ... == ... | barrier-guards.rb:219:4:219:32 | [true] ... and ... | true | +| barrier-guards.rb:219:4:219:15 | ... == ... | barrier-guards.rb:219:21:219:23 | foo | true | +| barrier-guards.rb:219:4:219:15 | ... == ... | barrier-guards.rb:220:5:220:7 | foo | true | +| barrier-guards.rb:219:4:219:32 | [true] ... and ... | barrier-guards.rb:220:5:220:7 | foo | true | +| barrier-guards.rb:219:21:219:32 | ... == ... | barrier-guards.rb:219:4:219:32 | [true] ... and ... | true | +| barrier-guards.rb:219:21:219:32 | ... == ... | barrier-guards.rb:220:5:220:7 | foo | true | +| barrier-guards.rb:223:4:223:4 | call to x | barrier-guards.rb:223:4:223:10 | [true] ... and ... | true | +| barrier-guards.rb:223:4:223:4 | call to x | barrier-guards.rb:223:10:223:10 | self | true | +| barrier-guards.rb:223:4:223:4 | call to x | barrier-guards.rb:224:5:224:7 | foo | true | +| barrier-guards.rb:223:4:223:10 | [true] ... and ... | barrier-guards.rb:224:5:224:7 | foo | true | +| barrier-guards.rb:223:10:223:10 | call to y | barrier-guards.rb:223:4:223:10 | [true] ... and ... | true | +| barrier-guards.rb:223:10:223:10 | call to y | barrier-guards.rb:224:5:224:7 | foo | true | +| barrier-guards.rb:227:4:227:15 | ... == ... | barrier-guards.rb:227:4:227:21 | [true] ... and ... | true | +| barrier-guards.rb:227:4:227:15 | ... == ... | barrier-guards.rb:227:21:227:21 | self | true | +| barrier-guards.rb:227:4:227:15 | ... == ... | barrier-guards.rb:228:5:228:7 | self | true | +| barrier-guards.rb:227:4:227:21 | [true] ... and ... | barrier-guards.rb:228:5:228:7 | self | true | +| barrier-guards.rb:227:21:227:21 | call to y | barrier-guards.rb:227:4:227:21 | [true] ... and ... | true | +| barrier-guards.rb:227:21:227:21 | call to y | barrier-guards.rb:228:5:228:7 | self | true | +| barrier-guards.rb:232:1:233:19 | when ... | barrier-guards.rb:233:5:233:7 | foo | match | +| barrier-guards.rb:232:6:232:17 | ... == ... | barrier-guards.rb:232:1:233:19 | [false] when ... | false | +| barrier-guards.rb:232:6:232:17 | ... == ... | barrier-guards.rb:232:1:233:19 | when ... | true | +| barrier-guards.rb:232:6:232:17 | ... == ... | barrier-guards.rb:233:5:233:7 | foo | true | +| barrier-guards.rb:237:1:237:38 | when ... | barrier-guards.rb:237:24:237:26 | foo | match | +| barrier-guards.rb:237:6:237:17 | ... == ... | barrier-guards.rb:237:1:237:38 | [false] when ... | false | +| barrier-guards.rb:237:6:237:17 | ... == ... | barrier-guards.rb:237:1:237:38 | when ... | true | +| barrier-guards.rb:237:6:237:17 | ... == ... | barrier-guards.rb:237:24:237:26 | foo | true | +| barrier-guards.rb:238:1:238:26 | when ... | barrier-guards.rb:238:24:238:26 | foo | match | +| barrier-guards.rb:238:6:238:17 | ... == ... | barrier-guards.rb:238:1:238:26 | [false] when ... | false | +| barrier-guards.rb:238:6:238:17 | ... == ... | barrier-guards.rb:238:1:238:26 | when ... | true | +| barrier-guards.rb:238:6:238:17 | ... == ... | barrier-guards.rb:238:24:238:26 | foo | true | +| barrier-guards.rb:239:1:239:22 | when ... | barrier-guards.rb:239:20:239:22 | foo | match | +| barrier-guards.rb:239:6:239:13 | ... == ... | barrier-guards.rb:239:1:239:22 | [false] when ... | false | +| barrier-guards.rb:239:6:239:13 | ... == ... | barrier-guards.rb:239:1:239:22 | when ... | true | +| barrier-guards.rb:239:6:239:13 | ... == ... | barrier-guards.rb:239:20:239:22 | foo | true | +| barrier-guards.rb:243:4:243:8 | "foo" | barrier-guards.rb:244:5:244:7 | foo | match | +| barrier-guards.rb:243:4:243:8 | "foo" | barrier-guards.rb:245:1:246:7 | in ... then ... | no-match | +| barrier-guards.rb:243:4:243:8 | "foo" | barrier-guards.rb:246:5:246:7 | foo | no-match | +| barrier-guards.rb:245:4:245:4 | x | barrier-guards.rb:246:5:246:7 | foo | match | +| barrier-guards.rb:250:4:250:8 | "foo" | barrier-guards.rb:251:5:251:7 | foo | match | +| barrier-guards.rb:250:4:250:8 | "foo" | barrier-guards.rb:254:1:256:3 | if ... | match | +| barrier-guards.rb:250:4:250:8 | "foo" | barrier-guards.rb:255:5:255:7 | foo | match | +| barrier-guards.rb:250:4:250:8 | "foo" | barrier-guards.rb:259:1:261:3 | if ... | match | +| barrier-guards.rb:250:4:250:8 | "foo" | barrier-guards.rb:260:5:260:7 | foo | match | +| barrier-guards.rb:250:4:250:8 | "foo" | barrier-guards.rb:264:1:266:3 | if ... | match | +| barrier-guards.rb:250:4:250:8 | "foo" | barrier-guards.rb:265:5:265:7 | foo | match | +| barrier-guards.rb:250:4:250:8 | "foo" | barrier-guards.rb:268:1:268:19 | ... && ... | match | +| barrier-guards.rb:250:4:250:8 | "foo" | barrier-guards.rb:268:17:268:19 | foo | match | +| barrier-guards.rb:250:4:250:8 | "foo" | barrier-guards.rb:269:1:269:19 | ... && ... | match | +| barrier-guards.rb:250:4:250:8 | "foo" | barrier-guards.rb:269:8:269:10 | foo | match | +| barrier-guards.rb:254:4:254:28 | ... == ... | barrier-guards.rb:255:5:255:7 | foo | true | +| barrier-guards.rb:259:4:259:16 | ... == ... | barrier-guards.rb:260:5:260:7 | foo | true | +| barrier-guards.rb:264:4:264:16 | ... == ... | barrier-guards.rb:265:5:265:7 | foo | true | +| barrier-guards.rb:268:1:268:12 | ... == ... | barrier-guards.rb:268:17:268:19 | foo | true | +| barrier-guards.rb:269:1:269:3 | foo | barrier-guards.rb:269:8:269:10 | foo | true | From 6d9745e5c35796240be0909f5c6c3a05bd4f0beb Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Fri, 24 Jun 2022 16:13:32 +0200 Subject: [PATCH 127/796] Python: Rewrite call-graph tests to be inline expectation (2/2) I ported the predicates showing difference between points-to and type-tracking, since it's helpful to see the list of differences, instead of having to parse expectations! --- .../library-tests/CallGraph/CallGraphTest.qll | 147 ------------------ .../CallGraph/InlineCallGraphTest.expected | 18 +++ .../CallGraph/InlineCallGraphTest.ql | 39 +++-- .../library-tests/CallGraph/PointsTo.expected | 6 - .../library-tests/CallGraph/PointsTo.ql | 10 -- .../library-tests/CallGraph/README.md | 38 ----- .../library-tests/CallGraph/Relative.expected | 20 --- .../library-tests/CallGraph/Relative.ql | 14 -- .../CallGraph/TypeTracker.expected | 21 --- .../library-tests/CallGraph/TypeTracker.ql | 10 -- .../CallGraph/code/runtime_decision.py | 4 - .../library-tests/CallGraph/code/simple.py | 9 +- .../code/underscore_prefix_func_name.py | 4 - 13 files changed, 48 insertions(+), 292 deletions(-) delete mode 100644 python/ql/test/experimental/library-tests/CallGraph/CallGraphTest.qll delete mode 100644 python/ql/test/experimental/library-tests/CallGraph/PointsTo.expected delete mode 100644 python/ql/test/experimental/library-tests/CallGraph/PointsTo.ql delete mode 100644 python/ql/test/experimental/library-tests/CallGraph/README.md delete mode 100644 python/ql/test/experimental/library-tests/CallGraph/Relative.expected delete mode 100644 python/ql/test/experimental/library-tests/CallGraph/Relative.ql delete mode 100644 python/ql/test/experimental/library-tests/CallGraph/TypeTracker.expected delete mode 100644 python/ql/test/experimental/library-tests/CallGraph/TypeTracker.ql diff --git a/python/ql/test/experimental/library-tests/CallGraph/CallGraphTest.qll b/python/ql/test/experimental/library-tests/CallGraph/CallGraphTest.qll deleted file mode 100644 index 0f8b3162980..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph/CallGraphTest.qll +++ /dev/null @@ -1,147 +0,0 @@ -import python - -/** Gets the comment on the line above `ast` */ -Comment commentFor(AstNode ast) { - exists(int line | line = ast.getLocation().getStartLine() - 1 | - result - .getLocation() - .hasLocationInfo(ast.getLocation().getFile().getAbsolutePath(), line, _, line, _) - ) -} - -/** Gets the value from `tag:value` in the comment for `ast` */ -string getAnnotation(AstNode ast, string tag) { - exists(Comment comment, string match, string theRegex | - theRegex = "([\\w]+):([\\w.]+)" and - comment = commentFor(ast) and - match = comment.getText().regexpFind(theRegex, _, _) and - tag = match.regexpCapture(theRegex, 1) and - result = match.regexpCapture(theRegex, 2) - ) -} - -/** Gets a callable annotated with `name:name` */ -Function annotatedCallable(string name) { name = getAnnotation(result, "name") } - -/** Gets a call annotated with `calls:name` */ -Call annotatedCall(string name) { name = getAnnotation(result, "calls") } - -predicate missingAnnotationForCallable(string name, Call call) { - call = annotatedCall(name) and - not exists(annotatedCallable(name)) -} - -predicate nonUniqueAnnotationForCallable(string name, Function callable) { - strictcount(annotatedCallable(name)) > 1 and - callable = annotatedCallable(name) -} - -predicate missingAnnotationForCall(string name, Function callable) { - not exists(annotatedCall(name)) and - callable = annotatedCallable(name) -} - -/** There is an obvious problem with the annotation `name` */ -predicate nameInErrorState(string name) { - missingAnnotationForCallable(name, _) - or - nonUniqueAnnotationForCallable(name, _) - or - missingAnnotationForCall(name, _) -} - -/** Source code has annotation with `name` showing that `call` will call `callable` */ -predicate annotatedCallEdge(string name, Call call, Function callable) { - not nameInErrorState(name) and - call = annotatedCall(name) and - callable = annotatedCallable(name) -} - -// ------------------------- Annotation debug query predicates ------------------------- -query predicate debug_missingAnnotationForCallable(Call call, string message) { - exists(string name | - message = - "This call is annotated with '" + name + - "', but no callable with that annotation was extracted. Please fix." and - missingAnnotationForCallable(name, call) - ) -} - -query predicate debug_nonUniqueAnnotationForCallable(Function callable, string message) { - exists(string name | - message = "Multiple callables are annotated with '" + name + "'. Please fix." and - nonUniqueAnnotationForCallable(name, callable) - ) -} - -query predicate debug_missingAnnotationForCall(Function callable, string message) { - exists(string name | - message = - "This callable is annotated with '" + name + - "', but no call with that annotation was extracted. Please fix." and - missingAnnotationForCall(name, callable) - ) -} - -// ------------------------- Call Graph resolution ------------------------- -private newtype TCallGraphResolver = - TPointsToResolver() or - TTypeTrackerResolver() - -/** A method of call graph resolution */ -abstract class CallGraphResolver extends TCallGraphResolver { - abstract predicate callEdge(Call call, Function callable); - - /** - * Holds if annotations show that `call` will call `callable`, - * but our call graph resolver was not able to figure that out - */ - predicate expectedCallEdgeNotFound(Call call, Function callable) { - annotatedCallEdge(_, call, callable) and - not this.callEdge(call, callable) - } - - /** - * Holds if there are no annotations that show that `call` will call `callable` (where at least one of these are annotated), - * but the call graph resolver claims that `call` will call `callable` - */ - predicate unexpectedCallEdgeFound(Call call, Function callable, string message) { - this.callEdge(call, callable) and - not annotatedCallEdge(_, call, callable) and - ( - exists(string name | - message = "Call resolved to the callable named '" + name + "' but was not annotated as such" and - callable = annotatedCallable(name) and - not nameInErrorState(name) - ) - or - exists(string name | - message = "Annotated call resolved to unannotated callable" and - call = annotatedCall(name) and - not nameInErrorState(name) and - not exists( | callable = annotatedCallable(_)) - ) - ) - } - - string toString() { result = "CallGraphResolver" } -} - -/** A call graph resolver based on the existing points-to analysis */ -class PointsToResolver extends CallGraphResolver, TPointsToResolver { - override predicate callEdge(Call call, Function callable) { - exists(PythonFunctionValue funcValue | - funcValue.getScope() = callable and - call = funcValue.getACall().getNode() - ) - } - - override string toString() { result = "PointsToResolver" } -} - -/** A call graph resolved based on Type Trackers */ -class TypeTrackerResolver extends CallGraphResolver, TTypeTrackerResolver { - override predicate callEdge(Call call, Function callable) { none() } - - override string toString() { result = "TypeTrackerResolver" } -} diff --git a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected index 2ff4aeb6865..975ac22dd2d 100644 --- a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected +++ b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected @@ -2,3 +2,21 @@ failures debug_callableNotUnique | code/class_advanced.py:18:5:18:18 | Function arg | Qualified function name 'B.arg' is not unique. Please fix. | | code/class_advanced.py:23:5:23:25 | Function arg | Qualified function name 'B.arg' is not unique. Please fix. | +pointsTo_found_typeTracker_notFound +| code/class_simple.py:28:1:28:15 | ControlFlowNode for Attribute() | A.some_method | +| code/class_simple.py:30:1:30:21 | ControlFlowNode for Attribute() | A.some_staticmethod | +| code/class_simple.py:32:1:32:20 | ControlFlowNode for Attribute() | A.some_classmethod | +| code/class_simple.py:35:1:35:21 | ControlFlowNode for Attribute() | A.some_staticmethod | +| code/class_simple.py:37:1:37:20 | ControlFlowNode for Attribute() | A.some_classmethod | +| code/runtime_decision.py:18:1:18:6 | ControlFlowNode for func() | rd_bar | +| code/runtime_decision.py:18:1:18:6 | ControlFlowNode for func() | rd_foo | +| code/runtime_decision.py:26:1:26:7 | ControlFlowNode for func2() | rd_bar | +| code/runtime_decision.py:26:1:26:7 | ControlFlowNode for func2() | rd_foo | +| code/simple.py:15:1:15:5 | ControlFlowNode for foo() | foo | +| code/simple.py:16:1:16:14 | ControlFlowNode for indirect_foo() | foo | +| code/simple.py:17:1:17:5 | ControlFlowNode for bar() | bar | +| code/simple.py:18:1:18:5 | ControlFlowNode for lam() | lambda[simple.py:12:7] | +| code/underscore_prefix_func_name.py:18:5:18:19 | ControlFlowNode for some_function() | some_function | +| code/underscore_prefix_func_name.py:21:5:21:19 | ControlFlowNode for some_function() | some_function | +| code/underscore_prefix_func_name.py:24:1:24:21 | ControlFlowNode for _works_since_called() | _works_since_called | +typeTracker_found_pointsTo_notFound diff --git a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.ql b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.ql index 6b59751e43b..50ad10bd191 100644 --- a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.ql +++ b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.ql @@ -28,22 +28,41 @@ class CallGraphTest extends InlineExpectationsTest { | location = call.getLocation() and element = call.toString() and - ( - // note: `target.getQualifiedName` for Lambdas is just "lambda", so is not very useful :| - not target.isLambda() and - value = target.getQualifiedName() - or - target.isLambda() and - value = - "lambda[" + target.getLocation().getFile().getShortName() + ":" + - target.getLocation().getStartLine() + ":" + target.getLocation().getStartColumn() + "]" - ) + value = betterQualName(target) ) } } +bindingset[func] +string betterQualName(Function func) { + // note: `target.getQualifiedName` for Lambdas is just "lambda", so is not very useful :| + not func.isLambda() and + result = func.getQualifiedName() + or + func.isLambda() and + result = + "lambda[" + func.getLocation().getFile().getShortName() + ":" + + func.getLocation().getStartLine() + ":" + func.getLocation().getStartColumn() + "]" +} + query predicate debug_callableNotUnique(Function callable, string message) { exists(Function f | f != callable and f.getQualifiedName() = callable.getQualifiedName()) and message = "Qualified function name '" + callable.getQualifiedName() + "' is not unique. Please fix." } + +query predicate pointsTo_found_typeTracker_notFound(CallNode call, string qualname) { + exists(Function target | + pointsToCallEdge(call, target) and + not typeTrackerCallEdge(call, target) and + qualname = betterQualName(target) + ) +} + +query predicate typeTracker_found_pointsTo_notFound(CallNode call, string qualname) { + exists(Function target | + not pointsToCallEdge(call, target) and + typeTrackerCallEdge(call, target) and + qualname = betterQualName(target) + ) +} diff --git a/python/ql/test/experimental/library-tests/CallGraph/PointsTo.expected b/python/ql/test/experimental/library-tests/CallGraph/PointsTo.expected deleted file mode 100644 index e7db0fde98c..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph/PointsTo.expected +++ /dev/null @@ -1,6 +0,0 @@ -debug_missingAnnotationForCallable -debug_nonUniqueAnnotationForCallable -debug_missingAnnotationForCall -expectedCallEdgeNotFound -| code/underscore_prefix_func_name.py:16:5:16:19 | some_function() | code/underscore_prefix_func_name.py:10:1:10:20 | Function some_function | -unexpectedCallEdgeFound diff --git a/python/ql/test/experimental/library-tests/CallGraph/PointsTo.ql b/python/ql/test/experimental/library-tests/CallGraph/PointsTo.ql deleted file mode 100644 index f86842f2fe4..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph/PointsTo.ql +++ /dev/null @@ -1,10 +0,0 @@ -import python -import CallGraphTest - -query predicate expectedCallEdgeNotFound(Call call, Function callable) { - any(PointsToResolver r).expectedCallEdgeNotFound(call, callable) -} - -query predicate unexpectedCallEdgeFound(Call call, Function callable, string message) { - any(PointsToResolver r).unexpectedCallEdgeFound(call, callable, message) -} diff --git a/python/ql/test/experimental/library-tests/CallGraph/README.md b/python/ql/test/experimental/library-tests/CallGraph/README.md deleted file mode 100644 index 0fbf6bdac9d..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# Call Graph Tests - -A small testing framework for our call graph resolution. It relies on manual annotation of calls and callables, **and will only include output if something is wrong**. For example, if we are not able to resolve that the `foo()` call will call the `foo` function, that should give an alert. - -```py -# name:foo -def foo(): - pass -# calls:foo -foo() -``` - -This is greatly inspired by [`CallGraphs/AnnotatedTest`](https://github.com/github/codeql/blob/696d19cb1440b6f6a75c6a2c1319e18860ceb436/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/Test.ql) from JavaScript. - -IMPORTANT: Names used in annotations are not scoped, so must be unique globally. (this is a bit annoying, but makes things simple). If multiple identical annotations are used, an error message will be output. - -Important files: - -- `CallGraphTest.qll`: main code to find annotated calls/callables and setting everything up. -- `PointsTo.ql`: results when using points-to for call graph resolution. -- `TypeTracker.ql`: results when using TypeTracking for call graph resolution. -- `Relative.ql`: differences between using points-to and TypeTracking. -- `code/` contains the actual Python code we test against (included by `test.py`). - -All queries will also execute some `debug_*` predicates. These highlight any obvious problems with the annotation setup, and so there should never be any results committed. To show that this works as expected, see the [CallGraph-xfail](../CallGraph-xfail/) which uses symlinked versions of the files in this directory (can't include as subdir, so has to be a sibling). - -## `options` file - -If the value for `--max-import-depth` is set so that `import random` will extract `random.py` from the standard library, BUT NO transitive imports are extracted, then points-to analysis will fail to handle the following snippet. - -```py -import random -if random.random() < 0.5: - func = foo -else: - func = bar -func() -``` diff --git a/python/ql/test/experimental/library-tests/CallGraph/Relative.expected b/python/ql/test/experimental/library-tests/CallGraph/Relative.expected deleted file mode 100644 index 9882dda21bf..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph/Relative.expected +++ /dev/null @@ -1,20 +0,0 @@ -debug_missingAnnotationForCallable -debug_nonUniqueAnnotationForCallable -debug_missingAnnotationForCall -pointsTo_found_typeTracker_notFound -| code/class_simple.py:28:1:28:15 | Attribute() | code/class_simple.py:8:5:8:26 | Function some_method | -| code/class_simple.py:30:1:30:21 | Attribute() | code/class_simple.py:13:5:13:28 | Function some_staticmethod | -| code/class_simple.py:32:1:32:20 | Attribute() | code/class_simple.py:18:5:18:30 | Function some_classmethod | -| code/class_simple.py:35:1:35:21 | Attribute() | code/class_simple.py:13:5:13:28 | Function some_staticmethod | -| code/class_simple.py:37:1:37:20 | Attribute() | code/class_simple.py:18:5:18:30 | Function some_classmethod | -| code/runtime_decision.py:21:1:21:6 | func() | code/runtime_decision.py:8:1:8:13 | Function rd_foo | -| code/runtime_decision.py:21:1:21:6 | func() | code/runtime_decision.py:12:1:12:13 | Function rd_bar | -| code/runtime_decision.py:30:1:30:7 | func2() | code/runtime_decision.py:8:1:8:13 | Function rd_foo | -| code/runtime_decision.py:30:1:30:7 | func2() | code/runtime_decision.py:12:1:12:13 | Function rd_bar | -| code/simple.py:19:1:19:5 | foo() | code/simple.py:2:1:2:10 | Function foo | -| code/simple.py:21:1:21:14 | indirect_foo() | code/simple.py:2:1:2:10 | Function foo | -| code/simple.py:23:1:23:5 | bar() | code/simple.py:10:1:10:10 | Function bar | -| code/simple.py:25:1:25:5 | lam() | code/simple.py:15:7:15:36 | Function lambda | -| code/underscore_prefix_func_name.py:21:5:21:19 | some_function() | code/underscore_prefix_func_name.py:10:1:10:20 | Function some_function | -| code/underscore_prefix_func_name.py:25:5:25:19 | some_function() | code/underscore_prefix_func_name.py:10:1:10:20 | Function some_function | -pointsTo_notFound_typeTracker_found diff --git a/python/ql/test/experimental/library-tests/CallGraph/Relative.ql b/python/ql/test/experimental/library-tests/CallGraph/Relative.ql deleted file mode 100644 index f62e4d21cbd..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph/Relative.ql +++ /dev/null @@ -1,14 +0,0 @@ -import python -import CallGraphTest - -query predicate pointsTo_found_typeTracker_notFound(Call call, Function callable) { - annotatedCallEdge(_, call, callable) and - any(PointsToResolver r).callEdge(call, callable) and - not any(TypeTrackerResolver r).callEdge(call, callable) -} - -query predicate pointsTo_notFound_typeTracker_found(Call call, Function callable) { - annotatedCallEdge(_, call, callable) and - not any(PointsToResolver r).callEdge(call, callable) and - any(TypeTrackerResolver r).callEdge(call, callable) -} diff --git a/python/ql/test/experimental/library-tests/CallGraph/TypeTracker.expected b/python/ql/test/experimental/library-tests/CallGraph/TypeTracker.expected deleted file mode 100644 index 5fc5376ca25..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph/TypeTracker.expected +++ /dev/null @@ -1,21 +0,0 @@ -debug_missingAnnotationForCallable -debug_nonUniqueAnnotationForCallable -debug_missingAnnotationForCall -expectedCallEdgeNotFound -| code/class_simple.py:28:1:28:15 | Attribute() | code/class_simple.py:8:5:8:26 | Function some_method | -| code/class_simple.py:30:1:30:21 | Attribute() | code/class_simple.py:13:5:13:28 | Function some_staticmethod | -| code/class_simple.py:32:1:32:20 | Attribute() | code/class_simple.py:18:5:18:30 | Function some_classmethod | -| code/class_simple.py:35:1:35:21 | Attribute() | code/class_simple.py:13:5:13:28 | Function some_staticmethod | -| code/class_simple.py:37:1:37:20 | Attribute() | code/class_simple.py:18:5:18:30 | Function some_classmethod | -| code/runtime_decision.py:21:1:21:6 | func() | code/runtime_decision.py:8:1:8:13 | Function rd_foo | -| code/runtime_decision.py:21:1:21:6 | func() | code/runtime_decision.py:12:1:12:13 | Function rd_bar | -| code/runtime_decision.py:30:1:30:7 | func2() | code/runtime_decision.py:8:1:8:13 | Function rd_foo | -| code/runtime_decision.py:30:1:30:7 | func2() | code/runtime_decision.py:12:1:12:13 | Function rd_bar | -| code/simple.py:19:1:19:5 | foo() | code/simple.py:2:1:2:10 | Function foo | -| code/simple.py:21:1:21:14 | indirect_foo() | code/simple.py:2:1:2:10 | Function foo | -| code/simple.py:23:1:23:5 | bar() | code/simple.py:10:1:10:10 | Function bar | -| code/simple.py:25:1:25:5 | lam() | code/simple.py:15:7:15:36 | Function lambda | -| code/underscore_prefix_func_name.py:16:5:16:19 | some_function() | code/underscore_prefix_func_name.py:10:1:10:20 | Function some_function | -| code/underscore_prefix_func_name.py:21:5:21:19 | some_function() | code/underscore_prefix_func_name.py:10:1:10:20 | Function some_function | -| code/underscore_prefix_func_name.py:25:5:25:19 | some_function() | code/underscore_prefix_func_name.py:10:1:10:20 | Function some_function | -unexpectedCallEdgeFound diff --git a/python/ql/test/experimental/library-tests/CallGraph/TypeTracker.ql b/python/ql/test/experimental/library-tests/CallGraph/TypeTracker.ql deleted file mode 100644 index a62332e3839..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph/TypeTracker.ql +++ /dev/null @@ -1,10 +0,0 @@ -import python -import CallGraphTest - -query predicate expectedCallEdgeNotFound(Call call, Function callable) { - any(TypeTrackerResolver r).expectedCallEdgeNotFound(call, callable) -} - -query predicate unexpectedCallEdgeFound(Call call, Function callable, string message) { - any(TypeTrackerResolver r).unexpectedCallEdgeFound(call, callable, message) -} diff --git a/python/ql/test/experimental/library-tests/CallGraph/code/runtime_decision.py b/python/ql/test/experimental/library-tests/CallGraph/code/runtime_decision.py index a271cbd9a6f..3c4ebbb73e1 100644 --- a/python/ql/test/experimental/library-tests/CallGraph/code/runtime_decision.py +++ b/python/ql/test/experimental/library-tests/CallGraph/code/runtime_decision.py @@ -4,11 +4,9 @@ import random # hmm, annoying that you have to keep names unique across files :| # since I like to use foo and bar ALL the time :D -# name:rd_foo def rd_foo(): print('rd_foo') -# name:rd_bar def rd_bar(): print('rd_bar') @@ -17,7 +15,6 @@ if len(sys.argv) >= 2 and not sys.argv[1] in ['0', 'False', 'false']: else: func = rd_bar -# calls:rd_foo calls:rd_bar func() # $ pt=rd_foo pt=rd_bar # Random doesn't work with points-to :O @@ -26,5 +23,4 @@ if random.random() < 0.5: else: func2 = rd_bar -# calls:rd_foo calls:rd_bar func2() # $ pt=rd_foo pt=rd_bar diff --git a/python/ql/test/experimental/library-tests/CallGraph/code/simple.py b/python/ql/test/experimental/library-tests/CallGraph/code/simple.py index 210df4f209e..ac07ace93b2 100644 --- a/python/ql/test/experimental/library-tests/CallGraph/code/simple.py +++ b/python/ql/test/experimental/library-tests/CallGraph/code/simple.py @@ -1,4 +1,3 @@ -# name:foo def foo(): print("foo called") @@ -6,22 +5,16 @@ def foo(): indirect_foo = foo -# name:bar def bar(): print("bar called") -# name:lam lam = lambda: print("lambda called") -# calls:foo foo() # $ pt=foo -# calls:foo indirect_foo() # $ pt=foo -# calls:bar bar() # $ pt=bar -# calls:lam -lam() # $ pt=lambda[simple.py:15:7] +lam() # $ pt=lambda[simple.py:12:7] # python -m trace --trackcalls simple.py diff --git a/python/ql/test/experimental/library-tests/CallGraph/code/underscore_prefix_func_name.py b/python/ql/test/experimental/library-tests/CallGraph/code/underscore_prefix_func_name.py index 1a1efe9d7b6..fb3f5fc45a8 100644 --- a/python/ql/test/experimental/library-tests/CallGraph/code/underscore_prefix_func_name.py +++ b/python/ql/test/experimental/library-tests/CallGraph/code/underscore_prefix_func_name.py @@ -6,22 +6,18 @@ # points-to information about the `open` call in # https://google-gruyere.appspot.com/code/gruyere.py on line 227 -# name:some_function def some_function(): print('some_function') def _ignored(): print('_ignored') - # calls:some_function some_function() def _works_since_called(): print('_works_since_called') - # calls:some_function some_function() # $ pt=some_function def works_even_though_not_called(): - # calls:some_function some_function() # $ pt=some_function globals()['_ignored']() From b60504f40463e1eed8a0aef2ff24b74a307e847b Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Fri, 24 Jun 2022 16:15:04 +0200 Subject: [PATCH 128/796] Python: Delete `CallGraph-xfail` No longer needed since we're using an established testing framework now --- .../CallGraph-xfail/PointsTo.expected | 18 -------- .../CallGraph-xfail/PointsTo.qlref | 1 - .../library-tests/CallGraph-xfail/README.md | 1 - .../CallGraph-xfail/annotation_xfail.py | 21 --------- .../CallGraph-xfail/call_edge_xfail.py | 43 ------------------- 5 files changed, 84 deletions(-) delete mode 100644 python/ql/test/experimental/library-tests/CallGraph-xfail/PointsTo.expected delete mode 100644 python/ql/test/experimental/library-tests/CallGraph-xfail/PointsTo.qlref delete mode 100644 python/ql/test/experimental/library-tests/CallGraph-xfail/README.md delete mode 100644 python/ql/test/experimental/library-tests/CallGraph-xfail/annotation_xfail.py delete mode 100644 python/ql/test/experimental/library-tests/CallGraph-xfail/call_edge_xfail.py diff --git a/python/ql/test/experimental/library-tests/CallGraph-xfail/PointsTo.expected b/python/ql/test/experimental/library-tests/CallGraph-xfail/PointsTo.expected deleted file mode 100644 index 680cee0e8b2..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph-xfail/PointsTo.expected +++ /dev/null @@ -1,18 +0,0 @@ -debug_missingAnnotationForCallable -| annotation_xfail.py:10:1:10:24 | callable_not_annotated() | This call is annotated with 'callable_not_annotated', but no callable with that annotation was extracted. Please fix. | -debug_nonUniqueAnnotationForCallable -| annotation_xfail.py:13:1:13:17 | Function non_unique | Multiple callables are annotated with 'non_unique'. Please fix. | -| annotation_xfail.py:17:1:17:26 | Function too_much_copy_paste | Multiple callables are annotated with 'non_unique'. Please fix. | -debug_missingAnnotationForCall -| annotation_xfail.py:2:1:2:24 | Function no_annotated_call | This callable is annotated with 'no_annotated_call', but no call with that annotation was extracted. Please fix. | -expectedCallEdgeNotFound -| call_edge_xfail.py:36:1:36:11 | xfail_foo() | call_edge_xfail.py:8:1:8:16 | Function xfail_bar | -| call_edge_xfail.py:39:1:39:11 | xfail_baz() | call_edge_xfail.py:8:1:8:16 | Function xfail_bar | -unexpectedCallEdgeFound -| call_edge_xfail.py:29:1:29:6 | func() | call_edge_xfail.py:4:1:4:16 | Function xfail_foo | Call resolved to the callable named 'xfail_foo' but was not annotated as such | -| call_edge_xfail.py:29:1:29:6 | func() | call_edge_xfail.py:8:1:8:16 | Function xfail_bar | Call resolved to the callable named 'xfail_bar' but was not annotated as such | -| call_edge_xfail.py:30:1:30:11 | xfail_foo() | call_edge_xfail.py:4:1:4:16 | Function xfail_foo | Call resolved to the callable named 'xfail_foo' but was not annotated as such | -| call_edge_xfail.py:31:1:31:14 | xfail_lambda() | call_edge_xfail.py:15:16:15:44 | Function lambda | Call resolved to the callable named 'xfail_lambda' but was not annotated as such | -| call_edge_xfail.py:36:1:36:11 | xfail_foo() | call_edge_xfail.py:4:1:4:16 | Function xfail_foo | Call resolved to the callable named 'xfail_foo' but was not annotated as such | -| call_edge_xfail.py:39:1:39:11 | xfail_baz() | call_edge_xfail.py:11:1:11:16 | Function xfail_baz | Annotated call resolved to unannotated callable | -| call_edge_xfail.py:43:1:43:6 | func() | call_edge_xfail.py:8:1:8:16 | Function xfail_bar | Call resolved to the callable named 'xfail_bar' but was not annotated as such | diff --git a/python/ql/test/experimental/library-tests/CallGraph-xfail/PointsTo.qlref b/python/ql/test/experimental/library-tests/CallGraph-xfail/PointsTo.qlref deleted file mode 100644 index da8a0d1631a..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph-xfail/PointsTo.qlref +++ /dev/null @@ -1 +0,0 @@ -../CallGraph/PointsTo.ql diff --git a/python/ql/test/experimental/library-tests/CallGraph-xfail/README.md b/python/ql/test/experimental/library-tests/CallGraph-xfail/README.md deleted file mode 100644 index 39021bce2a1..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph-xfail/README.md +++ /dev/null @@ -1 +0,0 @@ -Test that show our failure handling in [CallGraph](../CallGraph/) works as expected. diff --git a/python/ql/test/experimental/library-tests/CallGraph-xfail/annotation_xfail.py b/python/ql/test/experimental/library-tests/CallGraph-xfail/annotation_xfail.py deleted file mode 100644 index f8dbf88aa02..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph-xfail/annotation_xfail.py +++ /dev/null @@ -1,21 +0,0 @@ -# name:no_annotated_call -def no_annotated_call(): - pass - -def callable_not_annotated(): - pass - -no_annotated_call() -# calls:callable_not_annotated -callable_not_annotated() - -# name:non_unique -def non_unique(): - pass - -# name:non_unique -def too_much_copy_paste(): - pass - -# calls:non_unique -non_unique() diff --git a/python/ql/test/experimental/library-tests/CallGraph-xfail/call_edge_xfail.py b/python/ql/test/experimental/library-tests/CallGraph-xfail/call_edge_xfail.py deleted file mode 100644 index e72e02e376b..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph-xfail/call_edge_xfail.py +++ /dev/null @@ -1,43 +0,0 @@ -import sys - -# name:xfail_foo -def xfail_foo(): - print('xfail_foo') - -# name:xfail_bar -def xfail_bar(): - print('xfail_bar') - -def xfail_baz(): - print('xfail_baz') - -# name:xfail_lambda -xfail_lambda = lambda: print('xfail_lambda') - -if len(sys.argv) >= 2 and not sys.argv[1] in ['0', 'False', 'false']: - func = xfail_foo -else: - func = xfail_bar - -# Correct usage to suppress bad annotation errors -# calls:xfail_foo calls:xfail_bar -func() -# calls:xfail_lambda -xfail_lambda() - -# These are not annotated, and will give rise to unexpectedCallEdgeFound -func() -xfail_foo() -xfail_lambda() - -# These are annotated wrongly, and will give rise to unexpectedCallEdgeFound - -# calls:xfail_bar -xfail_foo() - -# calls:xfail_bar -xfail_baz() - -# The annotation is incomplete (does not include the call to xfail_bar) -# calls:xfail_foo -func() From ab42521906e8caff7eedd751c4d5584422cbea57 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Fri, 24 Jun 2022 16:17:26 +0200 Subject: [PATCH 129/796] Python: Port `CallGraph-implicit-init` tests to the new call-graph test setup. Nice that we can write `MISSING:` now! --- .../InlineCallGraphTest.expected | 5 +++++ .../CallGraph-implicit-init/InlineCallGraphTest.qlref | 1 + .../CallGraph-implicit-init/PointsTo.expected | 6 ------ .../CallGraph-implicit-init/PointsTo.qlref | 1 - .../CallGraph-implicit-init/Relative.expected | 6 ------ .../CallGraph-implicit-init/Relative.qlref | 1 - .../CallGraph-implicit-init/TypeTracker.expected | 7 ------- .../CallGraph-implicit-init/TypeTracker.qlref | 1 - .../library-tests/CallGraph-implicit-init/example.py | 10 +++++----- .../library-tests/CallGraph-implicit-init/foo/bar/a.py | 1 - .../CallGraph-implicit-init/foo_explicit/bar/a.py | 1 - 11 files changed, 11 insertions(+), 29 deletions(-) create mode 100644 python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.expected create mode 100644 python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.qlref delete mode 100644 python/ql/test/experimental/library-tests/CallGraph-implicit-init/PointsTo.expected delete mode 100644 python/ql/test/experimental/library-tests/CallGraph-implicit-init/PointsTo.qlref delete mode 100644 python/ql/test/experimental/library-tests/CallGraph-implicit-init/Relative.expected delete mode 100644 python/ql/test/experimental/library-tests/CallGraph-implicit-init/Relative.qlref delete mode 100644 python/ql/test/experimental/library-tests/CallGraph-implicit-init/TypeTracker.expected delete mode 100644 python/ql/test/experimental/library-tests/CallGraph-implicit-init/TypeTracker.qlref diff --git a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.expected b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.expected new file mode 100644 index 00000000000..c847f9a8aa2 --- /dev/null +++ b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.expected @@ -0,0 +1,5 @@ +failures +debug_callableNotUnique +pointsTo_found_typeTracker_notFound +| example.py:22:1:22:16 | ControlFlowNode for explicit_afunc() | explicit_afunc | +typeTracker_found_pointsTo_notFound diff --git a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.qlref b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.qlref new file mode 100644 index 00000000000..25117a4582b --- /dev/null +++ b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.qlref @@ -0,0 +1 @@ +../CallGraph/InlineCallGraphTest.ql diff --git a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/PointsTo.expected b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/PointsTo.expected deleted file mode 100644 index 349d99b46d8..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/PointsTo.expected +++ /dev/null @@ -1,6 +0,0 @@ -debug_missingAnnotationForCallable -debug_nonUniqueAnnotationForCallable -debug_missingAnnotationForCall -expectedCallEdgeNotFound -| example.py:19:1:19:7 | afunc() | foo/bar/a.py:2:1:2:12 | Function afunc | -unexpectedCallEdgeFound diff --git a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/PointsTo.qlref b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/PointsTo.qlref deleted file mode 100644 index da8a0d1631a..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/PointsTo.qlref +++ /dev/null @@ -1 +0,0 @@ -../CallGraph/PointsTo.ql diff --git a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/Relative.expected b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/Relative.expected deleted file mode 100644 index 38aab0b5888..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/Relative.expected +++ /dev/null @@ -1,6 +0,0 @@ -debug_missingAnnotationForCallable -debug_nonUniqueAnnotationForCallable -debug_missingAnnotationForCall -pointsTo_found_typeTracker_notFound -| example.py:22:1:22:16 | explicit_afunc() | foo_explicit/bar/a.py:2:1:2:21 | Function explicit_afunc | -pointsTo_notFound_typeTracker_found diff --git a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/Relative.qlref b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/Relative.qlref deleted file mode 100644 index 2ffa6c10d51..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/Relative.qlref +++ /dev/null @@ -1 +0,0 @@ -../CallGraph/Relative.ql diff --git a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/TypeTracker.expected b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/TypeTracker.expected deleted file mode 100644 index 5283683a6a5..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/TypeTracker.expected +++ /dev/null @@ -1,7 +0,0 @@ -debug_missingAnnotationForCallable -debug_nonUniqueAnnotationForCallable -debug_missingAnnotationForCall -expectedCallEdgeNotFound -| example.py:19:1:19:7 | afunc() | foo/bar/a.py:2:1:2:12 | Function afunc | -| example.py:22:1:22:16 | explicit_afunc() | foo_explicit/bar/a.py:2:1:2:21 | Function explicit_afunc | -unexpectedCallEdgeFound diff --git a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/TypeTracker.qlref b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/TypeTracker.qlref deleted file mode 100644 index 60c029a5510..00000000000 --- a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/TypeTracker.qlref +++ /dev/null @@ -1 +0,0 @@ -../CallGraph/TypeTracker.ql diff --git a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/example.py b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/example.py index 35d56620af7..75ad8a9db11 100644 --- a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/example.py +++ b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/example.py @@ -5,18 +5,18 @@ This is not included in the standard `CallGraph/code` folder, since we're testin understanding import work properly, so it's better to have a clean test setup that is obviously correct (the other one isn't in regards to imports). -Technically this is part of PEP 420 -- Implicit Namespace Packages, but does use the +Technically this is part of PEP 420 -- Implicit Namespace Packages, but does not use the *real* namespace package feature of allowing source code for a single package to reside in multiple places. +Maybe this should have been an import resolution test, and not a call-graph test ¯\_(ツ)_/¯ + Since PEP 420 was accepted in Python 3, this test is Python 3 only. """ from foo.bar.a import afunc from foo_explicit.bar.a import explicit_afunc -# calls:afunc -afunc() +afunc() # $ MISSING: pt,tt=afunc -# calls:explicit_afunc -explicit_afunc() +explicit_afunc() # $ pt=explicit_afunc MISSING: tt=explicit_afunc diff --git a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/foo/bar/a.py b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/foo/bar/a.py index a294b33191e..bc639f6c537 100644 --- a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/foo/bar/a.py +++ b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/foo/bar/a.py @@ -1,4 +1,3 @@ -# name:afunc def afunc(): print("afunc called") return 1 diff --git a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/foo_explicit/bar/a.py b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/foo_explicit/bar/a.py index 616c3fddca1..c84d63cfce2 100644 --- a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/foo_explicit/bar/a.py +++ b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/foo_explicit/bar/a.py @@ -1,4 +1,3 @@ -# name:explicit_afunc def explicit_afunc(): print("explicit_afunc called") return 1 From 887062d339cb7a367699aef4923ca3873665b2bb Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 10 Nov 2022 14:22:10 +0100 Subject: [PATCH 130/796] update cs/assembly-path-injection and cs/hardcoded-key to path-problems --- .../CWE-114/AssemblyPathInjection.ql | 10 ++-- .../CWE-321/HardcodedEncryptionKey.ql | 15 ++++-- .../AssemblyPathInjection.expected | 12 ++++- .../HardcodedSymmetricEncryptionKey.expected | 47 ++++++++++++++++--- 4 files changed, 68 insertions(+), 16 deletions(-) diff --git a/csharp/ql/src/Security Features/CWE-114/AssemblyPathInjection.ql b/csharp/ql/src/Security Features/CWE-114/AssemblyPathInjection.ql index 3ca894db15a..3705ece0e72 100644 --- a/csharp/ql/src/Security Features/CWE-114/AssemblyPathInjection.ql +++ b/csharp/ql/src/Security Features/CWE-114/AssemblyPathInjection.ql @@ -3,7 +3,7 @@ * @description Loading a .NET assembly based on a path constructed from user-controlled sources * may allow a malicious user to load code which modifies the program in unintended * ways. - * @kind problem + * @kind path-problem * @id cs/assembly-path-injection * @problem.severity error * @security-severity 8.2 @@ -15,6 +15,7 @@ import csharp import semmle.code.csharp.security.dataflow.flowsources.Remote import semmle.code.csharp.commons.Util +import DataFlow::PathGraph /** * A taint-tracking configuration for untrusted user input used to load a DLL. @@ -47,6 +48,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { } } -from TaintTrackingConfiguration c, DataFlow::Node source, DataFlow::Node sink -where c.hasFlow(source, sink) -select sink, "This assembly path depends on a $@.", source, "user-provided value" +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "This assembly path depends on a $@.", source, + "user-provided value" diff --git a/csharp/ql/src/Security Features/CWE-321/HardcodedEncryptionKey.ql b/csharp/ql/src/Security Features/CWE-321/HardcodedEncryptionKey.ql index 8f30847cde0..8e516f44d4a 100644 --- a/csharp/ql/src/Security Features/CWE-321/HardcodedEncryptionKey.ql +++ b/csharp/ql/src/Security Features/CWE-321/HardcodedEncryptionKey.ql @@ -1,7 +1,7 @@ /** * @name Hard-coded encryption key * @description The .Key property or rgbKey parameter of a SymmetricAlgorithm should never be a hard-coded value. - * @kind problem + * @kind path-problem * @id cs/hardcoded-key * @problem.severity error * @security-severity 8.1 @@ -15,6 +15,7 @@ import csharp import semmle.code.csharp.security.cryptography.EncryptionKeyDataFlowQuery +import DataFlow::PathGraph /** * The creation of a literal byte array. @@ -36,7 +37,13 @@ class StringLiteralSource extends KeySource { StringLiteralSource() { this.asExpr() instanceof StringLiteral } } -from SymmetricKeyTaintTrackingConfiguration keyFlow, KeySource src, SymmetricEncryptionKeySink sink -where keyFlow.hasFlow(src, sink) -select sink, "This hard-coded $@ is used in symmetric algorithm in " + sink.getDescription(), src, +from + SymmetricKeyTaintTrackingConfiguration keyFlow, DataFlow::PathNode source, + DataFlow::PathNode sink, KeySource srcNode, SymmetricEncryptionKeySink sinkNode +where + keyFlow.hasFlowPath(source, sink) and + source.getNode() = srcNode and + sink.getNode() = sinkNode +select sink.getNode(), source, sink, + "This hard-coded $@ is used in symmetric algorithm in " + sinkNode.getDescription(), srcNode, "symmetric key" diff --git a/csharp/ql/test/query-tests/Security Features/CWE-114/AssemblyPathInjection/AssemblyPathInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-114/AssemblyPathInjection/AssemblyPathInjection.expected index 2f3c3bbb4a6..396d766c3e6 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-114/AssemblyPathInjection/AssemblyPathInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-114/AssemblyPathInjection/AssemblyPathInjection.expected @@ -1 +1,11 @@ -| Test.cs:10:36:10:46 | access to local variable libraryName | This assembly path depends on a $@. | Test.cs:7:26:7:48 | access to property QueryString | user-provided value | +edges +| Test.cs:7:26:7:48 | access to property QueryString : NameValueCollection | Test.cs:7:26:7:63 | access to indexer : String | +| Test.cs:7:26:7:48 | access to property QueryString : NameValueCollection | Test.cs:10:36:10:46 | access to local variable libraryName | +| Test.cs:7:26:7:63 | access to indexer : String | Test.cs:10:36:10:46 | access to local variable libraryName | +nodes +| Test.cs:7:26:7:48 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection | +| Test.cs:7:26:7:63 | access to indexer : String | semmle.label | access to indexer : String | +| Test.cs:10:36:10:46 | access to local variable libraryName | semmle.label | access to local variable libraryName | +subpaths +#select +| Test.cs:10:36:10:46 | access to local variable libraryName | Test.cs:7:26:7:48 | access to property QueryString : NameValueCollection | Test.cs:10:36:10:46 | access to local variable libraryName | This assembly path depends on a $@. | Test.cs:7:26:7:48 | access to property QueryString : NameValueCollection | user-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-321/HardcodedSymmetricEncryptionKey/HardcodedSymmetricEncryptionKey.expected b/csharp/ql/test/query-tests/Security Features/CWE-321/HardcodedSymmetricEncryptionKey/HardcodedSymmetricEncryptionKey.expected index 7c3a2a7339c..10cb82ff67e 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-321/HardcodedSymmetricEncryptionKey/HardcodedSymmetricEncryptionKey.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-321/HardcodedSymmetricEncryptionKey/HardcodedSymmetricEncryptionKey.expected @@ -1,7 +1,40 @@ -| HardcodedSymmetricEncryptionKey.cs:17:21:17:97 | array creation of type Byte[] | This hard-coded $@ is used in symmetric algorithm in Key property assignment | HardcodedSymmetricEncryptionKey.cs:17:21:17:97 | array creation of type Byte[] | symmetric key | -| HardcodedSymmetricEncryptionKey.cs:22:23:22:99 | array creation of type Byte[] | This hard-coded $@ is used in symmetric algorithm in Key property assignment | HardcodedSymmetricEncryptionKey.cs:22:23:22:99 | array creation of type Byte[] | symmetric key | -| HardcodedSymmetricEncryptionKey.cs:31:21:31:21 | access to local variable d | This hard-coded $@ is used in symmetric algorithm in Key property assignment | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] | symmetric key | -| HardcodedSymmetricEncryptionKey.cs:68:87:68:94 | access to parameter password | This hard-coded $@ is used in symmetric algorithm in Decryptor(rgbKey, IV) | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] | symmetric key | -| HardcodedSymmetricEncryptionKey.cs:108:23:108:25 | access to parameter key | This hard-coded $@ is used in symmetric algorithm in Key property assignment | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] | symmetric key | -| HardcodedSymmetricEncryptionKey.cs:121:87:121:89 | access to parameter key | This hard-coded $@ is used in symmetric algorithm in Encryptor(rgbKey, IV) | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] | symmetric key | -| HardcodedSymmetricEncryptionKey.cs:121:87:121:89 | access to parameter key | This hard-coded $@ is used in symmetric algorithm in Encryptor(rgbKey, IV) | HardcodedSymmetricEncryptionKey.cs:28:62:28:115 | "Hello, world: here is a very bad way to create a key" | symmetric key | +edges +| HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | HardcodedSymmetricEncryptionKey.cs:31:21:31:21 | access to local variable d | +| HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | HardcodedSymmetricEncryptionKey.cs:36:37:36:37 | access to local variable d : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | HardcodedSymmetricEncryptionKey.cs:41:50:41:50 | access to local variable c : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | HardcodedSymmetricEncryptionKey.cs:50:35:50:35 | access to local variable c : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:28:39:28:116 | call to method GetBytes : Byte[] | HardcodedSymmetricEncryptionKey.cs:44:51:44:69 | access to local variable byteArrayFromString : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:28:62:28:115 | "Hello, world: here is a very bad way to create a key" : String | HardcodedSymmetricEncryptionKey.cs:28:39:28:116 | call to method GetBytes : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:36:37:36:37 | access to local variable d : Byte[] | HardcodedSymmetricEncryptionKey.cs:103:57:103:59 | key : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:41:50:41:50 | access to local variable c : Byte[] | HardcodedSymmetricEncryptionKey.cs:112:63:112:65 | key : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:44:51:44:69 | access to local variable byteArrayFromString : Byte[] | HardcodedSymmetricEncryptionKey.cs:112:63:112:65 | key : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:50:35:50:35 | access to local variable c : Byte[] | HardcodedSymmetricEncryptionKey.cs:59:64:59:71 | password : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:59:64:59:71 | password : Byte[] | HardcodedSymmetricEncryptionKey.cs:68:87:68:94 | access to parameter password | +| HardcodedSymmetricEncryptionKey.cs:103:57:103:59 | key : Byte[] | HardcodedSymmetricEncryptionKey.cs:108:23:108:25 | access to parameter key | +| HardcodedSymmetricEncryptionKey.cs:112:63:112:65 | key : Byte[] | HardcodedSymmetricEncryptionKey.cs:121:87:121:89 | access to parameter key | +nodes +| HardcodedSymmetricEncryptionKey.cs:17:21:17:97 | array creation of type Byte[] | semmle.label | array creation of type Byte[] | +| HardcodedSymmetricEncryptionKey.cs:22:23:22:99 | array creation of type Byte[] | semmle.label | array creation of type Byte[] | +| HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | semmle.label | array creation of type Byte[] : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:28:39:28:116 | call to method GetBytes : Byte[] | semmle.label | call to method GetBytes : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:28:62:28:115 | "Hello, world: here is a very bad way to create a key" : String | semmle.label | "Hello, world: here is a very bad way to create a key" : String | +| HardcodedSymmetricEncryptionKey.cs:31:21:31:21 | access to local variable d | semmle.label | access to local variable d | +| HardcodedSymmetricEncryptionKey.cs:36:37:36:37 | access to local variable d : Byte[] | semmle.label | access to local variable d : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:41:50:41:50 | access to local variable c : Byte[] | semmle.label | access to local variable c : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:44:51:44:69 | access to local variable byteArrayFromString : Byte[] | semmle.label | access to local variable byteArrayFromString : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:50:35:50:35 | access to local variable c : Byte[] | semmle.label | access to local variable c : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:59:64:59:71 | password : Byte[] | semmle.label | password : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:68:87:68:94 | access to parameter password | semmle.label | access to parameter password | +| HardcodedSymmetricEncryptionKey.cs:103:57:103:59 | key : Byte[] | semmle.label | key : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:108:23:108:25 | access to parameter key | semmle.label | access to parameter key | +| HardcodedSymmetricEncryptionKey.cs:112:63:112:65 | key : Byte[] | semmle.label | key : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:121:87:121:89 | access to parameter key | semmle.label | access to parameter key | +subpaths +#select +| HardcodedSymmetricEncryptionKey.cs:17:21:17:97 | array creation of type Byte[] | HardcodedSymmetricEncryptionKey.cs:17:21:17:97 | array creation of type Byte[] | HardcodedSymmetricEncryptionKey.cs:17:21:17:97 | array creation of type Byte[] | This hard-coded $@ is used in symmetric algorithm in Key property assignment | HardcodedSymmetricEncryptionKey.cs:17:21:17:97 | array creation of type Byte[] | symmetric key | +| HardcodedSymmetricEncryptionKey.cs:22:23:22:99 | array creation of type Byte[] | HardcodedSymmetricEncryptionKey.cs:22:23:22:99 | array creation of type Byte[] | HardcodedSymmetricEncryptionKey.cs:22:23:22:99 | array creation of type Byte[] | This hard-coded $@ is used in symmetric algorithm in Key property assignment | HardcodedSymmetricEncryptionKey.cs:22:23:22:99 | array creation of type Byte[] | symmetric key | +| HardcodedSymmetricEncryptionKey.cs:31:21:31:21 | access to local variable d | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | HardcodedSymmetricEncryptionKey.cs:31:21:31:21 | access to local variable d | This hard-coded $@ is used in symmetric algorithm in Key property assignment | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] | symmetric key | +| HardcodedSymmetricEncryptionKey.cs:68:87:68:94 | access to parameter password | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | HardcodedSymmetricEncryptionKey.cs:68:87:68:94 | access to parameter password | This hard-coded $@ is used in symmetric algorithm in Decryptor(rgbKey, IV) | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] | symmetric key | +| HardcodedSymmetricEncryptionKey.cs:108:23:108:25 | access to parameter key | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | HardcodedSymmetricEncryptionKey.cs:108:23:108:25 | access to parameter key | This hard-coded $@ is used in symmetric algorithm in Key property assignment | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] | symmetric key | +| HardcodedSymmetricEncryptionKey.cs:121:87:121:89 | access to parameter key | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | HardcodedSymmetricEncryptionKey.cs:121:87:121:89 | access to parameter key | This hard-coded $@ is used in symmetric algorithm in Encryptor(rgbKey, IV) | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] | symmetric key | +| HardcodedSymmetricEncryptionKey.cs:121:87:121:89 | access to parameter key | HardcodedSymmetricEncryptionKey.cs:28:62:28:115 | "Hello, world: here is a very bad way to create a key" : String | HardcodedSymmetricEncryptionKey.cs:121:87:121:89 | access to parameter key | This hard-coded $@ is used in symmetric algorithm in Encryptor(rgbKey, IV) | HardcodedSymmetricEncryptionKey.cs:28:62:28:115 | "Hello, world: here is a very bad way to create a key" | symmetric key | From 8147d2048e4821991886b17b6aa95f808ac55560 Mon Sep 17 00:00:00 2001 From: Bas van Schaik <5082246+sj@users.noreply.github.com> Date: Fri, 11 Nov 2022 10:36:26 +0000 Subject: [PATCH 131/796] Remove issue template for LGTM.com false positive reports --- .../lgtm-com---false-positive.md | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/lgtm-com---false-positive.md diff --git a/.github/ISSUE_TEMPLATE/lgtm-com---false-positive.md b/.github/ISSUE_TEMPLATE/lgtm-com---false-positive.md deleted file mode 100644 index 94a84906f24..00000000000 --- a/.github/ISSUE_TEMPLATE/lgtm-com---false-positive.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: LGTM.com - false positive -about: Tell us about an alert that shouldn't be reported -title: LGTM.com - false positive -labels: false-positive -assignees: '' - ---- - -**Description of the false positive** - - - -**URL to the alert on the project page on LGTM.com** - - From be60a871a316862adb5958a06683c4f623685af1 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Fri, 11 Nov 2022 12:01:23 +0000 Subject: [PATCH 132/796] Ruby: tweak comment --- ruby/ql/lib/codeql/ruby/Concepts.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/Concepts.qll b/ruby/ql/lib/codeql/ruby/Concepts.qll index a42fa354660..54eee4e3e0a 100644 --- a/ruby/ql/lib/codeql/ruby/Concepts.qll +++ b/ruby/ql/lib/codeql/ruby/Concepts.qll @@ -17,7 +17,7 @@ private import codeql.ruby.ApiGraphs * Often, it is worthy of an alert if a SQL statement is constructed such that * executing it would be a security risk. * - * If it is important that the SQL statement is indeed executed, use `SqlExecution`. + * If it is important that the SQL statement is executed, use `SqlExecution`. * * Extend this class to refine existing API models. If you want to model new APIs, * extend `SqlConstruction::Range` instead. @@ -35,7 +35,7 @@ module SqlConstruction { * Often, it is worthy of an alert if a SQL statement is constructed such that * executing it would be a security risk. * - * If it is important that the SQL statement is indeed executed, use `SqlExecution`. + * If it is important that the SQL statement is executed, use `SqlExecution`. * * Extend this class to model new APIs. If you want to refine existing API models, * extend `SqlConstruction` instead. From f659ee3e0be655385dcaf001fb219b86ea6624bf Mon Sep 17 00:00:00 2001 From: Gustav Date: Fri, 11 Nov 2022 13:07:30 +0100 Subject: [PATCH 133/796] Go: Optimize trap.Writer by buffering gzip writes The TRAP writer already buffers writes before emitting to file, but running gzip compression is also fairly costly (especially if you only do it a couple of bytes at a time). Thus, this injects another buffer that collects the emitted tuples in string form, and only triggers gzip compression once the buffer is full. In my local testing, this buffering was actually more beneficial than the one between gzip and file (likely because the gzip writer already emits data in chunks), but that one is still beneficial. --- go/extractor/trap/trapwriter.go | 34 ++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/go/extractor/trap/trapwriter.go b/go/extractor/trap/trapwriter.go index 4c0911e24d7..2a3944705bf 100644 --- a/go/extractor/trap/trapwriter.go +++ b/go/extractor/trap/trapwriter.go @@ -19,7 +19,8 @@ import ( // A Writer provides methods for writing data to a TRAP file type Writer struct { zip *gzip.Writer - w *bufio.Writer + wzip *bufio.Writer + wfile *bufio.Writer file *os.File Labeler *Labeler path string @@ -54,11 +55,13 @@ func NewWriter(path string, pkg *packages.Package) (*Writer, error) { if err != nil { return nil, err } - bufioWriter := bufio.NewWriter(tmpFile) - zipWriter := gzip.NewWriter(bufioWriter) + bufioFileWriter := bufio.NewWriter(tmpFile) + zipWriter := gzip.NewWriter(bufioFileWriter) + bufioZipWriter := bufio.NewWriter(zipWriter) tw := &Writer{ zipWriter, - bufioWriter, + bufioZipWriter, + bufioFileWriter, tmpFile, nil, path, @@ -88,13 +91,18 @@ func trapFolder() (string, error) { // Close the underlying file writer func (tw *Writer) Close() error { - err := tw.zip.Close() + err := tw.wzip.Flush() + if err != nil { + // throw away file close error + tw.file.Close() + } + err = tw.zip.Close() if err != nil { // return zip-close error, but ignore file-close error tw.file.Close() return err } - err = tw.w.Flush() + err = tw.wfile.Flush() if err != nil { // throw away close error because write errors are likely to be more important tw.file.Close() @@ -145,24 +153,24 @@ func capStringLength(s string) string { // Emit writes out a tuple of values for the given `table` func (tw *Writer) Emit(table string, values []interface{}) error { - fmt.Fprintf(tw.zip, "%s(", table) + fmt.Fprintf(tw.wzip, "%s(", table) for i, value := range values { if i > 0 { - fmt.Fprint(tw.zip, ", ") + fmt.Fprint(tw.wzip, ", ") } switch value := value.(type) { case Label: - fmt.Fprint(tw.zip, value.id) + fmt.Fprint(tw.wzip, value.id) case string: - fmt.Fprintf(tw.zip, "\"%s\"", escapeString(capStringLength(value))) + fmt.Fprintf(tw.wzip, "\"%s\"", escapeString(capStringLength(value))) case int: - fmt.Fprintf(tw.zip, "%d", value) + fmt.Fprintf(tw.wzip, "%d", value) case float64: - fmt.Fprintf(tw.zip, "%e", value) + fmt.Fprintf(tw.wzip, "%e", value) default: return errors.New("Cannot emit value") } } - fmt.Fprintf(tw.zip, ")\n") + fmt.Fprintf(tw.wzip, ")\n") return nil } From 131fc986b48d823cfd724fdecc196194395f4058 Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 11 Nov 2022 13:49:46 +0100 Subject: [PATCH 134/796] Python: Apply suggestions from code review Co-authored-by: Rasmus Wriedt Larsen Co-authored-by: yoff --- .../python/dataflow/new/internal/ImportResolution.qll | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll index e1e4381519c..f1f3da84d74 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -35,10 +35,10 @@ private import semmle.python.dataflow.new.TypeTracker * 1. If `foo` is a module, and `bar` is an attribute of `foo`, then `from foo import bar` imports * the attribute `bar` into the current module (binding it to the name `bar`). * 2. If `foo` is a package, and `bar` is a submodule of `foo`, then `from foo import bar` first imports - * `foo.bar`, and then attempts to locate the `bar` attribute again. In most cases, that attribute + * `foo.bar`, and then reads the `bar` attribute on `foo`. In most cases, that attribute * will then point to the `bar` submodule. * - * Now, when in comes to how these imports are represented in the AST, things get a bit complicated. + * Now, when it comes to how these imports are represented in the AST, things get a bit complicated. * First of all, both of the above forms of imports get mapped to the same kind of AST node: * `Import`. An `Import` node has a sequence of names, each of which is an `Alias` node. This `Alias` * node represents the `x as y` bit of each imported module. @@ -230,7 +230,7 @@ module ImportResolution { module_reexport(p, attr_name, m) ) or - // Submodules that are implicitly defined when importing via `from ... import ...` statements. + // Submodules that are implicitly defined whith relative imports of the form `from .foo import ...`. // In practice, we create a definition for each module in a package, even if it is not imported. exists(string submodule, Module package | SsaSource::init_module_submodule_defn(result.asVar().getSourceVariable(), From 7f790432cc4a34d0ca1c4695a51e899458b133ef Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 11 Nov 2022 14:40:58 +0100 Subject: [PATCH 135/796] Python: More review suggestions I could have sworn I added all of them to the batch, but somehow these slipped through. Co-authored-by: yoff Co-authored-by: Rasmus Wriedt Larsen --- .../dataflow/new/internal/ImportResolution.qll | 2 +- .../import-resolution/importflow.ql | 2 +- .../experimental/import-resolution/main.py | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll index f1f3da84d74..823bb34b9e2 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -78,7 +78,7 @@ module ImportResolution { ) or exists(Alias a | - defn.asExpr() = [a.getValue(), a.getValue().(ImportMember).getModule()] and + defn.asExpr() = [a.getValue().(ImportExpr), a.getValue().(ImportMember).getModule()] and a.getAsname().(Name).getId() = name and defn.getScope() = m ) diff --git a/python/ql/test/experimental/import-resolution/importflow.ql b/python/ql/test/experimental/import-resolution/importflow.ql index 0e7d300d328..9439ffe0693 100644 --- a/python/ql/test/experimental/import-resolution/importflow.ql +++ b/python/ql/test/experimental/import-resolution/importflow.ql @@ -27,7 +27,7 @@ private class ImportConfiguration extends DataFlow::Configuration { class ResolutionTest extends InlineExpectationsTest { ResolutionTest() { this = "ResolutionTest" } - override string getARelevantTag() { result = "import" } + override string getARelevantTag() { result = "prints" } override predicate hasActualResult(Location location, string element, string tag, string value) { exists(DataFlow::PathNode source, DataFlow::PathNode sink, ImportConfiguration config | diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index 827bb78896b..801b081df0c 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -1,4 +1,22 @@ #! /usr/bin/env python3 +""" +A slightly complicated test setup. I wanted to both make sure I captured +the semantics of Python and also the fact that the kinds of global flow +we expect to see are indeed present. + +The code is executable, and prints out both when the execution reaches +certain files, and also what values are assigned to the various +attributes that are referenced throughout the program. These values are +validated in the test as well. + +My original version used introspection to avoid referencing attributes +directly (thus enabling better error diagnostics), but unfortunately +that made it so that the model couldn't follow what was going on. + +The current setup is a bit clunky (and Python's scoping rules makes it +especially so -- cf. the explicit calls to `globals` and `locals`), but +I think it does the job okay. +""" from __future__ import print_function import sys From b540eb094cb5ba7aea5f795ce4751f49106920ce Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 11 Nov 2022 13:36:55 +0000 Subject: [PATCH 136/796] Python: Various small fixes - Swaps `module_reference_in_scope` and `module_name_in_scope`. - uses `AttrRead::accesses` instead of `getObject`, etc. - Removes an errant `none()`. - Expands the QLDoc for some of the predicates. --- .../new/internal/ImportResolution.qll | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll index 823bb34b9e2..3a9623dfb53 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -34,9 +34,11 @@ private import semmle.python.dataflow.new.TypeTracker * * 1. If `foo` is a module, and `bar` is an attribute of `foo`, then `from foo import bar` imports * the attribute `bar` into the current module (binding it to the name `bar`). - * 2. If `foo` is a package, and `bar` is a submodule of `foo`, then `from foo import bar` first imports - * `foo.bar`, and then reads the `bar` attribute on `foo`. In most cases, that attribute - * will then point to the `bar` submodule. + * 2. If `foo` is a package, and `bar` is already defined in `foo/__init__.py`, + * that value will be imported. If it is not defined, and `bar` is a submodule of `foo`, then + * `bar` is imported to `foo`, and the `bar` submodule imported. + * Note: We don't currently model if the attribute is already defined in `__init__.py` + * and always assume that the submodule will be used. * * Now, when it comes to how these imports are represented in the AST, things get a bit complicated. * First of all, both of the above forms of imports get mapped to the same kind of AST node: @@ -58,7 +60,7 @@ private import semmle.python.dataflow.new.TypeTracker * package, or the `bar` subpackage of the `foo` package. The practical difference here is the name of * the module that is imported, as the package `foo.bar` will have the "name" `foo.bar.__init__`, * corresponding to the fact that the code that is executed is in the `__init__.py` file of the - * `bar` package. + * `bar` subpackage. */ module ImportResolution { /** @@ -168,8 +170,17 @@ module ImportResolution { isPreferredModuleForName(result.getFile(), i.getImportedModuleName()) } - /** Gets a data-flow node that may be a reference to a module with the name `module_name`. */ - DataFlow::Node getReferenceToModuleName(string module_name) { + /** + * Gets a data-flow node that may be a reference to a module with the name `module_name`. + * + * This is a helper predicate for `getImmediateModuleReference`. It captures the fact that in an + * import such as `import foo`, + * - `foo` may simply be the name of a module, or + * - `foo` may be the name of a package (in which case its name is actually `foo.__init__`), or + * - `foo` may be a module name that has been added to `sys.modules` (in which case its actual name can + * be anything, for instance `os.path` is either `posixpath` or `ntpath`). + */ + private DataFlow::Node getReferenceToModuleName(string module_name) { // Regular import statements, e.g. // import foo # implicitly `import foo as foo` // import foo as foo_alias @@ -188,7 +199,6 @@ module ImportResolution { // from foo.bar import baz # imports foo.bar.baz as baz // from foo.bar import baz as baz_alias # imports foo.bar.baz as baz_alias exists(Import i, Alias a, ImportMember im | a = i.getAName() and im = a.getValue() | - i.isFromImport() and result.asExpr() = a.getAsname() and module_name = im.getModule().(ImportExpr).getImportedModuleName() + "." + im.getName() ) @@ -201,12 +211,15 @@ module ImportResolution { any(ImportMember i | i.getModule().(ImportExpr).getImportedModuleName() = module_name or - i.getModule().(ImportExpr).getImportedModuleName() + "." + i.getName() = module_name and - none() + i.getModule().(ImportExpr).getImportedModuleName() + "." + i.getName() = module_name ) } - /** Gets a dataflow node that is an immediate reference to the module `m`. */ + /** + * Gets a dataflow node that is an immediate reference to the module `m`. + * + * Because of attribute lookups, this is mutually recursive with `getModuleReference`. + */ DataFlow::Node getImmediateModuleReference(Module m) { exists(string module_name | result = getReferenceToModuleName(module_name) | // Depending on whether the referenced module is a package or not, we may need to add a @@ -219,9 +232,8 @@ module ImportResolution { or // Reading an attribute on a module may return a submodule (or subpackage). exists(DataFlow::AttrRead ar, Module p, string attr_name | - ar.getObject() = getModuleReference(p) and + ar.accesses(getModuleReference(p), attr_name) and attr_name = any(Module m0).getFile().getStem() and - ar.getAttributeName() = attr_name and result = ar | isPreferredModuleForName(m.getFile(), p.getPackageName() + "." + attr_name + ["", ".__init__"]) @@ -242,7 +254,7 @@ module ImportResolution { /** Join-order helper for `getModuleReference`. */ pragma[nomagic] - private predicate module_name_in_scope(DataFlow::Node node, Scope s, string name, Module m) { + private predicate module_reference_in_scope(DataFlow::Node node, Scope s, string name, Module m) { node.getScope() = s and node.asExpr().(Name).getId() = name and pragma[only_bind_into](node) = getImmediateModuleReference(pragma[only_bind_into](m)) @@ -250,7 +262,7 @@ module ImportResolution { /** Join-order helper for `getModuleReference`. */ pragma[nomagic] - private predicate module_reference_in_scope(DataFlow::Node node, Scope s, string name) { + private predicate module_name_in_scope(DataFlow::Node node, Scope s, string name) { node.getScope() = s and exists(Name n | n = node.asExpr() | n.getId() = name and @@ -277,9 +289,9 @@ module ImportResolution { or // A reference to a name that is bound to a module in an enclosing scope. exists(DataFlow::Node def, Scope def_scope, Scope use_scope, string name | - module_name_in_scope(pragma[only_bind_into](def), pragma[only_bind_into](def_scope), + module_reference_in_scope(pragma[only_bind_into](def), pragma[only_bind_into](def_scope), pragma[only_bind_into](name), pragma[only_bind_into](m)) and - module_reference_in_scope(result, use_scope, name) and + module_name_in_scope(result, use_scope, name) and use_scope.getEnclosingScope*() = def_scope ) } From 7d54b542b5fe304dc75ca35e5f1a46474637190b Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Fri, 11 Nov 2022 13:00:07 +0000 Subject: [PATCH 137/796] Kotlin: Put extractor name in a resource rather than generating code --- java/kotlin-extractor/build.py | 13 +++++++------ .../src/main/kotlin/KotlinExtractorExtension.kt | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/java/kotlin-extractor/build.py b/java/kotlin-extractor/build.py index 497e6da049e..ebca028be63 100755 --- a/java/kotlin-extractor/build.py +++ b/java/kotlin-extractor/build.py @@ -103,7 +103,7 @@ def compile_to_dir(srcs, classpath, java_classpath, output): '-classpath', os.path.pathsep.join([output, classpath, java_classpath])] + [s for s in srcs if s.endswith(".java")]) -def compile_to_jar(build_dir, srcs, classpath, java_classpath, output): +def compile_to_jar(build_dir, tmp_src_dir, srcs, classpath, java_classpath, output): class_dir = build_dir + '/classes' if os.path.exists(class_dir): @@ -114,7 +114,7 @@ def compile_to_jar(build_dir, srcs, classpath, java_classpath, output): run_process(['jar', 'cf', output, '-C', class_dir, '.', - '-C', 'src/main/resources', 'META-INF']) + '-C', tmp_src_dir + '/main/resources', '.']) shutil.rmtree(class_dir) @@ -185,9 +185,10 @@ def compile(jars, java_jars, dependency_folder, transform_to_embeddable, output, include_version_folder = tmp_src_dir + '/main/kotlin/utils/versions/to_include' os.makedirs(include_version_folder) - with open(tmp_src_dir + '/main/kotlin/utils/ExtractorName.kt', 'w') as f: - f.write('package com.github.codeql\n') - f.write('val extractor_name: String = "' + output + '"\n') + resource_dir = tmp_src_dir + '/main/resources/com/github/codeql' + os.makedirs(resource_dir) + with open(resource_dir + '/extractor.name', 'w') as f: + f.write(output) parsed_current_version = kotlin_plugin_versions.version_string_to_tuple( current_version) @@ -215,7 +216,7 @@ def compile(jars, java_jars, dependency_folder, transform_to_embeddable, output, transform_to_embeddable(srcs) - compile_to_jar(build_dir, srcs, classpath, java_classpath, output) + compile_to_jar(build_dir, tmp_src_dir, srcs, classpath, java_classpath, output) shutil.rmtree(tmp_src_dir) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt b/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt index 2ffef600476..71e1862a22e 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt @@ -132,6 +132,7 @@ class KotlinExtractorExtension( val compilation: Label = StringLabel("compilation") tw.writeCompilation_started(compilation) tw.writeCompilation_info(compilation, "Kotlin Compiler Version", KotlinCompilerVersion.getVersion() ?: "") + val extractor_name = this::class.java.getResource("extractor.name")?.readText() ?: "" tw.writeCompilation_info(compilation, "Kotlin Extractor Name", extractor_name) if (compilationStartTime != null) { tw.writeCompilation_compiler_times(compilation, -1.0, (System.currentTimeMillis()-compilationStartTime)/1000.0) From a8a7a59ae83dda9bd5aec5a7978614ddff9fab75 Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 11 Nov 2022 14:47:35 +0000 Subject: [PATCH 138/796] Python: Add test for attribute name clash --- .../experimental/import-resolution/attr_clash/__init__.py | 6 ++++++ .../import-resolution/attr_clash/clashing_attr.py | 4 ++++ .../import-resolution/attr_clash/non_clashing_submodule.py | 4 ++++ python/ql/test/experimental/import-resolution/main.py | 7 ++++++- python/ql/test/experimental/import-resolution/trace.py | 3 +++ 5 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 python/ql/test/experimental/import-resolution/attr_clash/__init__.py create mode 100644 python/ql/test/experimental/import-resolution/attr_clash/clashing_attr.py create mode 100644 python/ql/test/experimental/import-resolution/attr_clash/non_clashing_submodule.py diff --git a/python/ql/test/experimental/import-resolution/attr_clash/__init__.py b/python/ql/test/experimental/import-resolution/attr_clash/__init__.py new file mode 100644 index 00000000000..d210fbd703b --- /dev/null +++ b/python/ql/test/experimental/import-resolution/attr_clash/__init__.py @@ -0,0 +1,6 @@ +from trace import * +enter(__file__) + +clashing_attr = "clashing_attr" + +exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/attr_clash/clashing_attr.py b/python/ql/test/experimental/import-resolution/attr_clash/clashing_attr.py new file mode 100644 index 00000000000..7544594893b --- /dev/null +++ b/python/ql/test/experimental/import-resolution/attr_clash/clashing_attr.py @@ -0,0 +1,4 @@ +from trace import * +enter(__file__) + +exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/attr_clash/non_clashing_submodule.py b/python/ql/test/experimental/import-resolution/attr_clash/non_clashing_submodule.py new file mode 100644 index 00000000000..7544594893b --- /dev/null +++ b/python/ql/test/experimental/import-resolution/attr_clash/non_clashing_submodule.py @@ -0,0 +1,4 @@ +from trace import * +enter(__file__) + +exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index 801b081df0c..d2ad1b9e337 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -35,7 +35,7 @@ import foo as foo_alias #$ imports=foo as=foo_alias check("foo_alias.foo_attr", foo_alias.foo_attr, "foo_attr", globals()) #$ prints=foo_attr # A reference to a reexported module -check("foo.bar_reexported.bar_attr", foo.bar_reexported.bar_attr, "bar_attr", globals()) #$ prints=bar_attr +check("foo.bar_reexported.bar_attr", foo.bar_reexported.bar_attr, "bar_attr", globals()) #$ MISSING: prints=bar_attr # A simple "import from" statement. from bar import bar_attr @@ -73,6 +73,11 @@ if sys.version_info[0] >= 3: from namespace_package.namespace_module import namespace_module_attr check("namespace_module_attr", namespace_module_attr, "namespace_module_attr", globals()) #$ prints=namespace_module_attr + +from attr_clash import clashing_attr, non_clashing_submodule #$ imports=attr_clash.clashing_attr as=clashing_attr imports=attr_clash.non_clashing_submodule as=non_clashing_submodule +check("clashing_attr", clashing_attr, "clashing_attr", globals()) #$ prints=clashing_attr +check("non_clashing_submodule", non_clashing_submodule, "", globals()) + exit(__file__) print() diff --git a/python/ql/test/experimental/import-resolution/trace.py b/python/ql/test/experimental/import-resolution/trace.py index 04e847304e9..90d8efba3fb 100644 --- a/python/ql/test/experimental/import-resolution/trace.py +++ b/python/ql/test/experimental/import-resolution/trace.py @@ -24,6 +24,7 @@ def status(): return _status def check(attr_path, actual_value, expected_value, bindings): + global _status parts = attr_path.split(".") base, parts = parts[0], parts[1:] if base not in bindings: @@ -40,6 +41,8 @@ def check(attr_path, actual_value, expected_value, bindings): if val != actual_value: print("Error: Value at path {} and actual value are out of sync! {} != {}".format(attr_path, val, actual_value)) _status = 1 + if str(val).startswith("" if val != expected_value: print("Error: Expected {} to be {}, got {}".format(attr_path, expected_value, val)) _status = 1 From a08253b6d0e2f8c53332dd270250feaa29bf0741 Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 11 Nov 2022 14:50:04 +0000 Subject: [PATCH 139/796] Python: Fix typo --- .../semmle/python/dataflow/new/internal/ImportResolution.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll index 3a9623dfb53..dd92cbb7a45 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -242,7 +242,7 @@ module ImportResolution { module_reexport(p, attr_name, m) ) or - // Submodules that are implicitly defined whith relative imports of the form `from .foo import ...`. + // Submodules that are implicitly defined with relative imports of the form `from .foo import ...`. // In practice, we create a definition for each module in a package, even if it is not imported. exists(string submodule, Module package | SsaSource::init_module_submodule_defn(result.asVar().getSourceVariable(), From b5c7d6bfcd5c2af418b8ec353fdd5685ad354ced Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Fri, 11 Nov 2022 14:57:36 +0000 Subject: [PATCH 140/796] Kotlin: Fix build on OS X --- java/kotlin-extractor/build.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/kotlin-extractor/build.py b/java/kotlin-extractor/build.py index ebca028be63..05cb1204d86 100755 --- a/java/kotlin-extractor/build.py +++ b/java/kotlin-extractor/build.py @@ -114,7 +114,8 @@ def compile_to_jar(build_dir, tmp_src_dir, srcs, classpath, java_classpath, outp run_process(['jar', 'cf', output, '-C', class_dir, '.', - '-C', tmp_src_dir + '/main/resources', '.']) + '-C', tmp_src_dir + '/main/resources', 'META-INF', + '-C', tmp_src_dir + '/main/resources', 'com/github/codeql/extractor.name']) shutil.rmtree(class_dir) From f92d836607a48948054e5ddd205b93b82ddd1bb8 Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 11 Nov 2022 16:03:14 +0000 Subject: [PATCH 141/796] Python: Fix test failure Casting to `ImportExpr` caused the `typetracking_imports` test to fail. --- .../semmle/python/dataflow/new/internal/ImportResolution.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll index dd92cbb7a45..9e04d3f9681 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -80,7 +80,7 @@ module ImportResolution { ) or exists(Alias a | - defn.asExpr() = [a.getValue().(ImportExpr), a.getValue().(ImportMember).getModule()] and + defn.asExpr() = [a.getValue(), a.getValue().(ImportMember).getModule()] and a.getAsname().(Name).getId() = name and defn.getScope() = m ) From fea4b816af4646904e4c4fe8e8bc98e9d52af32e Mon Sep 17 00:00:00 2001 From: Gustav Date: Fri, 11 Nov 2022 17:12:13 +0100 Subject: [PATCH 142/796] Fix double close Co-authored-by: Chris Smowton --- go/extractor/trap/trapwriter.go | 1 + 1 file changed, 1 insertion(+) diff --git a/go/extractor/trap/trapwriter.go b/go/extractor/trap/trapwriter.go index 2a3944705bf..0833d845830 100644 --- a/go/extractor/trap/trapwriter.go +++ b/go/extractor/trap/trapwriter.go @@ -95,6 +95,7 @@ func (tw *Writer) Close() error { if err != nil { // throw away file close error tw.file.Close() + return err } err = tw.zip.Close() if err != nil { From 3514694cdfc5c7ab49e0ecdec63a73244dabd526 Mon Sep 17 00:00:00 2001 From: Gustav Date: Fri, 11 Nov 2022 18:39:25 +0100 Subject: [PATCH 143/796] Fix direct access to trap.Writer from trap.Labeler --- go/extractor/trap/labels.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/extractor/trap/labels.go b/go/extractor/trap/labels.go index 1e9bd298447..f1572fb874e 100644 --- a/go/extractor/trap/labels.go +++ b/go/extractor/trap/labels.go @@ -57,7 +57,7 @@ func (l *Labeler) GlobalID(key string) Label { label, exists := l.keyLabels[key] if !exists { id := l.nextID() - fmt.Fprintf(l.tw.zip, "%s=@\"%s\"\n", id, escapeString(key)) + fmt.Fprintf(l.tw.wzip, "%s=@\"%s\"\n", id, escapeString(key)) label = Label{id} l.keyLabels[key] = label } @@ -90,7 +90,7 @@ func (l *Labeler) LocalID(nd interface{}) Label { // FreshID creates a fresh label and returns it func (l *Labeler) FreshID() Label { id := l.nextID() - fmt.Fprintf(l.tw.zip, "%s=*\n", id) + fmt.Fprintf(l.tw.wzip, "%s=*\n", id) return Label{id} } From 0dadf0bbb4254ddcaa41ddb9b780b553a21c1ad3 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Fri, 11 Nov 2022 17:16:24 +0000 Subject: [PATCH 144/796] Ruby: add flow summary for Enumerable#index_by --- .../codeql/ruby/frameworks/ActiveSupport.qll | 12 +++- .../ActiveSupportDataFlow.expected | 63 +++++++++++++++++++ .../active_support/hash_extensions.rb | 13 ++++ 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll index 47742531e30..7d3286a0a74 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll @@ -284,7 +284,17 @@ module ActiveSupport { preservesValue = true } } - // TODO: index_by, index_with, pick, pluck (they require Hash dataflow) + + private class IndexBySummary extends SimpleSummarizedCallable { + IndexBySummary() { this = "index_by" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[self].Element[any]" and + output = ["Argument[block].Parameter[0]", "ReturnValue.Element[?]"] and + preservesValue = true + } + } + // TODO: index_with, pick, pluck (they require Hash dataflow) } } diff --git a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected index 0df4f1235f8..11b6b46ee3e 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected +++ b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected @@ -258,6 +258,34 @@ edges | hash_extensions.rb:58:10:58:10 | x [element :a] : | hash_extensions.rb:58:10:58:14 | ...[...] | | hash_extensions.rb:59:10:59:10 | x [element :b] : | hash_extensions.rb:59:10:59:14 | ...[...] | | hash_extensions.rb:59:10:59:10 | x [element :b] : | hash_extensions.rb:59:10:59:14 | ...[...] | +| hash_extensions.rb:67:15:67:25 | call to source : | hash_extensions.rb:68:9:68:14 | values [element 0] : | +| hash_extensions.rb:67:15:67:25 | call to source : | hash_extensions.rb:68:9:68:14 | values [element 0] : | +| hash_extensions.rb:67:28:67:38 | call to source : | hash_extensions.rb:68:9:68:14 | values [element 1] : | +| hash_extensions.rb:67:28:67:38 | call to source : | hash_extensions.rb:68:9:68:14 | values [element 1] : | +| hash_extensions.rb:67:41:67:51 | call to source : | hash_extensions.rb:68:9:68:14 | values [element 2] : | +| hash_extensions.rb:67:41:67:51 | call to source : | hash_extensions.rb:68:9:68:14 | values [element 2] : | +| hash_extensions.rb:68:9:68:14 | values [element 0] : | hash_extensions.rb:68:9:71:7 | call to index_by [element] : | +| hash_extensions.rb:68:9:68:14 | values [element 0] : | hash_extensions.rb:68:9:71:7 | call to index_by [element] : | +| hash_extensions.rb:68:9:68:14 | values [element 0] : | hash_extensions.rb:68:29:68:33 | value : | +| hash_extensions.rb:68:9:68:14 | values [element 0] : | hash_extensions.rb:68:29:68:33 | value : | +| hash_extensions.rb:68:9:68:14 | values [element 1] : | hash_extensions.rb:68:9:71:7 | call to index_by [element] : | +| hash_extensions.rb:68:9:68:14 | values [element 1] : | hash_extensions.rb:68:9:71:7 | call to index_by [element] : | +| hash_extensions.rb:68:9:68:14 | values [element 1] : | hash_extensions.rb:68:29:68:33 | value : | +| hash_extensions.rb:68:9:68:14 | values [element 1] : | hash_extensions.rb:68:29:68:33 | value : | +| hash_extensions.rb:68:9:68:14 | values [element 2] : | hash_extensions.rb:68:9:71:7 | call to index_by [element] : | +| hash_extensions.rb:68:9:68:14 | values [element 2] : | hash_extensions.rb:68:9:71:7 | call to index_by [element] : | +| hash_extensions.rb:68:9:68:14 | values [element 2] : | hash_extensions.rb:68:29:68:33 | value : | +| hash_extensions.rb:68:9:68:14 | values [element 2] : | hash_extensions.rb:68:29:68:33 | value : | +| hash_extensions.rb:68:9:71:7 | call to index_by [element] : | hash_extensions.rb:73:10:73:10 | h [element] : | +| hash_extensions.rb:68:9:71:7 | call to index_by [element] : | hash_extensions.rb:73:10:73:10 | h [element] : | +| hash_extensions.rb:68:9:71:7 | call to index_by [element] : | hash_extensions.rb:74:10:74:10 | h [element] : | +| hash_extensions.rb:68:9:71:7 | call to index_by [element] : | hash_extensions.rb:74:10:74:10 | h [element] : | +| hash_extensions.rb:68:29:68:33 | value : | hash_extensions.rb:69:14:69:18 | value | +| hash_extensions.rb:68:29:68:33 | value : | hash_extensions.rb:69:14:69:18 | value | +| hash_extensions.rb:73:10:73:10 | h [element] : | hash_extensions.rb:73:10:73:16 | ...[...] | +| hash_extensions.rb:73:10:73:10 | h [element] : | hash_extensions.rb:73:10:73:16 | ...[...] | +| hash_extensions.rb:74:10:74:10 | h [element] : | hash_extensions.rb:74:10:74:16 | ...[...] | +| hash_extensions.rb:74:10:74:10 | h [element] : | hash_extensions.rb:74:10:74:16 | ...[...] | nodes | active_support.rb:10:9:10:18 | call to source : | semmle.label | call to source : | | active_support.rb:11:10:11:10 | x : | semmle.label | x : | @@ -594,6 +622,32 @@ nodes | hash_extensions.rb:59:10:59:10 | x [element :b] : | semmle.label | x [element :b] : | | hash_extensions.rb:59:10:59:14 | ...[...] | semmle.label | ...[...] | | hash_extensions.rb:59:10:59:14 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:67:15:67:25 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:67:15:67:25 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:67:28:67:38 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:67:28:67:38 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:67:41:67:51 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:67:41:67:51 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:68:9:68:14 | values [element 0] : | semmle.label | values [element 0] : | +| hash_extensions.rb:68:9:68:14 | values [element 0] : | semmle.label | values [element 0] : | +| hash_extensions.rb:68:9:68:14 | values [element 1] : | semmle.label | values [element 1] : | +| hash_extensions.rb:68:9:68:14 | values [element 1] : | semmle.label | values [element 1] : | +| hash_extensions.rb:68:9:68:14 | values [element 2] : | semmle.label | values [element 2] : | +| hash_extensions.rb:68:9:68:14 | values [element 2] : | semmle.label | values [element 2] : | +| hash_extensions.rb:68:9:71:7 | call to index_by [element] : | semmle.label | call to index_by [element] : | +| hash_extensions.rb:68:9:71:7 | call to index_by [element] : | semmle.label | call to index_by [element] : | +| hash_extensions.rb:68:29:68:33 | value : | semmle.label | value : | +| hash_extensions.rb:68:29:68:33 | value : | semmle.label | value : | +| hash_extensions.rb:69:14:69:18 | value | semmle.label | value | +| hash_extensions.rb:69:14:69:18 | value | semmle.label | value | +| hash_extensions.rb:73:10:73:10 | h [element] : | semmle.label | h [element] : | +| hash_extensions.rb:73:10:73:10 | h [element] : | semmle.label | h [element] : | +| hash_extensions.rb:73:10:73:16 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:73:10:73:16 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:74:10:74:10 | h [element] : | semmle.label | h [element] : | +| hash_extensions.rb:74:10:74:10 | h [element] : | semmle.label | h [element] : | +| hash_extensions.rb:74:10:74:16 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:74:10:74:16 | ...[...] | semmle.label | ...[...] | subpaths #select | active_support.rb:182:10:182:13 | ...[...] | active_support.rb:180:10:180:17 | call to source : | active_support.rb:182:10:182:13 | ...[...] | $@ | active_support.rb:180:10:180:17 | call to source : | call to source : | @@ -622,3 +676,12 @@ subpaths | hash_extensions.rb:56:10:56:14 | ...[...] | hash_extensions.rb:50:52:50:61 | call to taint : | hash_extensions.rb:56:10:56:14 | ...[...] | $@ | hash_extensions.rb:50:52:50:61 | call to taint : | call to taint : | | hash_extensions.rb:58:10:58:14 | ...[...] | hash_extensions.rb:50:14:50:23 | call to taint : | hash_extensions.rb:58:10:58:14 | ...[...] | $@ | hash_extensions.rb:50:14:50:23 | call to taint : | call to taint : | | hash_extensions.rb:59:10:59:14 | ...[...] | hash_extensions.rb:50:29:50:38 | call to taint : | hash_extensions.rb:59:10:59:14 | ...[...] | $@ | hash_extensions.rb:50:29:50:38 | call to taint : | call to taint : | +| hash_extensions.rb:69:14:69:18 | value | hash_extensions.rb:67:15:67:25 | call to source : | hash_extensions.rb:69:14:69:18 | value | $@ | hash_extensions.rb:67:15:67:25 | call to source : | call to source : | +| hash_extensions.rb:69:14:69:18 | value | hash_extensions.rb:67:28:67:38 | call to source : | hash_extensions.rb:69:14:69:18 | value | $@ | hash_extensions.rb:67:28:67:38 | call to source : | call to source : | +| hash_extensions.rb:69:14:69:18 | value | hash_extensions.rb:67:41:67:51 | call to source : | hash_extensions.rb:69:14:69:18 | value | $@ | hash_extensions.rb:67:41:67:51 | call to source : | call to source : | +| hash_extensions.rb:73:10:73:16 | ...[...] | hash_extensions.rb:67:15:67:25 | call to source : | hash_extensions.rb:73:10:73:16 | ...[...] | $@ | hash_extensions.rb:67:15:67:25 | call to source : | call to source : | +| hash_extensions.rb:73:10:73:16 | ...[...] | hash_extensions.rb:67:28:67:38 | call to source : | hash_extensions.rb:73:10:73:16 | ...[...] | $@ | hash_extensions.rb:67:28:67:38 | call to source : | call to source : | +| hash_extensions.rb:73:10:73:16 | ...[...] | hash_extensions.rb:67:41:67:51 | call to source : | hash_extensions.rb:73:10:73:16 | ...[...] | $@ | hash_extensions.rb:67:41:67:51 | call to source : | call to source : | +| hash_extensions.rb:74:10:74:16 | ...[...] | hash_extensions.rb:67:15:67:25 | call to source : | hash_extensions.rb:74:10:74:16 | ...[...] | $@ | hash_extensions.rb:67:15:67:25 | call to source : | call to source : | +| hash_extensions.rb:74:10:74:16 | ...[...] | hash_extensions.rb:67:28:67:38 | call to source : | hash_extensions.rb:74:10:74:16 | ...[...] | $@ | hash_extensions.rb:67:28:67:38 | call to source : | call to source : | +| hash_extensions.rb:74:10:74:16 | ...[...] | hash_extensions.rb:67:41:67:51 | call to source : | hash_extensions.rb:74:10:74:16 | ...[...] | $@ | hash_extensions.rb:67:41:67:51 | call to source : | call to source : | diff --git a/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb b/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb index 6e477f17aa8..6669cd83c37 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb +++ b/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb @@ -62,3 +62,16 @@ def m_extract!(x) end m_extract!(:c) + +def m_index_by + values = [source("a"), source("b"), source("c")] + h = values.index_by do |value| + sink value # $ hasValueFlow=a $ hasValueFlow=b $ hasValueFlow=c + make_key(value) + end + + sink h[:foo] # $ hasValueFlow=a $ hasValueFlow=b $ hasValueFlow=c + sink h[:bar] # $ hasValueFlow=a $ hasValueFlow=b $ hasValueFlow=c +end + +m_index_by() From 16ba5b1bb5602b8deeb99b15be076c4f3c890f16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Mon, 14 Nov 2022 12:30:16 +0100 Subject: [PATCH 145/796] Swift: update doctests --- swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalBad.swift | 2 +- swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalGood.swift | 2 +- swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.swift | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalBad.swift b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalBad.swift index 2e5b0233e79..111f8100ee2 100644 --- a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalBad.swift +++ b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalBad.swift @@ -3,4 +3,4 @@ let remoteData = try String(contentsOf: URL(string: "http://example.com/evil.jso ... -_ = try await webview.evaluateJavaScript("alert(" + remoteData + ")") // BAD +_ = try await webview.evaluateJavaScript("console.log(" + remoteData + ")") // BAD diff --git a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalGood.swift b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalGood.swift index a51ffd60b63..ea8f6c0d5ee 100644 --- a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalGood.swift +++ b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEvalGood.swift @@ -4,7 +4,7 @@ let remoteData = try String(contentsOf: URL(string: "http://example.com/evil.jso ... _ = try await webview.callAsyncJavaScript( - "alert(JSON.parse(data))", + "console.log(data)", arguments: ["data": remoteData], // GOOD contentWorld: .page ) diff --git a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.swift b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.swift index 36cee943b66..e65c182a4c3 100644 --- a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.swift +++ b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.swift @@ -317,10 +317,10 @@ func testQHelpExamples() { let webview = WKWebView() let remoteData = try String(contentsOf: URL(string: "http://example.com/evil.json")!) - _ = try await webview.evaluateJavaScript("alert(" + remoteData + ")") // BAD [NOT DETECTED - TODO: extract Callables of @MainActor method calls] + _ = try await webview.evaluateJavaScript("console.log(" + remoteData + ")") // BAD [NOT DETECTED - TODO: extract Callables of @MainActor method calls] _ = try await webview.callAsyncJavaScript( - "alert(JSON.parse(data))", + "console.log(data)", arguments: ["data": remoteData], // GOOD contentWorld: .page ) From 87ee979a122f6ae22afb5c7a696ae6b5a77ed312 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 14 Nov 2022 11:31:37 +0000 Subject: [PATCH 146/796] Java/Kotlin: Add compilation info to telemetry This will give info about which kotlinc versions are used. --- java/ql/src/Telemetry/ExtractorInformation.ql | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/java/ql/src/Telemetry/ExtractorInformation.ql b/java/ql/src/Telemetry/ExtractorInformation.ql index 0eb420ba651..00ce79796b2 100644 --- a/java/ql/src/Telemetry/ExtractorInformation.ql +++ b/java/ql/src/Telemetry/ExtractorInformation.ql @@ -9,6 +9,13 @@ import java import semmle.code.java.Diagnostics +predicate compilationInfo(string key, int value) { + exists(Compilation c, string infoKey | + key = infoKey + ": " + c.getInfo(infoKey) and + value = 1 + ) +} + predicate fileCount(string key, int value) { key = "Number of files" and value = strictcount(File f) @@ -55,6 +62,7 @@ predicate extractorDiagnostics(string key, int value) { from string key, int value where + compilationInfo(key, value) or fileCount(key, value) or fileCountByExtension(key, value) or totalNumberOfLines(key, value) or From c03eab2410cfcd446dd6a0238e19c29cbc940a9d Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Fri, 4 Nov 2022 12:31:59 +0100 Subject: [PATCH 147/796] Add XMLDocument sinks --- swift/ql/lib/codeql/swift/security/XXE.qll | 27 +++++- .../Security/CWE-611/testXMLDocumentXXE.swift | 86 +++++++++++++++++++ .../{testXXE.swift => testXMLParserXXE.swift} | 0 3 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 swift/ql/test/query-tests/Security/CWE-611/testXMLDocumentXXE.swift rename swift/ql/test/query-tests/Security/CWE-611/{testXXE.swift => testXMLParserXXE.swift} (100%) diff --git a/swift/ql/lib/codeql/swift/security/XXE.qll b/swift/ql/lib/codeql/swift/security/XXE.qll index 506225f54a1..da8513be645 100644 --- a/swift/ql/lib/codeql/swift/security/XXE.qll +++ b/swift/ql/lib/codeql/swift/security/XXE.qll @@ -20,8 +20,8 @@ class XxeAdditionalTaintStep extends Unit { } /** The XML argument of a `XMLParser` vulnerable to XXE. */ -private class DefaultXxeSink extends XxeSink { - DefaultXxeSink() { +private class XmlParserXxeSink extends XxeSink { + XmlParserXxeSink() { this.asExpr() = any(Argument a | a.getApplyExpr() instanceof VulnerableParser).getExpr() } } @@ -67,3 +67,26 @@ private class XmlParserRef extends Expr { private class XmlParserType extends NominalType { XmlParserType() { this.getFullName() = "XMLParser" } } + +/** The XML argument of a `XMLDocument` vulnerable to XXE. */ +private class XmlDocumentXxeSink extends XxeSink { + XmlDocumentXxeSink() { this.asExpr() = any(VulnerableXmlDocument d).getArgument(0).getExpr() } +} + +/** An `XMLDocument` that sets `nodeLoadExternalEntitiesAlways` in its options. */ +private class VulnerableXmlDocument extends ApplyExpr { + VulnerableXmlDocument() { + this.getStaticTarget().(ConstructorDecl).getEnclosingDecl().(NominalTypeDecl).getFullName() = + "XMLDocument" and + this.getArgument(1).getExpr().(ArrayExpr).getAnElement().(MemberRefExpr).getMember() instanceof + NodeLoadExternalEntitiesAlways + } +} + +/** The option `XMLNode.Options.nodeLoadExternalEntitiesAlways`. */ +private class NodeLoadExternalEntitiesAlways extends VarDecl { + NodeLoadExternalEntitiesAlways() { + this.getName() = "nodeLoadExternalEntitiesAlways" and + this.getEnclosingDecl().(StructDecl).getFullName() = "XMLNode.Options" + } +} diff --git a/swift/ql/test/query-tests/Security/CWE-611/testXMLDocumentXXE.swift b/swift/ql/test/query-tests/Security/CWE-611/testXMLDocumentXXE.swift new file mode 100644 index 00000000000..cbfd2cb58ea --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-611/testXMLDocumentXXE.swift @@ -0,0 +1,86 @@ +// --- stubs --- + +class Data { + init(_ elements: S) {} +} + +struct URL { + init?(string: String) {} +} + +extension String { + init(contentsOf: URL) { + let data = "" + self.init(data) + } +} + +class XMLNode { + struct Options : OptionSet { + let rawValue: Int + static let nodeLoadExternalEntitiesAlways = XMLNode.Options(rawValue: 1 << 0) + static let nodeLoadExternalEntitiesNever = XMLNode.Options(rawValue: 1 << 1) + } +} + +class XMLElement {} + +class XMLDocument { + init(contentsOf: URL, options: XMLNode.Options = []) {} + init(data: Data, options: XMLNode.Options = []) {} + init(rootElement: XMLElement?) {} + init(xmlString: String, options: XMLNode.Options = []) {} +} + +// --- tests --- + +func testUrl() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteUrl = URL(string: remoteString)! + let _ = XMLDocument(contentsOf: remoteUrl, options: [.nodeLoadExternalEntitiesAlways]) // $ hasXXE=39 +} + +func testUrlSafeImplicit() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteUrl = URL(string: remoteString)! + let _ = XMLDocument(contentsOf: remoteUrl, options: []) // NO XXE: document doesn't enable external entities +} + +func testUrlSafeExplicit() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteUrl = URL(string: remoteString)! + let _ = XMLDocument(contentsOf: remoteUrl, options: [.nodeLoadExternalEntitiesNever]) // NO XXE: document disables external entities +} + +func testData() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + let _ = XMLDocument(data: remoteData, options: [.nodeLoadExternalEntitiesAlways]) // $ hasXXE=57 +} + +func testDataSafeImplicit() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + let _ = XMLDocument(data: remoteData, options: []) // NO XXE: document doesn't enable external entities +} + +func testDataSafeExplicit() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + let _ = XMLDocument(data: remoteData, options: [.nodeLoadExternalEntitiesNever]) // NO XXE: document disables external entities +} + +func testString() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let _ = XMLDocument(xmlString: remoteString, options: [.nodeLoadExternalEntitiesAlways]) // $ hasXXE=75 +} + +func testStringSafeImplicit() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let _ = XMLDocument(xmlString: remoteString, options: []) // NO XXE: document doesn't enable external entities +} + +func testStringSafeExplicit() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let _ = XMLDocument(xmlString: remoteString, options: [.nodeLoadExternalEntitiesNever]) // NO XXE: document disables external entities +} diff --git a/swift/ql/test/query-tests/Security/CWE-611/testXXE.swift b/swift/ql/test/query-tests/Security/CWE-611/testXMLParserXXE.swift similarity index 100% rename from swift/ql/test/query-tests/Security/CWE-611/testXXE.swift rename to swift/ql/test/query-tests/Security/CWE-611/testXMLParserXXE.swift From 52bd14021382cedb2e3ca98b79f73bb4276ca357 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Fri, 4 Nov 2022 13:02:02 +0100 Subject: [PATCH 148/796] Fix test expectations --- .../query-tests/Security/CWE-611/testXMLDocumentXXE.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/swift/ql/test/query-tests/Security/CWE-611/testXMLDocumentXXE.swift b/swift/ql/test/query-tests/Security/CWE-611/testXMLDocumentXXE.swift index cbfd2cb58ea..07180301e72 100644 --- a/swift/ql/test/query-tests/Security/CWE-611/testXMLDocumentXXE.swift +++ b/swift/ql/test/query-tests/Security/CWE-611/testXMLDocumentXXE.swift @@ -37,7 +37,7 @@ class XMLDocument { func testUrl() { let remoteString = String(contentsOf: URL(string: "http://example.com/")!) let remoteUrl = URL(string: remoteString)! - let _ = XMLDocument(contentsOf: remoteUrl, options: [.nodeLoadExternalEntitiesAlways]) // $ hasXXE=39 + let _ = XMLDocument(contentsOf: remoteUrl, options: [.nodeLoadExternalEntitiesAlways]) // $ hasXXE=38 } func testUrlSafeImplicit() { @@ -55,7 +55,7 @@ func testUrlSafeExplicit() { func testData() { let remoteString = String(contentsOf: URL(string: "http://example.com/")!) let remoteData = Data(remoteString) - let _ = XMLDocument(data: remoteData, options: [.nodeLoadExternalEntitiesAlways]) // $ hasXXE=57 + let _ = XMLDocument(data: remoteData, options: [.nodeLoadExternalEntitiesAlways]) // $ hasXXE=56 } func testDataSafeImplicit() { @@ -72,7 +72,7 @@ func testDataSafeExplicit() { func testString() { let remoteString = String(contentsOf: URL(string: "http://example.com/")!) - let _ = XMLDocument(xmlString: remoteString, options: [.nodeLoadExternalEntitiesAlways]) // $ hasXXE=75 + let _ = XMLDocument(xmlString: remoteString, options: [.nodeLoadExternalEntitiesAlways]) // $ hasXXE=74 } func testStringSafeImplicit() { From b39e2ef71cbee9fcae4dc97b5afe58566702ddce Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Fri, 29 Jul 2022 17:27:16 +0100 Subject: [PATCH 149/796] Ruby: add stacktrace exposure query --- .../StackTraceExposureCustomizations.qll | 55 +++++++++++++++++++ .../ruby/security/StackTraceExposureQuery.qll | 25 +++++++++ .../security/cwe-209/StackTraceExposure.qhelp | 49 +++++++++++++++++ .../security/cwe-209/StackTraceExposure.ql | 23 ++++++++ .../cwe-209/examples/StackTraceExposure.rb | 18 ++++++ .../cwe-209/StackTraceExposure.expected | 10 ++++ .../security/cwe-209/StackTraceExposure.qlref | 1 + .../security/cwe-209/StackTraceExposure.rb | 15 +++++ 8 files changed, 196 insertions(+) create mode 100644 ruby/ql/lib/codeql/ruby/security/StackTraceExposureCustomizations.qll create mode 100644 ruby/ql/lib/codeql/ruby/security/StackTraceExposureQuery.qll create mode 100644 ruby/ql/src/queries/security/cwe-209/StackTraceExposure.qhelp create mode 100644 ruby/ql/src/queries/security/cwe-209/StackTraceExposure.ql create mode 100644 ruby/ql/src/queries/security/cwe-209/examples/StackTraceExposure.rb create mode 100644 ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected create mode 100644 ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.qlref create mode 100644 ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.rb diff --git a/ruby/ql/lib/codeql/ruby/security/StackTraceExposureCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/StackTraceExposureCustomizations.qll new file mode 100644 index 00000000000..9a25dda844d --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/security/StackTraceExposureCustomizations.qll @@ -0,0 +1,55 @@ +/** + * Provides default sources, sinks and sanitizers for detecting stack trace + * exposure vulnerabilities, as well as extension points for adding your own. + */ + +private import codeql.ruby.AST +private import codeql.ruby.Concepts +private import codeql.ruby.DataFlow +private import codeql.ruby.controlflow.CfgNodes +private import codeql.ruby.frameworks.core.Kernel + +/** + * Provides default sources, sinks and sanitizers for detecting stack trace + * exposure vulnerabilities, as well as extension points for adding your own. + */ +module StackTraceExposure { + /** A data flow source for stack trace exposure vulnerabilities. */ + abstract class Source extends DataFlow::Node { } + + /** A data flow sink for stack trace exposure vulnerabilities. */ + abstract class Sink extends DataFlow::Node { } + + /** A data flow sanitizer for stack trace exposure vulnerabilities. */ + abstract class Sanitizer extends DataFlow::Node { } + + /** + * A call to `backtrace` or `backtrace_locations` on a `rescue` variable, + * considered as a flow source. + */ + class BacktraceCall extends Source, DataFlow::CallNode { + BacktraceCall() { + exists(DataFlow::LocalSourceNode varAccess | + varAccess.asExpr().(ExprNodes::VariableReadAccessCfgNode).getExpr().getVariable() = + any(RescueClause rc).getVariableExpr().(VariableAccess).getVariable() and + varAccess.flowsTo(this.getReceiver()) + ) and + this.getMethodName() = ["backtrace", "backtrace_locations"] + } + } + + /** + * A call to `Kernel#caller`, considered as a flow source. + */ + class KernelCallerCall extends Source, Kernel::KernelMethodCall { + KernelCallerCall() { this.getMethodName() = "caller" } + } + + /** + * The body of an HTTP response that will be returned from a server, + * considered as a flow sink. + */ + class ServerHttpResponseBodyAsSink extends Sink { + ServerHttpResponseBodyAsSink() { this = any(Http::Server::HttpResponse response).getBody() } + } +} diff --git a/ruby/ql/lib/codeql/ruby/security/StackTraceExposureQuery.qll b/ruby/ql/lib/codeql/ruby/security/StackTraceExposureQuery.qll new file mode 100644 index 00000000000..408d903d7b4 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/security/StackTraceExposureQuery.qll @@ -0,0 +1,25 @@ +/** + * Provides a taint-tracking configuration for detecting stack-trace exposure + * vulnerabilities. + * + * Note, for performance reasons: only import this file if + * `StackTraceExposure::Configuration` is needed; otherwise, + * `StackTraceExposureCustomizations` should be imported instead. + */ + +private import codeql.ruby.DataFlow +private import codeql.ruby.TaintTracking +private import StackTraceExposureCustomizations::StackTraceExposure + +/** + * A taint-tracking configuration for detecting "stack trace exposure" vulnerabilities. + */ +class Configuration extends TaintTracking::Configuration { + Configuration() { this = "StackTraceExposure" } + + override predicate isSource(DataFlow::Node source) { source instanceof Source } + + override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } +} diff --git a/ruby/ql/src/queries/security/cwe-209/StackTraceExposure.qhelp b/ruby/ql/src/queries/security/cwe-209/StackTraceExposure.qhelp new file mode 100644 index 00000000000..916f6cfcbeb --- /dev/null +++ b/ruby/ql/src/queries/security/cwe-209/StackTraceExposure.qhelp @@ -0,0 +1,49 @@ + + + + +

    +Software developers often add stack traces to error messages, as a debugging +aid. Whenever that error message occurs for an end user, the developer can use +the stack trace to help identify how to fix the problem. In particular, stack +traces can tell the developer more about the sequence of events that led to a +failure, as opposed to merely the final state of the software when the error +occurred. +

    + +

    +Unfortunately, the same information can be useful to an attacker. The sequence +of class or method names in a stack trace can reveal the structure of the +application as well as any internal components it relies on. Furthermore, the +error message at the top of a stack trace can include information such as +server-side file names and SQL code that the application relies on, allowing an +attacker to fine-tune a subsequent injection attack. +

    +
    + + +

    +Send the user a more generic error message that reveals less information. +Either suppress the stack trace entirely, or log it only on the server. +

    +
    + + +

    +In the following example, an exception is handled in two different ways. In the +first version, labeled BAD, the exception is exposted to the remote user by +rendering it as an HTTP response. As such, the user is able to see a detailed +stack trace, which may contain sensitive information. In the second version, the +error message is logged only on the server, and a generic error message is +displayed to the user. That way, the developers can still access and use the +error log, but remote users will not see the information.

    + + +
    + + +
  • OWASP: Improper Error Handling.
  • + + diff --git a/ruby/ql/src/queries/security/cwe-209/StackTraceExposure.ql b/ruby/ql/src/queries/security/cwe-209/StackTraceExposure.ql new file mode 100644 index 00000000000..95ea4a86908 --- /dev/null +++ b/ruby/ql/src/queries/security/cwe-209/StackTraceExposure.ql @@ -0,0 +1,23 @@ +/** + * @name Information exposure through an exception + * @description Leaking information about an exception, such as messages and stack traces, to an + * external user can expose implementation details that are useful to an attacker for + * developing a subsequent exploit. + * @kind path-problem + * @problem.severity error + * @security-severity 5.4 + * @precision high + * @id rb/stack-trace-exposure + * @tags security + * external/cwe/cwe-209 + * external/cwe/cwe-497 + */ + +import codeql.ruby.DataFlow +import codeql.ruby.security.StackTraceExposureQuery +import DataFlow::PathGraph + +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "$@ can be exposed to an external user.", source.getNode(), + "Error information" diff --git a/ruby/ql/src/queries/security/cwe-209/examples/StackTraceExposure.rb b/ruby/ql/src/queries/security/cwe-209/examples/StackTraceExposure.rb new file mode 100644 index 00000000000..591be56014f --- /dev/null +++ b/ruby/ql/src/queries/security/cwe-209/examples/StackTraceExposure.rb @@ -0,0 +1,18 @@ +class UsersController < ApplicationController + + def update_bad(id) + do_computation() + rescue => e + # BAD + render e.backtrace, content_type: "text/plain" + end + + def update_good(id) + do_computation() + rescue => e + # GOOD + log e.backtrace + redner "Computation failed", content_type: "text/plain" + end + +end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected new file mode 100644 index 00000000000..7a0e35973be --- /dev/null +++ b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected @@ -0,0 +1,10 @@ +edges +| StackTraceExposure.rb:11:10:11:17 | call to caller : | StackTraceExposure.rb:12:12:12:13 | bt | +nodes +| StackTraceExposure.rb:6:12:6:22 | call to backtrace | semmle.label | call to backtrace | +| StackTraceExposure.rb:11:10:11:17 | call to caller : | semmle.label | call to caller : | +| StackTraceExposure.rb:12:12:12:13 | bt | semmle.label | bt | +subpaths +#select +| StackTraceExposure.rb:6:12:6:22 | call to backtrace | StackTraceExposure.rb:6:12:6:22 | call to backtrace | StackTraceExposure.rb:6:12:6:22 | call to backtrace | $@ can be exposed to an external user. | StackTraceExposure.rb:6:12:6:22 | call to backtrace | Error information | +| StackTraceExposure.rb:12:12:12:13 | bt | StackTraceExposure.rb:11:10:11:17 | call to caller : | StackTraceExposure.rb:12:12:12:13 | bt | $@ can be exposed to an external user. | StackTraceExposure.rb:11:10:11:17 | call to caller | Error information | diff --git a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.qlref b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.qlref new file mode 100644 index 00000000000..c110f2b1765 --- /dev/null +++ b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.qlref @@ -0,0 +1 @@ +queries/security/cwe-209/StackTraceExposure.ql \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.rb b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.rb new file mode 100644 index 00000000000..a9faa66af02 --- /dev/null +++ b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.rb @@ -0,0 +1,15 @@ +class FooController < ApplicationController + + def show + something_that_might_fail() + rescue => e + render e.backtrace, content_type: "text/plain" + end + + + def show2 + bt = caller() + render bt, content_type: "text/plain" + end + +end From c660ea100b422fb05ca733dbc1b832edd06ba58c Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Mon, 14 Nov 2022 12:08:56 +0000 Subject: [PATCH 150/796] Ruby: add changenote for rb/stack-trace-exposure --- ruby/ql/src/change-notes/2022-11-14-stack-trace-exposure.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ruby/ql/src/change-notes/2022-11-14-stack-trace-exposure.md diff --git a/ruby/ql/src/change-notes/2022-11-14-stack-trace-exposure.md b/ruby/ql/src/change-notes/2022-11-14-stack-trace-exposure.md new file mode 100644 index 00000000000..c4b1e73766b --- /dev/null +++ b/ruby/ql/src/change-notes/2022-11-14-stack-trace-exposure.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `rb/stack-trace-exposure`, to detect exposure of stack-traces to users via HTTP responses. From b20f8fc8c9efe88282e542187aebe00c84d78e58 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 14 Nov 2022 12:27:54 +0000 Subject: [PATCH 151/796] Kotlin: Add total number of diagnostics to telemetry --- .../src/main/kotlin/utils/Logger.kt | 11 +++++-- java/ql/src/Telemetry/ExtractorInformation.ql | 31 ++++++++++++++++++- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt b/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt index 43c6ee4cc10..6ec568e769a 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt @@ -138,6 +138,10 @@ open class LoggerBase(val logCounter: LogCounter) { fullMsgBuilder.append(suffix) val fullMsg = fullMsgBuilder.toString() + emitDiagnostic(tw, severity, diagnosticLocStr, msg, fullMsg, locationString, mkLocationId) + } + + fun emitDiagnostic(tw: TrapWriter, severity: Severity, diagnosticLocStr: String, msg: String, fullMsg: String, locationString: String? = null, mkLocationId: () -> Label = { tw.unknownLocation }) { val locStr = if (locationString == null) "" else "At " + locationString + ": " val kind = if (severity <= Severity.WarnHigh) "WARN" else "ERROR" val logMessage = LogMessage(kind, "Diagnostic($diagnosticLocStr): $locStr$fullMsg") @@ -190,9 +194,10 @@ open class LoggerBase(val logCounter: LogCounter) { // We don't know if this location relates to an error // or a warning, so we just declare hitting the limit // to be an error regardless. - val logMessage = LogMessage("ERROR", "Total of $count diagnostics from $caller.") - tw.writeComment(logMessage.toText()) - logStream.write(logMessage.toJsonLine()) + val message = "Total of $count diagnostics (reached limit of ${logCounter.diagnosticLimit}) from $caller." + if (verbosity >= 1) { + emitDiagnostic(tw, Severity.Error, "Limit", message, message) + } } } } diff --git a/java/ql/src/Telemetry/ExtractorInformation.ql b/java/ql/src/Telemetry/ExtractorInformation.ql index 0eb420ba651..861cde5c661 100644 --- a/java/ql/src/Telemetry/ExtractorInformation.ql +++ b/java/ql/src/Telemetry/ExtractorInformation.ql @@ -53,6 +53,34 @@ predicate extractorDiagnostics(string key, int value) { ) } +/* + * Just counting the diagnostics doesn't give the full picture, as + * CODEQL_EXTRACTOR_KOTLIN_DIAGNOSTIC_LIMIT means that some diagnostics + * will be suppressed. In that case, we need to look for the + * suppression message, uncount those that did get emitted, uncount the + * suppression message itself, and then add on the full count. + */ + +predicate extractorTotalDiagnostics(string key, int value) { + exists(string extractor | + key = "Total number of diagnostics from " + extractor and + value = + strictcount(Diagnostic d | d.getGeneratedBy() = extractor) + + sum(Diagnostic d | + d.getGeneratedBy() = extractor + | + d.getMessage() + .regexpCapture("Total of ([0-9]+) diagnostics \\(reached limit of ([0-9]+)\\).*", + 1) + .toInt() - + d.getMessage() + .regexpCapture("Total of ([0-9]+) diagnostics \\(reached limit of ([0-9]+)\\).*", + 2) + .toInt() - 1 + ) + ) +} + from string key, int value where fileCount(key, value) or @@ -61,5 +89,6 @@ where numberOfLinesOfCode(key, value) or totalNumberOfLinesByExtension(key, value) or numberOfLinesOfCodeByExtension(key, value) or - extractorDiagnostics(key, value) + extractorDiagnostics(key, value) or + extractorTotalDiagnostics(key, value) select key, value From c80fbff648e9c33fd44c94b4bcf19bb55ec4fbc0 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Mon, 14 Nov 2022 12:47:50 +0000 Subject: [PATCH 152/796] Ruby: add changenote for Enumerable#index_by flow summary --- .../2022-11-14-activesupport-enumerable-index-by.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ruby/ql/lib/change-notes/2022-11-14-activesupport-enumerable-index-by.md diff --git a/ruby/ql/lib/change-notes/2022-11-14-activesupport-enumerable-index-by.md b/ruby/ql/lib/change-notes/2022-11-14-activesupport-enumerable-index-by.md new file mode 100644 index 00000000000..812c292dd94 --- /dev/null +++ b/ruby/ql/lib/change-notes/2022-11-14-activesupport-enumerable-index-by.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Data flow through the `ActiveSupport` extension `Enumerable#index_by` is now modeled. From 847ecd1eec06213714ef9907fdc461f333e77e59 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 14 Nov 2022 13:09:49 +0000 Subject: [PATCH 153/796] Java/Kotlin: Small refactoring of ExtractorInformation --- java/ql/src/Telemetry/ExtractorInformation.ql | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/java/ql/src/Telemetry/ExtractorInformation.ql b/java/ql/src/Telemetry/ExtractorInformation.ql index 861cde5c661..eaf0eac1fa9 100644 --- a/java/ql/src/Telemetry/ExtractorInformation.ql +++ b/java/ql/src/Telemetry/ExtractorInformation.ql @@ -62,21 +62,16 @@ predicate extractorDiagnostics(string key, int value) { */ predicate extractorTotalDiagnostics(string key, int value) { - exists(string extractor | + exists(string extractor, string limitRegex | + limitRegex = "Total of ([0-9]+) diagnostics \\(reached limit of ([0-9]+)\\).*" and key = "Total number of diagnostics from " + extractor and value = strictcount(Diagnostic d | d.getGeneratedBy() = extractor) + sum(Diagnostic d | d.getGeneratedBy() = extractor | - d.getMessage() - .regexpCapture("Total of ([0-9]+) diagnostics \\(reached limit of ([0-9]+)\\).*", - 1) - .toInt() - - d.getMessage() - .regexpCapture("Total of ([0-9]+) diagnostics \\(reached limit of ([0-9]+)\\).*", - 2) - .toInt() - 1 + d.getMessage().regexpCapture(limitRegex, 1).toInt() - + d.getMessage().regexpCapture(limitRegex, 2).toInt() - 1 ) ) } From fab2d30f381154f01abd35ff844cdb5a9228d8b0 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 14 Nov 2022 13:53:16 +0000 Subject: [PATCH 154/796] Kotlin: Make emitDiagnostic private --- java/kotlin-extractor/src/main/kotlin/utils/Logger.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt b/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt index 6ec568e769a..36ebda9dd1c 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt @@ -141,7 +141,7 @@ open class LoggerBase(val logCounter: LogCounter) { emitDiagnostic(tw, severity, diagnosticLocStr, msg, fullMsg, locationString, mkLocationId) } - fun emitDiagnostic(tw: TrapWriter, severity: Severity, diagnosticLocStr: String, msg: String, fullMsg: String, locationString: String? = null, mkLocationId: () -> Label = { tw.unknownLocation }) { + private fun emitDiagnostic(tw: TrapWriter, severity: Severity, diagnosticLocStr: String, msg: String, fullMsg: String, locationString: String? = null, mkLocationId: () -> Label = { tw.unknownLocation }) { val locStr = if (locationString == null) "" else "At " + locationString + ": " val kind = if (severity <= Severity.WarnHigh) "WARN" else "ERROR" val logMessage = LogMessage(kind, "Diagnostic($diagnosticLocStr): $locStr$fullMsg") From b028d72d51bffe870b427fa416bbaaf67593b390 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 14 Nov 2022 15:07:59 +0100 Subject: [PATCH 155/796] JS: Handle DynamicImport in the context of a type --- .../semmle/js/extractor/TypeExprKinds.java | 15 +- .../extractor/tests/ts/input/dynamic-type.ts | 1 + .../tests/ts/output/trap/dynamic-type.ts.trap | 139 ++++++++++++++++++ 3 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 javascript/extractor/tests/ts/input/dynamic-type.ts create mode 100644 javascript/extractor/tests/ts/output/trap/dynamic-type.ts.trap diff --git a/javascript/extractor/src/com/semmle/js/extractor/TypeExprKinds.java b/javascript/extractor/src/com/semmle/js/extractor/TypeExprKinds.java index a1c7b219a8a..82d4e4319c8 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/TypeExprKinds.java +++ b/javascript/extractor/src/com/semmle/js/extractor/TypeExprKinds.java @@ -10,6 +10,7 @@ import com.semmle.js.ast.TemplateElement; import com.semmle.js.extractor.ASTExtractor.IdContext; import com.semmle.ts.ast.ArrayTypeExpr; import com.semmle.ts.ast.ConditionalTypeExpr; +import com.semmle.js.ast.DynamicImport; import com.semmle.ts.ast.FunctionTypeExpr; import com.semmle.ts.ast.GenericTypeExpr; import com.semmle.ts.ast.ImportTypeExpr; @@ -221,8 +222,7 @@ public class TypeExprKinds { return inferTypeExpr; } - @Override - public Integer visit(ImportTypeExpr nd, Void c) { + private Integer handleInlineImport() { switch (idcontext) { case NAMESPACE_BIND: return importNamespaceAccess; @@ -235,6 +235,17 @@ public class TypeExprKinds { } } + @Override + public Integer visit(ImportTypeExpr nd, Void c) { + return handleInlineImport(); + } + + @Override + public Integer visit(DynamicImport nd, Void c) { + // These may appear in interface 'extend' clauses + return handleInlineImport(); + } + @Override public Integer visit(OptionalTypeExpr nd, Void c) { return optionalTypeExpr; diff --git a/javascript/extractor/tests/ts/input/dynamic-type.ts b/javascript/extractor/tests/ts/input/dynamic-type.ts new file mode 100644 index 00000000000..2b2f90337a2 --- /dev/null +++ b/javascript/extractor/tests/ts/input/dynamic-type.ts @@ -0,0 +1 @@ +interface Foo extends import("foo").Bar {} diff --git a/javascript/extractor/tests/ts/output/trap/dynamic-type.ts.trap b/javascript/extractor/tests/ts/output/trap/dynamic-type.ts.trap new file mode 100644 index 00000000000..71410d093cc --- /dev/null +++ b/javascript/extractor/tests/ts/output/trap/dynamic-type.ts.trap @@ -0,0 +1,139 @@ +#10000=@"/dynamic-type.ts;sourcefile" +files(#10000,"/dynamic-type.ts") +#10001=@"/;folder" +folders(#10001,"/") +containerparent(#10001,#10000) +#10002=@"loc,{#10000},0,0,0,0" +locations_default(#10002,#10000,0,0,0,0) +hasLocation(#10000,#10002) +#20000=@"global_scope" +scopes(#20000,0) +#20001=@"script;{#10000},1,1" +#20002=* +lines(#20002,#20001,"interface Foo extends import(""foo"").Bar {}"," +") +#20003=@"loc,{#10000},1,1,1,42" +locations_default(#20003,#10000,1,1,1,42) +hasLocation(#20002,#20003) +numlines(#20001,1,1,0) +#20004=* +tokeninfo(#20004,7,#20001,0,"interface") +#20005=@"loc,{#10000},1,1,1,9" +locations_default(#20005,#10000,1,1,1,9) +hasLocation(#20004,#20005) +#20006=* +tokeninfo(#20006,6,#20001,1,"Foo") +#20007=@"loc,{#10000},1,11,1,13" +locations_default(#20007,#10000,1,11,1,13) +hasLocation(#20006,#20007) +#20008=* +tokeninfo(#20008,7,#20001,2,"extends") +#20009=@"loc,{#10000},1,15,1,21" +locations_default(#20009,#10000,1,15,1,21) +hasLocation(#20008,#20009) +#20010=* +tokeninfo(#20010,7,#20001,3,"import") +#20011=@"loc,{#10000},1,23,1,28" +locations_default(#20011,#10000,1,23,1,28) +hasLocation(#20010,#20011) +#20012=* +tokeninfo(#20012,8,#20001,4,"(") +#20013=@"loc,{#10000},1,29,1,29" +locations_default(#20013,#10000,1,29,1,29) +hasLocation(#20012,#20013) +#20014=* +tokeninfo(#20014,4,#20001,5,"""foo""") +#20015=@"loc,{#10000},1,30,1,34" +locations_default(#20015,#10000,1,30,1,34) +hasLocation(#20014,#20015) +#20016=* +tokeninfo(#20016,8,#20001,6,")") +#20017=@"loc,{#10000},1,35,1,35" +locations_default(#20017,#10000,1,35,1,35) +hasLocation(#20016,#20017) +#20018=* +tokeninfo(#20018,8,#20001,7,".") +#20019=@"loc,{#10000},1,36,1,36" +locations_default(#20019,#10000,1,36,1,36) +hasLocation(#20018,#20019) +#20020=* +tokeninfo(#20020,6,#20001,8,"Bar") +#20021=@"loc,{#10000},1,37,1,39" +locations_default(#20021,#10000,1,37,1,39) +hasLocation(#20020,#20021) +#20022=* +tokeninfo(#20022,8,#20001,9,"{") +#20023=@"loc,{#10000},1,41,1,41" +locations_default(#20023,#10000,1,41,1,41) +hasLocation(#20022,#20023) +#20024=* +tokeninfo(#20024,8,#20001,10,"}") +#20025=@"loc,{#10000},1,42,1,42" +locations_default(#20025,#10000,1,42,1,42) +hasLocation(#20024,#20025) +#20026=* +tokeninfo(#20026,0,#20001,11,"") +#20027=@"loc,{#10000},2,1,2,0" +locations_default(#20027,#10000,2,1,2,0) +hasLocation(#20026,#20027) +toplevels(#20001,0) +#20028=@"loc,{#10000},1,1,2,0" +locations_default(#20028,#10000,1,1,2,0) +hasLocation(#20001,#20028) +#20029=@"local_type_name;{Foo};{#20000}" +local_type_names(#20029,"Foo",#20000) +#20030=* +stmts(#20030,34,#20001,0,"interfa ... .Bar {}") +hasLocation(#20030,#20003) +stmt_containers(#20030,#20001) +#20031=* +typeexprs(#20031,13,#20030,-1,"import(""foo"").Bar") +#20032=@"loc,{#10000},1,23,1,39" +locations_default(#20032,#10000,1,23,1,39) +hasLocation(#20031,#20032) +enclosing_stmt(#20031,#20030) +expr_containers(#20031,#20001) +#20033=* +typeexprs(#20033,31,#20031,0,"import(""foo"")") +#20034=@"loc,{#10000},1,23,1,35" +locations_default(#20034,#10000,1,23,1,35) +hasLocation(#20033,#20034) +enclosing_stmt(#20033,#20030) +expr_containers(#20033,#20001) +#20035=* +exprs(#20035,4,#20033,0,"""foo""") +hasLocation(#20035,#20015) +enclosing_stmt(#20035,#20030) +expr_containers(#20035,#20001) +literals("foo","""foo""",#20035) +#20036=* +regexpterm(#20036,14,#20035,0,"foo") +#20037=@"loc,{#10000},1,31,1,33" +locations_default(#20037,#10000,1,31,1,33) +hasLocation(#20036,#20037) +regexp_const_value(#20036,"foo") +#20038=* +typeexprs(#20038,15,#20031,1,"Bar") +hasLocation(#20038,#20021) +enclosing_stmt(#20038,#20030) +expr_containers(#20038,#20001) +literals("Bar","Bar",#20038) +#20039=* +typeexprs(#20039,1,#20030,0,"Foo") +hasLocation(#20039,#20007) +enclosing_stmt(#20039,#20030) +expr_containers(#20039,#20001) +literals("Foo","Foo",#20039) +typedecl(#20039,#20029) +#20040=* +entry_cfg_node(#20040,#20001) +#20041=@"loc,{#10000},1,1,1,0" +locations_default(#20041,#10000,1,1,1,0) +hasLocation(#20040,#20041) +#20042=* +exit_cfg_node(#20042,#20001) +hasLocation(#20042,#20027) +successor(#20030,#20042) +successor(#20040,#20030) +numlines(#10000,1,1,0) +filetype(#10000,"typescript") From 5f18484fa97a5dd32a0a424865bdbae395668560 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 14 Nov 2022 15:09:30 +0100 Subject: [PATCH 156/796] JS: Change note --- .../src/change-notes/2022-11-14-dynamic-import-type-expr.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 javascript/ql/src/change-notes/2022-11-14-dynamic-import-type-expr.md diff --git a/javascript/ql/src/change-notes/2022-11-14-dynamic-import-type-expr.md b/javascript/ql/src/change-notes/2022-11-14-dynamic-import-type-expr.md new file mode 100644 index 00000000000..5f975516620 --- /dev/null +++ b/javascript/ql/src/change-notes/2022-11-14-dynamic-import-type-expr.md @@ -0,0 +1,5 @@ +--- +category: fix +--- +* Fixed a bug that would cause the extractor to crash when an `import` type is used in + the `extends` clause of an `interface`. From 2bcf9b86cfa976972a16bb2d5d3452aedd7e7274 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 14 Nov 2022 15:09:50 +0100 Subject: [PATCH 157/796] JS: Bump extractor version string --- javascript/extractor/src/com/semmle/js/extractor/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/extractor/src/com/semmle/js/extractor/Main.java b/javascript/extractor/src/com/semmle/js/extractor/Main.java index d03b345af59..325e9e9123d 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/Main.java +++ b/javascript/extractor/src/com/semmle/js/extractor/Main.java @@ -41,7 +41,7 @@ public class Main { * A version identifier that should be updated every time the extractor changes in such a way that * it may produce different tuples for the same file under the same {@link ExtractorConfig}. */ - public static final String EXTRACTOR_VERSION = "2022-11-08"; + public static final String EXTRACTOR_VERSION = "2022-11-14"; public static final Pattern NEWLINE = Pattern.compile("\n"); From 3e6eedec300bcd6b9f70961225d63704d3a0f220 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 14 Nov 2022 14:42:56 +0000 Subject: [PATCH 158/796] Swift: Fix test output after merge. --- .../Security/CWE-311/CleartextTransmission.expected | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 0ce9f3b10c7..3245aa68d4e 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected @@ -1,11 +1,11 @@ edges +| testAlamofire.swift:150:45:150:45 | password : | testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | +| testAlamofire.swift:152:51:152:51 | password : | testAlamofire.swift:152:19:152:51 | ... .+(_:_:) ... | +| testAlamofire.swift:154:38:154:38 | email : | testAlamofire.swift:154:14:154:46 | ... .+(_:_:) ... | | testSend.swift:5:5:5:29 | [summary param] 0 in init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | | testSend.swift:33:14:33:32 | call to init(_:) : | testSend.swift:37:19:37:19 | data2 | | testSend.swift:33:19:33:19 | passwordPlain : | testSend.swift:5:5:5:29 | [summary param] 0 in init(_:) : | | testSend.swift:33:19:33:19 | passwordPlain : | testSend.swift:33:14:33:32 | call to init(_:) : | -| testAlamofire.swift:150:45:150:45 | password : | testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | -| testAlamofire.swift:152:51:152:51 | password : | testAlamofire.swift:152:19:152:51 | ... .+(_:_:) ... | -| testAlamofire.swift:154:38:154:38 | email : | testAlamofire.swift:154:14:154:46 | ... .+(_:_:) ... | | testSend.swift:41:10:41:18 | data : | testSend.swift:41:45:41:45 | data : | | testSend.swift:45:13:45:13 | password : | testSend.swift:52:27:52:27 | str1 | | testSend.swift:46:13:46:13 | password : | testSend.swift:53:27:53:27 | str2 | @@ -16,13 +16,13 @@ edges | testURL.swift:16:55:16:55 | credit_card_no : | testURL.swift:16:22:16:55 | ... .+(_:_:) ... | nodes | file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | semmle.label | [summary] to write: return (return) in init(_:) : | -| testSend.swift:5:5:5:29 | [summary param] 0 in init(_:) : | semmle.label | [summary param] 0 in init(_:) : | | testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | | testAlamofire.swift:150:45:150:45 | password : | semmle.label | password : | | testAlamofire.swift:152:19:152:51 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | | testAlamofire.swift:152:51:152:51 | password : | semmle.label | password : | | testAlamofire.swift:154:14:154:46 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | -| testAlamofire.swift:154:38:154:38 | email : | semmle.label | email : |= +| testAlamofire.swift:154:38:154:38 | email : | semmle.label | email : | +| testSend.swift:5:5:5:29 | [summary param] 0 in init(_:) : | semmle.label | [summary param] 0 in init(_:) : | | testSend.swift:29:19:29:19 | passwordPlain | semmle.label | passwordPlain | | testSend.swift:33:14:33:32 | call to init(_:) : | semmle.label | call to init(_:) : | | testSend.swift:33:19:33:19 | passwordPlain : | semmle.label | passwordPlain : | From f2888dcb1e9b456470d09dd6800e9df55b7127f1 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Fri, 4 Nov 2022 20:16:41 +0100 Subject: [PATCH 159/796] Add sinks and tests for the AEXML library. --- .../codeql/swift/frameworks/AEXML/AEXML.qll | 56 +++++++ swift/ql/lib/codeql/swift/security/XXE.qll | 71 +++++++++ .../CWE-611/testAEXMLDocumentXXE.swift | 148 ++++++++++++++++++ 3 files changed, 275 insertions(+) create mode 100644 swift/ql/lib/codeql/swift/frameworks/AEXML/AEXML.qll create mode 100644 swift/ql/test/query-tests/Security/CWE-611/testAEXMLDocumentXXE.swift diff --git a/swift/ql/lib/codeql/swift/frameworks/AEXML/AEXML.qll b/swift/ql/lib/codeql/swift/frameworks/AEXML/AEXML.qll new file mode 100644 index 00000000000..c779c8f7122 --- /dev/null +++ b/swift/ql/lib/codeql/swift/frameworks/AEXML/AEXML.qll @@ -0,0 +1,56 @@ +import swift + +/** The creation of an `AEXMLParser`. */ +class AexmlParser extends ApplyExpr { + AexmlParser() { + this.getStaticTarget().(ConstructorDecl).getEnclosingDecl() instanceof AexmlParserDecl + } +} + +/** The creation of an `AEXMLDocument`. */ +class AexmlDocument extends ApplyExpr { + AexmlDocument() { + this.getStaticTarget().(ConstructorDecl).getEnclosingDecl() instanceof AexmlDocumentDecl + } +} + +/** A call to `AEXMLDocument.loadXML(_:)`. */ +class AexmlDocumentLoadXml extends MethodApplyExpr { + AexmlDocumentLoadXml() { + exists(MethodDecl f | + this.getStaticTarget() = f and + f.hasName("loadXML(_:)") and + f.getEnclosingDecl() instanceof AexmlDocumentDecl + ) + } +} + +/** The class `AEXMLParser`. */ +class AexmlParserDecl extends ClassDecl { + AexmlParserDecl() { this.getFullName() = "AEXMLParser" } +} + +/** The class `AEXMLDocument`. */ +class AexmlDocumentDecl extends ClassDecl { + AexmlDocumentDecl() { this.getFullName() = "AEXMLDocument" } +} + +/** A reference to the field `AEXMLOptions.ParserSettings.shouldResolveExternalEntities`. */ +class AexmlShouldResolveExternalEntities extends MemberRefExpr { + AexmlShouldResolveExternalEntities() { + exists(FieldDecl f | this.getMember() = f | + f.getName() = "shouldResolveExternalEntities" and + f.getEnclosingDecl().(NominalTypeDecl).getType() instanceof AexmlOptionsParserSettingsType + ) + } +} + +/** The type `AEXMLOptions`. */ +class AexmlOptionsType extends StructType { + AexmlOptionsType() { this.getFullName() = "AEXMLOptions" } +} + +/** The type `AEXMLOptions.ParserSettings`. */ +class AexmlOptionsParserSettingsType extends StructType { + AexmlOptionsParserSettingsType() { this.getFullName() = "AEXMLOptions.ParserSettings" } +} diff --git a/swift/ql/lib/codeql/swift/security/XXE.qll b/swift/ql/lib/codeql/swift/security/XXE.qll index da8513be645..cc102a34ff0 100644 --- a/swift/ql/lib/codeql/swift/security/XXE.qll +++ b/swift/ql/lib/codeql/swift/security/XXE.qll @@ -2,6 +2,7 @@ import swift private import codeql.swift.dataflow.DataFlow +private import codeql.swift.frameworks.AEXML.AEXML /** A data flow sink for XML external entities (XXE) vulnerabilities. */ abstract class XxeSink extends DataFlow::Node { } @@ -90,3 +91,73 @@ private class NodeLoadExternalEntitiesAlways extends VarDecl { this.getEnclosingDecl().(StructDecl).getFullName() = "XMLNode.Options" } } + +/** The XML argument of an `AEXMLDocument` vulnerable to XXE. */ +private class AexmlDocumentSink extends XxeSink { + AexmlDocumentSink() { + // `AEXMLDocument` initialized with vulnerable options. + exists(ApplyExpr call | this.asExpr() = call.getArgument(0).getExpr() | + call.(VulnerableAexmlDocument) + .getStaticTarget() + .hasName(["init(xml:options:)", "init(xml:encoding:options:)"]) + or + // `loadXML` called on a vulnerable AEXMLDocument. + DataFlow::localExprFlow(any(VulnerableAexmlDocument v), + call.(AexmlDocumentLoadXml).getQualifier()) + ) + } +} + +/** The XML argument of an `AEXMLParser` initialized with an `AEXMLDocument` vulnerable to XXE. */ +private class AexmlParserSink extends XxeSink { + AexmlParserSink() { + exists(AexmlParser parser | this.asExpr() = parser.getArgument(1).getExpr() | + DataFlow::localExprFlow(any(VulnerableAexmlDocument v), parser.getArgument(0).getExpr()) + ) + } +} + +/** The creation of an `AEXMLDocument` that receives a vulnerable `AEXMLOptions` argument. */ +private class VulnerableAexmlDocument extends AexmlDocument { + VulnerableAexmlDocument() { + exists(AexmlOptions optionsArgument, VulnerableAexmlOptions vulnOpts | + this.getAnArgument().getExpr() = optionsArgument and + DataFlow::localExprFlow(vulnOpts, optionsArgument) + ) + } +} + +/** + * An `AEXMLOptions` object which contains a `parserSettings` with `shouldResolveExternalEntities` + * set to `true`. + */ +private class VulnerableAexmlOptions extends AexmlOptions { + VulnerableAexmlOptions() { + exists(ParserSettings parserSettings, AexmlShouldResolveExternalEntities sree, AssignExpr a | + a.getSource() = any(BooleanLiteralExpr b | b.getValue() = true) and + a.getDest() = sree and + sree.(MemberRefExpr).getBase() = parserSettings and + parserSettings.(MemberRefExpr).getBase() = this + ) + } +} + +/** An expression of type `AEXMLOptions.ParserSettings`. */ +class ParserSettings extends Expr { + pragma[inline] + ParserSettings() { + this.getType() instanceof AexmlOptionsParserSettingsType or + this.getType() = any(OptionalType t | t.getBaseType() instanceof AexmlOptionsParserSettingsType) or + this.getType() = any(LValueType t | t.getObjectType() instanceof AexmlOptionsParserSettingsType) + } +} + +/** An expression of type `AEXMLOptions`. */ +class AexmlOptions extends Expr { + pragma[inline] + AexmlOptions() { + this.getType() instanceof AexmlOptionsType or + this.getType() = any(OptionalType t | t.getBaseType() instanceof AexmlOptionsType) or + this.getType() = any(LValueType t | t.getObjectType() instanceof AexmlOptionsType) + } +} diff --git a/swift/ql/test/query-tests/Security/CWE-611/testAEXMLDocumentXXE.swift b/swift/ql/test/query-tests/Security/CWE-611/testAEXMLDocumentXXE.swift new file mode 100644 index 00000000000..9f337030158 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-611/testAEXMLDocumentXXE.swift @@ -0,0 +1,148 @@ +// --- stubs --- + +class Data { + init(_ elements: S) {} +} + +struct URL { + init?(string: String) {} +} + +extension String { + struct Encoding: Hashable { + let rawValue: UInt + static let utf8 = String.Encoding(rawValue: 1) + } + + init(contentsOf: URL) { + let data = "" + self.init(data) + } +} + +class AEXMLElement {} + +struct AEXMLOptions { + var parserSettings = ParserSettings() + + struct ParserSettings { + public var shouldResolveExternalEntities = false + } +} + +class AEXMLDocument { + init(root: AEXMLElement? = nil, options: AEXMLOptions) {} + init(xml: Data, options: AEXMLOptions = AEXMLOptions()) {} + init(xml: String, encoding: String.Encoding, options: AEXMLOptions) {} + func loadXML(_: Data) {} +} + +class AEXMLParser { + init(document: AEXMLDocument, data: Data) {} +} + +// --- tests --- + +func testString() { + var options = AEXMLOptions() + options.parserSettings.shouldResolveExternalEntities = true + + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let _ = AEXMLDocument(xml: remoteString, encoding: String.Encoding.utf8, options: options) // $ hasXXE=50 +} + +func testStringSafeImplicit() { + var options = AEXMLOptions() + + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let _ = AEXMLDocument(xml: remoteString, encoding: String.Encoding.utf8, options: options) // NO XXE +} + +func testStringSafeExplicit() { + var options = AEXMLOptions() + options.parserSettings.shouldResolveExternalEntities = false + + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let _ = AEXMLDocument(xml: remoteString, encoding: String.Encoding.utf8, options: options) // NO XXE +} + +func testData() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + var options = AEXMLOptions() + options.parserSettings.shouldResolveExternalEntities = true + let _ = AEXMLDocument(xml: remoteData, options: options) // $ hasXXE=70 +} + +func testDataSafeImplicit() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + var options = AEXMLOptions() + let _ = AEXMLDocument(xml: remoteData, options: options) // NO XXE +} + +func testDataSafeExplicit() { + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + var options = AEXMLOptions() + options.parserSettings.shouldResolveExternalEntities = false + let _ = AEXMLDocument(xml: remoteData, options: options) // NO XXE +} + +func testDataLoadXml() { + var options = AEXMLOptions() + options.parserSettings.shouldResolveExternalEntities = true + let doc = AEXMLDocument(root: nil, options: options) + + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + doc.loadXML(remoteData) // $ hasXXE=97 +} + +func testDataLoadXmlSafeImplicit() { + var options = AEXMLOptions() + let doc = AEXMLDocument(root: nil, options: options) + + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + doc.loadXML(remoteData) // NO XXE +} + +func testDataLoadXmlSafeExplicit() { + var options = AEXMLOptions() + options.parserSettings.shouldResolveExternalEntities = false + let doc = AEXMLDocument(root: nil, options: options) + + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + doc.loadXML(remoteData) // NO XXE +} + +func testParser() { + var options = AEXMLOptions() + options.parserSettings.shouldResolveExternalEntities = true + let doc = AEXMLDocument(root: nil, options: options) + + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + let _ = AEXMLParser(document: doc, data: remoteData) // $ hasXXE=126 +} + +func testParserSafeImplicit() { + var options = AEXMLOptions() + let doc = AEXMLDocument(root: nil, options: options) + + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + let _ = AEXMLParser(document: doc, data: remoteData) // NO XXE +} + +func testParserSafeExplicit() { + var options = AEXMLOptions() + options.parserSettings.shouldResolveExternalEntities = false + let doc = AEXMLDocument(root: nil, options: options) + + let remoteString = String(contentsOf: URL(string: "http://example.com/")!) + let remoteData = Data(remoteString) + let _ = AEXMLParser(document: doc, data: remoteData) // NO XXE +} \ No newline at end of file From 07de92cdb6d93b9b052639208e7065bab3ba9319 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Mon, 7 Nov 2022 17:09:18 +0100 Subject: [PATCH 160/796] Move AEXML.qll to avoid nesting --- swift/ql/lib/codeql/swift/frameworks/{AEXML => }/AEXML.qll | 0 swift/ql/lib/codeql/swift/security/XXE.qll | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename swift/ql/lib/codeql/swift/frameworks/{AEXML => }/AEXML.qll (100%) diff --git a/swift/ql/lib/codeql/swift/frameworks/AEXML/AEXML.qll b/swift/ql/lib/codeql/swift/frameworks/AEXML.qll similarity index 100% rename from swift/ql/lib/codeql/swift/frameworks/AEXML/AEXML.qll rename to swift/ql/lib/codeql/swift/frameworks/AEXML.qll diff --git a/swift/ql/lib/codeql/swift/security/XXE.qll b/swift/ql/lib/codeql/swift/security/XXE.qll index cc102a34ff0..eeb6170a7c7 100644 --- a/swift/ql/lib/codeql/swift/security/XXE.qll +++ b/swift/ql/lib/codeql/swift/security/XXE.qll @@ -2,7 +2,7 @@ import swift private import codeql.swift.dataflow.DataFlow -private import codeql.swift.frameworks.AEXML.AEXML +private import codeql.swift.frameworks.AEXML /** A data flow sink for XML external entities (XXE) vulnerabilities. */ abstract class XxeSink extends DataFlow::Node { } From 5791e8b9a2650a6e674a1db02503c1275b61486a Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Tue, 8 Nov 2022 10:31:49 +0100 Subject: [PATCH 161/796] Slight renaming --- swift/ql/lib/codeql/swift/security/XXE.qll | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/XXE.qll b/swift/ql/lib/codeql/swift/security/XXE.qll index eeb6170a7c7..5f80426fa56 100644 --- a/swift/ql/lib/codeql/swift/security/XXE.qll +++ b/swift/ql/lib/codeql/swift/security/XXE.qll @@ -133,7 +133,9 @@ private class VulnerableAexmlDocument extends AexmlDocument { */ private class VulnerableAexmlOptions extends AexmlOptions { VulnerableAexmlOptions() { - exists(ParserSettings parserSettings, AexmlShouldResolveExternalEntities sree, AssignExpr a | + exists( + AexmlParserSettings parserSettings, AexmlShouldResolveExternalEntities sree, AssignExpr a + | a.getSource() = any(BooleanLiteralExpr b | b.getValue() = true) and a.getDest() = sree and sree.(MemberRefExpr).getBase() = parserSettings and @@ -143,9 +145,9 @@ private class VulnerableAexmlOptions extends AexmlOptions { } /** An expression of type `AEXMLOptions.ParserSettings`. */ -class ParserSettings extends Expr { +private class AexmlParserSettings extends Expr { pragma[inline] - ParserSettings() { + AexmlParserSettings() { this.getType() instanceof AexmlOptionsParserSettingsType or this.getType() = any(OptionalType t | t.getBaseType() instanceof AexmlOptionsParserSettingsType) or this.getType() = any(LValueType t | t.getObjectType() instanceof AexmlOptionsParserSettingsType) @@ -153,7 +155,7 @@ class ParserSettings extends Expr { } /** An expression of type `AEXMLOptions`. */ -class AexmlOptions extends Expr { +private class AexmlOptions extends Expr { pragma[inline] AexmlOptions() { this.getType() instanceof AexmlOptionsType or From 324e0e8f9030fa0675f31ce497c5a91b481e12d5 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 14 Nov 2022 17:33:48 +0100 Subject: [PATCH 162/796] always sort both by location and by term tostring --- shared/regex/codeql/regex/nfa/NfaUtils.qll | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shared/regex/codeql/regex/nfa/NfaUtils.qll b/shared/regex/codeql/regex/nfa/NfaUtils.qll index b3be9c73bfd..cb5091c40aa 100644 --- a/shared/regex/codeql/regex/nfa/NfaUtils.qll +++ b/shared/regex/codeql/regex/nfa/NfaUtils.qll @@ -166,7 +166,7 @@ module Make { min(RelevantRegExpTerm t | str = getCanonicalizationString(t) | - t order by getTermLocationString(t) + t order by getTermLocationString(t), t.toString() ) } @@ -949,7 +949,7 @@ module Make { isStartState(s) and getRoot(s.getRepr()) = root | - s order by getTermLocationString(s.getRepr()) + s order by getTermLocationString(s.getRepr()), s.getRepr().toString() ) ) } @@ -1047,7 +1047,7 @@ module Make { isCandidate(s, _) and s.getRepr() instanceof InfiniteRepetitionQuantifier | - s order by getTermLocationString(s.getRepr()) + s order by getTermLocationString(s.getRepr()), s.getRepr().toString() ) ) } From 99636ba3445e204696e9e25956a3a12d62973dfa Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 14 Nov 2022 17:35:55 +0100 Subject: [PATCH 163/796] fix typo Co-authored-by: yoff --- python/ql/lib/semmle/python/RegexTreeView.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/RegexTreeView.qll b/python/ql/lib/semmle/python/RegexTreeView.qll index 4af5ca19523..9ef211d53b0 100644 --- a/python/ql/lib/semmle/python/RegexTreeView.qll +++ b/python/ql/lib/semmle/python/RegexTreeView.qll @@ -82,7 +82,7 @@ private RegExpTerm seqChild(Regex re, int start, int end, int i) { ) } -/** An implementation that statisfies the RegexTreeView signature. */ +/** An implementation that satisfies the RegexTreeView signature. */ module Impl implements RegexTreeViewSig { /** * An element containing a regular expression term, that is, either From af1470de076fd30e81285568151f611697255bec Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 1 Nov 2022 12:13:10 +0100 Subject: [PATCH 164/796] add codeql/regex as a dependency --- java/ql/lib/qlpack.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 0d8258e5ef1..32f1ef40ae8 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -5,3 +5,5 @@ dbscheme: config/semmlecode.dbscheme extractor: java library: true upgrades: upgrades +dependencies: + codeql/regex: 0.0.1 \ No newline at end of file From 20254dfc084010dccc7ef1851e4fbe69e19c850a Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 1 Nov 2022 12:14:50 +0100 Subject: [PATCH 165/796] move existing regex-tree into a module --- .../semmle/code/java/regex/RegexTreeView.qll | 1949 +++++++++-------- 1 file changed, 977 insertions(+), 972 deletions(-) diff --git a/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll b/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll index 14663327103..ceccd3efd5f 100644 --- a/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll +++ b/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll @@ -2,6 +2,10 @@ private import java private import semmle.code.java.regex.regex +import Impl + +/** Gets the parse tree resulting from parsing `re`, if such has been constructed. */ +RegExpTerm getParsedRegExp(StringLiteral re) { result.getRegex() = re and result.isRootTerm() } /** * An element containing a regular expression term, that is, either @@ -49,1038 +53,1039 @@ private newtype TRegExpParent = /** A back reference */ TRegExpBackRef(Regex re, int start, int end) { re.backreference(start, end) } -/** - * An element containing a regular expression term, that is, either - * a string literal (parsed as a regular expression; the root of the parse tree) - * or another regular expression term (a descendant of the root). - */ -class RegExpParent extends TRegExpParent { - /** Gets a textual representation of this element. */ - string toString() { result = "RegExpParent" } +module Impl { + /** + * An element containing a regular expression term, that is, either + * a string literal (parsed as a regular expression; the root of the parse tree) + * or another regular expression term (a descendant of the root). + */ + class RegExpParent extends TRegExpParent { + /** Gets a textual representation of this element. */ + string toString() { result = "RegExpParent" } - /** Gets the `i`th child term. */ - RegExpTerm getChild(int i) { none() } + /** Gets the `i`th child term. */ + RegExpTerm getChild(int i) { none() } - /** Gets a child term . */ - RegExpTerm getAChild() { result = this.getChild(_) } + /** Gets a child term . */ + RegExpTerm getAChild() { result = this.getChild(_) } - /** Gets the number of child terms. */ - int getNumChild() { result = count(this.getAChild()) } + /** Gets the number of child terms. */ + int getNumChild() { result = count(this.getAChild()) } - /** Gets the associated regex. */ - abstract Regex getRegex(); -} - -/** - * A string literal used as a regular expression. - * - * As an optimisation, only regexes containing an infinite repitition quatifier (`+`, `*`, or `{x,}`) - * and therefore may be relevant for ReDoS queries are considered. - */ -class RegExpLiteral extends TRegExpLiteral, RegExpParent { - Regex re; - - RegExpLiteral() { this = TRegExpLiteral(re) } - - override string toString() { result = re.toString() } - - override RegExpTerm getChild(int i) { i = 0 and result.getRegex() = re and result.isRootTerm() } - - /** Holds if dot, `.`, matches all characters, including newlines. */ - predicate isDotAll() { re.getAMode() = "DOTALL" } - - /** Holds if this regex matching is case-insensitive for this regex. */ - predicate isIgnoreCase() { re.getAMode() = "IGNORECASE" } - - /** Get a string representing all modes for this regex. */ - string getFlags() { result = concat(string mode | mode = re.getAMode() | mode, " | ") } - - override Regex getRegex() { result = re } - - /** Gets the primary QL class for this regex. */ - string getPrimaryQLClass() { result = "RegExpLiteral" } -} - -/** - * A regular expression term, that is, a syntactic part of a regular expression. - * These are the tree nodes that form the parse tree of a regular expression literal. - */ -class RegExpTerm extends RegExpParent { - Regex re; - int start; - int end; - - RegExpTerm() { - this = TRegExpAlt(re, start, end) - or - this = TRegExpBackRef(re, start, end) - or - this = TRegExpCharacterClass(re, start, end) - or - this = TRegExpCharacterRange(re, start, end) - or - this = TRegExpNormalChar(re, start, end) - or - this = TRegExpQuote(re, start, end) - or - this = TRegExpGroup(re, start, end) - or - this = TRegExpQuantifier(re, start, end) - or - this = TRegExpSequence(re, start, end) - or - this = TRegExpSpecialChar(re, start, end) + /** Gets the associated regex. */ + abstract Regex getRegex(); } /** - * Gets the outermost term of this regular expression. + * A string literal used as a regular expression. + * + * As an optimisation, only regexes containing an infinite repitition quatifier (`+`, `*`, or `{x,}`) + * and therefore may be relevant for ReDoS queries are considered. */ - RegExpTerm getRootTerm() { - this.isRootTerm() and result = this - or - result = this.getParent().(RegExpTerm).getRootTerm() + class RegExpLiteral extends TRegExpLiteral, RegExpParent { + Regex re; + + RegExpLiteral() { this = TRegExpLiteral(re) } + + override string toString() { result = re.toString() } + + override RegExpTerm getChild(int i) { i = 0 and result.getRegex() = re and result.isRootTerm() } + + /** Holds if dot, `.`, matches all characters, including newlines. */ + predicate isDotAll() { re.getAMode() = "DOTALL" } + + /** Holds if this regex matching is case-insensitive for this regex. */ + predicate isIgnoreCase() { re.getAMode() = "IGNORECASE" } + + /** Get a string representing all modes for this regex. */ + string getFlags() { result = concat(string mode | mode = re.getAMode() | mode, " | ") } + + override Regex getRegex() { result = re } + + /** Gets the primary QL class for this regex. */ + string getPrimaryQLClass() { result = "RegExpLiteral" } } /** - * Holds if this term is part of a string literal - * that is interpreted as a regular expression. + * A regular expression term, that is, a syntactic part of a regular expression. + * These are the tree nodes that form the parse tree of a regular expression literal. */ - predicate isUsedAsRegExp() { any() } + class RegExpTerm extends RegExpParent { + Regex re; + int start; + int end; - /** - * Holds if this is the root term of a regular expression. - */ - predicate isRootTerm() { start = 0 and end = re.getText().length() } + RegExpTerm() { + this = TRegExpAlt(re, start, end) + or + this = TRegExpBackRef(re, start, end) + or + this = TRegExpCharacterClass(re, start, end) + or + this = TRegExpCharacterRange(re, start, end) + or + this = TRegExpNormalChar(re, start, end) + or + this = TRegExpQuote(re, start, end) + or + this = TRegExpGroup(re, start, end) + or + this = TRegExpQuantifier(re, start, end) + or + this = TRegExpSequence(re, start, end) + or + this = TRegExpSpecialChar(re, start, end) + } - /** - * Gets the parent term of this regular expression term, or the - * regular expression literal if this is the root term. - */ - RegExpParent getParent() { result.getAChild() = this } - - override Regex getRegex() { result = re } - - /** Gets the offset at which this term starts. */ - int getStart() { result = start } - - /** Gets the offset at which this term ends. */ - int getEnd() { result = end } - - /** Holds if this term occurs in regex `inRe` offsets `startOffset` to `endOffset`. */ - predicate occursInRegex(Regex inRe, int startOffset, int endOffset) { - inRe = re and startOffset = start and endOffset = end - } - - override string toString() { result = re.getText().substring(start, end) } - - /** - * Gets the location of the surrounding regex, as locations inside the regex do not exist. - * To get location information corresponding to the term inside the regex, - * use `hasLocationInfo`. - */ - Location getLocation() { result = re.getLocation() } - - /** Holds if this term is found at the specified location offsets. */ - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - /* - * This is an approximation that handles the simple and common case of single, - * normal string literal written in the source, but does not give correct results in more complex cases - * such as compile-time concatenation, or multi-line string literals. + /** + * Gets the outermost term of this regular expression. */ - - exists(int re_start, int re_end, int src_start, int src_end | - re.getLocation().hasLocationInfo(filepath, startline, re_start, endline, re_end) and - re.sourceCharacter(start, src_start, _) and - re.sourceCharacter(end - 1, _, src_end) and - startcolumn = re_start + src_start and - endcolumn = re_start + src_end - 1 - ) - } - - /** Gets the file in which this term is found. */ - File getFile() { result = this.getLocation().getFile() } - - /** Gets the raw source text of this term. */ - string getRawValue() { result = this.toString() } - - /** Gets the string literal in which this term is found. */ - RegExpLiteral getLiteral() { result = TRegExpLiteral(re) } - - /** Gets the regular expression term that is matched (textually) before this one, if any. */ - RegExpTerm getPredecessor() { - exists(RegExpTerm parent | parent = this.getParent() | - result = parent.(RegExpSequence).previousElement(this) + RegExpTerm getRootTerm() { + this.isRootTerm() and result = this or - not exists(parent.(RegExpSequence).previousElement(this)) and - not parent instanceof RegExpSubPattern and - result = parent.getPredecessor() - ) + result = this.getParent().(RegExpTerm).getRootTerm() + } + + /** + * Holds if this term is part of a string literal + * that is interpreted as a regular expression. + */ + predicate isUsedAsRegExp() { any() } + + /** + * Holds if this is the root term of a regular expression. + */ + predicate isRootTerm() { start = 0 and end = re.getText().length() } + + /** + * Gets the parent term of this regular expression term, or the + * regular expression literal if this is the root term. + */ + RegExpParent getParent() { result.getAChild() = this } + + override Regex getRegex() { result = re } + + /** Gets the offset at which this term starts. */ + int getStart() { result = start } + + /** Gets the offset at which this term ends. */ + int getEnd() { result = end } + + /** Holds if this term occurs in regex `inRe` offsets `startOffset` to `endOffset`. */ + predicate occursInRegex(Regex inRe, int startOffset, int endOffset) { + inRe = re and startOffset = start and endOffset = end + } + + override string toString() { result = re.getText().substring(start, end) } + + /** + * Gets the location of the surrounding regex, as locations inside the regex do not exist. + * To get location information corresponding to the term inside the regex, + * use `hasLocationInfo`. + */ + Location getLocation() { result = re.getLocation() } + + /** Holds if this term is found at the specified location offsets. */ + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + /* + * This is an approximation that handles the simple and common case of single, + * normal string literal written in the source, but does not give correct results in more complex cases + * such as compile-time concatenation, or multi-line string literals. + */ + + exists(int re_start, int re_end, int src_start, int src_end | + re.getLocation().hasLocationInfo(filepath, startline, re_start, endline, re_end) and + re.sourceCharacter(start, src_start, _) and + re.sourceCharacter(end - 1, _, src_end) and + startcolumn = re_start + src_start and + endcolumn = re_start + src_end - 1 + ) + } + + /** Gets the file in which this term is found. */ + File getFile() { result = this.getLocation().getFile() } + + /** Gets the raw source text of this term. */ + string getRawValue() { result = this.toString() } + + /** Gets the string literal in which this term is found. */ + RegExpLiteral getLiteral() { result = TRegExpLiteral(re) } + + /** Gets the regular expression term that is matched (textually) before this one, if any. */ + RegExpTerm getPredecessor() { + exists(RegExpTerm parent | parent = this.getParent() | + result = parent.(RegExpSequence).previousElement(this) + or + not exists(parent.(RegExpSequence).previousElement(this)) and + not parent instanceof RegExpSubPattern and + result = parent.getPredecessor() + ) + } + + /** Gets the regular expression term that is matched (textually) after this one, if any. */ + RegExpTerm getSuccessor() { + exists(RegExpTerm parent | parent = this.getParent() | + result = parent.(RegExpSequence).nextElement(this) + or + not exists(parent.(RegExpSequence).nextElement(this)) and + not parent instanceof RegExpSubPattern and + result = parent.getSuccessor() + ) + } + + /** Gets the primary QL class for this term. */ + string getPrimaryQLClass() { result = "RegExpTerm" } } - /** Gets the regular expression term that is matched (textually) after this one, if any. */ - RegExpTerm getSuccessor() { - exists(RegExpTerm parent | parent = this.getParent() | - result = parent.(RegExpSequence).nextElement(this) - or - not exists(parent.(RegExpSequence).nextElement(this)) and - not parent instanceof RegExpSubPattern and - result = parent.getSuccessor() - ) - } - - /** Gets the primary QL class for this term. */ - string getPrimaryQLClass() { result = "RegExpTerm" } -} - -/** - * A quantified regular expression term. - * - * Example: - * - * ``` - * ((ECMA|Java)[sS]cript)* - * ``` - */ -class RegExpQuantifier extends RegExpTerm, TRegExpQuantifier { - int part_end; - boolean maybe_empty; - boolean may_repeat_forever; - - RegExpQuantifier() { - this = TRegExpQuantifier(re, start, end) and - re.quantifiedPart(start, part_end, end, maybe_empty, may_repeat_forever) - } - - override RegExpTerm getChild(int i) { - i = 0 and - result.occursInRegex(re, start, part_end) - } - - /** Holds if this term may match zero times. */ - predicate mayBeEmpty() { maybe_empty = true } - - /** Holds if this term may match an unlimited number of times. */ - predicate mayRepeatForever() { may_repeat_forever = true } - - /** Gets the quantifier for this term. That is e.g "?" for "a?". */ - string getQuantifier() { result = re.getText().substring(part_end, end) } - - /** Holds if this is a possessive quantifier, e.g. a*+. */ - predicate isPossessive() { - exists(string q | q = this.getQuantifier() | q.length() > 1 and q.charAt(q.length() - 1) = "+") - } - - override string getPrimaryQLClass() { result = "RegExpQuantifier" } -} - -/** - * A regular expression term that permits unlimited repetitions. - */ -class InfiniteRepetitionQuantifier extends RegExpQuantifier { - InfiniteRepetitionQuantifier() { this.mayRepeatForever() } -} - -/** - * A star-quantified term. - * - * Example: - * - * ``` - * \w* - * ``` - */ -class RegExpStar extends InfiniteRepetitionQuantifier { - RegExpStar() { this.getQuantifier().charAt(0) = "*" } - - override string getPrimaryQLClass() { result = "RegExpStar" } -} - -/** - * A plus-quantified term. - * - * Example: - * - * ``` - * \w+ - * ``` - */ -class RegExpPlus extends InfiniteRepetitionQuantifier { - RegExpPlus() { this.getQuantifier().charAt(0) = "+" } - - override string getPrimaryQLClass() { result = "RegExpPlus" } -} - -/** - * An optional term. - * - * Example: - * - * ``` - * ;? - * ``` - */ -class RegExpOpt extends RegExpQuantifier { - RegExpOpt() { this.getQuantifier().charAt(0) = "?" } - - override string getPrimaryQLClass() { result = "RegExpOpt" } -} - -/** - * A range-quantified term - * - * Examples: - * - * ``` - * \w{2,4} - * \w{2,} - * \w{2} - * ``` - */ -class RegExpRange extends RegExpQuantifier { - string upper; - string lower; - - RegExpRange() { re.multiples(part_end, end, lower, upper) } - - /** Gets the string defining the upper bound of this range, which is empty when no such bound exists. */ - string getUpper() { result = upper } - - /** Gets the string defining the lower bound of this range, which is empty when no such bound exists. */ - string getLower() { result = lower } - /** - * Gets the upper bound of the range, if any. + * A quantified regular expression term. * - * If there is no upper bound, any number of repetitions is allowed. - * For a term of the form `r{lo}`, both the lower and the upper bound - * are `lo`. + * Example: + * + * ``` + * ((ECMA|Java)[sS]cript)* + * ``` */ - int getUpperBound() { result = this.getUpper().toInt() } + class RegExpQuantifier extends RegExpTerm, TRegExpQuantifier { + int part_end; + boolean maybe_empty; + boolean may_repeat_forever; - /** Gets the lower bound of the range. */ - int getLowerBound() { result = this.getLower().toInt() } + RegExpQuantifier() { + this = TRegExpQuantifier(re, start, end) and + re.quantifiedPart(start, part_end, end, maybe_empty, may_repeat_forever) + } - override string getPrimaryQLClass() { result = "RegExpRange" } -} - -/** - * A sequence term. - * - * Example: - * - * ``` - * (ECMA|Java)Script - * ``` - * - * This is a sequence with the elements `(ECMA|Java)` and `Script`. - */ -class RegExpSequence extends RegExpTerm, TRegExpSequence { - RegExpSequence() { this = TRegExpSequence(re, start, end) } - - override RegExpTerm getChild(int i) { result = seqChild(re, start, end, i) } - - /** Gets the element preceding `element` in this sequence. */ - RegExpTerm previousElement(RegExpTerm element) { element = this.nextElement(result) } - - /** Gets the element following `element` in this sequence. */ - RegExpTerm nextElement(RegExpTerm element) { - exists(int i | - element = this.getChild(i) and - result = this.getChild(i + 1) - ) - } - - override string getPrimaryQLClass() { result = "RegExpSequence" } -} - -pragma[nomagic] -private int seqChildEnd(Regex re, int start, int end, int i) { - result = seqChild(re, start, end, i).getEnd() -} - -// moved out so we can use it in the charpred -private RegExpTerm seqChild(Regex re, int start, int end, int i) { - re.sequence(start, end) and - ( - i = 0 and - exists(int itemEnd | - re.item(start, itemEnd) and - result.occursInRegex(re, start, itemEnd) - ) - or - i > 0 and - exists(int itemStart, int itemEnd | itemStart = seqChildEnd(re, start, end, i - 1) | - re.item(itemStart, itemEnd) and - result.occursInRegex(re, itemStart, itemEnd) - ) - ) -} - -/** - * An alternative term, that is, a term of the form `a|b`. - * - * Example: - * - * ``` - * ECMA|Java - * ``` - */ -class RegExpAlt extends RegExpTerm, TRegExpAlt { - RegExpAlt() { this = TRegExpAlt(re, start, end) } - - override RegExpTerm getChild(int i) { - i = 0 and - exists(int part_end | - re.alternationOption(start, end, start, part_end) and + override RegExpTerm getChild(int i) { + i = 0 and result.occursInRegex(re, start, part_end) - ) - or - i > 0 and - exists(int part_start, int part_end | - part_start = this.getChild(i - 1).getEnd() + 1 // allow for the | - | - re.alternationOption(start, end, part_start, part_end) and - result.occursInRegex(re, part_start, part_end) - ) + } + + /** Holds if this term may match zero times. */ + predicate mayBeEmpty() { maybe_empty = true } + + /** Holds if this term may match an unlimited number of times. */ + predicate mayRepeatForever() { may_repeat_forever = true } + + /** Gets the quantifier for this term. That is e.g "?" for "a?". */ + string getQuantifier() { result = re.getText().substring(part_end, end) } + + /** Holds if this is a possessive quantifier, e.g. a*+. */ + predicate isPossessive() { + exists(string q | q = this.getQuantifier() | + q.length() > 1 and q.charAt(q.length() - 1) = "+" + ) + } + + override string getPrimaryQLClass() { result = "RegExpQuantifier" } } - override string getPrimaryQLClass() { result = "RegExpAlt" } -} - -/** - * An escaped regular expression term, that is, a regular expression - * term starting with a backslash, which is not a backreference. - * - * Example: - * - * ``` - * \. - * \w - * ``` - */ -class RegExpEscape extends RegExpNormalChar { - RegExpEscape() { re.escapedCharacter(start, end) } - /** - * Gets the name of the escaped; for example, `w` for `\w`. - * TODO: Handle named escapes. + * A regular expression term that permits unlimited repetitions. */ - override string getValue() { - not this.isUnicode() and - this.isIdentityEscape() and - result = this.getUnescaped() - or - this.getUnescaped() = "n" and result = "\n" - or - this.getUnescaped() = "r" and result = "\r" - or - this.getUnescaped() = "t" and result = "\t" - or - this.getUnescaped() = "f" and result = 12.toUnicode() // form feed - or - this.getUnescaped() = "a" and result = 7.toUnicode() // alert/bell - or - this.getUnescaped() = "e" and result = 27.toUnicode() // escape (0x1B) - or - this.isUnicode() and - result = this.getUnicode() - } - - /** Holds if this terms name is given by the part following the escape character. */ - predicate isIdentityEscape() { not this.getUnescaped() in ["n", "r", "t", "f", "a", "e"] } - - override string getPrimaryQLClass() { result = "RegExpEscape" } - - /** Gets the part of the term following the escape character. That is e.g. "w" if the term is "\w". */ - private string getUnescaped() { result = this.getText().suffix(1) } - - /** - * Gets the text for this escape. That is e.g. "\w". - */ - private string getText() { result = re.getText().substring(start, end) } - - /** - * Holds if this is a unicode escape. - */ - private predicate isUnicode() { this.getText().matches(["\\u%", "\\x%"]) } - - /** - * Gets the unicode char for this escape. - * E.g. for `\u0061` this returns "a". - */ - private string getUnicode() { - exists(int codepoint | codepoint = sum(this.getHexValueFromUnicode(_)) | - result = codepoint.toUnicode() - ) - } - - /** Gets the part of this escape that is a hexidecimal string */ - private string getHexString() { - this.isUnicode() and - if this.getText().matches("\\u%") // \uhhhh - then result = this.getText().suffix(2) - else - if this.getText().matches("\\x{%") // \x{h..h} - then result = this.getText().substring(3, this.getText().length() - 1) - else result = this.getText().suffix(2) // \xhh + class InfiniteRepetitionQuantifier extends RegExpQuantifier { + InfiniteRepetitionQuantifier() { this.mayRepeatForever() } } /** - * Gets int value for the `index`th char in the hex number of the unicode escape. - * E.g. for `\u0061` and `index = 2` this returns 96 (the number `6` interpreted as hex). - */ - private int getHexValueFromUnicode(int index) { - this.isUnicode() and - exists(string hex, string char | hex = this.getHexString() | - char = hex.charAt(index) and - result = 16.pow(hex.length() - index - 1) * toHex(char) - ) - } -} - -/** - * Gets the hex number for the `hex` char. - */ -private int toHex(string hex) { - result = [0 .. 9] and hex = result.toString() - or - result = 10 and hex = ["a", "A"] - or - result = 11 and hex = ["b", "B"] - or - result = 12 and hex = ["c", "C"] - or - result = 13 and hex = ["d", "D"] - or - result = 14 and hex = ["e", "E"] - or - result = 15 and hex = ["f", "F"] -} - -/** - * A character class escape in a regular expression. - * That is, an escaped character that denotes multiple characters. - * - * Examples: - * - * ``` - * \w - * \S - * ``` - */ -class RegExpCharacterClassEscape extends RegExpEscape { - RegExpCharacterClassEscape() { - this.getValue() in ["d", "D", "s", "S", "w", "W", "h", "H", "v", "V"] or - this.getValue().charAt(0) in ["p", "P"] - } - - override RegExpTerm getChild(int i) { none() } - - override string getPrimaryQLClass() { result = "RegExpCharacterClassEscape" } -} - -/** - * A named character class in a regular expression. - * - * Examples: - * - * ``` - * \p{Digit} - * \p{IsLowerCase} - */ -class RegExpNamedProperty extends RegExpCharacterClassEscape { - boolean inverted; - string name; - - RegExpNamedProperty() { - name = this.getValue().substring(2, this.getValue().length() - 1) and - ( - inverted = false and - this.getValue().charAt(0) = "p" - or - inverted = true and - this.getValue().charAt(0) = "P" - ) - } - - /** Holds if this class is inverted. */ - predicate isInverted() { inverted = true } - - /** Gets the name of this class. */ - string getClassName() { result = name } - - /** - * Gets an equivalent single-chcracter escape sequence for this class (e.g. \d) if possible, excluding the escape character. - */ - string getBackslashEquivalent() { - exists(string eq | if inverted = true then result = eq.toUpperCase() else result = eq | - name = ["Digit", "IsDigit"] and - eq = "d" - or - name = ["Space", "IsWhite_Space"] and - eq = "s" - ) - } -} - -/** - * A character class in a regular expression. - * - * Examples: - * - * ``` - * [a-z_] - * [^<>&] - * ``` - */ -class RegExpCharacterClass extends RegExpTerm, TRegExpCharacterClass { - RegExpCharacterClass() { this = TRegExpCharacterClass(re, start, end) } - - /** Holds if this character class is inverted, matching the opposite of its content. */ - predicate isInverted() { re.getChar(start + 1) = "^" } - - /** Holds if this character class can match anything. */ - predicate isUniversalClass() { - // [^] - this.isInverted() and not exists(this.getAChild()) - or - // [\w\W] and similar - not this.isInverted() and - exists(string cce1, string cce2 | - cce1 = this.getAChild().(RegExpCharacterClassEscape).getValue() and - cce2 = this.getAChild().(RegExpCharacterClassEscape).getValue() - | - cce1 != cce2 and cce1.toLowerCase() = cce2.toLowerCase() - ) - } - - override RegExpTerm getChild(int i) { - i = 0 and - exists(int itemStart, int itemEnd | - re.charSetStart(start, itemStart) and - re.charSetChild(start, itemStart, itemEnd) and - result.occursInRegex(re, itemStart, itemEnd) - ) - or - i > 0 and - exists(int itemStart, int itemEnd | itemStart = this.getChild(i - 1).getEnd() | - result.occursInRegex(re, itemStart, itemEnd) and - re.charSetChild(start, itemStart, itemEnd) - ) - } - - override string getPrimaryQLClass() { result = "RegExpCharacterClass" } -} - -/** - * A character range in a character class in a regular expression. - * - * Example: - * - * ``` - * a-z - * ``` - */ -class RegExpCharacterRange extends RegExpTerm, TRegExpCharacterRange { - int lower_end; - int upper_start; - - RegExpCharacterRange() { - this = TRegExpCharacterRange(re, start, end) and - re.charRange(_, start, lower_end, upper_start, end) - } - - /** Holds if this range goes from `lo` to `hi`, in effect is `lo-hi`. */ - predicate isRange(string lo, string hi) { - lo = re.getText().substring(start, lower_end) and - hi = re.getText().substring(upper_start, end) - } - - override RegExpTerm getChild(int i) { - i = 0 and - result.occursInRegex(re, start, lower_end) - or - i = 1 and - result.occursInRegex(re, upper_start, end) - } - - override string getPrimaryQLClass() { result = "RegExpCharacterRange" } -} - -/** - * A normal character in a regular expression, that is, a character - * without special meaning. This includes escaped characters. - * It also includes escape sequences that represent character classes. - * - * Examples: - * ``` - * t - * \t - * ``` - */ -class RegExpNormalChar extends RegExpTerm, TRegExpNormalChar { - RegExpNormalChar() { this = TRegExpNormalChar(re, start, end) } - - /** - * Holds if this constant represents a valid Unicode character (as opposed - * to a surrogate code point that does not correspond to a character by itself.) - */ - predicate isCharacter() { any() } - - /** Gets the string representation of the char matched by this term. */ - string getValue() { result = re.getText().substring(start, end) } - - override RegExpTerm getChild(int i) { none() } - - override string getPrimaryQLClass() { result = "RegExpNormalChar" } -} - -/** - * A quoted sequence. - * - * Example: - * ``` - * \Qabc\E - * ``` - */ -class RegExpQuote extends RegExpTerm, TRegExpQuote { - string value; - - RegExpQuote() { - exists(int inner_start, int inner_end | - this = TRegExpQuote(re, start, end) and - re.quote(start, end, inner_start, inner_end) and - value = re.getText().substring(inner_start, inner_end) - ) - } - - /** Gets the string matched by this quote term. */ - string getValue() { result = value } - - override string getPrimaryQLClass() { result = "RegExpQuote" } -} - -/** - * A constant regular expression term, that is, a regular expression - * term matching a single string. This can be a single character or a quoted sequence. - * - * Example: - * - * ``` - * a - * ``` - */ -class RegExpConstant extends RegExpTerm { - string value; - - RegExpConstant() { - (value = this.(RegExpNormalChar).getValue() or value = this.(RegExpQuote).getValue()) and - not this instanceof RegExpCharacterClassEscape - } - - /** - * Holds if this constant represents a valid Unicode character (as opposed - * to a surrogate code point that does not correspond to a character by itself.) - */ - predicate isCharacter() { any() } - - /** Gets the string matched by this constant term. */ - string getValue() { result = value } - - override RegExpTerm getChild(int i) { none() } - - override string getPrimaryQLClass() { result = "RegExpConstant" } -} - -/** - * A grouped regular expression. - * - * Examples: - * - * ``` - * (ECMA|Java) - * (?:ECMA|Java) - * (?['"]) - * ``` - */ -class RegExpGroup extends RegExpTerm, TRegExpGroup { - RegExpGroup() { this = TRegExpGroup(re, start, end) } - - /** - * Gets the index of this capture group within the enclosing regular - * expression literal. + * A star-quantified term. * - * For example, in the regular expression `/((a?).)(?:b)/`, the - * group `((a?).)` has index 1, the group `(a?)` nested inside it - * has index 2, and the group `(?:b)` has no index, since it is - * not a capture group. + * Example: + * + * ``` + * \w* + * ``` */ - int getNumber() { result = re.getGroupNumber(start, end) } + class RegExpStar extends InfiniteRepetitionQuantifier { + RegExpStar() { this.getQuantifier().charAt(0) = "*" } - /** Holds if this is a named capture group. */ - predicate isNamed() { exists(this.getName()) } + override string getPrimaryQLClass() { result = "RegExpStar" } + } - /** Gets the name of this capture group, if any. */ - string getName() { result = re.getGroupName(start, end) } + /** + * A plus-quantified term. + * + * Example: + * + * ``` + * \w+ + * ``` + */ + class RegExpPlus extends InfiniteRepetitionQuantifier { + RegExpPlus() { this.getQuantifier().charAt(0) = "+" } - override RegExpTerm getChild(int i) { - i = 0 and - exists(int in_start, int in_end | re.groupContents(start, end, in_start, in_end) | - result.occursInRegex(re, in_start, in_end) + override string getPrimaryQLClass() { result = "RegExpPlus" } + } + + /** + * An optional term. + * + * Example: + * + * ``` + * ;? + * ``` + */ + class RegExpOpt extends RegExpQuantifier { + RegExpOpt() { this.getQuantifier().charAt(0) = "?" } + + override string getPrimaryQLClass() { result = "RegExpOpt" } + } + + /** + * A range-quantified term + * + * Examples: + * + * ``` + * \w{2,4} + * \w{2,} + * \w{2} + * ``` + */ + class RegExpRange extends RegExpQuantifier { + string upper; + string lower; + + RegExpRange() { re.multiples(part_end, end, lower, upper) } + + /** Gets the string defining the upper bound of this range, which is empty when no such bound exists. */ + string getUpper() { result = upper } + + /** Gets the string defining the lower bound of this range, which is empty when no such bound exists. */ + string getLower() { result = lower } + + /** + * Gets the upper bound of the range, if any. + * + * If there is no upper bound, any number of repetitions is allowed. + * For a term of the form `r{lo}`, both the lower and the upper bound + * are `lo`. + */ + int getUpperBound() { result = this.getUpper().toInt() } + + /** Gets the lower bound of the range. */ + int getLowerBound() { result = this.getLower().toInt() } + + override string getPrimaryQLClass() { result = "RegExpRange" } + } + + /** + * A sequence term. + * + * Example: + * + * ``` + * (ECMA|Java)Script + * ``` + * + * This is a sequence with the elements `(ECMA|Java)` and `Script`. + */ + class RegExpSequence extends RegExpTerm, TRegExpSequence { + RegExpSequence() { this = TRegExpSequence(re, start, end) } + + override RegExpTerm getChild(int i) { result = seqChild(re, start, end, i) } + + /** Gets the element preceding `element` in this sequence. */ + RegExpTerm previousElement(RegExpTerm element) { element = this.nextElement(result) } + + /** Gets the element following `element` in this sequence. */ + RegExpTerm nextElement(RegExpTerm element) { + exists(int i | + element = this.getChild(i) and + result = this.getChild(i + 1) + ) + } + + override string getPrimaryQLClass() { result = "RegExpSequence" } + } + + pragma[nomagic] + private int seqChildEnd(Regex re, int start, int end, int i) { + result = seqChild(re, start, end, i).getEnd() + } + + // moved out so we can use it in the charpred + private RegExpTerm seqChild(Regex re, int start, int end, int i) { + re.sequence(start, end) and + ( + i = 0 and + exists(int itemEnd | + re.item(start, itemEnd) and + result.occursInRegex(re, start, itemEnd) + ) + or + i > 0 and + exists(int itemStart, int itemEnd | itemStart = seqChildEnd(re, start, end, i - 1) | + re.item(itemStart, itemEnd) and + result.occursInRegex(re, itemStart, itemEnd) + ) ) } - override string getPrimaryQLClass() { result = "RegExpGroup" } + /** + * An alternative term, that is, a term of the form `a|b`. + * + * Example: + * + * ``` + * ECMA|Java + * ``` + */ + class RegExpAlt extends RegExpTerm, TRegExpAlt { + RegExpAlt() { this = TRegExpAlt(re, start, end) } - /** Holds if this is the `n`th numbered group of literal `lit`. */ - predicate isNumberedGroupOfLiteral(RegExpLiteral lit, int n) { - lit = this.getLiteral() and n = this.getNumber() - } + override RegExpTerm getChild(int i) { + i = 0 and + exists(int part_end | + re.alternationOption(start, end, start, part_end) and + result.occursInRegex(re, start, part_end) + ) + or + i > 0 and + exists(int part_start, int part_end | + part_start = this.getChild(i - 1).getEnd() + 1 // allow for the | + | + re.alternationOption(start, end, part_start, part_end) and + result.occursInRegex(re, part_start, part_end) + ) + } - /** Holds if this is a group with name `name` of literal `lit`. */ - predicate isNamedGroupOfLiteral(RegExpLiteral lit, string name) { - lit = this.getLiteral() and name = this.getName() - } -} - -/** - * A special character in a regular expression. - * - * Examples: - * ``` - * ^ - * $ - * . - * ``` - */ -class RegExpSpecialChar extends RegExpTerm, TRegExpSpecialChar { - string char; - - RegExpSpecialChar() { - this = TRegExpSpecialChar(re, start, end) and - re.specialCharacter(start, end, char) + override string getPrimaryQLClass() { result = "RegExpAlt" } } /** - * Holds if this constant represents a valid Unicode character (as opposed - * to a surrogate code point that does not correspond to a character by itself.) + * An escaped regular expression term, that is, a regular expression + * term starting with a backslash, which is not a backreference. + * + * Example: + * + * ``` + * \. + * \w + * ``` */ - predicate isCharacter() { any() } + class RegExpEscape extends RegExpNormalChar { + RegExpEscape() { re.escapedCharacter(start, end) } - /** Gets the char for this term. */ - string getChar() { result = char } + /** + * Gets the name of the escaped; for example, `w` for `\w`. + * TODO: Handle named escapes. + */ + override string getValue() { + not this.isUnicode() and + this.isIdentityEscape() and + result = this.getUnescaped() + or + this.getUnescaped() = "n" and result = "\n" + or + this.getUnescaped() = "r" and result = "\r" + or + this.getUnescaped() = "t" and result = "\t" + or + this.getUnescaped() = "f" and result = 12.toUnicode() // form feed + or + this.getUnescaped() = "a" and result = 7.toUnicode() // alert/bell + or + this.getUnescaped() = "e" and result = 27.toUnicode() // escape (0x1B) + or + this.isUnicode() and + result = this.getUnicode() + } - override RegExpTerm getChild(int i) { none() } + /** Holds if this terms name is given by the part following the escape character. */ + predicate isIdentityEscape() { not this.getUnescaped() in ["n", "r", "t", "f", "a", "e"] } - override string getPrimaryQLClass() { result = "RegExpSpecialChar" } -} + override string getPrimaryQLClass() { result = "RegExpEscape" } -/** - * A dot regular expression. - * - * Example: - * - * ``` - * . - * ``` - */ -class RegExpDot extends RegExpSpecialChar { - RegExpDot() { this.getChar() = "." } + /** Gets the part of the term following the escape character. That is e.g. "w" if the term is "\w". */ + private string getUnescaped() { result = this.getText().suffix(1) } - override string getPrimaryQLClass() { result = "RegExpDot" } -} + /** + * Gets the text for this escape. That is e.g. "\w". + */ + private string getText() { result = re.getText().substring(start, end) } -/** - * A dollar assertion `$` matching the end of a line. - * - * Example: - * - * ``` - * $ - * ``` - */ -class RegExpDollar extends RegExpSpecialChar { - RegExpDollar() { this.getChar() = "$" } + /** + * Holds if this is a unicode escape. + */ + private predicate isUnicode() { this.getText().matches(["\\u%", "\\x%"]) } - override string getPrimaryQLClass() { result = "RegExpDollar" } -} + /** + * Gets the unicode char for this escape. + * E.g. for `\u0061` this returns "a". + */ + private string getUnicode() { + exists(int codepoint | codepoint = sum(this.getHexValueFromUnicode(_)) | + result = codepoint.toUnicode() + ) + } -/** - * A caret assertion `^` matching the beginning of a line. - * - * Example: - * - * ``` - * ^ - * ``` - */ -class RegExpCaret extends RegExpSpecialChar { - RegExpCaret() { this.getChar() = "^" } + /** Gets the part of this escape that is a hexidecimal string */ + private string getHexString() { + this.isUnicode() and + if this.getText().matches("\\u%") // \uhhhh + then result = this.getText().suffix(2) + else + if this.getText().matches("\\x{%") // \x{h..h} + then result = this.getText().substring(3, this.getText().length() - 1) + else result = this.getText().suffix(2) // \xhh + } - override string getPrimaryQLClass() { result = "RegExpCaret" } -} - -/** - * A zero-width match, that is, either an empty group or an assertion. - * - * Examples: - * ``` - * () - * (?=\w) - * ``` - */ -class RegExpZeroWidthMatch extends RegExpGroup { - RegExpZeroWidthMatch() { re.zeroWidthMatch(start, end) } - - override RegExpTerm getChild(int i) { none() } - - override string getPrimaryQLClass() { result = "RegExpZeroWidthMatch" } -} - -/** - * A zero-width lookahead or lookbehind assertion. - * - * Examples: - * - * ``` - * (?=\w) - * (?!\n) - * (?<=\.) - * (?` - * in a regular expression. - * - * Examples: - * - * ``` - * \1 - * (?P=quote) - * ``` - */ -class RegExpBackRef extends RegExpTerm, TRegExpBackRef { - RegExpBackRef() { this = TRegExpBackRef(re, start, end) } /** - * Gets the number of the capture group this back reference refers to, if any. + * Gets the hex number for the `hex` char. */ - int getNumber() { result = re.getBackrefNumber(start, end) } - - /** - * Gets the name of the capture group this back reference refers to, if any. - */ - string getName() { result = re.getBackrefName(start, end) } - - /** Gets the capture group this back reference refers to. */ - RegExpGroup getGroup() { - result.isNumberedGroupOfLiteral(this.getLiteral(), this.getNumber()) + private int toHex(string hex) { + result = [0 .. 9] and hex = result.toString() or - result.isNamedGroupOfLiteral(this.getLiteral(), this.getName()) + result = 10 and hex = ["a", "A"] + or + result = 11 and hex = ["b", "B"] + or + result = 12 and hex = ["c", "C"] + or + result = 13 and hex = ["d", "D"] + or + result = 14 and hex = ["e", "E"] + or + result = 15 and hex = ["f", "F"] } - override RegExpTerm getChild(int i) { none() } + /** + * A character class escape in a regular expression. + * That is, an escaped character that denotes multiple characters. + * + * Examples: + * + * ``` + * \w + * \S + * ``` + */ + class RegExpCharacterClassEscape extends RegExpEscape { + RegExpCharacterClassEscape() { + this.getValue() in ["d", "D", "s", "S", "w", "W", "h", "H", "v", "V"] or + this.getValue().charAt(0) in ["p", "P"] + } - override string getPrimaryQLClass() { result = "RegExpBackRef" } + override RegExpTerm getChild(int i) { none() } + + override string getPrimaryQLClass() { result = "RegExpCharacterClassEscape" } + } + + /** + * A named character class in a regular expression. + * + * Examples: + * + * ``` + * \p{Digit} + * \p{IsLowerCase} + */ + class RegExpNamedProperty extends RegExpCharacterClassEscape { + boolean inverted; + string name; + + RegExpNamedProperty() { + name = this.getValue().substring(2, this.getValue().length() - 1) and + ( + inverted = false and + this.getValue().charAt(0) = "p" + or + inverted = true and + this.getValue().charAt(0) = "P" + ) + } + + /** Holds if this class is inverted. */ + predicate isInverted() { inverted = true } + + /** Gets the name of this class. */ + string getClassName() { result = name } + + /** + * Gets an equivalent single-chcracter escape sequence for this class (e.g. \d) if possible, excluding the escape character. + */ + string getBackslashEquivalent() { + exists(string eq | if inverted = true then result = eq.toUpperCase() else result = eq | + name = ["Digit", "IsDigit"] and + eq = "d" + or + name = ["Space", "IsWhite_Space"] and + eq = "s" + ) + } + } + + /** + * A character class in a regular expression. + * + * Examples: + * + * ``` + * [a-z_] + * [^<>&] + * ``` + */ + class RegExpCharacterClass extends RegExpTerm, TRegExpCharacterClass { + RegExpCharacterClass() { this = TRegExpCharacterClass(re, start, end) } + + /** Holds if this character class is inverted, matching the opposite of its content. */ + predicate isInverted() { re.getChar(start + 1) = "^" } + + /** Holds if this character class can match anything. */ + predicate isUniversalClass() { + // [^] + this.isInverted() and not exists(this.getAChild()) + or + // [\w\W] and similar + not this.isInverted() and + exists(string cce1, string cce2 | + cce1 = this.getAChild().(RegExpCharacterClassEscape).getValue() and + cce2 = this.getAChild().(RegExpCharacterClassEscape).getValue() + | + cce1 != cce2 and cce1.toLowerCase() = cce2.toLowerCase() + ) + } + + override RegExpTerm getChild(int i) { + i = 0 and + exists(int itemStart, int itemEnd | + re.charSetStart(start, itemStart) and + re.charSetChild(start, itemStart, itemEnd) and + result.occursInRegex(re, itemStart, itemEnd) + ) + or + i > 0 and + exists(int itemStart, int itemEnd | itemStart = this.getChild(i - 1).getEnd() | + result.occursInRegex(re, itemStart, itemEnd) and + re.charSetChild(start, itemStart, itemEnd) + ) + } + + override string getPrimaryQLClass() { result = "RegExpCharacterClass" } + } + + /** + * A character range in a character class in a regular expression. + * + * Example: + * + * ``` + * a-z + * ``` + */ + class RegExpCharacterRange extends RegExpTerm, TRegExpCharacterRange { + int lower_end; + int upper_start; + + RegExpCharacterRange() { + this = TRegExpCharacterRange(re, start, end) and + re.charRange(_, start, lower_end, upper_start, end) + } + + /** Holds if this range goes from `lo` to `hi`, in effect is `lo-hi`. */ + predicate isRange(string lo, string hi) { + lo = re.getText().substring(start, lower_end) and + hi = re.getText().substring(upper_start, end) + } + + override RegExpTerm getChild(int i) { + i = 0 and + result.occursInRegex(re, start, lower_end) + or + i = 1 and + result.occursInRegex(re, upper_start, end) + } + + override string getPrimaryQLClass() { result = "RegExpCharacterRange" } + } + + /** + * A normal character in a regular expression, that is, a character + * without special meaning. This includes escaped characters. + * It also includes escape sequences that represent character classes. + * + * Examples: + * ``` + * t + * \t + * ``` + */ + class RegExpNormalChar extends RegExpTerm, TRegExpNormalChar { + RegExpNormalChar() { this = TRegExpNormalChar(re, start, end) } + + /** + * Holds if this constant represents a valid Unicode character (as opposed + * to a surrogate code point that does not correspond to a character by itself.) + */ + predicate isCharacter() { any() } + + /** Gets the string representation of the char matched by this term. */ + string getValue() { result = re.getText().substring(start, end) } + + override RegExpTerm getChild(int i) { none() } + + override string getPrimaryQLClass() { result = "RegExpNormalChar" } + } + + /** + * A quoted sequence. + * + * Example: + * ``` + * \Qabc\E + * ``` + */ + class RegExpQuote extends RegExpTerm, TRegExpQuote { + string value; + + RegExpQuote() { + exists(int inner_start, int inner_end | + this = TRegExpQuote(re, start, end) and + re.quote(start, end, inner_start, inner_end) and + value = re.getText().substring(inner_start, inner_end) + ) + } + + /** Gets the string matched by this quote term. */ + string getValue() { result = value } + + override string getPrimaryQLClass() { result = "RegExpQuote" } + } + + /** + * A constant regular expression term, that is, a regular expression + * term matching a single string. This can be a single character or a quoted sequence. + * + * Example: + * + * ``` + * a + * ``` + */ + class RegExpConstant extends RegExpTerm { + string value; + + RegExpConstant() { + (value = this.(RegExpNormalChar).getValue() or value = this.(RegExpQuote).getValue()) and + not this instanceof RegExpCharacterClassEscape + } + + /** + * Holds if this constant represents a valid Unicode character (as opposed + * to a surrogate code point that does not correspond to a character by itself.) + */ + predicate isCharacter() { any() } + + /** Gets the string matched by this constant term. */ + string getValue() { result = value } + + override RegExpTerm getChild(int i) { none() } + + override string getPrimaryQLClass() { result = "RegExpConstant" } + } + + /** + * A grouped regular expression. + * + * Examples: + * + * ``` + * (ECMA|Java) + * (?:ECMA|Java) + * (?['"]) + * ``` + */ + class RegExpGroup extends RegExpTerm, TRegExpGroup { + RegExpGroup() { this = TRegExpGroup(re, start, end) } + + /** + * Gets the index of this capture group within the enclosing regular + * expression literal. + * + * For example, in the regular expression `/((a?).)(?:b)/`, the + * group `((a?).)` has index 1, the group `(a?)` nested inside it + * has index 2, and the group `(?:b)` has no index, since it is + * not a capture group. + */ + int getNumber() { result = re.getGroupNumber(start, end) } + + /** Holds if this is a named capture group. */ + predicate isNamed() { exists(this.getName()) } + + /** Gets the name of this capture group, if any. */ + string getName() { result = re.getGroupName(start, end) } + + override RegExpTerm getChild(int i) { + i = 0 and + exists(int in_start, int in_end | re.groupContents(start, end, in_start, in_end) | + result.occursInRegex(re, in_start, in_end) + ) + } + + override string getPrimaryQLClass() { result = "RegExpGroup" } + + /** Holds if this is the `n`th numbered group of literal `lit`. */ + predicate isNumberedGroupOfLiteral(RegExpLiteral lit, int n) { + lit = this.getLiteral() and n = this.getNumber() + } + + /** Holds if this is a group with name `name` of literal `lit`. */ + predicate isNamedGroupOfLiteral(RegExpLiteral lit, string name) { + lit = this.getLiteral() and name = this.getName() + } + } + + /** + * A special character in a regular expression. + * + * Examples: + * ``` + * ^ + * $ + * . + * ``` + */ + class RegExpSpecialChar extends RegExpTerm, TRegExpSpecialChar { + string char; + + RegExpSpecialChar() { + this = TRegExpSpecialChar(re, start, end) and + re.specialCharacter(start, end, char) + } + + /** + * Holds if this constant represents a valid Unicode character (as opposed + * to a surrogate code point that does not correspond to a character by itself.) + */ + predicate isCharacter() { any() } + + /** Gets the char for this term. */ + string getChar() { result = char } + + override RegExpTerm getChild(int i) { none() } + + override string getPrimaryQLClass() { result = "RegExpSpecialChar" } + } + + /** + * A dot regular expression. + * + * Example: + * + * ``` + * . + * ``` + */ + class RegExpDot extends RegExpSpecialChar { + RegExpDot() { this.getChar() = "." } + + override string getPrimaryQLClass() { result = "RegExpDot" } + } + + /** + * A dollar assertion `$` matching the end of a line. + * + * Example: + * + * ``` + * $ + * ``` + */ + class RegExpDollar extends RegExpSpecialChar { + RegExpDollar() { this.getChar() = "$" } + + override string getPrimaryQLClass() { result = "RegExpDollar" } + } + + /** + * A caret assertion `^` matching the beginning of a line. + * + * Example: + * + * ``` + * ^ + * ``` + */ + class RegExpCaret extends RegExpSpecialChar { + RegExpCaret() { this.getChar() = "^" } + + override string getPrimaryQLClass() { result = "RegExpCaret" } + } + + /** + * A zero-width match, that is, either an empty group or an assertion. + * + * Examples: + * ``` + * () + * (?=\w) + * ``` + */ + class RegExpZeroWidthMatch extends RegExpGroup { + RegExpZeroWidthMatch() { re.zeroWidthMatch(start, end) } + + override RegExpTerm getChild(int i) { none() } + + override string getPrimaryQLClass() { result = "RegExpZeroWidthMatch" } + } + + /** + * A zero-width lookahead or lookbehind assertion. + * + * Examples: + * + * ``` + * (?=\w) + * (?!\n) + * (?<=\.) + * (?` + * in a regular expression. + * + * Examples: + * + * ``` + * \1 + * (?P=quote) + * ``` + */ + class RegExpBackRef extends RegExpTerm, TRegExpBackRef { + RegExpBackRef() { this = TRegExpBackRef(re, start, end) } + + /** + * Gets the number of the capture group this back reference refers to, if any. + */ + int getNumber() { result = re.getBackrefNumber(start, end) } + + /** + * Gets the name of the capture group this back reference refers to, if any. + */ + string getName() { result = re.getBackrefName(start, end) } + + /** Gets the capture group this back reference refers to. */ + RegExpGroup getGroup() { + result.isNumberedGroupOfLiteral(this.getLiteral(), this.getNumber()) + or + result.isNamedGroupOfLiteral(this.getLiteral(), this.getName()) + } + + override RegExpTerm getChild(int i) { none() } + + override string getPrimaryQLClass() { result = "RegExpBackRef" } + } } - -/** Gets the parse tree resulting from parsing `re`, if such has been constructed. */ -RegExpTerm getParsedRegExp(StringLiteral re) { result.getRegex() = re and result.isRootTerm() } From b737bdbca037dd178690c3245d1b0d3d5b08ed2e Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 1 Nov 2022 12:16:28 +0100 Subject: [PATCH 166/796] add a Java implementation of `RegexTreeViewSig` --- .../semmle/code/java/regex/RegexTreeView.qll | 91 ++++++++++++++++++- 1 file changed, 87 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll b/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll index ceccd3efd5f..2eecff1e627 100644 --- a/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll +++ b/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll @@ -1,11 +1,19 @@ /** Provides a class hierarchy corresponding to a parse tree of regular expressions. */ -private import java -private import semmle.code.java.regex.regex +private import semmle.code.java.regex.regex as RE // importing under a namescape to avoid naming conflict for `Top`. +private import codeql.regex.nfa.NfaUtils as NfaUtils +// exporting as RegexTreeView, and in the top-level scope. +import Impl as RegexTreeView import Impl /** Gets the parse tree resulting from parsing `re`, if such has been constructed. */ -RegExpTerm getParsedRegExp(StringLiteral re) { result.getRegex() = re and result.isRootTerm() } +RegExpTerm getParsedRegExp(RE::StringLiteral re) { result.getRegex() = re and result.isRootTerm() } + +private class Regex = RE::Regex; + +private class Location = RE::Location; + +private class File = RE::File; /** * An element containing a regular expression term, that is, either @@ -53,7 +61,10 @@ private newtype TRegExpParent = /** A back reference */ TRegExpBackRef(Regex re, int start, int end) { re.backreference(start, end) } -module Impl { +private import codeql.regex.RegexTreeView + +/** An implementation that statisfies the RegexTreeView signature. */ +module Impl implements RegexTreeViewSig { /** * An element containing a regular expression term, that is, either * a string literal (parsed as a regular expression; the root of the parse tree) @@ -547,6 +558,13 @@ module Impl { } } + /** + * A word boundary, that is, a regular expression term of the form `\b`. + */ + class RegExpWordBoundary extends RegExpSpecialChar { + RegExpWordBoundary() { this.getChar() = "\\b" } + } + /** * Gets the hex number for the `hex` char. */ @@ -1088,4 +1106,69 @@ module Impl { override string getPrimaryQLClass() { result = "RegExpBackRef" } } + + class Top = RegExpParent; + + /** + * Holds if `term` is an escape class representing e.g. `\d`. + * `clazz` is which character class it represents, e.g. "d" for `\d`. + */ + predicate isEscapeClass(RegExpTerm term, string clazz) { + term.(RegExpCharacterClassEscape).getValue() = clazz + or + term.(RegExpNamedProperty).getBackslashEquivalent() = clazz + } + + /** + * Holds if `term` is a possessive quantifier, e.g. `a*+`. + */ + predicate isPossessive(RegExpQuantifier term) { term.isPossessive() } + + /** + * Holds if the regex that `term` is part of is used in a way that ignores any leading prefix of the input it's matched against. + */ + predicate matchesAnyPrefix(RegExpTerm term) { not term.getRegex().matchesFullString() } + + /** + * Holds if the regex that `term` is part of is used in a way that ignores any trailing suffix of the input it's matched against. + */ + predicate matchesAnySuffix(RegExpTerm term) { not term.getRegex().matchesFullString() } + + /** + * Holds if the regular expression should not be considered. + * + * We make the pragmatic performance optimization to ignore regular expressions in files + * that do not belong to the project code (such as installed dependencies). + */ + predicate isExcluded(RegExpParent parent) { + not exists(parent.getRegex().getLocation().getFile().getRelativePath()) + or + // Regexes with many occurrences of ".*" may cause the polynomial ReDoS computation to explode, so + // we explicitly exclude these. + strictcount(int i | exists(parent.getRegex().getText().regexpFind("\\.\\*", i, _)) | i) > 10 + } + + /** + * Holds if `root` has the `i` flag for case-insensitive matching. + */ + predicate isIgnoreCase(RegExpTerm root) { + root.isRootTerm() and + root.getLiteral().isIgnoreCase() + } + + /** + * Gets the flags for `root`, or the empty string if `root` has no flags. + */ + deprecated string getFlags(RegExpTerm root) { + root.isRootTerm() and + result = root.getLiteral().getFlags() + } + + /** + * Holds if `root` has the `s` flag for multi-line matching. + */ + predicate isDotAll(RegExpTerm root) { + root.isRootTerm() and + root.getLiteral().isDotAll() + } } From d5b066636f41c5e09f547b4a410d87ced9c24265 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 1 Nov 2022 12:17:46 +0100 Subject: [PATCH 167/796] use namespace in `PrintAst.qll` to avoid conflict with `Top` --- java/ql/lib/semmle/code/java/PrintAst.qll | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/java/ql/lib/semmle/code/java/PrintAst.qll b/java/ql/lib/semmle/code/java/PrintAst.qll index 4fe7e3f1ec5..4df23f4ec14 100644 --- a/java/ql/lib/semmle/code/java/PrintAst.qll +++ b/java/ql/lib/semmle/code/java/PrintAst.qll @@ -7,7 +7,7 @@ */ import java -import semmle.code.java.regex.RegexTreeView +import semmle.code.java.regex.RegexTreeView as RegexTreeView private newtype TPrintAstConfiguration = MkPrintAstConfiguration() @@ -134,8 +134,10 @@ private newtype TPrintAstNode = TImportsNode(CompilationUnit cu) { shouldPrint(cu, _) and exists(Import i | i.getCompilationUnit() = cu) } or - TRegExpTermNode(RegExpTerm term) { - exists(StringLiteral str | term.getRootTerm() = getParsedRegExp(str) and shouldPrint(str, _)) + TRegExpTermNode(RegexTreeView::RegExpTerm term) { + exists(StringLiteral str | + term.getRootTerm() = RegexTreeView::getParsedRegExp(str) and shouldPrint(str, _) + ) } /** @@ -316,7 +318,7 @@ final class StringLiteralNode extends ExprStmtNode { override PrintAstNode getChild(int childIndex) { childIndex = 0 and - result.(RegExpTermNode).getTerm() = getParsedRegExp(element) + result.(RegExpTermNode).getTerm() = RegexTreeView::getParsedRegExp(element) } } @@ -324,12 +326,12 @@ final class StringLiteralNode extends ExprStmtNode { * A node representing a regular expression term. */ class RegExpTermNode extends TRegExpTermNode, PrintAstNode { - RegExpTerm term; + RegexTreeView::RegExpTerm term; RegExpTermNode() { this = TRegExpTermNode(term) } /** Gets the `RegExpTerm` for this node. */ - RegExpTerm getTerm() { result = term } + RegexTreeView::RegExpTerm getTerm() { result = term } override PrintAstNode getChild(int childIndex) { result.(RegExpTermNode).getTerm() = term.getChild(childIndex) From c0290483066af7f687e79a6ee07f49170e594b30 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 1 Nov 2022 12:20:05 +0100 Subject: [PATCH 168/796] port the Java regex/redos queries to use the shared pack --- .../java/security/OverlyLargeRangeQuery.qll | 289 +--- .../regexp/ExponentialBackTracking.qll | 285 +--- .../code/java/security/regexp/NfaUtils.qll | 1333 +---------------- .../java/security/regexp/NfaUtilsSpecific.qll | 76 - .../security/regexp/PolynomialReDoSQuery.qll | 11 +- .../regexp/SuperlinearBackTracking.qll | 385 +---- .../Security/CWE/CWE-020/OverlyLargeRange.ql | 9 +- .../Security/CWE/CWE-730/PolynomialReDoS.ql | 4 +- java/ql/src/Security/CWE/CWE-730/ReDoS.ql | 8 +- .../regex/parser/RegexParseTests.ql | 12 +- .../security/CWE-730/PolynomialReDoS.ql | 6 +- .../query-tests/security/CWE-730/ReDoS.ql | 7 +- 12 files changed, 49 insertions(+), 2376 deletions(-) delete mode 100644 java/ql/lib/semmle/code/java/security/regexp/NfaUtilsSpecific.qll diff --git a/java/ql/lib/semmle/code/java/security/OverlyLargeRangeQuery.qll b/java/ql/lib/semmle/code/java/security/OverlyLargeRangeQuery.qll index 65e662f0bc5..06b538d4a63 100644 --- a/java/ql/lib/semmle/code/java/security/OverlyLargeRangeQuery.qll +++ b/java/ql/lib/semmle/code/java/security/OverlyLargeRangeQuery.qll @@ -2,288 +2,7 @@ * Classes and predicates for working with suspicious character ranges. */ -// We don't need the NFA utils, just the regexp tree. -// but the below is a nice shared library that exposes the API we need. -import regexp.NfaUtils - -/** - * Gets a rank for `range` that is unique for ranges in the same file. - * Prioritizes ranges that match more characters. - */ -int rankRange(RegExpCharacterRange range) { - range = - rank[result](RegExpCharacterRange r, Location l, int low, int high | - r.getLocation() = l and - isRange(r, low, high) - | - r order by (high - low) desc, l.getStartLine(), l.getStartColumn() - ) -} - -/** Holds if `range` spans from the unicode code points `low` to `high` (both inclusive). */ -predicate isRange(RegExpCharacterRange range, int low, int high) { - exists(string lowc, string highc | - range.isRange(lowc, highc) and - low.toUnicode() = lowc and - high.toUnicode() = highc - ) -} - -/** Holds if `char` is an alpha-numeric character. */ -predicate isAlphanumeric(string char) { - // written like this to avoid having a bindingset for the predicate - char = [[48 .. 57], [65 .. 90], [97 .. 122]].toUnicode() // 0-9, A-Z, a-z -} - -/** - * Holds if the given ranges are from the same character class - * and there exists at least one character matched by both ranges. - */ -predicate overlap(RegExpCharacterRange a, RegExpCharacterRange b) { - exists(RegExpCharacterClass clz | - a = clz.getAChild() and - b = clz.getAChild() and - a != b - | - exists(int alow, int ahigh, int blow, int bhigh | - isRange(a, alow, ahigh) and - isRange(b, blow, bhigh) and - alow <= bhigh and - blow <= ahigh - ) - ) -} - -/** - * Holds if `range` overlaps with the char class `escape` from the same character class. - */ -predicate overlapsWithCharEscape(RegExpCharacterRange range, RegExpCharacterClassEscape escape) { - exists(RegExpCharacterClass clz, string low, string high | - range = clz.getAChild() and - escape = clz.getAChild() and - range.isRange(low, high) - | - escape.getValue() = "w" and - getInRange(low, high).regexpMatch("\\w") - or - escape.getValue() = "d" and - getInRange(low, high).regexpMatch("\\d") - or - escape.getValue() = "s" and - getInRange(low, high).regexpMatch("\\s") - ) -} - -/** Gets the unicode code point for a `char`. */ -bindingset[char] -int toCodePoint(string char) { result.toUnicode() = char } - -/** A character range that appears to be overly wide. */ -class OverlyWideRange extends RegExpCharacterRange { - OverlyWideRange() { - exists(int low, int high, int numChars | - isRange(this, low, high) and - numChars = (1 + high - low) and - this.getRootTerm().isUsedAsRegExp() and - numChars >= 10 - | - // across the Z-a range (which includes backticks) - toCodePoint("Z") >= low and - toCodePoint("a") <= high - or - // across the 9-A range (which includes e.g. ; and ?) - toCodePoint("9") >= low and - toCodePoint("A") <= high - or - // a non-alphanumeric char as part of the range boundaries - exists(int bound | bound = [low, high] | not isAlphanumeric(bound.toUnicode())) and - // while still being ascii - low < 128 and - high < 128 - ) and - // allowlist for known ranges - not this = allowedWideRanges() - } - - /** Gets a string representation of a character class that matches the same chars as this range. */ - string printEquivalent() { result = RangePrinter::printEquivalentCharClass(this) } -} - -/** Gets a range that should not be reported as an overly wide range. */ -RegExpCharacterRange allowedWideRanges() { - // ~ is the last printable ASCII character, it's used right in various wide ranges. - result.isRange(_, "~") - or - // the same with " " and "!". " " is the first printable character, and "!" is the first non-white-space printable character. - result.isRange([" ", "!"], _) - or - // the `[@-_]` range is intentional - result.isRange("@", "_") - or - // starting from the zero byte is a good indication that it's purposely matching a large range. - result.isRange(0.toUnicode(), _) -} - -/** Gets a char between (and including) `low` and `high`. */ -bindingset[low, high] -private string getInRange(string low, string high) { - result = [toCodePoint(low) .. toCodePoint(high)].toUnicode() -} - -/** A module computing an equivalent character class for an overly wide range. */ -module RangePrinter { - bindingset[char] - bindingset[result] - private string next(string char) { - exists(int prev, int next | - prev.toUnicode() = char and - next.toUnicode() = result and - next = prev + 1 - ) - } - - /** Gets the points where the parts of the pretty printed range should be cut off. */ - private string cutoffs() { result = ["A", "Z", "a", "z", "0", "9"] } - - /** Gets the char to use in the low end of a range for a given `cut` */ - private string lowCut(string cut) { - cut = ["A", "a", "0"] and - result = cut - or - cut = ["Z", "z", "9"] and - result = next(cut) - } - - /** Gets the char to use in the high end of a range for a given `cut` */ - private string highCut(string cut) { - cut = ["Z", "z", "9"] and - result = cut - or - cut = ["A", "a", "0"] and - next(result) = cut - } - - /** Gets the cutoff char used for a given `part` of a range when pretty-printing it. */ - private string cutoff(OverlyWideRange range, int part) { - exists(int low, int high | isRange(range, low, high) | - result = - rank[part + 1](string cut | - cut = cutoffs() and low < toCodePoint(cut) and toCodePoint(cut) < high - | - cut order by toCodePoint(cut) - ) - ) - } - - /** Gets the number of parts we should print for a given `range`. */ - private int parts(OverlyWideRange range) { result = 1 + count(cutoff(range, _)) } - - /** Holds if the given part of a range should span from `low` to `high`. */ - private predicate part(OverlyWideRange range, int part, string low, string high) { - // first part. - part = 0 and - ( - range.isRange(low, high) and - parts(range) = 1 - or - parts(range) >= 2 and - range.isRange(low, _) and - high = highCut(cutoff(range, part)) - ) - or - // middle - part >= 1 and - part < parts(range) - 1 and - low = lowCut(cutoff(range, part - 1)) and - high = highCut(cutoff(range, part)) - or - // last. - part = parts(range) - 1 and - low = lowCut(cutoff(range, part - 1)) and - range.isRange(_, high) - } - - /** Gets an escaped `char` for use in a character class. */ - bindingset[char] - private string escape(string char) { - exists(string reg | reg = "(\\[|\\]|\\\\|-|/)" | - if char.regexpMatch(reg) then result = "\\" + char else result = char - ) - } - - /** Gets a part of the equivalent range. */ - private string printEquivalentCharClass(OverlyWideRange range, int part) { - exists(string low, string high | part(range, part, low, high) | - if - isAlphanumeric(low) and - isAlphanumeric(high) - then result = low + "-" + high - else - result = - strictconcat(string char | char = getInRange(low, high) | escape(char) order by char) - ) - } - - /** Gets the entire pretty printed equivalent range. */ - string printEquivalentCharClass(OverlyWideRange range) { - result = - strictconcat(string r, int part | - r = "[" and part = -1 and exists(range) - or - r = printEquivalentCharClass(range, part) - or - r = "]" and part = parts(range) - | - r order by part - ) - } -} - -/** Gets a char range that is overly large because of `reason`. */ -RegExpCharacterRange getABadRange(string reason, int priority) { - result instanceof OverlyWideRange and - priority = 0 and - exists(string equiv | equiv = result.(OverlyWideRange).printEquivalent() | - if equiv.length() <= 50 - then reason = "is equivalent to " + equiv - else reason = "is equivalent to " + equiv.substring(0, 50) + "..." - ) - or - priority = 1 and - exists(RegExpCharacterRange other | - reason = "overlaps with " + other + " in the same character class" and - rankRange(result) < rankRange(other) and - overlap(result, other) - ) - or - priority = 2 and - exists(RegExpCharacterClassEscape escape | - reason = "overlaps with " + escape + " in the same character class" and - overlapsWithCharEscape(result, escape) - ) - or - reason = "is empty" and - priority = 3 and - exists(int low, int high | - isRange(result, low, high) and - low > high - ) -} - -/** Holds if `range` matches suspiciously many characters. */ -predicate problem(RegExpCharacterRange range, string reason) { - reason = - strictconcat(string m, int priority | - range = getABadRange(m, priority) - | - m, ", and " order by priority desc - ) and - // specifying a range using an escape is usually OK. - not range.getAChild() instanceof RegExpEscape and - // Unicode escapes in strings are interpreted before it turns into a regexp, - // so e.g. [\u0001-\uFFFF] will just turn up as a range between two constants. - // We therefore exclude these ranges. - range.getRootTerm().getParent() instanceof RegExpLiteral and - // is used as regexp (mostly for JS where regular expressions are parsed eagerly) - range.getRootTerm().isUsedAsRegExp() -} +private import semmle.code.java.regex.RegexTreeView::RegexTreeView as TreeView +// OverlyLargeRangeQuery should be used directly from the shared pack, and not from this file. +deprecated import codeql.regex.OverlyLargeRangeQuery::Make as Dep +import Dep diff --git a/java/ql/lib/semmle/code/java/security/regexp/ExponentialBackTracking.qll b/java/ql/lib/semmle/code/java/security/regexp/ExponentialBackTracking.qll index 4a608890249..d0a08dc88bf 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/ExponentialBackTracking.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/ExponentialBackTracking.qll @@ -62,284 +62,7 @@ * a suffix `x` (possible empty) that is most likely __not__ accepted. */ -import NfaUtils - -/** - * Holds if state `s` might be inside a backtracking repetition. - */ -pragma[noinline] -private predicate stateInsideBacktracking(State s) { - s.getRepr().getParent*() instanceof MaybeBacktrackingRepetition -} - -/** - * A infinitely repeating quantifier that might backtrack. - */ -private class MaybeBacktrackingRepetition extends InfiniteRepetitionQuantifier { - MaybeBacktrackingRepetition() { - exists(RegExpTerm child | - child instanceof RegExpAlt or - child instanceof RegExpQuantifier - | - child.getParent+() = this - ) - } -} - -/** - * A state in the product automaton. - */ -private newtype TStatePair = - /** - * We lazily only construct those states that we are actually - * going to need: `(q, q)` for every fork state `q`, and any - * pair of states that can be reached from a pair that we have - * already constructed. To cut down on the number of states, - * we only represent states `(q1, q2)` where `q1` is lexicographically - * no bigger than `q2`. - * - * States are only constructed if both states in the pair are - * inside a repetition that might backtrack. - */ - MkStatePair(State q1, State q2) { - isFork(q1, _, _, _, _) and q2 = q1 - or - (step(_, _, _, q1, q2) or step(_, _, _, q2, q1)) and - rankState(q1) <= rankState(q2) - } - -/** - * Gets a unique number for a `state`. - * Is used to create an ordering of states, where states with the same `toString()` will be ordered differently. - */ -private int rankState(State state) { - state = - rank[result](State s, Location l | - stateInsideBacktracking(s) and - l = s.getRepr().getLocation() - | - s order by l.getStartLine(), l.getStartColumn(), s.toString() - ) -} - -/** - * A state in the product automaton. - */ -private class StatePair extends TStatePair { - State q1; - State q2; - - StatePair() { this = MkStatePair(q1, q2) } - - /** Gets a textual representation of this element. */ - string toString() { result = "(" + q1 + ", " + q2 + ")" } - - /** Gets the first component of the state pair. */ - State getLeft() { result = q1 } - - /** Gets the second component of the state pair. */ - State getRight() { result = q2 } -} - -/** - * Holds for `(fork, fork)` state pairs when `isFork(fork, _, _, _, _)` holds. - * - * Used in `statePairDistToFork` - */ -private predicate isStatePairFork(StatePair p) { - exists(State fork | p = MkStatePair(fork, fork) and isFork(fork, _, _, _, _)) -} - -/** - * Holds if there are transitions from the components of `q` to the corresponding - * components of `r`. - * - * Used in `statePairDistToFork` - */ -private predicate reverseStep(StatePair r, StatePair q) { step(q, _, _, r) } - -/** - * Gets the minimum length of a path from `q` to `r` in the - * product automaton. - */ -private int statePairDistToFork(StatePair q, StatePair r) = - shortestDistances(isStatePairFork/1, reverseStep/2)(r, q, result) - -/** - * Holds if there are transitions from `q` to `r1` and from `q` to `r2` - * labelled with `s1` and `s2`, respectively, where `s1` and `s2` do not - * trivially have an empty intersection. - * - * This predicate only holds for states associated with regular expressions - * that have at least one repetition quantifier in them (otherwise the - * expression cannot be vulnerable to ReDoS attacks anyway). - */ -pragma[noopt] -private predicate isFork(State q, InputSymbol s1, InputSymbol s2, State r1, State r2) { - stateInsideBacktracking(q) and - exists(State q1, State q2 | - q1 = epsilonSucc*(q) and - delta(q1, s1, r1) and - q2 = epsilonSucc*(q) and - delta(q2, s2, r2) and - // Use pragma[noopt] to prevent intersect(s1,s2) from being the starting point of the join. - // From (s1,s2) it would find a huge number of intermediate state pairs (q1,q2) originating from different literals, - // and discover at the end that no `q` can reach both `q1` and `q2` by epsilon transitions. - exists(intersect(s1, s2)) - | - s1 != s2 - or - r1 != r2 - or - r1 = r2 and q1 != q2 - or - // If q can reach itself by epsilon transitions, then there are two distinct paths to the q1/q2 state: - // one that uses the loop and one that doesn't. The engine will separately attempt to match with each path, - // despite ending in the same state. The "fork" thus arises from the choice of whether to use the loop or not. - // To avoid every state in the loop becoming a fork state, - // we arbitrarily pick the InfiniteRepetitionQuantifier state as the canonical fork state for the loop - // (every epsilon-loop must contain such a state). - // - // We additionally require that the there exists another InfiniteRepetitionQuantifier `mid` on the path from `q` to itself. - // This is done to avoid flagging regular expressions such as `/(a?)*b/` - that only has polynomial runtime, and is detected by `js/polynomial-redos`. - // The below code is therefore a heuristic, that only flags regular expressions such as `/(a*)*b/`, - // and does not flag regular expressions such as `/(a?b?)c/`, but the latter pattern is not used frequently. - r1 = r2 and - q1 = q2 and - epsilonSucc+(q) = q and - exists(RegExpTerm term | term = q.getRepr() | term instanceof InfiniteRepetitionQuantifier) and - // One of the mid states is an infinite quantifier itself - exists(State mid, RegExpTerm term | - mid = epsilonSucc+(q) and - term = mid.getRepr() and - term instanceof InfiniteRepetitionQuantifier and - q = epsilonSucc+(mid) and - not mid = q - ) - ) and - stateInsideBacktracking(r1) and - stateInsideBacktracking(r2) -} - -/** - * Gets the state pair `(q1, q2)` or `(q2, q1)`; note that only - * one or the other is defined. - */ -private StatePair mkStatePair(State q1, State q2) { - result = MkStatePair(q1, q2) or result = MkStatePair(q2, q1) -} - -/** - * Holds if there are transitions from the components of `q` to the corresponding - * components of `r` labelled with `s1` and `s2`, respectively. - */ -private predicate step(StatePair q, InputSymbol s1, InputSymbol s2, StatePair r) { - exists(State r1, State r2 | step(q, s1, s2, r1, r2) and r = mkStatePair(r1, r2)) -} - -/** - * Holds if there are transitions from the components of `q` to `r1` and `r2` - * labelled with `s1` and `s2`, respectively. - * - * We only consider transitions where the resulting states `(r1, r2)` are both - * inside a repetition that might backtrack. - */ -pragma[noopt] -private predicate step(StatePair q, InputSymbol s1, InputSymbol s2, State r1, State r2) { - exists(State q1, State q2 | q.getLeft() = q1 and q.getRight() = q2 | - deltaClosed(q1, s1, r1) and - deltaClosed(q2, s2, r2) and - // use noopt to force the join on `intersect` to happen last. - exists(intersect(s1, s2)) - ) and - stateInsideBacktracking(r1) and - stateInsideBacktracking(r2) -} - -private newtype TTrace = - Nil() or - Step(InputSymbol s1, InputSymbol s2, TTrace t) { isReachableFromFork(_, _, s1, s2, t, _) } - -/** - * A list of pairs of input symbols that describe a path in the product automaton - * starting from some fork state. - */ -private class Trace extends TTrace { - /** Gets a textual representation of this element. */ - string toString() { - this = Nil() and result = "Nil()" - or - exists(InputSymbol s1, InputSymbol s2, Trace t | this = Step(s1, s2, t) | - result = "Step(" + s1 + ", " + s2 + ", " + t + ")" - ) - } -} - -/** - * Holds if `r` is reachable from `(fork, fork)` under input `w`, and there is - * a path from `r` back to `(fork, fork)` with `rem` steps. - */ -private predicate isReachableFromFork(State fork, StatePair r, Trace w, int rem) { - exists(InputSymbol s1, InputSymbol s2, Trace v | - isReachableFromFork(fork, r, s1, s2, v, rem) and - w = Step(s1, s2, v) - ) -} - -private predicate isReachableFromFork( - State fork, StatePair r, InputSymbol s1, InputSymbol s2, Trace v, int rem -) { - // base case - exists(State q1, State q2 | - isFork(fork, s1, s2, q1, q2) and - r = MkStatePair(q1, q2) and - v = Nil() and - rem = statePairDistToFork(r, MkStatePair(fork, fork)) - ) - or - // recursive case - exists(StatePair p | - isReachableFromFork(fork, p, v, rem + 1) and - step(p, s1, s2, r) and - rem = statePairDistToFork(r, MkStatePair(fork, fork)) - ) -} - -/** - * Gets a state in the product automaton from which `(fork, fork)` is - * reachable in zero or more epsilon transitions. - */ -private StatePair getAForkPair(State fork) { - isFork(fork, _, _, _, _) and - result = MkStatePair(epsilonPred*(fork), epsilonPred*(fork)) -} - -/** An implementation of a chain containing chars for use by `Concretizer`. */ -private module CharTreeImpl implements CharTree { - class CharNode = Trace; - - CharNode getPrev(CharNode t) { t = Step(_, _, result) } - - /** Holds if `n` is a trace that is used by `concretize` in `isPumpable`. */ - predicate isARelevantEnd(CharNode n) { - exists(State f | isReachableFromFork(f, getAForkPair(f), n, _)) - } - - string getChar(CharNode t) { - exists(InputSymbol s1, InputSymbol s2 | t = Step(s1, s2, _) | result = intersect(s1, s2)) - } -} - -/** - * Holds if `fork` is a pumpable fork with word `w`. - */ -private predicate isPumpable(State fork, string w) { - exists(StatePair q, Trace t | - isReachableFromFork(fork, q, t, _) and - q = getAForkPair(fork) and - w = Concretizer::concretize(t) - ) -} - -/** Holds if `state` has exponential ReDoS */ -predicate hasReDoSResult = ReDoSPruning::hasReDoSResult/4; +private import semmle.code.java.regex.RegexTreeView::RegexTreeView as TreeView +// ExponentialBackTracking should be used directly from the shared pack, and not from this file. +deprecated private import codeql.regex.nfa.ExponentialBackTracking::Make as Dep +import Dep 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 5ff0cb6a39e..3b69ecc7120 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll @@ -7,1332 +7,7 @@ * other queries that benefit from reasoning about NFAs. */ -import NfaUtilsSpecific - -/** - * Gets the char after `c` (from a simplified ASCII table). - */ -private string nextChar(string c) { exists(int code | code = ascii(c) | code + 1 = ascii(result)) } - -/** - * Gets an approximation for the ASCII code for `char`. - * Only the easily printable chars are included (so no newline, tab, null, etc). - */ -private int ascii(string char) { - char = - rank[result](string c | - c = - "! \"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" - .charAt(_) - ) -} - -/** - * Holds if `t` matches at least an epsilon symbol. - * - * That is, this term does not restrict the language of the enclosing regular expression. - * - * This is implemented as an under-approximation, and this predicate does not hold for sub-patterns in particular. - */ -predicate matchesEpsilon(RegExpTerm t) { - t instanceof RegExpStar - or - t instanceof RegExpOpt - or - t.(RegExpRange).getLowerBound() = 0 - or - exists(RegExpTerm child | - child = t.getAChild() and - matchesEpsilon(child) - | - t instanceof RegExpAlt or - t instanceof RegExpGroup or - t instanceof RegExpPlus or - t instanceof RegExpRange - ) - or - matchesEpsilon(t.(RegExpBackRef).getGroup()) - or - forex(RegExpTerm child | child = t.(RegExpSequence).getAChild() | matchesEpsilon(child)) -} - -/** - * A lookahead/lookbehind that matches the empty string. - */ -class EmptyPositiveSubPattern extends RegExpSubPattern { - EmptyPositiveSubPattern() { - ( - this instanceof RegExpPositiveLookahead - or - this instanceof RegExpPositiveLookbehind - ) and - matchesEpsilon(this.getOperand()) - } -} - -/** DEPRECATED: Use `EmptyPositiveSubPattern` instead. */ -deprecated class EmptyPositiveSubPatttern = EmptyPositiveSubPattern; - -/** - * A branch in a disjunction that is the root node in a literal, or a literal - * whose root node is not a disjunction. - */ -class RegExpRoot extends RegExpTerm { - RegExpRoot() { - exists(RegExpParent parent | - exists(RegExpAlt alt | - alt.isRootTerm() and - this = alt.getAChild() and - parent = alt.getParent() - ) - or - this.isRootTerm() and - not this instanceof RegExpAlt and - parent = this.getParent() - ) - } - - /** - * Holds if this root term is relevant to the ReDoS analysis. - */ - predicate isRelevant() { - // is actually used as a RegExp - this.isUsedAsRegExp() and - // not excluded for library specific reasons - not isExcluded(this.getRootTerm().getParent()) - } -} - -/** - * A constant in a regular expression that represents valid Unicode character(s). - */ -private class RegexpCharacterConstant extends RegExpConstant { - RegexpCharacterConstant() { this.isCharacter() } -} - -/** - * A regexp term that is relevant for this ReDoS analysis. - */ -class RelevantRegExpTerm extends RegExpTerm { - RelevantRegExpTerm() { getRoot(this).isRelevant() } -} - -/** - * Holds if `term` is the chosen canonical representative for all terms with string representation `str`. - * The string representation includes which flags are used with the regular expression. - * - * Using canonical representatives gives a huge performance boost when working with tuples containing multiple `InputSymbol`s. - * The number of `InputSymbol`s is decreased by 3 orders of magnitude or more in some larger benchmarks. - */ -private predicate isCanonicalTerm(RelevantRegExpTerm term, string str) { - term = - min(RelevantRegExpTerm t, Location loc, File file | - loc = t.getLocation() and - file = t.getFile() and - str = getCanonicalizationString(t) - | - t order by t.getFile().getRelativePath(), loc.getStartLine(), loc.getStartColumn() - ) -} - -/** - * Gets a string representation of `term` that is used for canonicalization. - */ -private string getCanonicalizationString(RelevantRegExpTerm term) { - exists(string ignoreCase | - (if RegExpFlags::isIgnoreCase(term.getRootTerm()) then ignoreCase = "i" else ignoreCase = "") and - result = term.getRawValue() + "|" + ignoreCase - ) -} - -/** - * An abstract input symbol, representing a set of concrete characters. - */ -private newtype TInputSymbol = - /** An input symbol corresponding to character `c`. */ - Char(string c) { - c = - any(RegexpCharacterConstant cc | - cc instanceof RelevantRegExpTerm and - not RegExpFlags::isIgnoreCase(cc.getRootTerm()) - ).getValue().charAt(_) - or - // normalize everything to lower case if the regexp is case insensitive - c = - any(RegexpCharacterConstant cc, string char | - cc instanceof RelevantRegExpTerm and - RegExpFlags::isIgnoreCase(cc.getRootTerm()) and - char = cc.getValue().charAt(_) - | - char.toLowerCase() - ) - } or - /** - * An input symbol representing all characters matched by - * a (non-universal) character class that has string representation `charClassString`. - */ - CharClass(string charClassString) { - exists(RelevantRegExpTerm recc | isCanonicalTerm(recc, charClassString) | - recc instanceof RegExpCharacterClass and - not recc.(RegExpCharacterClass).isUniversalClass() - or - isEscapeClass(recc, _) - ) - } or - /** An input symbol representing all characters matched by `.`. */ - Dot() or - /** An input symbol representing all characters. */ - Any() or - /** An epsilon transition in the automaton. */ - Epsilon() - -/** - * Gets the the CharClass corresponding to the canonical representative `term`. - */ -private CharClass getCharClassForCanonicalTerm(RegExpTerm term) { - exists(string str | isCanonicalTerm(term, str) | result = CharClass(str)) -} - -/** - * Gets a char class that represents `term`, even when `term` is not the canonical representative. - */ -CharacterClass getCanonicalCharClass(RegExpTerm term) { - exists(string str | str = getCanonicalizationString(term) and result = CharClass(str)) -} - -/** - * Holds if `a` and `b` are input symbols from the same regexp. - */ -private predicate sharesRoot(InputSymbol a, InputSymbol b) { - exists(RegExpRoot root | - belongsTo(a, root) and - belongsTo(b, root) - ) -} - -/** - * Holds if the `a` is an input symbol from a regexp that has root `root`. - */ -private predicate belongsTo(InputSymbol a, RegExpRoot root) { - exists(State s | getRoot(s.getRepr()) = root | - delta(s, a, _) - or - delta(_, a, s) - ) -} - -/** - * An abstract input symbol, representing a set of concrete characters. - */ -class InputSymbol extends TInputSymbol { - InputSymbol() { not this instanceof Epsilon } - - /** - * Gets a string representation of this input symbol. - */ - string toString() { - this = Char(result) - or - this = CharClass(result) - or - this = Dot() and result = "." - or - this = Any() and result = "[^]" - } -} - -/** - * An abstract input symbol that represents a character class. - */ -abstract class CharacterClass extends InputSymbol { - /** - * Gets a character that is relevant for intersection-tests involving this - * character class. - * - * Specifically, this is any of the characters mentioned explicitly in the - * character class, offset by one if it is inverted. For character class escapes, - * the result is as if the class had been written out as a series of intervals. - * - * This set is large enough to ensure that for any two intersecting character - * classes, one contains a relevant character from the other. - */ - abstract string getARelevantChar(); - - /** - * Holds if this character class matches `char`. - */ - bindingset[char] - abstract predicate matches(string char); - - /** - * Gets a character matched by this character class. - */ - string choose() { result = this.getARelevantChar() and this.matches(result) } -} - -/** - * Provides implementations for `CharacterClass`. - */ -private module CharacterClasses { - /** - * Holds if the character class `cc` has a child (constant or range) that matches `char`. - */ - pragma[noinline] - predicate hasChildThatMatches(RegExpCharacterClass cc, string char) { - if RegExpFlags::isIgnoreCase(cc.getRootTerm()) - then - // normalize everything to lower case if the regexp is case insensitive - exists(string c | hasChildThatMatchesIgnoringCasingFlags(cc, c) | char = c.toLowerCase()) - else hasChildThatMatchesIgnoringCasingFlags(cc, char) - } - - /** - * Holds if the character class `cc` has a child (constant or range) that matches `char`. - * Ignores whether the character class is inside a regular expression that has the ignore case flag. - */ - pragma[noinline] - predicate hasChildThatMatchesIgnoringCasingFlags(RegExpCharacterClass cc, string char) { - exists(getCharClassForCanonicalTerm(cc)) and - exists(RegExpTerm child | child = cc.getAChild() | - char = child.(RegexpCharacterConstant).getValue() - or - rangeMatchesOnLetterOrDigits(child, char) - or - not rangeMatchesOnLetterOrDigits(child, _) and - char = getARelevantChar() and - exists(string lo, string hi | child.(RegExpCharacterRange).isRange(lo, hi) | - lo <= char and - char <= hi - ) - or - exists(string charClass | isEscapeClass(child, charClass) | - charClass.toLowerCase() = charClass and - classEscapeMatches(charClass, char) - or - char = getARelevantChar() and - charClass.toUpperCase() = charClass and - not classEscapeMatches(charClass, char) - ) - ) - } - - /** - * Holds if `range` is a range on lower-case, upper-case, or digits, and matches `char`. - * This predicate is used to restrict the searchspace for ranges by only joining `getAnyPossiblyMatchedChar` - * on a few ranges. - */ - private predicate rangeMatchesOnLetterOrDigits(RegExpCharacterRange range, string char) { - exists(string lo, string hi | - range.isRange(lo, hi) and lo = lowercaseLetter() and hi = lowercaseLetter() - | - lo <= char and - char <= hi and - char = lowercaseLetter() - ) - or - exists(string lo, string hi | - range.isRange(lo, hi) and lo = upperCaseLetter() and hi = upperCaseLetter() - | - lo <= char and - char <= hi and - char = upperCaseLetter() - ) - or - exists(string lo, string hi | range.isRange(lo, hi) and lo = digit() and hi = digit() | - lo <= char and - char <= hi and - char = digit() - ) - } - - private string lowercaseLetter() { result = "abcdefghijklmnopqrstuvwxyz".charAt(_) } - - private string upperCaseLetter() { result = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".charAt(_) } - - private string digit() { result = [0 .. 9].toString() } - - /** - * Gets a char that could be matched by a regular expression. - * Includes all printable ascii chars, all constants mentioned in a regexp, and all chars matches by the regexp `/\s|\d|\w/`. - */ - string getARelevantChar() { - exists(ascii(result)) - or - exists(RegexpCharacterConstant c | result = c.getValue().charAt(_)) - or - classEscapeMatches(_, result) - } - - /** - * Gets a char that is mentioned in the character class `c`. - */ - private string getAMentionedChar(RegExpCharacterClass c) { - exists(RegExpTerm child | child = c.getAChild() | - result = child.(RegexpCharacterConstant).getValue() - or - child.(RegExpCharacterRange).isRange(result, _) - or - child.(RegExpCharacterRange).isRange(_, result) - or - exists(string charClass | isEscapeClass(child, charClass) | - result = min(string s | classEscapeMatches(charClass.toLowerCase(), s)) - or - result = max(string s | classEscapeMatches(charClass.toLowerCase(), s)) - ) - ) - } - - bindingset[char, cc] - private string caseNormalize(string char, RegExpTerm cc) { - if RegExpFlags::isIgnoreCase(cc.getRootTerm()) - then result = char.toLowerCase() - else result = char - } - - /** - * An implementation of `CharacterClass` for positive (non inverted) character classes. - */ - private class PositiveCharacterClass extends CharacterClass { - RegExpCharacterClass cc; - - PositiveCharacterClass() { this = getCharClassForCanonicalTerm(cc) and not cc.isInverted() } - - override string getARelevantChar() { result = caseNormalize(getAMentionedChar(cc), cc) } - - override predicate matches(string char) { hasChildThatMatches(cc, char) } - } - - /** - * An implementation of `CharacterClass` for inverted character classes. - */ - private class InvertedCharacterClass extends CharacterClass { - RegExpCharacterClass cc; - - InvertedCharacterClass() { this = getCharClassForCanonicalTerm(cc) and cc.isInverted() } - - override string getARelevantChar() { - result = nextChar(caseNormalize(getAMentionedChar(cc), cc)) or - nextChar(result) = caseNormalize(getAMentionedChar(cc), cc) - } - - bindingset[char] - override predicate matches(string char) { not hasChildThatMatches(cc, char) } - } - - /** - * Holds if the character class escape `clazz` (\d, \s, or \w) matches `char`. - */ - pragma[noinline] - private predicate classEscapeMatches(string clazz, string char) { - clazz = "d" and - char = "0123456789".charAt(_) - or - clazz = "s" and - char = [" ", "\t", "\r", "\n", 11.toUnicode(), 12.toUnicode()] // 11.toUnicode() = \v, 12.toUnicode() = \f - or - clazz = "w" and - char = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_".charAt(_) - } - - /** - * An implementation of `CharacterClass` for \d, \s, and \w. - */ - private class PositiveCharacterClassEscape extends CharacterClass { - string charClass; - RegExpTerm cc; - - PositiveCharacterClassEscape() { - isEscapeClass(cc, charClass) and - this = getCharClassForCanonicalTerm(cc) and - charClass = ["d", "s", "w"] - } - - override string getARelevantChar() { - charClass = "d" and - result = ["0", "9"] - or - charClass = "s" and - result = " " - or - charClass = "w" and - if RegExpFlags::isIgnoreCase(cc.getRootTerm()) - then result = ["a", "z", "_", "0", "9"] - else result = ["a", "Z", "_", "0", "9"] - } - - override predicate matches(string char) { classEscapeMatches(charClass, char) } - - override string choose() { - charClass = "d" and - result = "9" - or - charClass = "s" and - result = " " - or - charClass = "w" and - result = "a" - } - } - - /** - * An implementation of `CharacterClass` for \D, \S, and \W. - */ - private class NegativeCharacterClassEscape extends CharacterClass { - string charClass; - - NegativeCharacterClassEscape() { - exists(RegExpTerm cc | - isEscapeClass(cc, charClass) and - this = getCharClassForCanonicalTerm(cc) and - charClass = ["D", "S", "W"] - ) - } - - override string getARelevantChar() { - charClass = "D" and - result = ["a", "Z", "!"] - or - charClass = "S" and - result = ["a", "9", "!"] - or - charClass = "W" and - result = [" ", "!"] - } - - bindingset[char] - override predicate matches(string char) { - not classEscapeMatches(charClass.toLowerCase(), char) - } - } - - /** Gets a representative for all char classes that match the same chars as `c`. */ - CharacterClass normalize(CharacterClass c) { - exists(string normalization | - normalization = getNormalizationString(c) and - result = - min(CharacterClass cc, string raw | - getNormalizationString(cc) = normalization and cc = CharClass(raw) - | - cc order by raw - ) - ) - } - - /** Gets a string representing all the chars matched by `c` */ - private string getNormalizationString(CharacterClass c) { - (c instanceof PositiveCharacterClass or c instanceof PositiveCharacterClassEscape) and - result = concat(string char | c.matches(char) and char = CharacterClasses::getARelevantChar()) - or - (c instanceof InvertedCharacterClass or c instanceof NegativeCharacterClassEscape) and - // the string produced by the concat can not contain repeated chars - // so by starting the below with "nn" we can guarantee that - // it will not overlap with the above case. - // and a negative char class can never match the same chars as a positive one, so we don't miss any results from this. - result = - "nn:" + - concat(string char | not c.matches(char) and char = CharacterClasses::getARelevantChar()) - } -} - -private class EdgeLabel extends TInputSymbol { - string toString() { - this = Epsilon() and result = "" - or - exists(InputSymbol s | this = s and result = s.toString()) - } -} - -/** - * A RegExp term that acts like a plus. - * Either it's a RegExpPlus, or it is a range {1,X} where X is >= 30. - * 30 has been chosen as a threshold because for exponential blowup 2^30 is enough to get a decent DOS attack. - */ -private class EffectivelyPlus extends RegExpTerm { - EffectivelyPlus() { - this instanceof RegExpPlus - or - exists(RegExpRange range | - range.getLowerBound() = 1 and - (range.getUpperBound() >= 30 or not exists(range.getUpperBound())) - | - this = range - ) - } -} - -/** - * A RegExp term that acts like a star. - * Either it's a RegExpStar, or it is a range {0,X} where X is >= 30. - */ -private class EffectivelyStar extends RegExpTerm { - EffectivelyStar() { - this instanceof RegExpStar - or - exists(RegExpRange range | - range.getLowerBound() = 0 and - (range.getUpperBound() >= 30 or not exists(range.getUpperBound())) - | - this = range - ) - } -} - -/** - * A RegExp term that acts like a question mark. - * Either it's a RegExpQuestion, or it is a range {0,1}. - */ -private class EffectivelyQuestion extends RegExpTerm { - EffectivelyQuestion() { - this instanceof RegExpOpt - or - exists(RegExpRange range | range.getLowerBound() = 0 and range.getUpperBound() = 1 | - this = range - ) - } -} - -/** - * Gets the state before matching `t`. - */ -pragma[inline] -private State before(RegExpTerm t) { result = Match(t, 0) } - -/** - * Gets a state the NFA may be in after matching `t`. - */ -State after(RegExpTerm t) { - exists(RegExpAlt alt | t = alt.getAChild() | result = after(alt)) - or - exists(RegExpSequence seq, int i | t = seq.getChild(i) | - result = before(seq.getChild(i + 1)) - or - i + 1 = seq.getNumChild() and result = after(seq) - ) - or - exists(RegExpGroup grp | t = grp.getAChild() | result = after(grp)) - or - exists(EffectivelyStar star | t = star.getAChild() | - not isPossessive(star) and - result = before(star) - ) - or - exists(EffectivelyPlus plus | t = plus.getAChild() | - not isPossessive(plus) and - result = before(plus) - or - result = after(plus) - ) - or - exists(EffectivelyQuestion opt | t = opt.getAChild() | result = after(opt)) - or - exists(RegExpRoot root | t = root | - if matchesAnySuffix(root) then result = AcceptAnySuffix(root) else result = Accept(root) - ) -} - -/** - * Holds if the NFA has a transition from `q1` to `q2` labelled with `lbl`. - */ -predicate delta(State q1, EdgeLabel lbl, State q2) { - exists(RegexpCharacterConstant s, int i | - q1 = Match(s, i) and - ( - not RegExpFlags::isIgnoreCase(s.getRootTerm()) and - lbl = Char(s.getValue().charAt(i)) - or - // normalize everything to lower case if the regexp is case insensitive - RegExpFlags::isIgnoreCase(s.getRootTerm()) and - exists(string c | c = s.getValue().charAt(i) | lbl = Char(c.toLowerCase())) - ) and - ( - q2 = Match(s, i + 1) - or - s.getValue().length() = i + 1 and - q2 = after(s) - ) - ) - or - exists(RegExpDot dot | q1 = before(dot) and q2 = after(dot) | - if RegExpFlags::isDotAll(dot.getRootTerm()) then lbl = Any() else lbl = Dot() - ) - or - exists(RegExpCharacterClass cc | - cc.isUniversalClass() and q1 = before(cc) and lbl = Any() and q2 = after(cc) - or - q1 = before(cc) and - lbl = CharacterClasses::normalize(CharClass(getCanonicalizationString(cc))) and - q2 = after(cc) - ) - or - exists(RegExpTerm cc | isEscapeClass(cc, _) | - q1 = before(cc) and - lbl = CharacterClasses::normalize(CharClass(getCanonicalizationString(cc))) and - q2 = after(cc) - ) - or - exists(RegExpAlt alt | lbl = Epsilon() | q1 = before(alt) and q2 = before(alt.getAChild())) - or - exists(RegExpSequence seq | lbl = Epsilon() | q1 = before(seq) and q2 = before(seq.getChild(0))) - or - exists(RegExpGroup grp | lbl = Epsilon() | q1 = before(grp) and q2 = before(grp.getChild(0))) - or - exists(EffectivelyStar star | lbl = Epsilon() | - q1 = before(star) and q2 = before(star.getChild(0)) - or - q1 = before(star) and q2 = after(star) - ) - or - exists(EffectivelyPlus plus | lbl = Epsilon() | - q1 = before(plus) and q2 = before(plus.getChild(0)) - ) - or - exists(EffectivelyQuestion opt | lbl = Epsilon() | - q1 = before(opt) and q2 = before(opt.getChild(0)) - or - q1 = before(opt) and q2 = after(opt) - ) - or - exists(RegExpRoot root | q1 = AcceptAnySuffix(root) | - lbl = Any() and q2 = q1 - or - lbl = Epsilon() and q2 = Accept(root) - ) - or - exists(RegExpRoot root | q1 = Match(root, 0) | matchesAnyPrefix(root) and lbl = Any() and q2 = q1) - or - exists(RegExpDollar dollar | q1 = before(dollar) | - lbl = Epsilon() and q2 = Accept(getRoot(dollar)) - ) - or - exists(EmptyPositiveSubPattern empty | q1 = before(empty) | lbl = Epsilon() and q2 = after(empty)) -} - -/** - * Gets a state that `q` has an epsilon transition to. - */ -State epsilonSucc(State q) { delta(q, Epsilon(), result) } - -/** - * Gets a state that has an epsilon transition to `q`. - */ -State epsilonPred(State q) { q = epsilonSucc(result) } - -/** - * Holds if there is a state `q` that can be reached from `q1` - * along epsilon edges, such that there is a transition from - * `q` to `q2` that consumes symbol `s`. - */ -predicate deltaClosed(State q1, InputSymbol s, State q2) { delta(epsilonSucc*(q1), s, q2) } - -/** - * Gets the root containing the given term, that is, the root of the literal, - * or a branch of the root disjunction. - */ -RegExpRoot getRoot(RegExpTerm term) { - result = term or - result = getRoot(term.getParent()) -} - -/** - * A state in the NFA. - */ -newtype TState = - /** - * A state representing that the NFA is about to match a term. - * `i` is used to index into multi-char literals. - */ - Match(RelevantRegExpTerm t, int i) { - i = 0 - or - exists(t.(RegexpCharacterConstant).getValue().charAt(i)) - } or - /** - * An accept state, where exactly the given input string is accepted. - */ - Accept(RegExpRoot l) { l.isRelevant() } or - /** - * An accept state, where the given input string, or any string that has this - * string as a prefix, is accepted. - */ - AcceptAnySuffix(RegExpRoot l) { l.isRelevant() } - -/** - * Gets a state that is about to match the regular expression `t`. - */ -State mkMatch(RegExpTerm t) { result = Match(t, 0) } - -/** - * A state in the NFA corresponding to a regular expression. - * - * Each regular expression literal `l` has one accepting state - * `Accept(l)`, one state that accepts all suffixes `AcceptAnySuffix(l)`, - * and a state `Match(t, i)` for every subterm `t`, - * which represents the state of the NFA before starting to - * match `t`, or the `i`th character in `t` if `t` is a constant. - */ -class State extends TState { - RegExpTerm repr; - - State() { - this = Match(repr, _) or - this = Accept(repr) or - this = AcceptAnySuffix(repr) - } - - /** - * Gets a string representation for this state in a regular expression. - */ - string toString() { - exists(int i | this = Match(repr, i) | result = "Match(" + repr + "," + i + ")") - or - this instanceof Accept and - result = "Accept(" + repr + ")" - or - this instanceof AcceptAnySuffix and - result = "AcceptAny(" + repr + ")" - } - - /** - * Gets the location for this state. - */ - Location getLocation() { result = repr.getLocation() } - - /** - * Gets the term represented by this state. - */ - RegExpTerm getRepr() { result = repr } -} - -/** - * Gets the minimum char that is matched by both the character classes `c` and `d`. - */ -private string getMinOverlapBetweenCharacterClasses(CharacterClass c, CharacterClass d) { - result = min(getAOverlapBetweenCharacterClasses(c, d)) -} - -/** - * Gets a char that is matched by both the character classes `c` and `d`. - * And `c` and `d` is not the same character class. - */ -private string getAOverlapBetweenCharacterClasses(CharacterClass c, CharacterClass d) { - sharesRoot(c, d) and - result = [c.getARelevantChar(), d.getARelevantChar()] and - c.matches(result) and - d.matches(result) and - not c = d -} - -/** - * Gets a character that is represented by both `c` and `d`. - */ -string intersect(InputSymbol c, InputSymbol d) { - (sharesRoot(c, d) or [c, d] = Any()) and - ( - c = Char(result) and - d = getAnInputSymbolMatching(result) - or - result = getMinOverlapBetweenCharacterClasses(c, d) - or - result = c.(CharacterClass).choose() and - ( - d = c - or - d = Dot() and - not (result = "\n" or result = "\r") - or - d = Any() - ) - or - (c = Dot() or c = Any()) and - (d = Dot() or d = Any()) and - result = "a" - ) - or - result = intersect(d, c) -} - -/** - * Gets a symbol that matches `char`. - */ -bindingset[char] -InputSymbol getAnInputSymbolMatching(string char) { - result = Char(char) - or - result.(CharacterClass).matches(char) - or - result = Dot() and - not (char = "\n" or char = "\r") - or - result = Any() -} - -/** - * Holds if `state` is a start state. - */ -predicate isStartState(State state) { - state = mkMatch(any(RegExpRoot r)) - or - exists(RegExpCaret car | state = after(car)) -} - -/** - * Holds if `state` is a candidate for ReDoS with string `pump`. - */ -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(RelevantState state) { - exists(RegExpRoot root | - state = - max(RelevantState s, Location l | - 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)) - } - - /** A state within a regular expression that contains a candidate state. */ - class RelevantState instanceof State { - RelevantState() { - exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(this.getRepr())) - } - - /** Gets a string representation for this state in a regular expression. */ - string toString() { result = State.super.toString() } - - /** Gets the term represented by this state. */ - RegExpTerm getRepr() { result = State.super.getRepr() } - } -} - -/** - * A module for pruning candidate ReDoS states. - * The candidates are specified by the `isCandidate` signature predicate. - * The candidates are checked for rejecting suffixes and deduplicated, - * and the resulting ReDoS states are read by the `hasReDoSResult` predicate. - */ -module ReDoSPruning { - /** - * Holds if repeating `pump` starting at `state` is a candidate for causing backtracking. - * No check whether a rejected suffix exists has been made. - */ - private predicate isReDoSCandidate(State state, string pump) { - isCandidate(state, pump) and - not state = acceptsAnySuffix() and // pruning early - these can never get stuck in a rejecting state. - ( - not isCandidate(epsilonSucc+(state), _) - or - epsilonSucc+(state) = state and - state = - max(State s, Location l | - s = epsilonSucc+(state) and - l = s.getRepr().getLocation() and - isCandidate(s, _) and - s.getRepr() instanceof InfiniteRepetitionQuantifier - | - s order by l.getStartLine(), l.getStartColumn(), l.getEndColumn(), l.getEndLine() - ) - ) - } - - /** Gets a state that can reach the `accept-any` state using only epsilon steps. */ - private State acceptsAnySuffix() { epsilonSucc*(result) = AcceptAnySuffix(_) } - - predicate isCandidateState(State s) { isReDoSCandidate(s, _) } - - import PrefixConstruction as Prefix - - class RelevantState = Prefix::RelevantState; - - /** - * Predicates for testing the presence of a rejecting suffix. - * - * These predicates are used to ensure that the all states reached from the fork - * by repeating `w` have a rejecting suffix. - * - * For example, a regexp like `/^(a+)+/` will accept any string as long the prefix is - * some number of `"a"`s, and it is therefore not possible to construct a rejecting suffix. - * - * A regexp like `/(a+)+$/` or `/(a+)+b/` trivially has a rejecting suffix, - * as the suffix "X" will cause both the regular expressions to be rejected. - * - * The string `w` is repeated any number of times because it needs to be - * infinitely repeatable for the attack to work. - * For the regular expression `/((ab)+)*abab/` the accepting state is not reachable from the fork - * using epsilon transitions. But any attempt at repeating `w` will end in a state that accepts all suffixes. - */ - private module SuffixConstruction { - /** - * Holds if all states reachable from `fork` by repeating `w` - * are likely rejectable by appending some suffix. - */ - predicate reachesOnlyRejectableSuffixes(State fork, string w) { - isReDoSCandidate(fork, w) and - forex(State next | next = process(fork, w, w.length() - 1) | isLikelyRejectable(next)) and - not getProcessPrevious(fork, _, w) = acceptsAnySuffix() // we stop `process(..)` early if we can, check here if it happened. - } - - /** - * Holds if there likely exists a suffix starting from `s` that leads to the regular expression being rejected. - * This predicate might find impossible suffixes when searching for suffixes of length > 1, which can cause FPs. - */ - pragma[noinline] - private predicate isLikelyRejectable(RelevantState s) { - // exists a reject edge with some char. - hasRejectEdge(s) - or - hasEdgeToLikelyRejectable(s) - or - // stopping here is rejection - isRejectState(s) - } - - /** - * Holds if `s` is not an accept state, and there is no epsilon transition to an accept state. - */ - predicate isRejectState(RelevantState s) { not epsilonSucc*(s) = Accept(_) } - - /** - * Holds if there is likely a non-empty suffix leading to rejection starting in `s`. - */ - pragma[noopt] - predicate hasEdgeToLikelyRejectable(RelevantState s) { - // 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) | - // noopt to force `hasEdgeToLikelyRejectableHelper` to be first in the join-order. - exists(State next | deltaClosedChar(s, char, next) | isLikelyRejectable(next)) and - forall(State next | deltaClosedChar(s, char, next) | isLikelyRejectable(next)) - ) - } - - /** - * Gets a char for there exists a transition away from `s`, - * and `s` has not been found to be rejectable by `hasRejectEdge` or `isRejectState`. - */ - pragma[noinline] - private string hasEdgeToLikelyRejectableHelper(RelevantState s) { - not hasRejectEdge(s) and - not isRejectState(s) and - deltaClosedChar(s, result, _) - } - - /** - * Holds if there is a state `next` that can be reached from `prev` - * along epsilon edges, such that there is a transition from - * `prev` to `next` that the character symbol `char`. - */ - predicate deltaClosedChar(RelevantState prev, string char, RelevantState next) { - deltaClosed(prev, getAnInputSymbolMatchingRelevant(char), next) - } - - pragma[noinline] - InputSymbol getAnInputSymbolMatchingRelevant(string char) { - char = relevant(_) and - result = getAnInputSymbolMatching(char) - } - - pragma[noinline] - RegExpRoot relevantRoot() { - exists(RegExpTerm term, State s | - s.getRepr() = term and isCandidateState(s) and result = term.getRootTerm() - ) - } - - /** - * Gets a char used for finding possible suffixes inside `root`. - */ - pragma[noinline] - private string relevant(RegExpRoot root) { - root = relevantRoot() and - ( - exists(ascii(result)) and exists(root) - or - exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _)) - or - // The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation). - // The three chars must be kept in sync with `hasSimpleRejectEdge`. - result = ["|", "\n", "Z"] and exists(root) - ) - } - - /** - * Holds if there exists a `char` such that there is no edge from `s` labeled `char` in our NFA. - * The NFA does not model reject states, so the above is the same as saying there is a reject edge. - */ - private predicate hasRejectEdge(State s) { - hasSimpleRejectEdge(s) - or - not hasSimpleRejectEdge(s) and - exists(string char | char = relevant(getRoot(s.getRepr())) | not deltaClosedChar(s, char, _)) - } - - /** - * Holds if there is no edge from `s` labeled with "|", "\n", or "Z" in our NFA. - * This predicate is used as a cheap pre-processing to speed up `hasRejectEdge`. - */ - private predicate hasSimpleRejectEdge(State s) { - // The three chars were chosen arbitrarily. The three chars must be kept in sync with `relevant`. - exists(string char | char = ["|", "\n", "Z"] | not deltaClosedChar(s, char, _)) - } - - /** - * Gets a state that can be reached from pumpable `fork` consuming all - * chars in `w` any number of times followed by the first `i+1` characters of `w`. - */ - pragma[noopt] - private State process(State fork, string w, int i) { - exists(State prev | prev = getProcessPrevious(fork, i, w) | - not prev = acceptsAnySuffix() and // we stop `process(..)` early if we can. If the successor accepts any suffix, then we know it can never be rejected. - exists(string char, InputSymbol sym | - char = w.charAt(i) and - deltaClosed(prev, sym, result) and - // noopt to prevent joining `prev` with all possible `chars` that could transition away from `prev`. - // Instead only join with the set of `chars` where a relevant `InputSymbol` has already been found. - sym = getAProcessInputSymbol(char) - ) - ) - } - - /** - * Gets a state that can be reached from pumpable `fork` consuming all - * chars in `w` any number of times followed by the first `i` characters of `w`. - */ - private State getProcessPrevious(State fork, int i, string w) { - isReDoSCandidate(fork, w) and - ( - i = 0 and result = fork - or - result = process(fork, w, i - 1) - or - // repeat until fixpoint - i = 0 and - result = process(fork, w, w.length() - 1) - ) - } - - /** - * Gets an InputSymbol that matches `char`. - * The predicate is specialized to only have a result for the `char`s that are relevant for the `process` predicate. - */ - private InputSymbol getAProcessInputSymbol(string char) { - char = getAProcessChar() and - result = getAnInputSymbolMatching(char) - } - - /** - * Gets a `char` that occurs in a `pump` string. - */ - private string getAProcessChar() { result = any(string s | isReDoSCandidate(_, s)).charAt(_) } - } - - /** - * Holds if `term` may cause superlinear backtracking on strings containing many repetitions of `pump`. - * Gets the shortest string that causes superlinear backtracking. - */ - private predicate isReDoSAttackable(RegExpTerm term, string pump, State s) { - exists(int i, string c | s = Match(term, i) | - c = - min(string w | - isCandidate(s, w) and - SuffixConstruction::reachesOnlyRejectableSuffixes(s, w) - | - w order by w.length(), w - ) and - pump = escape(rotate(c, i)) - ) - } - - /** - * Holds if the state `s` (represented by the term `t`) can have backtracking with repetitions of `pump`. - * - * `prefixMsg` contains a friendly message for a prefix that reaches `s` (or `prefixMsg` is the empty string if the prefix is empty or if no prefix could be found). - */ - predicate hasReDoSResult(RegExpTerm t, string pump, State s, string prefixMsg) { - isReDoSAttackable(t, pump, s) and - ( - prefixMsg = "starting with '" + escape(Prefix::prefix(s)) + "' and " and - not Prefix::prefix(s) = "" - or - Prefix::prefix(s) = "" and prefixMsg = "" - or - not exists(Prefix::prefix(s)) and prefixMsg = "" - ) - } - - /** - * Gets the result of backslash-escaping newlines, carriage-returns and - * backslashes in `s`. - */ - bindingset[s] - private string escape(string s) { - result = - s.replaceAll("\\", "\\\\") - .replaceAll("\n", "\\n") - .replaceAll("\r", "\\r") - .replaceAll("\t", "\\t") - } - - /** - * Gets `str` with the last `i` characters moved to the front. - * - * We use this to adjust the pump string to match with the beginning of - * a RegExpTerm, so it doesn't start in the middle of a constant. - */ - bindingset[str, i] - private string rotate(string str, int i) { - result = str.suffix(str.length() - i) + str.prefix(str.length() - i) - } -} - -/** - * A module that describes a tree where each node has one or more associated characters, also known as a trie. - * The root node has no associated character. - * This module is a signature used in `Concretizer`. - */ -signature module CharTree { - /** A node in the tree. */ - class CharNode; - - /** Gets the previous node in the tree from `t`. */ - CharNode getPrev(CharNode t); - - /** - * Holds if `n` is at the end of a tree. I.e. a node that should have a result in the `Concretizer` module. - * Such a node can still have children. - */ - predicate isARelevantEnd(CharNode n); - - /** Gets a char associated with `t`. */ - string getChar(CharNode t); -} - -/** - * Implements an algorithm for computing all possible strings - * from following a tree of nodes (as described in `CharTree`). - * - * The string is build using one big concat, where all the chars are computed first. - * See `concretize`. - */ -module Concretizer { - private class Node = Impl::CharNode; - - private predicate getPrev = Impl::getPrev/1; - - private predicate isARelevantEnd = Impl::isARelevantEnd/1; - - private predicate getChar = Impl::getChar/1; - - /** Holds if `n` is on a path from the root to a leaf, and is therefore relevant for the results in `concretize`. */ - private predicate isRelevant(Node n) { - isARelevantEnd(n) - or - exists(Node succ | isRelevant(succ) | n = getPrev(succ)) - } - - /** Holds if `n` is a root with no predecessors. */ - private predicate isRoot(Node n) { not exists(getPrev(n)) } - - /** Gets the distance from a root to `n`. */ - private int nodeDepth(Node n) { - result = 0 and isRoot(n) - or - isRelevant(n) and - exists(Node prev | result = nodeDepth(prev) + 1 | prev = getPrev(n)) - } - - /** Gets an ancestor of `end`, where `end` is a node that should have a result in `concretize`. */ - private Node getAnAncestor(Node end) { isARelevantEnd(end) and result = getPrev*(end) } - - /** Gets the `i`th character on the path from the root to `n`. */ - pragma[noinline] - private string getPrefixChar(Node n, int i) { - exists(Node ancestor | - result = getChar(ancestor) and - ancestor = getAnAncestor(n) and - i = nodeDepth(ancestor) - ) - } - - /** Gets a string corresponding to `node`. */ - language[monotonicAggregates] - string concretize(Node n) { - result = strictconcat(int i | exists(getPrefixChar(n, i)) | getPrefixChar(n, i) order by i) - } -} +private import semmle.code.java.regex.RegexTreeView::RegexTreeView as TreeView +// NfaUtils should be used directly from the shared pack, and not from this file. +deprecated private import codeql.regex.nfa.NfaUtils::Make as Dep +import Dep diff --git a/java/ql/lib/semmle/code/java/security/regexp/NfaUtilsSpecific.qll b/java/ql/lib/semmle/code/java/security/regexp/NfaUtilsSpecific.qll deleted file mode 100644 index 742229eacca..00000000000 --- a/java/ql/lib/semmle/code/java/security/regexp/NfaUtilsSpecific.qll +++ /dev/null @@ -1,76 +0,0 @@ -/** - * This module should provide a class hierarchy corresponding to a parse tree of regular expressions. - * This is the interface to the shared ReDoS library. - */ - -private import java -import semmle.code.FileSystem -import semmle.code.java.regex.RegexTreeView - -/** - * Holds if `term` is an escape class representing e.g. `\d`. - * `clazz` is which character class it represents, e.g. "d" for `\d`. - */ -predicate isEscapeClass(RegExpTerm term, string clazz) { - term.(RegExpCharacterClassEscape).getValue() = clazz - or - term.(RegExpNamedProperty).getBackslashEquivalent() = clazz -} - -/** - * Holds if `term` is a possessive quantifier, e.g. `a*+`. - */ -predicate isPossessive(RegExpQuantifier term) { term.isPossessive() } - -/** - * Holds if the regex that `term` is part of is used in a way that ignores any leading prefix of the input it's matched against. - */ -predicate matchesAnyPrefix(RegExpTerm term) { not term.getRegex().matchesFullString() } - -/** - * Holds if the regex that `term` is part of is used in a way that ignores any trailing suffix of the input it's matched against. - */ -predicate matchesAnySuffix(RegExpTerm term) { not term.getRegex().matchesFullString() } - -/** - * Holds if the regular expression should not be considered. - * - * We make the pragmatic performance optimization to ignore regular expressions in files - * that do not belong to the project code (such as installed dependencies). - */ -predicate isExcluded(RegExpParent parent) { - not exists(parent.getRegex().getLocation().getFile().getRelativePath()) - or - // Regexes with many occurrences of ".*" may cause the polynomial ReDoS computation to explode, so - // we explicitly exclude these. - strictcount(int i | exists(parent.getRegex().getText().regexpFind("\\.\\*", i, _)) | i) > 10 -} - -/** - * A module containing predicates for determining which flags a regular expression have. - */ -module RegExpFlags { - /** - * Holds if `root` has the `i` flag for case-insensitive matching. - */ - predicate isIgnoreCase(RegExpTerm root) { - root.isRootTerm() and - root.getLiteral().isIgnoreCase() - } - - /** - * Gets the flags for `root`, or the empty string if `root` has no flags. - */ - deprecated string getFlags(RegExpTerm root) { - root.isRootTerm() and - result = root.getLiteral().getFlags() - } - - /** - * Holds if `root` has the `s` flag for multi-line matching. - */ - predicate isDotAll(RegExpTerm root) { - root.isRootTerm() and - root.getLiteral().isDotAll() - } -} diff --git a/java/ql/lib/semmle/code/java/security/regexp/PolynomialReDoSQuery.qll b/java/ql/lib/semmle/code/java/security/regexp/PolynomialReDoSQuery.qll index b0a8ff1a3c5..2a822ac69de 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/PolynomialReDoSQuery.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/PolynomialReDoSQuery.qll @@ -1,19 +1,19 @@ /** Definitions and configurations for the Polynomial ReDoS query */ -import semmle.code.java.security.regexp.SuperlinearBackTracking +private import semmle.code.java.regex.RegexTreeView::RegexTreeView as TreeView +import codeql.regex.nfa.SuperlinearBackTracking::Make as SuperlinearBackTracking import semmle.code.java.dataflow.DataFlow -import semmle.code.java.regex.RegexTreeView import semmle.code.java.regex.RegexFlowConfigs import semmle.code.java.dataflow.FlowSources /** A sink for polynomial redos queries, where a regex is matched. */ class PolynomialRedosSink extends DataFlow::Node { - RegExpLiteral reg; + TreeView::RegExpLiteral reg; PolynomialRedosSink() { regexMatchedAgainst(reg.getRegex(), this.asExpr()) } /** Gets the regex that is matched against this node. */ - RegExpTerm getRegExp() { result.getParent() = reg } + TreeView::RegExpTerm getRegExp() { result.getParent() = reg } } /** @@ -49,7 +49,8 @@ class PolynomialRedosConfig extends TaintTracking::Configuration { /** Holds if there is flow from `source` to `sink` that is matched against the regexp term `regexp` that is vulnerable to Polynomial ReDoS. */ predicate hasPolynomialReDoSResult( - DataFlow::PathNode source, DataFlow::PathNode sink, PolynomialBackTrackingTerm regexp + DataFlow::PathNode source, DataFlow::PathNode sink, + SuperlinearBackTracking::PolynomialBackTrackingTerm regexp ) { any(PolynomialRedosConfig config).hasFlowPath(source, sink) and regexp.getRootTerm() = sink.getNode().(PolynomialRedosSink).getRegExp() diff --git a/java/ql/lib/semmle/code/java/security/regexp/SuperlinearBackTracking.qll b/java/ql/lib/semmle/code/java/security/regexp/SuperlinearBackTracking.qll index 14a69dc0644..623b1540ef1 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/SuperlinearBackTracking.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/SuperlinearBackTracking.qll @@ -1,11 +1,4 @@ /** - * Provides classes for working with regular expressions that can - * perform backtracking in superlinear time. - */ - -import NfaUtils - -/* * This module implements the analysis described in the paper: * Valentin Wustholz, Oswaldo Olivo, Marijn J. H. Heule, and Isil Dillig: * Static Detection of DoS Vulnerabilities in @@ -42,377 +35,7 @@ import NfaUtils * It also doesn't find all transitions in the product automaton, which can cause false negatives. */ -/** - * Gets any root (start) state of a regular expression. - */ -private State getRootState() { result = mkMatch(any(RegExpRoot r)) } - -private newtype TStateTuple = - MkStateTuple(State q1, State q2, State q3) { - // starts at (pivot, pivot, succ) - isStartLoops(q1, q3) and q1 = q2 - or - step(_, _, _, _, q1, q2, q3) and FeasibleTuple::isFeasibleTuple(q1, q2, q3) - } - -/** - * A state in the product automaton. - * The product automaton contains 3-tuples of states. - * - * We lazily only construct those states that we are actually - * going to need. - * Either a start state `(pivot, pivot, succ)`, or a state - * where there exists a transition from an already existing state. - * - * The exponential variant of this query (`js/redos`) uses an optimization - * trick where `q1 <= q2`. This trick cannot be used here as the order - * of the elements matter. - */ -class StateTuple extends TStateTuple { - State q1; - State q2; - State q3; - - StateTuple() { this = MkStateTuple(q1, q2, q3) } - - /** - * Gest a string representation of this tuple. - */ - string toString() { result = "(" + q1 + ", " + q2 + ", " + q3 + ")" } - - /** - * Holds if this tuple is `(r1, r2, r3)`. - */ - pragma[noinline] - predicate isTuple(State r1, State r2, State r3) { r1 = q1 and r2 = q2 and r3 = q3 } -} - -/** - * A module for determining feasible tuples for the product automaton. - * - * The implementation is split into many predicates for performance reasons. - */ -private module FeasibleTuple { - /** - * Holds if the tuple `(r1, r2, r3)` might be on path from a start-state to an end-state in the product automaton. - */ - pragma[inline] - predicate isFeasibleTuple(State r1, State r2, State r3) { - // The first element is either inside a repetition (or the start state itself) - isRepetitionOrStart(r1) and - // The last element is inside a repetition - stateInsideRepetition(r3) and - // The states are reachable in the NFA in the order r1 -> r2 -> r3 - delta+(r1) = r2 and - delta+(r2) = r3 and - // The first element can reach a beginning (the "pivot" state in a `(pivot, succ)` pair). - canReachABeginning(r1) and - // The last element can reach a target (the "succ" state in a `(pivot, succ)` pair). - canReachATarget(r3) - } - - /** - * Holds if `s` is either inside a repetition, or is the start state (which is a repetition). - */ - pragma[noinline] - private predicate isRepetitionOrStart(State s) { stateInsideRepetition(s) or s = getRootState() } - - /** - * Holds if state `s` might be inside a backtracking repetition. - */ - pragma[noinline] - private predicate stateInsideRepetition(State s) { - s.getRepr().getParent*() instanceof InfiniteRepetitionQuantifier - } - - /** - * Holds if there exists a path in the NFA from `s` to a "pivot" state - * (from a `(pivot, succ)` pair that starts the search). - */ - pragma[noinline] - private predicate canReachABeginning(State s) { - delta+(s) = any(State pivot | isStartLoops(pivot, _)) - } - - /** - * Holds if there exists a path in the NFA from `s` to a "succ" state - * (from a `(pivot, succ)` pair that starts the search). - */ - pragma[noinline] - private predicate canReachATarget(State s) { delta+(s) = any(State succ | isStartLoops(_, succ)) } -} - -/** - * Holds if `pivot` and `succ` are a pair of loops that could be the beginning of a quadratic blowup. - * - * There is a slight implementation difference compared to the paper: this predicate requires that `pivot != succ`. - * The case where `pivot = succ` causes exponential backtracking and is handled by the `js/redos` query. - */ -predicate isStartLoops(State pivot, State succ) { - pivot != succ and - succ.getRepr() instanceof InfiniteRepetitionQuantifier and - delta+(pivot) = succ and - ( - pivot.getRepr() instanceof InfiniteRepetitionQuantifier - or - pivot = mkMatch(any(RegExpRoot root)) - ) -} - -/** - * Gets a state for which there exists a transition in the NFA from `s'. - */ -State delta(State s) { delta(s, _, result) } - -/** - * Holds if there are transitions from the components of `q` to the corresponding - * components of `r` labelled with `s1`, `s2`, and `s3`, respectively. - */ -pragma[noinline] -predicate step(StateTuple q, InputSymbol s1, InputSymbol s2, InputSymbol s3, StateTuple r) { - exists(State r1, State r2, State r3 | - step(q, s1, s2, s3, r1, r2, r3) and r = MkStateTuple(r1, r2, r3) - ) -} - -/** - * Holds if there are transitions from the components of `q` to `r1`, `r2`, and `r3 - * labelled with `s1`, `s2`, and `s3`, respectively. - */ -pragma[noopt] -predicate step( - StateTuple q, InputSymbol s1, InputSymbol s2, InputSymbol s3, State r1, State r2, State r3 -) { - exists(State q1, State q2, State q3 | q.isTuple(q1, q2, q3) | - deltaClosed(q1, s1, r1) and - deltaClosed(q2, s2, r2) and - deltaClosed(q3, s3, r3) and - // use noopt to force the join on `getAThreewayIntersect` to happen last. - exists(getAThreewayIntersect(s1, s2, s3)) - ) -} - -/** - * Gets a char that is matched by all the edges `s1`, `s2`, and `s3`. - * - * The result is not complete, and might miss some combination of edges that share some character. - */ -pragma[noinline] -string getAThreewayIntersect(InputSymbol s1, InputSymbol s2, InputSymbol s3) { - result = minAndMaxIntersect(s1, s2) and result = [intersect(s2, s3), intersect(s1, s3)] - or - result = minAndMaxIntersect(s1, s3) and result = [intersect(s2, s3), intersect(s1, s2)] - or - result = minAndMaxIntersect(s2, s3) and result = [intersect(s1, s2), intersect(s1, s3)] -} - -/** - * Gets the minimum and maximum characters that intersect between `a` and `b`. - * This predicate is used to limit the size of `getAThreewayIntersect`. - */ -pragma[noinline] -string minAndMaxIntersect(InputSymbol a, InputSymbol b) { - result = [min(intersect(a, b)), max(intersect(a, b))] -} - -private newtype TTrace = - Nil() or - Step(InputSymbol s1, InputSymbol s2, InputSymbol s3, TTrace t) { - isReachableFromStartTuple(_, _, t, s1, s2, s3, _, _) - } - -/** - * A list of tuples of input symbols that describe a path in the product automaton - * starting from some start state. - */ -class Trace extends TTrace { - /** - * Gets a string representation of this Trace that can be used for debug purposes. - */ - string toString() { - this = Nil() and result = "Nil()" - or - exists(InputSymbol s1, InputSymbol s2, InputSymbol s3, Trace t | this = Step(s1, s2, s3, t) | - result = "Step(" + s1 + ", " + s2 + ", " + s3 + ", " + t + ")" - ) - } -} - -/** - * Holds if there exists a transition from `r` to `q` in the product automaton. - * Notice that the arguments are flipped, and thus the direction is backwards. - */ -pragma[noinline] -predicate tupleDeltaBackwards(StateTuple q, StateTuple r) { step(r, _, _, _, q) } - -/** - * Holds if `tuple` is an end state in our search. - * That means there exists a pair of loops `(pivot, succ)` such that `tuple = (pivot, succ, succ)`. - */ -predicate isEndTuple(StateTuple tuple) { tuple = getAnEndTuple(_, _) } - -/** - * Gets the minimum length of a path from `r` to some an end state `end`. - * - * The implementation searches backwards from the end-tuple. - * This approach was chosen because it is way more efficient if the first predicate given to `shortestDistances` is small. - * The `end` argument must always be an end state. - */ -int distBackFromEnd(StateTuple r, StateTuple end) = - shortestDistances(isEndTuple/1, tupleDeltaBackwards/2)(end, r, result) - -/** - * Holds if there exists a pair of repetitions `(pivot, succ)` in the regular expression such that: - * `tuple` is reachable from `(pivot, pivot, succ)` in the product automaton, - * and there is a distance of `dist` from `tuple` to the nearest end-tuple `(pivot, succ, succ)`, - * and a path from a start-state to `tuple` follows the transitions in `trace`. - */ -private predicate isReachableFromStartTuple( - State pivot, State succ, StateTuple tuple, Trace trace, int dist -) { - exists(InputSymbol s1, InputSymbol s2, InputSymbol s3, Trace v | - isReachableFromStartTuple(pivot, succ, v, s1, s2, s3, tuple, dist) and - trace = Step(s1, s2, s3, v) - ) -} - -private predicate isReachableFromStartTuple( - State pivot, State succ, Trace trace, InputSymbol s1, InputSymbol s2, InputSymbol s3, - StateTuple tuple, int dist -) { - // base case. - exists(State q1, State q2, State q3 | - isStartLoops(pivot, succ) and - step(MkStateTuple(pivot, pivot, succ), s1, s2, s3, tuple) and - tuple = MkStateTuple(q1, q2, q3) and - trace = Nil() and - dist = distBackFromEnd(tuple, MkStateTuple(pivot, succ, succ)) - ) - or - // recursive case - exists(StateTuple p | - isReachableFromStartTuple(pivot, succ, p, trace, dist + 1) and - dist = distBackFromEnd(tuple, MkStateTuple(pivot, succ, succ)) and - step(p, s1, s2, s3, tuple) - ) -} - -/** - * Gets the tuple `(pivot, succ, succ)` from the product automaton. - */ -StateTuple getAnEndTuple(State pivot, State succ) { - isStartLoops(pivot, succ) and - result = MkStateTuple(pivot, succ, succ) -} - -/** An implementation of a chain containing chars for use by `Concretizer`. */ -private module CharTreeImpl implements CharTree { - class CharNode = Trace; - - CharNode getPrev(CharNode t) { t = Step(_, _, _, result) } - - /** Holds if `n` is used in `isPumpable`. */ - predicate isARelevantEnd(CharNode n) { - exists(State pivot, State succ | - isReachableFromStartTuple(pivot, succ, getAnEndTuple(pivot, succ), n, _) - ) - } - - string getChar(CharNode t) { - exists(InputSymbol s1, InputSymbol s2, InputSymbol s3 | t = Step(s1, s2, s3, _) | - result = getAThreewayIntersect(s1, s2, s3) - ) - } -} - -/** - * Holds if matching repetitions of `pump` can: - * 1) Transition from `pivot` back to `pivot`. - * 2) Transition from `pivot` to `succ`. - * 3) Transition from `succ` to `succ`. - * - * From theorem 3 in the paper linked in the top of this file we can therefore conclude that - * the regular expression has polynomial backtracking - if a rejecting suffix exists. - * - * This predicate is used by `SuperLinearReDoSConfiguration`, and the final results are - * available in the `hasReDoSResult` predicate. - */ -predicate isPumpable(State pivot, State succ, string pump) { - exists(StateTuple q, Trace t | - isReachableFromStartTuple(pivot, succ, q, t, _) and - q = getAnEndTuple(pivot, succ) and - pump = Concretizer::concretize(t) - ) -} - -/** - * Holds if states starting in `state` can have polynomial backtracking with the string `pump`. - */ -predicate isReDoSCandidate(State state, string pump) { isPumpable(_, state, pump) } - -/** - * Holds if repetitions of `pump` at `t` will cause polynomial backtracking. - */ -predicate polynomialReDoS(RegExpTerm t, string pump, string prefixMsg, RegExpTerm prev) { - exists(State s, State pivot | - ReDoSPruning::hasReDoSResult(t, pump, s, prefixMsg) and - isPumpable(pivot, s, _) and - prev = pivot.getRepr() - ) -} - -/** - * Gets a message for why `term` can cause polynomial backtracking. - */ -string getReasonString(RegExpTerm term, string pump, string prefixMsg, RegExpTerm prev) { - polynomialReDoS(term, pump, prefixMsg, prev) and - result = - "Strings " + prefixMsg + "with many repetitions of '" + pump + - "' can start matching anywhere after the start of the preceeding " + prev -} - -/** - * A term that may cause a regular expression engine to perform a - * polynomial number of match attempts, relative to the input length. - */ -class PolynomialBackTrackingTerm extends InfiniteRepetitionQuantifier { - string reason; - string pump; - string prefixMsg; - RegExpTerm prev; - - PolynomialBackTrackingTerm() { - reason = getReasonString(this, pump, prefixMsg, prev) and - // there might be many reasons for this term to have polynomial backtracking - we pick the shortest one. - reason = min(string msg | msg = getReasonString(this, _, _, _) | msg order by msg.length(), msg) - } - - /** - * Holds if all non-empty successors to the polynomial backtracking term matches the end of the line. - */ - predicate isAtEndLine() { - forall(RegExpTerm succ | this.getSuccessor+() = succ and not matchesEpsilon(succ) | - succ instanceof RegExpDollar - ) - } - - /** - * Gets the string that should be repeated to cause this regular expression to perform polynomially. - */ - string getPumpString() { result = pump } - - /** - * Gets a message for which prefix a matching string must start with for this term to cause polynomial backtracking. - */ - string getPrefixMessage() { result = prefixMsg } - - /** - * Gets a predecessor to `this`, which also loops on the pump string, and thereby causes polynomial backtracking. - */ - RegExpTerm getPreviousLoop() { result = prev } - - /** - * Gets the reason for the number of match attempts. - */ - string getReason() { result = reason } -} +private import semmle.code.java.regex.RegexTreeView::RegexTreeView as TreeView +// SuperlinearBackTracking should be used directly from the shared pack, and not from this file. +deprecated private import codeql.regex.nfa.SuperlinearBackTracking::Make as Dep +import Dep diff --git a/java/ql/src/Security/CWE/CWE-020/OverlyLargeRange.ql b/java/ql/src/Security/CWE/CWE-020/OverlyLargeRange.ql index d054659892c..b8ea3e52dbd 100644 --- a/java/ql/src/Security/CWE/CWE-020/OverlyLargeRange.ql +++ b/java/ql/src/Security/CWE/CWE-020/OverlyLargeRange.ql @@ -12,14 +12,15 @@ * external/cwe/cwe-020 */ -import semmle.code.java.security.OverlyLargeRangeQuery +private import semmle.code.java.regex.RegexTreeView::RegexTreeView as TreeView +import codeql.regex.OverlyLargeRangeQuery::Make -RegExpCharacterClass potentialMisparsedCharClass() { +TreeView::RegExpCharacterClass potentialMisparsedCharClass() { // nested char classes are currently misparsed - result.getAChild().(RegExpNormalChar).getValue() = "[" + result.getAChild().(TreeView::RegExpNormalChar).getValue() = "[" } -from RegExpCharacterRange range, string reason +from TreeView::RegExpCharacterRange range, string reason where problem(range, reason) and not range.getParent() = potentialMisparsedCharClass() diff --git a/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.ql b/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.ql index 75cd8335fac..a84f1c5213e 100644 --- a/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.ql +++ b/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.ql @@ -17,7 +17,9 @@ import java import semmle.code.java.security.regexp.PolynomialReDoSQuery import DataFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, PolynomialBackTrackingTerm regexp +from + DataFlow::PathNode source, DataFlow::PathNode sink, + SuperlinearBackTracking::PolynomialBackTrackingTerm regexp where hasPolynomialReDoSResult(source, sink, regexp) select sink, source, sink, "This $@ that depends on a $@ may run slow on strings " + regexp.getPrefixMessage() + diff --git a/java/ql/src/Security/CWE/CWE-730/ReDoS.ql b/java/ql/src/Security/CWE/CWE-730/ReDoS.ql index 23e258e8915..ca4750fc858 100644 --- a/java/ql/src/Security/CWE/CWE-730/ReDoS.ql +++ b/java/ql/src/Security/CWE/CWE-730/ReDoS.ql @@ -14,12 +14,12 @@ * external/cwe/cwe-400 */ -import java -import semmle.code.java.security.regexp.ExponentialBackTracking +private import semmle.code.java.regex.RegexTreeView::RegexTreeView as TreeView +import codeql.regex.nfa.ExponentialBackTracking::Make as ExponentialBackTracking -from RegExpTerm t, string pump, State s, string prefixMsg +from TreeView::RegExpTerm t, string pump, ExponentialBackTracking::State s, string prefixMsg where - hasReDoSResult(t, pump, s, prefixMsg) and + ExponentialBackTracking::hasReDoSResult(t, pump, s, prefixMsg) and // exclude verbose mode regexes for now not t.getRegex().getAMode() = "VERBOSE" select t, diff --git a/java/ql/test/library-tests/regex/parser/RegexParseTests.ql b/java/ql/test/library-tests/regex/parser/RegexParseTests.ql index 345031a3b2d..4c8d7519f14 100644 --- a/java/ql/test/library-tests/regex/parser/RegexParseTests.ql +++ b/java/ql/test/library-tests/regex/parser/RegexParseTests.ql @@ -1,10 +1,12 @@ import java -import semmle.code.java.regex.RegexTreeView -import semmle.code.java.regex.regex +import semmle.code.java.regex.RegexTreeView as RegexTreeView +import semmle.code.java.regex.regex as Regex -string getQLClases(RegExpTerm t) { result = "[" + strictconcat(t.getPrimaryQLClass(), ",") + "]" } +string getQLClases(RegexTreeView::RegExpTerm t) { + result = "[" + strictconcat(t.getPrimaryQLClass(), ",") + "]" +} -query predicate parseFailures(Regex r, int i) { r.failedToParse(i) } +query predicate parseFailures(Regex::Regex r, int i) { r.failedToParse(i) } -from RegExpTerm t +from RegexTreeView::RegExpTerm t select t, getQLClases(t) diff --git a/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.ql b/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.ql index bd600a6d8af..c8c1566a7a4 100644 --- a/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.ql +++ b/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.ql @@ -1,4 +1,3 @@ -import java import TestUtilities.InlineExpectationsTest import semmle.code.java.security.regexp.PolynomialReDoSQuery @@ -9,7 +8,10 @@ class HasPolyRedos extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasPolyRedos" and - exists(DataFlow::PathNode source, DataFlow::PathNode sink, PolynomialBackTrackingTerm regexp | + exists( + DataFlow::PathNode source, DataFlow::PathNode sink, + SuperlinearBackTracking::PolynomialBackTrackingTerm regexp + | hasPolynomialReDoSResult(source, sink, regexp) and location = sink.getNode().getLocation() and element = sink.getNode().toString() and diff --git a/java/ql/test/query-tests/security/CWE-730/ReDoS.ql b/java/ql/test/query-tests/security/CWE-730/ReDoS.ql index 288ca57f2e2..7226541bcb2 100644 --- a/java/ql/test/query-tests/security/CWE-730/ReDoS.ql +++ b/java/ql/test/query-tests/security/CWE-730/ReDoS.ql @@ -1,6 +1,7 @@ import java import TestUtilities.InlineExpectationsTest -import semmle.code.java.security.regexp.ExponentialBackTracking +private import semmle.code.java.regex.RegexTreeView::RegexTreeView as TreeView +import codeql.regex.nfa.ExponentialBackTracking::Make as ExponentialBackTracking import semmle.code.java.regex.regex class HasExpRedos extends InlineExpectationsTest { @@ -10,8 +11,8 @@ class HasExpRedos extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasExpRedos" and - exists(RegExpTerm t, string pump, State s, string prefixMsg | - hasReDoSResult(t, pump, s, prefixMsg) and + exists(TreeView::RegExpTerm t, string pump, ExponentialBackTracking::State s, string prefixMsg | + ExponentialBackTracking::hasReDoSResult(t, pump, s, prefixMsg) and not t.getRegex().getAMode() = "VERBOSE" and value = "" and location = t.getLocation() and From a4acea9adf9463cba31368a017aaf646fff16272 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 1 Nov 2022 12:20:15 +0100 Subject: [PATCH 169/796] add change-note --- java/ql/lib/change-notes/2022-10-31-shared-redos-pack.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2022-10-31-shared-redos-pack.md diff --git a/java/ql/lib/change-notes/2022-10-31-shared-redos-pack.md b/java/ql/lib/change-notes/2022-10-31-shared-redos-pack.md new file mode 100644 index 00000000000..405ddd1108c --- /dev/null +++ b/java/ql/lib/change-notes/2022-10-31-shared-redos-pack.md @@ -0,0 +1,4 @@ +--- + category: minorAnalysis +--- + * The ReDoS libraries in `semmle.code.java.security.regexp` has been moved to a shared pack inside the `shared/` folder, and the previous location has been deprecated. \ No newline at end of file From b59a9bc95cf7a2a81256248f406d642c0cc93238 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 7 Nov 2022 14:29:51 +0100 Subject: [PATCH 170/796] use instead of a fixed version number --- java/ql/lib/qlpack.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 32f1ef40ae8..4b103c629a2 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -6,4 +6,4 @@ extractor: java library: true upgrades: upgrades dependencies: - codeql/regex: 0.0.1 \ No newline at end of file + codeql/regex: ${workspace} \ No newline at end of file From 5bbdaad0e54c3706e50ac7c4c08d8d45f1bc2065 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Mon, 14 Nov 2022 16:50:39 -0500 Subject: [PATCH 171/796] C++: deprecate AST-based GVN --- cpp/ql/lib/change-notes/2022-11-14-deprecate-ast-gvn.md | 6 ++++++ .../code/cpp/valuenumbering/GlobalValueNumberingImpl.qll | 8 ++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 cpp/ql/lib/change-notes/2022-11-14-deprecate-ast-gvn.md diff --git a/cpp/ql/lib/change-notes/2022-11-14-deprecate-ast-gvn.md b/cpp/ql/lib/change-notes/2022-11-14-deprecate-ast-gvn.md new file mode 100644 index 00000000000..eb6bd755c2b --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-11-14-deprecate-ast-gvn.md @@ -0,0 +1,6 @@ +--- +category: deprecated +--- + + +* Deprecated `semmle.code.cpp.valuenumbering.GlobalValueNumberingImpl`. Use `semmle.code.cpp.valuenumbering.GlobalValueNumbering`, which exposes the same API. \ No newline at end of file diff --git a/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll b/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll index 7dd55dbfde3..10e3d3ba1c2 100644 --- a/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll @@ -1,4 +1,8 @@ /** + * DEPRECATED: This library has been replaced with a newer version which + * provides better performance and precision. Use + * `semmle.code.cpp.valuenumbering.GlobalValueNumbering` instead. + * * Provides an implementation of Global Value Numbering. * See https://en.wikipedia.org/wiki/Global_value_numbering * @@ -221,7 +225,7 @@ private newtype GvnBase = * expression with this `GVN` and using its `toString` and `getLocation` * methods. */ -class GVN extends GvnBase { +deprecated class GVN extends GvnBase { GVN() { this instanceof GvnBase } /** Gets an expression that has this GVN. */ @@ -503,7 +507,7 @@ private predicate mk_Deref(GVN p, ControlFlowNode dominator, PointerDereferenceE /** Gets the global value number of expression `e`. */ cached -GVN globalValueNumber(Expr e) { +deprecated GVN globalValueNumber(Expr e) { exists(int val, Type t | mk_IntConst(val, t, e) and result = GVN_IntConst(val, t) From 5ea03b1ded4380816c8d3396a652c36841e8a856 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Mon, 14 Nov 2022 22:56:06 +0100 Subject: [PATCH 172/796] Update Hapi.qll Add `server` definitions in plugin registration and plugin dependency declaration --- .../ql/lib/semmle/javascript/frameworks/Hapi.qll | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll index 4c7dd3e5a49..0d04aac34c6 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll @@ -14,16 +14,24 @@ module Hapi { // `server = new Hapi.Server()` this = DataFlow::moduleMember("hapi", "Server").getAnInstantiation() or - // server = Glue.compose(manifest, composeOptions) + // `server = Glue.compose(manifest, composeOptions)` this = DataFlow::moduleMember("@hapi/glue", "compose").getAnInvocation() or - // server inside a plugin - // TODO match `function (server, options)` + // `register (server, options)` exists(Function f | this.(DataFlow::ParameterNode).getParameter() = f.getParameter(0) and + f.getName() = "register" and f.getParameter(0).getName() = "server" and f.getParameter(1).getName() = "options" ) + or + // `const after = function (server) {...};` + // `server.dependency('name', after);` + exists(ServerDefinition server, DataFlow::MethodCallNode call | + call = server.ref().getAMethodCall() and + call.getMethodName() = "dependency" and + this = call.getArgument(1).(DataFlow::FunctionNode).getParameter(0) + ) } } @@ -261,7 +269,7 @@ module Hapi { RouteHandlerCandidate() { exists(string request, string responseToolkit | (request = "request" or request = "req") and - responseToolkit = "h" and + responseToolkit = ["h", "hapi"] and // heuristic: parameter names match the Hapi documentation astNode.getNumParameter() = 2 and astNode.getParameter(0).getName() = request and From 9d7e7735d566a1aa27e8f4f8be3f6cd56b5afb78 Mon Sep 17 00:00:00 2001 From: tiferet Date: Mon, 14 Nov 2022 14:33:08 -0800 Subject: [PATCH 173/796] Extract training data: Implement the new query that selects data for training. For now we include clauses that implement logic that is identical to the old queries. Include a temporary wrapper query that converts the resulting data into the format expected by the endpoint pipeline. Move the small pieces of `ExtractEndpointData` that are still needed into `ExtractEndpointDataTraining.qll`. --- .../EndpointCharacteristics.qll | 3 + .../extraction/ExtractEndpointDataTraining.ql | 21 +- .../ExtractEndpointDataTraining.qll | 239 ++++++++++++++++++ 3 files changed, 245 insertions(+), 18 deletions(-) create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index 33cd559503c..b20031bf228 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -45,6 +45,9 @@ abstract class EndpointCharacteristic extends string { EndpointType endpointClass, boolean isPositiveIndicator, float confidence ); + /** Indicators with confidence at or above this threshold are considered to be high-confidence indicators. */ + final float getHighConfidenceThreshold() { result = 0.8 } + // The following are some confidence values that are used in practice by the subclasses. They are defined as named // constants here to make it easier to change them in the future. final float maximalConfidence() { result = 1.0 } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.ql index 20ece497585..3b0bb468ffd 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.ql @@ -4,23 +4,8 @@ * Extracts training data we can use to train ML models for ML-powered queries. */ -import javascript -import ExtractEndpointData as ExtractEndpointData +private import ExtractEndpointDataTraining as ExtractEndpointDataTraining -query predicate endpoints( - DataFlow::Node endpoint, string queryName, string key, string value, string valueType -) { - ExtractEndpointData::endpoints(endpoint, queryName, key, value, valueType) and - // only select endpoints that are either Sink or NotASink - ExtractEndpointData::endpoints(endpoint, queryName, "sinkLabel", ["Sink", "NotASink"], "string") and - // do not select endpoints filtered out by end-to-end evaluation - ExtractEndpointData::endpoints(endpoint, queryName, "isExcludedFromEndToEndEvaluation", "false", - "boolean") and - // only select endpoints that can be part of a tainted flow - ExtractEndpointData::endpoints(endpoint, queryName, "isConstantExpression", "false", "boolean") -} +query predicate endpoints = ExtractEndpointDataTraining::reformattedTrainingEndpoints/5; -query predicate tokenFeatures(DataFlow::Node endpoint, string featureName, string featureValue) { - endpoints(endpoint, _, _, _, _) and - ExtractEndpointData::tokenFeatures(endpoint, featureName, featureValue) -} +query predicate tokenFeatures = ExtractEndpointDataTraining::tokenFeatures/3; diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll new file mode 100644 index 00000000000..00733c8abae --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll @@ -0,0 +1,239 @@ +/* + * For internal use only. + * + * Extracts training data we can use to train ML models for ML-powered queries. + */ + +import javascript +import experimental.adaptivethreatmodeling.EndpointCharacteristics +import experimental.adaptivethreatmodeling.EndpointFeatures as EndpointFeatures +import NoFeaturizationRestrictionsConfig +private import Exclusions as Exclusions +private import Queries +private import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm +private import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm +private import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm +private import experimental.adaptivethreatmodeling.XssATM as XssAtm + +/** + * Gets the set of featureName-featureValue pairs for each endpoint in the training set. + * + * `EndpointFeatures::tokenFeatures` has no results when `featureName` is absent for the endpoint + * `endpoint`. To preserve compatibility with the data pipeline, this relation will instead set + * `featureValue` to the empty string in this case. + */ +query predicate tokenFeatures(DataFlow::Node endpoint, string featureName, string featureValue) { + trainingEndpoints(endpoint, _, _) and + ( + EndpointFeatures::tokenFeatures(endpoint, featureName, featureValue) + or + // Performance note: this creates a Cartesian product between `endpoint` and `featureName`. + featureName = EndpointFeatures::getASupportedFeatureName() and + not exists(string value | EndpointFeatures::tokenFeatures(endpoint, featureName, value)) and + featureValue = "" + ) +} + +/** + * Holds if the given endpoint should be included in the training set as a sample belonging to endpointClass, and has + * the given characteristic. This query uses the endpoint characteristics to select and label endpoints for the training + * set, and provides a list of characteristics for each endpoint in the training set, which is used in the modeling + * code. + * + * Params: + * endpoint: The endpoint to include / exclude. + * endpointClass: The sink type. Each EndpointType has a predicate getEncoding, which specifies the classifier class + * for this sink type. Class 0 is the negative class (non-sink). Each positive int corresponds to a single sink type. + * This gives us the label for the endpoint in the training data. + * characteristic: Provides the list of characteristics that apply to the endpoint, which the modeling code currently + * uses for type balancing. + * + * Note: This predicate will produce multiple tuples for endpoints that have multiple characteristics, which we must + * then group together into a list of characteristics. + */ +query predicate trainingEndpoints( + DataFlow::Node endpoint, EndpointType endpointClass, EndpointCharacteristic characteristic +) { + characteristic.getEndpoints(endpoint) and + // Only consider the source code for the project being analyzed. + exists(endpoint.getFile().getRelativePath()) and + // Only select endpoints that can be part of a tainted flow: Constant expressions always evaluate to a constant + // primitive value. Therefore they can't ever appear in an alert, making them less interesting training examples. + // TODO: Experiment with removing this requirement. + not endpoint.asExpr() instanceof ConstantExpr and + // Do not select endpoints filtered out by end-to-end evaluation. + // TODO: Experiment with removing this requirement. + not Exclusions::isFileExcluded(endpoint.getFile()) and + // Filter out negative examples that also have a LikelyNotASinkReason, because this is currently done here + // https://github.com/github/codeql/blob/387e57546bf7352f7c1cfe781daa1a3799b7063e/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.qll#L77 + // TODO: Experiment with removing this requirement. + not ( + endpointClass instanceof NegativeType and + exists(EndpointCharacteristic c | + c.getEndpoints(endpoint) and + c instanceof LikelyNotASinkCharacteristic + ) + ) and + ( + // If the list of characteristics includes positive indicators with high confidence for this class, select this as a + // training sample belonging to the class. + exists(EndpointCharacteristic characteristic2, float confidence | + characteristic2.getEndpoints(endpoint) and + characteristic2.getImplications(endpointClass, true, confidence) and + confidence >= characteristic2.getHighConfidenceThreshold() + ) and + ( + // Temporarily limit this only to positive classes. For negative classes, additionally select only endpoints that + // have no high confidence indicators that they are sinks, because this is what was previously done. + // TODO: Experiment with removing this requirement, and instead ensuring that an endpoint never has both a high + // confidence indicator that it _is_ a sink and a high confidence indicator that it is _not_ a sink. + not endpointClass instanceof NegativeType + or + not exists(EndpointCharacteristic characteristic3, float confidence3, EndpointType posClass | + characteristic3.getEndpoints(endpoint) and + characteristic3.getImplications(posClass, true, confidence3) and + confidence3 >= characteristic3.getHighConfidenceThreshold() and + not posClass instanceof NegativeType + ) + ) + or + // If the list of characteristics includes negative indicators with high confidence for all classes other than 0, + // select this as a training sample of class 0 (this means we had query-specific characteristics to decide this + // endpoint isn’t a sink for each of our sink types). + endpointClass instanceof NegativeType and + forall(EndpointType otherClass | not otherClass instanceof NegativeType | + exists(EndpointCharacteristic characteristic2, float confidence | + characteristic2.getEndpoints(endpoint) and + characteristic2.getImplications(otherClass, false, confidence) and + confidence >= characteristic2.getHighConfidenceThreshold() + ) + ) + ) +} + +/** + * Temporary: + * Reformat the training data that was extracted with the new logic to match the format produced by the old predicate. + * This is the format expected by the endpoint pipeline. + */ +query predicate reformattedTrainingEndpoints( + DataFlow::Node endpoint, string queryName, string key, string value, string valueType +) { + trainingEndpoints(endpoint, _, _) and + exists(Query query | + queryName = query.getName() and + // For sinks, only list that sink type, but for non-sinks, list all sink types. + ( + exists(EndpointType endpointClass | + endpointClass.getDescription().matches(queryName + "%") and + not endpointClass instanceof NegativeType and + trainingEndpoints(endpoint, endpointClass, _) + ) + or + exists(EndpointType endpointClass | + endpointClass instanceof NegativeType and + trainingEndpoints(endpoint, endpointClass, _) + ) + ) and + ( + // NOTE: We don't use hasFlowFromSource in training, so we could just hardcode it to be false. + key = "hasFlowFromSource" and + ( + if FlowFromSource::hasFlowFromSource(endpoint, query) + then value = "true" + else value = "false" + ) and + valueType = "boolean" + or + // Constant expressions always evaluate to a constant primitive value. Therefore they can't ever + // appear in an alert, making them less interesting training examples. + key = "isConstantExpression" and + (if endpoint.asExpr() instanceof ConstantExpr then value = "true" else value = "false") and + valueType = "boolean" + or + // Holds if alerts involving the endpoint are excluded from the end-to-end evaluation. + key = "isExcludedFromEndToEndEvaluation" and + (if Exclusions::isFileExcluded(endpoint.getFile()) then value = "true" else value = "false") and + valueType = "boolean" + or + // The label for this query, considering the endpoint as a sink. + key = "sinkLabel" and + valueType = "string" and + value = "Sink" and + exists(EndpointType endpointClass | + endpointClass.getDescription().matches(queryName + "%") and + not endpointClass instanceof NegativeType and + trainingEndpoints(endpoint, endpointClass, _) + ) + or + key = "sinkLabel" and + valueType = "string" and + value = "NotASink" and + exists(EndpointType endpointClass | + endpointClass instanceof NegativeType and + trainingEndpoints(endpoint, endpointClass, _) + ) + or + // The reason, or reasons, why the endpoint was labeled NotASink for this query, only for negative examples. + key = "notASinkReason" and + exists(EndpointCharacteristic characteristic, EndpointType endpointClass | + characteristic.getEndpoints(endpoint) and + characteristic.getImplications(endpointClass, true, _) and + endpointClass instanceof NegativeType and + value = characteristic + ) and + // Don't include a notASinkReason for endpoints that are also known sinks. + not exists(EndpointCharacteristic characteristic3, float confidence3, EndpointType posClass | + characteristic3.getEndpoints(endpoint) and + characteristic3.getImplications(posClass, true, confidence3) and + confidence3 >= characteristic3.getHighConfidenceThreshold() and + not posClass instanceof NegativeType + ) and + valueType = "string" + ) + ) +} + +/** + * Gets the ATM data flow configuration for the specified query. + * TODO: Delete this once we are no longer surfacing `hasFlowFromSource`. + */ +DataFlow::Configuration getDataFlowCfg(Query query) { + query instanceof NosqlInjectionQuery and result instanceof NosqlInjectionAtm::Configuration + or + query instanceof SqlInjectionQuery and result instanceof SqlInjectionAtm::Configuration + or + query instanceof TaintedPathQuery and result instanceof TaintedPathAtm::Configuration + or + query instanceof XssQuery and result instanceof XssAtm::Configuration +} + +// TODO: Delete this once we are no longer surfacing `hasFlowFromSource`. +module FlowFromSource { + predicate hasFlowFromSource(DataFlow::Node endpoint, Query q) { + exists(Configuration cfg | cfg.getQuery() = q | cfg.hasFlow(_, endpoint)) + } + + /** + * A data flow configuration that replicates the data flow configuration for a specific query, but + * replaces the set of sinks with the set of endpoints we're extracting. + * + * We use this to find out when there is flow to a particular endpoint from a known source. + * + * This configuration behaves in a very similar way to the `ForwardExploringConfiguration` class + * from the CodeQL standard libraries for JavaScript. + */ + private class Configuration extends DataFlow::Configuration { + Query q; + + Configuration() { this = getDataFlowCfg(q) } + + Query getQuery() { result = q } + + /** Holds if `sink` is an endpoint we're extracting. */ + override predicate isSink(DataFlow::Node sink) { any() } + + /** Holds if `sink` is an endpoint we're extracting. */ + override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel lbl) { exists(lbl) } + } +} From b47723d6070abab1a8231e0517aba38ffd081c8a Mon Sep 17 00:00:00 2001 From: tiferet Date: Mon, 14 Nov 2022 14:57:59 -0800 Subject: [PATCH 174/796] Delete `ExtractEndpointData`. Also remove the associated test files. --- .../modelbuilding/DebugResultInclusion.ql | 4 +- .../extraction/ExtractEndpointData.ql | 11 - .../extraction/ExtractEndpointData.qll | 215 ------------------ .../ExtractEndpointData.qlref | 1 - .../ExtractEndpointData.qlref | 1 - 5 files changed, 2 insertions(+), 230 deletions(-) delete mode 100644 javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.ql delete mode 100644 javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.qll delete mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointData.qlref delete mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_unit_tests/ExtractEndpointData.qlref diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql index 28a95268a57..c5654e86a12 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql @@ -11,7 +11,7 @@ import javascript import experimental.adaptivethreatmodeling.ATMConfig -import extraction.ExtractEndpointData +import extraction.ExtractEndpointDataTraining string getAReasonSinkExcluded(DataFlow::Node sinkCandidate, Query query) { query instanceof NosqlInjectionQuery and @@ -33,7 +33,7 @@ string getDescriptionForAlertCandidate( ) { result = "excluded[reason=" + getAReasonSinkExcluded(sinkCandidate, query) + "]" or - getAtmCfg(query).isKnownSink(sinkCandidate) and + getDataFlowCfg(query).(AtmConfig).isKnownSink(sinkCandidate) and result = "excluded[reason=known-sink]" or not exists(getAReasonSinkExcluded(sinkCandidate, query)) and diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.ql deleted file mode 100644 index 73dab4af324..00000000000 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.ql +++ /dev/null @@ -1,11 +0,0 @@ -/* - * For internal use only. - * - * Extracts training and evaluation data we can use to train ML models for ML-powered queries. - */ - -import ExtractEndpointData as ExtractEndpointData - -query predicate endpoints = ExtractEndpointData::endpoints/5; - -query predicate tokenFeatures = ExtractEndpointData::tokenFeatures/3; diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.qll deleted file mode 100644 index af91933b7a4..00000000000 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.qll +++ /dev/null @@ -1,215 +0,0 @@ -/* - * For internal use only. - * - * Library code for training and evaluation data we can use to train ML models for ML-powered - * queries. - */ - -import javascript -import Exclusions as Exclusions -import evaluation.EndToEndEvaluation as EndToEndEvaluation -import experimental.adaptivethreatmodeling.ATMConfig -import experimental.adaptivethreatmodeling.CoreKnowledge as CoreKnowledge -import experimental.adaptivethreatmodeling.EndpointFeatures as EndpointFeatures -import experimental.adaptivethreatmodeling.EndpointScoring as EndpointScoring -import experimental.adaptivethreatmodeling.EndpointTypes -import experimental.adaptivethreatmodeling.FilteringReasons -import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm - -/** DEPRECATED: Alias for NosqlInjectionAtm */ -deprecated module NosqlInjectionATM = NosqlInjectionAtm; - -import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm - -/** DEPRECATED: Alias for SqlInjectionAtm */ -deprecated module SqlInjectionATM = SqlInjectionAtm; - -import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm - -/** DEPRECATED: Alias for TaintedPathAtm */ -deprecated module TaintedPathATM = TaintedPathAtm; - -import experimental.adaptivethreatmodeling.XssATM as XssAtm - -/** DEPRECATED: Alias for XssAtm */ -deprecated module XssATM = XssAtm; - -import Labels -import NoFeaturizationRestrictionsConfig -import Queries - -/** Gets the ATM configuration object for the specified query. */ -AtmConfig getAtmCfg(Query query) { - query instanceof NosqlInjectionQuery and - result instanceof NosqlInjectionAtm::NosqlInjectionAtmConfig - or - query instanceof SqlInjectionQuery and result instanceof SqlInjectionAtm::SqlInjectionAtmConfig - or - query instanceof TaintedPathQuery and result instanceof TaintedPathAtm::TaintedPathAtmConfig - or - query instanceof XssQuery and result instanceof XssAtm::DomBasedXssAtmConfig -} - -/** DEPRECATED: Alias for getAtmCfg */ -deprecated ATMConfig getATMCfg(Query query) { result = getAtmCfg(query) } - -/** Gets the ATM data flow configuration for the specified query. */ -DataFlow::Configuration getDataFlowCfg(Query query) { - query instanceof NosqlInjectionQuery and result instanceof NosqlInjectionAtm::Configuration - or - query instanceof SqlInjectionQuery and result instanceof SqlInjectionAtm::Configuration - or - query instanceof TaintedPathQuery and result instanceof TaintedPathAtm::Configuration - or - query instanceof XssQuery and result instanceof XssAtm::Configuration -} - -/** Gets a known sink for the specified query. */ -private DataFlow::Node getASink(Query query) { - getAtmCfg(query).isKnownSink(result) and - // Only consider the source code for the project being analyzed. - exists(result.getFile().getRelativePath()) -} - -/** Gets a data flow node that is known not to be a sink for the specified query. */ -private DataFlow::Node getANotASink(NotASinkReason reason) { - CoreKnowledge::isOtherModeledArgument(result, reason) and - // Some endpoints can be assigned both a `NotASinkReason` and a `LikelyNotASinkReason`. We - // consider these endpoints to be `LikelyNotASink`, therefore this line excludes them from the - // definition of `NotASink`. - not CoreKnowledge::isOtherModeledArgument(result, any(LikelyNotASinkReason t)) and - not result = getASink(_) and - // Only consider the source code for the project being analyzed. - exists(result.getFile().getRelativePath()) -} - -/** - * Gets a data flow node whose label is unknown for the specified query. - * - * In other words, this is an endpoint that is not `Sink`, `NotASink`, or `LikelyNotASink` for the - * specified query. - */ -private DataFlow::Node getAnUnknown(Query query) { - getAtmCfg(query).isEffectiveSink(result) and - // Effective sinks should exclude sinks but this is a defensive requirement - not result = getASink(query) and - // Effective sinks should exclude NotASink but for some queries (e.g. Xss) this is currently not always the case and - // so this is a defensive requirement - not result = getANotASink(_) and - // Only consider the source code for the project being analyzed. - exists(result.getFile().getRelativePath()) -} - -/** Gets the query-specific sink label for the given endpoint, if such a label exists. */ -private EndpointLabel getSinkLabelForEndpoint(DataFlow::Node endpoint, Query query) { - endpoint = getASink(query) and result instanceof SinkLabel - or - endpoint = getANotASink(_) and result instanceof NotASinkLabel - or - endpoint = getAnUnknown(query) and result instanceof UnknownLabel -} - -/** Gets an endpoint that should be extracted. */ -DataFlow::Node getAnEndpoint(Query query) { exists(getSinkLabelForEndpoint(result, query)) } - -/** - * Endpoints and associated metadata. - * - * Note that we draw a distinction between _features_, that are provided to the model at training - * and query time, and _metadata_, that is only provided to the model at training time. - * - * Internal: See the design document for - * [extensible extraction queries](https://docs.google.com/document/d/1g3ci2Nf1hGMG6ZUP0Y4PqCy_8elcoC_dhBvgTxdAWpg) - * for technical information about the design of this predicate. - */ -predicate endpoints( - DataFlow::Node endpoint, string queryName, string key, string value, string valueType -) { - exists(Query query | - // Only provide metadata for labelled endpoints, since we do not extract all endpoints. - endpoint = getAnEndpoint(query) and - queryName = query.getName() and - ( - // Holds if there is a taint flow path from a known source to the endpoint - key = "hasFlowFromSource" and - ( - if FlowFromSource::hasFlowFromSource(endpoint, query) - then value = "true" - else value = "false" - ) and - valueType = "boolean" - or - // Constant expressions always evaluate to a constant primitive value. Therefore they can't ever - // appear in an alert, making them less interesting training examples. - key = "isConstantExpression" and - (if endpoint.asExpr() instanceof ConstantExpr then value = "true" else value = "false") and - valueType = "boolean" - or - // Holds if alerts involving the endpoint are excluded from the end-to-end evaluation. - key = "isExcludedFromEndToEndEvaluation" and - (if Exclusions::isFileExcluded(endpoint.getFile()) then value = "true" else value = "false") and - valueType = "boolean" - or - // The label for this query, considering the endpoint as a sink. - key = "sinkLabel" and - value = getSinkLabelForEndpoint(endpoint, query).getEncoding() and - valueType = "string" - or - // The reason, or reasons, why the endpoint was labeled NotASink for this query. - key = "notASinkReason" and - exists(FilteringReason reason | - endpoint = getANotASink(reason) and - value = reason.getDescription() - ) and - valueType = "string" - ) - ) -} - -/** - * `EndpointFeatures::tokenFeatures` has no results when `featureName` is absent for the endpoint - * `endpoint`. To preserve compatibility with the data pipeline, this relation will instead set - * `featureValue` to the empty string in this case. - */ -predicate tokenFeatures(DataFlow::Node endpoint, string featureName, string featureValue) { - endpoints(endpoint, _, _, _, _) and - ( - EndpointFeatures::tokenFeatures(endpoint, featureName, featureValue) - or - // Performance note: this creates a Cartesian product between `endpoint` and `featureName`. - featureName = EndpointFeatures::getASupportedFeatureName() and - not exists(string value | EndpointFeatures::tokenFeatures(endpoint, featureName, value)) and - featureValue = "" - ) -} - -module FlowFromSource { - predicate hasFlowFromSource(DataFlow::Node endpoint, Query q) { - exists(Configuration cfg | cfg.getQuery() = q | cfg.hasFlow(_, endpoint)) - } - - /** - * A data flow configuration that replicates the data flow configuration for a specific query, but - * replaces the set of sinks with the set of endpoints we're extracting. - * - * We use this to find out when there is flow to a particular endpoint from a known source. - * - * This configuration behaves in a very similar way to the `ForwardExploringConfiguration` class - * from the CodeQL standard libraries for JavaScript. - */ - private class Configuration extends DataFlow::Configuration { - Query q; - - Configuration() { this = getDataFlowCfg(q) } - - Query getQuery() { result = q } - - /** Holds if `sink` is an endpoint we're extracting. */ - override predicate isSink(DataFlow::Node sink) { sink = getAnEndpoint(q) } - - /** Holds if `sink` is an endpoint we're extracting. */ - override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel lbl) { - sink = getAnEndpoint(q) and exists(lbl) - } - } -} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointData.qlref b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointData.qlref deleted file mode 100644 index b1e84d268d9..00000000000 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointData.qlref +++ /dev/null @@ -1 +0,0 @@ -extraction/ExtractEndpointData.ql diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_unit_tests/ExtractEndpointData.qlref b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_unit_tests/ExtractEndpointData.qlref deleted file mode 100644 index b1e84d268d9..00000000000 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_unit_tests/ExtractEndpointData.qlref +++ /dev/null @@ -1 +0,0 @@ -extraction/ExtractEndpointData.ql From 6b7612fed712f2b2f506113382e03af94bfe64f2 Mon Sep 17 00:00:00 2001 From: tiferet Date: Mon, 14 Nov 2022 15:33:46 -0800 Subject: [PATCH 175/796] Fix import errors in `DebugResultInclusion.ql` --- .../extraction/ExtractEndpointDataTraining.qll | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll index 00733c8abae..0eff964038d 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll @@ -9,11 +9,11 @@ import experimental.adaptivethreatmodeling.EndpointCharacteristics import experimental.adaptivethreatmodeling.EndpointFeatures as EndpointFeatures import NoFeaturizationRestrictionsConfig private import Exclusions as Exclusions -private import Queries -private import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm -private import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm -private import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm -private import experimental.adaptivethreatmodeling.XssATM as XssAtm +import Queries +import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm +import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm +import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm +import experimental.adaptivethreatmodeling.XssATM as XssAtm /** * Gets the set of featureName-featureValue pairs for each endpoint in the training set. From 9ecff0723cbd15b0198345015ef67b17ee091b1b Mon Sep 17 00:00:00 2001 From: tiferet Date: Mon, 14 Nov 2022 16:34:24 -0800 Subject: [PATCH 176/796] Fix non-ascii character in docs --- .../modelbuilding/extraction/ExtractEndpointDataTraining.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll index 0eff964038d..533f7bb2d9d 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll @@ -99,7 +99,7 @@ query predicate trainingEndpoints( or // If the list of characteristics includes negative indicators with high confidence for all classes other than 0, // select this as a training sample of class 0 (this means we had query-specific characteristics to decide this - // endpoint isn’t a sink for each of our sink types). + // endpoint isn't a sink for each of our sink types). endpointClass instanceof NegativeType and forall(EndpointType otherClass | not otherClass instanceof NegativeType | exists(EndpointCharacteristic characteristic2, float confidence | From eda028721e29eaefe31cd1c16fd678159e280315 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 15 Nov 2022 09:17:29 +0100 Subject: [PATCH 177/796] C#: Update all nuget packages --- .../Semmle.Autobuild.CSharp.Tests.csproj | 14 +++++++------- .../Semmle.Autobuild.CSharp.csproj | 12 ++++++------ .../Semmle.Autobuild.Shared.csproj | 6 +++--- .../Semmle.Extraction.CIL.csproj | 4 ++-- .../Semmle.Extraction.CSharp.Standalone.csproj | 16 ++++++++-------- .../Semmle.Extraction.CSharp.csproj | 12 ++++++------ .../Semmle.Extraction.Tests.csproj | 18 +++++++++--------- .../Semmle.Extraction/Semmle.Extraction.csproj | 4 ++-- .../Semmle.Util.Tests/Semmle.Util.Tests.csproj | 8 ++++---- .../posix-only/dotnet_test/dotnet_test.csproj | 8 ++++---- 10 files changed, 51 insertions(+), 51 deletions(-) diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj index a91868fbd80..1d5ac39a96f 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj @@ -6,17 +6,17 @@ enable - - - - + + + + all runtime; build; native; contentfiles; analyzers - + - - + + \ No newline at end of file diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj b/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj index 4f712a651d4..d05daec1de0 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj @@ -11,15 +11,15 @@ enable - + - - + + - - - + + + \ No newline at end of file diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj b/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj index d3e24dd6ad5..f76a28f6a0b 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj @@ -8,12 +8,12 @@ enable - + - + - + \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction.CIL/Semmle.Extraction.CIL.csproj b/csharp/extractor/Semmle.Extraction.CIL/Semmle.Extraction.CIL.csproj index 8dc6d8a9f76..2d9263eb24e 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Semmle.Extraction.CIL.csproj +++ b/csharp/extractor/Semmle.Extraction.CIL/Semmle.Extraction.CIL.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -24,7 +24,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj index 5546278e93c..c02999c9acd 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj @@ -12,17 +12,17 @@ enable - - + + - + - - - - - + + + + + \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj b/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj index 77e204997b3..02d1e96558d 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj +++ b/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj @@ -10,15 +10,15 @@ enable - - - + + + - + - - + + \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj b/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj index c4fa93f9697..e75d4c779ae 100644 --- a/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj +++ b/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj @@ -6,19 +6,19 @@ enable - - - - + + + + all runtime; build; native; contentfiles; analyzers - + - - - - + + + + \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj b/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj index f647003ebf0..b93f3a40043 100644 --- a/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj +++ b/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj @@ -12,13 +12,13 @@ TRACE;DEBUG;DEBUG_LABELS - + runtime; build; native; contentfiles; analyzers; buildtransitive all - + \ No newline at end of file diff --git a/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj b/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj index 7447a7e82c1..9edca915bd0 100644 --- a/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj +++ b/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj @@ -6,14 +6,14 @@ enable - - + + all runtime; build; native; contentfiles; analyzers - + - + \ No newline at end of file diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj b/csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj index 50852359bb8..a2fd6979adf 100644 --- a/csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj +++ b/csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj @@ -8,10 +8,10 @@ - - - - + + + + From 279ba60eb1cd9c928a45d204dcf8387223a47779 Mon Sep 17 00:00:00 2001 From: Gustav Munkby Date: Tue, 15 Nov 2022 10:00:53 +0100 Subject: [PATCH 178/796] Refactor package path extraction In preparation for pulling all package information at once. --- go/extractor/extractor.go | 34 ++++++++++++++-------------------- go/extractor/util/util.go | 15 +++++++++++++++ 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/go/extractor/extractor.go b/go/extractor/extractor.go index 1be2bfef224..82ed3be6f69 100644 --- a/go/extractor/extractor.go +++ b/go/extractor/extractor.go @@ -103,10 +103,8 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error { extractUniverseScope() log.Println("Done extracting universe scope.") - // a map of package path to package root directory (currently the module root or the source directory) - pkgRoots := make(map[string]string) - // a map of package path to source code directory - pkgDirs := make(map[string]string) + // a map of package path to source directory and module root directory + pkgInfos := make(map[string]util.PkgInfo) // root directories of packages that we want to extract wantedRoots := make(map[string]bool) @@ -116,16 +114,8 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error { }, func(pkg *packages.Package) { log.Printf("Processing package %s.", pkg.PkgPath) - if _, ok := pkgRoots[pkg.PkgPath]; !ok { - mdir := util.GetModDir(pkg.PkgPath, modFlags...) - pdir := util.GetPkgDir(pkg.PkgPath, modFlags...) - // GetModDir returns the empty string if the module directory cannot be determined, e.g. if the package - // is not using modules. If this is the case, fall back to the package directory - if mdir == "" { - mdir = pdir - } - pkgRoots[pkg.PkgPath] = mdir - pkgDirs[pkg.PkgPath] = pdir + if _, ok := pkgInfos[pkg.PkgPath]; !ok { + pkgInfos[pkg.PkgPath] = util.GetPkgInfo(pkg.PkgPath, modFlags...) } log.Printf("Extracting types for package %s.", pkg.PkgPath) @@ -152,11 +142,14 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error { }) for _, pkg := range pkgs { - if pkgRoots[pkg.PkgPath] == "" { + pkgInfo, ok := pkgInfos[pkg.PkgPath] + if !ok || pkgInfo.PkgDir == "" { log.Fatalf("Unable to get a source directory for input package %s.", pkg.PkgPath) } - wantedRoots[pkgRoots[pkg.PkgPath]] = true - wantedRoots[pkgDirs[pkg.PkgPath]] = true + wantedRoots[pkgInfo.PkgDir] = true + if pkgInfo.ModDir != "" { + wantedRoots[pkgInfo.ModDir] = true + } } log.Println("Done processing dependencies.") @@ -174,7 +167,8 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error { return true }, func(pkg *packages.Package) { for root, _ := range wantedRoots { - relDir, err := filepath.Rel(root, pkgDirs[pkg.PkgPath]) + pkgInfo := pkgInfos[pkg.PkgPath] + relDir, err := filepath.Rel(root, pkgInfo.PkgDir) if err != nil || noExtractRe.MatchString(relDir) { // if the path can't be made relative or matches the noExtract regexp skip it continue @@ -182,8 +176,8 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error { extraction.extractPackage(pkg) - if pkgRoots[pkg.PkgPath] != "" { - modPath := filepath.Join(pkgRoots[pkg.PkgPath], "go.mod") + if pkgInfo.ModDir != "" { + modPath := filepath.Join(pkgInfo.ModDir, "go.mod") if util.FileExists(modPath) { log.Printf("Extracting %s", modPath) start := time.Now() diff --git a/go/extractor/util/util.go b/go/extractor/util/util.go index 5725c03d5b6..31c202678f4 100644 --- a/go/extractor/util/util.go +++ b/go/extractor/util/util.go @@ -54,6 +54,21 @@ func runGoListWithEnv(format string, pkgpath string, additionalEnv []string, fla return strings.TrimSpace(string(out)), nil } +// PkgInfo holds package directory and module directory (if any) for a package +type PkgInfo struct { + PkgDir string // the directory directly containing source code of this package + ModDir string // the module directory containing this package, empty if not a module +} + +// GetPkgInfo fills the package info structure for the specified package path. +// It passes the `go list` the flags specified by `flags`. +func GetPkgInfo(pkgpath string, flags ...string) PkgInfo { + return PkgInfo{ + PkgDir: GetModDir(pkgpath, flags...), + ModDir: GetPkgDir(pkgpath, flags...), + } +} + // GetModDir gets the absolute directory of the module containing the package with path // `pkgpath`. It passes the `go list` the flags specified by `flags`. func GetModDir(pkgpath string, flags ...string) string { From ec3578364ebc92ff01a3b22baa43147b5fb037dd Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Tue, 15 Nov 2022 10:17:38 +0100 Subject: [PATCH 179/796] remove superfluous class in EndpointCharacteristics hierarchy --- .../EndpointCharacteristics.qll | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index 33cd559503c..e1539a504ec 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -135,20 +135,11 @@ private class NosqlInjectionSinkCharacteristic extends EndpointCharacteristic { * Characteristics that are indicative of not being a sink of any type. */ -/** - * A characteristic that is an indicator of not being a sink of any type, because it's an argument that has a manual - * model. - */ -abstract private class OtherModeledArgumentCharacteristic extends EndpointCharacteristic { - bindingset[this] - OtherModeledArgumentCharacteristic() { any() } -} - /** * A characteristic that is an indicator of not being a sink of any type, because it's an argument to a function of a * builtin object. */ -abstract private class ArgumentToBuiltinFunctionCharacteristic extends OtherModeledArgumentCharacteristic { +abstract private class ArgumentToBuiltinFunctionCharacteristic extends EndpointCharacteristic { bindingset[this] ArgumentToBuiltinFunctionCharacteristic() { any() } } @@ -156,7 +147,7 @@ abstract private class ArgumentToBuiltinFunctionCharacteristic extends OtherMode /** * A high-confidence characteristic that indicates that an endpoint is not a sink of any type. */ -abstract private class NotASinkCharacteristic extends OtherModeledArgumentCharacteristic { +abstract private class NotASinkCharacteristic extends EndpointCharacteristic { bindingset[this] NotASinkCharacteristic() { any() } @@ -175,7 +166,7 @@ abstract private class NotASinkCharacteristic extends OtherModeledArgumentCharac * TODO: This class is currently not private, because the current extraction logic explicitly avoids including these * endpoints in the training data. We might want to change this in the future. */ -abstract class LikelyNotASinkCharacteristic extends OtherModeledArgumentCharacteristic { +abstract class LikelyNotASinkCharacteristic extends EndpointCharacteristic { bindingset[this] LikelyNotASinkCharacteristic() { any() } From a293239bd5324ffd0892b53518e9d82c816fafee Mon Sep 17 00:00:00 2001 From: Gustav Munkby Date: Tue, 15 Nov 2022 10:30:56 +0100 Subject: [PATCH 180/796] Accelerating go-extractor by using 'go list -deps' Resurrect https://github.com/github/codeql-go/pull/554, but behind an environment variable as to avoid the broken builds noted in https://github.com/github/codeql/issues/9304, but still allowing some people to opt in to the much faster approach. --- go/extractor/extractor.go | 10 ++++++ go/extractor/util/util.go | 75 ++++++++++++++++++++++++++++++++++----- 2 files changed, 77 insertions(+), 8 deletions(-) diff --git a/go/extractor/extractor.go b/go/extractor/extractor.go index 82ed3be6f69..4d479f6384b 100644 --- a/go/extractor/extractor.go +++ b/go/extractor/extractor.go @@ -108,6 +108,16 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error { // root directories of packages that we want to extract wantedRoots := make(map[string]bool) + if os.Getenv("CODEQL_EXTRACTOR_GO_FAST_PACKAGE_INFO") != "" { + log.Printf("Running go list to resolve package and module directories.") + // get all packages information + pkgInfos, err = util.GetPkgsInfo(patterns, true, modFlags...) + if err != nil { + log.Fatalf("Error getting dependency package or module directories: %v.", err) + } + log.Printf("Done running go list deps: resolved %d packages.", len(pkgInfos)) + } + // Do a post-order traversal and extract the package scope of each package packages.Visit(pkgs, func(pkg *packages.Package) bool { return true diff --git a/go/extractor/util/util.go b/go/extractor/util/util.go index 31c202678f4..71ca932f366 100644 --- a/go/extractor/util/util.go +++ b/go/extractor/util/util.go @@ -1,7 +1,9 @@ package util import ( + "encoding/json" "errors" + "io" "log" "os" "os/exec" @@ -31,13 +33,13 @@ func Getenv(key string, aliases ...string) string { // runGoList is a helper function for running go list with format `format` and flags `flags` on // package `pkgpath`. -func runGoList(format string, pkgpath string, flags ...string) (string, error) { - return runGoListWithEnv(format, pkgpath, nil, flags...) +func runGoList(format string, patterns []string, flags ...string) (string, error) { + return runGoListWithEnv(format, patterns, nil, flags...) } -func runGoListWithEnv(format string, pkgpath string, additionalEnv []string, flags ...string) (string, error) { +func runGoListWithEnv(format string, patterns []string, additionalEnv []string, flags ...string) (string, error) { args := append([]string{"list", "-e", "-f", format}, flags...) - args = append(args, pkgpath) + args = append(args, patterns...) cmd := exec.Command("go", args...) cmd.Env = append(os.Environ(), additionalEnv...) out, err := cmd.Output() @@ -60,6 +62,63 @@ type PkgInfo struct { ModDir string // the module directory containing this package, empty if not a module } +// GetPkgsInfo gets the absolute module and package root directories for the packages matched by the +// patterns `patterns`. It passes to `go list` the flags specified by `flags`. If `includingDeps` +// is true, all dependencies will also be included. +func GetPkgsInfo(patterns []string, includingDeps bool, flags ...string) (map[string]PkgInfo, error) { + // enable module mode so that we can find a module root if it exists, even if go module support is + // disabled by a build + if includingDeps { + // the flag `-deps` causes all dependencies to be retrieved + flags = append(flags, "-deps") + } + + // using -json overrides -f format + output, err := runGoList("", patterns, append(flags, "-json")...) + if err != nil { + return nil, err + } + + // the output of `go list -json` is a stream of json object + type goListPkgInfo struct { + ImportPath string + Dir string + Module *struct { + Dir string + } + } + pkgInfoMapping := make(map[string]PkgInfo) + streamDecoder := json.NewDecoder(strings.NewReader(output)) + for { + var pkgInfo goListPkgInfo + decErr := streamDecoder.Decode(&pkgInfo) + if decErr == io.EOF { + break + } + if decErr != nil { + log.Printf("Error decoding output of go list -json: %s", err.Error()) + return nil, decErr + } + pkgAbsDir, err := filepath.Abs(pkgInfo.Dir) + if err != nil { + log.Printf("Unable to make package dir %s absolute: %s", pkgInfo.Dir, err.Error()) + } + var modAbsDir string + if pkgInfo.Module != nil { + modAbsDir, err = filepath.Abs(pkgInfo.Module.Dir) + if err != nil { + log.Printf("Unable to make module dir %s absolute: %s", pkgInfo.Module.Dir, err.Error()) + } + } + pkgInfoMapping[pkgInfo.ImportPath] = PkgInfo{ + PkgDir: pkgAbsDir, + ModDir: modAbsDir, + } + } + return pkgInfoMapping, nil +} + + // GetPkgInfo fills the package info structure for the specified package path. // It passes the `go list` the flags specified by `flags`. func GetPkgInfo(pkgpath string, flags ...string) PkgInfo { @@ -74,13 +133,13 @@ func GetPkgInfo(pkgpath string, flags ...string) PkgInfo { func GetModDir(pkgpath string, flags ...string) string { // enable module mode so that we can find a module root if it exists, even if go module support is // disabled by a build - mod, err := runGoListWithEnv("{{.Module}}", pkgpath, []string{"GO111MODULE=on"}, flags...) + mod, err := runGoListWithEnv("{{.Module}}", []string{pkgpath}, []string{"GO111MODULE=on"}, flags...) if err != nil || mod == "" { // if the command errors or modules aren't being used, return the empty string return "" } - modDir, err := runGoListWithEnv("{{.Module.Dir}}", pkgpath, []string{"GO111MODULE=on"}, flags...) + modDir, err := runGoListWithEnv("{{.Module.Dir}}", []string{pkgpath}, []string{"GO111MODULE=on"}, flags...) if err != nil { return "" } @@ -96,7 +155,7 @@ func GetModDir(pkgpath string, flags ...string) string { // GetPkgDir gets the absolute directory containing the package with path `pkgpath`. It passes the // `go list` command the flags specified by `flags`. func GetPkgDir(pkgpath string, flags ...string) string { - pkgDir, err := runGoList("{{.Dir}}", pkgpath, flags...) + pkgDir, err := runGoList("{{.Dir}}", []string{pkgpath}, flags...) if err != nil { return "" } @@ -112,7 +171,7 @@ func GetPkgDir(pkgpath string, flags ...string) string { // DepErrors checks there are any errors resolving dependencies for `pkgpath`. It passes the `go // list` command the flags specified by `flags`. func DepErrors(pkgpath string, flags ...string) bool { - out, err := runGoList("{{if .DepsErrors}}{{else}}error{{end}}", pkgpath, flags...) + out, err := runGoList("{{if .DepsErrors}}{{else}}error{{end}}", []string{pkgpath}, flags...) if err != nil { // if go list failed, assume dependencies are broken return false From 65c9d8cb78a284fbf6869ccaa764a765bb45a247 Mon Sep 17 00:00:00 2001 From: Gustav Munkby Date: Tue, 15 Nov 2022 10:38:06 +0100 Subject: [PATCH 181/796] Run go linux tests with fast package extraction To ensure this code path is actively tested. --- .github/workflows/go-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index 3cc61eafa5c..5ce27627e8a 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -51,7 +51,7 @@ jobs: - name: Test run: | cd go - make test + env CODEQL_EXTRACTOR_GO_FAST_PACKAGE_INFO=1 make test test-mac: name: Test MacOS From 7ca32ee2b57faec856bc5f9be44fbc1edaa78294 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 15 Nov 2022 11:11:36 +0100 Subject: [PATCH 182/796] Python: Fieldflow: merge assignment tests --- .../experimental/dataflow/fieldflow/test.py | 72 ++++++++----------- 1 file changed, 30 insertions(+), 42 deletions(-) diff --git a/python/ql/test/experimental/dataflow/fieldflow/test.py b/python/ql/test/experimental/dataflow/fieldflow/test.py index 70db8554241..f5b20daff96 100644 --- a/python/ql/test/experimental/dataflow/fieldflow/test.py +++ b/python/ql/test/experimental/dataflow/fieldflow/test.py @@ -39,33 +39,55 @@ class MyObj(object): self.foo = foo def setFoo(obj, x): - SINK_F(obj.foo) obj.foo = x -@expects(2) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) + +@expects(3) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) def test_indirect_assign(): - myobj = MyObj("OK") + myobj = MyObj(NONSOURCE) + SINK_F(myobj.foo) setFoo(myobj, SOURCE) SINK(myobj.foo) # $ flow="SOURCE, l:-1 -> myobj.foo" + setFoo(myobj, NONSOURCE) + SINK_F(myobj.foo) # $ SPURIOUS: flow="SOURCE, l:-4 -> myobj.foo" + +@expects(3) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) def test_indirect_assign_method(): - myobj = MyObj("OK") + myobj = MyObj(NONSOURCE) + SINK_F(myobj.foo) myobj.setFoo(SOURCE) SINK(myobj.foo) # $ flow="SOURCE, l:-1 -> myobj.foo" + myobj.setFoo(NONSOURCE) + SINK_F(myobj.foo) # $ SPURIOUS: flow="SOURCE, l:-4 -> myobj.foo" + +@expects(3) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) +def test_indirect_assign_bound_method(): + myobj = MyObj(NONSOURCE) + SINK_F(myobj.foo) + + sf = myobj.setFoo + + sf(SOURCE) + SINK(myobj.foo) # $ MISSING: flow="SOURCE, l:-1 -> myobj.foo" + + sf(NONSOURCE) + SINK_F(myobj.foo) + + +@expects(3) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) def test_direct_assign(): myobj = MyObj(NONSOURCE) + SINK_F(myobj.foo) + myobj.foo = SOURCE SINK(myobj.foo) # $ flow="SOURCE, l:-1 -> myobj.foo" - -def test_direct_assign_overwrite(): - myobj = MyObj(NONSOURCE) - myobj.foo = SOURCE myobj.foo = NONSOURCE SINK_F(myobj.foo) @@ -160,40 +182,6 @@ def test_nested_obj_method(): a.getObj().foo = x SINK(a.obj.foo) # $ flow="SOURCE, l:-3 -> a.obj.foo" -# ------------------------------------------------------------------------------ -# Bound Method calls -# ------------------------------------------------------------------------------ - -class Foo: - def __init__(self, x): - self.x = x - - def update_x(self, x): - self.x = x - -@expects(7) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) -def test_bound_method_call(): - # direct assignment - foo = Foo(None) - SINK_F(foo.x) - foo.x = SOURCE - SINK(foo.x) # $ flow="SOURCE, l:-1 -> foo.x" - foo.x = None - SINK_F(foo.x) - - # assignment through function - foo = Foo(SOURCE) - SINK(foo.x) # $ flow="SOURCE, l:-1 -> foo.x" - foo.update_x(None) - SINK_F(foo.x) # $ flow="SOURCE, l:-3 -> foo.x" - - # assignment through bound-method calls - foo = Foo(SOURCE) - ux = foo.update_x - SINK(foo.x) # $ flow="SOURCE, l:-2 -> foo.x" - ux(None) - SINK_F(foo.x) # $ SPURIOUS: flow="SOURCE, l:-4 -> foo.x" - # ------------------------------------------------------------------------------ # Crosstalk test -- using different function based on conditional From 98bf3adc7245d094a9d848276098f6cad6f53241 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Sun, 13 Nov 2022 20:35:23 +0100 Subject: [PATCH 183/796] Python: Add enclosing-callable test --- .../EnclosingCallable.expected | 24 +++++++++++++++++++ .../enclosing-callable/EnclosingCallable.ql | 6 +++++ .../enclosing-callable/class_example.py | 7 ++++++ .../dataflow/enclosing-callable/generator.py | 2 ++ 4 files changed, 39 insertions(+) create mode 100644 python/ql/test/experimental/dataflow/enclosing-callable/EnclosingCallable.expected create mode 100644 python/ql/test/experimental/dataflow/enclosing-callable/EnclosingCallable.ql create mode 100644 python/ql/test/experimental/dataflow/enclosing-callable/class_example.py create mode 100644 python/ql/test/experimental/dataflow/enclosing-callable/generator.py diff --git a/python/ql/test/experimental/dataflow/enclosing-callable/EnclosingCallable.expected b/python/ql/test/experimental/dataflow/enclosing-callable/EnclosingCallable.expected new file mode 100644 index 00000000000..a1e3de562f5 --- /dev/null +++ b/python/ql/test/experimental/dataflow/enclosing-callable/EnclosingCallable.expected @@ -0,0 +1,24 @@ +| file://:0:0:0:0 | Function generator_func | generator.py:1:20:1:21 | ControlFlowNode for xs | +| file://:0:0:0:0 | Function generator_func | generator.py:2:12:2:26 | ControlFlowNode for .0 | +| file://:0:0:0:0 | Function generator_func | generator.py:2:12:2:26 | ControlFlowNode for .0 | +| file://:0:0:0:0 | Function generator_func | generator.py:2:12:2:26 | ControlFlowNode for ListComp | +| file://:0:0:0:0 | Function generator_func | generator.py:2:13:2:13 | ControlFlowNode for Yield | +| file://:0:0:0:0 | Function generator_func | generator.py:2:13:2:13 | ControlFlowNode for x | +| file://:0:0:0:0 | Function generator_func | generator.py:2:19:2:19 | ControlFlowNode for x | +| file://:0:0:0:0 | Function generator_func | generator.py:2:24:2:25 | ControlFlowNode for xs | +| file://:0:0:0:0 | Module class_example | class_example.py:1:1:1:3 | ControlFlowNode for wat | +| file://:0:0:0:0 | Module class_example | class_example.py:1:7:1:7 | ControlFlowNode for IntegerLiteral | +| file://:0:0:0:0 | Module class_example | class_example.py:3:1:3:10 | ControlFlowNode for ClassExpr | +| file://:0:0:0:0 | Module class_example | class_example.py:3:7:3:9 | ControlFlowNode for Wat | +| file://:0:0:0:0 | Module class_example | class_example.py:4:5:4:7 | ControlFlowNode for wat | +| file://:0:0:0:0 | Module class_example | class_example.py:4:11:4:11 | ControlFlowNode for IntegerLiteral | +| file://:0:0:0:0 | Module class_example | class_example.py:5:5:5:9 | ControlFlowNode for print | +| file://:0:0:0:0 | Module class_example | class_example.py:5:5:5:26 | ControlFlowNode for print() | +| file://:0:0:0:0 | Module class_example | class_example.py:5:11:5:20 | ControlFlowNode for Str | +| file://:0:0:0:0 | Module class_example | class_example.py:5:23:5:25 | ControlFlowNode for wat | +| file://:0:0:0:0 | Module class_example | class_example.py:7:1:7:5 | ControlFlowNode for print | +| file://:0:0:0:0 | Module class_example | class_example.py:7:1:7:23 | ControlFlowNode for print() | +| file://:0:0:0:0 | Module class_example | class_example.py:7:7:7:17 | ControlFlowNode for Str | +| file://:0:0:0:0 | Module class_example | class_example.py:7:20:7:22 | ControlFlowNode for wat | +| file://:0:0:0:0 | Module generator | generator.py:1:1:1:23 | ControlFlowNode for FunctionExpr | +| file://:0:0:0:0 | Module generator | generator.py:1:5:1:18 | ControlFlowNode for generator_func | diff --git a/python/ql/test/experimental/dataflow/enclosing-callable/EnclosingCallable.ql b/python/ql/test/experimental/dataflow/enclosing-callable/EnclosingCallable.ql new file mode 100644 index 00000000000..1fa6a8ffc54 --- /dev/null +++ b/python/ql/test/experimental/dataflow/enclosing-callable/EnclosingCallable.ql @@ -0,0 +1,6 @@ +import python +import semmle.python.dataflow.new.DataFlow + +from DataFlow::CfgNode node +where exists(node.getLocation().getFile().getRelativePath()) +select node.getEnclosingCallable() as enclosingCallable, node diff --git a/python/ql/test/experimental/dataflow/enclosing-callable/class_example.py b/python/ql/test/experimental/dataflow/enclosing-callable/class_example.py new file mode 100644 index 00000000000..389b293d2bd --- /dev/null +++ b/python/ql/test/experimental/dataflow/enclosing-callable/class_example.py @@ -0,0 +1,7 @@ +wat = 1 + +class Wat: + wat = 2 + print("in class", wat) # prints 2 + +print("in module", wat) # prints 1 diff --git a/python/ql/test/experimental/dataflow/enclosing-callable/generator.py b/python/ql/test/experimental/dataflow/enclosing-callable/generator.py new file mode 100644 index 00000000000..56b6202abd7 --- /dev/null +++ b/python/ql/test/experimental/dataflow/enclosing-callable/generator.py @@ -0,0 +1,2 @@ +def generator_func(xs): + return [x for x in xs] From e886b53a947ddce06437dfa1ac06e3ba1250c2f2 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 15 Nov 2022 11:16:10 +0100 Subject: [PATCH 184/796] Python: CallGraph tests: remove rest of old annotations --- .../CallGraph/InlineCallGraphTest.expected | 10 +++++----- .../library-tests/CallGraph/code/class_simple.py | 8 -------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected index 975ac22dd2d..02d08ac4c81 100644 --- a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected +++ b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected @@ -3,11 +3,11 @@ debug_callableNotUnique | code/class_advanced.py:18:5:18:18 | Function arg | Qualified function name 'B.arg' is not unique. Please fix. | | code/class_advanced.py:23:5:23:25 | Function arg | Qualified function name 'B.arg' is not unique. Please fix. | pointsTo_found_typeTracker_notFound -| code/class_simple.py:28:1:28:15 | ControlFlowNode for Attribute() | A.some_method | -| code/class_simple.py:30:1:30:21 | ControlFlowNode for Attribute() | A.some_staticmethod | -| code/class_simple.py:32:1:32:20 | ControlFlowNode for Attribute() | A.some_classmethod | -| code/class_simple.py:35:1:35:21 | ControlFlowNode for Attribute() | A.some_staticmethod | -| code/class_simple.py:37:1:37:20 | ControlFlowNode for Attribute() | A.some_classmethod | +| code/class_simple.py:24:1:24:15 | ControlFlowNode for Attribute() | A.some_method | +| code/class_simple.py:25:1:25:21 | ControlFlowNode for Attribute() | A.some_staticmethod | +| code/class_simple.py:26:1:26:20 | ControlFlowNode for Attribute() | A.some_classmethod | +| code/class_simple.py:28:1:28:21 | ControlFlowNode for Attribute() | A.some_staticmethod | +| code/class_simple.py:29:1:29:20 | ControlFlowNode for Attribute() | A.some_classmethod | | code/runtime_decision.py:18:1:18:6 | ControlFlowNode for func() | rd_bar | | code/runtime_decision.py:18:1:18:6 | ControlFlowNode for func() | rd_foo | | code/runtime_decision.py:26:1:26:7 | ControlFlowNode for func2() | rd_bar | diff --git a/python/ql/test/experimental/library-tests/CallGraph/code/class_simple.py b/python/ql/test/experimental/library-tests/CallGraph/code/class_simple.py index a679cc5e25c..f201e648e3a 100644 --- a/python/ql/test/experimental/library-tests/CallGraph/code/class_simple.py +++ b/python/ql/test/experimental/library-tests/CallGraph/code/class_simple.py @@ -4,17 +4,14 @@ class A(object): print('A.__init__', arg) self.arg = arg - # name:A.some_method def some_method(self): print('A.some_method', self) @staticmethod - # name:A.some_staticmethod def some_staticmethod(): print('A.some_staticmethod') @classmethod - # name:A.some_classmethod def some_classmethod(cls): print('A.some_classmethod', cls) @@ -24,14 +21,9 @@ class A(object): # However, current test setup uses "callable" for naming, and expects things to be Function. a = A(42) -# calls:A.some_method a.some_method() # $ pt=A.some_method -# calls:A.some_staticmethod a.some_staticmethod() # $ pt=A.some_staticmethod -# calls:A.some_classmethod a.some_classmethod() # $ pt=A.some_classmethod -# calls:A.some_staticmethod A.some_staticmethod() # $ pt=A.some_staticmethod -# calls:A.some_classmethod A.some_classmethod() # $ pt=A.some_classmethod From a7492127075ec86a3ed3a2901eb13e95a9ab24a7 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 15 Nov 2022 11:22:19 +0100 Subject: [PATCH 185/796] C#: Handle `op_Checked*` operators in the extractor --- .../Semmle.Extraction.CSharp/Entities/UserOperator.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/UserOperator.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/UserOperator.cs index 11e54ddff35..9f0d3c8f4c5 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/UserOperator.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/UserOperator.cs @@ -2,6 +2,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using System.IO; using System.Linq; +using System.Text.RegularExpressions; namespace Semmle.Extraction.CSharp.Entities { @@ -161,6 +162,9 @@ namespace Semmle.Extraction.CSharp.Entities case "op_False": operatorName = "false"; break; + case var @checked when Regex.IsMatch(@checked, "^op_Checked.*"): + operatorName = @checked; + break; default: operatorName = methodName; success = false; From dc2cd994d4f2dfa2ad5bdd54a93cda7f2a6e9b10 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 15 Nov 2022 11:22:48 +0100 Subject: [PATCH 186/796] C#: Update expected test output --- .../library-tests/csharp9/PrintAst.expected | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/csharp/ql/test/library-tests/csharp9/PrintAst.expected b/csharp/ql/test/library-tests/csharp9/PrintAst.expected index 3c708935143..aeaea302fa3 100644 --- a/csharp/ql/test/library-tests/csharp9/PrintAst.expected +++ b/csharp/ql/test/library-tests/csharp9/PrintAst.expected @@ -5,7 +5,8 @@ AnonymousObjectCreation.cs: # 7| 1: [TypeMention] AnonObj # 7| 1: [AssignExpr] ... = ... # 7| 0: [FieldAccess] access to field l -# 7| 1: [ObjectCreation] object creation of type List +# 7| 1: [CastExpr] (...) ... +# 7| 1: [ObjectCreation] object creation of type List # 9| 6: [Property] Prop1 # 9| -1: [TypeMention] int # 9| 3: [Getter] get_Prop1 @@ -21,13 +22,15 @@ AnonymousObjectCreation.cs: # 13| 0: [ExprStmt] ...; # 13| 0: [MethodCall] call to method M1 # 13| -1: [ThisAccess] this access -# 13| 0: [ObjectCreation] object creation of type AnonObj -# 13| -1: [ObjectInitializer] { ..., ... } -# 13| 0: [MemberInitializer] ... = ... -# 13| 0: [PropertyCall] access to property Prop1 -# 13| 1: [IntLiteral] 1 +# 13| 0: [CastExpr] (...) ... +# 13| 1: [ObjectCreation] object creation of type AnonObj +# 13| -1: [ObjectInitializer] { ..., ... } +# 13| 0: [MemberInitializer] ... = ... +# 13| 0: [PropertyCall] access to property Prop1 +# 13| 1: [IntLiteral] 1 # 14| 1: [ReturnStmt] return ...; -# 14| 0: [ObjectCreation] object creation of type AnonObj +# 14| 0: [CastExpr] (...) ... +# 14| 1: [ObjectCreation] object creation of type AnonObj # 17| 8: [DelegateType] D #-----| 2: (Parameters) # 17| 0: [Parameter] x @@ -42,9 +45,10 @@ AnonymousObjectCreation.cs: # 21| -1: [TypeMention] D # 21| 4: [BlockStmt] {...} # 21| 0: [ReturnStmt] return ...; -# 21| 0: [ExplicitDelegateCreation] delegate creation of type D -# 21| 0: [ImplicitDelegateCreation] delegate creation of type D -# 21| 0: [MethodAccess] access to method M2 +# 21| 0: [CastExpr] (...) ... +# 21| 1: [ExplicitDelegateCreation] delegate creation of type D +# 21| 0: [ImplicitDelegateCreation] delegate creation of type D +# 21| 0: [MethodAccess] access to method M2 # 23| 11: [Method] MethodAdd # 23| -1: [TypeMention] Void # 24| 4: [BlockStmt] {...} @@ -53,7 +57,8 @@ AnonymousObjectCreation.cs: # 25| -1: [TypeMention] List # 25| 1: [TypeMention] int # 25| 0: [LocalVariableAccess] access to local variable list -# 25| 1: [ObjectCreation] object creation of type List +# 25| 1: [CastExpr] (...) ... +# 25| 1: [ObjectCreation] object creation of type List BinaryPattern.cs: # 3| [Class] BinaryPattern # 5| 5: [Property] P1 From 32f60fd11281fcbf943e920e40991aad43447127 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 14 Nov 2022 14:07:02 +0100 Subject: [PATCH 187/796] Ruby: Add more local flow tests for use-use flow --- .../dataflow/local/DataflowStep.expected | 109 ++++++++++++++++- .../dataflow/local/Nodes.expected | 60 +++++++++ .../dataflow/local/TaintStep.expected | 115 +++++++++++++++++- .../dataflow/local/local_dataflow.rb | 26 ++++ 4 files changed, 308 insertions(+), 2 deletions(-) diff --git a/ruby/ql/test/library-tests/dataflow/local/DataflowStep.expected b/ruby/ql/test/library-tests/dataflow/local/DataflowStep.expected index c6023a039d3..db3bc7b7296 100644 --- a/ruby/ql/test/library-tests/dataflow/local/DataflowStep.expected +++ b/ruby/ql/test/library-tests/dataflow/local/DataflowStep.expected @@ -1,6 +1,6 @@ | local_dataflow.rb:1:1:7:3 | self (foo) | local_dataflow.rb:3:8:3:10 | self | | local_dataflow.rb:1:1:7:3 | self in foo | local_dataflow.rb:1:1:7:3 | self (foo) | -| local_dataflow.rb:1:1:124:4 | self (local_dataflow.rb) | local_dataflow.rb:49:1:53:3 | self | +| local_dataflow.rb:1:1:150:3 | self (local_dataflow.rb) | local_dataflow.rb:49:1:53:3 | self | | local_dataflow.rb:1:9:1:9 | a | local_dataflow.rb:1:9:1:9 | a | | local_dataflow.rb:1:9:1:9 | a | local_dataflow.rb:2:7:2:7 | a | | local_dataflow.rb:2:3:2:7 | ... = ... | local_dataflow.rb:3:13:3:13 | b | @@ -279,3 +279,110 @@ | local_dataflow.rb:123:8:123:20 | call to dup | local_dataflow.rb:123:8:123:45 | call to tap | | local_dataflow.rb:123:8:123:45 | call to tap | local_dataflow.rb:123:8:123:49 | call to dup | | local_dataflow.rb:123:26:123:45 | self | local_dataflow.rb:123:32:123:43 | self | +| local_dataflow.rb:126:1:128:3 | self (use) | local_dataflow.rb:127:3:127:8 | self | +| local_dataflow.rb:126:1:128:3 | self in use | local_dataflow.rb:126:1:128:3 | self (use) | +| local_dataflow.rb:130:1:150:3 | self (use_use_madness) | local_dataflow.rb:132:6:132:11 | self | +| local_dataflow.rb:130:1:150:3 | self in use_use_madness | local_dataflow.rb:130:1:150:3 | self (use_use_madness) | +| local_dataflow.rb:131:3:131:8 | ... = ... | local_dataflow.rb:132:10:132:10 | x | +| local_dataflow.rb:131:7:131:8 | "" | local_dataflow.rb:131:3:131:8 | ... = ... | +| local_dataflow.rb:131:7:131:8 | "" | local_dataflow.rb:131:3:131:8 | ... = ... | +| local_dataflow.rb:132:6:132:11 | [post] self | local_dataflow.rb:133:8:133:13 | self | +| local_dataflow.rb:132:6:132:11 | self | local_dataflow.rb:133:8:133:13 | self | +| local_dataflow.rb:132:10:132:10 | x | local_dataflow.rb:133:12:133:12 | x | +| local_dataflow.rb:132:12:148:10 | then ... | local_dataflow.rb:132:3:149:5 | if ... | +| local_dataflow.rb:133:8:133:13 | [post] self | local_dataflow.rb:133:18:133:23 | self | +| local_dataflow.rb:133:8:133:13 | [post] self | local_dataflow.rb:134:7:134:12 | self | +| local_dataflow.rb:133:8:133:13 | call to use | local_dataflow.rb:133:8:133:23 | [false] ... \|\| ... | +| local_dataflow.rb:133:8:133:13 | call to use | local_dataflow.rb:133:8:133:23 | [true] ... \|\| ... | +| local_dataflow.rb:133:8:133:13 | self | local_dataflow.rb:133:18:133:23 | self | +| local_dataflow.rb:133:8:133:13 | self | local_dataflow.rb:134:7:134:12 | self | +| local_dataflow.rb:133:12:133:12 | x | local_dataflow.rb:133:22:133:22 | x | +| local_dataflow.rb:133:12:133:12 | x | local_dataflow.rb:134:11:134:11 | x | +| local_dataflow.rb:133:18:133:23 | [post] self | local_dataflow.rb:134:7:134:12 | self | +| local_dataflow.rb:133:18:133:23 | [post] self | local_dataflow.rb:136:7:136:12 | self | +| local_dataflow.rb:133:18:133:23 | call to use | local_dataflow.rb:133:8:133:23 | [false] ... \|\| ... | +| local_dataflow.rb:133:18:133:23 | call to use | local_dataflow.rb:133:8:133:23 | [true] ... \|\| ... | +| local_dataflow.rb:133:18:133:23 | self | local_dataflow.rb:134:7:134:12 | self | +| local_dataflow.rb:133:18:133:23 | self | local_dataflow.rb:136:7:136:12 | self | +| local_dataflow.rb:133:22:133:22 | x | local_dataflow.rb:134:11:134:11 | x | +| local_dataflow.rb:133:22:133:22 | x | local_dataflow.rb:136:11:136:11 | x | +| local_dataflow.rb:133:24:134:12 | then ... | local_dataflow.rb:133:5:139:7 | if ... | +| local_dataflow.rb:134:7:134:12 | [post] self | local_dataflow.rb:141:9:141:14 | self | +| local_dataflow.rb:134:7:134:12 | call to use | local_dataflow.rb:133:24:134:12 | then ... | +| local_dataflow.rb:134:7:134:12 | self | local_dataflow.rb:141:9:141:14 | self | +| local_dataflow.rb:134:11:134:11 | x | local_dataflow.rb:141:13:141:13 | x | +| local_dataflow.rb:135:5:138:9 | else ... | local_dataflow.rb:133:5:139:7 | if ... | +| local_dataflow.rb:136:7:136:12 | [post] self | local_dataflow.rb:137:10:137:15 | self | +| local_dataflow.rb:136:7:136:12 | self | local_dataflow.rb:137:10:137:15 | self | +| local_dataflow.rb:136:11:136:11 | x | local_dataflow.rb:137:14:137:14 | x | +| local_dataflow.rb:137:7:138:9 | if ... | local_dataflow.rb:135:5:138:9 | else ... | +| local_dataflow.rb:137:10:137:15 | [post] self | local_dataflow.rb:137:21:137:26 | self | +| local_dataflow.rb:137:10:137:15 | [post] self | local_dataflow.rb:141:9:141:14 | self | +| local_dataflow.rb:137:10:137:15 | call to use | local_dataflow.rb:137:10:137:26 | [false] ... && ... | +| local_dataflow.rb:137:10:137:15 | call to use | local_dataflow.rb:137:10:137:26 | [true] ... && ... | +| local_dataflow.rb:137:10:137:15 | self | local_dataflow.rb:137:21:137:26 | self | +| local_dataflow.rb:137:10:137:15 | self | local_dataflow.rb:141:9:141:14 | self | +| local_dataflow.rb:137:14:137:14 | x | local_dataflow.rb:137:25:137:25 | x | +| local_dataflow.rb:137:14:137:14 | x | local_dataflow.rb:141:13:141:13 | x | +| local_dataflow.rb:137:20:137:26 | [false] ! ... | local_dataflow.rb:137:10:137:26 | [false] ... && ... | +| local_dataflow.rb:137:20:137:26 | [true] ! ... | local_dataflow.rb:137:10:137:26 | [true] ... && ... | +| local_dataflow.rb:137:21:137:26 | [post] self | local_dataflow.rb:141:9:141:14 | self | +| local_dataflow.rb:137:21:137:26 | self | local_dataflow.rb:141:9:141:14 | self | +| local_dataflow.rb:137:25:137:25 | x | local_dataflow.rb:141:13:141:13 | x | +| local_dataflow.rb:141:8:141:14 | [false] ! ... | local_dataflow.rb:141:8:141:37 | [false] ... \|\| ... | +| local_dataflow.rb:141:8:141:14 | [false] ! ... | local_dataflow.rb:141:8:141:37 | [true] ... \|\| ... | +| local_dataflow.rb:141:8:141:14 | [true] ! ... | local_dataflow.rb:141:8:141:37 | [true] ... \|\| ... | +| local_dataflow.rb:141:9:141:14 | [post] self | local_dataflow.rb:141:20:141:25 | self | +| local_dataflow.rb:141:9:141:14 | [post] self | local_dataflow.rb:147:5:147:10 | self | +| local_dataflow.rb:141:9:141:14 | self | local_dataflow.rb:141:20:141:25 | self | +| local_dataflow.rb:141:9:141:14 | self | local_dataflow.rb:147:5:147:10 | self | +| local_dataflow.rb:141:13:141:13 | x | local_dataflow.rb:141:24:141:24 | x | +| local_dataflow.rb:141:13:141:13 | x | local_dataflow.rb:147:9:147:9 | x | +| local_dataflow.rb:141:19:141:37 | [false] ( ... ) | local_dataflow.rb:141:8:141:37 | [false] ... \|\| ... | +| local_dataflow.rb:141:19:141:37 | [true] ( ... ) | local_dataflow.rb:141:8:141:37 | [true] ... \|\| ... | +| local_dataflow.rb:141:20:141:25 | [post] self | local_dataflow.rb:141:31:141:36 | self | +| local_dataflow.rb:141:20:141:25 | [post] self | local_dataflow.rb:143:11:143:16 | self | +| local_dataflow.rb:141:20:141:25 | call to use | local_dataflow.rb:141:20:141:36 | [false] ... && ... | +| local_dataflow.rb:141:20:141:25 | call to use | local_dataflow.rb:141:20:141:36 | [true] ... && ... | +| local_dataflow.rb:141:20:141:25 | self | local_dataflow.rb:141:31:141:36 | self | +| local_dataflow.rb:141:20:141:25 | self | local_dataflow.rb:143:11:143:16 | self | +| local_dataflow.rb:141:20:141:36 | [false] ... && ... | local_dataflow.rb:141:19:141:37 | [false] ( ... ) | +| local_dataflow.rb:141:20:141:36 | [true] ... && ... | local_dataflow.rb:141:19:141:37 | [true] ( ... ) | +| local_dataflow.rb:141:24:141:24 | x | local_dataflow.rb:141:35:141:35 | x | +| local_dataflow.rb:141:24:141:24 | x | local_dataflow.rb:143:15:143:15 | x | +| local_dataflow.rb:141:30:141:36 | [false] ! ... | local_dataflow.rb:141:20:141:36 | [false] ... && ... | +| local_dataflow.rb:141:30:141:36 | [true] ! ... | local_dataflow.rb:141:20:141:36 | [true] ... && ... | +| local_dataflow.rb:141:31:141:36 | [post] self | local_dataflow.rb:143:11:143:16 | self | +| local_dataflow.rb:141:31:141:36 | [post] self | local_dataflow.rb:147:5:147:10 | self | +| local_dataflow.rb:141:31:141:36 | self | local_dataflow.rb:143:11:143:16 | self | +| local_dataflow.rb:141:31:141:36 | self | local_dataflow.rb:147:5:147:10 | self | +| local_dataflow.rb:141:35:141:35 | x | local_dataflow.rb:143:15:143:15 | x | +| local_dataflow.rb:141:35:141:35 | x | local_dataflow.rb:147:9:147:9 | x | +| local_dataflow.rb:141:38:142:9 | then ... | local_dataflow.rb:141:5:145:7 | if ... | +| local_dataflow.rb:142:7:142:9 | nil | local_dataflow.rb:141:38:142:9 | then ... | +| local_dataflow.rb:143:5:144:16 | elsif ... | local_dataflow.rb:141:5:145:7 | if ... | +| local_dataflow.rb:143:11:143:16 | [post] self | local_dataflow.rb:143:21:143:26 | self | +| local_dataflow.rb:143:11:143:16 | [post] self | local_dataflow.rb:144:11:144:16 | self | +| local_dataflow.rb:143:11:143:16 | call to use | local_dataflow.rb:143:11:143:26 | [false] ... \|\| ... | +| local_dataflow.rb:143:11:143:16 | call to use | local_dataflow.rb:143:11:143:26 | [true] ... \|\| ... | +| local_dataflow.rb:143:11:143:16 | self | local_dataflow.rb:143:21:143:26 | self | +| local_dataflow.rb:143:11:143:16 | self | local_dataflow.rb:144:11:144:16 | self | +| local_dataflow.rb:143:15:143:15 | x | local_dataflow.rb:143:25:143:25 | x | +| local_dataflow.rb:143:15:143:15 | x | local_dataflow.rb:144:15:144:15 | x | +| local_dataflow.rb:143:21:143:26 | [post] self | local_dataflow.rb:144:11:144:16 | self | +| local_dataflow.rb:143:21:143:26 | [post] self | local_dataflow.rb:147:5:147:10 | self | +| local_dataflow.rb:143:21:143:26 | call to use | local_dataflow.rb:143:11:143:26 | [false] ... \|\| ... | +| local_dataflow.rb:143:21:143:26 | call to use | local_dataflow.rb:143:11:143:26 | [true] ... \|\| ... | +| local_dataflow.rb:143:21:143:26 | self | local_dataflow.rb:144:11:144:16 | self | +| local_dataflow.rb:143:21:143:26 | self | local_dataflow.rb:147:5:147:10 | self | +| local_dataflow.rb:143:25:143:25 | x | local_dataflow.rb:144:15:144:15 | x | +| local_dataflow.rb:143:25:143:25 | x | local_dataflow.rb:147:9:147:9 | x | +| local_dataflow.rb:143:27:144:16 | then ... | local_dataflow.rb:143:5:144:16 | elsif ... | +| local_dataflow.rb:144:11:144:16 | [post] self | local_dataflow.rb:147:5:147:10 | self | +| local_dataflow.rb:144:11:144:16 | call to use | local_dataflow.rb:143:27:144:16 | then ... | +| local_dataflow.rb:144:11:144:16 | self | local_dataflow.rb:147:5:147:10 | self | +| local_dataflow.rb:144:15:144:15 | x | local_dataflow.rb:147:9:147:9 | x | +| local_dataflow.rb:147:5:147:10 | [post] self | local_dataflow.rb:148:5:148:10 | self | +| local_dataflow.rb:147:5:147:10 | self | local_dataflow.rb:148:5:148:10 | self | +| local_dataflow.rb:147:9:147:9 | x | local_dataflow.rb:148:9:148:9 | x | +| local_dataflow.rb:148:5:148:10 | call to use | local_dataflow.rb:132:12:148:10 | then ... | diff --git a/ruby/ql/test/library-tests/dataflow/local/Nodes.expected b/ruby/ql/test/library-tests/dataflow/local/Nodes.expected index 353d1f0d2d6..fcb55f6ada7 100644 --- a/ruby/ql/test/library-tests/dataflow/local/Nodes.expected +++ b/ruby/ql/test/library-tests/dataflow/local/Nodes.expected @@ -19,6 +19,8 @@ ret | local_dataflow.rb:119:3:119:31 | call to sink | | local_dataflow.rb:123:3:123:50 | call to sink | | local_dataflow.rb:123:32:123:43 | call to puts | +| local_dataflow.rb:127:3:127:8 | call to rand | +| local_dataflow.rb:132:3:149:5 | if ... | arg | local_dataflow.rb:3:8:3:10 | self | local_dataflow.rb:3:8:3:10 | call to p | self | | local_dataflow.rb:3:10:3:10 | a | local_dataflow.rb:3:8:3:10 | call to p | position 0 | @@ -170,3 +172,61 @@ arg | local_dataflow.rb:123:26:123:45 | { ... } | local_dataflow.rb:123:8:123:45 | call to tap | block | | local_dataflow.rb:123:32:123:43 | self | local_dataflow.rb:123:32:123:43 | call to puts | self | | local_dataflow.rb:123:37:123:43 | "hello" | local_dataflow.rb:123:32:123:43 | call to puts | position 0 | +| local_dataflow.rb:127:3:127:8 | self | local_dataflow.rb:127:3:127:8 | call to rand | self | +| local_dataflow.rb:132:6:132:11 | self | local_dataflow.rb:132:6:132:11 | call to use | self | +| local_dataflow.rb:132:10:132:10 | x | local_dataflow.rb:132:6:132:11 | call to use | position 0 | +| local_dataflow.rb:133:8:133:13 | call to use | local_dataflow.rb:133:8:133:23 | [false] ... \|\| ... | self | +| local_dataflow.rb:133:8:133:13 | call to use | local_dataflow.rb:133:8:133:23 | [true] ... \|\| ... | self | +| local_dataflow.rb:133:8:133:13 | self | local_dataflow.rb:133:8:133:13 | call to use | self | +| local_dataflow.rb:133:12:133:12 | x | local_dataflow.rb:133:8:133:13 | call to use | position 0 | +| local_dataflow.rb:133:18:133:23 | call to use | local_dataflow.rb:133:8:133:23 | [false] ... \|\| ... | position 0 | +| local_dataflow.rb:133:18:133:23 | call to use | local_dataflow.rb:133:8:133:23 | [true] ... \|\| ... | position 0 | +| local_dataflow.rb:133:18:133:23 | self | local_dataflow.rb:133:18:133:23 | call to use | self | +| local_dataflow.rb:133:22:133:22 | x | local_dataflow.rb:133:18:133:23 | call to use | position 0 | +| local_dataflow.rb:134:7:134:12 | self | local_dataflow.rb:134:7:134:12 | call to use | self | +| local_dataflow.rb:134:11:134:11 | x | local_dataflow.rb:134:7:134:12 | call to use | position 0 | +| local_dataflow.rb:136:7:136:12 | self | local_dataflow.rb:136:7:136:12 | call to use | self | +| local_dataflow.rb:136:11:136:11 | x | local_dataflow.rb:136:7:136:12 | call to use | position 0 | +| local_dataflow.rb:137:10:137:15 | call to use | local_dataflow.rb:137:10:137:26 | [false] ... && ... | self | +| local_dataflow.rb:137:10:137:15 | call to use | local_dataflow.rb:137:10:137:26 | [true] ... && ... | self | +| local_dataflow.rb:137:10:137:15 | self | local_dataflow.rb:137:10:137:15 | call to use | self | +| local_dataflow.rb:137:14:137:14 | x | local_dataflow.rb:137:10:137:15 | call to use | position 0 | +| local_dataflow.rb:137:20:137:26 | [false] ! ... | local_dataflow.rb:137:10:137:26 | [false] ... && ... | position 0 | +| local_dataflow.rb:137:20:137:26 | [true] ! ... | local_dataflow.rb:137:10:137:26 | [true] ... && ... | position 0 | +| local_dataflow.rb:137:21:137:26 | call to use | local_dataflow.rb:137:20:137:26 | [false] ! ... | self | +| local_dataflow.rb:137:21:137:26 | call to use | local_dataflow.rb:137:20:137:26 | [true] ! ... | self | +| local_dataflow.rb:137:21:137:26 | self | local_dataflow.rb:137:21:137:26 | call to use | self | +| local_dataflow.rb:137:25:137:25 | x | local_dataflow.rb:137:21:137:26 | call to use | position 0 | +| local_dataflow.rb:141:8:141:14 | [false] ! ... | local_dataflow.rb:141:8:141:37 | [false] ... \|\| ... | self | +| local_dataflow.rb:141:8:141:14 | [false] ! ... | local_dataflow.rb:141:8:141:37 | [true] ... \|\| ... | self | +| local_dataflow.rb:141:8:141:14 | [true] ! ... | local_dataflow.rb:141:8:141:37 | [true] ... \|\| ... | self | +| local_dataflow.rb:141:9:141:14 | call to use | local_dataflow.rb:141:8:141:14 | [false] ! ... | self | +| local_dataflow.rb:141:9:141:14 | call to use | local_dataflow.rb:141:8:141:14 | [true] ! ... | self | +| local_dataflow.rb:141:9:141:14 | self | local_dataflow.rb:141:9:141:14 | call to use | self | +| local_dataflow.rb:141:13:141:13 | x | local_dataflow.rb:141:9:141:14 | call to use | position 0 | +| local_dataflow.rb:141:19:141:37 | [false] ( ... ) | local_dataflow.rb:141:8:141:37 | [false] ... \|\| ... | position 0 | +| local_dataflow.rb:141:19:141:37 | [true] ( ... ) | local_dataflow.rb:141:8:141:37 | [true] ... \|\| ... | position 0 | +| local_dataflow.rb:141:20:141:25 | call to use | local_dataflow.rb:141:20:141:36 | [false] ... && ... | self | +| local_dataflow.rb:141:20:141:25 | call to use | local_dataflow.rb:141:20:141:36 | [true] ... && ... | self | +| local_dataflow.rb:141:20:141:25 | self | local_dataflow.rb:141:20:141:25 | call to use | self | +| local_dataflow.rb:141:24:141:24 | x | local_dataflow.rb:141:20:141:25 | call to use | position 0 | +| local_dataflow.rb:141:30:141:36 | [false] ! ... | local_dataflow.rb:141:20:141:36 | [false] ... && ... | position 0 | +| local_dataflow.rb:141:30:141:36 | [true] ! ... | local_dataflow.rb:141:20:141:36 | [true] ... && ... | position 0 | +| local_dataflow.rb:141:31:141:36 | call to use | local_dataflow.rb:141:30:141:36 | [false] ! ... | self | +| local_dataflow.rb:141:31:141:36 | call to use | local_dataflow.rb:141:30:141:36 | [true] ! ... | self | +| local_dataflow.rb:141:31:141:36 | self | local_dataflow.rb:141:31:141:36 | call to use | self | +| local_dataflow.rb:141:35:141:35 | x | local_dataflow.rb:141:31:141:36 | call to use | position 0 | +| local_dataflow.rb:143:11:143:16 | call to use | local_dataflow.rb:143:11:143:26 | [false] ... \|\| ... | self | +| local_dataflow.rb:143:11:143:16 | call to use | local_dataflow.rb:143:11:143:26 | [true] ... \|\| ... | self | +| local_dataflow.rb:143:11:143:16 | self | local_dataflow.rb:143:11:143:16 | call to use | self | +| local_dataflow.rb:143:15:143:15 | x | local_dataflow.rb:143:11:143:16 | call to use | position 0 | +| local_dataflow.rb:143:21:143:26 | call to use | local_dataflow.rb:143:11:143:26 | [false] ... \|\| ... | position 0 | +| local_dataflow.rb:143:21:143:26 | call to use | local_dataflow.rb:143:11:143:26 | [true] ... \|\| ... | position 0 | +| local_dataflow.rb:143:21:143:26 | self | local_dataflow.rb:143:21:143:26 | call to use | self | +| local_dataflow.rb:143:25:143:25 | x | local_dataflow.rb:143:21:143:26 | call to use | position 0 | +| local_dataflow.rb:144:11:144:16 | self | local_dataflow.rb:144:11:144:16 | call to use | self | +| local_dataflow.rb:144:15:144:15 | x | local_dataflow.rb:144:11:144:16 | call to use | position 0 | +| local_dataflow.rb:147:5:147:10 | self | local_dataflow.rb:147:5:147:10 | call to use | self | +| local_dataflow.rb:147:9:147:9 | x | local_dataflow.rb:147:5:147:10 | call to use | position 0 | +| local_dataflow.rb:148:5:148:10 | self | local_dataflow.rb:148:5:148:10 | call to use | self | +| local_dataflow.rb:148:9:148:9 | x | local_dataflow.rb:148:5:148:10 | call to use | position 0 | diff --git a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected index 85473aea3dd..f1b8eb2da26 100644 --- a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected +++ b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected @@ -50,7 +50,7 @@ | file://:0:0:0:0 | parameter self of each(0) | file://:0:0:0:0 | [summary] read: argument self.any element in each(0) | | local_dataflow.rb:1:1:7:3 | self (foo) | local_dataflow.rb:3:8:3:10 | self | | local_dataflow.rb:1:1:7:3 | self in foo | local_dataflow.rb:1:1:7:3 | self (foo) | -| local_dataflow.rb:1:1:124:4 | self (local_dataflow.rb) | local_dataflow.rb:49:1:53:3 | self | +| local_dataflow.rb:1:1:150:3 | self (local_dataflow.rb) | local_dataflow.rb:49:1:53:3 | self | | local_dataflow.rb:1:9:1:9 | a | local_dataflow.rb:1:9:1:9 | a | | local_dataflow.rb:1:9:1:9 | a | local_dataflow.rb:2:7:2:7 | a | | local_dataflow.rb:2:3:2:7 | ... = ... | local_dataflow.rb:3:13:3:13 | b | @@ -354,3 +354,116 @@ | local_dataflow.rb:123:8:123:20 | call to dup | local_dataflow.rb:123:8:123:45 | call to tap | | local_dataflow.rb:123:8:123:45 | call to tap | local_dataflow.rb:123:8:123:49 | call to dup | | local_dataflow.rb:123:26:123:45 | self | local_dataflow.rb:123:32:123:43 | self | +| local_dataflow.rb:126:1:128:3 | self (use) | local_dataflow.rb:127:3:127:8 | self | +| local_dataflow.rb:126:1:128:3 | self in use | local_dataflow.rb:126:1:128:3 | self (use) | +| local_dataflow.rb:130:1:150:3 | self (use_use_madness) | local_dataflow.rb:132:6:132:11 | self | +| local_dataflow.rb:130:1:150:3 | self in use_use_madness | local_dataflow.rb:130:1:150:3 | self (use_use_madness) | +| local_dataflow.rb:131:3:131:8 | ... = ... | local_dataflow.rb:132:10:132:10 | x | +| local_dataflow.rb:131:7:131:8 | "" | local_dataflow.rb:131:3:131:8 | ... = ... | +| local_dataflow.rb:131:7:131:8 | "" | local_dataflow.rb:131:3:131:8 | ... = ... | +| local_dataflow.rb:132:6:132:11 | [post] self | local_dataflow.rb:133:8:133:13 | self | +| local_dataflow.rb:132:6:132:11 | self | local_dataflow.rb:133:8:133:13 | self | +| local_dataflow.rb:132:10:132:10 | x | local_dataflow.rb:133:12:133:12 | x | +| local_dataflow.rb:132:12:148:10 | then ... | local_dataflow.rb:132:3:149:5 | if ... | +| local_dataflow.rb:133:8:133:13 | [post] self | local_dataflow.rb:133:18:133:23 | self | +| local_dataflow.rb:133:8:133:13 | [post] self | local_dataflow.rb:134:7:134:12 | self | +| local_dataflow.rb:133:8:133:13 | call to use | local_dataflow.rb:133:8:133:23 | [false] ... \|\| ... | +| local_dataflow.rb:133:8:133:13 | call to use | local_dataflow.rb:133:8:133:23 | [true] ... \|\| ... | +| local_dataflow.rb:133:8:133:13 | self | local_dataflow.rb:133:18:133:23 | self | +| local_dataflow.rb:133:8:133:13 | self | local_dataflow.rb:134:7:134:12 | self | +| local_dataflow.rb:133:12:133:12 | x | local_dataflow.rb:133:22:133:22 | x | +| local_dataflow.rb:133:12:133:12 | x | local_dataflow.rb:134:11:134:11 | x | +| local_dataflow.rb:133:18:133:23 | [post] self | local_dataflow.rb:134:7:134:12 | self | +| local_dataflow.rb:133:18:133:23 | [post] self | local_dataflow.rb:136:7:136:12 | self | +| local_dataflow.rb:133:18:133:23 | call to use | local_dataflow.rb:133:8:133:23 | [false] ... \|\| ... | +| local_dataflow.rb:133:18:133:23 | call to use | local_dataflow.rb:133:8:133:23 | [true] ... \|\| ... | +| local_dataflow.rb:133:18:133:23 | self | local_dataflow.rb:134:7:134:12 | self | +| local_dataflow.rb:133:18:133:23 | self | local_dataflow.rb:136:7:136:12 | self | +| local_dataflow.rb:133:22:133:22 | x | local_dataflow.rb:134:11:134:11 | x | +| local_dataflow.rb:133:22:133:22 | x | local_dataflow.rb:136:11:136:11 | x | +| local_dataflow.rb:133:24:134:12 | then ... | local_dataflow.rb:133:5:139:7 | if ... | +| local_dataflow.rb:134:7:134:12 | [post] self | local_dataflow.rb:141:9:141:14 | self | +| local_dataflow.rb:134:7:134:12 | call to use | local_dataflow.rb:133:24:134:12 | then ... | +| local_dataflow.rb:134:7:134:12 | self | local_dataflow.rb:141:9:141:14 | self | +| local_dataflow.rb:134:11:134:11 | x | local_dataflow.rb:141:13:141:13 | x | +| local_dataflow.rb:135:5:138:9 | else ... | local_dataflow.rb:133:5:139:7 | if ... | +| local_dataflow.rb:136:7:136:12 | [post] self | local_dataflow.rb:137:10:137:15 | self | +| local_dataflow.rb:136:7:136:12 | self | local_dataflow.rb:137:10:137:15 | self | +| local_dataflow.rb:136:11:136:11 | x | local_dataflow.rb:137:14:137:14 | x | +| local_dataflow.rb:137:7:138:9 | if ... | local_dataflow.rb:135:5:138:9 | else ... | +| local_dataflow.rb:137:10:137:15 | [post] self | local_dataflow.rb:137:21:137:26 | self | +| local_dataflow.rb:137:10:137:15 | [post] self | local_dataflow.rb:141:9:141:14 | self | +| local_dataflow.rb:137:10:137:15 | call to use | local_dataflow.rb:137:10:137:26 | [false] ... && ... | +| local_dataflow.rb:137:10:137:15 | call to use | local_dataflow.rb:137:10:137:26 | [true] ... && ... | +| local_dataflow.rb:137:10:137:15 | self | local_dataflow.rb:137:21:137:26 | self | +| local_dataflow.rb:137:10:137:15 | self | local_dataflow.rb:141:9:141:14 | self | +| local_dataflow.rb:137:14:137:14 | x | local_dataflow.rb:137:25:137:25 | x | +| local_dataflow.rb:137:14:137:14 | x | local_dataflow.rb:141:13:141:13 | x | +| local_dataflow.rb:137:20:137:26 | [false] ! ... | local_dataflow.rb:137:10:137:26 | [false] ... && ... | +| local_dataflow.rb:137:20:137:26 | [true] ! ... | local_dataflow.rb:137:10:137:26 | [true] ... && ... | +| local_dataflow.rb:137:21:137:26 | [post] self | local_dataflow.rb:141:9:141:14 | self | +| local_dataflow.rb:137:21:137:26 | call to use | local_dataflow.rb:137:20:137:26 | [false] ! ... | +| local_dataflow.rb:137:21:137:26 | call to use | local_dataflow.rb:137:20:137:26 | [true] ! ... | +| local_dataflow.rb:137:21:137:26 | self | local_dataflow.rb:141:9:141:14 | self | +| local_dataflow.rb:137:25:137:25 | x | local_dataflow.rb:141:13:141:13 | x | +| local_dataflow.rb:141:8:141:14 | [false] ! ... | local_dataflow.rb:141:8:141:37 | [false] ... \|\| ... | +| local_dataflow.rb:141:8:141:14 | [false] ! ... | local_dataflow.rb:141:8:141:37 | [true] ... \|\| ... | +| local_dataflow.rb:141:8:141:14 | [true] ! ... | local_dataflow.rb:141:8:141:37 | [true] ... \|\| ... | +| local_dataflow.rb:141:9:141:14 | [post] self | local_dataflow.rb:141:20:141:25 | self | +| local_dataflow.rb:141:9:141:14 | [post] self | local_dataflow.rb:147:5:147:10 | self | +| local_dataflow.rb:141:9:141:14 | call to use | local_dataflow.rb:141:8:141:14 | [false] ! ... | +| local_dataflow.rb:141:9:141:14 | call to use | local_dataflow.rb:141:8:141:14 | [true] ! ... | +| local_dataflow.rb:141:9:141:14 | self | local_dataflow.rb:141:20:141:25 | self | +| local_dataflow.rb:141:9:141:14 | self | local_dataflow.rb:147:5:147:10 | self | +| local_dataflow.rb:141:13:141:13 | x | local_dataflow.rb:141:24:141:24 | x | +| local_dataflow.rb:141:13:141:13 | x | local_dataflow.rb:147:9:147:9 | x | +| local_dataflow.rb:141:19:141:37 | [false] ( ... ) | local_dataflow.rb:141:8:141:37 | [false] ... \|\| ... | +| local_dataflow.rb:141:19:141:37 | [true] ( ... ) | local_dataflow.rb:141:8:141:37 | [true] ... \|\| ... | +| local_dataflow.rb:141:20:141:25 | [post] self | local_dataflow.rb:141:31:141:36 | self | +| local_dataflow.rb:141:20:141:25 | [post] self | local_dataflow.rb:143:11:143:16 | self | +| local_dataflow.rb:141:20:141:25 | call to use | local_dataflow.rb:141:20:141:36 | [false] ... && ... | +| local_dataflow.rb:141:20:141:25 | call to use | local_dataflow.rb:141:20:141:36 | [true] ... && ... | +| local_dataflow.rb:141:20:141:25 | self | local_dataflow.rb:141:31:141:36 | self | +| local_dataflow.rb:141:20:141:25 | self | local_dataflow.rb:143:11:143:16 | self | +| local_dataflow.rb:141:20:141:36 | [false] ... && ... | local_dataflow.rb:141:19:141:37 | [false] ( ... ) | +| local_dataflow.rb:141:20:141:36 | [true] ... && ... | local_dataflow.rb:141:19:141:37 | [true] ( ... ) | +| local_dataflow.rb:141:24:141:24 | x | local_dataflow.rb:141:35:141:35 | x | +| local_dataflow.rb:141:24:141:24 | x | local_dataflow.rb:143:15:143:15 | x | +| local_dataflow.rb:141:30:141:36 | [false] ! ... | local_dataflow.rb:141:20:141:36 | [false] ... && ... | +| local_dataflow.rb:141:30:141:36 | [true] ! ... | local_dataflow.rb:141:20:141:36 | [true] ... && ... | +| local_dataflow.rb:141:31:141:36 | [post] self | local_dataflow.rb:143:11:143:16 | self | +| local_dataflow.rb:141:31:141:36 | [post] self | local_dataflow.rb:147:5:147:10 | self | +| local_dataflow.rb:141:31:141:36 | call to use | local_dataflow.rb:141:30:141:36 | [false] ! ... | +| local_dataflow.rb:141:31:141:36 | call to use | local_dataflow.rb:141:30:141:36 | [true] ! ... | +| local_dataflow.rb:141:31:141:36 | self | local_dataflow.rb:143:11:143:16 | self | +| local_dataflow.rb:141:31:141:36 | self | local_dataflow.rb:147:5:147:10 | self | +| local_dataflow.rb:141:35:141:35 | x | local_dataflow.rb:143:15:143:15 | x | +| local_dataflow.rb:141:35:141:35 | x | local_dataflow.rb:147:9:147:9 | x | +| local_dataflow.rb:141:38:142:9 | then ... | local_dataflow.rb:141:5:145:7 | if ... | +| local_dataflow.rb:142:7:142:9 | nil | local_dataflow.rb:141:38:142:9 | then ... | +| local_dataflow.rb:143:5:144:16 | elsif ... | local_dataflow.rb:141:5:145:7 | if ... | +| local_dataflow.rb:143:11:143:16 | [post] self | local_dataflow.rb:143:21:143:26 | self | +| local_dataflow.rb:143:11:143:16 | [post] self | local_dataflow.rb:144:11:144:16 | self | +| local_dataflow.rb:143:11:143:16 | call to use | local_dataflow.rb:143:11:143:26 | [false] ... \|\| ... | +| local_dataflow.rb:143:11:143:16 | call to use | local_dataflow.rb:143:11:143:26 | [true] ... \|\| ... | +| local_dataflow.rb:143:11:143:16 | self | local_dataflow.rb:143:21:143:26 | self | +| local_dataflow.rb:143:11:143:16 | self | local_dataflow.rb:144:11:144:16 | self | +| local_dataflow.rb:143:15:143:15 | x | local_dataflow.rb:143:25:143:25 | x | +| local_dataflow.rb:143:15:143:15 | x | local_dataflow.rb:144:15:144:15 | x | +| local_dataflow.rb:143:21:143:26 | [post] self | local_dataflow.rb:144:11:144:16 | self | +| local_dataflow.rb:143:21:143:26 | [post] self | local_dataflow.rb:147:5:147:10 | self | +| local_dataflow.rb:143:21:143:26 | call to use | local_dataflow.rb:143:11:143:26 | [false] ... \|\| ... | +| local_dataflow.rb:143:21:143:26 | call to use | local_dataflow.rb:143:11:143:26 | [true] ... \|\| ... | +| local_dataflow.rb:143:21:143:26 | self | local_dataflow.rb:144:11:144:16 | self | +| local_dataflow.rb:143:21:143:26 | self | local_dataflow.rb:147:5:147:10 | self | +| local_dataflow.rb:143:25:143:25 | x | local_dataflow.rb:144:15:144:15 | x | +| local_dataflow.rb:143:25:143:25 | x | local_dataflow.rb:147:9:147:9 | x | +| local_dataflow.rb:143:27:144:16 | then ... | local_dataflow.rb:143:5:144:16 | elsif ... | +| local_dataflow.rb:144:11:144:16 | [post] self | local_dataflow.rb:147:5:147:10 | self | +| local_dataflow.rb:144:11:144:16 | call to use | local_dataflow.rb:143:27:144:16 | then ... | +| local_dataflow.rb:144:11:144:16 | self | local_dataflow.rb:147:5:147:10 | self | +| local_dataflow.rb:144:15:144:15 | x | local_dataflow.rb:147:9:147:9 | x | +| local_dataflow.rb:147:5:147:10 | [post] self | local_dataflow.rb:148:5:148:10 | self | +| local_dataflow.rb:147:5:147:10 | self | local_dataflow.rb:148:5:148:10 | self | +| local_dataflow.rb:147:9:147:9 | x | local_dataflow.rb:148:9:148:9 | x | +| local_dataflow.rb:148:5:148:10 | call to use | local_dataflow.rb:132:12:148:10 | then ... | diff --git a/ruby/ql/test/library-tests/dataflow/local/local_dataflow.rb b/ruby/ql/test/library-tests/dataflow/local/local_dataflow.rb index f3c6a097273..d72ed8ac5d4 100644 --- a/ruby/ql/test/library-tests/dataflow/local/local_dataflow.rb +++ b/ruby/ql/test/library-tests/dataflow/local/local_dataflow.rb @@ -122,3 +122,29 @@ end def dup_tap sink(source(1).dup.tap { |x| puts "hello" }.dup) # $ hasValueFlow=1 end + +def use x + rand() +end + +def use_use_madness + x = "" + if use(x) + if use(x) || use(x) + use(x) + else + use(x) + if use(x) && !use(x) + end + end + + if !use(x) || (use(x) && !use(x)) + nil + elsif use(x) || use(x) + use(x) + end + + use(x) + use(x) + end +end \ No newline at end of file From 81a1fa167ab6569bb0956ede441af3e1b31bf63b Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 10 Nov 2022 16:40:58 +0100 Subject: [PATCH 188/796] SSA: Expose phi-reads --- shared/ssa/codeql/ssa/Ssa.qll | 591 +++++++++++++++++++++++++--------- 1 file changed, 431 insertions(+), 160 deletions(-) diff --git a/shared/ssa/codeql/ssa/Ssa.qll b/shared/ssa/codeql/ssa/Ssa.qll index 19f31f7c8bb..f7f7683d386 100644 --- a/shared/ssa/codeql/ssa/Ssa.qll +++ b/shared/ssa/codeql/ssa/Ssa.qll @@ -264,8 +264,22 @@ module Make { ) } + /** + * Holds if `bb` is in the dominance frontier of a block containing a + * read of `v`. + */ + pragma[nomagic] + private predicate inReadDominanceFrontier(BasicBlock bb, SourceVariable v) { + exists(BasicBlock readbb | inDominanceFrontier(readbb, bb) | + lastRefIsRead(readbb, v) + or + exists(TPhiReadNode(v, readbb)) and + not ref(readbb, _, v, _) + ) + } + cached - newtype TDefinition = + private newtype TDefinitionExt = TWriteDef(SourceVariable v, BasicBlock bb, int i) { variableWrite(bb, i, v, _) and liveAfterWrite(bb, i, v) @@ -273,8 +287,16 @@ module Make { TPhiNode(SourceVariable v, BasicBlock bb) { inDefDominanceFrontier(bb, v) and liveAtEntry(bb, v) + } or + TPhiReadNode(SourceVariable v, BasicBlock bb) { + inReadDominanceFrontier(bb, v) and + liveAtEntry(bb, v) and + // no need to create a phi-read if there is already a normal phi + not any(PhiNode def).definesAt(v, bb, _) } + private class TDefinition = TWriteDef or TPhiNode; + private module SsaDefReaches { newtype TSsaRefKind = SsaActualRead() or @@ -283,6 +305,10 @@ module Make { class SsaRead = SsaActualRead or SsaPhiRead; + class SsaDefExt = SsaDef or SsaPhiRead; + + SsaDefExt ssaDefExt() { any() } + /** * A classification of SSA variable references into reads and definitions. */ @@ -307,98 +333,27 @@ module Make { } } - /** - * Holds if `bb` is in the dominance frontier of a block containing a - * read of `v`. - */ - pragma[nomagic] - private predicate inReadDominanceFrontier(BasicBlock bb, SourceVariable v) { - exists(BasicBlock readbb | inDominanceFrontier(readbb, bb) | - lastRefIsRead(readbb, v) - or - phiRead(readbb, v) - ) - } - - /** - * Holds if a phi-read node should be inserted for variable `v` at the beginning - * of basic block `bb`. - * - * Phi-read nodes are like normal phi nodes, but they are inserted based on reads - * instead of writes, and only if the dominance-frontier block does not already - * contain a reference (read or write) to `v`. Unlike normal phi nodes, this is - * an internal implementation detail that is not exposed. - * - * The motivation for adding phi-reads is to improve performance of the use-use - * calculation in cases where there is a large number of reads that can reach the - * same join-point, and from there reach a large number of basic blocks. Example: - * - * ```cs - * if (a) - * use(x); - * else if (b) - * use(x); - * else if (c) - * use(x); - * else if (d) - * use(x); - * // many more ifs ... - * - * // phi-read for `x` inserted here - * - * // program not mentioning `x`, with large basic block graph - * - * use(x); - * ``` - * - * Without phi-reads, the analysis has to replicate reachability for each of - * the guarded uses of `x`. However, with phi-reads, the analysis will limit - * each conditional use of `x` to reach the basic block containing the phi-read - * node for `x`, and only that basic block will have to compute reachability - * through the remainder of the large program. - * - * Like normal reads, each phi-read node `phi-read` can be reached from exactly - * one SSA definition (without passing through another definition): Assume, for - * the sake of contradiction, that there are two reaching definitions `def1` and - * `def2`. Now, if both `def1` and `def2` dominate `phi-read`, then the nearest - * dominating definition will prevent the other from reaching `phi-read`. So, at - * least one of `def1` and `def2` cannot dominate `phi-read`; assume it is `def1`. - * Then `def1` must go through one of its dominance-frontier blocks in order to - * reach `phi-read`. However, such a block will always start with a (normal) phi - * node, which contradicts reachability. - * - * Also, like normal reads, the unique SSA definition `def` that reaches `phi-read`, - * will dominate `phi-read`. Assuming it doesn't means that the path from `def` - * to `phi-read` goes through a dominance-frontier block, and hence a phi node, - * which contradicts reachability. - */ - pragma[nomagic] - predicate phiRead(BasicBlock bb, SourceVariable v) { - inReadDominanceFrontier(bb, v) and - liveAtEntry(bb, v) and - // only if there are no other references to `v` inside `bb` - not ref(bb, _, v, _) and - not exists(Definition def | def.definesAt(v, bb, _)) - } - /** * Holds if the `i`th node of basic block `bb` is a reference to `v`, - * either a read (when `k` is `SsaRead()`) or an SSA definition (when `k` - * is `SsaDef()`). + * either a read (when `k` is `SsaActualRead()`), an SSA definition (when `k` + * is `SsaDef()`), or a phi-read (when `k` is `SsaPhiRead()`). * - * Unlike `Liveness::ref`, this includes `phi` nodes. + * Unlike `Liveness::ref`, this includes `phi` (read) nodes. */ pragma[nomagic] predicate ssaRef(BasicBlock bb, int i, SourceVariable v, SsaRefKind k) { variableRead(bb, i, v, _) and k = SsaActualRead() or - phiRead(bb, v) and - i = -1 and - k = SsaPhiRead() - or - any(Definition def).definesAt(v, bb, i) and - k = SsaDef() + any(DefinitionExt def).definesAt(v, bb, i, k) + } + + /** + * Holds if the `i`th node of basic block `bb` is a reference to `v`, and + * this reference is not a phi-read. + */ + predicate ssaRefNonPhiRead(BasicBlock bb, int i, SourceVariable v) { + ssaRef(bb, i, v, [SsaActualRead().(TSsaRefKind), SsaDef()]) } private newtype OrderedSsaRefIndex = @@ -445,37 +400,36 @@ module Make { * Holds if the SSA definition `def` reaches rank index `rnk` in its own * basic block `bb`. */ - predicate ssaDefReachesRank(BasicBlock bb, Definition def, int rnk, SourceVariable v) { + predicate ssaDefReachesRank(BasicBlock bb, DefinitionExt def, int rnk, SourceVariable v) { exists(int i | - rnk = ssaRefRank(bb, i, v, SsaDef()) and - def.definesAt(v, bb, i) + rnk = ssaRefRank(bb, i, v, ssaDefExt()) and + def.definesAt(v, bb, i, _) ) or ssaDefReachesRank(bb, def, rnk - 1, v) and - rnk = ssaRefRank(bb, _, v, any(SsaRead k)) + rnk = ssaRefRank(bb, _, v, SsaActualRead()) } /** * Holds if the SSA definition of `v` at `def` reaches index `i` in the same * basic block `bb`, without crossing another SSA definition of `v`. */ - predicate ssaDefReachesReadWithinBlock(SourceVariable v, Definition def, BasicBlock bb, int i) { + predicate ssaDefReachesReadWithinBlock(SourceVariable v, DefinitionExt def, BasicBlock bb, int i) { exists(int rnk | ssaDefReachesRank(bb, def, rnk, v) and - rnk = ssaRefRank(bb, i, v, any(SsaRead k)) + rnk = ssaRefRank(bb, i, v, SsaActualRead()) ) } /** * Same as `ssaRefRank()`, but restricted to a particular SSA definition `def`. */ - int ssaDefRank(Definition def, SourceVariable v, BasicBlock bb, int i, SsaRefKind k) { - v = def.getSourceVariable() and + int ssaDefRank(DefinitionExt def, SourceVariable v, BasicBlock bb, int i, SsaRefKind k) { result = ssaRefRank(bb, i, v, k) and ( - ssaDefReachesRead(_, def, bb, i) + ssaDefReachesReadExt(v, def, bb, i) or - def.definesAt(_, bb, i) + def.definesAt(v, bb, i, k) ) } @@ -484,18 +438,38 @@ module Make { * last reference to `v` inside `bb`. */ pragma[noinline] - predicate lastSsaRef(Definition def, SourceVariable v, BasicBlock bb, int i) { + predicate lastSsaRefExt(DefinitionExt def, SourceVariable v, BasicBlock bb, int i) { ssaDefRank(def, v, bb, i, _) = maxSsaRefRank(bb, v) } - predicate defOccursInBlock(Definition def, BasicBlock bb, SourceVariable v, SsaRefKind k) { + /** Gets a phi-read node into which `inp` is an input, if any. */ + pragma[nomagic] + private DefinitionExt getAPhiReadOutput(DefinitionExt inp) { + phiHasInputFromBlockExt(result.(PhiReadNode), inp, _) + } + + pragma[nomagic] + DefinitionExt getAnUltimateOutput(Definition def) { result = getAPhiReadOutput*(def) } + + /** + * Same as `lastSsaRefExt`, but ignores phi-reads. + */ + pragma[noinline] + predicate lastSsaRef(Definition def, SourceVariable v, BasicBlock bb, int i) { + lastSsaRefExt(getAnUltimateOutput(def), v, bb, i) and + ssaRefNonPhiRead(bb, i, v) + } + + predicate defOccursInBlock(DefinitionExt def, BasicBlock bb, SourceVariable v, SsaRefKind k) { exists(ssaDefRank(def, v, bb, _, k)) } pragma[noinline] - private predicate ssaDefReachesThroughBlock(Definition def, BasicBlock bb) { - ssaDefReachesEndOfBlock(bb, def, _) and - not defOccursInBlock(_, bb, def.getSourceVariable(), _) + private predicate ssaDefReachesThroughBlock(DefinitionExt def, BasicBlock bb) { + exists(SourceVariable v | + ssaDefReachesEndOfBlockExt(bb, def, v) and + not defOccursInBlock(_, bb, v, _) + ) } /** @@ -503,85 +477,114 @@ module Make { * `bb2` is a transitive successor of `bb1`, `def` is live at the end of _some_ * predecessor of `bb2`, and the underlying variable for `def` is neither read * nor written in any block on the path between `bb1` and `bb2`. - * - * Phi reads are considered as normal reads for this predicate. */ pragma[nomagic] - private predicate varBlockReachesInclPhiRead(Definition def, BasicBlock bb1, BasicBlock bb2) { - defOccursInBlock(def, bb1, _, _) and + predicate varBlockReachesExt(DefinitionExt def, SourceVariable v, BasicBlock bb1, BasicBlock bb2) { + defOccursInBlock(def, bb1, v, _) and bb2 = getABasicBlockSuccessor(bb1) or exists(BasicBlock mid | - varBlockReachesInclPhiRead(def, bb1, mid) and + varBlockReachesExt(def, v, bb1, mid) and ssaDefReachesThroughBlock(def, mid) and bb2 = getABasicBlockSuccessor(mid) ) } pragma[nomagic] - private predicate phiReadStep(Definition def, SourceVariable v, BasicBlock bb1, BasicBlock bb2) { - varBlockReachesInclPhiRead(def, bb1, bb2) and - defOccursInBlock(def, bb2, v, SsaPhiRead()) + private predicate phiReadStep(DefinitionExt def, PhiReadNode phi, BasicBlock bb1, BasicBlock bb2) { + exists(SourceVariable v | + varBlockReachesExt(pragma[only_bind_into](def), v, bb1, pragma[only_bind_into](bb2)) and + phi.definesAt(v, bb2, _, _) and + not ref(bb2, _, v, _) + ) } pragma[nomagic] - private predicate varBlockReachesExclPhiRead(Definition def, BasicBlock bb1, BasicBlock bb2) { - varBlockReachesInclPhiRead(pragma[only_bind_into](def), bb1, pragma[only_bind_into](bb2)) and - ssaRef(bb2, _, def.getSourceVariable(), [SsaActualRead().(TSsaRefKind), SsaDef()]) + private predicate varBlockReachesExclPhiRead( + DefinitionExt def, SourceVariable v, BasicBlock bb1, BasicBlock bb2 + ) { + varBlockReachesExt(def, v, bb1, bb2) and + ssaRefNonPhiRead(bb2, _, v) or - exists(BasicBlock mid | - varBlockReachesExclPhiRead(def, mid, bb2) and - phiReadStep(def, _, bb1, mid) + exists(PhiReadNode phi, BasicBlock mid | + varBlockReachesExclPhiRead(phi, v, mid, bb2) and + phiReadStep(def, phi, bb1, mid) ) } /** - * Holds if `def` is accessed in basic block `bb1` (either a read or a write), - * the underlying variable `v` of `def` is accessed in basic block `bb2` - * (either a read or a write), `bb2` is a transitive successor of `bb1`, and - * `v` is neither read nor written in any block on the path between `bb1` - * and `bb2`. + * Same as `varBlockReachesExt`, but ignores phi-reads, and furthermore + * `bb2` is restricted to blocks in which the underlying variable `v` of + * `def` is referenced (either a read or a write). */ pragma[nomagic] - predicate varBlockReaches(Definition def, BasicBlock bb1, BasicBlock bb2) { - varBlockReachesExclPhiRead(def, bb1, bb2) and - not defOccursInBlock(def, bb1, _, SsaPhiRead()) + predicate varBlockReachesRef(Definition def, SourceVariable v, BasicBlock bb1, BasicBlock bb2) { + varBlockReachesExclPhiRead(getAnUltimateOutput(def), v, bb1, bb2) and + ssaRefNonPhiRead(bb1, _, v) + } + + pragma[nomagic] + predicate defAdjacentReadExt(DefinitionExt def, BasicBlock bb1, BasicBlock bb2, int i2) { + exists(SourceVariable v | + varBlockReachesExt(def, v, bb1, bb2) and + ssaRefRank(bb2, i2, v, SsaActualRead()) = 1 + ) } pragma[nomagic] predicate defAdjacentRead(Definition def, BasicBlock bb1, BasicBlock bb2, int i2) { - varBlockReaches(def, bb1, bb2) and - ssaRefRank(bb2, i2, def.getSourceVariable(), SsaActualRead()) = 1 + exists(SourceVariable v | varBlockReachesRef(def, v, bb1, bb2) | + ssaRefRank(bb2, i2, v, SsaActualRead()) = 1 + or + ssaRefRank(bb2, _, v, SsaPhiRead()) = 1 and + ssaRefRank(bb2, i2, v, SsaActualRead()) = 2 + ) } /** * Holds if `def` is accessed in basic block `bb` (either a read or a write), - * `bb1` can reach a transitive successor `bb2` where `def` is no longer live, + * `bb` can reach a transitive successor `bb2` where `def` is no longer live, * and `v` is neither read nor written in any block on the path between `bb` * and `bb2`. */ pragma[nomagic] - predicate varBlockReachesExit(Definition def, BasicBlock bb) { - exists(BasicBlock bb2 | varBlockReachesInclPhiRead(def, bb, bb2) | + predicate varBlockReachesExitExt(DefinitionExt def, BasicBlock bb) { + exists(BasicBlock bb2 | varBlockReachesExt(def, _, bb, bb2) | not defOccursInBlock(def, bb2, _, _) and - not ssaDefReachesEndOfBlock(bb2, def, _) - ) - or - exists(BasicBlock mid | - varBlockReachesExit(def, mid) and - phiReadStep(def, _, bb, mid) + not ssaDefReachesEndOfBlockExt(bb2, def, _) ) } - } - predicate phiReadExposedForTesting = phiRead/2; + pragma[nomagic] + private predicate varBlockReachesExitExclPhiRead(DefinitionExt def, BasicBlock bb) { + exists(BasicBlock bb2, SourceVariable v | + varBlockReachesExt(def, v, bb, bb2) and + not defOccursInBlock(def, bb2, _, _) and + not ssaDefReachesEndOfBlockExt(bb2, def, _) and + not any(PhiReadNode phi).definesAt(v, bb2, _, _) + ) + or + exists(PhiReadNode phi, BasicBlock bb2 | + varBlockReachesExitExclPhiRead(phi, bb2) and + phiReadStep(def, phi, bb, bb2) + ) + } + + /** + * Same as `varBlockReachesExitExt`, but ignores phi-reads. + */ + pragma[nomagic] + predicate varBlockReachesExit(Definition def, BasicBlock bb) { + varBlockReachesExitExclPhiRead(getAnUltimateOutput(def), bb) + } + } private import SsaDefReaches pragma[nomagic] - private predicate liveThrough(BasicBlock bb, SourceVariable v) { + private predicate liveThroughExt(BasicBlock bb, SourceVariable v) { liveAtExit(bb, v) and - not ssaRef(bb, _, v, SsaDef()) + not ssaRef(bb, _, v, ssaDefExt()) } /** @@ -592,7 +595,7 @@ module Make { * SSA definition of `v`. */ pragma[nomagic] - predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SourceVariable v) { + predicate ssaDefReachesEndOfBlockExt(BasicBlock bb, DefinitionExt def, SourceVariable v) { exists(int last | last = maxSsaRefRank(pragma[only_bind_into](bb), pragma[only_bind_into](v)) and ssaDefReachesRank(bb, def, last, v) and @@ -605,8 +608,31 @@ module Make { // the node. If two definitions dominate a node then one must dominate the // other, so therefore the definition of _closest_ is given by the dominator // tree. Thus, reaching definitions can be calculated in terms of dominance. - ssaDefReachesEndOfBlock(getImmediateBasicBlockDominator(bb), def, pragma[only_bind_into](v)) and - liveThrough(bb, pragma[only_bind_into](v)) + ssaDefReachesEndOfBlockExt(getImmediateBasicBlockDominator(bb), def, pragma[only_bind_into](v)) and + liveThroughExt(bb, pragma[only_bind_into](v)) + } + + pragma[nomagic] + private predicate phiReadReachesEndOfBlock(BasicBlock pred, BasicBlock bb, SourceVariable v) { + exists(PhiReadNode phi | + ssaDefReachesEndOfBlockExt(bb, phi, v) and + pred = getImmediateBasicBlockDominator(phi.getBasicBlock()) + ) + } + + /** + * NB: If this predicate is exposed, it should be cached. + * + * Same as `ssaDefReachesEndOfBlockExt`, but ignores phi-reads. + */ + pragma[nomagic] + predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SourceVariable v) { + ssaDefReachesEndOfBlockExt(bb, def, v) + or + exists(BasicBlock mid | + ssaDefReachesEndOfBlock(mid, def, v) and + phiReadReachesEndOfBlock(mid, bb, v) + ) } /** @@ -623,20 +649,50 @@ module Make { ) } + /** + * NB: If this predicate is exposed, it should be cached. + * + * Holds if `inp` is an input to the phi (read) node `phi` along the edge originating in `bb`. + */ + pragma[nomagic] + predicate phiHasInputFromBlockExt(DefinitionExt phi, DefinitionExt inp, BasicBlock bb) { + exists(SourceVariable v, BasicBlock bbDef | + phi.definesAt(v, bbDef, _, _) and + getABasicBlockPredecessor(bbDef) = bb and + ssaDefReachesEndOfBlockExt(bb, inp, v) + | + phi instanceof PhiNode or + phi instanceof PhiReadNode + ) + } + /** * NB: If this predicate is exposed, it should be cached. * * Holds if the SSA definition of `v` at `def` reaches a read at index `i` in - * basic block `bb`, without crossing another SSA definition of `v`. The read - * is of kind `rk`. + * basic block `bb`, without crossing another SSA definition of `v`. + */ + pragma[nomagic] + predicate ssaDefReachesReadExt(SourceVariable v, DefinitionExt def, BasicBlock bb, int i) { + ssaDefReachesReadWithinBlock(v, def, bb, i) + or + ssaRef(bb, i, v, SsaActualRead()) and + ssaDefReachesEndOfBlockExt(getABasicBlockPredecessor(bb), def, v) and + not ssaDefReachesReadWithinBlock(v, _, bb, i) + } + + /** + * NB: If this predicate is exposed, it should be cached. + * + * Same as `ssaDefReachesReadExt`, but ignores phi-reads. */ pragma[nomagic] predicate ssaDefReachesRead(SourceVariable v, Definition def, BasicBlock bb, int i) { ssaDefReachesReadWithinBlock(v, def, bb, i) or - ssaRef(bb, i, v, any(SsaRead k)) and + ssaRef(bb, i, v, SsaActualRead()) and ssaDefReachesEndOfBlock(getABasicBlockPredecessor(bb), def, v) and - not ssaDefReachesReadWithinBlock(v, _, bb, i) + not exists(Definition other | ssaDefReachesReadWithinBlock(v, other, bb, i)) } /** @@ -647,14 +703,32 @@ module Make { * path between them without any read of `def`. */ pragma[nomagic] - predicate adjacentDefRead(Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2) { + predicate adjacentDefReadExt( + DefinitionExt def, SourceVariable v, BasicBlock bb1, int i1, BasicBlock bb2, int i2 + ) { exists(int rnk | - rnk = ssaDefRank(def, _, bb1, i1, _) and - rnk + 1 = ssaDefRank(def, _, bb1, i2, SsaActualRead()) and - variableRead(bb1, i2, _, _) and + rnk = ssaDefRank(def, v, bb1, i1, _) and + rnk + 1 = ssaDefRank(def, v, bb1, i2, SsaActualRead()) and + variableRead(bb1, i2, v, _) and bb2 = bb1 ) or + lastSsaRefExt(def, v, bb1, i1) and + defAdjacentReadExt(def, bb1, bb2, i2) + } + + /** + * NB: If this predicate is exposed, it should be cached. + * + * Same as `adjacentDefReadExt`, but ignores phi-reads. + */ + pragma[nomagic] + predicate adjacentDefRead(Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2) { + exists(SourceVariable v | + adjacentDefReadExt(getAnUltimateOutput(def), v, bb1, i1, bb2, i2) and + ssaRefNonPhiRead(bb1, i1, v) + ) + or lastSsaRef(def, _, bb1, i1) and defAdjacentRead(def, bb1, bb2, i2) } @@ -704,19 +778,41 @@ module Make { * without passing through another read or write. */ pragma[nomagic] + predicate lastRefRedefExt( + DefinitionExt def, SourceVariable v, BasicBlock bb, int i, DefinitionExt next + ) { + // Next reference to `v` inside `bb` is a write + exists(int rnk, int j | + rnk = ssaDefRank(def, v, bb, i, _) and + next.definesAt(v, bb, j, _) and + rnk + 1 = ssaRefRank(bb, j, v, ssaDefExt()) + ) + or + // Can reach a write using one or more steps + lastSsaRefExt(def, v, bb, i) and + exists(BasicBlock bb2 | + varBlockReachesExt(def, v, bb, bb2) and + 1 = ssaDefRank(next, v, bb2, _, ssaDefExt()) + ) + } + + /** + * NB: If this predicate is exposed, it should be cached. + * + * Same as `lastRefRedefExt`, but ignores phi-reads. + */ + pragma[nomagic] predicate lastRefRedef(Definition def, BasicBlock bb, int i, Definition next) { exists(SourceVariable v | - // Next reference to `v` inside `bb` is a write - exists(int rnk, int j | - rnk = ssaDefRank(def, v, bb, i, _) and - next.definesAt(v, bb, j) and - rnk + 1 = ssaRefRank(bb, j, v, SsaDef()) - ) - or - // Can reach a write using one or more steps + lastRefRedefExt(getAnUltimateOutput(def), v, bb, i, next) and + ssaRefNonPhiRead(bb, i, v) + ) + or + // Can reach a write using one or more steps + exists(SourceVariable v | lastSsaRef(def, v, bb, i) and exists(BasicBlock bb2 | - varBlockReaches(def, bb, bb2) and + varBlockReachesRef(def, v, bb, bb2) and 1 = ssaDefRank(next, v, bb2, _, SsaDef()) ) ) @@ -770,6 +866,25 @@ module Make { * another read. */ pragma[nomagic] + predicate lastRefExt(DefinitionExt def, BasicBlock bb, int i) { + // Can reach another definition + lastRefRedefExt(def, _, bb, i, _) + or + exists(SourceVariable v | lastSsaRefExt(def, v, bb, i) | + // Can reach exit directly + bb instanceof ExitBasicBlock + or + // Can reach a block using one or more steps, where `def` is no longer live + varBlockReachesExitExt(def, bb) + ) + } + + /** + * NB: If this predicate is exposed, it should be cached. + * + * Same as `lastRefExt`, but ignores phi-reads. + */ + pragma[nomagic] predicate lastRef(Definition def, BasicBlock bb, int i) { // Can reach another definition lastRefRedef(def, bb, i, _) @@ -819,7 +934,7 @@ module Make { final BasicBlock getBasicBlock() { this.definesAt(_, result, _) } /** Gets a textual representation of this SSA definition. */ - string toString() { none() } + string toString() { result = "SSA def(" + this.getSourceVariable() + ")" } } /** An SSA definition that corresponds to a write. */ @@ -829,13 +944,11 @@ module Make { private int i; WriteDefinition() { this = TWriteDef(v, bb, i) } - - override string toString() { result = "WriteDef" } } /** A phi node. */ class PhiNode extends Definition, TPhiNode { - override string toString() { result = "Phi" } + override string toString() { result = "SSA phi(" + this.getSourceVariable() + ")" } } /** @@ -851,6 +964,120 @@ module Make { } } + /** + * An extended static single assignment (SSA) definition. + * + * This is either a normal SSA definition (`Definition`) or a + * phi-read node (`PhiReadNode`). + */ + class DefinitionExt extends TDefinitionExt { + /** Gets the source variable underlying this SSA definition. */ + SourceVariable getSourceVariable() { this.definesAt(result, _, _, _) } + + /** + * Holds if this SSA definition defines `v` at index `i` in basic block `bb`. + * Phi nodes are considered to be at index `-1`, while normal variable writes + * are at the index of the control flow node they wrap. + */ + final predicate definesAt(SourceVariable v, BasicBlock bb, int i, SsaRefKind kind) { + this.(Definition).definesAt(v, bb, i) and + kind = SsaDef() + or + this = TPhiReadNode(v, bb) and i = -1 and kind = SsaPhiRead() + } + + /** Gets the basic block to which this SSA definition belongs. */ + final BasicBlock getBasicBlock() { this.definesAt(_, result, _, _) } + + /** Gets a textual representation of this SSA definition. */ + string toString() { result = this.(Definition).toString() } + } + + /** + * A phi-read node. + * + * Phi-read nodes are like normal phi nodes, but they are inserted based on reads + * instead of writes, and only if the dominance-frontier block does not already + * contain a normal phi node. + * + * The motivation for adding phi-reads is to improve performance of the use-use + * calculation in cases where there is a large number of reads that can reach the + * same join-point, and from there reach a large number of basic blocks. Example: + * + * ```cs + * if (a) + * use(x); + * else if (b) + * use(x); + * else if (c) + * use(x); + * else if (d) + * use(x); + * // many more ifs ... + * + * // phi-read for `x` inserted here + * + * // program not mentioning `x`, with large basic block graph + * + * use(x); + * ``` + * + * Without phi-reads, the analysis has to replicate reachability for each of + * the guarded uses of `x`. However, with phi-reads, the analysis will limit + * each conditional use of `x` to reach the basic block containing the phi-read + * node for `x`, and only that basic block will have to compute reachability + * through the remainder of the large program. + * + * Another motivation for phi-reads is when a large number of reads can reach + * another large number of reads: + * + * ```cs + * if (a) + * use(x); + * else if (b) + * use(x); + * else if (c) + * use(x); + * else if (d) + * use(x); + * // many more ifs ... + * + * // phi-read for `x` inserted here + * + * if (a) + * use(x); + * else if (b) + * use(x); + * else if (c) + * use(x); + * else if (d) + * use(x); + * // many more ifs ... + * ``` + * + * Without phi-reads, one needs to add `n*m` data-flow edges (assuming `n` reads + * before the phi-read and `m` reads after the phi-read), whereas if we include + * phi-reads in the data-flow graph, we only need to add `n+m` edges. + * + * Like normal reads, each phi-read node `phi-read` can be reached from exactly + * one SSA definition (without passing through another definition): Assume, for + * the sake of contradiction, that there are two reaching definitions `def1` and + * `def2`. Now, if both `def1` and `def2` dominate `phi-read`, then the nearest + * dominating definition will prevent the other from reaching `phi-read`. So, at + * least one of `def1` and `def2` cannot dominate `phi-read`; assume it is `def1`. + * Then `def1` must go through one of its dominance-frontier blocks in order to + * reach `phi-read`. However, such a block will always start with a (normal) phi + * node, which contradicts reachability. + * + * Also, like normal reads, the unique SSA definition `def` that reaches `phi-read`, + * will dominate `phi-read`. Assuming it doesn't means that the path from `def` + * to `phi-read` goes through a dominance-frontier block, and hence a phi node, + * which contradicts reachability. + */ + class PhiReadNode extends DefinitionExt, TPhiReadNode { + override string toString() { result = "SSA phi read(" + this.getSourceVariable() + ")" } + } + /** Provides a set of consistency queries. */ module Consistency { /** A definition that is relevant for the consistency queries. */ @@ -861,18 +1088,40 @@ module Make { ); } + /** A definition that is relevant for the consistency queries. */ + abstract class RelevantDefinitionExt extends DefinitionExt { + /** Override this predicate to ensure locations in consistency results. */ + abstract predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ); + } + /** Holds if a read can be reached from multiple definitions. */ query predicate nonUniqueDef(RelevantDefinition def, SourceVariable v, BasicBlock bb, int i) { ssaDefReachesRead(v, def, bb, i) and not exists(unique(Definition def0 | ssaDefReachesRead(v, def0, bb, i))) } + /** Holds if a read can be reached from multiple definitions. */ + query predicate nonUniqueDefExt( + RelevantDefinitionExt def, SourceVariable v, BasicBlock bb, int i + ) { + ssaDefReachesReadExt(v, def, bb, i) and + not exists(unique(DefinitionExt def0 | ssaDefReachesReadExt(v, def0, bb, i))) + } + /** Holds if a read cannot be reached from a definition. */ query predicate readWithoutDef(SourceVariable v, BasicBlock bb, int i) { variableRead(bb, i, v, _) and not ssaDefReachesRead(v, _, bb, i) } + /** Holds if a read cannot be reached from a definition. */ + query predicate readWithoutDefExt(SourceVariable v, BasicBlock bb, int i) { + variableRead(bb, i, v, _) and + not ssaDefReachesReadExt(v, _, bb, i) + } + /** Holds if a definition cannot reach a read. */ query predicate deadDef(RelevantDefinition def, SourceVariable v) { v = def.getSourceVariable() and @@ -881,6 +1130,14 @@ module Make { not uncertainWriteDefinitionInput(_, def) } + /** Holds if a definition cannot reach a read. */ + query predicate deadDefExt(RelevantDefinitionExt def, SourceVariable v) { + v = def.getSourceVariable() and + not ssaDefReachesReadExt(_, def, _, _) and + not phiHasInputFromBlockExt(_, def, _) and + not uncertainWriteDefinitionInput(_, def) + } + /** Holds if a read is not dominated by a definition. */ query predicate notDominatedByDef(RelevantDefinition def, SourceVariable v, BasicBlock bb, int i) { exists(BasicBlock bbDef, int iDef | def.definesAt(v, bbDef, iDef) | @@ -892,5 +1149,19 @@ module Make { not def.definesAt(v, getImmediateBasicBlockDominator*(bb), _) ) } + + /** Holds if a read is not dominated by a definition. */ + query predicate notDominatedByDefExt( + RelevantDefinitionExt def, SourceVariable v, BasicBlock bb, int i + ) { + exists(BasicBlock bbDef, int iDef | def.definesAt(v, bbDef, iDef, _) | + ssaDefReachesReadWithinBlock(v, def, bb, i) and + (bb != bbDef or i < iDef) + or + ssaDefReachesReadExt(v, def, bb, i) and + not ssaDefReachesReadWithinBlock(v, def, bb, i) and + not def.definesAt(v, getImmediateBasicBlockDominator*(bb), _, _) + ) + } } } From bd78e73131061aa7732278546656e19146016a61 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 10 Nov 2022 16:41:08 +0100 Subject: [PATCH 189/796] C#: Add tests for phi reads --- .../ql/consistency-queries/SsaConsistency.ql | 11 ++- .../lib/semmle/code/csharp/dataflow/SSA.qll | 38 +++----- .../code/csharp/dataflow/internal/SsaImpl.qll | 91 ++++++++++++++++--- .../dataflow/ssa/SSAPhiRead.expected | 34 ++++++- .../library-tests/dataflow/ssa/SSAPhiRead.ql | 17 +++- .../test/library-tests/dataflow/ssa/Test.cs | 2 +- 6 files changed, 144 insertions(+), 49 deletions(-) diff --git a/csharp/ql/consistency-queries/SsaConsistency.ql b/csharp/ql/consistency-queries/SsaConsistency.ql index bd666a71e49..225aeb4e6de 100644 --- a/csharp/ql/consistency-queries/SsaConsistency.ql +++ b/csharp/ql/consistency-queries/SsaConsistency.ql @@ -1,5 +1,6 @@ import csharp -import semmle.code.csharp.dataflow.internal.SsaImpl::Consistency +import semmle.code.csharp.dataflow.internal.SsaImpl as Impl +import Impl::Consistency import Ssa class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition { @@ -10,6 +11,14 @@ class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition { } } +class MyRelevantDefinitionExt extends RelevantDefinitionExt, Impl::DefinitionExt { + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } +} + query predicate localDeclWithSsaDef(LocalVariableDeclExpr d) { // Local variables in C# must be initialized before every use, so uninitialized // local variables should not have an SSA definition, as that would imply that diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll index f377d94e15c..8764da0a784 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll @@ -138,25 +138,6 @@ module Ssa { } } - private string getSplitString(Definition def) { - exists(ControlFlow::BasicBlock bb, int i, ControlFlow::Node cfn | - def.definesAt(_, bb, i) and - result = cfn.(ControlFlow::Nodes::ElementNode).getSplitsString() - | - cfn = bb.getNode(i) - or - not exists(bb.getNode(i)) and - cfn = bb.getFirstNode() - ) - } - - private string getToStringPrefix(Definition def) { - result = "[" + getSplitString(def) + "] " - or - not exists(getSplitString(def)) and - result = "" - } - /** * A static single assignment (SSA) definition. Either an explicit variable * definition (`ExplicitDefinition`), an implicit variable definition @@ -521,8 +502,8 @@ module Ssa { override string toString() { if this.getADefinition() instanceof AssignableDefinitions::ImplicitParameterDefinition - then result = getToStringPrefix(this) + "SSA param(" + this.getSourceVariable() + ")" - else result = getToStringPrefix(this) + "SSA def(" + this.getSourceVariable() + ")" + then result = SsaImpl::getToStringPrefix(this) + "SSA param(" + this.getSourceVariable() + ")" + else result = SsaImpl::getToStringPrefix(this) + "SSA def(" + this.getSourceVariable() + ")" } override Location getLocation() { result = ad.getLocation() } @@ -570,8 +551,12 @@ module Ssa { override string toString() { if this.getSourceVariable().getAssignable() instanceof LocalScopeVariable - then result = getToStringPrefix(this) + "SSA capture def(" + this.getSourceVariable() + ")" - else result = getToStringPrefix(this) + "SSA entry def(" + this.getSourceVariable() + ")" + then + result = + SsaImpl::getToStringPrefix(this) + "SSA capture def(" + this.getSourceVariable() + ")" + else + result = + SsaImpl::getToStringPrefix(this) + "SSA entry def(" + this.getSourceVariable() + ")" } override Location getLocation() { result = this.getCallable().getLocation() } @@ -612,7 +597,7 @@ module Ssa { } override string toString() { - result = getToStringPrefix(this) + "SSA call def(" + this.getSourceVariable() + ")" + result = SsaImpl::getToStringPrefix(this) + "SSA call def(" + this.getSourceVariable() + ")" } override Location getLocation() { result = this.getCall().getLocation() } @@ -640,7 +625,8 @@ module Ssa { final Definition getQualifierDefinition() { result = q } override string toString() { - result = getToStringPrefix(this) + "SSA qualifier def(" + this.getSourceVariable() + ")" + result = + SsaImpl::getToStringPrefix(this) + "SSA qualifier def(" + this.getSourceVariable() + ")" } override Location getLocation() { result = this.getQualifierDefinition().getLocation() } @@ -682,7 +668,7 @@ module Ssa { } override string toString() { - result = getToStringPrefix(this) + "SSA phi(" + this.getSourceVariable() + ")" + result = SsaImpl::getToStringPrefix(this) + "SSA phi(" + this.getSourceVariable() + ")" } /* diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll index adfacd2970a..98a1cad843a 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll @@ -49,7 +49,23 @@ private module SsaInput implements SsaImplCommon::InputSig { } } -import SsaImplCommon::Make +private import SsaImplCommon::Make as Impl + +class Definition = Impl::Definition; + +class WriteDefinition = Impl::WriteDefinition; + +class UncertainWriteDefinition = Impl::UncertainWriteDefinition; + +class PhiNode = Impl::PhiNode; + +module Consistency = Impl::Consistency; + +module ExposedForTestingOnly { + predicate ssaDefReachesReadExt = Impl::ssaDefReachesReadExt/4; + + predicate phiHasInputFromBlockExt = Impl::phiHasInputFromBlockExt/3; +} /** * Holds if the `i`th node of basic block `bb` reads source variable `v`. @@ -1072,7 +1088,7 @@ private predicate adjacentDefRead( Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2, SsaInput::SourceVariable v ) { - adjacentDefRead(def, bb1, i1, bb2, i2) and + Impl::adjacentDefRead(def, bb1, i1, bb2, i2) and v = def.getSourceVariable() } @@ -1088,7 +1104,7 @@ private predicate adjacentDefReachesRead( exists(SsaInput::BasicBlock bb3, int i3 | adjacentDefReachesRead(def, bb1, i1, bb3, i3) and SsaInput::variableRead(bb3, i3, _, false) and - adjacentDefRead(def, bb3, i3, bb2, i2) + Impl::adjacentDefRead(def, bb3, i3, bb2, i2) ) } @@ -1111,11 +1127,11 @@ private predicate adjacentDefReachesUncertainRead( /** Same as `lastRefRedef`, but skips uncertain reads. */ pragma[nomagic] private predicate lastRefSkipUncertainReads(Definition def, SsaInput::BasicBlock bb, int i) { - lastRef(def, bb, i) and + Impl::lastRef(def, bb, i) and not SsaInput::variableRead(bb, i, def.getSourceVariable(), false) or exists(SsaInput::BasicBlock bb0, int i0 | - lastRef(def, bb0, i0) and + Impl::lastRef(def, bb0, i0) and adjacentDefReachesUncertainRead(def, bb, i, bb0, i0) ) } @@ -1237,7 +1253,7 @@ private module Cached { v = def.getSourceVariable() and capturedReadIn(_, _, v, edef.getSourceVariable(), c, additionalCalls) and def = def0.getAnUltimateDefinition() and - ssaDefReachesRead(_, def0, bb, i) and + Impl::ssaDefReachesRead(_, def0, bb, i) and capturedReadIn(bb, i, v, _, _, _) and c = bb.getNode(i) ) @@ -1264,18 +1280,18 @@ private module Cached { cached predicate isLiveAtEndOfBlock(Definition def, ControlFlow::BasicBlock bb) { - ssaDefReachesEndOfBlock(bb, def, _) + Impl::ssaDefReachesEndOfBlock(bb, def, _) } cached - Definition phiHasInputFromBlock(PhiNode phi, ControlFlow::BasicBlock bb) { - phiHasInputFromBlock(phi, result, bb) + Definition phiHasInputFromBlock(Ssa::PhiNode phi, ControlFlow::BasicBlock bb) { + Impl::phiHasInputFromBlock(phi, result, bb) } cached AssignableRead getAReadAtNode(Definition def, ControlFlow::Node cfn) { exists(Ssa::SourceVariable v, ControlFlow::BasicBlock bb, int i | - ssaDefReachesRead(v, def, bb, i) and + Impl::ssaDefReachesRead(v, def, bb, i) and variableReadActual(bb, i, v) and cfn = bb.getNode(i) and result.getAControlFlowNode() = cfn @@ -1313,11 +1329,11 @@ private module Cached { /** Same as `lastRefRedef`, but skips uncertain reads. */ cached predicate lastRefBeforeRedef(Definition def, ControlFlow::BasicBlock bb, int i, Definition next) { - lastRefRedef(def, bb, i, next) and + Impl::lastRefRedef(def, bb, i, next) and not SsaInput::variableRead(bb, i, def.getSourceVariable(), false) or exists(SsaInput::BasicBlock bb0, int i0 | - lastRefRedef(def, bb0, i0, next) and + Impl::lastRefRedef(def, bb0, i0, next) and adjacentDefReachesUncertainRead(def, bb, i, bb0, i0) ) } @@ -1333,7 +1349,7 @@ private module Cached { cached Definition uncertainWriteDefinitionInput(UncertainWriteDefinition def) { - uncertainWriteDefinitionInput(def, result) + Impl::uncertainWriteDefinitionInput(def, result) } cached @@ -1343,10 +1359,57 @@ private module Cached { v = def.getSourceVariable() and p = v.getAssignable() and def = def0.getAnUltimateDefinition() and - ssaDefReachesRead(_, def0, bb, i) and + Impl::ssaDefReachesRead(_, def0, bb, i) and outRefExitRead(bb, i, v) ) } } import Cached + +private string getSplitString(DefinitionExt def) { + exists(ControlFlow::BasicBlock bb, int i, ControlFlow::Node cfn | + def.definesAt(_, bb, i, _) and + result = cfn.(ControlFlow::Nodes::ElementNode).getSplitsString() + | + cfn = bb.getNode(i) + or + not exists(bb.getNode(i)) and + cfn = bb.getFirstNode() + ) +} + +string getToStringPrefix(DefinitionExt def) { + result = "[" + getSplitString(def) + "] " + or + not exists(getSplitString(def)) and + result = "" +} + +/** + * An extended static single assignment (SSA) definition. + * + * This is either a normal SSA definition (`Definition`) or a + * phi-read node (`PhiReadNode`). + * + * Only intended for internal use. + */ +class DefinitionExt extends Impl::DefinitionExt { + override string toString() { result = this.(Ssa::Definition).toString() } + + /** Gets the location of this definition. */ + Location getLocation() { result = this.(Ssa::Definition).getLocation() } +} + +/** + * A phi-read node. + * + * Only intended for internal use. + */ +class PhiReadNode extends DefinitionExt, Impl::PhiReadNode { + override string toString() { + result = getToStringPrefix(this) + "SSA phi read(" + this.getSourceVariable() + ")" + } + + override Location getLocation() { result = this.getBasicBlock().getLocation() } +} diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SSAPhiRead.expected b/csharp/ql/test/library-tests/dataflow/ssa/SSAPhiRead.expected index 19c394b58fd..970e6fce524 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SSAPhiRead.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SSAPhiRead.expected @@ -1,4 +1,30 @@ -| DefUse.cs:63:9:63:14 | this.Field2 | DefUse.cs:80:30:80:31 | access to local variable x1 | -| Fields.cs:65:24:65:32 | this.LoopField | Fields.cs:63:16:63:28 | this access | -| Properties.cs:65:24:65:31 | this.LoopProp | Properties.cs:63:16:63:16 | access to parameter i | -| Test.cs:78:13:78:13 | x | Test.cs:90:9:97:9 | if (...) ... | +phiReadNode +| DefUse.cs:80:30:80:31 | SSA phi read(this.Field2) | DefUse.cs:63:9:63:14 | this.Field2 | +| Fields.cs:63:16:63:28 | SSA phi read(this.LoopField) | Fields.cs:65:24:65:32 | this.LoopField | +| Patterns.cs:20:9:38:9 | SSA phi read(o) | Patterns.cs:7:16:7:16 | o | +| Properties.cs:63:16:63:16 | SSA phi read(this.LoopProp) | Properties.cs:65:24:65:31 | this.LoopProp | +| Test.cs:25:16:25:16 | SSA phi read(x) | Test.cs:8:13:8:13 | x | +| Test.cs:90:9:97:9 | SSA phi read(x) | Test.cs:78:13:78:13 | x | +| Test.cs:99:9:99:15 | SSA phi read(x) | Test.cs:78:13:78:13 | x | +phiReadNodeRead +| DefUse.cs:80:30:80:31 | SSA phi read(this.Field2) | DefUse.cs:63:9:63:14 | this.Field2 | DefUse.cs:80:37:80:42 | access to field Field2 | +| Fields.cs:63:16:63:28 | SSA phi read(this.LoopField) | Fields.cs:65:24:65:32 | this.LoopField | Fields.cs:65:24:65:32 | access to field LoopField | +| Patterns.cs:20:9:38:9 | SSA phi read(o) | Patterns.cs:7:16:7:16 | o | Patterns.cs:20:17:20:17 | access to local variable o | +| Properties.cs:63:16:63:16 | SSA phi read(this.LoopProp) | Properties.cs:65:24:65:31 | this.LoopProp | Properties.cs:65:24:65:31 | access to property LoopProp | +| Test.cs:25:16:25:16 | SSA phi read(x) | Test.cs:8:13:8:13 | x | Test.cs:25:16:25:16 | access to local variable x | +| Test.cs:90:9:97:9 | SSA phi read(x) | Test.cs:78:13:78:13 | x | Test.cs:92:17:92:17 | access to local variable x | +| Test.cs:90:9:97:9 | SSA phi read(x) | Test.cs:78:13:78:13 | x | Test.cs:96:17:96:17 | access to local variable x | +| Test.cs:99:9:99:15 | SSA phi read(x) | Test.cs:78:13:78:13 | x | Test.cs:99:13:99:13 | access to local variable x | +| Test.cs:99:9:99:15 | SSA phi read(x) | Test.cs:78:13:78:13 | x | Test.cs:104:17:104:17 | access to local variable x | +phiReadInput +| DefUse.cs:80:30:80:31 | SSA phi read(this.Field2) | DefUse.cs:63:9:63:18 | SSA def(this.Field2) | +| DefUse.cs:80:30:80:31 | SSA phi read(this.Field2) | DefUse.cs:80:30:80:31 | SSA phi read(this.Field2) | +| Fields.cs:63:16:63:28 | SSA phi read(this.LoopField) | Fields.cs:61:17:61:17 | SSA entry def(this.LoopField) | +| Fields.cs:63:16:63:28 | SSA phi read(this.LoopField) | Fields.cs:63:16:63:28 | SSA phi read(this.LoopField) | +| Patterns.cs:20:9:38:9 | SSA phi read(o) | Patterns.cs:7:16:7:23 | SSA def(o) | +| Properties.cs:63:16:63:16 | SSA phi read(this.LoopProp) | Properties.cs:61:17:61:17 | SSA entry def(this.LoopProp) | +| Properties.cs:63:16:63:16 | SSA phi read(this.LoopProp) | Properties.cs:63:16:63:16 | SSA phi read(this.LoopProp) | +| Test.cs:25:16:25:16 | SSA phi read(x) | Test.cs:24:9:24:15 | SSA phi(x) | +| Test.cs:25:16:25:16 | SSA phi read(x) | Test.cs:25:16:25:16 | SSA phi read(x) | +| Test.cs:90:9:97:9 | SSA phi read(x) | Test.cs:78:13:78:17 | SSA def(x) | +| Test.cs:99:9:99:15 | SSA phi read(x) | Test.cs:90:9:97:9 | SSA phi read(x) | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SSAPhiRead.ql b/csharp/ql/test/library-tests/dataflow/ssa/SSAPhiRead.ql index f9603dc1da2..8fee62217bf 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SSAPhiRead.ql +++ b/csharp/ql/test/library-tests/dataflow/ssa/SSAPhiRead.ql @@ -1,6 +1,17 @@ import csharp import semmle.code.csharp.dataflow.internal.SsaImpl +import ExposedForTestingOnly -from Ssa::SourceVariable v, ControlFlow::BasicBlock bb -where phiReadExposedForTesting(bb, v) -select v, bb +query predicate phiReadNode(PhiReadNode phi, Ssa::SourceVariable v) { phi.getSourceVariable() = v } + +query predicate phiReadNodeRead(PhiReadNode phi, Ssa::SourceVariable v, ControlFlow::Node read) { + phi.getSourceVariable() = v and + exists(ControlFlow::BasicBlock bb, int i | + ssaDefReachesReadExt(v, phi, bb, i) and + read = bb.getNode(i) + ) +} + +query predicate phiReadInput(PhiReadNode phi, DefinitionExt inp) { + phiHasInputFromBlockExt(phi, inp, _) +} diff --git a/csharp/ql/test/library-tests/dataflow/ssa/Test.cs b/csharp/ql/test/library-tests/dataflow/ssa/Test.cs index 5d321d0117d..23fee7d4706 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/Test.cs +++ b/csharp/ql/test/library-tests/dataflow/ssa/Test.cs @@ -95,7 +95,7 @@ class Test { use(x); } - // no phi_use for `x`, because actual use exists in the block + // phi_use for `x`, even though there is an actual use in the block use(x); From 67f31ffdf06e30fcf29caff37062a45f9266ede6 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 10 Nov 2022 14:28:35 +0100 Subject: [PATCH 190/796] Ruby: Add tests for phi reads --- ruby/ql/consistency-queries/SsaConsistency.ql | 11 ++- .../codeql/ruby/dataflow/internal/SsaImpl.qll | 67 +++++++++++++--- .../variables/parameter.expected | 4 + .../test/library-tests/variables/ssa.expected | 77 +++++++++++++++++++ ruby/ql/test/library-tests/variables/ssa.ql | 16 ++++ ruby/ql/test/library-tests/variables/ssa.rb | 15 ++++ .../variables/varaccess.expected | 34 ++++++++ .../library-tests/variables/variable.expected | 8 +- .../variables/varscopes.expected | 3 +- 9 files changed, 220 insertions(+), 15 deletions(-) diff --git a/ruby/ql/consistency-queries/SsaConsistency.ql b/ruby/ql/consistency-queries/SsaConsistency.ql index 7ba9262baa4..30503e6aa1f 100644 --- a/ruby/ql/consistency-queries/SsaConsistency.ql +++ b/ruby/ql/consistency-queries/SsaConsistency.ql @@ -1,5 +1,6 @@ import codeql.ruby.dataflow.SSA -import codeql.ruby.dataflow.internal.SsaImpl::Consistency +import codeql.ruby.dataflow.internal.SsaImpl +import Consistency class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition { override predicate hasLocationInfo( @@ -8,3 +9,11 @@ class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition { this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) } } + +class MyRelevantDefinitionExt extends RelevantDefinitionExt, DefinitionExt { + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } +} diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll index c7154b50d0f..2f3b1e085b0 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll @@ -2,6 +2,7 @@ private import codeql.ssa.Ssa as SsaImplCommon private import codeql.ruby.AST private import codeql.ruby.CFG as Cfg private import codeql.ruby.controlflow.internal.ControlFlowGraphImplShared as ControlFlowGraphImplShared +private import codeql.ruby.dataflow.SSA private import codeql.ruby.ast.Variable private import Cfg::CfgNodes::ExprNodes @@ -61,7 +62,23 @@ private module SsaInput implements SsaImplCommon::InputSig { } } -import SsaImplCommon::Make +private import SsaImplCommon::Make as Impl + +class Definition = Impl::Definition; + +class WriteDefinition = Impl::WriteDefinition; + +class UncertainWriteDefinition = Impl::UncertainWriteDefinition; + +class PhiNode = Impl::PhiNode; + +module Consistency = Impl::Consistency; + +module ExposedForTestingOnly { + predicate ssaDefReachesReadExt = Impl::ssaDefReachesReadExt/4; + + predicate phiHasInputFromBlockExt = Impl::phiHasInputFromBlockExt/3; +} /** Holds if `v` is uninitialized at index `i` in entry block `bb`. */ predicate uninitializedWrite(Cfg::EntryBasicBlock bb, int i, LocalVariable v) { @@ -204,7 +221,7 @@ private predicate adjacentDefRead( Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2, SsaInput::SourceVariable v ) { - adjacentDefRead(def, bb1, i1, bb2, i2) and + Impl::adjacentDefRead(def, bb1, i1, bb2, i2) and v = def.getSourceVariable() } @@ -220,7 +237,7 @@ private predicate adjacentDefReachesRead( exists(SsaInput::BasicBlock bb3, int i3 | adjacentDefReachesRead(def, bb1, i1, bb3, i3) and SsaInput::variableRead(bb3, i3, _, false) and - adjacentDefRead(def, bb3, i3, bb2, i2) + Impl::adjacentDefRead(def, bb3, i3, bb2, i2) ) } @@ -243,11 +260,11 @@ private predicate adjacentDefReachesUncertainRead( /** Same as `lastRefRedef`, but skips uncertain reads. */ pragma[nomagic] private predicate lastRefSkipUncertainReads(Definition def, SsaInput::BasicBlock bb, int i) { - lastRef(def, bb, i) and + Impl::lastRef(def, bb, i) and not SsaInput::variableRead(bb, i, def.getSourceVariable(), false) or exists(SsaInput::BasicBlock bb0, int i0 | - lastRef(def, bb0, i0) and + Impl::lastRef(def, bb0, i0) and adjacentDefReachesUncertainRead(def, bb, i, bb0, i0) ) } @@ -304,7 +321,7 @@ private module Cached { cached VariableReadAccessCfgNode getARead(Definition def) { exists(LocalVariable v, Cfg::BasicBlock bb, int i | - ssaDefReachesRead(v, def, bb, i) and + Impl::ssaDefReachesRead(v, def, bb, i) and variableReadActual(bb, i, v) and result = bb.getNode(i) ) @@ -315,7 +332,7 @@ private module Cached { Definition def, CallCfgNode call, LocalVariable v, Cfg::CfgScope scope ) { exists(Cfg::BasicBlock bb, int i | - ssaDefReachesRead(v, def, bb, i) and + Impl::ssaDefReachesRead(v, def, bb, i) and capturedCallRead(call, bb, i, v) and scope.getOuterCfgScope() = bb.getScope() ) @@ -360,7 +377,7 @@ private module Cached { Definition def, LocalVariable v, Cfg::CfgScope scope ) { exists(Cfg::BasicBlock bb, int i | - ssaDefReachesRead(v, def, bb, i) and + Impl::ssaDefReachesRead(v, def, bb, i) and capturedExitRead(bb, i, v) and scope = bb.getScope().getOuterCfgScope*() ) @@ -403,7 +420,7 @@ private module Cached { cached Definition phiHasInputFromBlock(PhiNode phi, Cfg::BasicBlock bb) { - phiHasInputFromBlock(phi, result, bb) + Impl::phiHasInputFromBlock(phi, result, bb) } /** @@ -459,19 +476,45 @@ private module Cached { */ cached predicate lastRefBeforeRedef(Definition def, Cfg::BasicBlock bb, int i, Definition next) { - lastRefRedef(def, bb, i, next) and + Impl::lastRefRedef(def, bb, i, next) and not SsaInput::variableRead(bb, i, def.getSourceVariable(), false) or exists(SsaInput::BasicBlock bb0, int i0 | - lastRefRedef(def, bb0, i0, next) and + Impl::lastRefRedef(def, bb0, i0, next) and adjacentDefReachesUncertainRead(def, bb, i, bb0, i0) ) } cached Definition uncertainWriteDefinitionInput(UncertainWriteDefinition def) { - uncertainWriteDefinitionInput(def, result) + Impl::uncertainWriteDefinitionInput(def, result) } } import Cached + +/** + * An extended static single assignment (SSA) definition. + * + * This is either a normal SSA definition (`Definition`) or a + * phi-read node (`PhiReadNode`). + * + * Only intended for internal use. + */ +class DefinitionExt extends Impl::DefinitionExt { + override string toString() { result = this.(Ssa::Definition).toString() } + + /** Gets the location of this definition. */ + Location getLocation() { result = this.(Ssa::Definition).getLocation() } +} + +/** + * A phi-read node. + * + * Only intended for internal use. + */ +class PhiReadNode extends DefinitionExt, Impl::PhiReadNode { + override string toString() { result = "SSA phi read(" + this.getSourceVariable() + ")" } + + override Location getLocation() { result = this.getBasicBlock().getLocation() } +} diff --git a/ruby/ql/test/library-tests/variables/parameter.expected b/ruby/ql/test/library-tests/variables/parameter.expected index 292ae665964..6e6c8426f86 100644 --- a/ruby/ql/test/library-tests/variables/parameter.expected +++ b/ruby/ql/test/library-tests/variables/parameter.expected @@ -38,6 +38,10 @@ parameterVariable | ssa.rb:53:8:53:10 | foo | ssa.rb:53:8:53:10 | foo | | ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a | | ssa.rb:66:15:66:15 | a | ssa.rb:66:15:66:15 | a | +| ssa.rb:90:9:90:10 | b1 | ssa.rb:90:9:90:10 | b1 | +| ssa.rb:90:13:90:14 | b2 | ssa.rb:90:13:90:14 | b2 | +| ssa.rb:90:17:90:18 | b3 | ssa.rb:90:17:90:18 | b3 | +| ssa.rb:90:21:90:22 | b4 | ssa.rb:90:21:90:22 | b4 | parameterNoVariable | parameters.rb:45:22:45:22 | _ | parameterVariableNoAccess diff --git a/ruby/ql/test/library-tests/variables/ssa.expected b/ruby/ql/test/library-tests/variables/ssa.expected index e1df08d4285..20133a71857 100644 --- a/ruby/ql/test/library-tests/variables/ssa.expected +++ b/ruby/ql/test/library-tests/variables/ssa.expected @@ -164,6 +164,12 @@ definition | ssa.rb:83:7:87:5 | self | ssa.rb:81:1:88:3 | self | | ssa.rb:84:10:86:8 | captured | ssa.rb:82:3:82:10 | captured | | ssa.rb:84:10:86:8 | self | ssa.rb:81:1:88:3 | self | +| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | +| ssa.rb:90:9:90:10 | b1 | ssa.rb:90:9:90:10 | b1 | +| ssa.rb:90:13:90:14 | b2 | ssa.rb:90:13:90:14 | b2 | +| ssa.rb:90:17:90:18 | b3 | ssa.rb:90:17:90:18 | b3 | +| ssa.rb:90:21:90:22 | b4 | ssa.rb:90:21:90:22 | b4 | +| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | read | class_variables.rb:1:1:29:4 | self (class_variables.rb) | class_variables.rb:1:1:29:4 | self | class_variables.rb:3:1:3:5 | self | | class_variables.rb:5:1:7:3 | self (print) | class_variables.rb:5:1:7:3 | self | class_variables.rb:6:2:6:6 | self | @@ -347,6 +353,18 @@ read | ssa.rb:83:7:87:5 | self | ssa.rb:81:1:88:3 | self | ssa.rb:84:6:86:8 | self | | ssa.rb:84:10:86:8 | captured | ssa.rb:82:3:82:10 | captured | ssa.rb:85:15:85:22 | captured | | ssa.rb:84:10:86:8 | self | ssa.rb:81:1:88:3 | self | ssa.rb:85:10:85:22 | self | +| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:93:5:93:10 | self | +| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:95:5:95:10 | self | +| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:99:5:99:10 | self | +| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:101:5:101:10 | self | +| ssa.rb:90:9:90:10 | b1 | ssa.rb:90:9:90:10 | b1 | ssa.rb:92:7:92:8 | b1 | +| ssa.rb:90:13:90:14 | b2 | ssa.rb:90:13:90:14 | b2 | ssa.rb:94:10:94:11 | b2 | +| ssa.rb:90:17:90:18 | b3 | ssa.rb:90:17:90:18 | b3 | ssa.rb:98:7:98:8 | b3 | +| ssa.rb:90:21:90:22 | b4 | ssa.rb:90:21:90:22 | b4 | ssa.rb:100:10:100:11 | b4 | +| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:93:10:93:10 | x | +| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:95:10:95:10 | x | +| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:99:10:99:10 | x | +| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:101:10:101:10 | x | firstRead | class_variables.rb:1:1:29:4 | self (class_variables.rb) | class_variables.rb:1:1:29:4 | self | class_variables.rb:3:1:3:5 | self | | class_variables.rb:5:1:7:3 | self (print) | class_variables.rb:5:1:7:3 | self | class_variables.rb:6:2:6:6 | self | @@ -485,6 +503,18 @@ firstRead | ssa.rb:83:7:87:5 | self | ssa.rb:81:1:88:3 | self | ssa.rb:84:6:86:8 | self | | ssa.rb:84:10:86:8 | captured | ssa.rb:82:3:82:10 | captured | ssa.rb:85:15:85:22 | captured | | ssa.rb:84:10:86:8 | self | ssa.rb:81:1:88:3 | self | ssa.rb:85:10:85:22 | self | +| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:93:5:93:10 | self | +| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:95:5:95:10 | self | +| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:99:5:99:10 | self | +| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:101:5:101:10 | self | +| ssa.rb:90:9:90:10 | b1 | ssa.rb:90:9:90:10 | b1 | ssa.rb:92:7:92:8 | b1 | +| ssa.rb:90:13:90:14 | b2 | ssa.rb:90:13:90:14 | b2 | ssa.rb:94:10:94:11 | b2 | +| ssa.rb:90:17:90:18 | b3 | ssa.rb:90:17:90:18 | b3 | ssa.rb:98:7:98:8 | b3 | +| ssa.rb:90:21:90:22 | b4 | ssa.rb:90:21:90:22 | b4 | ssa.rb:100:10:100:11 | b4 | +| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:93:10:93:10 | x | +| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:95:10:95:10 | x | +| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:99:10:99:10 | x | +| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:101:10:101:10 | x | lastRead | class_variables.rb:1:1:29:4 | self (class_variables.rb) | class_variables.rb:1:1:29:4 | self | class_variables.rb:3:1:3:5 | self | | class_variables.rb:5:1:7:3 | self (print) | class_variables.rb:5:1:7:3 | self | class_variables.rb:6:2:6:6 | self | @@ -624,6 +654,18 @@ lastRead | ssa.rb:83:7:87:5 | self | ssa.rb:81:1:88:3 | self | ssa.rb:84:6:86:8 | self | | ssa.rb:84:10:86:8 | captured | ssa.rb:82:3:82:10 | captured | ssa.rb:85:15:85:22 | captured | | ssa.rb:84:10:86:8 | self | ssa.rb:81:1:88:3 | self | ssa.rb:85:10:85:22 | self | +| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:93:5:93:10 | self | +| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:95:5:95:10 | self | +| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:99:5:99:10 | self | +| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:101:5:101:10 | self | +| ssa.rb:90:9:90:10 | b1 | ssa.rb:90:9:90:10 | b1 | ssa.rb:92:7:92:8 | b1 | +| ssa.rb:90:13:90:14 | b2 | ssa.rb:90:13:90:14 | b2 | ssa.rb:94:10:94:11 | b2 | +| ssa.rb:90:17:90:18 | b3 | ssa.rb:90:17:90:18 | b3 | ssa.rb:98:7:98:8 | b3 | +| ssa.rb:90:21:90:22 | b4 | ssa.rb:90:21:90:22 | b4 | ssa.rb:100:10:100:11 | b4 | +| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:93:10:93:10 | x | +| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:95:10:95:10 | x | +| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:99:10:99:10 | x | +| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:101:10:101:10 | x | adjacentReads | class_variables.rb:26:1:29:3 | self (N) | class_variables.rb:26:1:29:3 | self | class_variables.rb:27:3:27:11 | self | class_variables.rb:28:3:28:7 | self | | instance_variables.rb:1:1:44:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:1:1:1:4 | self | instance_variables.rb:11:1:11:9 | self | @@ -674,6 +716,14 @@ adjacentReads | ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:39:8:39:9 | self | ssa.rb:41:3:41:13 | self | | ssa.rb:66:11:70:5 | captured | ssa.rb:65:3:65:10 | captured | ssa.rb:68:10:68:17 | captured | ssa.rb:69:5:69:12 | captured | | ssa.rb:66:11:70:5 | self | ssa.rb:64:1:72:3 | self | ssa.rb:67:5:67:10 | self | ssa.rb:68:5:68:17 | self | +| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:93:5:93:10 | self | ssa.rb:99:5:99:10 | self | +| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:93:5:93:10 | self | ssa.rb:101:5:101:10 | self | +| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:95:5:95:10 | self | ssa.rb:99:5:99:10 | self | +| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:95:5:95:10 | self | ssa.rb:101:5:101:10 | self | +| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:93:10:93:10 | x | ssa.rb:99:10:99:10 | x | +| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:93:10:93:10 | x | ssa.rb:101:10:101:10 | x | +| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:95:10:95:10 | x | ssa.rb:99:10:99:10 | x | +| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:95:10:95:10 | x | ssa.rb:101:10:101:10 | x | phi | parameters.rb:37:3:37:18 | phi | parameters.rb:35:16:35:16 | b | parameters.rb:35:1:38:3 | | | parameters.rb:37:3:37:18 | phi | parameters.rb:35:16:35:16 | b | parameters.rb:35:16:35:20 | ... = ... | @@ -689,3 +739,30 @@ phi | ssa.rb:45:3:45:12 | phi | ssa.rb:45:3:45:3 | x | ssa.rb:45:3:45:7 | ... = ... | | ssa.rb:50:3:50:8 | phi | ssa.rb:49:14:49:14 | y | ssa.rb:49:1:51:3 | | | ssa.rb:50:3:50:8 | phi | ssa.rb:49:14:49:14 | y | ssa.rb:49:14:49:19 | ... = ... | +phiReadNode +| parameters.rb:26:3:26:11 | SSA phi read(name) | parameters.rb:25:15:25:18 | name | +| ssa.rb:5:3:13:5 | SSA phi read(self) | ssa.rb:1:1:16:3 | self | +| ssa.rb:19:9:19:9 | SSA phi read(self) | ssa.rb:18:1:23:3 | self | +| ssa.rb:92:3:96:5 | SSA phi read(self) | ssa.rb:90:1:103:3 | self | +| ssa.rb:92:3:96:5 | SSA phi read(x) | ssa.rb:91:3:91:3 | x | +| ssa.rb:94:3:95:10 | SSA phi read(self) | ssa.rb:90:1:103:3 | self | +| ssa.rb:94:3:95:10 | SSA phi read(x) | ssa.rb:91:3:91:3 | x | +phiReadNodeRead +| parameters.rb:26:3:26:11 | SSA phi read(name) | parameters.rb:25:15:25:18 | name | parameters.rb:26:8:26:11 | name | +| ssa.rb:5:3:13:5 | SSA phi read(self) | ssa.rb:1:1:16:3 | self | ssa.rb:15:3:15:8 | self | +| ssa.rb:19:9:19:9 | SSA phi read(self) | ssa.rb:18:1:23:3 | self | ssa.rb:20:5:20:10 | self | +| ssa.rb:92:3:96:5 | SSA phi read(self) | ssa.rb:90:1:103:3 | self | ssa.rb:99:5:99:10 | self | +| ssa.rb:92:3:96:5 | SSA phi read(self) | ssa.rb:90:1:103:3 | self | ssa.rb:101:5:101:10 | self | +| ssa.rb:92:3:96:5 | SSA phi read(x) | ssa.rb:91:3:91:3 | x | ssa.rb:99:10:99:10 | x | +| ssa.rb:92:3:96:5 | SSA phi read(x) | ssa.rb:91:3:91:3 | x | ssa.rb:101:10:101:10 | x | +phiReadInput +| parameters.rb:26:3:26:11 | SSA phi read(name) | parameters.rb:25:15:25:18 | name | +| ssa.rb:5:3:13:5 | SSA phi read(self) | ssa.rb:1:1:16:3 | self (m) | +| ssa.rb:19:9:19:9 | SSA phi read(self) | ssa.rb:18:1:23:3 | self (m1) | +| ssa.rb:19:9:19:9 | SSA phi read(self) | ssa.rb:19:9:19:9 | SSA phi read(self) | +| ssa.rb:92:3:96:5 | SSA phi read(self) | ssa.rb:90:1:103:3 | self (m12) | +| ssa.rb:92:3:96:5 | SSA phi read(self) | ssa.rb:94:3:95:10 | SSA phi read(self) | +| ssa.rb:92:3:96:5 | SSA phi read(x) | ssa.rb:91:3:91:7 | ... = ... | +| ssa.rb:92:3:96:5 | SSA phi read(x) | ssa.rb:94:3:95:10 | SSA phi read(x) | +| ssa.rb:94:3:95:10 | SSA phi read(self) | ssa.rb:90:1:103:3 | self (m12) | +| ssa.rb:94:3:95:10 | SSA phi read(x) | ssa.rb:91:3:91:7 | ... = ... | diff --git a/ruby/ql/test/library-tests/variables/ssa.ql b/ruby/ql/test/library-tests/variables/ssa.ql index 26f3d5f8c0d..b7a8378e8ff 100644 --- a/ruby/ql/test/library-tests/variables/ssa.ql +++ b/ruby/ql/test/library-tests/variables/ssa.ql @@ -1,6 +1,8 @@ import codeql.ruby.AST import codeql.ruby.CFG import codeql.ruby.dataflow.SSA +import codeql.ruby.dataflow.internal.SsaImpl +import ExposedForTestingOnly query predicate definition(Ssa::Definition def, Variable v) { def.getSourceVariable() = v } @@ -24,3 +26,17 @@ query predicate adjacentReads(Ssa::Definition def, Variable v, CfgNode read1, Cf query predicate phi(Ssa::PhiNode phi, Variable v, Ssa::Definition input) { phi.getSourceVariable() = v and input = phi.getAnInput() } + +query predicate phiReadNode(PhiReadNode phi, Variable v) { phi.getSourceVariable() = v } + +query predicate phiReadNodeRead(PhiReadNode phi, Variable v, CfgNode read) { + phi.getSourceVariable() = v and + exists(BasicBlock bb, int i | + ssaDefReachesReadExt(v, phi, bb, i) and + read = bb.getNode(i) + ) +} + +query predicate phiReadInput(PhiReadNode phi, DefinitionExt inp) { + phiHasInputFromBlockExt(phi, inp, _) +} diff --git a/ruby/ql/test/library-tests/variables/ssa.rb b/ruby/ql/test/library-tests/variables/ssa.rb index bb13dd6c4c9..c8a28e39f07 100644 --- a/ruby/ql/test/library-tests/variables/ssa.rb +++ b/ruby/ql/test/library-tests/variables/ssa.rb @@ -85,4 +85,19 @@ def m11 puts captured end end +end + +def m12(b1, b2, b3, b4) + x = 0 + if (b1) then + puts x + elsif (b2) then + puts x + end + # phi read for x + if (b3) then + puts x + elsif (b4) then + puts x + end end \ No newline at end of file diff --git a/ruby/ql/test/library-tests/variables/varaccess.expected b/ruby/ql/test/library-tests/variables/varaccess.expected index 59a5ee362f6..4443373e8c2 100644 --- a/ruby/ql/test/library-tests/variables/varaccess.expected +++ b/ruby/ql/test/library-tests/variables/varaccess.expected @@ -279,6 +279,23 @@ variableAccess | ssa.rb:84:6:86:8 | self | ssa.rb:81:1:88:3 | self | ssa.rb:81:1:88:3 | m11 | | ssa.rb:85:10:85:22 | self | ssa.rb:81:1:88:3 | self | ssa.rb:81:1:88:3 | m11 | | ssa.rb:85:15:85:22 | captured | ssa.rb:82:3:82:10 | captured | ssa.rb:81:1:88:3 | m11 | +| ssa.rb:90:9:90:10 | b1 | ssa.rb:90:9:90:10 | b1 | ssa.rb:90:1:103:3 | m12 | +| ssa.rb:90:13:90:14 | b2 | ssa.rb:90:13:90:14 | b2 | ssa.rb:90:1:103:3 | m12 | +| ssa.rb:90:17:90:18 | b3 | ssa.rb:90:17:90:18 | b3 | ssa.rb:90:1:103:3 | m12 | +| ssa.rb:90:21:90:22 | b4 | ssa.rb:90:21:90:22 | b4 | ssa.rb:90:1:103:3 | m12 | +| ssa.rb:91:3:91:3 | x | ssa.rb:91:3:91:3 | x | ssa.rb:90:1:103:3 | m12 | +| ssa.rb:92:7:92:8 | b1 | ssa.rb:90:9:90:10 | b1 | ssa.rb:90:1:103:3 | m12 | +| ssa.rb:93:5:93:10 | self | ssa.rb:90:1:103:3 | self | ssa.rb:90:1:103:3 | m12 | +| ssa.rb:93:10:93:10 | x | ssa.rb:91:3:91:3 | x | ssa.rb:90:1:103:3 | m12 | +| ssa.rb:94:10:94:11 | b2 | ssa.rb:90:13:90:14 | b2 | ssa.rb:90:1:103:3 | m12 | +| ssa.rb:95:5:95:10 | self | ssa.rb:90:1:103:3 | self | ssa.rb:90:1:103:3 | m12 | +| ssa.rb:95:10:95:10 | x | ssa.rb:91:3:91:3 | x | ssa.rb:90:1:103:3 | m12 | +| ssa.rb:98:7:98:8 | b3 | ssa.rb:90:17:90:18 | b3 | ssa.rb:90:1:103:3 | m12 | +| ssa.rb:99:5:99:10 | self | ssa.rb:90:1:103:3 | self | ssa.rb:90:1:103:3 | m12 | +| ssa.rb:99:10:99:10 | x | ssa.rb:91:3:91:3 | x | ssa.rb:90:1:103:3 | m12 | +| ssa.rb:100:10:100:11 | b4 | ssa.rb:90:21:90:22 | b4 | ssa.rb:90:1:103:3 | m12 | +| ssa.rb:101:5:101:10 | self | ssa.rb:90:1:103:3 | self | ssa.rb:90:1:103:3 | m12 | +| ssa.rb:101:10:101:10 | x | ssa.rb:91:3:91:3 | x | ssa.rb:90:1:103:3 | m12 | explicitWrite | class_variables.rb:1:1:1:3 | @@x | class_variables.rb:1:1:1:8 | ... = ... | | class_variables.rb:19:3:19:5 | @@x | class_variables.rb:19:3:19:10 | ... = ... | @@ -349,6 +366,7 @@ explicitWrite | ssa.rb:69:5:69:12 | captured | ssa.rb:69:5:69:17 | ... = ... | | ssa.rb:75:3:75:10 | captured | ssa.rb:75:3:75:14 | ... = ... | | ssa.rb:82:3:82:10 | captured | ssa.rb:82:3:82:14 | ... = ... | +| ssa.rb:91:3:91:3 | x | ssa.rb:91:3:91:7 | ... = ... | implicitWrite | nested_scopes.rb:15:23:15:23 | a | | nested_scopes.rb:16:26:16:26 | x | @@ -390,6 +408,10 @@ implicitWrite | ssa.rb:53:8:53:10 | foo | | ssa.rb:64:8:64:8 | a | | ssa.rb:66:15:66:15 | a | +| ssa.rb:90:9:90:10 | b1 | +| ssa.rb:90:13:90:14 | b2 | +| ssa.rb:90:17:90:18 | b3 | +| ssa.rb:90:21:90:22 | b4 | readAccess | class_variables.rb:3:1:3:5 | self | | class_variables.rb:3:3:3:5 | @@x | @@ -582,3 +604,15 @@ readAccess | ssa.rb:84:6:86:8 | self | | ssa.rb:85:10:85:22 | self | | ssa.rb:85:15:85:22 | captured | +| ssa.rb:92:7:92:8 | b1 | +| ssa.rb:93:5:93:10 | self | +| ssa.rb:93:10:93:10 | x | +| ssa.rb:94:10:94:11 | b2 | +| ssa.rb:95:5:95:10 | self | +| ssa.rb:95:10:95:10 | x | +| ssa.rb:98:7:98:8 | b3 | +| ssa.rb:99:5:99:10 | self | +| ssa.rb:99:10:99:10 | x | +| ssa.rb:100:10:100:11 | b4 | +| ssa.rb:101:5:101:10 | self | +| ssa.rb:101:10:101:10 | x | diff --git a/ruby/ql/test/library-tests/variables/variable.expected b/ruby/ql/test/library-tests/variables/variable.expected index 541ed394653..ccab8a3cdf4 100644 --- a/ruby/ql/test/library-tests/variables/variable.expected +++ b/ruby/ql/test/library-tests/variables/variable.expected @@ -120,7 +120,7 @@ | scopes.rb:43:2:43:4 | foo | | scopes.rb:46:5:46:8 | var2 | | ssa.rb:1:1:16:3 | self | -| ssa.rb:1:1:88:3 | self | +| ssa.rb:1:1:103:3 | self | | ssa.rb:1:7:1:7 | b | | ssa.rb:2:3:2:3 | i | | ssa.rb:18:1:23:3 | self | @@ -152,3 +152,9 @@ | ssa.rb:75:3:75:10 | captured | | ssa.rb:81:1:88:3 | self | | ssa.rb:82:3:82:10 | captured | +| ssa.rb:90:1:103:3 | self | +| ssa.rb:90:9:90:10 | b1 | +| ssa.rb:90:13:90:14 | b2 | +| ssa.rb:90:17:90:18 | b3 | +| ssa.rb:90:21:90:22 | b4 | +| ssa.rb:91:3:91:3 | x | diff --git a/ruby/ql/test/library-tests/variables/varscopes.expected b/ruby/ql/test/library-tests/variables/varscopes.expected index 1859ab01550..6b64ca6f97d 100644 --- a/ruby/ql/test/library-tests/variables/varscopes.expected +++ b/ruby/ql/test/library-tests/variables/varscopes.expected @@ -57,7 +57,7 @@ | scopes.rb:37:1:39:3 | foo | | scopes.rb:41:1:49:3 | M | | ssa.rb:1:1:16:3 | m | -| ssa.rb:1:1:88:3 | ssa.rb | +| ssa.rb:1:1:103:3 | ssa.rb | | ssa.rb:18:1:23:3 | m1 | | ssa.rb:25:1:30:3 | m2 | | ssa.rb:26:3:28:5 | { ... } | @@ -75,3 +75,4 @@ | ssa.rb:81:1:88:3 | m11 | | ssa.rb:83:7:87:5 | do ... end | | ssa.rb:84:10:86:8 | do ... end | +| ssa.rb:90:1:103:3 | m12 | From dff7b475fbcd1eef192382c437eeb8ce43b7b118 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 15 Nov 2022 11:46:44 +0100 Subject: [PATCH 191/796] make the top-level comment in SuperlinearBackTracking.qll a QLDoc --- shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll b/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll index 00f53784554..efe5beb3b4a 100644 --- a/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll +++ b/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll @@ -1,4 +1,4 @@ -/* +/** * This module implements the analysis described in the paper: * Valentin Wustholz, Oswaldo Olivo, Marijn J. H. Heule, and Isil Dillig: * Static Detection of DoS Vulnerabilities in From 8d9b106be1c437aff320246213de46a0be95c508 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 15 Nov 2022 11:19:40 +0000 Subject: [PATCH 192/796] Exclude invalid identifiers from generated stubs --- java/ql/src/utils/stub-generator/Stubs.qll | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/java/ql/src/utils/stub-generator/Stubs.qll b/java/ql/src/utils/stub-generator/Stubs.qll index 5c04dee0090..91e7835f4ba 100644 --- a/java/ql/src/utils/stub-generator/Stubs.qll +++ b/java/ql/src/utils/stub-generator/Stubs.qll @@ -7,12 +7,17 @@ import java +/** Holds if `id` is a valid Java identifier. */ +bindingset[id] +private predicate isValidIdentifier(string id) { id.regexpMatch("[\\w_$]+") } + /** A type that should be in the generated code. */ abstract private class GeneratedType extends ClassOrInterface { GeneratedType() { not this instanceof AnonymousClass and not this.isLocal() and - not this.getPackage() instanceof ExcludedPackage + not this.getPackage() instanceof ExcludedPackage and + isValidIdentifier(this.getName()) } private string stubKeyword() { @@ -108,7 +113,8 @@ abstract private class GeneratedType extends ClassOrInterface { not result.isPrivate() and not result.isPackageProtected() and not result instanceof StaticInitializer and - not result instanceof InstanceInitializer + not result instanceof InstanceInitializer and + isValidIdentifier(result.getName()) } final Type getAGeneratedType() { From 9b38e1102a7f2e2743c7b8cafe9a661ea18e8cdf Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 14 Nov 2022 17:31:29 +0000 Subject: [PATCH 193/796] Swift: Add more tests of optionals. --- .../dataflow/dataflow/DataFlow.expected | 123 +++++++++-------- .../dataflow/dataflow/LocalFlow.expected | 130 +++++++++++------- .../dataflow/dataflow/test.swift | 49 +++++-- 3 files changed, 182 insertions(+), 120 deletions(-) diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected index c4e0a7a01e6..0f55b0155c3 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected @@ -100,29 +100,30 @@ edges | test.swift:225:14:225:21 | call to source() : | test.swift:235:13:235:15 | .source_value | | test.swift:225:14:225:21 | call to source() : | test.swift:238:13:238:15 | .source_value | | test.swift:259:12:259:19 | call to source() : | test.swift:263:13:263:28 | call to optionalSource() : | -| test.swift:263:13:263:28 | call to optionalSource() : | test.swift:264:15:264:16 | ...! | -| test.swift:263:13:263:28 | call to optionalSource() : | test.swift:266:15:266:16 | ...? : | -| test.swift:265:15:265:22 | call to source() : | file://:0:0:0:0 | [summary param] this in signum() : | -| test.swift:265:15:265:22 | call to source() : | test.swift:265:15:265:31 | call to signum() | -| test.swift:266:15:266:16 | ...? : | file://:0:0:0:0 | [summary param] this in signum() : | -| test.swift:266:15:266:16 | ...? : | test.swift:266:15:266:25 | call to signum() : | -| test.swift:266:15:266:25 | call to signum() : | test.swift:266:15:266:25 | OptionalEvaluationExpr | -| test.swift:277:14:277:26 | (...) [Tuple element at index 1] : | test.swift:281:15:281:15 | t1 [Tuple element at index 1] : | -| test.swift:277:18:277:25 | call to source() : | test.swift:277:14:277:26 | (...) [Tuple element at index 1] : | -| test.swift:281:15:281:15 | t1 [Tuple element at index 1] : | test.swift:281:15:281:18 | .1 | -| test.swift:289:5:289:5 | [post] t1 [Tuple element at index 0] : | test.swift:292:15:292:15 | t1 [Tuple element at index 0] : | -| test.swift:289:12:289:19 | call to source() : | test.swift:289:5:289:5 | [post] t1 [Tuple element at index 0] : | -| test.swift:292:15:292:15 | t1 [Tuple element at index 0] : | test.swift:292:15:292:18 | .0 | -| test.swift:297:14:297:45 | (...) [Tuple element at index 0] : | test.swift:302:15:302:15 | t1 [Tuple element at index 0] : | -| test.swift:297:14:297:45 | (...) [Tuple element at index 0] : | test.swift:306:15:306:15 | t2 [Tuple element at index 0] : | -| test.swift:297:14:297:45 | (...) [Tuple element at index 1] : | test.swift:303:15:303:15 | t1 [Tuple element at index 1] : | -| test.swift:297:14:297:45 | (...) [Tuple element at index 1] : | test.swift:307:15:307:15 | t2 [Tuple element at index 1] : | -| test.swift:297:18:297:25 | call to source() : | test.swift:297:14:297:45 | (...) [Tuple element at index 0] : | -| test.swift:297:31:297:38 | call to source() : | test.swift:297:14:297:45 | (...) [Tuple element at index 1] : | -| test.swift:302:15:302:15 | t1 [Tuple element at index 0] : | test.swift:302:15:302:18 | .0 | -| test.swift:303:15:303:15 | t1 [Tuple element at index 1] : | test.swift:303:15:303:18 | .1 | -| test.swift:306:15:306:15 | t2 [Tuple element at index 0] : | test.swift:306:15:306:18 | .0 | -| test.swift:307:15:307:15 | t2 [Tuple element at index 1] : | test.swift:307:15:307:18 | .1 | +| test.swift:263:13:263:28 | call to optionalSource() : | test.swift:265:15:265:15 | x | +| test.swift:263:13:263:28 | call to optionalSource() : | test.swift:267:15:267:16 | ...! | +| test.swift:263:13:263:28 | call to optionalSource() : | test.swift:271:15:271:16 | ...? : | +| test.swift:270:15:270:22 | call to source() : | file://:0:0:0:0 | [summary param] this in signum() : | +| test.swift:270:15:270:22 | call to source() : | test.swift:270:15:270:31 | call to signum() | +| test.swift:271:15:271:16 | ...? : | file://:0:0:0:0 | [summary param] this in signum() : | +| test.swift:271:15:271:16 | ...? : | test.swift:271:15:271:25 | call to signum() : | +| test.swift:271:15:271:25 | call to signum() : | test.swift:271:15:271:25 | OptionalEvaluationExpr | +| test.swift:302:14:302:26 | (...) [Tuple element at index 1] : | test.swift:306:15:306:15 | t1 [Tuple element at index 1] : | +| test.swift:302:18:302:25 | call to source() : | test.swift:302:14:302:26 | (...) [Tuple element at index 1] : | +| test.swift:306:15:306:15 | t1 [Tuple element at index 1] : | test.swift:306:15:306:18 | .1 | +| test.swift:314:5:314:5 | [post] t1 [Tuple element at index 0] : | test.swift:317:15:317:15 | t1 [Tuple element at index 0] : | +| test.swift:314:12:314:19 | call to source() : | test.swift:314:5:314:5 | [post] t1 [Tuple element at index 0] : | +| test.swift:317:15:317:15 | t1 [Tuple element at index 0] : | test.swift:317:15:317:18 | .0 | +| test.swift:322:14:322:45 | (...) [Tuple element at index 0] : | test.swift:327:15:327:15 | t1 [Tuple element at index 0] : | +| test.swift:322:14:322:45 | (...) [Tuple element at index 0] : | test.swift:331:15:331:15 | t2 [Tuple element at index 0] : | +| test.swift:322:14:322:45 | (...) [Tuple element at index 1] : | test.swift:328:15:328:15 | t1 [Tuple element at index 1] : | +| test.swift:322:14:322:45 | (...) [Tuple element at index 1] : | test.swift:332:15:332:15 | t2 [Tuple element at index 1] : | +| test.swift:322:18:322:25 | call to source() : | test.swift:322:14:322:45 | (...) [Tuple element at index 0] : | +| test.swift:322:31:322:38 | call to source() : | test.swift:322:14:322:45 | (...) [Tuple element at index 1] : | +| test.swift:327:15:327:15 | t1 [Tuple element at index 0] : | test.swift:327:15:327:18 | .0 | +| test.swift:328:15:328:15 | t1 [Tuple element at index 1] : | test.swift:328:15:328:18 | .1 | +| test.swift:331:15:331:15 | t2 [Tuple element at index 0] : | test.swift:331:15:331:18 | .0 | +| test.swift:332:15:332:15 | t2 [Tuple element at index 1] : | test.swift:332:15:332:18 | .1 | nodes | file://:0:0:0:0 | .a [x] : | semmle.label | .a [x] : | | file://:0:0:0:0 | .x : | semmle.label | .x : | @@ -237,32 +238,33 @@ nodes | test.swift:238:13:238:15 | .source_value | semmle.label | .source_value | | test.swift:259:12:259:19 | call to source() : | semmle.label | call to source() : | | test.swift:263:13:263:28 | call to optionalSource() : | semmle.label | call to optionalSource() : | -| test.swift:264:15:264:16 | ...! | semmle.label | ...! | -| test.swift:265:15:265:22 | call to source() : | semmle.label | call to source() : | -| test.swift:265:15:265:31 | call to signum() | semmle.label | call to signum() | -| test.swift:266:15:266:16 | ...? : | semmle.label | ...? : | -| test.swift:266:15:266:25 | OptionalEvaluationExpr | semmle.label | OptionalEvaluationExpr | -| test.swift:266:15:266:25 | call to signum() : | semmle.label | call to signum() : | -| test.swift:277:14:277:26 | (...) [Tuple element at index 1] : | semmle.label | (...) [Tuple element at index 1] : | -| test.swift:277:18:277:25 | call to source() : | semmle.label | call to source() : | -| test.swift:281:15:281:15 | t1 [Tuple element at index 1] : | semmle.label | t1 [Tuple element at index 1] : | -| test.swift:281:15:281:18 | .1 | semmle.label | .1 | -| test.swift:289:5:289:5 | [post] t1 [Tuple element at index 0] : | semmle.label | [post] t1 [Tuple element at index 0] : | -| test.swift:289:12:289:19 | call to source() : | semmle.label | call to source() : | -| test.swift:292:15:292:15 | t1 [Tuple element at index 0] : | semmle.label | t1 [Tuple element at index 0] : | -| test.swift:292:15:292:18 | .0 | semmle.label | .0 | -| test.swift:297:14:297:45 | (...) [Tuple element at index 0] : | semmle.label | (...) [Tuple element at index 0] : | -| test.swift:297:14:297:45 | (...) [Tuple element at index 1] : | semmle.label | (...) [Tuple element at index 1] : | -| test.swift:297:18:297:25 | call to source() : | semmle.label | call to source() : | -| test.swift:297:31:297:38 | call to source() : | semmle.label | call to source() : | -| test.swift:302:15:302:15 | t1 [Tuple element at index 0] : | semmle.label | t1 [Tuple element at index 0] : | -| test.swift:302:15:302:18 | .0 | semmle.label | .0 | -| test.swift:303:15:303:15 | t1 [Tuple element at index 1] : | semmle.label | t1 [Tuple element at index 1] : | -| test.swift:303:15:303:18 | .1 | semmle.label | .1 | -| test.swift:306:15:306:15 | t2 [Tuple element at index 0] : | semmle.label | t2 [Tuple element at index 0] : | -| test.swift:306:15:306:18 | .0 | semmle.label | .0 | -| test.swift:307:15:307:15 | t2 [Tuple element at index 1] : | semmle.label | t2 [Tuple element at index 1] : | -| test.swift:307:15:307:18 | .1 | semmle.label | .1 | +| test.swift:265:15:265:15 | x | semmle.label | x | +| test.swift:267:15:267:16 | ...! | semmle.label | ...! | +| test.swift:270:15:270:22 | call to source() : | semmle.label | call to source() : | +| test.swift:270:15:270:31 | call to signum() | semmle.label | call to signum() | +| test.swift:271:15:271:16 | ...? : | semmle.label | ...? : | +| test.swift:271:15:271:25 | OptionalEvaluationExpr | semmle.label | OptionalEvaluationExpr | +| test.swift:271:15:271:25 | call to signum() : | semmle.label | call to signum() : | +| test.swift:302:14:302:26 | (...) [Tuple element at index 1] : | semmle.label | (...) [Tuple element at index 1] : | +| test.swift:302:18:302:25 | call to source() : | semmle.label | call to source() : | +| test.swift:306:15:306:15 | t1 [Tuple element at index 1] : | semmle.label | t1 [Tuple element at index 1] : | +| test.swift:306:15:306:18 | .1 | semmle.label | .1 | +| test.swift:314:5:314:5 | [post] t1 [Tuple element at index 0] : | semmle.label | [post] t1 [Tuple element at index 0] : | +| test.swift:314:12:314:19 | call to source() : | semmle.label | call to source() : | +| test.swift:317:15:317:15 | t1 [Tuple element at index 0] : | semmle.label | t1 [Tuple element at index 0] : | +| test.swift:317:15:317:18 | .0 | semmle.label | .0 | +| test.swift:322:14:322:45 | (...) [Tuple element at index 0] : | semmle.label | (...) [Tuple element at index 0] : | +| test.swift:322:14:322:45 | (...) [Tuple element at index 1] : | semmle.label | (...) [Tuple element at index 1] : | +| test.swift:322:18:322:25 | call to source() : | semmle.label | call to source() : | +| test.swift:322:31:322:38 | call to source() : | semmle.label | call to source() : | +| test.swift:327:15:327:15 | t1 [Tuple element at index 0] : | semmle.label | t1 [Tuple element at index 0] : | +| test.swift:327:15:327:18 | .0 | semmle.label | .0 | +| test.swift:328:15:328:15 | t1 [Tuple element at index 1] : | semmle.label | t1 [Tuple element at index 1] : | +| test.swift:328:15:328:18 | .1 | semmle.label | .1 | +| test.swift:331:15:331:15 | t2 [Tuple element at index 0] : | semmle.label | t2 [Tuple element at index 0] : | +| test.swift:331:15:331:18 | .0 | semmle.label | .0 | +| test.swift:332:15:332:15 | t2 [Tuple element at index 1] : | semmle.label | t2 [Tuple element at index 1] : | +| test.swift:332:15:332:18 | .1 | semmle.label | .1 | subpaths | test.swift:75:21:75:22 | &... : | test.swift:65:16:65:28 | arg1 : | test.swift:65:1:70:1 | arg2[return] : | test.swift:75:31:75:32 | [post] &... : | | test.swift:114:19:114:19 | arg : | test.swift:109:9:109:14 | arg : | test.swift:110:12:110:12 | arg : | test.swift:114:12:114:22 | call to ... : | @@ -289,8 +291,8 @@ subpaths | test.swift:218:11:218:18 | call to source() : | test.swift:169:12:169:22 | value : | test.swift:170:5:170:5 | [post] self [x] : | test.swift:218:3:218:5 | [post] getter for .a [x] : | | test.swift:219:13:219:13 | b [a, x] : | test.swift:185:7:185:7 | self [a, x] : | file://:0:0:0:0 | .a [x] : | test.swift:219:13:219:15 | .a [x] : | | test.swift:219:13:219:15 | .a [x] : | test.swift:163:7:163:7 | self [x] : | file://:0:0:0:0 | .x : | test.swift:219:13:219:17 | .x | -| test.swift:265:15:265:22 | call to source() : | file://:0:0:0:0 | [summary param] this in signum() : | file://:0:0:0:0 | [summary] to write: return (return) in signum() : | test.swift:265:15:265:31 | call to signum() | -| test.swift:266:15:266:16 | ...? : | file://:0:0:0:0 | [summary param] this in signum() : | file://:0:0:0:0 | [summary] to write: return (return) in signum() : | test.swift:266:15:266:25 | call to signum() : | +| test.swift:270:15:270:22 | call to source() : | file://:0:0:0:0 | [summary param] this in signum() : | file://:0:0:0:0 | [summary] to write: return (return) in signum() : | test.swift:270:15:270:31 | call to signum() | +| test.swift:271:15:271:16 | ...? : | file://:0:0:0:0 | [summary param] this in signum() : | file://:0:0:0:0 | [summary] to write: return (return) in signum() : | test.swift:271:15:271:25 | call to signum() : | #select | test.swift:7:15:7:15 | t1 | test.swift:6:19:6:26 | call to source() : | test.swift:7:15:7:15 | t1 | result | | test.swift:9:15:9:15 | t1 | test.swift:6:19:6:26 | call to source() : | test.swift:9:15:9:15 | t1 | result | @@ -320,12 +322,13 @@ subpaths | test.swift:219:13:219:17 | .x | test.swift:218:11:218:18 | call to source() : | test.swift:219:13:219:17 | .x | result | | test.swift:235:13:235:15 | .source_value | test.swift:225:14:225:21 | call to source() : | test.swift:235:13:235:15 | .source_value | result | | test.swift:238:13:238:15 | .source_value | test.swift:225:14:225:21 | call to source() : | test.swift:238:13:238:15 | .source_value | result | -| test.swift:264:15:264:16 | ...! | test.swift:259:12:259:19 | call to source() : | test.swift:264:15:264:16 | ...! | result | -| test.swift:265:15:265:31 | call to signum() | test.swift:265:15:265:22 | call to source() : | test.swift:265:15:265:31 | call to signum() | result | -| test.swift:266:15:266:25 | OptionalEvaluationExpr | test.swift:259:12:259:19 | call to source() : | test.swift:266:15:266:25 | OptionalEvaluationExpr | result | -| test.swift:281:15:281:18 | .1 | test.swift:277:18:277:25 | call to source() : | test.swift:281:15:281:18 | .1 | result | -| test.swift:292:15:292:18 | .0 | test.swift:289:12:289:19 | call to source() : | test.swift:292:15:292:18 | .0 | result | -| test.swift:302:15:302:18 | .0 | test.swift:297:18:297:25 | call to source() : | test.swift:302:15:302:18 | .0 | result | -| test.swift:303:15:303:18 | .1 | test.swift:297:31:297:38 | call to source() : | test.swift:303:15:303:18 | .1 | result | -| test.swift:306:15:306:18 | .0 | test.swift:297:18:297:25 | call to source() : | test.swift:306:15:306:18 | .0 | result | -| test.swift:307:15:307:18 | .1 | test.swift:297:31:297:38 | call to source() : | test.swift:307:15:307:18 | .1 | result | +| test.swift:265:15:265:15 | x | test.swift:259:12:259:19 | call to source() : | test.swift:265:15:265:15 | x | result | +| test.swift:267:15:267:16 | ...! | test.swift:259:12:259:19 | call to source() : | test.swift:267:15:267:16 | ...! | result | +| test.swift:270:15:270:31 | call to signum() | test.swift:270:15:270:22 | call to source() : | test.swift:270:15:270:31 | call to signum() | result | +| test.swift:271:15:271:25 | OptionalEvaluationExpr | test.swift:259:12:259:19 | call to source() : | test.swift:271:15:271:25 | OptionalEvaluationExpr | result | +| test.swift:306:15:306:18 | .1 | test.swift:302:18:302:25 | call to source() : | test.swift:306:15:306:18 | .1 | result | +| test.swift:317:15:317:18 | .0 | test.swift:314:12:314:19 | call to source() : | test.swift:317:15:317:18 | .0 | result | +| test.swift:327:15:327:18 | .0 | test.swift:322:18:322:25 | call to source() : | test.swift:327:15:327:18 | .0 | result | +| test.swift:328:15:328:18 | .1 | test.swift:322:31:322:38 | call to source() : | test.swift:328:15:328:18 | .1 | result | +| test.swift:331:15:331:18 | .0 | test.swift:322:18:322:25 | call to source() : | test.swift:331:15:331:18 | .0 | result | +| test.swift:332:15:332:18 | .1 | test.swift:322:31:322:38 | call to source() : | test.swift:332:15:332:18 | .1 | result | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected index 987d7073b87..91709720aa2 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected @@ -184,52 +184,86 @@ | test.swift:247:9:247:9 | [post] self | test.swift:246:5:248:5 | self[return] | | test.swift:247:9:247:9 | self | test.swift:246:5:248:5 | self[return] | | test.swift:252:23:252:23 | value | test.swift:252:23:252:23 | WriteDef | -| test.swift:263:9:263:9 | WriteDef | test.swift:264:15:264:15 | x | +| test.swift:262:21:262:27 | WriteDef | test.swift:266:15:266:15 | y | +| test.swift:262:21:262:27 | y | test.swift:262:21:262:27 | WriteDef | +| test.swift:263:9:263:9 | WriteDef | test.swift:265:15:265:15 | x | | test.swift:263:13:263:28 | call to optionalSource() | test.swift:263:9:263:9 | WriteDef | -| test.swift:264:15:264:15 | x | test.swift:264:15:264:16 | ...! | -| test.swift:264:15:264:15 | x | test.swift:266:15:266:15 | x | -| test.swift:266:15:266:15 | x | test.swift:266:15:266:16 | ...? | -| test.swift:266:15:266:15 | x | test.swift:267:15:267:15 | x | -| test.swift:266:15:266:25 | call to signum() | test.swift:266:15:266:25 | OptionalEvaluationExpr | -| test.swift:267:15:267:15 | x | test.swift:268:16:268:16 | x | -| test.swift:277:9:277:9 | WriteDef | test.swift:279:15:279:15 | t1 | -| test.swift:277:14:277:26 | (...) | test.swift:277:9:277:9 | WriteDef | -| test.swift:279:15:279:15 | t1 | test.swift:280:15:280:15 | t1 | -| test.swift:280:15:280:15 | [post] t1 | test.swift:281:15:281:15 | t1 | -| test.swift:280:15:280:15 | t1 | test.swift:281:15:281:15 | t1 | -| test.swift:281:15:281:15 | [post] t1 | test.swift:283:5:283:5 | t1 | -| test.swift:281:15:281:15 | t1 | test.swift:283:5:283:5 | t1 | -| test.swift:283:5:283:5 | [post] t1 | test.swift:285:15:285:15 | t1 | -| test.swift:283:5:283:5 | t1 | test.swift:285:15:285:15 | t1 | -| test.swift:285:15:285:15 | t1 | test.swift:286:15:286:15 | t1 | -| test.swift:286:15:286:15 | [post] t1 | test.swift:287:15:287:15 | t1 | -| test.swift:286:15:286:15 | t1 | test.swift:287:15:287:15 | t1 | -| test.swift:287:15:287:15 | [post] t1 | test.swift:289:5:289:5 | t1 | -| test.swift:287:15:287:15 | t1 | test.swift:289:5:289:5 | t1 | -| test.swift:289:5:289:5 | [post] t1 | test.swift:291:15:291:15 | t1 | -| test.swift:289:5:289:5 | t1 | test.swift:291:15:291:15 | t1 | -| test.swift:291:15:291:15 | t1 | test.swift:292:15:292:15 | t1 | -| test.swift:292:15:292:15 | [post] t1 | test.swift:293:15:293:15 | t1 | -| test.swift:292:15:292:15 | t1 | test.swift:293:15:293:15 | t1 | -| test.swift:297:9:297:9 | WriteDef | test.swift:298:14:298:14 | t1 | -| test.swift:297:14:297:45 | (...) | test.swift:297:9:297:9 | WriteDef | -| test.swift:298:9:298:9 | WriteDef | test.swift:305:15:305:15 | t2 | -| test.swift:298:14:298:14 | t1 | test.swift:298:9:298:9 | WriteDef | -| test.swift:298:14:298:14 | t1 | test.swift:299:21:299:21 | t1 | -| test.swift:299:9:299:17 | WriteDef | test.swift:309:15:309:15 | a | -| test.swift:299:9:299:17 | WriteDef | test.swift:310:15:310:15 | b | -| test.swift:299:9:299:17 | WriteDef | test.swift:311:15:311:15 | c | -| test.swift:299:21:299:21 | t1 | test.swift:299:9:299:17 | WriteDef | -| test.swift:299:21:299:21 | t1 | test.swift:299:9:299:17 | WriteDef | -| test.swift:299:21:299:21 | t1 | test.swift:299:9:299:17 | WriteDef | -| test.swift:299:21:299:21 | t1 | test.swift:301:15:301:15 | t1 | -| test.swift:301:15:301:15 | t1 | test.swift:302:15:302:15 | t1 | -| test.swift:302:15:302:15 | [post] t1 | test.swift:303:15:303:15 | t1 | -| test.swift:302:15:302:15 | t1 | test.swift:303:15:303:15 | t1 | -| test.swift:303:15:303:15 | [post] t1 | test.swift:304:15:304:15 | t1 | -| test.swift:303:15:303:15 | t1 | test.swift:304:15:304:15 | t1 | -| test.swift:305:15:305:15 | t2 | test.swift:306:15:306:15 | t2 | -| test.swift:306:15:306:15 | [post] t2 | test.swift:307:15:307:15 | t2 | -| test.swift:306:15:306:15 | t2 | test.swift:307:15:307:15 | t2 | -| test.swift:307:15:307:15 | [post] t2 | test.swift:308:15:308:15 | t2 | -| test.swift:307:15:307:15 | t2 | test.swift:308:15:308:15 | t2 | +| test.swift:265:15:265:15 | x | test.swift:267:15:267:15 | x | +| test.swift:266:15:266:15 | y | test.swift:268:15:268:15 | y | +| test.swift:267:15:267:15 | x | test.swift:267:15:267:16 | ...! | +| test.swift:267:15:267:15 | x | test.swift:271:15:271:15 | x | +| test.swift:268:15:268:15 | y | test.swift:268:15:268:16 | ...! | +| test.swift:268:15:268:15 | y | test.swift:272:15:272:15 | y | +| test.swift:271:15:271:15 | x | test.swift:271:15:271:16 | ...? | +| test.swift:271:15:271:15 | x | test.swift:274:15:274:15 | x | +| test.swift:271:15:271:25 | call to signum() | test.swift:271:15:271:25 | OptionalEvaluationExpr | +| test.swift:272:15:272:15 | y | test.swift:272:15:272:16 | ...? | +| test.swift:272:15:272:15 | y | test.swift:276:15:276:15 | y | +| test.swift:272:15:272:25 | call to signum() | test.swift:272:15:272:25 | OptionalEvaluationExpr | +| test.swift:274:15:274:15 | x | test.swift:275:15:275:15 | x | +| test.swift:275:15:275:15 | x | test.swift:279:15:279:15 | x | +| test.swift:276:15:276:15 | y | test.swift:277:15:277:15 | y | +| test.swift:277:15:277:15 | y | test.swift:281:15:281:15 | y | +| test.swift:279:15:279:15 | x | test.swift:279:26:279:26 | x | +| test.swift:279:15:279:15 | x | test.swift:280:15:280:15 | x | +| test.swift:279:26:279:26 | x | test.swift:279:26:279:27 | ...! | +| test.swift:279:26:279:26 | x | test.swift:280:15:280:15 | x | +| test.swift:280:15:280:15 | x | test.swift:280:26:280:26 | x | +| test.swift:280:15:280:15 | x | test.swift:284:16:284:16 | x | +| test.swift:280:26:280:26 | x | test.swift:280:26:280:27 | ...! | +| test.swift:280:26:280:26 | x | test.swift:284:16:284:16 | x | +| test.swift:281:15:281:15 | y | test.swift:281:26:281:26 | y | +| test.swift:281:15:281:15 | y | test.swift:282:15:282:15 | y | +| test.swift:281:26:281:26 | y | test.swift:281:26:281:27 | ...! | +| test.swift:281:26:281:26 | y | test.swift:282:15:282:15 | y | +| test.swift:282:15:282:15 | y | test.swift:282:26:282:26 | y | +| test.swift:282:15:282:15 | y | test.swift:287:16:287:16 | y | +| test.swift:282:26:282:26 | y | test.swift:282:26:282:27 | ...! | +| test.swift:282:26:282:26 | y | test.swift:287:16:287:16 | y | +| test.swift:284:16:284:16 | x | test.swift:290:16:290:16 | x | +| test.swift:287:16:287:16 | y | test.swift:293:16:293:16 | y | +| test.swift:290:16:290:16 | x | test.swift:290:16:290:17 | ...? | +| test.swift:290:16:290:26 | call to signum() | test.swift:290:16:290:26 | OptionalEvaluationExpr | +| test.swift:293:16:293:16 | y | test.swift:293:16:293:17 | ...? | +| test.swift:293:16:293:26 | call to signum() | test.swift:293:16:293:26 | OptionalEvaluationExpr | +| test.swift:304:9:304:9 | WriteDef | test.swift:306:15:306:15 | t1 | +| test.swift:304:14:304:26 | (...) | test.swift:304:9:304:9 | WriteDef | +| test.swift:306:15:306:15 | t1 | test.swift:307:15:307:15 | t1 | +| test.swift:307:15:307:15 | [post] t1 | test.swift:308:15:308:15 | t1 | +| test.swift:307:15:307:15 | t1 | test.swift:308:15:308:15 | t1 | +| test.swift:308:15:308:15 | [post] t1 | test.swift:310:5:310:5 | t1 | +| test.swift:308:15:308:15 | t1 | test.swift:310:5:310:5 | t1 | +| test.swift:310:5:310:5 | [post] t1 | test.swift:312:15:312:15 | t1 | +| test.swift:310:5:310:5 | t1 | test.swift:312:15:312:15 | t1 | +| test.swift:312:15:312:15 | t1 | test.swift:313:15:313:15 | t1 | +| test.swift:313:15:313:15 | [post] t1 | test.swift:314:15:314:15 | t1 | +| test.swift:313:15:313:15 | t1 | test.swift:314:15:314:15 | t1 | +| test.swift:314:15:314:15 | [post] t1 | test.swift:316:5:316:5 | t1 | +| test.swift:314:15:314:15 | t1 | test.swift:316:5:316:5 | t1 | +| test.swift:316:5:316:5 | [post] t1 | test.swift:318:15:318:15 | t1 | +| test.swift:316:5:316:5 | t1 | test.swift:318:15:318:15 | t1 | +| test.swift:318:15:318:15 | t1 | test.swift:319:15:319:15 | t1 | +| test.swift:319:15:319:15 | [post] t1 | test.swift:320:15:320:15 | t1 | +| test.swift:319:15:319:15 | t1 | test.swift:320:15:320:15 | t1 | +| test.swift:324:9:324:9 | WriteDef | test.swift:325:14:325:14 | t1 | +| test.swift:324:14:324:45 | (...) | test.swift:324:9:324:9 | WriteDef | +| test.swift:325:9:325:9 | WriteDef | test.swift:332:15:332:15 | t2 | +| test.swift:325:14:325:14 | t1 | test.swift:325:9:325:9 | WriteDef | +| test.swift:325:14:325:14 | t1 | test.swift:326:21:326:21 | t1 | +| test.swift:326:9:326:17 | WriteDef | test.swift:336:15:336:15 | a | +| test.swift:326:9:326:17 | WriteDef | test.swift:337:15:337:15 | b | +| test.swift:326:9:326:17 | WriteDef | test.swift:338:15:338:15 | c | +| test.swift:326:21:326:21 | t1 | test.swift:326:9:326:17 | WriteDef | +| test.swift:326:21:326:21 | t1 | test.swift:326:9:326:17 | WriteDef | +| test.swift:326:21:326:21 | t1 | test.swift:326:9:326:17 | WriteDef | +| test.swift:326:21:326:21 | t1 | test.swift:328:15:328:15 | t1 | +| test.swift:328:15:328:15 | t1 | test.swift:329:15:329:15 | t1 | +| test.swift:329:15:329:15 | [post] t1 | test.swift:330:15:330:15 | t1 | +| test.swift:329:15:329:15 | t1 | test.swift:330:15:330:15 | t1 | +| test.swift:330:15:330:15 | [post] t1 | test.swift:331:15:331:15 | t1 | +| test.swift:330:15:330:15 | t1 | test.swift:331:15:331:15 | t1 | +| test.swift:332:15:332:15 | t2 | test.swift:333:15:333:15 | t2 | +| test.swift:333:15:333:15 | [post] t2 | test.swift:334:15:334:15 | t2 | +| test.swift:333:15:333:15 | t2 | test.swift:334:15:334:15 | t2 | +| test.swift:334:15:334:15 | [post] t2 | test.swift:335:15:335:15 | t2 | +| test.swift:334:15:334:15 | t2 | test.swift:335:15:335:15 | t2 | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/test.swift b/swift/ql/test/library-tests/dataflow/dataflow/test.swift index 23c8d138a2d..6995754e85c 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/test.swift +++ b/swift/ql/test/library-tests/dataflow/dataflow/test.swift @@ -259,14 +259,39 @@ func optionalSource() -> Int? { return source() } -func test_optionals() { +func test_optionals(y: Int?) { let x = optionalSource() + + sink(opt: x) // $ flow=259 + sink(opt: y) sink(arg: x!) // $ flow=259 - sink(arg: source().signum()) // $ flow=265 + sink(arg: y!) + + sink(arg: source().signum()) // $ flow=270 sink(opt: x?.signum()) // $ flow=259 + sink(opt: y?.signum()) + sink(arg: x ?? 0) // $ MISSING: flow=259 - if let y = x { - sink(arg: y) // $ MISSING: flow=259 + sink(arg: x ?? source()) // $ MISSING: flow=259, 276 + sink(arg: y ?? 0) + sink(arg: y ?? source()) // $ MISSING: flow=278 + + sink(arg: x != nil ? x! : 0) // $ MISSING: flow=259 + sink(arg: x != nil ? x! : source()) // $ MISSING: flow=259, 281 + sink(arg: y != nil ? y! : 0) + sink(arg: y != nil ? y! : source()) // $ MISSING: flow=283 + + if let z = x { + sink(arg: z) // $ MISSING: flow=259 + } + if let z = y { + sink(arg: z) + } + if let z = x?.signum() { // $ MISSING: flow=259 + sink(arg: z) + } + if let z = y?.signum() { + sink(arg: z) } } @@ -278,7 +303,7 @@ func testTuples() { sink(arg: t1) sink(arg: t1.0) - sink(arg: t1.1) // $ flow=277 + sink(arg: t1.1) // $ flow=302 t1.1 = 2 @@ -289,7 +314,7 @@ func testTuples() { t1.0 = source() sink(arg: t1) - sink(arg: t1.0) // $ flow=289 + sink(arg: t1.0) // $ flow=314 sink(arg: t1.1) } @@ -299,14 +324,14 @@ func testTuples2() { let (a, b, c) = t1 sink(arg: t1) - sink(arg: t1.x) // $ flow=297 - sink(arg: t1.y) // $ flow=297 + sink(arg: t1.x) // $ flow=322 + sink(arg: t1.y) // $ flow=322 sink(arg: t1.z) sink(arg: t2) - sink(arg: t2.x) // $ flow=297 - sink(arg: t2.y) // $ flow=297 + sink(arg: t2.x) // $ flow=322 + sink(arg: t2.y) // $ flow=322 sink(arg: t2.z) - sink(arg: a) // $ MISSING: flow=297 - sink(arg: b) // $ MISSING: flow=297 + sink(arg: a) // $ MISSING: flow=322 + sink(arg: b) // $ MISSING: flow=322 sink(arg: c) } From 2dbb8919424978a588ed69c1828f8a5ade13d459 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 14 Nov 2022 18:29:35 +0000 Subject: [PATCH 194/796] Swift: Dataflow through ??. --- .../dataflow/internal/DataFlowPrivate.qll | 7 ++ .../dataflow/dataflow/DataFlow.expected | 6 ++ .../dataflow/dataflow/LocalFlow.expected | 86 ++++++++++--------- .../dataflow/dataflow/test.swift | 4 +- 4 files changed, 62 insertions(+), 41 deletions(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 82332b4c47d..f811a540c97 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -153,6 +153,13 @@ private module Cached { or nodeFrom.asExpr() = nodeTo.asExpr().(OptionalEvaluationExpr).getSubExpr() or + // flow through nil-coalescing operator `??` + exists(BinaryExpr nco | + nco.getFunction().(DeclRefExpr).getDecl().(FreeFunctionDecl).getName() = "??(_:_:)" and + nodeFrom.asExpr() = nco.getAnOperand() and + nodeTo.asExpr() = nco + ) + or // flow through a flow summary (extension of `SummaryModelCsv`) FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true) } diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected index 0f55b0155c3..8c9c931a4ff 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected @@ -103,6 +103,8 @@ edges | test.swift:263:13:263:28 | call to optionalSource() : | test.swift:265:15:265:15 | x | | test.swift:263:13:263:28 | call to optionalSource() : | test.swift:267:15:267:16 | ...! | | test.swift:263:13:263:28 | call to optionalSource() : | test.swift:271:15:271:16 | ...? : | +| test.swift:263:13:263:28 | call to optionalSource() : | test.swift:274:15:274:20 | ... ??(_:_:) ... | +| test.swift:263:13:263:28 | call to optionalSource() : | test.swift:275:15:275:27 | ... ??(_:_:) ... | | test.swift:270:15:270:22 | call to source() : | file://:0:0:0:0 | [summary param] this in signum() : | | test.swift:270:15:270:22 | call to source() : | test.swift:270:15:270:31 | call to signum() | | test.swift:271:15:271:16 | ...? : | file://:0:0:0:0 | [summary param] this in signum() : | @@ -245,6 +247,8 @@ nodes | test.swift:271:15:271:16 | ...? : | semmle.label | ...? : | | test.swift:271:15:271:25 | OptionalEvaluationExpr | semmle.label | OptionalEvaluationExpr | | test.swift:271:15:271:25 | call to signum() : | semmle.label | call to signum() : | +| test.swift:274:15:274:20 | ... ??(_:_:) ... | semmle.label | ... ??(_:_:) ... | +| test.swift:275:15:275:27 | ... ??(_:_:) ... | semmle.label | ... ??(_:_:) ... | | test.swift:302:14:302:26 | (...) [Tuple element at index 1] : | semmle.label | (...) [Tuple element at index 1] : | | test.swift:302:18:302:25 | call to source() : | semmle.label | call to source() : | | test.swift:306:15:306:15 | t1 [Tuple element at index 1] : | semmle.label | t1 [Tuple element at index 1] : | @@ -326,6 +330,8 @@ subpaths | test.swift:267:15:267:16 | ...! | test.swift:259:12:259:19 | call to source() : | test.swift:267:15:267:16 | ...! | result | | test.swift:270:15:270:31 | call to signum() | test.swift:270:15:270:22 | call to source() : | test.swift:270:15:270:31 | call to signum() | result | | test.swift:271:15:271:25 | OptionalEvaluationExpr | test.swift:259:12:259:19 | call to source() : | test.swift:271:15:271:25 | OptionalEvaluationExpr | result | +| test.swift:274:15:274:20 | ... ??(_:_:) ... | test.swift:259:12:259:19 | call to source() : | test.swift:274:15:274:20 | ... ??(_:_:) ... | result | +| test.swift:275:15:275:27 | ... ??(_:_:) ... | test.swift:259:12:259:19 | call to source() : | test.swift:275:15:275:27 | ... ??(_:_:) ... | result | | test.swift:306:15:306:18 | .1 | test.swift:302:18:302:25 | call to source() : | test.swift:306:15:306:18 | .1 | result | | test.swift:317:15:317:18 | .0 | test.swift:314:12:314:19 | call to source() : | test.swift:317:15:317:18 | .0 | result | | test.swift:327:15:327:18 | .0 | test.swift:322:18:322:25 | call to source() : | test.swift:327:15:327:18 | .0 | result | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected index 91709720aa2..0d48a6af63f 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected @@ -200,10 +200,18 @@ | test.swift:272:15:272:15 | y | test.swift:272:15:272:16 | ...? | | test.swift:272:15:272:15 | y | test.swift:276:15:276:15 | y | | test.swift:272:15:272:25 | call to signum() | test.swift:272:15:272:25 | OptionalEvaluationExpr | +| test.swift:274:15:274:15 | x | test.swift:274:15:274:20 | ... ??(_:_:) ... | | test.swift:274:15:274:15 | x | test.swift:275:15:275:15 | x | +| test.swift:274:20:274:20 | { ... } | test.swift:274:15:274:20 | ... ??(_:_:) ... | +| test.swift:275:15:275:15 | x | test.swift:275:15:275:27 | ... ??(_:_:) ... | | test.swift:275:15:275:15 | x | test.swift:279:15:279:15 | x | +| test.swift:275:20:275:27 | { ... } | test.swift:275:15:275:27 | ... ??(_:_:) ... | +| test.swift:276:15:276:15 | y | test.swift:276:15:276:20 | ... ??(_:_:) ... | | test.swift:276:15:276:15 | y | test.swift:277:15:277:15 | y | +| test.swift:276:20:276:20 | { ... } | test.swift:276:15:276:20 | ... ??(_:_:) ... | +| test.swift:277:15:277:15 | y | test.swift:277:15:277:27 | ... ??(_:_:) ... | | test.swift:277:15:277:15 | y | test.swift:281:15:281:15 | y | +| test.swift:277:20:277:27 | { ... } | test.swift:277:15:277:27 | ... ??(_:_:) ... | | test.swift:279:15:279:15 | x | test.swift:279:26:279:26 | x | | test.swift:279:15:279:15 | x | test.swift:280:15:280:15 | x | | test.swift:279:26:279:26 | x | test.swift:279:26:279:27 | ...! | @@ -226,44 +234,44 @@ | test.swift:290:16:290:26 | call to signum() | test.swift:290:16:290:26 | OptionalEvaluationExpr | | test.swift:293:16:293:16 | y | test.swift:293:16:293:17 | ...? | | test.swift:293:16:293:26 | call to signum() | test.swift:293:16:293:26 | OptionalEvaluationExpr | -| test.swift:304:9:304:9 | WriteDef | test.swift:306:15:306:15 | t1 | -| test.swift:304:14:304:26 | (...) | test.swift:304:9:304:9 | WriteDef | -| test.swift:306:15:306:15 | t1 | test.swift:307:15:307:15 | t1 | -| test.swift:307:15:307:15 | [post] t1 | test.swift:308:15:308:15 | t1 | -| test.swift:307:15:307:15 | t1 | test.swift:308:15:308:15 | t1 | -| test.swift:308:15:308:15 | [post] t1 | test.swift:310:5:310:5 | t1 | -| test.swift:308:15:308:15 | t1 | test.swift:310:5:310:5 | t1 | -| test.swift:310:5:310:5 | [post] t1 | test.swift:312:15:312:15 | t1 | -| test.swift:310:5:310:5 | t1 | test.swift:312:15:312:15 | t1 | -| test.swift:312:15:312:15 | t1 | test.swift:313:15:313:15 | t1 | -| test.swift:313:15:313:15 | [post] t1 | test.swift:314:15:314:15 | t1 | -| test.swift:313:15:313:15 | t1 | test.swift:314:15:314:15 | t1 | -| test.swift:314:15:314:15 | [post] t1 | test.swift:316:5:316:5 | t1 | -| test.swift:314:15:314:15 | t1 | test.swift:316:5:316:5 | t1 | -| test.swift:316:5:316:5 | [post] t1 | test.swift:318:15:318:15 | t1 | -| test.swift:316:5:316:5 | t1 | test.swift:318:15:318:15 | t1 | -| test.swift:318:15:318:15 | t1 | test.swift:319:15:319:15 | t1 | -| test.swift:319:15:319:15 | [post] t1 | test.swift:320:15:320:15 | t1 | -| test.swift:319:15:319:15 | t1 | test.swift:320:15:320:15 | t1 | -| test.swift:324:9:324:9 | WriteDef | test.swift:325:14:325:14 | t1 | -| test.swift:324:14:324:45 | (...) | test.swift:324:9:324:9 | WriteDef | -| test.swift:325:9:325:9 | WriteDef | test.swift:332:15:332:15 | t2 | -| test.swift:325:14:325:14 | t1 | test.swift:325:9:325:9 | WriteDef | -| test.swift:325:14:325:14 | t1 | test.swift:326:21:326:21 | t1 | -| test.swift:326:9:326:17 | WriteDef | test.swift:336:15:336:15 | a | -| test.swift:326:9:326:17 | WriteDef | test.swift:337:15:337:15 | b | -| test.swift:326:9:326:17 | WriteDef | test.swift:338:15:338:15 | c | -| test.swift:326:21:326:21 | t1 | test.swift:326:9:326:17 | WriteDef | -| test.swift:326:21:326:21 | t1 | test.swift:326:9:326:17 | WriteDef | -| test.swift:326:21:326:21 | t1 | test.swift:326:9:326:17 | WriteDef | -| test.swift:326:21:326:21 | t1 | test.swift:328:15:328:15 | t1 | +| test.swift:302:9:302:9 | WriteDef | test.swift:304:15:304:15 | t1 | +| test.swift:302:14:302:26 | (...) | test.swift:302:9:302:9 | WriteDef | +| test.swift:304:15:304:15 | t1 | test.swift:305:15:305:15 | t1 | +| test.swift:305:15:305:15 | [post] t1 | test.swift:306:15:306:15 | t1 | +| test.swift:305:15:305:15 | t1 | test.swift:306:15:306:15 | t1 | +| test.swift:306:15:306:15 | [post] t1 | test.swift:308:5:308:5 | t1 | +| test.swift:306:15:306:15 | t1 | test.swift:308:5:308:5 | t1 | +| test.swift:308:5:308:5 | [post] t1 | test.swift:310:15:310:15 | t1 | +| test.swift:308:5:308:5 | t1 | test.swift:310:15:310:15 | t1 | +| test.swift:310:15:310:15 | t1 | test.swift:311:15:311:15 | t1 | +| test.swift:311:15:311:15 | [post] t1 | test.swift:312:15:312:15 | t1 | +| test.swift:311:15:311:15 | t1 | test.swift:312:15:312:15 | t1 | +| test.swift:312:15:312:15 | [post] t1 | test.swift:314:5:314:5 | t1 | +| test.swift:312:15:312:15 | t1 | test.swift:314:5:314:5 | t1 | +| test.swift:314:5:314:5 | [post] t1 | test.swift:316:15:316:15 | t1 | +| test.swift:314:5:314:5 | t1 | test.swift:316:15:316:15 | t1 | +| test.swift:316:15:316:15 | t1 | test.swift:317:15:317:15 | t1 | +| test.swift:317:15:317:15 | [post] t1 | test.swift:318:15:318:15 | t1 | +| test.swift:317:15:317:15 | t1 | test.swift:318:15:318:15 | t1 | +| test.swift:322:9:322:9 | WriteDef | test.swift:323:14:323:14 | t1 | +| test.swift:322:14:322:45 | (...) | test.swift:322:9:322:9 | WriteDef | +| test.swift:323:9:323:9 | WriteDef | test.swift:330:15:330:15 | t2 | +| test.swift:323:14:323:14 | t1 | test.swift:323:9:323:9 | WriteDef | +| test.swift:323:14:323:14 | t1 | test.swift:324:21:324:21 | t1 | +| test.swift:324:9:324:17 | WriteDef | test.swift:334:15:334:15 | a | +| test.swift:324:9:324:17 | WriteDef | test.swift:335:15:335:15 | b | +| test.swift:324:9:324:17 | WriteDef | test.swift:336:15:336:15 | c | +| test.swift:324:21:324:21 | t1 | test.swift:324:9:324:17 | WriteDef | +| test.swift:324:21:324:21 | t1 | test.swift:324:9:324:17 | WriteDef | +| test.swift:324:21:324:21 | t1 | test.swift:324:9:324:17 | WriteDef | +| test.swift:324:21:324:21 | t1 | test.swift:326:15:326:15 | t1 | +| test.swift:326:15:326:15 | t1 | test.swift:327:15:327:15 | t1 | +| test.swift:327:15:327:15 | [post] t1 | test.swift:328:15:328:15 | t1 | +| test.swift:327:15:327:15 | t1 | test.swift:328:15:328:15 | t1 | +| test.swift:328:15:328:15 | [post] t1 | test.swift:329:15:329:15 | t1 | | test.swift:328:15:328:15 | t1 | test.swift:329:15:329:15 | t1 | -| test.swift:329:15:329:15 | [post] t1 | test.swift:330:15:330:15 | t1 | -| test.swift:329:15:329:15 | t1 | test.swift:330:15:330:15 | t1 | -| test.swift:330:15:330:15 | [post] t1 | test.swift:331:15:331:15 | t1 | -| test.swift:330:15:330:15 | t1 | test.swift:331:15:331:15 | t1 | +| test.swift:330:15:330:15 | t2 | test.swift:331:15:331:15 | t2 | +| test.swift:331:15:331:15 | [post] t2 | test.swift:332:15:332:15 | t2 | +| test.swift:331:15:331:15 | t2 | test.swift:332:15:332:15 | t2 | +| test.swift:332:15:332:15 | [post] t2 | test.swift:333:15:333:15 | t2 | | test.swift:332:15:332:15 | t2 | test.swift:333:15:333:15 | t2 | -| test.swift:333:15:333:15 | [post] t2 | test.swift:334:15:334:15 | t2 | -| test.swift:333:15:333:15 | t2 | test.swift:334:15:334:15 | t2 | -| test.swift:334:15:334:15 | [post] t2 | test.swift:335:15:335:15 | t2 | -| test.swift:334:15:334:15 | t2 | test.swift:335:15:335:15 | t2 | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/test.swift b/swift/ql/test/library-tests/dataflow/dataflow/test.swift index 6995754e85c..a8a90fd5dca 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/test.swift +++ b/swift/ql/test/library-tests/dataflow/dataflow/test.swift @@ -271,8 +271,8 @@ func test_optionals(y: Int?) { sink(opt: x?.signum()) // $ flow=259 sink(opt: y?.signum()) - sink(arg: x ?? 0) // $ MISSING: flow=259 - sink(arg: x ?? source()) // $ MISSING: flow=259, 276 + sink(arg: x ?? 0) // $ flow=259 + sink(arg: x ?? source()) // $ flow=259 MISSING: flow=276 sink(arg: y ?? 0) sink(arg: y ?? source()) // $ MISSING: flow=278 From 52d5578fb5d842e5c07dc40ef2387588b3345893 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 14 Nov 2022 22:10:17 +0000 Subject: [PATCH 195/796] Swift: Dataflow through second argument of ??. --- .../codeql/swift/dataflow/internal/DataFlowPrivate.qll | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index f811a540c97..81a8bd4c85a 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -156,7 +156,14 @@ private module Cached { // flow through nil-coalescing operator `??` exists(BinaryExpr nco | nco.getFunction().(DeclRefExpr).getDecl().(FreeFunctionDecl).getName() = "??(_:_:)" and - nodeFrom.asExpr() = nco.getAnOperand() and + ( + // value argument + nodeFrom.asExpr() = nco.getAnOperand() + or + // unpack closure (the second argument is typically an `AutoClosureExpr` argument) + nodeFrom.asExpr() = + nco.getAnOperand().(AbstractClosureExpr).getBody().getAnElement().(ReturnStmt).getResult() + ) and nodeTo.asExpr() = nco ) or From 4c806a442aa6f193af9fcb38b7bcb87d26171519 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 15 Nov 2022 11:53:34 +0000 Subject: [PATCH 196/796] Swift: Dataflow through ? :. --- .../swift/dataflow/internal/DataFlowPrivate.qll | 9 +++++++++ .../dataflow/dataflow/DataFlow.expected | 13 +++++++++++++ .../dataflow/dataflow/LocalFlow.expected | 8 ++++++++ .../test/library-tests/dataflow/dataflow/test.swift | 6 +++--- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 81a8bd4c85a..7fcabf587ef 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -167,6 +167,15 @@ private module Cached { nodeTo.asExpr() = nco ) or + // flow through ternary operator `? :` + exists(IfExpr ie | + nodeTo.asExpr() = ie and + ( + nodeFrom.asExpr() = ie.getThenExpr() or + nodeFrom.asExpr() = ie.getElseExpr() + ) + ) + or // flow through a flow summary (extension of `SummaryModelCsv`) FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true) } diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected index 8c9c931a4ff..1277d30cdc2 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected @@ -105,11 +105,15 @@ edges | test.swift:263:13:263:28 | call to optionalSource() : | test.swift:271:15:271:16 | ...? : | | test.swift:263:13:263:28 | call to optionalSource() : | test.swift:274:15:274:20 | ... ??(_:_:) ... | | test.swift:263:13:263:28 | call to optionalSource() : | test.swift:275:15:275:27 | ... ??(_:_:) ... | +| test.swift:263:13:263:28 | call to optionalSource() : | test.swift:279:15:279:31 | ... ? ... : ... | +| test.swift:263:13:263:28 | call to optionalSource() : | test.swift:280:15:280:38 | ... ? ... : ... | | test.swift:270:15:270:22 | call to source() : | file://:0:0:0:0 | [summary param] this in signum() : | | test.swift:270:15:270:22 | call to source() : | test.swift:270:15:270:31 | call to signum() | | test.swift:271:15:271:16 | ...? : | file://:0:0:0:0 | [summary param] this in signum() : | | test.swift:271:15:271:16 | ...? : | test.swift:271:15:271:25 | call to signum() : | | test.swift:271:15:271:25 | call to signum() : | test.swift:271:15:271:25 | OptionalEvaluationExpr | +| test.swift:280:31:280:38 | call to source() : | test.swift:280:15:280:38 | ... ? ... : ... | +| test.swift:282:31:282:38 | call to source() : | test.swift:282:15:282:38 | ... ? ... : ... | | test.swift:302:14:302:26 | (...) [Tuple element at index 1] : | test.swift:306:15:306:15 | t1 [Tuple element at index 1] : | | test.swift:302:18:302:25 | call to source() : | test.swift:302:14:302:26 | (...) [Tuple element at index 1] : | | test.swift:306:15:306:15 | t1 [Tuple element at index 1] : | test.swift:306:15:306:18 | .1 | @@ -249,6 +253,11 @@ nodes | test.swift:271:15:271:25 | call to signum() : | semmle.label | call to signum() : | | test.swift:274:15:274:20 | ... ??(_:_:) ... | semmle.label | ... ??(_:_:) ... | | test.swift:275:15:275:27 | ... ??(_:_:) ... | semmle.label | ... ??(_:_:) ... | +| test.swift:279:15:279:31 | ... ? ... : ... | semmle.label | ... ? ... : ... | +| test.swift:280:15:280:38 | ... ? ... : ... | semmle.label | ... ? ... : ... | +| test.swift:280:31:280:38 | call to source() : | semmle.label | call to source() : | +| test.swift:282:15:282:38 | ... ? ... : ... | semmle.label | ... ? ... : ... | +| test.swift:282:31:282:38 | call to source() : | semmle.label | call to source() : | | test.swift:302:14:302:26 | (...) [Tuple element at index 1] : | semmle.label | (...) [Tuple element at index 1] : | | test.swift:302:18:302:25 | call to source() : | semmle.label | call to source() : | | test.swift:306:15:306:15 | t1 [Tuple element at index 1] : | semmle.label | t1 [Tuple element at index 1] : | @@ -332,6 +341,10 @@ subpaths | test.swift:271:15:271:25 | OptionalEvaluationExpr | test.swift:259:12:259:19 | call to source() : | test.swift:271:15:271:25 | OptionalEvaluationExpr | result | | test.swift:274:15:274:20 | ... ??(_:_:) ... | test.swift:259:12:259:19 | call to source() : | test.swift:274:15:274:20 | ... ??(_:_:) ... | result | | test.swift:275:15:275:27 | ... ??(_:_:) ... | test.swift:259:12:259:19 | call to source() : | test.swift:275:15:275:27 | ... ??(_:_:) ... | result | +| test.swift:279:15:279:31 | ... ? ... : ... | test.swift:259:12:259:19 | call to source() : | test.swift:279:15:279:31 | ... ? ... : ... | result | +| test.swift:280:15:280:38 | ... ? ... : ... | test.swift:259:12:259:19 | call to source() : | test.swift:280:15:280:38 | ... ? ... : ... | result | +| test.swift:280:15:280:38 | ... ? ... : ... | test.swift:280:31:280:38 | call to source() : | test.swift:280:15:280:38 | ... ? ... : ... | result | +| test.swift:282:15:282:38 | ... ? ... : ... | test.swift:282:31:282:38 | call to source() : | test.swift:282:15:282:38 | ... ? ... : ... | result | | test.swift:306:15:306:18 | .1 | test.swift:302:18:302:25 | call to source() : | test.swift:306:15:306:18 | .1 | result | | test.swift:317:15:317:18 | .0 | test.swift:314:12:314:19 | call to source() : | test.swift:317:15:317:18 | .0 | result | | test.swift:327:15:327:18 | .0 | test.swift:322:18:322:25 | call to source() : | test.swift:327:15:327:18 | .0 | result | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected index 0d48a6af63f..69e2a3ad207 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected @@ -216,18 +216,26 @@ | test.swift:279:15:279:15 | x | test.swift:280:15:280:15 | x | | test.swift:279:26:279:26 | x | test.swift:279:26:279:27 | ...! | | test.swift:279:26:279:26 | x | test.swift:280:15:280:15 | x | +| test.swift:279:26:279:27 | ...! | test.swift:279:15:279:31 | ... ? ... : ... | +| test.swift:279:31:279:31 | 0 | test.swift:279:15:279:31 | ... ? ... : ... | | test.swift:280:15:280:15 | x | test.swift:280:26:280:26 | x | | test.swift:280:15:280:15 | x | test.swift:284:16:284:16 | x | | test.swift:280:26:280:26 | x | test.swift:280:26:280:27 | ...! | | test.swift:280:26:280:26 | x | test.swift:284:16:284:16 | x | +| test.swift:280:26:280:27 | ...! | test.swift:280:15:280:38 | ... ? ... : ... | +| test.swift:280:31:280:38 | call to source() | test.swift:280:15:280:38 | ... ? ... : ... | | test.swift:281:15:281:15 | y | test.swift:281:26:281:26 | y | | test.swift:281:15:281:15 | y | test.swift:282:15:282:15 | y | | test.swift:281:26:281:26 | y | test.swift:281:26:281:27 | ...! | | test.swift:281:26:281:26 | y | test.swift:282:15:282:15 | y | +| test.swift:281:26:281:27 | ...! | test.swift:281:15:281:31 | ... ? ... : ... | +| test.swift:281:31:281:31 | 0 | test.swift:281:15:281:31 | ... ? ... : ... | | test.swift:282:15:282:15 | y | test.swift:282:26:282:26 | y | | test.swift:282:15:282:15 | y | test.swift:287:16:287:16 | y | | test.swift:282:26:282:26 | y | test.swift:282:26:282:27 | ...! | | test.swift:282:26:282:26 | y | test.swift:287:16:287:16 | y | +| test.swift:282:26:282:27 | ...! | test.swift:282:15:282:38 | ... ? ... : ... | +| test.swift:282:31:282:38 | call to source() | test.swift:282:15:282:38 | ... ? ... : ... | | test.swift:284:16:284:16 | x | test.swift:290:16:290:16 | x | | test.swift:287:16:287:16 | y | test.swift:293:16:293:16 | y | | test.swift:290:16:290:16 | x | test.swift:290:16:290:17 | ...? | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/test.swift b/swift/ql/test/library-tests/dataflow/dataflow/test.swift index a8a90fd5dca..093e8c2db95 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/test.swift +++ b/swift/ql/test/library-tests/dataflow/dataflow/test.swift @@ -276,10 +276,10 @@ func test_optionals(y: Int?) { sink(arg: y ?? 0) sink(arg: y ?? source()) // $ MISSING: flow=278 - sink(arg: x != nil ? x! : 0) // $ MISSING: flow=259 - sink(arg: x != nil ? x! : source()) // $ MISSING: flow=259, 281 + sink(arg: x != nil ? x! : 0) // $ flow=259 + sink(arg: x != nil ? x! : source()) // $ flow=259 flow=280 sink(arg: y != nil ? y! : 0) - sink(arg: y != nil ? y! : source()) // $ MISSING: flow=283 + sink(arg: y != nil ? y! : source()) // $ flow=282 if let z = x { sink(arg: z) // $ MISSING: flow=259 From ae5689b2952f64a36f99e1d1a62bd19899ac854f Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 15 Nov 2022 12:04:10 +0000 Subject: [PATCH 197/796] Swift: Update comment. --- swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 7fcabf587ef..565bb4a8e93 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -148,7 +148,7 @@ private module Cached { // flow through `!` nodeFrom.asExpr() = nodeTo.asExpr().(ForceValueExpr).getSubExpr() or - // flow through `?` + // flow through `?` and `?.` nodeFrom.asExpr() = nodeTo.asExpr().(BindOptionalExpr).getSubExpr() or nodeFrom.asExpr() = nodeTo.asExpr().(OptionalEvaluationExpr).getSubExpr() From 65c1e239eb1249d02361e65b0ffc38a1ada60593 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 15 Nov 2022 14:49:06 +0100 Subject: [PATCH 198/796] clean up the cache when compiling on main --- .github/workflows/compile-queries.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/compile-queries.yml b/.github/workflows/compile-queries.yml index bdcf0ba8d8a..73b674aff30 100644 --- a/.github/workflows/compile-queries.yml +++ b/.github/workflows/compile-queries.yml @@ -56,4 +56,20 @@ jobs: # do full compile if running on main - this populates the cache if : ${{ github.event_name != 'pull_request' }} shell: bash - run: codeql query compile -j0 */ql/src --keep-going --warnings=error \ No newline at end of file + run: | + # Move all the existing cache into another folder, so we only preserve the cache for the current queries. + mkdir -p ${COMBINED_CACHE_DIR} + rm */ql/src/.cache/{lock,size} + # replicate the folder structure from the .cache folders into the combined cache folder. (because cp doesn't have a "create missing folders" option) + find */ql/src/.cache -type d | cut -d "/" -f 6,7 | sort | uniq > folders.txt + cat folders.txt | xargs -I {} mkdir -p ${COMBINED_CACHE_DIR}/{} + # copy the contents of the .cache folders into the combined cache folder. + cp -r */ql/src/.cache/* ${COMBINED_CACHE_DIR}/ + # clean up the .cache folders + rm -rf */ql/src/.cache/* + rm folders.txt + + # compile the queries + codeql query compile -j0 */ql/src --keep-going --warnings=error --compilation-cache ${COMBINED_CACHE_DIR} + env: + COMBINED_CACHE_DIR: ${{ github.workspace }}/compilation-dir \ No newline at end of file From c2171c01e1514b331f8cb41a72640a9431286699 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 15 Nov 2022 15:00:30 +0100 Subject: [PATCH 199/796] Swift: remove double newlines in schema While PEP8 mandates those, they look bad in the schema file. `autopep8` already ignores those, and they were single newlines at some point until an overeager IDE has "fixed" them at some point without me realizing. Also, the pre-commit configuration was updated to take `schema.py` into account. --- .pre-commit-config.yaml | 4 +- swift/schema.py | 279 ---------------------------------------- 2 files changed, 2 insertions(+), 281 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 50a6adf80d9..14845337b36 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: rev: v1.6.0 hooks: - id: autopep8 - files: ^swift/codegen/.*\.py + files: ^swift/.*\.py - repo: local hooks: @@ -44,7 +44,7 @@ repos: - id: swift-codegen name: Run Swift checked in code generation - files: ^swift/(codegen/|.*/generated/|ql/lib/(swift\.dbscheme$|codeql/swift/elements)) + files: ^swift/(schema.py$|codegen/|.*/generated/|ql/lib/(swift\.dbscheme$|codeql/swift/elements)) language: system entry: bazel run //swift/codegen -- --quiet pass_filenames: false diff --git a/swift/schema.py b/swift/schema.py index eac52c4e97b..e9e8746d0c3 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -11,17 +11,14 @@ from swift.codegen.lib.schema.defs import * include("prefix.dbscheme") - @qltest.skip class Element: is_unknown: predicate | cpp.skip - @qltest.collapse_hierarchy class File(Element): name: string - @qltest.skip @qltest.collapse_hierarchy class Location(Element): @@ -31,19 +28,16 @@ class Location(Element): end_line: int end_column: int - @qltest.skip class Locatable(Element): location: optional[Location] | cpp.skip | doc("location associated with this element in the code") - @qltest.collapse_hierarchy @qltest.skip class ErrorElement(Locatable): """The superclass of all elements indicating some kind of error.""" pass - @use_for_null class UnspecifiedElement(ErrorElement): parent: optional[Element] @@ -51,130 +45,103 @@ class UnspecifiedElement(ErrorElement): index: optional[int] error: string - class Comment(Locatable): text: string - class Diagnostics(Locatable): text: string kind: int - class DbFile(File): pass - class DbLocation(Location): pass - @synth.on_arguments() class UnknownFile(File): pass - @synth.on_arguments() class UnknownLocation(Location): pass - class AstNode(Locatable): pass - @group("type") class Type(Element): name: string canonical_type: "Type" - @group("decl") class Decl(AstNode): module: "ModuleDecl" - @group("expr") class Expr(AstNode): """The base class for all expressions in Swift.""" type: optional[Type] - @group("pattern") class Pattern(AstNode): pass - @group("stmt") class Stmt(AstNode): pass - @group("decl") class GenericContext(Element): generic_type_params: list["GenericTypeParamDecl"] | child - @group("decl") class IterableDeclContext(Element): members: list[Decl] | child - class EnumCaseDecl(Decl): elements: list["EnumElementDecl"] - class ExtensionDecl(GenericContext, IterableDeclContext, Decl): extended_type_decl: "NominalTypeDecl" - class IfConfigDecl(Decl): active_elements: list[AstNode] - class ImportDecl(Decl): is_exported: predicate imported_module: optional["ModuleDecl"] declarations: list["ValueDecl"] - @qltest.skip class MissingMemberDecl(Decl): """A placeholder for missing declarations that can arise on object deserialization.""" name: string - class OperatorDecl(Decl): name: string - class PatternBindingDecl(Decl): inits: list[optional[Expr]] | child patterns: list[Pattern] | child - class PoundDiagnosticDecl(Decl): """ A diagnostic directive, which is either `#error` or `#warning`.""" kind: int | doc("""This is 1 for `#error` and 2 for `#warning`""") message: "StringLiteralExpr" | child - class PrecedenceGroupDecl(Decl): pass - class TopLevelCodeDecl(Decl): body: "BraceStmt" | child - class ValueDecl(Decl): interface_type: Type - class AbstractStorageDecl(ValueDecl): accessor_decls: list["AccessorDecl"] | child - class VarDecl(AbstractStorageDecl): name: string type: Type @@ -198,7 +165,6 @@ class VarDecl(AbstractStorageDecl): prefixed with `$`. """) - class ParamDecl(VarDecl): is_inout: predicate | doc("this is an `inout` parameter") property_wrapper_local_wrapped_var_binding: optional[PatternBindingDecl] | child | desc(""" @@ -210,101 +176,80 @@ class ParamDecl(VarDecl): has a property wrapper. """) - class Callable(Element): self_param: optional[ParamDecl] | child params: list[ParamDecl] | child body: optional["BraceStmt"] | child | desc("The body is absent within protocol declarations.") - class AbstractFunctionDecl(GenericContext, ValueDecl, Callable): name: string | doc("name of this function") - class EnumElementDecl(ValueDecl): name: string params: list[ParamDecl] | child - class InfixOperatorDecl(OperatorDecl): precedence_group: optional[PrecedenceGroupDecl] - class PostfixOperatorDecl(OperatorDecl): pass - class PrefixOperatorDecl(OperatorDecl): pass - class TypeDecl(ValueDecl): name: string base_types: list[Type] - class AbstractTypeParamDecl(TypeDecl): pass - class ConstructorDecl(AbstractFunctionDecl): pass - class DestructorDecl(AbstractFunctionDecl): pass - class FuncDecl(AbstractFunctionDecl): pass - class GenericTypeDecl(GenericContext, TypeDecl): pass - class ModuleDecl(TypeDecl): is_builtin_module: predicate | doc("this module is the built-in one") is_system_module: predicate | doc("this module is a system one") imported_modules: list["ModuleDecl"] exported_modules: list["ModuleDecl"] - class SubscriptDecl(AbstractStorageDecl, GenericContext): params: list[ParamDecl] | child element_type: Type element_type: Type - class AccessorDecl(FuncDecl): is_getter: predicate | doc('this accessor is a getter') is_setter: predicate | doc('this accessor is a setter') is_will_set: predicate | doc('this accessor is a `willSet`, called before the property is set') is_did_set: predicate | doc('this accessor is a `didSet`, called after the property is set') - class AssociatedTypeDecl(AbstractTypeParamDecl): pass - class ConcreteFuncDecl(FuncDecl): pass - class ConcreteVarDecl(VarDecl): introducer_int: int | doc("introducer enumeration value") | desc(""" This is 0 if the variable was introduced with `let` and 1 if it was introduced with `var`. """) - class GenericTypeParamDecl(AbstractTypeParamDecl): pass - class NominalTypeDecl(GenericTypeDecl, IterableDeclContext): type: Type - class OpaqueTypeDecl(GenericTypeDecl): """ A declaration of an opaque type, that is formally equivalent to a given type but abstracts it @@ -321,71 +266,56 @@ class OpaqueTypeDecl(GenericTypeDecl): opaque_generic_params: list["GenericTypeParamType"] opaque_generic_params: list["GenericTypeParamType"] - class TypeAliasDecl(GenericTypeDecl): pass - class ClassDecl(NominalTypeDecl): pass - class EnumDecl(NominalTypeDecl): pass - class ProtocolDecl(NominalTypeDecl): pass - class StructDecl(NominalTypeDecl): pass - @group("expr") class Argument(Locatable): label: string expr: Expr | child - class AbstractClosureExpr(Expr, Callable): pass - class AnyTryExpr(Expr): sub_expr: Expr | child - class AppliedPropertyWrapperExpr(Expr): """An implicit application of a property wrapper on the argument of a call.""" kind: int | desc("This is 1 for a wrapped value and 2 for a projected one.") value: Expr | child | desc("The value on which the wrapper is applied.") param: ParamDecl | doc("parameter declaration owning this wrapper application") - class ApplyExpr(Expr): function: Expr | child | doc("function being applied") arguments: list[Argument] | child | doc("arguments passed to the applied function") - class AssignExpr(Expr): dest: Expr | child source: Expr | child - class BindOptionalExpr(Expr): sub_expr: Expr | child - class CaptureListExpr(Expr): binding_decls: list[PatternBindingDecl] | child closure_body: "ClosureExpr" | child - class CollectionExpr(Expr): pass - class DeclRefExpr(Expr): decl: Decl replacement_types: list[Type] @@ -393,125 +323,99 @@ class DeclRefExpr(Expr): has_direct_to_implementation_semantics: predicate has_ordinary_semantics: predicate - class DefaultArgumentExpr(Expr): param_decl: ParamDecl param_index: int caller_side_default: optional[Expr] - class DiscardAssignmentExpr(Expr): pass - class DotSyntaxBaseIgnoredExpr(Expr): qualifier: Expr | child sub_expr: Expr | child - class DynamicTypeExpr(Expr): base: Expr | child - class EnumIsCaseExpr(Expr): sub_expr: Expr | child element: EnumElementDecl - @qltest.skip class ErrorExpr(Expr, ErrorElement): pass - class ExplicitCastExpr(Expr): sub_expr: Expr | child - class ForceValueExpr(Expr): sub_expr: Expr | child - @qltest.collapse_hierarchy class IdentityExpr(Expr): sub_expr: Expr | child - class IfExpr(Expr): condition: Expr | child then_expr: Expr | child else_expr: Expr | child - @qltest.collapse_hierarchy class ImplicitConversionExpr(Expr): sub_expr: Expr | child - class InOutExpr(Expr): sub_expr: Expr | child - class KeyPathApplicationExpr(Expr): base: Expr | child key_path: Expr | child - class KeyPathDotExpr(Expr): pass - class KeyPathExpr(Expr): root: optional["TypeRepr"] | child parsed_path: optional[Expr] | child - class LazyInitializerExpr(Expr): sub_expr: Expr | child - class LiteralExpr(Expr): pass - class LookupExpr(Expr): base: Expr | child member: optional[Decl] - class MakeTemporarilyEscapableExpr(Expr): escaping_closure: "OpaqueValueExpr" | child nonescaping_closure: Expr | child sub_expr: Expr | child - @qltest.skip class ObjCSelectorExpr(Expr): sub_expr: Expr | child method: AbstractFunctionDecl - class OneWayExpr(Expr): sub_expr: Expr | child - class OpaqueValueExpr(Expr): pass - class OpenExistentialExpr(Expr): sub_expr: Expr | child existential: Expr | child opaque_expr: OpaqueValueExpr | child - class OptionalEvaluationExpr(Expr): sub_expr: Expr | child - class OtherConstructorDeclRefExpr(Expr): constructor_decl: ConstructorDecl - class PropertyWrapperValuePlaceholderExpr(Expr): """ A placeholder substituting property initializations with `=` when the property has a property @@ -520,233 +424,178 @@ class PropertyWrapperValuePlaceholderExpr(Expr): wrapped_value: optional[Expr] placeholder: OpaqueValueExpr - class RebindSelfInConstructorExpr(Expr): sub_expr: Expr | child self: VarDecl - @qltest.skip class SequenceExpr(Expr): elements: list[Expr] | child - class SuperRefExpr(Expr): self: VarDecl - class TapExpr(Expr): sub_expr: optional[Expr] | child body: "BraceStmt" | child var: VarDecl - class TupleElementExpr(Expr): sub_expr: Expr | child index: int - class TupleExpr(Expr): elements: list[Expr] | child - class TypeExpr(Expr): type_repr: optional["TypeRepr"] | child - class UnresolvedDeclRefExpr(Expr, ErrorElement): name: optional[string] - class UnresolvedDotExpr(Expr, ErrorElement): base: Expr | child name: string - class UnresolvedMemberExpr(Expr, ErrorElement): name: string - class UnresolvedPatternExpr(Expr, ErrorElement): sub_pattern: Pattern | child - class UnresolvedSpecializeExpr(Expr, ErrorElement): sub_expr: Expr | child - class VarargExpansionExpr(Expr): sub_expr: Expr | child - class AnyHashableErasureExpr(ImplicitConversionExpr): pass - class ArchetypeToSuperExpr(ImplicitConversionExpr): pass - class ArrayExpr(CollectionExpr): elements: list[Expr] | child - class ArrayToPointerExpr(ImplicitConversionExpr): pass - class AutoClosureExpr(AbstractClosureExpr): pass - class AwaitExpr(IdentityExpr): pass - class BinaryExpr(ApplyExpr): pass - @qltest.skip class BridgeFromObjCExpr(ImplicitConversionExpr): pass - @qltest.skip class BridgeToObjCExpr(ImplicitConversionExpr): pass - class BuiltinLiteralExpr(LiteralExpr): pass - class CallExpr(ApplyExpr): pass - class CheckedCastExpr(ExplicitCastExpr): pass - class ClassMetatypeToObjectExpr(ImplicitConversionExpr): pass - class ClosureExpr(AbstractClosureExpr): pass - class CoerceExpr(ExplicitCastExpr): pass - class CollectionUpcastConversionExpr(ImplicitConversionExpr): pass - @qltest.skip class ConditionalBridgeFromObjCExpr(ImplicitConversionExpr): pass - class CovariantFunctionConversionExpr(ImplicitConversionExpr): pass - class CovariantReturnConversionExpr(ImplicitConversionExpr): pass - class DerivedToBaseExpr(ImplicitConversionExpr): pass - class DestructureTupleExpr(ImplicitConversionExpr): pass - class DictionaryExpr(CollectionExpr): elements: list[Expr] | child - class DifferentiableFunctionExpr(ImplicitConversionExpr): pass - class DifferentiableFunctionExtractOriginalExpr(ImplicitConversionExpr): pass - class DotSelfExpr(IdentityExpr): pass - @qltest.collapse_hierarchy class DynamicLookupExpr(LookupExpr): pass - class ErasureExpr(ImplicitConversionExpr): pass - class ExistentialMetatypeToObjectExpr(ImplicitConversionExpr): pass - class ForceTryExpr(AnyTryExpr): pass - class ForeignObjectConversionExpr(ImplicitConversionExpr): pass - class FunctionConversionExpr(ImplicitConversionExpr): pass - class InOutToPointerExpr(ImplicitConversionExpr): pass - class InjectIntoOptionalExpr(ImplicitConversionExpr): pass - class InterpolatedStringLiteralExpr(LiteralExpr): interpolation_expr: optional[OpaqueValueExpr] interpolation_count_expr: optional[Expr] | child literal_capacity_expr: optional[Expr] | child appending_expr: optional[TapExpr] | child - class LinearFunctionExpr(ImplicitConversionExpr): pass - class LinearFunctionExtractOriginalExpr(ImplicitConversionExpr): pass - class LinearToDifferentiableFunctionExpr(ImplicitConversionExpr): pass - class LoadExpr(ImplicitConversionExpr): pass - class MemberRefExpr(LookupExpr): has_direct_to_storage_semantics: predicate has_direct_to_implementation_semantics: predicate has_ordinary_semantics: predicate - class MetatypeConversionExpr(ImplicitConversionExpr): pass - class NilLiteralExpr(LiteralExpr): pass - class ObjectLiteralExpr(LiteralExpr): """ An instance of `#fileLiteral`, `#imageLiteral` or `#colorLiteral` expressions, which are used in playgrounds. @@ -754,11 +603,9 @@ class ObjectLiteralExpr(LiteralExpr): kind: int | desc("""This is 0 for `#fileLiteral`, 1 for `#imageLiteral` and 2 for `#colorLiteral`.""") arguments: list[Argument] | child - class OptionalTryExpr(AnyTryExpr): pass - class OverloadedDeclRefExpr(Expr, ErrorElement): """ An ambiguous expression that might refer to multiple declarations. This will be present only @@ -766,287 +613,222 @@ class OverloadedDeclRefExpr(Expr, ErrorElement): """ possible_declarations: list[ValueDecl] - class ParenExpr(IdentityExpr): pass - class PointerToPointerExpr(ImplicitConversionExpr): pass - class PostfixUnaryExpr(ApplyExpr): pass - class PrefixUnaryExpr(ApplyExpr): pass - class ProtocolMetatypeToObjectExpr(ImplicitConversionExpr): pass - class RegexLiteralExpr(LiteralExpr): pass - class SelfApplyExpr(ApplyExpr): base: Expr - class StringToPointerExpr(ImplicitConversionExpr): pass - class SubscriptExpr(LookupExpr): arguments: list[Argument] | child has_direct_to_storage_semantics: predicate has_direct_to_implementation_semantics: predicate has_ordinary_semantics: predicate - class TryExpr(AnyTryExpr): pass - class UnderlyingToOpaqueExpr(ImplicitConversionExpr): pass - class UnevaluatedInstanceExpr(ImplicitConversionExpr): pass - class UnresolvedMemberChainResultExpr(IdentityExpr, ErrorElement): pass - class UnresolvedTypeConversionExpr(ImplicitConversionExpr, ErrorElement): pass - class BooleanLiteralExpr(BuiltinLiteralExpr): value: boolean - class ConditionalCheckedCastExpr(CheckedCastExpr): pass - class ConstructorRefCallExpr(SelfApplyExpr): pass - class DotSyntaxCallExpr(SelfApplyExpr): pass - @synth.from_class(DotSyntaxCallExpr) class MethodRefExpr(LookupExpr): pass - class DynamicMemberRefExpr(DynamicLookupExpr): pass - class DynamicSubscriptExpr(DynamicLookupExpr): pass - class ForcedCheckedCastExpr(CheckedCastExpr): pass - class IsExpr(CheckedCastExpr): pass - class MagicIdentifierLiteralExpr(BuiltinLiteralExpr): kind: string - class NumberLiteralExpr(BuiltinLiteralExpr): pass - class StringLiteralExpr(BuiltinLiteralExpr): value: string - class FloatLiteralExpr(NumberLiteralExpr): string_value: string - class IntegerLiteralExpr(NumberLiteralExpr): string_value: string - class AnyPattern(Pattern): pass - class BindingPattern(Pattern): sub_pattern: Pattern | child - class BoolPattern(Pattern): value: boolean - class EnumElementPattern(Pattern): element: EnumElementDecl sub_pattern: optional[Pattern] | child - class ExprPattern(Pattern): sub_expr: Expr | child - class IsPattern(Pattern): cast_type_repr: optional["TypeRepr"] | child sub_pattern: optional[Pattern] | child - class NamedPattern(Pattern): name: string - class OptionalSomePattern(Pattern): sub_pattern: Pattern | child - class ParenPattern(Pattern): sub_pattern: Pattern | child - class TuplePattern(Pattern): elements: list[Pattern] | child - class TypedPattern(Pattern): sub_pattern: Pattern | child type_repr: optional["TypeRepr"] | child - @group("stmt") class CaseLabelItem(AstNode): pattern: Pattern | child guard: optional[Expr] | child - @group("stmt") class ConditionElement(AstNode): boolean: optional[Expr] | child pattern: optional[Pattern] | child initializer: optional[Expr] | child - @group("stmt") class StmtCondition(AstNode): elements: list[ConditionElement] | child - class BraceStmt(Stmt): elements: list[AstNode] | child - class BreakStmt(Stmt): target_name: optional[string] target: optional[Stmt] - class CaseStmt(Stmt): body: Stmt | child labels: list[CaseLabelItem] | child variables: list[VarDecl] - class ContinueStmt(Stmt): target_name: optional[string] target: optional[Stmt] - class DeferStmt(Stmt): body: BraceStmt | child - class FailStmt(Stmt): pass - class FallthroughStmt(Stmt): fallthrough_source: CaseStmt fallthrough_dest: CaseStmt - class LabeledStmt(Stmt): label: optional[string] - class PoundAssertStmt(Stmt): condition: Expr message: string - class ReturnStmt(Stmt): result: optional[Expr] | child - class ThrowStmt(Stmt): sub_expr: Expr | child - class YieldStmt(Stmt): results: list[Expr] | child - class DoCatchStmt(LabeledStmt): body: Stmt | child catches: list[CaseStmt] | child - class DoStmt(LabeledStmt): body: BraceStmt | child - class ForEachStmt(LabeledStmt): pattern: Pattern | child sequence: Expr | child where: optional[Expr] | child body: BraceStmt | child - class LabeledConditionalStmt(LabeledStmt): condition: StmtCondition | child - class RepeatWhileStmt(LabeledStmt): condition: Expr | child body: Stmt | child - class SwitchStmt(LabeledStmt): expr: Expr | child cases: list[CaseStmt] | child - class GuardStmt(LabeledConditionalStmt): body: BraceStmt | child - class IfStmt(LabeledConditionalStmt): then: Stmt | child else_: optional[Stmt] | child - class WhileStmt(LabeledConditionalStmt): body: Stmt | child - @group("type") class TypeRepr(AstNode): type: Type - @ql.default_doc_name("function type") class AnyFunctionType(Type): result: Type @@ -1055,255 +837,194 @@ class AnyFunctionType(Type): is_throwing: predicate | doc("this type refers to a throwing function") is_async: predicate | doc("this type refers to an `async` function") - class AnyGenericType(Type): parent: optional[Type] declaration: Decl - class AnyMetatypeType(Type): pass - @qltest.collapse_hierarchy class BuiltinType(Type): pass - class DependentMemberType(Type): base_type: Type associated_type_decl: AssociatedTypeDecl - class DynamicSelfType(Type): static_self_type: Type - class ErrorType(Type, ErrorElement): pass - class ExistentialType(Type): constraint: Type - class InOutType(Type): object_type: Type - class LValueType(Type): object_type: Type - class ModuleType(Type): module: ModuleDecl - class ProtocolCompositionType(Type): members: list[Type] - class ReferenceStorageType(Type): referent_type: Type - class SubstitutableType(Type): pass - class SugarType(Type): pass - class TupleType(Type): types: list[Type] names: list[optional[string]] - class UnresolvedType(Type, ErrorElement): pass - class AnyBuiltinIntegerType(BuiltinType): pass - class ArchetypeType(SubstitutableType): interface_type: Type superclass: optional[Type] protocols: list[ProtocolDecl] - class BuiltinBridgeObjectType(BuiltinType): pass - class BuiltinDefaultActorStorageType(BuiltinType): pass - class BuiltinExecutorType(BuiltinType): pass - class BuiltinFloatType(BuiltinType): pass - class BuiltinJobType(BuiltinType): pass - class BuiltinNativeObjectType(BuiltinType): pass - class BuiltinRawPointerType(BuiltinType): pass - class BuiltinRawUnsafeContinuationType(BuiltinType): pass - class BuiltinUnsafeValueBufferType(BuiltinType): pass - class BuiltinVectorType(BuiltinType): pass - class ExistentialMetatypeType(AnyMetatypeType): pass - class FunctionType(AnyFunctionType): pass - class GenericFunctionType(AnyFunctionType): """ The type of a generic function with type parameters """ generic_params: list["GenericTypeParamType"] | doc("type {parameters} of this generic type") - class GenericTypeParamType(SubstitutableType): pass - class MetatypeType(AnyMetatypeType): pass - class NominalOrBoundGenericNominalType(AnyGenericType): pass - class ParenType(SugarType): type: Type - class SyntaxSugarType(SugarType): pass - class TypeAliasType(SugarType): decl: TypeAliasDecl - class UnboundGenericType(AnyGenericType): pass - class UnmanagedStorageType(ReferenceStorageType): pass - class UnownedStorageType(ReferenceStorageType): pass - class WeakStorageType(ReferenceStorageType): pass - class BoundGenericType(NominalOrBoundGenericNominalType): arg_types: list[Type] - class BuiltinIntegerLiteralType(AnyBuiltinIntegerType): pass - @qltest.uncollapse_hierarchy class BuiltinIntegerType(AnyBuiltinIntegerType): width: optional[int] - class DictionaryType(SyntaxSugarType): key_type: Type value_type: Type - class NominalType(NominalOrBoundGenericNominalType): pass - class OpaqueTypeArchetypeType(ArchetypeType): """An opaque type, that is a type formally equivalent to an underlying type but abstracting it away. See https://docs.swift.org/swift-book/LanguageGuide/OpaqueTypes.html.""" declaration: OpaqueTypeDecl - class OpenedArchetypeType(ArchetypeType): pass - class PrimaryArchetypeType(ArchetypeType): pass - class UnarySyntaxSugarType(SyntaxSugarType): base_type: Type - class ArraySliceType(UnarySyntaxSugarType): pass - class BoundGenericClassType(BoundGenericType): pass - class BoundGenericEnumType(BoundGenericType): pass - class BoundGenericStructType(BoundGenericType): pass - class ClassType(NominalType): pass - class EnumType(NominalType): pass - class OptionalType(UnarySyntaxSugarType): pass - class ProtocolType(NominalType): pass - class StructType(NominalType): pass - class VariadicSequenceType(UnarySyntaxSugarType): pass - class ParameterizedProtocolType(Type): """ A sugar type of the form `P` with `P` a protocol. From 635391eae8032f628e463d24383782f6c4df95c1 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 15 Nov 2022 15:43:05 +0100 Subject: [PATCH 200/796] Swift: autopep8 integration tests --- swift/integration-tests/posix-only/cross-references/test.py | 4 ++-- .../posix-only/frontend-invocations/test.py | 2 +- swift/integration-tests/posix-only/hello-world/test.py | 4 ++-- swift/integration-tests/posix-only/partial-modules/test.py | 6 +++--- swift/integration-tests/runner.py | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/swift/integration-tests/posix-only/cross-references/test.py b/swift/integration-tests/posix-only/cross-references/test.py index 19271030c19..6f2b8b26143 100644 --- a/swift/integration-tests/posix-only/cross-references/test.py +++ b/swift/integration-tests/posix-only/cross-references/test.py @@ -1,6 +1,6 @@ from create_database_utils import * run_codeql_database_create([ - 'swift package clean', - 'swift build' + 'swift package clean', + 'swift build' ], lang='swift') diff --git a/swift/integration-tests/posix-only/frontend-invocations/test.py b/swift/integration-tests/posix-only/frontend-invocations/test.py index 2c956137cb5..b415c024e56 100644 --- a/swift/integration-tests/posix-only/frontend-invocations/test.py +++ b/swift/integration-tests/posix-only/frontend-invocations/test.py @@ -1,5 +1,5 @@ from create_database_utils import * run_codeql_database_create([ - 'make', + 'make', ], lang='swift') diff --git a/swift/integration-tests/posix-only/hello-world/test.py b/swift/integration-tests/posix-only/hello-world/test.py index 19271030c19..6f2b8b26143 100644 --- a/swift/integration-tests/posix-only/hello-world/test.py +++ b/swift/integration-tests/posix-only/hello-world/test.py @@ -1,6 +1,6 @@ from create_database_utils import * run_codeql_database_create([ - 'swift package clean', - 'swift build' + 'swift package clean', + 'swift build' ], lang='swift') diff --git a/swift/integration-tests/posix-only/partial-modules/test.py b/swift/integration-tests/posix-only/partial-modules/test.py index ae89d5da5d7..17320f33628 100644 --- a/swift/integration-tests/posix-only/partial-modules/test.py +++ b/swift/integration-tests/posix-only/partial-modules/test.py @@ -1,7 +1,7 @@ from create_database_utils import * run_codeql_database_create([ - 'env', - 'swift package clean', - 'swift build' + 'env', + 'swift package clean', + 'swift build' ], lang='swift', keep_trap=True) diff --git a/swift/integration-tests/runner.py b/swift/integration-tests/runner.py index b5c608c2a97..b0b2ecd92b0 100755 --- a/swift/integration-tests/runner.py +++ b/swift/integration-tests/runner.py @@ -21,7 +21,7 @@ this_dir = pathlib.Path(__file__).parent.resolve() def options(): p = argparse.ArgumentParser() p.add_argument("--test-dir", "-d", type=pathlib.Path, action="append") - #FIXME: the following should be the default + # FIXME: the following should be the default p.add_argument("--check-databases", action="store_true") p.add_argument("--learn", action="store_true") p.add_argument("--threads", "-j", type=int, default=0) From 563a56af9d6781af6b1795b7d13a9c1f3f8d7528 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Tue, 15 Nov 2022 15:46:34 +0100 Subject: [PATCH 201/796] Update Hapi.qll --- .../ql/lib/semmle/javascript/frameworks/Hapi.qll | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll index 0d04aac34c6..b3bed8112ad 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll @@ -18,12 +18,14 @@ module Hapi { this = DataFlow::moduleMember("@hapi/glue", "compose").getAnInvocation() or // `register (server, options)` - exists(Function f | - this.(DataFlow::ParameterNode).getParameter() = f.getParameter(0) and - f.getName() = "register" and - f.getParameter(0).getName() = "server" and - f.getParameter(1).getName() = "options" - ) + // `module.exports.plugin = {register, pkg};` + this = + any(NodeModule m) + .getAnExportedValue("plugin") + .(DataFlow::ObjectLiteralNode) + .getAPropertySource("register") + .(DataFlow::FunctionNode) + .getParameter(0) or // `const after = function (server) {...};` // `server.dependency('name', after);` From 8ca004fde157f5fbc3a2cacf452fd886903ea3d9 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Tue, 15 Nov 2022 16:14:22 +0100 Subject: [PATCH 202/796] Add AdditionalTaintStep --- swift/ql/lib/codeql/swift/dataflow/FlowSteps.qll | 14 ++++++++++++++ .../dataflow/internal/TaintTrackingPrivate.qll | 2 ++ 2 files changed, 16 insertions(+) diff --git a/swift/ql/lib/codeql/swift/dataflow/FlowSteps.qll b/swift/ql/lib/codeql/swift/dataflow/FlowSteps.qll index e538f44b957..fef6646511d 100644 --- a/swift/ql/lib/codeql/swift/dataflow/FlowSteps.qll +++ b/swift/ql/lib/codeql/swift/dataflow/FlowSteps.qll @@ -1,6 +1,20 @@ import swift private import codeql.swift.dataflow.DataFlow +/** + * A unit class for adding additional taint steps. + * + * Extend this class to add additional taint steps that should apply to all + * taint configurations. + */ +class AdditionalTaintStep extends Unit { + /** + * Holds if the step from `node1` to `node2` should be considered a taint + * step for all configurations. + */ + abstract predicate step(DataFlow::Node node1, DataFlow::Node node2); +} + /** * A `Content` that should be implicitly regarded as tainted whenever an object with such `Content` * is itself tainted. diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll index cd38648aef9..92724729d0e 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll @@ -64,6 +64,8 @@ private module Cached { or // flow through a flow summary (extension of `SummaryModelCsv`) FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, false) + or + any(AdditionalTaintStep a).step(nodeFrom, nodeTo) } /** From e5e3bb3705e5272187b02cdf6b103dfb407bc910 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Tue, 15 Nov 2022 16:27:14 +0100 Subject: [PATCH 203/796] Generalize the server definition in plugin registration --- javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll index b3bed8112ad..b0b33c078db 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll @@ -20,11 +20,11 @@ module Hapi { // `register (server, options)` // `module.exports.plugin = {register, pkg};` this = - any(NodeModule m) + any(Module m) .getAnExportedValue("plugin") - .(DataFlow::ObjectLiteralNode) + .getALocalSource() .getAPropertySource("register") - .(DataFlow::FunctionNode) + .getAFunctionValue() .getParameter(0) or // `const after = function (server) {...};` From 8109a7b67a6cdb654e03d9ada70d235319cb4e70 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Tue, 15 Nov 2022 16:27:21 +0100 Subject: [PATCH 204/796] Update javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll Co-authored-by: Erik Krogh Kristensen --- javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll index b0b33c078db..c791cd9e25d 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll @@ -32,7 +32,7 @@ module Hapi { exists(ServerDefinition server, DataFlow::MethodCallNode call | call = server.ref().getAMethodCall() and call.getMethodName() = "dependency" and - this = call.getArgument(1).(DataFlow::FunctionNode).getParameter(0) + this = call.getABoundCallbackParameter(1, 0) ) } } From da7788dd64a22d51debadcf90f3a74932ed8f332 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Tue, 15 Nov 2022 16:25:59 +0100 Subject: [PATCH 205/796] CodeQL: add 'False positive' issue template --- .github/ISSUE_TEMPLATE/ql--false-positive.md | 36 ++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/ql--false-positive.md diff --git a/.github/ISSUE_TEMPLATE/ql--false-positive.md b/.github/ISSUE_TEMPLATE/ql--false-positive.md new file mode 100644 index 00000000000..b3d942ab5d7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/ql--false-positive.md @@ -0,0 +1,36 @@ +--- +name: False positive +about: Tell us about an alert that shouldn't be reported +title: False positive +labels: false-positive +assignees: '' + +--- + +**Description of the false positive** + + + +**Code samples or links to source code** + + + +**URL to the alert on GitHub CodeScanning (optional)** + + From 56b207e41f250dd0c143c860f4af67b94d97ab9e Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 15 Nov 2022 17:07:52 +0100 Subject: [PATCH 206/796] Swift: remove IPA classes from `cppgen` --- swift/codegen/generators/cppgen.py | 9 +++- swift/codegen/test/test_cppgen.py | 79 ++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/swift/codegen/generators/cppgen.py b/swift/codegen/generators/cppgen.py index 45f0d98949b..18d65d54150 100644 --- a/swift/codegen/generators/cppgen.py +++ b/swift/codegen/generators/cppgen.py @@ -80,10 +80,17 @@ class Processor: trap_name=trap_name, ) + @functools.lru_cache(maxsize=None) + def _is_ipa(self, name: str) -> bool: + cls = self._classmap[name] + return cls.ipa is not None or ( + cls.derived and all(self._is_ipa(d) for d in cls.derived)) + def get_classes(self): ret = {'': []} for k, cls in self._classmap.items(): - ret.setdefault(cls.group, []).append(self._get_class(cls.name)) + if not self._is_ipa(k): + ret.setdefault(cls.group, []).append(self._get_class(cls.name)) return ret diff --git a/swift/codegen/test/test_cppgen.py b/swift/codegen/test/test_cppgen.py index df4925cb70e..54f1fdf1f7a 100644 --- a/swift/codegen/test/test_cppgen.py +++ b/swift/codegen/test/test_cppgen.py @@ -180,5 +180,84 @@ def test_cpp_skip_pragma(generate): ] +def test_ipa_classes_ignored(generate): + assert generate([ + schema.Class( + name="X", + ipa=schema.IpaInfo(from_class="A"), + ), + schema.Class( + name="Y", + ipa=schema.IpaInfo(on_arguments={"a": "A", "b": "int"}), + ), + schema.Class( + name="Z", + ), + ]) == [ + cpp.Class(name="Z", final=True, trap_name="Zs"), + ] + + +def test_ipa_hierarchy_ignored(generate): + assert generate([ + schema.Class( + name="Root", + derived={"Base", "Z"}, + ), + schema.Class( + name="Base", + bases=["Root"], + derived={"X", "Y"} + ), + schema.Class( + name="X", + bases=["Base"], + ipa=schema.IpaInfo(from_class="A"), + ), + schema.Class( + name="Y", + bases=["Base"], + ipa=schema.IpaInfo(on_arguments={"a": "A", "b": "int"}), + ), + schema.Class( + name="Z", + ipa=schema.IpaInfo(from_class="A"), + ), + ]) == [] + + +def test_ipa_hierarchy_not_ignored_with_non_ipa_descendant(generate): + root = cpp.Class(name="Root") + base = cpp.Class(name="Base", bases=[root]) + assert generate([ + schema.Class( + name="Root", + derived={"Base", "Z"}, + ), + schema.Class( + name="Base", + bases=["Root"], + derived={"X", "Y"} + ), + schema.Class( + name="X", + bases=["Base"], + ), + schema.Class( + name="Y", + bases=["Base"], + ipa=schema.IpaInfo(on_arguments={"a": "A", "b": "int"}), + ), + schema.Class( + name="Z", + ipa=schema.IpaInfo(from_class="A"), + ), + ]) == [ + root, + base, + cpp.Class(name="X", bases=[base], final=True, trap_name="Xes"), + ] + + if __name__ == '__main__': sys.exit(pytest.main([__file__] + sys.argv[1:])) From 98176007d89ebc991350ad0a9189dc9fccb9ca68 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 15 Nov 2022 17:18:08 +0100 Subject: [PATCH 207/796] C++: Fix type in dataflow test comment --- cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp index 131f0f5d05d..f9df8c9497c 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp @@ -87,7 +87,7 @@ Top *identity(Top *top) { void callIdentityFunctions(Top *top, Bottom *bottom) { identity(bottom)->isSink(source()); // $ MISSING: ast,ir - identity(top)->isSink(source()); // now flow + identity(top)->isSink(source()); // no flow } using SinkFunctionType = void (*)(int); From 1b6317d584c20c89f600ec693cb89be3f78469d6 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 15 Nov 2022 17:19:32 +0000 Subject: [PATCH 208/796] Update swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll Co-authored-by: Mathias Vorreiter Pedersen --- .../lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 565bb4a8e93..afb82dbc9f7 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -170,10 +170,7 @@ private module Cached { // flow through ternary operator `? :` exists(IfExpr ie | nodeTo.asExpr() = ie and - ( - nodeFrom.asExpr() = ie.getThenExpr() or - nodeFrom.asExpr() = ie.getElseExpr() - ) + nodeFrom.asExpr() = ie.getBranch(_) ) or // flow through a flow summary (extension of `SummaryModelCsv`) From 0ce4500b48ae0df011d02348e513e4a453b1201a Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Tue, 15 Nov 2022 18:20:28 +0100 Subject: [PATCH 209/796] Apply suggestions from code review Co-authored-by: Pierre --- .github/ISSUE_TEMPLATE/ql--false-positive.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/ql--false-positive.md b/.github/ISSUE_TEMPLATE/ql--false-positive.md index b3d942ab5d7..7f22c577d14 100644 --- a/.github/ISSUE_TEMPLATE/ql--false-positive.md +++ b/.github/ISSUE_TEMPLATE/ql--false-positive.md @@ -1,6 +1,6 @@ --- -name: False positive -about: Tell us about an alert that shouldn't be reported +name: CodeQL False positive +about: Report CodeQL alerts that you think should not have been detected (not applicable, not exploitable, etc.) title: False positive labels: false-positive assignees: '' @@ -26,7 +26,7 @@ function execSh(command, options) { ``` --> -**URL to the alert on GitHub CodeScanning (optional)** +**URL to the alert on GitHub code scanning (optional)** + + + + + + + + + \ No newline at end of file From 92190e50951da1da027c751845d582ce1f4681e3 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 5 Oct 2022 15:58:38 +0100 Subject: [PATCH 267/796] Add docs --- java/ql/src/Security/CWE/CWE-524/Example.xml | 15 ++++++++ .../CWE/CWE-524/SensitiveKeyboardCache.qhelp | 37 ++++++++++++++++++- .../CWE/CWE-524/SensitiveKeyboardCache.ql | 4 +- 3 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 java/ql/src/Security/CWE/CWE-524/Example.xml diff --git a/java/ql/src/Security/CWE/CWE-524/Example.xml b/java/ql/src/Security/CWE/CWE-524/Example.xml new file mode 100644 index 00000000000..7317eda1618 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-524/Example.xml @@ -0,0 +1,15 @@ + + + + + + + + + \ No newline at end of file diff --git a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp index 4d944060479..29b176b6c07 100644 --- a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp +++ b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp @@ -1 +1,36 @@ -todo \ No newline at end of file + + + + +

    When a user enters information to a text input field on an Android application, then by default their input is saved to a keyboard cache, +which provides autocomplete suggestions and predictions. If the input field is expected to contain sensitive information, such as a password or banking details, +this sensitive data may be leaked to other applications via the keyboard cache.

    + +
    + + +

    For input fields expected to accept sensitive information, an input type such as "textNoSuggestions" (or "textPassword" for a password) +should be used to ensure that the input does not get stored in the keyboard cache.

    + +
    + + +

    In the following example, the field labeled BAD could allow the password to be saved to the keyboard cache; + whereas the field labeled GOOD uses the "textPassword" input type, which ensures that it is not.

    + + + +
    + + +
  • + OWASP Mobile Application Security Testing Guie: Determining Whether the Keyboard Cache Is Disabled for Text Input Fields. +
  • +
  • + Android Developers: android:inputType attribute documentation. +
  • + + + diff --git a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql index 5407b6ac854..81c98ff6598 100644 --- a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql +++ b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql @@ -3,9 +3,9 @@ * @description Sensitive information should not be saved to the keyboard cache. * @kind problem * @problem.severity warning - * @id java/android/debuggable-attribute-enabled + * @id java/android/sensetive-keyboard-cache * @tags security - * external/cwe/cwe-489 + * external/cwe/cwe-524 * @precision high */ From 0bce1894ae0e7ac2a9560c4cd41c1ab31259f59b Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 5 Oct 2022 15:59:14 +0100 Subject: [PATCH 268/796] Remove redundant import --- .../semmle/code/java/security/SensitiveKeyboardCacheQuery.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll index ea87b053ab1..5cb95821a14 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll @@ -1,7 +1,6 @@ /** Definitions for the keyboard cache query */ import java -import semmle.code.xml.XML import semmle.code.java.security.SensitiveActions /** An Android Layout XML file. */ From c085c1f3ad3052c4ed0001cefe5e9fe564c8b56d Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 6 Oct 2022 10:15:01 +0100 Subject: [PATCH 269/796] Fix typos --- .../semmle/code/java/security/SensitiveKeyboardCacheQuery.qll | 2 +- java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp | 4 ++-- java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll index 5cb95821a14..e7fa5f8209c 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll @@ -30,7 +30,7 @@ class AndroidEditableXmlElement extends XmlElement { string getId() { result = id.getValue() } } -/** Gets a regex inidcating that an input field may contain sensitive data. */ +/** Gets a regex indicating that an input field may contain sensitive data. */ private string getInputSensitiveInfoRegex() { result = [ diff --git a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp index 29b176b6c07..2ee1d6577c5 100644 --- a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp +++ b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp @@ -26,10 +26,10 @@ should be used to ensure that the input does not get stored in the keyboard cach
  • - OWASP Mobile Application Security Testing Guie: Determining Whether the Keyboard Cache Is Disabled for Text Input Fields. + OWASP Mobile Application Security Testing Guide: Determining Whether the Keyboard Cache Is Disabled for Text Input Fields.
  • - Android Developers: android:inputType attribute documentation. + Android Developers: android:inputType attribute documentation.
  • diff --git a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql index 81c98ff6598..5a1608044d8 100644 --- a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql +++ b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql @@ -1,9 +1,9 @@ /** - * @name Android sensetive keyboard cache + * @name Android sensitive keyboard cache * @description Sensitive information should not be saved to the keyboard cache. * @kind problem * @problem.severity warning - * @id java/android/sensetive-keyboard-cache + * @id java/android/sensitive-keyboard-cache * @tags security * external/cwe/cwe-524 * @precision high From 775a5507a67e52f4de32fe2401f8ce7b7238289f Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 6 Oct 2022 11:26:41 +0100 Subject: [PATCH 270/796] Add security severity --- java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql index 5a1608044d8..5375aad04e0 100644 --- a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql +++ b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql @@ -3,6 +3,7 @@ * @description Sensitive information should not be saved to the keyboard cache. * @kind problem * @problem.severity warning + * @security-severity 8.1 * @id java/android/sensitive-keyboard-cache * @tags security * external/cwe/cwe-524 From b4216767ad62910c1ad35bd299ed42348717b4e1 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 7 Oct 2022 14:32:36 +0100 Subject: [PATCH 271/796] Add change note --- .../src/change-notes/2022-10-07-sensitive-keyboard-cache.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/src/change-notes/2022-10-07-sensitive-keyboard-cache.md diff --git a/java/ql/src/change-notes/2022-10-07-sensitive-keyboard-cache.md b/java/ql/src/change-notes/2022-10-07-sensitive-keyboard-cache.md new file mode 100644 index 00000000000..21a1652cc93 --- /dev/null +++ b/java/ql/src/change-notes/2022-10-07-sensitive-keyboard-cache.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `java/android/sensitive-keyboard-cache`, to detect instances of sensitive information possibly being saved to the keyboard cache. \ No newline at end of file From e6dd3673a11ebf929fb00e5ba641e8853d87f86b Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 7 Oct 2022 15:18:29 +0100 Subject: [PATCH 272/796] Fix qldoc --- java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp index 2ee1d6577c5..bef79d279a1 100644 --- a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp +++ b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp @@ -29,8 +29,8 @@ should be used to ensure that the input does not get stored in the keyboard cach OWASP Mobile Application Security Testing Guide: Determining Whether the Keyboard Cache Is Disabled for Text Input Fields.
  • - Android Developers: android:inputType attribute documentation. -
  • + Android Developers: android:inputType attribute documentation. +
  • From f48b57c95ad8a40a7bbb0a4fd700d0be30b0973c Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 13 Oct 2022 13:23:47 +0100 Subject: [PATCH 273/796] Apply review suggestions --- .../java/security/SensitiveKeyboardCacheQuery.qll | 11 +++++------ .../Security/CWE/CWE-524/SensitiveKeyboardCache.ql | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll index e7fa5f8209c..c5d52a42eac 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll @@ -2,24 +2,23 @@ import java import semmle.code.java.security.SensitiveActions +import semmle.code.xml.AndroidManifest /** An Android Layout XML file. */ -class AndroidLayoutXmlFile extends XmlFile { - AndroidLayoutXmlFile() { this.getAbsolutePath().matches("%/res/layout/%.xml") } +private class AndroidLayoutXmlFile extends XmlFile { + AndroidLayoutXmlFile() { this.getRelativePath().matches("%/res/layout/%.xml") } } /** An XML element that represents an editable text field. */ class AndroidEditableXmlElement extends XmlElement { - XmlAttribute inputType; - XmlAttribute id; + AndroidXmlAttribute inputType; + AndroidXmlAttribute id; AndroidEditableXmlElement() { this.getFile() instanceof AndroidLayoutXmlFile and inputType = this.getAnAttribute() and - inputType.getNamespace().getPrefix() = "android" and inputType.getName() = "inputType" and id = this.getAnAttribute() and - id.getNamespace().getPrefix() = "android" and id.getName() = "id" } diff --git a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql index 5375aad04e0..559695e056d 100644 --- a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql +++ b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql @@ -7,7 +7,7 @@ * @id java/android/sensitive-keyboard-cache * @tags security * external/cwe/cwe-524 - * @precision high + * @precision medium */ import java From 359d703dede438f61d5f2d8c634396ffe9c5abbe Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 28 Oct 2022 16:07:35 +0100 Subject: [PATCH 274/796] More precise layout xml handling --- .../security/SensitiveKeyboardCacheQuery.qll | 40 +++++++++++++------ .../query-tests/security/CWE-524/Test.java | 2 + .../test/query-tests/security/CWE-524/options | 1 + 3 files changed, 31 insertions(+), 12 deletions(-) create mode 100644 java/ql/test/query-tests/security/CWE-524/options diff --git a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll index c5d52a42eac..df7cfb6219d 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll @@ -9,24 +9,40 @@ private class AndroidLayoutXmlFile extends XmlFile { AndroidLayoutXmlFile() { this.getRelativePath().matches("%/res/layout/%.xml") } } -/** An XML element that represents an editable text field. */ -class AndroidEditableXmlElement extends XmlElement { - AndroidXmlAttribute inputType; +/** A component declared in an Android layout file. */ +class AndroidLayoutXmlElement extends XmlElement { AndroidXmlAttribute id; - AndroidEditableXmlElement() { + AndroidLayoutXmlElement() { this.getFile() instanceof AndroidLayoutXmlFile and - inputType = this.getAnAttribute() and - inputType.getName() = "inputType" and - id = this.getAnAttribute() and - id.getName() = "id" + id = this.getAttribute("id") } - /** Gets the input type of this field. */ - string getInputType() { result = inputType.getValue() } - - /** Gets the ID of this field. */ + /** Gets the ID of this component. */ string getId() { result = id.getValue() } + + /** Gets the class of this component. */ + Class getClass() { + this.getName() = "view" and + this.getAttribute("class").getValue() = result.getQualifiedName() + or + this.getName() = result.getQualifiedName() + or + result.hasQualifiedName(["android.widget", "android.view"], this.getName()) + } +} + +/** An XML element that represents an editable text field. */ +class AndroidEditableXmlElement extends AndroidLayoutXmlElement { + AndroidEditableXmlElement() { + exists(Class editText | + editText.hasQualifiedName("android.widget", "EditText") and + editText = this.getClass().getASourceSupertype*() + ) + } + + /** Gets the input type of this field, if any. */ + string getInputType() { result = this.getAttribute("inputType").(AndroidXmlAttribute).getValue() } } /** Gets a regex indicating that an input field may contain sensitive data. */ diff --git a/java/ql/test/query-tests/security/CWE-524/Test.java b/java/ql/test/query-tests/security/CWE-524/Test.java index 183c3f5b3be..6bdb6d3f9f5 100644 --- a/java/ql/test/query-tests/security/CWE-524/Test.java +++ b/java/ql/test/query-tests/security/CWE-524/Test.java @@ -1 +1,3 @@ +import android.widget.EditText; + class Test {} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-524/options b/java/ql/test/query-tests/security/CWE-524/options new file mode 100644 index 00000000000..126d514284a --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-524/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/google-android-9.0.0 \ No newline at end of file From 10a3b3bd14e755cb109506d0d3f8eb81dd271c08 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 31 Oct 2022 14:41:07 +0000 Subject: [PATCH 275/796] Cover cases in which input type is set via code --- .../security/SensitiveKeyboardCacheQuery.qll | 69 ++++++++++++++++++- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll index df7cfb6219d..1991af10ee1 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll @@ -1,6 +1,7 @@ /** Definitions for the keyboard cache query */ import java +import semmle.code.java.dataflow.DataFlow import semmle.code.java.security.SensitiveActions import semmle.code.xml.AndroidManifest @@ -45,6 +46,62 @@ class AndroidEditableXmlElement extends AndroidLayoutXmlElement { string getInputType() { result = this.getAttribute("inputType").(AndroidXmlAttribute).getValue() } } +/** Gets a use of the view that has the given id. */ +private Expr getAUseOfId(string id) { + exists(string name, MethodAccess findView, NestedClass r_id, Field id_field | + id = "@+id/" + name and + findView + .getMethod() + .hasQualifiedName("android.view", "View", ["findViewById", "requireViewById"]) and + r_id.getEnclosingType().hasName("R") and + r_id.hasName("id") and + id_field.getDeclaringType() = r_id and + id_field.hasName(name) + | + DataFlow::localExprFlow(id_field.getAnAccess(), findView.getArgument(0)) and + result = findView + ) +} + +/** Gets the argument of a use of `setInputType` called on the view with the given id. */ +private Expr setInputTypeForId(string id) { + exists(MethodAccess setInputType | + setInputType.getMethod().hasQualifiedName("android.widget", "TextView", "setInputType") and + DataFlow::localExprFlow(getAUseOfId(id), setInputType.getQualifier()) and + result = setInputType.getArgument(0) + ) +} + +/** Holds if the given field is a constant flag indicating that an input with this type will not be cached. */ +private predicate inputTypeFieldNotCached(Field f) { + f.getDeclaringType().hasQualifiedName("android.text", "InputType") and + ( + not f.getName().matches("%TEXT%") + or + f.getName().matches("%PASSWORD%") + or + f.getName() = "TYPE_TEXT_FLAG_NO_SUGGESTIONS" + ) +} + +/** Configuration that finds uses of `setInputType` that for non cached fields. */ +private class GoodInputTypeConf extends DataFlow::Configuration { + GoodInputTypeConf() { this = "GoodInputTypeConf" } + + override predicate isSource(DataFlow::Node node) { + inputTypeFieldNotCached(node.asExpr().(FieldAccess).getField()) + } + + override predicate isSink(DataFlow::Node node) { node.asExpr() = setInputTypeForId(_) } + + override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(OrBitwiseExpr bitOr | + node1.asExpr() = bitOr.getAChildExpr() and + node2.asExpr() = bitOr + ) + } +} + /** Gets a regex indicating that an input field may contain sensitive data. */ private string getInputSensitiveInfoRegex() { result = @@ -54,7 +111,7 @@ private string getInputSensitiveInfoRegex() { ] } -/** Holds if input using the given input type may be stored in the keyboard cache. */ +/** Holds if input using the given input type (as written in XML) may be stored in the keyboard cache. */ bindingset[ty] private predicate inputTypeCached(string ty) { ty.matches("%text%") and @@ -64,5 +121,13 @@ private predicate inputTypeCached(string ty) { /** Gets an input field whose contents may be sensitive and may be stored in the keyboard cache. */ AndroidEditableXmlElement getASensitiveCachedInput() { result.getId().regexpMatch(getInputSensitiveInfoRegex()) and - inputTypeCached(result.getInputType()) + ( + inputTypeCached(result.getInputType()) + or + not exists(result.getInputType()) and + not exists(GoodInputTypeConf conf, DataFlow::Node src, DataFlow::Node sink | + conf.hasFlow(src, sink) and + sink.asExpr() = setInputTypeForId(result.getId()) + ) + ) } From dd4e1d0ac3b90a5e889fc825a183d65b8959037a Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 31 Oct 2022 16:08:28 +0000 Subject: [PATCH 276/796] Add tests and fix issues --- .../security/SensitiveKeyboardCacheQuery.qll | 16 +++++++++++++--- .../CWE/CWE-524/SensitiveKeyboardCache.qhelp | 2 +- java/ql/test/query-tests/security/CWE-524/R.java | 8 ++++++++ .../test/query-tests/security/CWE-524/Test.java | 15 ++++++++++++++- .../security/CWE-524/res/layout/Test.xml | 9 +++++++++ .../android/app/Activity.java | 4 ++++ 6 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 java/ql/test/query-tests/security/CWE-524/R.java diff --git a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll index 1991af10ee1..4937d397b63 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll @@ -46,13 +46,23 @@ class AndroidEditableXmlElement extends AndroidLayoutXmlElement { string getInputType() { result = this.getAttribute("inputType").(AndroidXmlAttribute).getValue() } } +/** A `findViewById` or `requireViewById` method on `Activity` or `View`. */ +private class FindViewMethod extends Method { + FindViewMethod() { + hasQualifiedName("android.view", "View", ["findViewById", "requireViewById"]) + or + exists(Method m | + m.hasQualifiedName("android.app", "Activity", ["findViewById", "requireViewById"]) and + this = m.getAnOverride*() + ) + } +} + /** Gets a use of the view that has the given id. */ private Expr getAUseOfId(string id) { exists(string name, MethodAccess findView, NestedClass r_id, Field id_field | id = "@+id/" + name and - findView - .getMethod() - .hasQualifiedName("android.view", "View", ["findViewById", "requireViewById"]) and + findView.getMethod() instanceof FindViewMethod and r_id.getEnclosingType().hasName("R") and r_id.hasName("id") and id_field.getDeclaringType() = r_id and diff --git a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp index bef79d279a1..072506410bf 100644 --- a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp +++ b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp @@ -13,7 +13,7 @@ this sensitive data may be leaked to other applications via the keyboard cache.<

    For input fields expected to accept sensitive information, an input type such as "textNoSuggestions" (or "textPassword" for a password) should be used to ensure that the input does not get stored in the keyboard cache.

    - +

    The input type can also be set in code through TextView.setInputType() rather than declared through XML.

    diff --git a/java/ql/test/query-tests/security/CWE-524/R.java b/java/ql/test/query-tests/security/CWE-524/R.java new file mode 100644 index 00000000000..46eb99e1b7b --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-524/R.java @@ -0,0 +1,8 @@ +package com.example.test; + +public final class R { + public static final class id { + public static final int test7_password = 1; + public static final int test8_password = 2; + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-524/Test.java b/java/ql/test/query-tests/security/CWE-524/Test.java index 6bdb6d3f9f5..0ceff44adde 100644 --- a/java/ql/test/query-tests/security/CWE-524/Test.java +++ b/java/ql/test/query-tests/security/CWE-524/Test.java @@ -1,3 +1,16 @@ +package com.example.test; +import android.app.Activity; +import android.os.Bundle; import android.widget.EditText; +import android.view.View; +import android.text.InputType; -class Test {} \ No newline at end of file +class Test extends Activity { + public void onCreate(Bundle b) { + EditText test7pw = findViewById(R.id.test7_password); + test7pw.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); + + EditText test8pw = requireViewById(R.id.test8_password); + test8pw.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-524/res/layout/Test.xml b/java/ql/test/query-tests/security/CWE-524/res/layout/Test.xml index 11f379a7005..107c13dd306 100644 --- a/java/ql/test/query-tests/security/CWE-524/res/layout/Test.xml +++ b/java/ql/test/query-tests/security/CWE-524/res/layout/Test.xml @@ -23,4 +23,13 @@ + + + + + + \ No newline at end of file diff --git a/java/ql/test/stubs/google-android-9.0.0/android/app/Activity.java b/java/ql/test/stubs/google-android-9.0.0/android/app/Activity.java index cad1d58cad5..f292c6b1168 100644 --- a/java/ql/test/stubs/google-android-9.0.0/android/app/Activity.java +++ b/java/ql/test/stubs/google-android-9.0.0/android/app/Activity.java @@ -488,4 +488,8 @@ public class Activity extends ContextWrapper { public T findViewById(int id) { return null; } + + public T requireViewById(int id) { + return null; + } } From 63f715e650ba06ee8a37c4a34e7e883591e15fb0 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 1 Nov 2022 11:29:09 +0000 Subject: [PATCH 277/796] fix implicit this --- .../semmle/code/java/security/SensitiveKeyboardCacheQuery.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll index 4937d397b63..d2d75b49bd0 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll @@ -49,7 +49,7 @@ class AndroidEditableXmlElement extends AndroidLayoutXmlElement { /** A `findViewById` or `requireViewById` method on `Activity` or `View`. */ private class FindViewMethod extends Method { FindViewMethod() { - hasQualifiedName("android.view", "View", ["findViewById", "requireViewById"]) + this.hasQualifiedName("android.view", "View", ["findViewById", "requireViewById"]) or exists(Method m | m.hasQualifiedName("android.app", "Activity", ["findViewById", "requireViewById"]) and From 6d465aaf52e88a34efd38ebbd713e7eeabd0bd86 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 8 Nov 2022 14:55:13 +0000 Subject: [PATCH 278/796] Apply code review suggestions --- .../security/SensitiveKeyboardCacheQuery.qll | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll index d2d75b49bd0..12c44b50f49 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll @@ -36,10 +36,7 @@ class AndroidLayoutXmlElement extends XmlElement { /** An XML element that represents an editable text field. */ class AndroidEditableXmlElement extends AndroidLayoutXmlElement { AndroidEditableXmlElement() { - exists(Class editText | - editText.hasQualifiedName("android.widget", "EditText") and - editText = this.getClass().getASourceSupertype*() - ) + this.getClass().getASourceSupertype*().hasQualifiedName("android.widget", "EditText") } /** Gets the input type of this field, if any. */ @@ -59,25 +56,24 @@ private class FindViewMethod extends Method { } /** Gets a use of the view that has the given id. */ -private Expr getAUseOfId(string id) { - exists(string name, MethodAccess findView, NestedClass r_id, Field id_field | +private MethodAccess getAUseOfViewWithId(string id) { + exists(string name, NestedClass r_id, Field id_field | id = "@+id/" + name and - findView.getMethod() instanceof FindViewMethod and + result.getMethod() instanceof FindViewMethod and r_id.getEnclosingType().hasName("R") and r_id.hasName("id") and id_field.getDeclaringType() = r_id and id_field.hasName(name) | - DataFlow::localExprFlow(id_field.getAnAccess(), findView.getArgument(0)) and - result = findView + DataFlow::localExprFlow(id_field.getAnAccess(), result.getArgument(0)) ) } /** Gets the argument of a use of `setInputType` called on the view with the given id. */ -private Expr setInputTypeForId(string id) { +private Argument setInputTypeForId(string id) { exists(MethodAccess setInputType | setInputType.getMethod().hasQualifiedName("android.widget", "TextView", "setInputType") and - DataFlow::localExprFlow(getAUseOfId(id), setInputType.getQualifier()) and + DataFlow::localExprFlow(getAUseOfViewWithId(id), setInputType.getQualifier()) and result = setInputType.getArgument(0) ) } @@ -90,11 +86,11 @@ private predicate inputTypeFieldNotCached(Field f) { or f.getName().matches("%PASSWORD%") or - f.getName() = "TYPE_TEXT_FLAG_NO_SUGGESTIONS" + f.hasName("TYPE_TEXT_FLAG_NO_SUGGESTIONS") ) } -/** Configuration that finds uses of `setInputType` that for non cached fields. */ +/** Configuration that finds uses of `setInputType` for non cached fields. */ private class GoodInputTypeConf extends DataFlow::Configuration { GoodInputTypeConf() { this = "GoodInputTypeConf" } From 7ae41ff1659091481bb074b0e8a3d91ced6226ba Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 8 Nov 2022 16:33:42 +0000 Subject: [PATCH 279/796] Invert the xml logic to be consistent with the dataflow logic --- .../java/security/SensitiveKeyboardCacheQuery.qll | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll index 12c44b50f49..e7b5112a44a 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll @@ -117,20 +117,19 @@ private string getInputSensitiveInfoRegex() { ] } -/** Holds if input using the given input type (as written in XML) may be stored in the keyboard cache. */ +/** Holds if input using the given input type (as written in XML) is not stored in the keyboard cache. */ bindingset[ty] -private predicate inputTypeCached(string ty) { - ty.matches("%text%") and - not ty.regexpMatch("(?i).*(nosuggestions|password).*") +private predicate inputTypeNotCached(string ty) { + not ty.matches("%text%") + or + ty.regexpMatch("(?i).*(nosuggestions|password).*") } /** Gets an input field whose contents may be sensitive and may be stored in the keyboard cache. */ AndroidEditableXmlElement getASensitiveCachedInput() { result.getId().regexpMatch(getInputSensitiveInfoRegex()) and ( - inputTypeCached(result.getInputType()) - or - not exists(result.getInputType()) and + not inputTypeNotCached(result.getInputType()) and not exists(GoodInputTypeConf conf, DataFlow::Node src, DataFlow::Node sink | conf.hasFlow(src, sink) and sink.asExpr() = setInputTypeForId(result.getId()) From 255123cbf9285694438d5e61b5e0e72d690da166 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 15 Nov 2022 16:57:48 +0000 Subject: [PATCH 280/796] Apply suggestions from docs review Co-authored-by: Sam Browning <106113886+sabrowning1@users.noreply.github.com> --- .../Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp | 11 ++++------- .../Security/CWE/CWE-524/SensitiveKeyboardCache.ql | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp index 072506410bf..6b0b5eb96f6 100644 --- a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp +++ b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp @@ -4,21 +4,18 @@ -

    When a user enters information to a text input field on an Android application, then by default their input is saved to a keyboard cache, -which provides autocomplete suggestions and predictions. If the input field is expected to contain sensitive information, such as a password or banking details, -this sensitive data may be leaked to other applications via the keyboard cache.

    +

    When a user enters information in a text input field on an Android application, their input is saved to a keyboard cache which provides autocomplete suggestions and predictions. There is a risk that sensitive user data, such as passwords or banking information, may be leaked to other applications via the keyboard cache.

    -

    For input fields expected to accept sensitive information, an input type such as "textNoSuggestions" (or "textPassword" for a password) -should be used to ensure that the input does not get stored in the keyboard cache.

    +

    For input fields expected to accept sensitive information, use input types such as "textNoSuggestions" (or "textPassword" for a password) to ensure the input does not get stored in the keyboard cache.

    The input type can also be set in code through TextView.setInputType() rather than declared through XML.

    -

    In the following example, the field labeled BAD could allow the password to be saved to the keyboard cache; - whereas the field labeled GOOD uses the "textPassword" input type, which ensures that it is not.

    +

    In the following example, the field labeled BAD allows the password to be saved to the keyboard cache, + whereas the field labeled GOOD uses the "textPassword" input type to ensure the password is not cached.

    diff --git a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql index 559695e056d..d5a7bc50c05 100644 --- a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql +++ b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql @@ -1,6 +1,6 @@ /** * @name Android sensitive keyboard cache - * @description Sensitive information should not be saved to the keyboard cache. + * @description Allowing the keyboard to cache sensitive information may result in information leaks to other applications. * @kind problem * @problem.severity warning * @security-severity 8.1 From cc960377acb6b697f1b7fbaff3b40374c380acd6 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 16 Nov 2022 10:53:40 +0000 Subject: [PATCH 281/796] Apply suggestion from docs review Co-authored-by: Sam Browning <106113886+sabrowning1@users.noreply.github.com> --- java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp index 6b0b5eb96f6..7a16bbd6f80 100644 --- a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp +++ b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp @@ -10,7 +10,7 @@

    For input fields expected to accept sensitive information, use input types such as "textNoSuggestions" (or "textPassword" for a password) to ensure the input does not get stored in the keyboard cache.

    -

    The input type can also be set in code through TextView.setInputType() rather than declared through XML.

    +

    Optionally, instead of declaring an input type through XML, you can set the input type in your code using TextView.setInputType().

    From 55dc929a1fc50e662b89b2b5c8f1cf52d003b43c Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 11:57:05 +0100 Subject: [PATCH 282/796] Kotlin: Add test case for confusing overloading query --- .../ConfusingOverloading.expected} | 0 .../ConfusingOverloading.qlref} | 0 .../Test.kt | 6 ++++++ 3 files changed, 6 insertions(+) rename java/ql/test/kotlin/query-tests/{ConfusingMethodSignature/ConfusingMethodSignature.expected => ConfusingOverloading/ConfusingOverloading.expected} (100%) rename java/ql/test/kotlin/query-tests/{ConfusingMethodSignature/ConfusingMethodSignature.qlref => ConfusingOverloading/ConfusingOverloading.qlref} (100%) rename java/ql/test/kotlin/query-tests/{ConfusingMethodSignature => ConfusingOverloading}/Test.kt (78%) diff --git a/java/ql/test/kotlin/query-tests/ConfusingMethodSignature/ConfusingMethodSignature.expected b/java/ql/test/kotlin/query-tests/ConfusingOverloading/ConfusingOverloading.expected similarity index 100% rename from java/ql/test/kotlin/query-tests/ConfusingMethodSignature/ConfusingMethodSignature.expected rename to java/ql/test/kotlin/query-tests/ConfusingOverloading/ConfusingOverloading.expected diff --git a/java/ql/test/kotlin/query-tests/ConfusingMethodSignature/ConfusingMethodSignature.qlref b/java/ql/test/kotlin/query-tests/ConfusingOverloading/ConfusingOverloading.qlref similarity index 100% rename from java/ql/test/kotlin/query-tests/ConfusingMethodSignature/ConfusingMethodSignature.qlref rename to java/ql/test/kotlin/query-tests/ConfusingOverloading/ConfusingOverloading.qlref diff --git a/java/ql/test/kotlin/query-tests/ConfusingMethodSignature/Test.kt b/java/ql/test/kotlin/query-tests/ConfusingOverloading/Test.kt similarity index 78% rename from java/ql/test/kotlin/query-tests/ConfusingMethodSignature/Test.kt rename to java/ql/test/kotlin/query-tests/ConfusingOverloading/Test.kt index b802d9f76a0..37dbe32f378 100644 --- a/java/ql/test/kotlin/query-tests/ConfusingMethodSignature/Test.kt +++ b/java/ql/test/kotlin/query-tests/ConfusingOverloading/Test.kt @@ -12,3 +12,9 @@ class A { fun fn(value: T, i: Int = 1) {} fun fn(value: String, i: Int = 1) {} } + +class Foo { + val str by lazy { + "someString" + } +} From bafb9ae0201a612de0864227580be70e365c0650 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 16 Nov 2022 12:00:26 +0100 Subject: [PATCH 283/796] Swift: add upgrade/downgrade scripts --- .../old.dbscheme | 2478 ++++++++++++++++ .../swift.dbscheme | 2493 +++++++++++++++++ .../upgrade.properties | 2 + .../old.dbscheme | 2493 +++++++++++++++++ .../swift.dbscheme | 2478 ++++++++++++++++ .../upgrade.properties | 5 + 6 files changed, 9949 insertions(+) create mode 100644 swift/downgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/old.dbscheme create mode 100644 swift/downgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/swift.dbscheme create mode 100644 swift/downgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/upgrade.properties create mode 100644 swift/ql/lib/upgrades/ceca289a0ff56bcc88f72ad78a8fbff1d850922f/old.dbscheme create mode 100644 swift/ql/lib/upgrades/ceca289a0ff56bcc88f72ad78a8fbff1d850922f/swift.dbscheme create mode 100644 swift/ql/lib/upgrades/ceca289a0ff56bcc88f72ad78a8fbff1d850922f/upgrade.properties diff --git a/swift/downgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/old.dbscheme b/swift/downgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/old.dbscheme new file mode 100644 index 00000000000..abbb8c9e840 --- /dev/null +++ b/swift/downgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/old.dbscheme @@ -0,0 +1,2478 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @iterable_decl_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @case_label_item +| @condition_element +| @decl +| @expr +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +@decl = + @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +@generic_context = + @abstract_function_decl +| @extension_decl +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +@iterable_decl_context = + @extension_decl +| @nominal_type_decl +; + +#keyset[id, index] +iterable_decl_context_members( //dir=decl + int id: @iterable_decl_context ref, + int index: int ref, + int member: @decl_or_none ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_function_decl +| @abstract_storage_decl +| @enum_element_decl +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_function_decl = + @constructor_decl +| @destructor_decl +| @func_decl +; + +#keyset[id] +abstract_function_decls( //dir=decl + int id: @abstract_function_decl ref, + string name: string ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessor_decls( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor_decl: @accessor_decl_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +constructor_decls( //dir=decl + unique int id: @constructor_decl +); + +destructor_decls( //dir=decl + unique int id: @destructor_decl +); + +@func_decl = + @accessor_decl +| @concrete_func_decl +; + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id, index] +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessor_decls( //dir=decl + unique int id: @accessor_decl +); + +#keyset[id] +accessor_decl_is_getter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_setter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_will_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_did_set( //dir=decl + int id: @accessor_decl ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_func_decls( //dir=decl + unique int id: @concrete_func_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @abstract_closure_expr +| @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initializer_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_constructor_decl_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_constructor_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@abstract_closure_expr = + @auto_closure_expr +| @closure_expr +; + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id] +key_path_expr_parsed_paths( //dir=expr + int id: @key_path_expr ref, + int parsed_path: @expr_or_none ref +); + +lazy_initializer_exprs( //dir=expr + unique int id: @lazy_initializer_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @abstract_function_decl_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_constructor_decl_ref_exprs( //dir=expr + unique int id: @other_constructor_decl_ref_expr, + int constructor_decl: @constructor_decl_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_constructor_exprs( //dir=expr + unique int id: @rebind_self_in_constructor_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +closure_exprs( //dir=expr + unique int id: @closure_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr +); + +@self_apply_expr = + @constructor_ref_call_expr +| @dot_syntax_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +constructor_ref_call_exprs( //dir=expr + unique int id: @constructor_ref_call_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_labels( //dir=type + int id: @any_function_type ref, + int index: int ref, + string param_label: string ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@abstract_function_decl_or_none = + @abstract_function_decl +| @unspecified_element +; + +@accessor_decl_or_none = + @accessor_decl +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@constructor_decl_or_none = + @constructor_decl +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/downgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/swift.dbscheme b/swift/downgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/swift.dbscheme new file mode 100644 index 00000000000..ceca289a0ff --- /dev/null +++ b/swift/downgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/swift.dbscheme @@ -0,0 +1,2493 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @iterable_decl_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +@file = + @db_file +| @unknown_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +| @unknown_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @case_label_item +| @condition_element +| @decl +| @expr +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +unknown_files( + unique int id: @unknown_file +); + +unknown_locations( + unique int id: @unknown_location +); + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +@decl = + @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +@generic_context = + @abstract_function_decl +| @extension_decl +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +@iterable_decl_context = + @extension_decl +| @nominal_type_decl +; + +#keyset[id, index] +iterable_decl_context_members( //dir=decl + int id: @iterable_decl_context ref, + int index: int ref, + int member: @decl_or_none ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_function_decl +| @abstract_storage_decl +| @enum_element_decl +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_function_decl = + @constructor_decl +| @destructor_decl +| @func_decl +; + +#keyset[id] +abstract_function_decls( //dir=decl + int id: @abstract_function_decl ref, + string name: string ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessor_decls( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor_decl: @accessor_decl_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +constructor_decls( //dir=decl + unique int id: @constructor_decl +); + +destructor_decls( //dir=decl + unique int id: @destructor_decl +); + +@func_decl = + @accessor_decl +| @concrete_func_decl +; + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id, index] +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessor_decls( //dir=decl + unique int id: @accessor_decl +); + +#keyset[id] +accessor_decl_is_getter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_setter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_will_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_did_set( //dir=decl + int id: @accessor_decl ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_func_decls( //dir=decl + unique int id: @concrete_func_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @abstract_closure_expr +| @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initializer_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_constructor_decl_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_constructor_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@abstract_closure_expr = + @auto_closure_expr +| @closure_expr +; + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id] +key_path_expr_parsed_paths( //dir=expr + int id: @key_path_expr ref, + int parsed_path: @expr_or_none ref +); + +lazy_initializer_exprs( //dir=expr + unique int id: @lazy_initializer_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @method_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @abstract_function_decl_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_constructor_decl_ref_exprs( //dir=expr + unique int id: @other_constructor_decl_ref_expr, + int constructor_decl: @constructor_decl_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_constructor_exprs( //dir=expr + unique int id: @rebind_self_in_constructor_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +closure_exprs( //dir=expr + unique int id: @closure_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +method_ref_exprs( //dir=expr + unique int id: @method_ref_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr +); + +@self_apply_expr = + @constructor_ref_call_expr +| @dot_syntax_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +constructor_ref_call_exprs( //dir=expr + unique int id: @constructor_ref_call_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_labels( //dir=type + int id: @any_function_type ref, + int index: int ref, + string param_label: string ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@abstract_function_decl_or_none = + @abstract_function_decl +| @unspecified_element +; + +@accessor_decl_or_none = + @accessor_decl +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@constructor_decl_or_none = + @constructor_decl +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/downgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/upgrade.properties b/swift/downgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/upgrade.properties new file mode 100644 index 00000000000..7b33ab56770 --- /dev/null +++ b/swift/downgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/upgrade.properties @@ -0,0 +1,2 @@ +description: Remove unfilled tables that were generated for actually synthesized QL types +compatibility: full diff --git a/swift/ql/lib/upgrades/ceca289a0ff56bcc88f72ad78a8fbff1d850922f/old.dbscheme b/swift/ql/lib/upgrades/ceca289a0ff56bcc88f72ad78a8fbff1d850922f/old.dbscheme new file mode 100644 index 00000000000..ceca289a0ff --- /dev/null +++ b/swift/ql/lib/upgrades/ceca289a0ff56bcc88f72ad78a8fbff1d850922f/old.dbscheme @@ -0,0 +1,2493 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @iterable_decl_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +@file = + @db_file +| @unknown_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +| @unknown_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @case_label_item +| @condition_element +| @decl +| @expr +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +unknown_files( + unique int id: @unknown_file +); + +unknown_locations( + unique int id: @unknown_location +); + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +@decl = + @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +@generic_context = + @abstract_function_decl +| @extension_decl +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +@iterable_decl_context = + @extension_decl +| @nominal_type_decl +; + +#keyset[id, index] +iterable_decl_context_members( //dir=decl + int id: @iterable_decl_context ref, + int index: int ref, + int member: @decl_or_none ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_function_decl +| @abstract_storage_decl +| @enum_element_decl +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_function_decl = + @constructor_decl +| @destructor_decl +| @func_decl +; + +#keyset[id] +abstract_function_decls( //dir=decl + int id: @abstract_function_decl ref, + string name: string ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessor_decls( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor_decl: @accessor_decl_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +constructor_decls( //dir=decl + unique int id: @constructor_decl +); + +destructor_decls( //dir=decl + unique int id: @destructor_decl +); + +@func_decl = + @accessor_decl +| @concrete_func_decl +; + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id, index] +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessor_decls( //dir=decl + unique int id: @accessor_decl +); + +#keyset[id] +accessor_decl_is_getter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_setter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_will_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_did_set( //dir=decl + int id: @accessor_decl ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_func_decls( //dir=decl + unique int id: @concrete_func_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @abstract_closure_expr +| @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initializer_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_constructor_decl_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_constructor_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@abstract_closure_expr = + @auto_closure_expr +| @closure_expr +; + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id] +key_path_expr_parsed_paths( //dir=expr + int id: @key_path_expr ref, + int parsed_path: @expr_or_none ref +); + +lazy_initializer_exprs( //dir=expr + unique int id: @lazy_initializer_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @method_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @abstract_function_decl_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_constructor_decl_ref_exprs( //dir=expr + unique int id: @other_constructor_decl_ref_expr, + int constructor_decl: @constructor_decl_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_constructor_exprs( //dir=expr + unique int id: @rebind_self_in_constructor_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +closure_exprs( //dir=expr + unique int id: @closure_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +method_ref_exprs( //dir=expr + unique int id: @method_ref_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr +); + +@self_apply_expr = + @constructor_ref_call_expr +| @dot_syntax_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +constructor_ref_call_exprs( //dir=expr + unique int id: @constructor_ref_call_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_labels( //dir=type + int id: @any_function_type ref, + int index: int ref, + string param_label: string ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@abstract_function_decl_or_none = + @abstract_function_decl +| @unspecified_element +; + +@accessor_decl_or_none = + @accessor_decl +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@constructor_decl_or_none = + @constructor_decl +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/ql/lib/upgrades/ceca289a0ff56bcc88f72ad78a8fbff1d850922f/swift.dbscheme b/swift/ql/lib/upgrades/ceca289a0ff56bcc88f72ad78a8fbff1d850922f/swift.dbscheme new file mode 100644 index 00000000000..abbb8c9e840 --- /dev/null +++ b/swift/ql/lib/upgrades/ceca289a0ff56bcc88f72ad78a8fbff1d850922f/swift.dbscheme @@ -0,0 +1,2478 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @iterable_decl_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @case_label_item +| @condition_element +| @decl +| @expr +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +@decl = + @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +@generic_context = + @abstract_function_decl +| @extension_decl +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +@iterable_decl_context = + @extension_decl +| @nominal_type_decl +; + +#keyset[id, index] +iterable_decl_context_members( //dir=decl + int id: @iterable_decl_context ref, + int index: int ref, + int member: @decl_or_none ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_function_decl +| @abstract_storage_decl +| @enum_element_decl +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_function_decl = + @constructor_decl +| @destructor_decl +| @func_decl +; + +#keyset[id] +abstract_function_decls( //dir=decl + int id: @abstract_function_decl ref, + string name: string ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessor_decls( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor_decl: @accessor_decl_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +constructor_decls( //dir=decl + unique int id: @constructor_decl +); + +destructor_decls( //dir=decl + unique int id: @destructor_decl +); + +@func_decl = + @accessor_decl +| @concrete_func_decl +; + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id, index] +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessor_decls( //dir=decl + unique int id: @accessor_decl +); + +#keyset[id] +accessor_decl_is_getter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_setter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_will_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_did_set( //dir=decl + int id: @accessor_decl ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_func_decls( //dir=decl + unique int id: @concrete_func_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @abstract_closure_expr +| @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initializer_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_constructor_decl_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_constructor_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@abstract_closure_expr = + @auto_closure_expr +| @closure_expr +; + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id] +key_path_expr_parsed_paths( //dir=expr + int id: @key_path_expr ref, + int parsed_path: @expr_or_none ref +); + +lazy_initializer_exprs( //dir=expr + unique int id: @lazy_initializer_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @abstract_function_decl_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_constructor_decl_ref_exprs( //dir=expr + unique int id: @other_constructor_decl_ref_expr, + int constructor_decl: @constructor_decl_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_constructor_exprs( //dir=expr + unique int id: @rebind_self_in_constructor_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +closure_exprs( //dir=expr + unique int id: @closure_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr +); + +@self_apply_expr = + @constructor_ref_call_expr +| @dot_syntax_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +constructor_ref_call_exprs( //dir=expr + unique int id: @constructor_ref_call_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_labels( //dir=type + int id: @any_function_type ref, + int index: int ref, + string param_label: string ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@abstract_function_decl_or_none = + @abstract_function_decl +| @unspecified_element +; + +@accessor_decl_or_none = + @accessor_decl +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@constructor_decl_or_none = + @constructor_decl +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/ql/lib/upgrades/ceca289a0ff56bcc88f72ad78a8fbff1d850922f/upgrade.properties b/swift/ql/lib/upgrades/ceca289a0ff56bcc88f72ad78a8fbff1d850922f/upgrade.properties new file mode 100644 index 00000000000..bb4b061ea2b --- /dev/null +++ b/swift/ql/lib/upgrades/ceca289a0ff56bcc88f72ad78a8fbff1d850922f/upgrade.properties @@ -0,0 +1,5 @@ +description: Remove unfilled tables that were generated for actually synthesized QL types +compatibility: full +unknown_files.rel: delete +unknown_locations: delete +method_ref_exprs: delete From 798b03f29dca3c4616a916068238c71a8d8e2ee9 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Wed, 16 Nov 2022 12:06:07 +0100 Subject: [PATCH 284/796] code generalization Co-authored-by: Erik Krogh Kristensen --- javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll index c791cd9e25d..150096a1bcf 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll @@ -235,7 +235,8 @@ module Hapi { this.getMethodName() = "route" and handler = this.getArgument(0) - .(DataFlow::ArrayLiteralNode) + .getALocalSource() + .(DataFlow::ArrayCreationNode) .getAnElement() .(DataFlow::ObjectLiteralNode) .getAPropertySource("handler") From 8bf0bbb715526d388e3b3909201cc3f493eca20f Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Wed, 16 Nov 2022 12:06:23 +0100 Subject: [PATCH 285/796] code generalization Co-authored-by: Erik Krogh Kristensen --- javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll index 150096a1bcf..46bbb624839 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll @@ -238,7 +238,7 @@ module Hapi { .getALocalSource() .(DataFlow::ArrayCreationNode) .getAnElement() - .(DataFlow::ObjectLiteralNode) + .getALocalSource() .getAPropertySource("handler") .getAFunctionValue() ) From de082260d85396e5dc1b537d2fc19d40e4adee05 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 16 Nov 2022 12:48:25 +0100 Subject: [PATCH 286/796] QL: fixup `getQLDoc()` --- ql/ql/src/codeql_ql/ast/Ast.qll | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll index d6a5039a3c7..fd7e416f291 100644 --- a/ql/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/ql/src/codeql_ql/ast/Ast.qll @@ -156,12 +156,15 @@ class TopLevel extends TTopLevel, AstNode { } QLDoc getQLDocFor(ModuleMember m) { - exists(int i | i > 0 and result = this.getMember(i) and m = this.getMember(i + 1)) + exists(int i | result = this.getMember(i) and m = this.getMember(i + 1)) } override string getAPrimaryQlClass() { result = "TopLevel" } - override QLDoc getQLDoc() { result = this.getMember(0) } + override QLDoc getQLDoc() { + result = this.getMember(0) and + result.getLocation().getStartLine() = 1 // this might not hold if there is a block comment above, and that's the point. + } } abstract class Comment extends AstNode, TComment { @@ -536,6 +539,12 @@ class ClasslessPredicate extends TClasslessPredicate, Predicate, ModuleDeclarati /** Holds if this classless predicate is a signature predicate with no body. */ predicate isSignature() { not exists(this.getBody()) } + + override QLDoc getQLDoc() { + result = any(TopLevel m).getQLDocFor(this) + or + result = any(Module m).getQLDocFor(this) + } } /** From f71359c81d18da5243ad1e90a1de14a7e8b8f7ce Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 16 Nov 2022 12:49:27 +0100 Subject: [PATCH 287/796] QL: detect toplevel block-comments that should be QLDoc --- ql/ql/src/queries/style/NonDocBlock.ql | 36 ++++++++++++++++++++------ 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/ql/ql/src/queries/style/NonDocBlock.ql b/ql/ql/src/queries/style/NonDocBlock.ql index 17d39eb9bdb..c81ed3c77db 100644 --- a/ql/ql/src/queries/style/NonDocBlock.ql +++ b/ql/ql/src/queries/style/NonDocBlock.ql @@ -30,23 +30,43 @@ int getLineAboveNodeThatCouldHaveDoc(File file) { pragma[noinline] BlockComment getACommentThatCouldBeQLDoc(File file) { file = result.getLocation().getFile() and - result.getLocation().getEndLine() = getLineAboveNodeThatCouldHaveDoc(file) and result.getLocation().getFile().getExtension() = "qll" and - not result.getContents().matches("/**%") + not result.getContents().matches("/**%") and + ( + // above something that can be commented. + result.getLocation().getEndLine() = getLineAboveNodeThatCouldHaveDoc(file) + or + // toplevel in file. + result.getLocation().getStartLine() = 1 and + result.getLocation().getStartColumn() = 1 + ) } pragma[noinline] -BlockComment getCommentAt(File file, int endLine) { +BlockComment getCommentAtEnd(File file, int endLine) { result = getACommentThatCouldBeQLDoc(file) and result.getLocation().getEndLine() = endLine } -from AstNode node, BlockComment comment +pragma[noinline] +BlockComment getCommentAtStart(File file, int startLine) { + result = getACommentThatCouldBeQLDoc(file) and + result.getLocation().getStartLine() = startLine +} + +from AstNode node, BlockComment comment, string nodeDescrip where - canHaveQLDoc(node) and + ( + canHaveQLDoc(node) and + comment = getCommentAtEnd(node.getLocation().getFile(), node.getLocation().getStartLine() - 1) and + nodeDescrip = "the below code" + or + node instanceof TopLevel and + comment = getCommentAtStart(node.getLocation().getFile(), 1) and + nodeDescrip = "the file" + ) and not exists(node.getQLDoc()) and not node.(ClassPredicate).isOverride() and // ignore override predicates not node.hasAnnotation("deprecated") and // ignore deprecated - not node.hasAnnotation("private") and // ignore private - comment = getCommentAt(node.getLocation().getFile(), node.getLocation().getStartLine() - 1) -select comment, "Block comment could be QLDoc for $@.", node, "the below code" + not node.hasAnnotation("private") // ignore private +select comment, "Block comment could be QLDoc for $@.", node, nodeDescrip From f2222d32db6c90f809f0ab0fc3a0df60cd318b4b Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 16 Nov 2022 12:51:38 +0100 Subject: [PATCH 288/796] QL: add test --- ql/ql/test/queries/style/NonDocBlock/Foo.qll | 13 +++++++++++++ .../queries/style/NonDocBlock/NonDocBlock.expected | 2 ++ .../queries/style/NonDocBlock/NonDocBlock.qlref | 1 + 3 files changed, 16 insertions(+) create mode 100644 ql/ql/test/queries/style/NonDocBlock/Foo.qll create mode 100644 ql/ql/test/queries/style/NonDocBlock/NonDocBlock.expected create mode 100644 ql/ql/test/queries/style/NonDocBlock/NonDocBlock.qlref diff --git a/ql/ql/test/queries/style/NonDocBlock/Foo.qll b/ql/ql/test/queries/style/NonDocBlock/Foo.qll new file mode 100644 index 00000000000..238bc18ff9c --- /dev/null +++ b/ql/ql/test/queries/style/NonDocBlock/Foo.qll @@ -0,0 +1,13 @@ +/* + * This should be QLDoc. + */ + +/** + * this is fine + */ +predicate foo() { any() } + +/* Note: this is bad. */ +class Foo extends string { + Foo() { this = "FOo" } +} diff --git a/ql/ql/test/queries/style/NonDocBlock/NonDocBlock.expected b/ql/ql/test/queries/style/NonDocBlock/NonDocBlock.expected new file mode 100644 index 00000000000..7bdbfd18d95 --- /dev/null +++ b/ql/ql/test/queries/style/NonDocBlock/NonDocBlock.expected @@ -0,0 +1,2 @@ +| Foo.qll:1:1:3:3 | BlockComment | Block comment could be QLDoc for $@. | Foo.qll:1:1:13:2 | TopLevel | the file | +| Foo.qll:10:1:10:24 | BlockComment | Block comment could be QLDoc for $@. | Foo.qll:11:7:11:9 | Class Foo | the below code | diff --git a/ql/ql/test/queries/style/NonDocBlock/NonDocBlock.qlref b/ql/ql/test/queries/style/NonDocBlock/NonDocBlock.qlref new file mode 100644 index 00000000000..b6dbdf50604 --- /dev/null +++ b/ql/ql/test/queries/style/NonDocBlock/NonDocBlock.qlref @@ -0,0 +1 @@ +queries/style/NonDocBlock.ql \ No newline at end of file From 6fb014b34d8505c4043f21dc334ed25be9cd582c Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Wed, 16 Nov 2022 13:09:47 +0100 Subject: [PATCH 289/796] "CodeQL False positive" -> "CodeQL false positive" --- .github/ISSUE_TEMPLATE/ql--false-positive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/ql--false-positive.md b/.github/ISSUE_TEMPLATE/ql--false-positive.md index 7f22c577d14..b80590a1832 100644 --- a/.github/ISSUE_TEMPLATE/ql--false-positive.md +++ b/.github/ISSUE_TEMPLATE/ql--false-positive.md @@ -1,5 +1,5 @@ --- -name: CodeQL False positive +name: CodeQL false positive about: Report CodeQL alerts that you think should not have been detected (not applicable, not exploitable, etc.) title: False positive labels: false-positive From 67e8ec1a5fb19f353ddfd4f911a43ad68e99f296 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 16 Nov 2022 11:40:45 +0100 Subject: [PATCH 290/796] Swift: Update expected test output --- .../dataflow/dataflow/LocalFlow.expected | 298 +++++++++--------- 1 file changed, 149 insertions(+), 149 deletions(-) diff --git a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected index 987d7073b87..a4a883a2808 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected @@ -1,199 +1,199 @@ -| test.swift:6:9:6:13 | WriteDef | test.swift:7:15:7:15 | t1 | -| test.swift:6:19:6:26 | call to source() | test.swift:6:9:6:13 | WriteDef | +| test.swift:6:9:6:13 | SSA def(t1) | test.swift:7:15:7:15 | t1 | +| test.swift:6:19:6:26 | call to source() | test.swift:6:9:6:13 | SSA def(t1) | | test.swift:7:15:7:15 | t1 | test.swift:8:10:8:10 | t1 | -| test.swift:8:5:8:10 | WriteDef | test.swift:10:15:10:15 | t2 | -| test.swift:8:10:8:10 | t1 | test.swift:8:5:8:10 | WriteDef | +| test.swift:8:5:8:10 | SSA def(t2) | test.swift:10:15:10:15 | t2 | +| test.swift:8:10:8:10 | t1 | test.swift:8:5:8:10 | SSA def(t2) | | test.swift:8:10:8:10 | t1 | test.swift:9:15:9:15 | t1 | | test.swift:9:15:9:15 | t1 | test.swift:11:8:11:8 | t1 | -| test.swift:12:9:12:14 | WriteDef | test.swift:13:19:13:19 | t2 | -| test.swift:12:14:12:14 | 0 | test.swift:12:9:12:14 | WriteDef | -| test.swift:15:5:15:5 | Phi | test.swift:15:15:15:15 | t2 | -| test.swift:17:5:17:10 | WriteDef | test.swift:21:15:21:15 | t1 | -| test.swift:17:10:17:10 | 0 | test.swift:17:5:17:10 | WriteDef | -| test.swift:29:18:29:21 | WriteDef | test.swift:30:15:30:15 | x | -| test.swift:29:18:29:21 | x | test.swift:29:18:29:21 | WriteDef | -| test.swift:29:26:29:29 | WriteDef | test.swift:31:15:31:15 | y | -| test.swift:29:26:29:29 | y | test.swift:29:26:29:29 | WriteDef | -| test.swift:42:16:42:19 | WriteDef | test.swift:45:8:45:8 | b | -| test.swift:42:16:42:19 | b | test.swift:42:16:42:19 | WriteDef | -| test.swift:43:9:43:13 | WriteDef | test.swift:46:13:46:13 | t1 | -| test.swift:43:19:43:26 | call to source() | test.swift:43:9:43:13 | WriteDef | -| test.swift:46:9:46:13 | WriteDef | test.swift:50:5:50:5 | Phi | -| test.swift:46:13:46:13 | t1 | test.swift:46:9:46:13 | WriteDef | -| test.swift:48:9:48:13 | WriteDef | test.swift:50:5:50:5 | Phi | -| test.swift:48:13:48:13 | 1 | test.swift:48:9:48:13 | WriteDef | -| test.swift:50:5:50:5 | Phi | test.swift:50:15:50:15 | t | -| test.swift:54:5:54:18 | WriteDef | test.swift:53:1:56:1 | arg[return] | -| test.swift:54:11:54:18 | call to source() | test.swift:54:5:54:18 | WriteDef | -| test.swift:59:9:59:12 | WriteDef | test.swift:60:15:60:15 | x | -| test.swift:59:18:59:18 | 0 | test.swift:59:9:59:12 | WriteDef | +| test.swift:12:9:12:14 | SSA def(t2) | test.swift:13:19:13:19 | t2 | +| test.swift:12:14:12:14 | 0 | test.swift:12:9:12:14 | SSA def(t2) | +| test.swift:15:5:15:5 | SSA phi(t2) | test.swift:15:15:15:15 | t2 | +| test.swift:17:5:17:10 | SSA def(t1) | test.swift:21:15:21:15 | t1 | +| test.swift:17:10:17:10 | 0 | test.swift:17:5:17:10 | SSA def(t1) | +| test.swift:29:18:29:21 | SSA def(x) | test.swift:30:15:30:15 | x | +| test.swift:29:18:29:21 | x | test.swift:29:18:29:21 | SSA def(x) | +| test.swift:29:26:29:29 | SSA def(y) | test.swift:31:15:31:15 | y | +| test.swift:29:26:29:29 | y | test.swift:29:26:29:29 | SSA def(y) | +| test.swift:42:16:42:19 | SSA def(b) | test.swift:45:8:45:8 | b | +| test.swift:42:16:42:19 | b | test.swift:42:16:42:19 | SSA def(b) | +| test.swift:43:9:43:13 | SSA def(t1) | test.swift:46:13:46:13 | t1 | +| test.swift:43:19:43:26 | call to source() | test.swift:43:9:43:13 | SSA def(t1) | +| test.swift:46:9:46:13 | SSA def(t) | test.swift:50:5:50:5 | SSA phi(t) | +| test.swift:46:13:46:13 | t1 | test.swift:46:9:46:13 | SSA def(t) | +| test.swift:48:9:48:13 | SSA def(t) | test.swift:50:5:50:5 | SSA phi(t) | +| test.swift:48:13:48:13 | 1 | test.swift:48:9:48:13 | SSA def(t) | +| test.swift:50:5:50:5 | SSA phi(t) | test.swift:50:15:50:15 | t | +| test.swift:54:5:54:18 | SSA def(arg) | test.swift:53:1:56:1 | arg[return] | +| test.swift:54:11:54:18 | call to source() | test.swift:54:5:54:18 | SSA def(arg) | +| test.swift:59:9:59:12 | SSA def(x) | test.swift:60:15:60:15 | x | +| test.swift:59:18:59:18 | 0 | test.swift:59:9:59:12 | SSA def(x) | | test.swift:60:15:60:15 | x | test.swift:61:23:61:23 | x | | test.swift:61:22:61:23 | &... | test.swift:62:15:62:15 | x | | test.swift:61:22:61:23 | [post] &... | test.swift:62:15:62:15 | x | | test.swift:61:23:61:23 | x | test.swift:61:22:61:23 | &... | -| test.swift:65:16:65:28 | WriteDef | test.swift:66:21:66:21 | arg1 | -| test.swift:65:16:65:28 | arg1 | test.swift:65:16:65:28 | WriteDef | -| test.swift:65:33:65:45 | WriteDef | test.swift:67:12:67:12 | arg2 | -| test.swift:65:33:65:45 | arg2 | test.swift:65:33:65:45 | WriteDef | -| test.swift:66:9:66:15 | WriteDef | test.swift:68:12:68:12 | temp | -| test.swift:66:21:66:21 | arg1 | test.swift:66:9:66:15 | WriteDef | -| test.swift:67:5:67:12 | WriteDef | test.swift:65:1:70:1 | arg1[return] | -| test.swift:67:12:67:12 | arg2 | test.swift:67:5:67:12 | WriteDef | -| test.swift:68:5:68:12 | WriteDef | test.swift:65:1:70:1 | arg2[return] | -| test.swift:68:12:68:12 | temp | test.swift:68:5:68:12 | WriteDef | -| test.swift:73:9:73:12 | WriteDef | test.swift:75:22:75:22 | x | -| test.swift:73:18:73:25 | call to source() | test.swift:73:9:73:12 | WriteDef | -| test.swift:74:9:74:12 | WriteDef | test.swift:75:32:75:32 | y | -| test.swift:74:18:74:18 | 0 | test.swift:74:9:74:12 | WriteDef | +| test.swift:65:16:65:28 | SSA def(arg1) | test.swift:66:21:66:21 | arg1 | +| test.swift:65:16:65:28 | arg1 | test.swift:65:16:65:28 | SSA def(arg1) | +| test.swift:65:33:65:45 | SSA def(arg2) | test.swift:67:12:67:12 | arg2 | +| test.swift:65:33:65:45 | arg2 | test.swift:65:33:65:45 | SSA def(arg2) | +| test.swift:66:9:66:15 | SSA def(temp) | test.swift:68:12:68:12 | temp | +| test.swift:66:21:66:21 | arg1 | test.swift:66:9:66:15 | SSA def(temp) | +| test.swift:67:5:67:12 | SSA def(arg1) | test.swift:65:1:70:1 | arg1[return] | +| test.swift:67:12:67:12 | arg2 | test.swift:67:5:67:12 | SSA def(arg1) | +| test.swift:68:5:68:12 | SSA def(arg2) | test.swift:65:1:70:1 | arg2[return] | +| test.swift:68:12:68:12 | temp | test.swift:68:5:68:12 | SSA def(arg2) | +| test.swift:73:9:73:12 | SSA def(x) | test.swift:75:22:75:22 | x | +| test.swift:73:18:73:25 | call to source() | test.swift:73:9:73:12 | SSA def(x) | +| test.swift:74:9:74:12 | SSA def(y) | test.swift:75:32:75:32 | y | +| test.swift:74:18:74:18 | 0 | test.swift:74:9:74:12 | SSA def(y) | | test.swift:75:21:75:22 | &... | test.swift:76:15:76:15 | x | | test.swift:75:21:75:22 | [post] &... | test.swift:76:15:76:15 | x | | test.swift:75:22:75:22 | x | test.swift:75:21:75:22 | &... | | test.swift:75:31:75:32 | &... | test.swift:77:15:77:15 | y | | test.swift:75:31:75:32 | [post] &... | test.swift:77:15:77:15 | y | | test.swift:75:32:75:32 | y | test.swift:75:31:75:32 | &... | -| test.swift:81:5:81:18 | WriteDef | test.swift:80:1:82:1 | arg[return] | -| test.swift:81:11:81:18 | call to source() | test.swift:81:5:81:18 | WriteDef | -| test.swift:84:1:91:1 | Phi | test.swift:84:1:91:1 | arg[return] | -| test.swift:84:48:84:54 | WriteDef | test.swift:85:8:85:8 | bool | -| test.swift:84:48:84:54 | bool | test.swift:84:48:84:54 | WriteDef | -| test.swift:86:9:86:22 | WriteDef | test.swift:84:1:91:1 | Phi | -| test.swift:86:15:86:22 | call to source() | test.swift:86:9:86:22 | WriteDef | -| test.swift:89:9:89:22 | WriteDef | test.swift:84:1:91:1 | Phi | -| test.swift:89:15:89:22 | call to source() | test.swift:89:9:89:22 | WriteDef | -| test.swift:93:17:93:23 | WriteDef | test.swift:104:50:104:50 | bool | -| test.swift:93:17:93:23 | bool | test.swift:93:17:93:23 | WriteDef | -| test.swift:95:13:95:16 | WriteDef | test.swift:96:19:96:19 | x | -| test.swift:95:22:95:22 | 0 | test.swift:95:13:95:16 | WriteDef | +| test.swift:81:5:81:18 | SSA def(arg) | test.swift:80:1:82:1 | arg[return] | +| test.swift:81:11:81:18 | call to source() | test.swift:81:5:81:18 | SSA def(arg) | +| test.swift:84:1:91:1 | SSA phi(arg) | test.swift:84:1:91:1 | arg[return] | +| test.swift:84:48:84:54 | SSA def(bool) | test.swift:85:8:85:8 | bool | +| test.swift:84:48:84:54 | bool | test.swift:84:48:84:54 | SSA def(bool) | +| test.swift:86:9:86:22 | SSA def(arg) | test.swift:84:1:91:1 | SSA phi(arg) | +| test.swift:86:15:86:22 | call to source() | test.swift:86:9:86:22 | SSA def(arg) | +| test.swift:89:9:89:22 | SSA def(arg) | test.swift:84:1:91:1 | SSA phi(arg) | +| test.swift:89:15:89:22 | call to source() | test.swift:89:9:89:22 | SSA def(arg) | +| test.swift:93:17:93:23 | SSA def(bool) | test.swift:104:50:104:50 | bool | +| test.swift:93:17:93:23 | bool | test.swift:93:17:93:23 | SSA def(bool) | +| test.swift:95:13:95:16 | SSA def(x) | test.swift:96:19:96:19 | x | +| test.swift:95:22:95:22 | 0 | test.swift:95:13:95:16 | SSA def(x) | | test.swift:96:19:96:19 | x | test.swift:97:40:97:40 | x | | test.swift:97:39:97:40 | &... | test.swift:98:19:98:19 | x | | test.swift:97:39:97:40 | [post] &... | test.swift:98:19:98:19 | x | | test.swift:97:40:97:40 | x | test.swift:97:39:97:40 | &... | -| test.swift:102:13:102:16 | WriteDef | test.swift:103:19:103:19 | x | -| test.swift:102:22:102:22 | 0 | test.swift:102:13:102:16 | WriteDef | +| test.swift:102:13:102:16 | SSA def(x) | test.swift:103:19:103:19 | x | +| test.swift:102:22:102:22 | 0 | test.swift:102:13:102:16 | SSA def(x) | | test.swift:103:19:103:19 | x | test.swift:104:41:104:41 | x | | test.swift:104:40:104:41 | &... | test.swift:105:19:105:19 | x | | test.swift:104:40:104:41 | [post] &... | test.swift:105:19:105:19 | x | | test.swift:104:41:104:41 | x | test.swift:104:40:104:41 | &... | -| test.swift:109:9:109:14 | WriteDef | test.swift:110:12:110:12 | arg | -| test.swift:109:9:109:14 | arg | test.swift:109:9:109:14 | WriteDef | -| test.swift:113:14:113:19 | WriteDef | test.swift:114:19:114:19 | arg | -| test.swift:113:14:113:19 | arg | test.swift:113:14:113:19 | WriteDef | -| test.swift:113:24:113:41 | WriteDef | test.swift:114:12:114:12 | lambda | -| test.swift:113:24:113:41 | lambda | test.swift:113:24:113:41 | WriteDef | -| test.swift:118:9:118:12 | WriteDef | test.swift:119:31:119:31 | x | -| test.swift:118:18:118:25 | call to source() | test.swift:118:9:118:12 | WriteDef | -| test.swift:119:9:119:12 | WriteDef | test.swift:120:15:120:15 | y | -| test.swift:119:18:119:44 | call to forward(arg:lambda:) | test.swift:119:9:119:12 | WriteDef | -| test.swift:122:9:122:12 | WriteDef | test.swift:126:15:126:15 | z | -| test.swift:122:18:125:6 | call to forward(arg:lambda:) | test.swift:122:9:122:12 | WriteDef | -| test.swift:123:10:123:13 | WriteDef | test.swift:124:16:124:16 | i | -| test.swift:123:10:123:13 | i | test.swift:123:10:123:13 | WriteDef | -| test.swift:128:9:128:16 | WriteDef | test.swift:132:15:132:15 | clean | -| test.swift:128:22:131:6 | call to forward(arg:lambda:) | test.swift:128:9:128:16 | WriteDef | -| test.swift:141:9:141:9 | WriteDef | test.swift:145:15:145:15 | lambda2 | -| test.swift:141:19:144:5 | { ... } | test.swift:141:9:141:9 | WriteDef | -| test.swift:142:10:142:13 | WriteDef | test.swift:143:16:143:16 | i | -| test.swift:142:10:142:13 | i | test.swift:142:10:142:13 | WriteDef | -| test.swift:147:9:147:9 | WriteDef | test.swift:151:15:151:15 | lambdaSource | -| test.swift:147:24:150:5 | { ... } | test.swift:147:9:147:9 | WriteDef | +| test.swift:109:9:109:14 | SSA def(arg) | test.swift:110:12:110:12 | arg | +| test.swift:109:9:109:14 | arg | test.swift:109:9:109:14 | SSA def(arg) | +| test.swift:113:14:113:19 | SSA def(arg) | test.swift:114:19:114:19 | arg | +| test.swift:113:14:113:19 | arg | test.swift:113:14:113:19 | SSA def(arg) | +| test.swift:113:24:113:41 | SSA def(lambda) | test.swift:114:12:114:12 | lambda | +| test.swift:113:24:113:41 | lambda | test.swift:113:24:113:41 | SSA def(lambda) | +| test.swift:118:9:118:12 | SSA def(x) | test.swift:119:31:119:31 | x | +| test.swift:118:18:118:25 | call to source() | test.swift:118:9:118:12 | SSA def(x) | +| test.swift:119:9:119:12 | SSA def(y) | test.swift:120:15:120:15 | y | +| test.swift:119:18:119:44 | call to forward(arg:lambda:) | test.swift:119:9:119:12 | SSA def(y) | +| test.swift:122:9:122:12 | SSA def(z) | test.swift:126:15:126:15 | z | +| test.swift:122:18:125:6 | call to forward(arg:lambda:) | test.swift:122:9:122:12 | SSA def(z) | +| test.swift:123:10:123:13 | SSA def(i) | test.swift:124:16:124:16 | i | +| test.swift:123:10:123:13 | i | test.swift:123:10:123:13 | SSA def(i) | +| test.swift:128:9:128:16 | SSA def(clean) | test.swift:132:15:132:15 | clean | +| test.swift:128:22:131:6 | call to forward(arg:lambda:) | test.swift:128:9:128:16 | SSA def(clean) | +| test.swift:141:9:141:9 | SSA def(lambda2) | test.swift:145:15:145:15 | lambda2 | +| test.swift:141:19:144:5 | { ... } | test.swift:141:9:141:9 | SSA def(lambda2) | +| test.swift:142:10:142:13 | SSA def(i) | test.swift:143:16:143:16 | i | +| test.swift:142:10:142:13 | i | test.swift:142:10:142:13 | SSA def(i) | +| test.swift:147:9:147:9 | SSA def(lambdaSource) | test.swift:151:15:151:15 | lambdaSource | +| test.swift:147:24:150:5 | { ... } | test.swift:147:9:147:9 | SSA def(lambdaSource) | | test.swift:151:15:151:15 | lambdaSource | test.swift:159:16:159:16 | lambdaSource | -| test.swift:153:9:153:9 | WriteDef | test.swift:157:5:157:5 | lambdaSink | -| test.swift:153:22:156:5 | { ... } | test.swift:153:9:153:9 | WriteDef | -| test.swift:154:10:154:13 | WriteDef | test.swift:155:19:155:19 | i | -| test.swift:154:10:154:13 | i | test.swift:154:10:154:13 | WriteDef | +| test.swift:153:9:153:9 | SSA def(lambdaSink) | test.swift:157:5:157:5 | lambdaSink | +| test.swift:153:22:156:5 | { ... } | test.swift:153:9:153:9 | SSA def(lambdaSink) | +| test.swift:154:10:154:13 | SSA def(i) | test.swift:155:19:155:19 | i | +| test.swift:154:10:154:13 | i | test.swift:154:10:154:13 | SSA def(i) | | test.swift:157:5:157:5 | lambdaSink | test.swift:159:5:159:5 | lambdaSink | -| test.swift:162:7:162:7 | WriteDef | test.swift:162:7:162:7 | self[return] | -| test.swift:162:7:162:7 | self | test.swift:162:7:162:7 | WriteDef | -| test.swift:163:7:163:7 | self | test.swift:163:7:163:7 | WriteDef | -| test.swift:163:7:163:7 | self | test.swift:163:7:163:7 | WriteDef | -| test.swift:163:7:163:7 | self | test.swift:163:7:163:7 | WriteDef | -| test.swift:163:7:163:7 | value | test.swift:163:7:163:7 | WriteDef | -| test.swift:165:3:165:3 | WriteDef | test.swift:166:5:166:5 | self | -| test.swift:165:3:165:3 | self | test.swift:165:3:165:3 | WriteDef | +| test.swift:162:7:162:7 | SSA def(self) | test.swift:162:7:162:7 | self[return] | +| test.swift:162:7:162:7 | self | test.swift:162:7:162:7 | SSA def(self) | +| test.swift:163:7:163:7 | self | test.swift:163:7:163:7 | SSA def(self) | +| test.swift:163:7:163:7 | self | test.swift:163:7:163:7 | SSA def(self) | +| test.swift:163:7:163:7 | self | test.swift:163:7:163:7 | SSA def(self) | +| test.swift:163:7:163:7 | value | test.swift:163:7:163:7 | SSA def(value) | +| test.swift:165:3:165:3 | SSA def(self) | test.swift:166:5:166:5 | self | +| test.swift:165:3:165:3 | self | test.swift:165:3:165:3 | SSA def(self) | | test.swift:166:5:166:5 | [post] self | test.swift:165:3:167:3 | self[return] | | test.swift:166:5:166:5 | self | test.swift:165:3:167:3 | self[return] | -| test.swift:169:8:169:8 | WriteDef | test.swift:170:5:170:5 | self | -| test.swift:169:8:169:8 | self | test.swift:169:8:169:8 | WriteDef | -| test.swift:169:12:169:22 | WriteDef | test.swift:170:9:170:9 | value | -| test.swift:169:12:169:22 | value | test.swift:169:12:169:22 | WriteDef | +| test.swift:169:8:169:8 | SSA def(self) | test.swift:170:5:170:5 | self | +| test.swift:169:8:169:8 | self | test.swift:169:8:169:8 | SSA def(self) | +| test.swift:169:12:169:22 | SSA def(value) | test.swift:170:9:170:9 | value | +| test.swift:169:12:169:22 | value | test.swift:169:12:169:22 | SSA def(value) | | test.swift:170:5:170:5 | [post] self | test.swift:169:3:171:3 | self[return] | | test.swift:170:5:170:5 | self | test.swift:169:3:171:3 | self[return] | -| test.swift:173:8:173:8 | WriteDef | test.swift:174:12:174:12 | self | -| test.swift:173:8:173:8 | self | test.swift:173:8:173:8 | WriteDef | +| test.swift:173:8:173:8 | SSA def(self) | test.swift:174:12:174:12 | self | +| test.swift:173:8:173:8 | self | test.swift:173:8:173:8 | SSA def(self) | | test.swift:174:12:174:12 | [post] self | test.swift:173:3:175:3 | self[return] | | test.swift:174:12:174:12 | self | test.swift:173:3:175:3 | self[return] | -| test.swift:179:7:179:7 | WriteDef | test.swift:180:3:180:3 | a | -| test.swift:179:11:179:13 | call to init() | test.swift:179:7:179:7 | WriteDef | +| test.swift:179:7:179:7 | SSA def(a) | test.swift:180:3:180:3 | a | +| test.swift:179:11:179:13 | call to init() | test.swift:179:7:179:7 | SSA def(a) | | test.swift:180:3:180:3 | [post] a | test.swift:181:13:181:13 | a | | test.swift:180:3:180:3 | a | test.swift:181:13:181:13 | a | -| test.swift:184:7:184:7 | WriteDef | test.swift:184:7:184:7 | self[return] | -| test.swift:184:7:184:7 | self | test.swift:184:7:184:7 | WriteDef | -| test.swift:185:7:185:7 | self | test.swift:185:7:185:7 | WriteDef | -| test.swift:185:7:185:7 | self | test.swift:185:7:185:7 | WriteDef | -| test.swift:185:7:185:7 | self | test.swift:185:7:185:7 | WriteDef | -| test.swift:185:7:185:7 | value | test.swift:185:7:185:7 | WriteDef | -| test.swift:187:3:187:3 | WriteDef | test.swift:188:5:188:5 | self | -| test.swift:187:3:187:3 | self | test.swift:187:3:187:3 | WriteDef | +| test.swift:184:7:184:7 | SSA def(self) | test.swift:184:7:184:7 | self[return] | +| test.swift:184:7:184:7 | self | test.swift:184:7:184:7 | SSA def(self) | +| test.swift:185:7:185:7 | self | test.swift:185:7:185:7 | SSA def(self) | +| test.swift:185:7:185:7 | self | test.swift:185:7:185:7 | SSA def(self) | +| test.swift:185:7:185:7 | self | test.swift:185:7:185:7 | SSA def(self) | +| test.swift:185:7:185:7 | value | test.swift:185:7:185:7 | SSA def(value) | +| test.swift:187:3:187:3 | SSA def(self) | test.swift:188:5:188:5 | self | +| test.swift:187:3:187:3 | self | test.swift:187:3:187:3 | SSA def(self) | | test.swift:188:5:188:5 | [post] self | test.swift:187:3:189:3 | self[return] | | test.swift:188:5:188:5 | self | test.swift:187:3:189:3 | self[return] | -| test.swift:193:7:193:7 | WriteDef | test.swift:194:3:194:3 | b | -| test.swift:193:11:193:13 | call to init() | test.swift:193:7:193:7 | WriteDef | +| test.swift:193:7:193:7 | SSA def(b) | test.swift:194:3:194:3 | b | +| test.swift:193:11:193:13 | call to init() | test.swift:193:7:193:7 | SSA def(b) | | test.swift:194:3:194:3 | [post] b | test.swift:195:13:195:13 | b | | test.swift:194:3:194:3 | b | test.swift:195:13:195:13 | b | -| test.swift:199:7:199:7 | WriteDef | test.swift:200:3:200:3 | a | -| test.swift:199:11:199:13 | call to init() | test.swift:199:7:199:7 | WriteDef | +| test.swift:199:7:199:7 | SSA def(a) | test.swift:200:3:200:3 | a | +| test.swift:199:11:199:13 | call to init() | test.swift:199:7:199:7 | SSA def(a) | | test.swift:200:3:200:3 | [post] a | test.swift:201:13:201:13 | a | | test.swift:200:3:200:3 | a | test.swift:201:13:201:13 | a | -| test.swift:205:7:205:7 | WriteDef | test.swift:206:3:206:3 | a | -| test.swift:205:11:205:13 | call to init() | test.swift:205:7:205:7 | WriteDef | +| test.swift:205:7:205:7 | SSA def(a) | test.swift:206:3:206:3 | a | +| test.swift:205:11:205:13 | call to init() | test.swift:205:7:205:7 | SSA def(a) | | test.swift:206:3:206:3 | [post] a | test.swift:207:13:207:13 | a | | test.swift:206:3:206:3 | a | test.swift:207:13:207:13 | a | -| test.swift:211:7:211:7 | WriteDef | test.swift:212:3:212:3 | a | -| test.swift:211:11:211:13 | call to init() | test.swift:211:7:211:7 | WriteDef | +| test.swift:211:7:211:7 | SSA def(a) | test.swift:212:3:212:3 | a | +| test.swift:211:11:211:13 | call to init() | test.swift:211:7:211:7 | SSA def(a) | | test.swift:212:3:212:3 | [post] a | test.swift:213:13:213:13 | a | | test.swift:212:3:212:3 | a | test.swift:213:13:213:13 | a | -| test.swift:217:7:217:7 | WriteDef | test.swift:218:3:218:3 | b | -| test.swift:217:11:217:13 | call to init() | test.swift:217:7:217:7 | WriteDef | +| test.swift:217:7:217:7 | SSA def(b) | test.swift:218:3:218:3 | b | +| test.swift:217:11:217:13 | call to init() | test.swift:217:7:217:7 | SSA def(b) | | test.swift:218:3:218:3 | [post] b | test.swift:219:13:219:13 | b | | test.swift:218:3:218:3 | b | test.swift:219:13:219:13 | b | -| test.swift:222:7:222:7 | WriteDef | test.swift:222:7:222:7 | self[return] | -| test.swift:222:7:222:7 | WriteDef | test.swift:222:7:222:7 | self[return] | -| test.swift:222:7:222:7 | self | test.swift:222:7:222:7 | WriteDef | -| test.swift:222:7:222:7 | self | test.swift:222:7:222:7 | WriteDef | -| test.swift:223:7:223:7 | self | test.swift:223:7:223:7 | WriteDef | -| test.swift:224:5:224:5 | WriteDef | test.swift:224:5:226:5 | self[return] | -| test.swift:224:5:224:5 | self | test.swift:224:5:224:5 | WriteDef | -| test.swift:227:5:227:5 | WriteDef | test.swift:227:5:229:5 | self[return] | -| test.swift:227:5:227:5 | self | test.swift:227:5:227:5 | WriteDef | -| test.swift:234:7:234:7 | WriteDef | test.swift:235:13:235:13 | a | -| test.swift:234:11:234:31 | call to init() | test.swift:234:7:234:7 | WriteDef | +| test.swift:222:7:222:7 | SSA def(self) | test.swift:222:7:222:7 | self[return] | +| test.swift:222:7:222:7 | SSA def(self) | test.swift:222:7:222:7 | self[return] | +| test.swift:222:7:222:7 | self | test.swift:222:7:222:7 | SSA def(self) | +| test.swift:222:7:222:7 | self | test.swift:222:7:222:7 | SSA def(self) | +| test.swift:223:7:223:7 | self | test.swift:223:7:223:7 | SSA def(self) | +| test.swift:224:5:224:5 | SSA def(self) | test.swift:224:5:226:5 | self[return] | +| test.swift:224:5:224:5 | self | test.swift:224:5:224:5 | SSA def(self) | +| test.swift:227:5:227:5 | SSA def(self) | test.swift:227:5:229:5 | self[return] | +| test.swift:227:5:227:5 | self | test.swift:227:5:227:5 | SSA def(self) | +| test.swift:234:7:234:7 | SSA def(a) | test.swift:235:13:235:13 | a | +| test.swift:234:11:234:31 | call to init() | test.swift:234:7:234:7 | SSA def(a) | | test.swift:235:13:235:13 | [post] a | test.swift:237:3:237:3 | a | | test.swift:235:13:235:13 | a | test.swift:237:3:237:3 | a | | test.swift:237:3:237:3 | [post] a | test.swift:238:13:238:13 | a | | test.swift:237:3:237:3 | a | test.swift:238:13:238:13 | a | -| test.swift:242:9:242:9 | self | test.swift:242:9:242:9 | WriteDef | -| test.swift:242:9:242:9 | self | test.swift:242:9:242:9 | WriteDef | -| test.swift:242:9:242:9 | self | test.swift:242:9:242:9 | WriteDef | -| test.swift:242:9:242:9 | value | test.swift:242:9:242:9 | WriteDef | -| test.swift:243:9:243:9 | WriteDef | test.swift:243:18:243:18 | self | -| test.swift:243:9:243:9 | self | test.swift:243:9:243:9 | WriteDef | +| test.swift:242:9:242:9 | self | test.swift:242:9:242:9 | SSA def(self) | +| test.swift:242:9:242:9 | self | test.swift:242:9:242:9 | SSA def(self) | +| test.swift:242:9:242:9 | self | test.swift:242:9:242:9 | SSA def(self) | +| test.swift:242:9:242:9 | value | test.swift:242:9:242:9 | SSA def(value) | +| test.swift:243:9:243:9 | SSA def(self) | test.swift:243:18:243:18 | self | +| test.swift:243:9:243:9 | self | test.swift:243:9:243:9 | SSA def(self) | | test.swift:243:18:243:18 | [post] self | test.swift:243:9:243:42 | self[return] | | test.swift:243:18:243:18 | self | test.swift:243:9:243:42 | self[return] | -| test.swift:246:5:246:5 | WriteDef | test.swift:247:9:247:9 | self | -| test.swift:246:5:246:5 | self | test.swift:246:5:246:5 | WriteDef | +| test.swift:246:5:246:5 | SSA def(self) | test.swift:247:9:247:9 | self | +| test.swift:246:5:246:5 | self | test.swift:246:5:246:5 | SSA def(self) | | test.swift:247:9:247:9 | [post] self | test.swift:246:5:248:5 | self[return] | | test.swift:247:9:247:9 | self | test.swift:246:5:248:5 | self[return] | -| test.swift:252:23:252:23 | value | test.swift:252:23:252:23 | WriteDef | -| test.swift:263:9:263:9 | WriteDef | test.swift:264:15:264:15 | x | -| test.swift:263:13:263:28 | call to optionalSource() | test.swift:263:9:263:9 | WriteDef | +| test.swift:252:23:252:23 | value | test.swift:252:23:252:23 | SSA def(value) | +| test.swift:263:9:263:9 | SSA def(x) | test.swift:264:15:264:15 | x | +| test.swift:263:13:263:28 | call to optionalSource() | test.swift:263:9:263:9 | SSA def(x) | | test.swift:264:15:264:15 | x | test.swift:264:15:264:16 | ...! | | test.swift:264:15:264:15 | x | test.swift:266:15:266:15 | x | | test.swift:266:15:266:15 | x | test.swift:266:15:266:16 | ...? | | test.swift:266:15:266:15 | x | test.swift:267:15:267:15 | x | | test.swift:266:15:266:25 | call to signum() | test.swift:266:15:266:25 | OptionalEvaluationExpr | | test.swift:267:15:267:15 | x | test.swift:268:16:268:16 | x | -| test.swift:277:9:277:9 | WriteDef | test.swift:279:15:279:15 | t1 | -| test.swift:277:14:277:26 | (...) | test.swift:277:9:277:9 | WriteDef | +| test.swift:277:9:277:9 | SSA def(t1) | test.swift:279:15:279:15 | t1 | +| test.swift:277:14:277:26 | (...) | test.swift:277:9:277:9 | SSA def(t1) | | test.swift:279:15:279:15 | t1 | test.swift:280:15:280:15 | t1 | | test.swift:280:15:280:15 | [post] t1 | test.swift:281:15:281:15 | t1 | | test.swift:280:15:280:15 | t1 | test.swift:281:15:281:15 | t1 | @@ -211,17 +211,17 @@ | test.swift:291:15:291:15 | t1 | test.swift:292:15:292:15 | t1 | | test.swift:292:15:292:15 | [post] t1 | test.swift:293:15:293:15 | t1 | | test.swift:292:15:292:15 | t1 | test.swift:293:15:293:15 | t1 | -| test.swift:297:9:297:9 | WriteDef | test.swift:298:14:298:14 | t1 | -| test.swift:297:14:297:45 | (...) | test.swift:297:9:297:9 | WriteDef | -| test.swift:298:9:298:9 | WriteDef | test.swift:305:15:305:15 | t2 | -| test.swift:298:14:298:14 | t1 | test.swift:298:9:298:9 | WriteDef | +| test.swift:297:9:297:9 | SSA def(t1) | test.swift:298:14:298:14 | t1 | +| test.swift:297:14:297:45 | (...) | test.swift:297:9:297:9 | SSA def(t1) | +| test.swift:298:9:298:9 | SSA def(t2) | test.swift:305:15:305:15 | t2 | +| test.swift:298:14:298:14 | t1 | test.swift:298:9:298:9 | SSA def(t2) | | test.swift:298:14:298:14 | t1 | test.swift:299:21:299:21 | t1 | -| test.swift:299:9:299:17 | WriteDef | test.swift:309:15:309:15 | a | -| test.swift:299:9:299:17 | WriteDef | test.swift:310:15:310:15 | b | -| test.swift:299:9:299:17 | WriteDef | test.swift:311:15:311:15 | c | -| test.swift:299:21:299:21 | t1 | test.swift:299:9:299:17 | WriteDef | -| test.swift:299:21:299:21 | t1 | test.swift:299:9:299:17 | WriteDef | -| test.swift:299:21:299:21 | t1 | test.swift:299:9:299:17 | WriteDef | +| test.swift:299:9:299:17 | SSA def(a) | test.swift:309:15:309:15 | a | +| test.swift:299:9:299:17 | SSA def(b) | test.swift:310:15:310:15 | b | +| test.swift:299:9:299:17 | SSA def(c) | test.swift:311:15:311:15 | c | +| test.swift:299:21:299:21 | t1 | test.swift:299:9:299:17 | SSA def(a) | +| test.swift:299:21:299:21 | t1 | test.swift:299:9:299:17 | SSA def(b) | +| test.swift:299:21:299:21 | t1 | test.swift:299:9:299:17 | SSA def(c) | | test.swift:299:21:299:21 | t1 | test.swift:301:15:301:15 | t1 | | test.swift:301:15:301:15 | t1 | test.swift:302:15:302:15 | t1 | | test.swift:302:15:302:15 | [post] t1 | test.swift:303:15:303:15 | t1 | From 78c9fb3d76b0d7a22811e3317c189699f85efdeb Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 16 Nov 2022 13:36:13 +0100 Subject: [PATCH 291/796] QL: don't flag up comments placed on the same line as non-comments --- ql/ql/src/queries/style/NonDocBlock.ql | 35 +++++++++++++------ ql/ql/test/queries/style/NonDocBlock/Foo.qll | 9 +++++ .../style/NonDocBlock/NonDocBlock.expected | 2 +- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/ql/ql/src/queries/style/NonDocBlock.ql b/ql/ql/src/queries/style/NonDocBlock.ql index c81ed3c77db..61efce0b902 100644 --- a/ql/ql/src/queries/style/NonDocBlock.ql +++ b/ql/ql/src/queries/style/NonDocBlock.ql @@ -29,16 +29,31 @@ int getLineAboveNodeThatCouldHaveDoc(File file) { pragma[noinline] BlockComment getACommentThatCouldBeQLDoc(File file) { - file = result.getLocation().getFile() and - result.getLocation().getFile().getExtension() = "qll" and - not result.getContents().matches("/**%") and - ( - // above something that can be commented. - result.getLocation().getEndLine() = getLineAboveNodeThatCouldHaveDoc(file) - or - // toplevel in file. - result.getLocation().getStartLine() = 1 and - result.getLocation().getStartColumn() = 1 + exists(Location loc | loc = result.getLocation() | + file = loc.getFile() and + loc.getFile().getExtension() = "qll" and + not result.getContents().matches("/**%") and + not [loc.getStartLine(), loc.getEndLine()] = getLinesWithNonComment(file) and + ( + // above something that can be commented. + loc.getEndLine() = getLineAboveNodeThatCouldHaveDoc(file) + or + // toplevel in file. + loc.getStartLine() = 1 and + loc.getStartColumn() = 1 + ) + ) +} + +pragma[noinline] +int getLinesWithNonComment(File f) { + exists(AstNode n, Location loc | + not n instanceof Comment and + not n instanceof TopLevel and + loc = n.getLocation() and + loc.getFile() = f + | + result = [loc.getEndLine(), loc.getStartLine()] ) } diff --git a/ql/ql/test/queries/style/NonDocBlock/Foo.qll b/ql/ql/test/queries/style/NonDocBlock/Foo.qll index 238bc18ff9c..99f957fa770 100644 --- a/ql/ql/test/queries/style/NonDocBlock/Foo.qll +++ b/ql/ql/test/queries/style/NonDocBlock/Foo.qll @@ -11,3 +11,12 @@ predicate foo() { any() } class Foo extends string { Foo() { this = "FOo" } } + +/** + * This is also fine. + */ +/*abstract*/ class Bar extends string { + string getMergeRaw() { none() } // <- fine. The abstract comment is fine, it doesn't need to be QLDoc. + + Bar() { this = "bar" } +} diff --git a/ql/ql/test/queries/style/NonDocBlock/NonDocBlock.expected b/ql/ql/test/queries/style/NonDocBlock/NonDocBlock.expected index 7bdbfd18d95..41f029af5fd 100644 --- a/ql/ql/test/queries/style/NonDocBlock/NonDocBlock.expected +++ b/ql/ql/test/queries/style/NonDocBlock/NonDocBlock.expected @@ -1,2 +1,2 @@ -| Foo.qll:1:1:3:3 | BlockComment | Block comment could be QLDoc for $@. | Foo.qll:1:1:13:2 | TopLevel | the file | +| Foo.qll:1:1:3:3 | BlockComment | Block comment could be QLDoc for $@. | Foo.qll:1:1:22:2 | TopLevel | the file | | Foo.qll:10:1:10:24 | BlockComment | Block comment could be QLDoc for $@. | Foo.qll:11:7:11:9 | Class Foo | the below code | From 20c4699478bd7cc213e72da272666f7c4de7df45 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 16 Nov 2022 13:39:22 +0100 Subject: [PATCH 292/796] CPP: convert some block-comments that could be QLDoc to QLDoc --- cpp/ql/lib/semmle/code/cpp/security/TaintTracking.qll | 2 +- cpp/ql/src/jsf/4.09 Style/Naming.qll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/security/TaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/security/TaintTracking.qll index 5b8f221f73a..49ef4137aa1 100644 --- a/cpp/ql/lib/semmle/code/cpp/security/TaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/security/TaintTracking.qll @@ -1,4 +1,4 @@ -/* +/** * Support for tracking tainted data through the program. This is an alias for * `semmle.code.cpp.ir.dataflow.DefaultTaintTracking` provided for backwards * compatibility. diff --git a/cpp/ql/src/jsf/4.09 Style/Naming.qll b/cpp/ql/src/jsf/4.09 Style/Naming.qll index 264a6bac219..5df3724a067 100644 --- a/cpp/ql/src/jsf/4.09 Style/Naming.qll +++ b/cpp/ql/src/jsf/4.09 Style/Naming.qll @@ -1,4 +1,4 @@ -/* +/** * Common functions for implementing naming conventions * * Naming rules are the following: From 6bfaf3b2f7916c99530964d89241b327389e43dd Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 16 Nov 2022 13:39:33 +0100 Subject: [PATCH 293/796] C#: convert some block-comments that could be QLDoc to QLDoc --- csharp/ql/campaigns/Solorigate/lib/Solorigate.qll | 2 +- .../code/csharp/Cryptography/NonCryptographicHashes.qll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/ql/campaigns/Solorigate/lib/Solorigate.qll b/csharp/ql/campaigns/Solorigate/lib/Solorigate.qll index 51559093b07..3d3468af78d 100644 --- a/csharp/ql/campaigns/Solorigate/lib/Solorigate.qll +++ b/csharp/ql/campaigns/Solorigate/lib/Solorigate.qll @@ -1,4 +1,4 @@ -/* +/** * Provides reusable predicates related to Solorigate */ diff --git a/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll b/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll index b7371fafb3e..adb8df80ea6 100644 --- a/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll +++ b/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll @@ -1,4 +1,4 @@ -/* +/** * Predicates that help detect potential non-cryptographic hash functions * * By themselves, non-cryptographic functions are common and not dangerous From 7331363618aa540c16410d54e8ddbb64b098646b Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 16 Nov 2022 13:40:15 +0100 Subject: [PATCH 294/796] Java: convert some block-comments that could be QLDoc to QLDoc --- java/ql/lib/semmle/code/java/frameworks/Properties.qll | 3 ++- java/ql/lib/semmle/code/java/frameworks/Rmi.qll | 3 ++- java/ql/lib/semmle/code/java/frameworks/apache/Exec.qll | 3 ++- java/ql/lib/semmle/code/java/security/ExternalProcess.qll | 3 ++- java/ql/lib/semmle/code/java/security/RelativePaths.qll | 3 ++- java/ql/lib/semmle/code/java/security/SqlUnescapedLib.qll | 3 ++- .../src/Violations of Best Practice/Dead Code/DeadLocals.qll | 2 +- 7 files changed, 13 insertions(+), 7 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/Properties.qll b/java/ql/lib/semmle/code/java/frameworks/Properties.qll index 0c7b83b2e52..096e3bbb43c 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Properties.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Properties.qll @@ -1,4 +1,5 @@ -/* Definitions related to `java.util.Properties`. */ +/** Definitions related to `java.util.Properties`. */ + import semmle.code.java.Type private import semmle.code.java.dataflow.FlowSteps diff --git a/java/ql/lib/semmle/code/java/frameworks/Rmi.qll b/java/ql/lib/semmle/code/java/frameworks/Rmi.qll index 19428afae92..3b96ccd828d 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Rmi.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Rmi.qll @@ -1,4 +1,5 @@ -/* Remote Method Invocation. */ +/** Remote Method Invocation. */ + import java /** The interface `java.rmi.Remote`. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/Exec.qll b/java/ql/lib/semmle/code/java/frameworks/apache/Exec.qll index 978154d3274..5f44f878eb2 100644 --- a/java/ql/lib/semmle/code/java/frameworks/apache/Exec.qll +++ b/java/ql/lib/semmle/code/java/frameworks/apache/Exec.qll @@ -1,4 +1,5 @@ -/* Definitions related to the Apache Commons Exec library. */ +/** Definitions related to the Apache Commons Exec library. */ + import semmle.code.java.Type import semmle.code.java.security.ExternalProcess diff --git a/java/ql/lib/semmle/code/java/security/ExternalProcess.qll b/java/ql/lib/semmle/code/java/security/ExternalProcess.qll index fe5e46d5efb..9a061c7a419 100644 --- a/java/ql/lib/semmle/code/java/security/ExternalProcess.qll +++ b/java/ql/lib/semmle/code/java/security/ExternalProcess.qll @@ -1,4 +1,5 @@ -/* Definitions related to external processes. */ +/** Definitions related to external processes. */ + import semmle.code.java.Member private module Instances { diff --git a/java/ql/lib/semmle/code/java/security/RelativePaths.qll b/java/ql/lib/semmle/code/java/security/RelativePaths.qll index 45473997489..458bb7aea5d 100644 --- a/java/ql/lib/semmle/code/java/security/RelativePaths.qll +++ b/java/ql/lib/semmle/code/java/security/RelativePaths.qll @@ -1,4 +1,5 @@ -/* Detection of strings and arrays of strings containing relative paths. */ +/** Detection of strings and arrays of strings containing relative paths. */ + import java /** diff --git a/java/ql/lib/semmle/code/java/security/SqlUnescapedLib.qll b/java/ql/lib/semmle/code/java/security/SqlUnescapedLib.qll index d76c77c499c..3f5810e141b 100644 --- a/java/ql/lib/semmle/code/java/security/SqlUnescapedLib.qll +++ b/java/ql/lib/semmle/code/java/security/SqlUnescapedLib.qll @@ -1,4 +1,5 @@ -/* Definitions used by `SqlUnescaped.ql`. */ +/** Definitions used by `SqlUnescaped.ql`. */ + import semmle.code.java.security.ControlledString import semmle.code.java.dataflow.TaintTracking diff --git a/java/ql/src/Violations of Best Practice/Dead Code/DeadLocals.qll b/java/ql/src/Violations of Best Practice/Dead Code/DeadLocals.qll index 82933aa9bac..8837b207e20 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/DeadLocals.qll +++ b/java/ql/src/Violations of Best Practice/Dead Code/DeadLocals.qll @@ -1,4 +1,4 @@ -/* +/** * Provides classes and predicates for "dead locals": which variables are used, which assignments are useless, etc. */ From 9eaeaf732270d97fd30f30131587efa6785c76e6 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 16 Nov 2022 13:41:52 +0100 Subject: [PATCH 295/796] ATM: convert some block-comments that could be QLDoc to QLDoc --- .../lib/experimental/adaptivethreatmodeling/ATMConfig.qll | 2 +- .../adaptivethreatmodeling/AdaptiveThreatModeling.qll | 2 +- .../lib/experimental/adaptivethreatmodeling/BaseScoring.qll | 2 +- .../lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll | 2 +- .../experimental/adaptivethreatmodeling/EndpointFeatures.qll | 2 +- .../lib/experimental/adaptivethreatmodeling/EndpointScoring.qll | 2 +- .../adaptivethreatmodeling/FunctionBodyFeatures.qll | 2 +- .../modelbuilding/counting/CountAlertsAndSinks.qll | 2 +- .../modelbuilding/extraction/Exclusions.qll | 2 +- .../modelbuilding/extraction/ExtractEndpointDataTraining.qll | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index 55d75ad2e4d..b9b077380fe 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -1,4 +1,4 @@ -/* +/** * For internal use only. * * Configures boosting for adaptive threat modeling (ATM). diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/AdaptiveThreatModeling.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/AdaptiveThreatModeling.qll index 002a5c8fe8e..0168d167509 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/AdaptiveThreatModeling.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/AdaptiveThreatModeling.qll @@ -1,4 +1,4 @@ -/* +/** * For internal use only. * * Provides information about the results of boosted queries for use in adaptive threat modeling (ATM). diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/BaseScoring.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/BaseScoring.qll index a6787196bbb..fb9b017b84c 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/BaseScoring.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/BaseScoring.qll @@ -1,4 +1,4 @@ -/* +/** * For internal use only. * * Provides shared scoring functionality for use in adaptive threat modeling (ATM). diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll index e569fb3dc96..274bab00221 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll @@ -1,4 +1,4 @@ -/* +/** * For internal use only. * * Provides predicates that expose the knowledge of models diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointFeatures.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointFeatures.qll index 60a490cc454..8b4d9147a00 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointFeatures.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointFeatures.qll @@ -1,4 +1,4 @@ -/* +/** * For internal use only. * * Extracts data about the database for use in adaptive threat modeling (ATM). diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointScoring.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointScoring.qll index 7f9e53a5465..6746c06db7b 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointScoring.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointScoring.qll @@ -1,4 +1,4 @@ -/* +/** * For internal use only. * * Provides an implementation of scoring alerts for use in adaptive threat modeling (ATM). diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FunctionBodyFeatures.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FunctionBodyFeatures.qll index 4464842bc38..62531a9d423 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FunctionBodyFeatures.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FunctionBodyFeatures.qll @@ -1,4 +1,4 @@ -/* +/** * FunctionBodyFeatures.qll * * Contains logic relating to the `enclosingFunctionBody` and `enclosingFunctionName` features. diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/counting/CountAlertsAndSinks.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/counting/CountAlertsAndSinks.qll index 2549db106f4..a4f52b1cf78 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/counting/CountAlertsAndSinks.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/counting/CountAlertsAndSinks.qll @@ -1,4 +1,4 @@ -/* +/** * For internal use only. * * diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/Exclusions.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/Exclusions.qll index 79d3486e2db..822b2d7ea62 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/Exclusions.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/Exclusions.qll @@ -1,4 +1,4 @@ -/* +/** * For internal use only. * * Defines files that should be excluded from the evaluation of ML models. diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll index 153afdb1b45..49f1f44e836 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll @@ -1,4 +1,4 @@ -/* +/** * For internal use only. * * Extracts training data we can use to train ML models for ML-powered queries. From fe49e41d7b8b4ed6ab137acb32f7b0dc6089a454 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 16 Nov 2022 13:42:12 +0100 Subject: [PATCH 296/796] JS: convert some block-comments that could be QLDoc to QLDoc --- .../ql/test/tutorials/Validating RAML-based APIs/Osprey.qll | 3 ++- .../ql/test/tutorials/Validating RAML-based APIs/RAML.qll | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/javascript/ql/test/tutorials/Validating RAML-based APIs/Osprey.qll b/javascript/ql/test/tutorials/Validating RAML-based APIs/Osprey.qll index d7c7df8e1fd..bf4d1dc2067 100644 --- a/javascript/ql/test/tutorials/Validating RAML-based APIs/Osprey.qll +++ b/javascript/ql/test/tutorials/Validating RAML-based APIs/Osprey.qll @@ -1,4 +1,5 @@ -/* Model of Osprey API implementations. */ +/** Model of Osprey API implementations. */ + import javascript import HTTP diff --git a/javascript/ql/test/tutorials/Validating RAML-based APIs/RAML.qll b/javascript/ql/test/tutorials/Validating RAML-based APIs/RAML.qll index a871d5e751e..b110a339046 100644 --- a/javascript/ql/test/tutorials/Validating RAML-based APIs/RAML.qll +++ b/javascript/ql/test/tutorials/Validating RAML-based APIs/RAML.qll @@ -1,4 +1,5 @@ -/* Model of RAML specifications. */ +/** Model of RAML specifications. */ + import javascript import HTTP From 25b32860baae8cf75d455c0fa871f459f1f64a0b Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 16 Nov 2022 13:42:43 +0100 Subject: [PATCH 297/796] Py: convert a block-comment that could be QLDoc to QLDoc --- python/ql/lib/semmle/python/TestUtils.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/TestUtils.qll b/python/ql/lib/semmle/python/TestUtils.qll index d7b8fc24676..8b1ae58be4f 100644 --- a/python/ql/lib/semmle/python/TestUtils.qll +++ b/python/ql/lib/semmle/python/TestUtils.qll @@ -1,4 +1,5 @@ -/* This file contains test-related utility functions */ +/** This file contains test-related utility functions */ + import python /** Removes everything up to the occurrence of `sub` in the string `str` */ From 76c6943159d3823df460f80a260a4f20a63e9eba Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 16 Nov 2022 13:48:41 +0100 Subject: [PATCH 298/796] add stats for @satisfies_expr --- javascript/ql/lib/semmlecode.javascript.dbscheme.stats | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/javascript/ql/lib/semmlecode.javascript.dbscheme.stats b/javascript/ql/lib/semmlecode.javascript.dbscheme.stats index ed051cd16ac..7e0b98ea867 100644 --- a/javascript/ql/lib/semmlecode.javascript.dbscheme.stats +++ b/javascript/ql/lib/semmlecode.javascript.dbscheme.stats @@ -450,6 +450,10 @@ 100 +@satisfies_expr +100 + + @preinc_expr 1792 From 54a6f066b3a5440be0f01336942f285c812a9d80 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 16 Nov 2022 09:45:53 +0100 Subject: [PATCH 299/796] Address review comment --- .../Semmle.Extraction.CSharp/Entities/UserOperator.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/UserOperator.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/UserOperator.cs index 9f0d3c8f4c5..536af5065ed 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/UserOperator.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/UserOperator.cs @@ -162,10 +162,14 @@ namespace Semmle.Extraction.CSharp.Entities case "op_False": operatorName = "false"; break; - case var @checked when Regex.IsMatch(@checked, "^op_Checked.*"): - operatorName = @checked; - break; default: + var match = Regex.Match(methodName, "^op_Checked(.*)$"); + if (match.Success) + { + OperatorSymbol("op_" + match.Groups[1], out var uncheckedName); + operatorName = "checked " + uncheckedName; + break; + } operatorName = methodName; success = false; break; From 782c82a2d3921def4d2e7ecf0958e5adb35ebe71 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 14:30:54 +0100 Subject: [PATCH 300/796] Kotlin: Add test case for non serializable inner class query --- .../NonSerializableInnerClass.expected | 2 ++ .../NonSerializableInnerClass.qlref | 1 + .../NonSerializableInnerClassTest.kt | 11 +++++++++++ 3 files changed, 14 insertions(+) create mode 100644 java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClass.expected create mode 100644 java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClass.qlref create mode 100644 java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClassTest.kt diff --git a/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClass.expected b/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClass.expected new file mode 100644 index 00000000000..a8db2188711 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClass.expected @@ -0,0 +1,2 @@ +| NonSerializableInnerClassTest.kt:4:3:5:3 | X | Serializable inner class of non-serializable class $@. Consider making the class static or implementing readObject() and writeObject(). | NonSerializableInnerClassTest.kt:3:1:6:1 | A | A | +| NonSerializableInnerClassTest.kt:9:3:10:3 | X | Serializable inner class of non-serializable class $@. Consider making the class static or implementing readObject() and writeObject(). | NonSerializableInnerClassTest.kt:8:1:11:1 | B | B | diff --git a/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClass.qlref b/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClass.qlref new file mode 100644 index 00000000000..4cbb0995764 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClass.qlref @@ -0,0 +1 @@ +Likely Bugs/Serialization/NonSerializableInnerClass.ql diff --git a/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClassTest.kt b/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClassTest.kt new file mode 100644 index 00000000000..3c3d72d0291 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClassTest.kt @@ -0,0 +1,11 @@ +import java.io.Serializable + +class A { + class X : Serializable { + } +} + +class B { + inner class X : Serializable { + } +} From 7a0e2480963e1dc4a0e84afb999690f0db891de5 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 14:46:01 +0100 Subject: [PATCH 301/796] Exclude .kt files from serializable inner class query --- .../src/Likely Bugs/Serialization/NonSerializableInnerClass.ql | 2 +- .../NonSerializableInnerClass.expected | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/java/ql/src/Likely Bugs/Serialization/NonSerializableInnerClass.ql b/java/ql/src/Likely Bugs/Serialization/NonSerializableInnerClass.ql index 1bf54abb89f..8081c551eed 100644 --- a/java/ql/src/Likely Bugs/Serialization/NonSerializableInnerClass.ql +++ b/java/ql/src/Likely Bugs/Serialization/NonSerializableInnerClass.ql @@ -77,7 +77,7 @@ predicate exceptions(NestedClass inner) { from NestedClass inner, Class outer, string advice where - inner.fromSource() and + inner.getFile().isJavaSourceFile() and isSerializable(inner) and outer = enclosingInstanceType+(inner) and not isSerializable(outer) and diff --git a/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClass.expected b/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClass.expected index a8db2188711..e69de29bb2d 100644 --- a/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClass.expected +++ b/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClass.expected @@ -1,2 +0,0 @@ -| NonSerializableInnerClassTest.kt:4:3:5:3 | X | Serializable inner class of non-serializable class $@. Consider making the class static or implementing readObject() and writeObject(). | NonSerializableInnerClassTest.kt:3:1:6:1 | A | A | -| NonSerializableInnerClassTest.kt:9:3:10:3 | X | Serializable inner class of non-serializable class $@. Consider making the class static or implementing readObject() and writeObject(). | NonSerializableInnerClassTest.kt:8:1:11:1 | B | B | From d6a395ba373fba154f2a7b3b6dbd42a007aa56ce Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 16 Nov 2022 11:38:36 +0000 Subject: [PATCH 302/796] Remove non-longer-needed expected diagnostics --- java/ql/test/kotlin/library-tests/annotation_classes/def.kt | 2 -- java/ql/test/kotlin/library-tests/annotations/jvmName/test.kt | 2 -- .../library-tests/arrays-with-variances/takesArrayList.kt | 2 -- java/ql/test/kotlin/library-tests/extensions/extensions.kt | 2 -- .../ql/test/kotlin/library-tests/generics-location/generics.kt | 2 -- .../internal-constructor-called-from-java/test.kt | 2 -- .../ql/test/kotlin/library-tests/internal-public-alias/test.kt | 2 -- java/ql/test/kotlin/library-tests/java_and_kotlin/Kotlin.kt | 2 -- .../kotlin/library-tests/java_and_kotlin_internal/Kotlin.kt | 2 -- java/ql/test/kotlin/library-tests/jvmoverloads_flow/test.kt | 2 -- .../ql/test/kotlin/library-tests/jvmoverloads_generics/test.kt | 2 -- .../library-tests/jvmstatic-annotation/PrintAst.expected | 3 --- java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.kt | 2 -- 13 files changed, 27 deletions(-) diff --git a/java/ql/test/kotlin/library-tests/annotation_classes/def.kt b/java/ql/test/kotlin/library-tests/annotation_classes/def.kt index 46c2c2055d4..556973c4728 100644 --- a/java/ql/test/kotlin/library-tests/annotation_classes/def.kt +++ b/java/ql/test/kotlin/library-tests/annotation_classes/def.kt @@ -1,5 +1,3 @@ annotation class SomeAnnotation -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata diff --git a/java/ql/test/kotlin/library-tests/annotations/jvmName/test.kt b/java/ql/test/kotlin/library-tests/annotations/jvmName/test.kt index b4a4bcf38be..edbca12e011 100644 --- a/java/ql/test/kotlin/library-tests/annotations/jvmName/test.kt +++ b/java/ql/test/kotlin/library-tests/annotations/jvmName/test.kt @@ -17,10 +17,8 @@ annotation class Ann( val p: Int, @get:JvmName("w") val q: Int) -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) // Diagnostic Matches: Incomplete annotation: @kotlin.jvm.JvmName(name="changeY") // Diagnostic Matches: Incomplete annotation: @kotlin.jvm.JvmName(name="getX_prop") // Diagnostic Matches: Incomplete annotation: @kotlin.jvm.JvmName(name="method") // Diagnostic Matches: Incomplete annotation: @kotlin.jvm.JvmName(name="y") -// Diagnostic Matches: Unknown location for kotlin.Metadata // Diagnostic Matches: Unknown location for kotlin.jvm.JvmName diff --git a/java/ql/test/kotlin/library-tests/arrays-with-variances/takesArrayList.kt b/java/ql/test/kotlin/library-tests/arrays-with-variances/takesArrayList.kt index 7f529df2dc9..009b1ae12f4 100644 --- a/java/ql/test/kotlin/library-tests/arrays-with-variances/takesArrayList.kt +++ b/java/ql/test/kotlin/library-tests/arrays-with-variances/takesArrayList.kt @@ -111,7 +111,5 @@ public class TakesArrayList { } -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata // Diagnostic Matches: Completion failure for type: org.jetbrains.annotations.NotNull // Diagnostic Matches: Unknown location for org.jetbrains.annotations.NotNull diff --git a/java/ql/test/kotlin/library-tests/extensions/extensions.kt b/java/ql/test/kotlin/library-tests/extensions/extensions.kt index 8742f55e7b9..c80841a849b 100644 --- a/java/ql/test/kotlin/library-tests/extensions/extensions.kt +++ b/java/ql/test/kotlin/library-tests/extensions/extensions.kt @@ -32,6 +32,4 @@ fun foo() { } // Diagnostic Matches: Completion failure for type: org.jetbrains.annotations.NotNull -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata // Diagnostic Matches: Unknown location for org.jetbrains.annotations.NotNull diff --git a/java/ql/test/kotlin/library-tests/generics-location/generics.kt b/java/ql/test/kotlin/library-tests/generics-location/generics.kt index dff06636bb1..05ff48bc323 100644 --- a/java/ql/test/kotlin/library-tests/generics-location/generics.kt +++ b/java/ql/test/kotlin/library-tests/generics-location/generics.kt @@ -10,5 +10,3 @@ class B { } } -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata diff --git a/java/ql/test/kotlin/library-tests/internal-constructor-called-from-java/test.kt b/java/ql/test/kotlin/library-tests/internal-constructor-called-from-java/test.kt index b9c4397e920..905d9852632 100644 --- a/java/ql/test/kotlin/library-tests/internal-constructor-called-from-java/test.kt +++ b/java/ql/test/kotlin/library-tests/internal-constructor-called-from-java/test.kt @@ -4,5 +4,3 @@ public class Test() { } -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata diff --git a/java/ql/test/kotlin/library-tests/internal-public-alias/test.kt b/java/ql/test/kotlin/library-tests/internal-public-alias/test.kt index f363f769e50..216d3b3450d 100644 --- a/java/ql/test/kotlin/library-tests/internal-public-alias/test.kt +++ b/java/ql/test/kotlin/library-tests/internal-public-alias/test.kt @@ -11,5 +11,3 @@ public class Test { } -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata diff --git a/java/ql/test/kotlin/library-tests/java_and_kotlin/Kotlin.kt b/java/ql/test/kotlin/library-tests/java_and_kotlin/Kotlin.kt index 1686e09e02d..61c48cf8a5c 100644 --- a/java/ql/test/kotlin/library-tests/java_and_kotlin/Kotlin.kt +++ b/java/ql/test/kotlin/library-tests/java_and_kotlin/Kotlin.kt @@ -16,7 +16,5 @@ class Dkotlin : Base() { // Diagnostic Matches: Completion failure for type: org.jetbrains.annotations.NotNull // Diagnostic Matches: Completion failure for type: org.jetbrains.annotations.Nullable -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata // Diagnostic Matches: Unknown location for org.jetbrains.annotations.NotNull // Diagnostic Matches: Unknown location for org.jetbrains.annotations.Nullable diff --git a/java/ql/test/kotlin/library-tests/java_and_kotlin_internal/Kotlin.kt b/java/ql/test/kotlin/library-tests/java_and_kotlin_internal/Kotlin.kt index 4cdedefbbc8..09297fd286e 100644 --- a/java/ql/test/kotlin/library-tests/java_and_kotlin_internal/Kotlin.kt +++ b/java/ql/test/kotlin/library-tests/java_and_kotlin_internal/Kotlin.kt @@ -3,5 +3,3 @@ public class Kotlin { } } -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata diff --git a/java/ql/test/kotlin/library-tests/jvmoverloads_flow/test.kt b/java/ql/test/kotlin/library-tests/jvmoverloads_flow/test.kt index f7e42c682df..fcd8e669425 100644 --- a/java/ql/test/kotlin/library-tests/jvmoverloads_flow/test.kt +++ b/java/ql/test/kotlin/library-tests/jvmoverloads_flow/test.kt @@ -86,8 +86,6 @@ public class TestDefaultParameterReference { } -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata // Diagnostic Matches: Completion failure for type: org.jetbrains.annotations.NotNull // Diagnostic Matches: Unknown location for org.jetbrains.annotations.NotNull // Diagnostic Matches: Completion failure for type: kotlin.jvm.JvmOverloads diff --git a/java/ql/test/kotlin/library-tests/jvmoverloads_generics/test.kt b/java/ql/test/kotlin/library-tests/jvmoverloads_generics/test.kt index ee49968eb57..eaa561d5ccf 100644 --- a/java/ql/test/kotlin/library-tests/jvmoverloads_generics/test.kt +++ b/java/ql/test/kotlin/library-tests/jvmoverloads_generics/test.kt @@ -5,8 +5,6 @@ public class A { } -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata // Diagnostic Matches: Completion failure for type: kotlin.jvm.JvmOverloads // Diagnostic Matches: Completion failure for type: org.jetbrains.annotations.Nullable // Diagnostic Matches: Unknown location for kotlin.jvm.JvmOverloads diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected index 1376baa4f1d..6386ec036fb 100644 --- a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected @@ -141,13 +141,11 @@ test.kt: # 65| 0: [MethodAccess] getPropWithStaticGetter(...) # 65| -1: [TypeAccess] NonCompanion # 9| 2: [Class] HasCompanion -#-----| -3: (Annotations) # 9| 2: [Constructor] HasCompanion # 9| 5: [BlockStmt] { ... } # 9| 0: [SuperConstructorInvocationStmt] super(...) # 9| 1: [BlockStmt] { ... } # 11| 3: [Class] Companion -#-----| -3: (Annotations) # 11| 1: [Constructor] Companion # 11| 5: [BlockStmt] { ... } # 11| 0: [SuperConstructorInvocationStmt] super(...) @@ -318,7 +316,6 @@ test.kt: # 25| -1: [TypeAccess] HasCompanion # 25| 0: [VarAccess] s # 31| 3: [Class] NonCompanion -#-----| -3: (Annotations) # 31| 2: [Constructor] NonCompanion # 31| 5: [BlockStmt] { ... } # 31| 0: [SuperConstructorInvocationStmt] super(...) diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.kt b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.kt index 6f7014723a2..211fceb0912 100644 --- a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.kt +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.kt @@ -66,8 +66,6 @@ fun externalUser() { } -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata // Diagnostic Matches: Completion failure for type: kotlin.jvm.JvmStatic // Diagnostic Matches: Completion failure for type: org.jetbrains.annotations.NotNull // Diagnostic Matches: Unknown location for kotlin.jvm.JvmStatic From 35078738bc44886c56251fc3774bd45d9417db60 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 14:51:21 +0100 Subject: [PATCH 303/796] Kotlin: Add FP test case for useless parameter query --- java/ql/test/kotlin/query-tests/UselessParameter/Test.kt | 3 +++ .../query-tests/UselessParameter/UselessParameter.expected | 1 + 2 files changed, 4 insertions(+) diff --git a/java/ql/test/kotlin/query-tests/UselessParameter/Test.kt b/java/ql/test/kotlin/query-tests/UselessParameter/Test.kt index 4e41e048aa4..d5e6c5ef7b7 100644 --- a/java/ql/test/kotlin/query-tests/UselessParameter/Test.kt +++ b/java/ql/test/kotlin/query-tests/UselessParameter/Test.kt @@ -19,3 +19,6 @@ object O {} fun C.fn() {} fun C.Companion.fn() {} fun O.fn() {} + +@Suppress("UNUSED_PARAMETER") +fun fn2(a: Int) {} diff --git a/java/ql/test/kotlin/query-tests/UselessParameter/UselessParameter.expected b/java/ql/test/kotlin/query-tests/UselessParameter/UselessParameter.expected index 72b3348a019..b43c7c299f2 100644 --- a/java/ql/test/kotlin/query-tests/UselessParameter/UselessParameter.expected +++ b/java/ql/test/kotlin/query-tests/UselessParameter/UselessParameter.expected @@ -1,2 +1,3 @@ | Test.kt:11:8:11:18 | a | The parameter 'a' is never used. | | Test.kt:19:5:19:5 | | The parameter '' is never used. | +| Test.kt:24:9:24:14 | a | The parameter 'a' is never used. | From 48c37a2c0f22b972afd0178412ce49ceb425efc5 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 14:51:49 +0100 Subject: [PATCH 304/796] Exclude .kt files from useless parameter query --- java/ql/lib/semmle/code/java/deadcode/DeadCode.qll | 2 +- .../query-tests/UselessParameter/UselessParameter.expected | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/java/ql/lib/semmle/code/java/deadcode/DeadCode.qll b/java/ql/lib/semmle/code/java/deadcode/DeadCode.qll index 6296d255103..d20ae81b00b 100644 --- a/java/ql/lib/semmle/code/java/deadcode/DeadCode.qll +++ b/java/ql/lib/semmle/code/java/deadcode/DeadCode.qll @@ -274,7 +274,7 @@ class DeadMethod extends Callable { class RootdefCallable extends Callable { RootdefCallable() { - this.fromSource() and + this.getFile().isJavaSourceFile() and not this.(Method).overridesOrInstantiates(_) } diff --git a/java/ql/test/kotlin/query-tests/UselessParameter/UselessParameter.expected b/java/ql/test/kotlin/query-tests/UselessParameter/UselessParameter.expected index b43c7c299f2..e69de29bb2d 100644 --- a/java/ql/test/kotlin/query-tests/UselessParameter/UselessParameter.expected +++ b/java/ql/test/kotlin/query-tests/UselessParameter/UselessParameter.expected @@ -1,3 +0,0 @@ -| Test.kt:11:8:11:18 | a | The parameter 'a' is never used. | -| Test.kt:19:5:19:5 | | The parameter '' is never used. | -| Test.kt:24:9:24:14 | a | The parameter 'a' is never used. | From e547be5e9acebac6e1d657e16d0a3c12ba4dcbe5 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 14:58:36 +0100 Subject: [PATCH 305/796] Kotlin: Add FP test case for misnamed reftype query --- .../NamingConventionsRefTypes.expected | 3 +++ .../NamingConventionsRefTypes.qlref | 1 + .../query-tests/NamingConventionsRefTypes/Test.kt | 12 ++++++++++++ 3 files changed, 16 insertions(+) create mode 100644 java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.expected create mode 100644 java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.qlref create mode 100644 java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/Test.kt diff --git a/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.expected b/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.expected new file mode 100644 index 00000000000..bc00b1c4761 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.expected @@ -0,0 +1,3 @@ +| Test.kt:3:23:5:9 | | Class and interface names should start in uppercase. | +| Test.kt:7:9:8:9 | | Class and interface names should start in uppercase. | +| Test.kt:12:1:12:13 | aaaa | Class and interface names should start in uppercase. | diff --git a/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.qlref b/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.qlref new file mode 100644 index 00000000000..6f76aed32cb --- /dev/null +++ b/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.qlref @@ -0,0 +1 @@ +Advisory/Naming/NamingConventionsRefTypes.ql \ No newline at end of file diff --git a/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/Test.kt b/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/Test.kt new file mode 100644 index 00000000000..f62497d59c6 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/Test.kt @@ -0,0 +1,12 @@ +class Foo { + fun myFun() { + val nestedStr by lazy { + "another string" + } + + fun nestedFun() { + } + } +} + +class aaaa {} \ No newline at end of file From c1be93a34ce8e99d46b9084714bce80a754895c3 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 14:59:20 +0100 Subject: [PATCH 306/796] Exclude .kt files from misnamed reftype query --- java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql | 2 +- .../NamingConventionsRefTypes.expected | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql b/java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql index 83093433123..f0d6d20b1b2 100644 --- a/java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql +++ b/java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql @@ -12,7 +12,7 @@ import java from RefType t where - t.fromSource() and + t.getFile().isJavaSourceFile() and not t instanceof AnonymousClass and not t.getName().substring(0, 1).toUpperCase() = t.getName().substring(0, 1) select t, "Class and interface names should start in uppercase." diff --git a/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.expected b/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.expected index bc00b1c4761..e69de29bb2d 100644 --- a/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.expected +++ b/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.expected @@ -1,3 +0,0 @@ -| Test.kt:3:23:5:9 | | Class and interface names should start in uppercase. | -| Test.kt:7:9:8:9 | | Class and interface names should start in uppercase. | -| Test.kt:12:1:12:13 | aaaa | Class and interface names should start in uppercase. | From 5f6f72ba8e759e25e81df1818f025bad1435ca9b Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 15:05:07 +0100 Subject: [PATCH 307/796] Kotlin: Add FP test case for ignored return value query --- .../ReturnValueIgnored.expected | 1 + .../ReturnValueIgnored/ReturnValueIgnored.qlref | 1 + .../query-tests/ReturnValueIgnored/Test.kt | 16 ++++++++++++++++ 3 files changed, 18 insertions(+) create mode 100644 java/ql/test/kotlin/query-tests/ReturnValueIgnored/ReturnValueIgnored.expected create mode 100644 java/ql/test/kotlin/query-tests/ReturnValueIgnored/ReturnValueIgnored.qlref create mode 100644 java/ql/test/kotlin/query-tests/ReturnValueIgnored/Test.kt diff --git a/java/ql/test/kotlin/query-tests/ReturnValueIgnored/ReturnValueIgnored.expected b/java/ql/test/kotlin/query-tests/ReturnValueIgnored/ReturnValueIgnored.expected new file mode 100644 index 00000000000..8088b356482 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/ReturnValueIgnored/ReturnValueIgnored.expected @@ -0,0 +1 @@ +| Test.kt:14:29:14:33 | foo(...) | The result of the call is ignored, but 90% of calls to foo use the return value. | diff --git a/java/ql/test/kotlin/query-tests/ReturnValueIgnored/ReturnValueIgnored.qlref b/java/ql/test/kotlin/query-tests/ReturnValueIgnored/ReturnValueIgnored.qlref new file mode 100644 index 00000000000..ef1dc964d95 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/ReturnValueIgnored/ReturnValueIgnored.qlref @@ -0,0 +1 @@ +Likely Bugs/Statements/ReturnValueIgnored.ql \ No newline at end of file diff --git a/java/ql/test/kotlin/query-tests/ReturnValueIgnored/Test.kt b/java/ql/test/kotlin/query-tests/ReturnValueIgnored/Test.kt new file mode 100644 index 00000000000..8520b3cedfc --- /dev/null +++ b/java/ql/test/kotlin/query-tests/ReturnValueIgnored/Test.kt @@ -0,0 +1,16 @@ +class Foo { + fun foo(): Int { return 5 } + fun bar() { + val x0 = foo() + val x1 = foo() + val x2 = foo() + val x3 = foo() + val x4 = foo() + val x5 = foo() + val x6 = foo() + val x7 = foo() + val x8 = foo() + val x9 = foo() + val x = if (true) { foo() } else 6 + } +} From c42663723f197030c2d06adf28679001aaf52dd2 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 15:05:29 +0100 Subject: [PATCH 308/796] Exclude .kt files from ignored return value query --- java/ql/src/Likely Bugs/Statements/ReturnValueIgnored.ql | 1 + .../query-tests/ReturnValueIgnored/ReturnValueIgnored.expected | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Likely Bugs/Statements/ReturnValueIgnored.ql b/java/ql/src/Likely Bugs/Statements/ReturnValueIgnored.ql index 3355fd22190..c50a9a5f1a4 100644 --- a/java/ql/src/Likely Bugs/Statements/ReturnValueIgnored.ql +++ b/java/ql/src/Likely Bugs/Statements/ReturnValueIgnored.ql @@ -75,6 +75,7 @@ predicate isMustBeQualifierMockingMethod(Method m) { predicate relevantMethodCall(MethodAccess ma, Method m) { // For "return value ignored", all method calls are relevant. + not ma.getFile().isKotlinSourceFile() and ma.getMethod() = m and not m.getReturnType().hasName("void") and (not isMockingMethod(m) or isMustBeQualifierMockingMethod(m)) and diff --git a/java/ql/test/kotlin/query-tests/ReturnValueIgnored/ReturnValueIgnored.expected b/java/ql/test/kotlin/query-tests/ReturnValueIgnored/ReturnValueIgnored.expected index 8088b356482..e69de29bb2d 100644 --- a/java/ql/test/kotlin/query-tests/ReturnValueIgnored/ReturnValueIgnored.expected +++ b/java/ql/test/kotlin/query-tests/ReturnValueIgnored/ReturnValueIgnored.expected @@ -1 +0,0 @@ -| Test.kt:14:29:14:33 | foo(...) | The result of the call is ignored, but 90% of calls to foo use the return value. | From 0d70b5c776379a4220c15bdcfcdbf564b7ae99cd Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 15:10:38 +0100 Subject: [PATCH 309/796] Kotlin: Add FP test case for one stmt in line query --- .../OneStatementPerLine/OneStatementPerLine.expected | 1 + .../OneStatementPerLine/OneStatementPerLine.qlref | 1 + .../ql/test/kotlin/query-tests/OneStatementPerLine/Test.kt | 7 +++++++ 3 files changed, 9 insertions(+) create mode 100644 java/ql/test/kotlin/query-tests/OneStatementPerLine/OneStatementPerLine.expected create mode 100644 java/ql/test/kotlin/query-tests/OneStatementPerLine/OneStatementPerLine.qlref create mode 100644 java/ql/test/kotlin/query-tests/OneStatementPerLine/Test.kt diff --git a/java/ql/test/kotlin/query-tests/OneStatementPerLine/OneStatementPerLine.expected b/java/ql/test/kotlin/query-tests/OneStatementPerLine/OneStatementPerLine.expected new file mode 100644 index 00000000000..b9d64771553 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/OneStatementPerLine/OneStatementPerLine.expected @@ -0,0 +1 @@ +| Test.kt:5:9:5:23 | return ... | This statement is followed by another on the same line. | diff --git a/java/ql/test/kotlin/query-tests/OneStatementPerLine/OneStatementPerLine.qlref b/java/ql/test/kotlin/query-tests/OneStatementPerLine/OneStatementPerLine.qlref new file mode 100644 index 00000000000..99f3f3f3293 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/OneStatementPerLine/OneStatementPerLine.qlref @@ -0,0 +1 @@ +Advisory/Statements/OneStatementPerLine.ql \ No newline at end of file diff --git a/java/ql/test/kotlin/query-tests/OneStatementPerLine/Test.kt b/java/ql/test/kotlin/query-tests/OneStatementPerLine/Test.kt new file mode 100644 index 00000000000..0936ef67775 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/OneStatementPerLine/Test.kt @@ -0,0 +1,7 @@ +class Foo { + fun foo(): Foo { return this } + + fun bar(x: Foo?): Foo? { + return x?.foo() + } +} From c9241cc93343832e43b567de4a4df2c2ab4912dc Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 15:11:38 +0100 Subject: [PATCH 310/796] Exclude .kt files from one stmt in line query --- java/ql/src/Advisory/Statements/OneStatementPerLine.ql | 1 + .../query-tests/OneStatementPerLine/OneStatementPerLine.expected | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Advisory/Statements/OneStatementPerLine.ql b/java/ql/src/Advisory/Statements/OneStatementPerLine.ql index 99ab9003e60..b4133761e27 100644 --- a/java/ql/src/Advisory/Statements/OneStatementPerLine.ql +++ b/java/ql/src/Advisory/Statements/OneStatementPerLine.ql @@ -37,6 +37,7 @@ predicate oneLineStatement(Stmt s, File f, int line, int col) { from Stmt s, Stmt s2 where exists(File f, int line, int col, int col2 | + f.isJavaSourceFile() and oneLineStatement(s, f, line, col) and oneLineStatement(s2, f, line, col2) and col < col2 and diff --git a/java/ql/test/kotlin/query-tests/OneStatementPerLine/OneStatementPerLine.expected b/java/ql/test/kotlin/query-tests/OneStatementPerLine/OneStatementPerLine.expected index b9d64771553..e69de29bb2d 100644 --- a/java/ql/test/kotlin/query-tests/OneStatementPerLine/OneStatementPerLine.expected +++ b/java/ql/test/kotlin/query-tests/OneStatementPerLine/OneStatementPerLine.expected @@ -1 +0,0 @@ -| Test.kt:5:9:5:23 | return ... | This statement is followed by another on the same line. | From 63e9ae3b93e116910e913a72fc2f3c03b57ee492 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 15:16:18 +0100 Subject: [PATCH 311/796] Kotlin: Add FP test case for mutual dependency query --- .../MutualDependency/MutualDependency.expected | 1 + .../query-tests/MutualDependency/MutualDependency.qlref | 1 + java/ql/test/kotlin/query-tests/MutualDependency/Test.kt | 8 ++++++++ 3 files changed, 10 insertions(+) create mode 100644 java/ql/test/kotlin/query-tests/MutualDependency/MutualDependency.expected create mode 100644 java/ql/test/kotlin/query-tests/MutualDependency/MutualDependency.qlref create mode 100644 java/ql/test/kotlin/query-tests/MutualDependency/Test.kt diff --git a/java/ql/test/kotlin/query-tests/MutualDependency/MutualDependency.expected b/java/ql/test/kotlin/query-tests/MutualDependency/MutualDependency.expected new file mode 100644 index 00000000000..b82b8484768 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/MutualDependency/MutualDependency.expected @@ -0,0 +1 @@ +| Test.kt:5:9:5:41 | | This type and type $@ are mutually dependent. | Test.kt:3:1:8:1 | Foo | Foo | diff --git a/java/ql/test/kotlin/query-tests/MutualDependency/MutualDependency.qlref b/java/ql/test/kotlin/query-tests/MutualDependency/MutualDependency.qlref new file mode 100644 index 00000000000..ab1dbe353ef --- /dev/null +++ b/java/ql/test/kotlin/query-tests/MutualDependency/MutualDependency.qlref @@ -0,0 +1 @@ +Architecture/Dependencies/MutualDependency.ql \ No newline at end of file diff --git a/java/ql/test/kotlin/query-tests/MutualDependency/Test.kt b/java/ql/test/kotlin/query-tests/MutualDependency/Test.kt new file mode 100644 index 00000000000..b0a9a45603f --- /dev/null +++ b/java/ql/test/kotlin/query-tests/MutualDependency/Test.kt @@ -0,0 +1,8 @@ +package foo.bar + +class Foo { + private fun someFun() { + fun say(s: String) { println(s) } + say("Str") + } +} From b6978128b17f3e949d288ee7d27b42bfbd7a54ba Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 15:16:51 +0100 Subject: [PATCH 312/796] Exclude .kt files from mutual dependency query --- java/ql/src/Architecture/Dependencies/MutualDependency.ql | 4 +++- .../query-tests/MutualDependency/MutualDependency.expected | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/java/ql/src/Architecture/Dependencies/MutualDependency.ql b/java/ql/src/Architecture/Dependencies/MutualDependency.ql index c6ef88cd305..6d66daf1c67 100644 --- a/java/ql/src/Architecture/Dependencies/MutualDependency.ql +++ b/java/ql/src/Architecture/Dependencies/MutualDependency.ql @@ -30,6 +30,8 @@ where t2.getName().toLowerCase().matches("%visitor%") or t1.getAMethod().getName().toLowerCase().matches("%visit%") or t2.getAMethod().getName().toLowerCase().matches("%visit%") or - t1.getPackage() = t2.getPackage() + t1.getPackage() = t2.getPackage() or + t1.getFile().isKotlinSourceFile() or + t2.getFile().isKotlinSourceFile() ) select t1, "This type and type $@ are mutually dependent.", t2, t2.getName() diff --git a/java/ql/test/kotlin/query-tests/MutualDependency/MutualDependency.expected b/java/ql/test/kotlin/query-tests/MutualDependency/MutualDependency.expected index b82b8484768..e69de29bb2d 100644 --- a/java/ql/test/kotlin/query-tests/MutualDependency/MutualDependency.expected +++ b/java/ql/test/kotlin/query-tests/MutualDependency/MutualDependency.expected @@ -1 +0,0 @@ -| Test.kt:5:9:5:41 | | This type and type $@ are mutually dependent. | Test.kt:3:1:8:1 | Foo | Foo | From fc614ad4d0cf9e66c6eed4d954dd91067ff83d5c Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 15:24:43 +0100 Subject: [PATCH 313/796] Kotlin: Exclude .kt files from missing `instanceof` in `equals` query --- .../src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql | 1 + .../kotlin/query-tests/MissingInstanceofInEquals/Test.kt | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql b/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql index 1f05298878a..1c7bb13c065 100644 --- a/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql +++ b/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql @@ -64,6 +64,7 @@ class UnimplementedEquals extends EqualsMethod { from EqualsMethod m where + m.getFile().isJavaSourceFile() and exists(m.getBody()) and exists(Parameter p | p = m.getAParameter() | // The parameter has no type test diff --git a/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/Test.kt b/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/Test.kt index 6eef90c517c..d5d230bffef 100644 --- a/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/Test.kt +++ b/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/Test.kt @@ -17,3 +17,9 @@ data class G(val x: Int) { return other != null && other.javaClass == this.javaClass } } + +data class H(val x: Int) { + override fun equals(other: Any?): Boolean { + return other != null + } +} From 9f2d89c9039a1b1dd0e49d9fde6035f9bcc6465e Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 16 Nov 2022 15:27:38 +0100 Subject: [PATCH 314/796] Update ql-style-guide.md Our [QLDoc style guide](https://github.com/github/codeql/blob/main/docs/qldoc-style-guide.md#predicates-with-result) says that we should avoid any use of `return`, so it would be smart to also do so in our own style guide for predicate names :blush: --- docs/ql-style-guide.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/ql-style-guide.md b/docs/ql-style-guide.md index 0b0efef27cc..29a427fdfae 100644 --- a/docs/ql-style-guide.md +++ b/docs/ql-style-guide.md @@ -176,7 +176,7 @@ private predicate foo(Expr e, Expr p) { 1. Acronyms *should* use normal PascalCase/camelCase. However, two-letter acronyms should have both letters capitalized. 1. Newtype predicate names *should* begin with `T`. 1. Predicates that have a result *should* be named `get...` -1. Predicates that can return multiple results *should* be named `getA...` or `getAn...` +1. Predicates that can have multiple results *should* be named `getA...` or `getAn...` 1. Predicates that don't have a result or parameters *should* be named `is...` or `has...` 1. *Avoid* underscores in names. 1. *Avoid* short or single-letter names for classes, predicates and fields. @@ -304,6 +304,7 @@ For more information about documenting the code that you contribute to this repo exists(Type arg | arg = this.getAChild() | arg instanceof TypeParameter) ``` + ```ql exists(Type qualifierType | this.hasNonExactQualifierType(qualifierType) From a9023d06d09e323727f9334736b9d8b7b9766f8b Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 15:29:24 +0100 Subject: [PATCH 315/796] Kotlin: Add FP test case for non serializable field query --- .../NonSerializableField/NonSerializableField.expected | 1 + .../NonSerializableField/NonSerializableField.qlref | 1 + .../NonSerializableField/NonSerializableFieldTest.kt | 4 ++++ 3 files changed, 6 insertions(+) create mode 100644 java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableField.expected create mode 100644 java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableField.qlref create mode 100644 java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableFieldTest.kt diff --git a/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableField.expected b/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableField.expected new file mode 100644 index 00000000000..54b712b084a --- /dev/null +++ b/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableField.expected @@ -0,0 +1 @@ +| NonSerializableFieldTest.kt:3:22:3:28 | | This field is in a serializable class, but is not serializable itself because Foo is not serializable. | diff --git a/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableField.qlref b/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableField.qlref new file mode 100644 index 00000000000..401d63757af --- /dev/null +++ b/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableField.qlref @@ -0,0 +1 @@ +Likely Bugs/Serialization/NonSerializableField.ql diff --git a/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableFieldTest.kt b/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableFieldTest.kt new file mode 100644 index 00000000000..bf790ea7c1e --- /dev/null +++ b/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableFieldTest.kt @@ -0,0 +1,4 @@ +class Foo { + fun f(i: Int) {} + fun g(i: Int) { (this::f)(i) } +} From 7d9ce53080aaa8d6f8eb0b4d1cf2c0a27d867153 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 15:30:25 +0100 Subject: [PATCH 316/796] Kotlin: Exclude .kt files from non serializable field query --- java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql | 2 +- .../NonSerializableField/NonSerializableField.expected | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql b/java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql index 920958ce3ce..bf00248720c 100644 --- a/java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql +++ b/java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql @@ -90,7 +90,7 @@ predicate exceptions(Class c, Field f) { from Class c, Field f, string reason where - c.fromSource() and + c.getFile().isJavaSourceFile() and c.getAStrictAncestor() instanceof TypeSerializable and f.getDeclaringType() = c and not exceptions(c, f) and diff --git a/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableField.expected b/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableField.expected index 54b712b084a..e69de29bb2d 100644 --- a/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableField.expected +++ b/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableField.expected @@ -1 +0,0 @@ -| NonSerializableFieldTest.kt:3:22:3:28 | | This field is in a serializable class, but is not serializable itself because Foo is not serializable. | From 7cab6b5491c68759b3f9f6ba3a35098708998a78 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 21 Oct 2022 14:23:30 +0200 Subject: [PATCH 317/796] C#: Include SSA "phi reads" in `DataFlow::Node` --- .../lib/semmle/code/cil/internal/SsaImpl.qll | 40 +++- .../dataflow/internal/DataFlowPrivate.qll | 195 +++++++++--------- .../dataflow/internal/DataFlowPublic.qll | 4 +- .../code/csharp/dataflow/internal/SsaImpl.qll | 111 +++++++++- .../csharp7/LocalTaintFlow.expected | 9 +- .../dataflow/local/DataFlowStep.expected | 130 ++++++------ .../dataflow/local/TaintTrackingStep.expected | 130 ++++++------ 7 files changed, 373 insertions(+), 246 deletions(-) diff --git a/csharp/ql/lib/semmle/code/cil/internal/SsaImpl.qll b/csharp/ql/lib/semmle/code/cil/internal/SsaImpl.qll index 683ee6268aa..2f8fde205fd 100644 --- a/csharp/ql/lib/semmle/code/cil/internal/SsaImpl.qll +++ b/csharp/ql/lib/semmle/code/cil/internal/SsaImpl.qll @@ -47,19 +47,19 @@ private module Cached { } cached - ReadAccess getAFirstRead(Definition def) { + ReadAccess getAFirstReadExt(DefinitionExt def) { exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 | - def.definesAt(_, bb1, i1) and - adjacentDefRead(def, bb1, i1, bb2, i2) and + def.definesAt(_, bb1, i1, _) and + adjacentDefReadExt(def, _, bb1, i1, bb2, i2) and result = bb2.getNode(i2) ) } cached - predicate hasAdjacentReads(Definition def, ReadAccess first, ReadAccess second) { + predicate hasAdjacentReadsExt(DefinitionExt def, ReadAccess first, ReadAccess second) { exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 | first = bb1.getNode(i1) and - adjacentDefRead(def, bb1, i1, bb2, i2) and + adjacentDefReadExt(def, _, bb1, i1, bb2, i2) and second = bb2.getNode(i2) ) } @@ -68,9 +68,35 @@ private module Cached { Definition getAPhiInput(PhiNode phi) { phiHasInputFromBlock(phi, result, _) } cached - predicate lastRefBeforeRedef(Definition def, BasicBlock bb, int i, Definition next) { - lastRefRedef(def, bb, i, next) + predicate lastRefBeforeRedefExt(DefinitionExt def, BasicBlock bb, int i, DefinitionExt next) { + lastRefRedefExt(def, _, bb, i, next) } } import Cached + +private module Deprecated { + private import CIL + + deprecated ReadAccess getAFirstRead(Definition def) { + exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 | + def.definesAt(_, bb1, i1) and + adjacentDefRead(def, bb1, i1, bb2, i2) and + result = bb2.getNode(i2) + ) + } + + deprecated predicate hasAdjacentReads(Definition def, ReadAccess first, ReadAccess second) { + exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 | + first = bb1.getNode(i1) and + adjacentDefRead(def, bb1, i1, bb2, i2) and + second = bb2.getNode(i2) + ) + } + + deprecated predicate lastRefBeforeRedef(Definition def, BasicBlock bb, int i, Definition next) { + lastRefRedef(def, bb, i, next) + } +} + +import Deprecated diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index 4fc2cb4f398..845d5bd378a 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -18,6 +18,7 @@ private import semmle.code.csharp.frameworks.NHibernate private import semmle.code.csharp.frameworks.system.Collections private import semmle.code.csharp.frameworks.system.threading.Tasks private import semmle.code.cil.Ssa::Ssa as CilSsa +private import semmle.code.cil.internal.SsaImpl as CilSsaImpl /** Gets the callable in which this node occurs. */ DataFlowCallable nodeGetEnclosingCallable(NodeImpl n) { result = n.getEnclosingCallableImpl() } @@ -174,7 +175,7 @@ predicate hasNodePath(ControlFlowReachabilityConfiguration conf, ExprNode n1, No cfn = n1.getControlFlowNode() and ssaDef.getADefinition() = def and ssaDef.getControlFlowNode() = cfnDef and - n2.(SsaDefinitionNode).getDefinition() = ssaDef + n2.(SsaDefinitionExtNode).getDefinitionExt() = ssaDef ) } @@ -306,17 +307,28 @@ module LocalFlow { } } + /** An SSA definition into which another SSA definition may flow. */ + private class SsaInputDefinitionExtNode extends SsaDefinitionExtNode { + SsaInputDefinitionExtNode() { + def instanceof Ssa::PhiNode + or + def instanceof SsaImpl::PhiReadNode + or + def instanceof LocalFlow::UncertainExplicitSsaDefinition + } + } + /** * Holds if `nodeFrom` is a last node referencing SSA definition `def`, which * can reach `next`. */ private predicate localFlowSsaInputFromDef( - Node nodeFrom, Ssa::Definition def, Ssa::Definition next + Node nodeFrom, SsaImpl::DefinitionExt def, SsaInputDefinitionExtNode next ) { exists(ControlFlow::BasicBlock bb, int i | - SsaImpl::lastRefBeforeRedef(def, bb, i, next) and - def.definesAt(_, bb, i) and - def = getSsaDefinition(nodeFrom) + SsaImpl::lastRefBeforeRedefExt(def, bb, i, next.getDefinitionExt()) and + def.definesAt(_, bb, i, _) and + def = getSsaDefinitionExt(nodeFrom) ) } @@ -324,18 +336,17 @@ module LocalFlow { * Holds if `read` is a last node reading SSA definition `def`, which * can reach `next`. */ - predicate localFlowSsaInputFromExpr( - ControlFlow::Node read, Ssa::Definition def, Ssa::Definition next + predicate localFlowSsaInputFromRead( + Node read, SsaImpl::DefinitionExt def, SsaInputDefinitionExtNode next ) { exists(ControlFlow::BasicBlock bb, int i | - SsaImpl::lastRefBeforeRedef(def, bb, i, next) and - read = bb.getNode(i) and - read.getElement() instanceof AssignableRead + SsaImpl::lastRefBeforeRedefExt(def, bb, i, next.getDefinitionExt()) and + read.asExprAtNode(bb.getNode(i)) instanceof AssignableRead ) } - private Ssa::Definition getSsaDefinition(Node n) { - result = n.(SsaDefinitionNode).getDefinition() + private SsaImpl::DefinitionExt getSsaDefinitionExt(Node n) { + result = n.(SsaDefinitionExtNode).getDefinitionExt() or result = n.(ExplicitParameterNode).getSsaDefinition() } @@ -344,9 +355,9 @@ module LocalFlow { * Holds if there is a local use-use flow step from `nodeFrom` to `nodeTo` * involving SSA definition `def`. */ - predicate localSsaFlowStepUseUse(Ssa::Definition def, Node nodeFrom, Node nodeTo) { + predicate localSsaFlowStepUseUse(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) { exists(ControlFlow::Node cfnFrom, ControlFlow::Node cfnTo | - SsaImpl::adjacentReadPairSameVar(def, cfnFrom, cfnTo) and + SsaImpl::adjacentReadPairSameVarExt(def, cfnFrom, cfnTo) and nodeTo = TExprNode(cfnTo) and nodeFrom = TExprNode(cfnFrom) ) @@ -356,31 +367,22 @@ module LocalFlow { * Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving * SSA definition `def`. */ - predicate localSsaFlowStep(Ssa::Definition def, Node nodeFrom, Node nodeTo) { + predicate localSsaFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) { // Flow from SSA definition/parameter to first read - exists(ControlFlow::Node cfn | - def = getSsaDefinition(nodeFrom) and - nodeTo.asExprAtNode(cfn) = def.getAFirstReadAtNode(cfn) - ) + def = getSsaDefinitionExt(nodeFrom) and + SsaImpl::firstReadSameVarExt(def, nodeTo.(ExprNode).getControlFlowNode()) or // Flow from read to next read localSsaFlowStepUseUse(def, nodeFrom.(PostUpdateNode).getPreUpdateNode(), nodeTo) or - // Flow into phi/uncertain SSA definition node from def - exists(Ssa::Definition next | - localFlowSsaInputFromDef(nodeFrom, def, next) and - next = nodeTo.(SsaDefinitionNode).getDefinition() - | - def = next.(Ssa::PhiNode).getAnInput() - or - def = next.(LocalFlow::UncertainExplicitSsaDefinition).getPriorDefinition() - ) + // Flow into phi (read)/uncertain SSA definition node from def + localFlowSsaInputFromDef(nodeFrom, def, nodeTo) } /** * Holds if the source variable of SSA definition `def` is an instance field. */ - predicate usesInstanceField(Ssa::Definition def) { + predicate usesInstanceField(SsaImpl::DefinitionExt def) { exists(Ssa::SourceVariables::FieldOrPropSourceVariable fp | fp = def.getSourceVariable() | not fp.getAssignable().(Modifiable).isStatic() ) @@ -389,25 +391,23 @@ module LocalFlow { predicate localFlowCapturedVarStep(Node nodeFrom, ImplicitCapturedArgumentNode nodeTo) { // Flow from SSA definition to implicit captured variable argument exists(Ssa::ExplicitDefinition def, ControlFlow::Nodes::ElementNode call | - def = getSsaDefinition(nodeFrom) and + def = getSsaDefinitionExt(nodeFrom) and def.isCapturedVariableDefinitionFlowIn(_, call, _) and nodeTo = TImplicitCapturedArgumentNode(call, def.getSourceVariable().getAssignable()) ) } private module CilFlow { - private import semmle.code.cil.internal.SsaImpl as CilSsaImpl - /** * Holds if `nodeFrom` is a last node referencing SSA definition `def`, which * can reach `next`. */ private predicate localFlowCilSsaInput( - Node nodeFrom, CilSsa::Definition def, CilSsa::Definition next + Node nodeFrom, CilSsaImpl::DefinitionExt def, CilSsaImpl::DefinitionExt next ) { - exists(CIL::BasicBlock bb, int i | CilSsaImpl::lastRefBeforeRedef(def, bb, i, next) | - def.definesAt(_, bb, i) and - def = nodeFrom.(CilSsaDefinitionNode).getDefinition() + exists(CIL::BasicBlock bb, int i | CilSsaImpl::lastRefBeforeRedefExt(def, bb, i, next) | + def.definesAt(_, bb, i, _) and + def = nodeFrom.(CilSsaDefinitionExtNode).getDefinition() or nodeFrom = TCilExprNode(bb.getNode(i).(CIL::ReadAccess)) ) @@ -417,30 +417,33 @@ module LocalFlow { * Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving * CIL SSA definition `def`. */ - private predicate localCilSsaFlowStep(CilSsa::Definition def, Node nodeFrom, Node nodeTo) { + private predicate localCilSsaFlowStep(CilSsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) { // Flow into SSA definition exists(CIL::VariableUpdate vu | - vu = def.getVariableUpdate() and + vu = def.(CilSsa::Definition).getVariableUpdate() and vu.getSource() = asCilDataFlowNode(nodeFrom) and - def = nodeTo.(CilSsaDefinitionNode).getDefinition() + def = nodeTo.(CilSsaDefinitionExtNode).getDefinition() ) or // Flow from SSA definition to first read - def = nodeFrom.(CilSsaDefinitionNode).getDefinition() and - nodeTo = TCilExprNode(CilSsaImpl::getAFirstRead(def)) + def = nodeFrom.(CilSsaDefinitionExtNode).getDefinition() and + nodeTo = TCilExprNode(CilSsaImpl::getAFirstReadExt(def)) or // Flow from read to next read exists(CIL::ReadAccess readFrom, CIL::ReadAccess readTo | - CilSsaImpl::hasAdjacentReads(def, readFrom, readTo) and + CilSsaImpl::hasAdjacentReadsExt(def, readFrom, readTo) and nodeTo = TCilExprNode(readTo) and nodeFrom = TCilExprNode(readFrom) ) or - // Flow into phi node - exists(CilSsa::PhiNode phi | + // Flow into phi (read) node + exists(CilSsaImpl::DefinitionExt phi | localFlowCilSsaInput(nodeFrom, def, phi) and - phi = nodeTo.(CilSsaDefinitionNode).getDefinition() and - def = CilSsaImpl::getAPhiInput(phi) + phi = nodeTo.(CilSsaDefinitionExtNode).getDefinition() + | + phi instanceof CilSsa::PhiNode + or + phi instanceof CilSsaImpl::PhiReadNode ) } @@ -466,7 +469,7 @@ module LocalFlow { } predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) { - exists(Ssa::Definition def | + exists(SsaImpl::DefinitionExt def | localSsaFlowStep(def, nodeFrom, nodeTo) and not usesInstanceField(def) ) @@ -528,26 +531,20 @@ module LocalFlow { predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) { LocalFlow::localFlowStepCommon(nodeFrom, nodeTo) or - exists(Ssa::Definition def | + exists(SsaImpl::DefinitionExt def | LocalFlow::localSsaFlowStepUseUse(def, nodeFrom, nodeTo) and not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom, _) and not LocalFlow::usesInstanceField(def) ) or - // Flow into phi/uncertain SSA definition node from read - exists(Ssa::Definition def, ControlFlow::Node read, Ssa::Definition next | - LocalFlow::localFlowSsaInputFromExpr(read, def, next) and - next = nodeTo.(SsaDefinitionNode).getDefinition() and - def = - [ - next.(Ssa::PhiNode).getAnInput(), - next.(LocalFlow::UncertainExplicitSsaDefinition).getPriorDefinition() - ] + // Flow into phi (read)/uncertain SSA definition node from read + exists(SsaImpl::DefinitionExt def, Node read | + LocalFlow::localFlowSsaInputFromRead(read, def, nodeTo) | - exists(nodeFrom.asExprAtNode(read)) and + nodeFrom = read and not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom, _) or - exists(nodeFrom.(PostUpdateNode).getPreUpdateNode().asExprAtNode(read)) + nodeFrom.(PostUpdateNode).getPreUpdateNode() = read ) or LocalFlow::localFlowCapturedVarStep(nodeFrom, nodeTo) @@ -813,8 +810,8 @@ private module Cached { cfn.getElement() instanceof Expr } or TCilExprNode(CIL::Expr e) { e.getImplementation() instanceof CIL::BestImplementation } or - TCilSsaDefinitionNode(CilSsa::Definition def) or - TSsaDefinitionNode(Ssa::Definition def) { + TCilSsaDefinitionExtNode(CilSsaImpl::DefinitionExt def) or + TSsaDefinitionExtNode(SsaImpl::DefinitionExt def) { // Handled by `TExplicitParameterNode` below not def.(Ssa::ExplicitDefinition).getADefinition() instanceof AssignableDefinitions::ImplicitParameterDefinition @@ -880,24 +877,18 @@ private module Cached { or LocalFlow::localSsaFlowStepUseUse(_, nodeFrom, nodeTo) or - exists(Ssa::Definition def | + exists(SsaImpl::DefinitionExt def | LocalFlow::localSsaFlowStep(def, nodeFrom, nodeTo) and LocalFlow::usesInstanceField(def) ) or - // Flow into phi/uncertain SSA definition node from read - exists(Ssa::Definition def, ControlFlow::Node read, Ssa::Definition next | - LocalFlow::localFlowSsaInputFromExpr(read, def, next) and - next = nodeTo.(SsaDefinitionNode).getDefinition() and - def = - [ - next.(Ssa::PhiNode).getAnInput(), - next.(LocalFlow::UncertainExplicitSsaDefinition).getPriorDefinition() - ] + // Flow into phi (read)/uncertain SSA definition node from read + exists(SsaImpl::DefinitionExt def, Node read | + LocalFlow::localFlowSsaInputFromRead(read, def, nodeTo) | - exists(nodeFrom.asExprAtNode(read)) + nodeFrom = read or - exists(nodeFrom.(PostUpdateNode).getPreUpdateNode().asExprAtNode(read)) + nodeFrom.(PostUpdateNode).getPreUpdateNode() = read ) or // Simple flow through library code is included in the exposed local @@ -945,9 +936,11 @@ import Cached /** Holds if `n` should be hidden from path explanations. */ predicate nodeIsHidden(Node n) { - exists(Ssa::Definition def | def = n.(SsaDefinitionNode).getDefinition() | + exists(SsaImpl::DefinitionExt def | def = n.(SsaDefinitionExtNode).getDefinitionExt() | def instanceof Ssa::PhiNode or + def instanceof SsaImpl::PhiReadNode + or def instanceof Ssa::ImplicitEntryDefinition or def instanceof Ssa::ImplicitCallDefinition @@ -978,13 +971,13 @@ predicate nodeIsHidden(Node n) { } /** A CIL SSA definition, viewed as a node in a data flow graph. */ -class CilSsaDefinitionNode extends NodeImpl, TCilSsaDefinitionNode { - CilSsa::Definition def; +class CilSsaDefinitionExtNode extends NodeImpl, TCilSsaDefinitionExtNode { + CilSsaImpl::DefinitionExt def; - CilSsaDefinitionNode() { this = TCilSsaDefinitionNode(def) } + CilSsaDefinitionExtNode() { this = TCilSsaDefinitionExtNode(def) } /** Gets the underlying SSA definition. */ - CilSsa::Definition getDefinition() { result = def } + CilSsaImpl::DefinitionExt getDefinition() { result = def } override DataFlowCallable getEnclosingCallableImpl() { result.asCallable() = def.getBasicBlock().getFirstNode().getImplementation().getMethod() @@ -1000,13 +993,13 @@ class CilSsaDefinitionNode extends NodeImpl, TCilSsaDefinitionNode { } /** An SSA definition, viewed as a node in a data flow graph. */ -class SsaDefinitionNode extends NodeImpl, TSsaDefinitionNode { - Ssa::Definition def; +class SsaDefinitionExtNode extends NodeImpl, TSsaDefinitionExtNode { + SsaImpl::DefinitionExt def; - SsaDefinitionNode() { this = TSsaDefinitionNode(def) } + SsaDefinitionExtNode() { this = TSsaDefinitionExtNode(def) } /** Gets the underlying SSA definition. */ - Ssa::Definition getDefinition() { result = def } + SsaImpl::DefinitionExt getDefinitionExt() { result = def } override DataFlowCallable getEnclosingCallableImpl() { result.asCallable() = def.getEnclosingCallable() @@ -1014,7 +1007,9 @@ class SsaDefinitionNode extends NodeImpl, TSsaDefinitionNode { override Type getTypeImpl() { result = def.getSourceVariable().getType() } - override ControlFlow::Node getControlFlowNodeImpl() { result = def.getControlFlowNode() } + override ControlFlow::Node getControlFlowNodeImpl() { + result = def.(Ssa::Definition).getControlFlowNode() + } override Location getLocationImpl() { result = def.getLocation() } @@ -1108,13 +1103,11 @@ private module ParameterNodes { * } } * ``` */ - class ImplicitCapturedParameterNode extends ParameterNodeImpl, SsaDefinitionNode { - override SsaCapturedEntryDefinition def; - - ImplicitCapturedParameterNode() { def = this.getDefinition() } + class ImplicitCapturedParameterNode extends ParameterNodeImpl, SsaDefinitionExtNode { + ImplicitCapturedParameterNode() { def instanceof SsaCapturedEntryDefinition } /** Gets the captured variable that this implicit parameter models. */ - LocalScopeVariable getVariable() { result = def.getVariable() } + LocalScopeVariable getVariable() { result = def.(SsaCapturedEntryDefinition).getVariable() } override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { pos.isImplicitCapturedParameterPosition(def.getSourceVariable().getAssignable()) and @@ -1349,12 +1342,12 @@ private module ReturnNodes { * A data-flow node that represents an assignment to an `out` or a `ref` * parameter. */ - class OutRefReturnNode extends ReturnNode, SsaDefinitionNode { + class OutRefReturnNode extends ReturnNode, SsaDefinitionExtNode { OutRefReturnKind kind; OutRefReturnNode() { exists(Parameter p | - this.getDefinition().isLiveOutRefParameterDefinition(p) and + this.getDefinitionExt().(Ssa::Definition).isLiveOutRefParameterDefinition(p) and kind.getPosition() = p.getPosition() | p.isOut() and kind instanceof OutReturnKind @@ -1438,11 +1431,11 @@ private module ReturnNodes { * } } * ``` */ - class ImplicitCapturedReturnNode extends ReturnNode, SsaDefinitionNode { + class ImplicitCapturedReturnNode extends ReturnNode, SsaDefinitionExtNode { private Ssa::ExplicitDefinition edef; ImplicitCapturedReturnNode() { - edef = this.getDefinition() and + edef = this.getDefinitionExt() and edef.isCapturedVariableDefinitionFlowOut(_, _) } @@ -1450,8 +1443,8 @@ private module ReturnNodes { * Holds if the value at this node may flow out to the implicit call definition * at `node`, using one or more calls. */ - predicate flowsOutTo(SsaDefinitionNode node, boolean additionalCalls) { - edef.isCapturedVariableDefinitionFlowOut(node.getDefinition(), additionalCalls) + predicate flowsOutTo(SsaDefinitionExtNode node, boolean additionalCalls) { + edef.isCapturedVariableDefinitionFlowOut(node.getDefinitionExt(), additionalCalls) } override ImplicitCapturedReturnKind getKind() { @@ -1558,13 +1551,13 @@ private module OutNodes { * A data-flow node that reads a value returned implicitly by a callable * using a captured variable. */ - class CapturedOutNode extends OutNode, SsaDefinitionNode { + class CapturedOutNode extends OutNode, SsaDefinitionExtNode { private DataFlowCall call; CapturedOutNode() { exists(ImplicitCapturedReturnNode n, boolean additionalCalls, ControlFlow::Node cfn | n.flowsOutTo(this, additionalCalls) and - cfn = this.getDefinition().getControlFlowNode() + cfn = this.getDefinitionExt().(Ssa::Definition).getControlFlowNode() | additionalCalls = false and call = csharpCall(_, cfn) or @@ -1576,7 +1569,7 @@ private module OutNodes { override DataFlowCall getCall(ReturnKind kind) { result = call and kind.(ImplicitCapturedReturnKind).getVariable() = - this.getDefinition().getSourceVariable().getAssignable() + this.getDefinitionExt().getSourceVariable().getAssignable() } } @@ -1857,7 +1850,7 @@ predicate readStep(Node node1, Content c, Node node2) { exists(ForeachStmt fs, Ssa::ExplicitDefinition def | x.hasDefPath(fs.getIterableExpr(), node1.getControlFlowNode(), def.getADefinition(), def.getControlFlowNode()) and - node2.(SsaDefinitionNode).getDefinition() = def and + node2.(SsaDefinitionExtNode).getDefinitionExt() = def and c instanceof ElementContent ) or @@ -1880,7 +1873,7 @@ predicate readStep(Node node1, Content c, Node node2) { or // item = variable in node1 = (..., variable, ...) exists(AssignableDefinitions::TupleAssignmentDefinition tad, Ssa::ExplicitDefinition def | - node2.(SsaDefinitionNode).getDefinition() = def and + node2.(SsaDefinitionExtNode).getDefinitionExt() = def and def.getADefinition() = tad and tad.getLeaf() = item and hasNodePath(x, node1, node2) @@ -1889,7 +1882,7 @@ predicate readStep(Node node1, Content c, Node node2) { // item = variable in node1 = (..., variable, ...) in a case/is var (..., ...) te = any(PatternExpr pe).getAChildExpr*() and exists(AssignableDefinitions::LocalVariableDefinition lvd, Ssa::ExplicitDefinition def | - node2.(SsaDefinitionNode).getDefinition() = def and + node2.(SsaDefinitionExtNode).getDefinitionExt() = def and def.getADefinition() = lvd and lvd.getDeclaration() = item and hasNodePath(x, node1, node2) @@ -2223,7 +2216,7 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { /** Extra data-flow steps needed for lambda flow analysis. */ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { - exists(Ssa::Definition def | + exists(SsaImpl::DefinitionExt def | LocalFlow::localSsaFlowStep(def, nodeFrom, nodeTo) and LocalFlow::usesInstanceField(def) and preservesValue = true diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll index f6520147e19..b22712087f2 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll @@ -119,10 +119,10 @@ class ParameterNode extends Node instanceof ParameterNodeImpl { } /** A definition, viewed as a node in a data flow graph. */ -class AssignableDefinitionNode extends Node, TSsaDefinitionNode { +class AssignableDefinitionNode extends Node, TSsaDefinitionExtNode { private Ssa::ExplicitDefinition edef; - AssignableDefinitionNode() { this = TSsaDefinitionNode(edef) } + AssignableDefinitionNode() { this = TSsaDefinitionExtNode(edef) } /** Gets the underlying definition. */ AssignableDefinition getDefinition() { result = this.getDefinitionAtNode(_) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll index 98a1cad843a..80d3dbd28ab 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll @@ -1093,35 +1093,79 @@ private predicate adjacentDefRead( } private predicate adjacentDefReachesRead( - Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2 + Definition def, SsaInput::SourceVariable v, SsaInput::BasicBlock bb1, int i1, + SsaInput::BasicBlock bb2, int i2 ) { - exists(SsaInput::SourceVariable v | adjacentDefRead(def, bb1, i1, bb2, i2, v) | + adjacentDefRead(def, bb1, i1, bb2, i2, v) and + ( def.definesAt(v, bb1, i1) or SsaInput::variableRead(bb1, i1, v, true) ) or exists(SsaInput::BasicBlock bb3, int i3 | - adjacentDefReachesRead(def, bb1, i1, bb3, i3) and + adjacentDefReachesRead(def, v, bb1, i1, bb3, i3) and SsaInput::variableRead(bb3, i3, _, false) and Impl::adjacentDefRead(def, bb3, i3, bb2, i2) ) } +private predicate adjacentDefReachesReadExt( + DefinitionExt def, SsaInput::SourceVariable v, SsaInput::BasicBlock bb1, int i1, + SsaInput::BasicBlock bb2, int i2 +) { + Impl::adjacentDefReadExt(def, v, bb1, i1, bb2, i2) and + ( + def.definesAt(v, bb1, i1, _) + or + SsaInput::variableRead(bb1, i1, v, true) + ) + or + exists(SsaInput::BasicBlock bb3, int i3 | + adjacentDefReachesReadExt(def, v, bb1, i1, bb3, i3) and + SsaInput::variableRead(bb3, i3, v, false) and + Impl::adjacentDefReadExt(def, v, bb3, i3, bb2, i2) + ) +} + /** Same as `adjacentDefRead`, but skips uncertain reads. */ pragma[nomagic] private predicate adjacentDefSkipUncertainReads( Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2 ) { - adjacentDefReachesRead(def, bb1, i1, bb2, i2) and - SsaInput::variableRead(bb2, i2, _, true) + exists(SsaInput::SourceVariable v | + adjacentDefReachesRead(def, v, bb1, i1, bb2, i2) and + SsaInput::variableRead(bb2, i2, v, true) + ) +} + +/** Same as `adjacentDefReadExt`, but skips uncertain reads. */ +pragma[nomagic] +private predicate adjacentDefSkipUncertainReadsExt( + DefinitionExt def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2 +) { + exists(SsaInput::SourceVariable v | + adjacentDefReachesReadExt(def, v, bb1, i1, bb2, i2) and + SsaInput::variableRead(bb2, i2, v, true) + ) } private predicate adjacentDefReachesUncertainRead( Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2 ) { - adjacentDefReachesRead(def, bb1, i1, bb2, i2) and - SsaInput::variableRead(bb2, i2, _, false) + exists(SsaInput::SourceVariable v | + adjacentDefReachesRead(def, v, bb1, i1, bb2, i2) and + SsaInput::variableRead(bb2, i2, v, false) + ) +} + +private predicate adjacentDefReachesUncertainReadExt( + DefinitionExt def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2 +) { + exists(SsaInput::SourceVariable v | + adjacentDefReachesReadExt(def, v, bb1, i1, bb2, i2) and + SsaInput::variableRead(bb2, i2, v, false) + ) } /** Same as `lastRefRedef`, but skips uncertain reads. */ @@ -1311,6 +1355,19 @@ private module Cached { ) } + /** + * Holds if the value defined at SSA definition `def` can reach a read at `cfn`, + * without passing through any other read. + */ + cached + predicate firstReadSameVarExt(DefinitionExt def, ControlFlow::Node cfn) { + exists(ControlFlow::BasicBlock bb1, int i1, ControlFlow::BasicBlock bb2, int i2 | + def.definesAt(_, bb1, i1, _) and + adjacentDefSkipUncertainReadsExt(def, bb1, i1, bb2, i2) and + cfn = bb2.getNode(i2) + ) + } + /** * Holds if the read at `cfn2` is a read of the same SSA definition `def` * as the read at `cfn1`, and `cfn2` can be reached from `cfn1` without @@ -1326,7 +1383,23 @@ private module Cached { ) } - /** Same as `lastRefRedef`, but skips uncertain reads. */ + /** + * Holds if the read at `cfn2` is a read of the same SSA definition `def` + * as the read at `cfn1`, and `cfn2` can be reached from `cfn1` without + * passing through another read. + */ + cached + predicate adjacentReadPairSameVarExt( + DefinitionExt def, ControlFlow::Node cfn1, ControlFlow::Node cfn2 + ) { + exists(ControlFlow::BasicBlock bb1, int i1, ControlFlow::BasicBlock bb2, int i2 | + cfn1 = bb1.getNode(i1) and + variableReadActual(bb1, i1, _) and + adjacentDefSkipUncertainReadsExt(def, bb1, i1, bb2, i2) and + cfn2 = bb2.getNode(i2) + ) + } + cached predicate lastRefBeforeRedef(Definition def, ControlFlow::BasicBlock bb, int i, Definition next) { Impl::lastRefRedef(def, bb, i, next) and @@ -1338,6 +1411,21 @@ private module Cached { ) } + cached + predicate lastRefBeforeRedefExt( + DefinitionExt def, ControlFlow::BasicBlock bb, int i, DefinitionExt next + ) { + exists(SsaInput::SourceVariable v | + Impl::lastRefRedefExt(def, v, bb, i, next) and + not SsaInput::variableRead(bb, i, v, false) + ) + or + exists(SsaInput::BasicBlock bb0, int i0 | + Impl::lastRefRedefExt(def, _, bb0, i0, next) and + adjacentDefReachesUncertainReadExt(def, bb, i, bb0, i0) + ) + } + cached predicate lastReadSameVar(Definition def, ControlFlow::Node cfn) { exists(ControlFlow::BasicBlock bb, int i | @@ -1399,6 +1487,9 @@ class DefinitionExt extends Impl::DefinitionExt { /** Gets the location of this definition. */ Location getLocation() { result = this.(Ssa::Definition).getLocation() } + + /** Gets the enclosing callable of this definition. */ + Callable getEnclosingCallable() { result = this.(Ssa::Definition).getEnclosingCallable() } } /** @@ -1412,4 +1503,8 @@ class PhiReadNode extends DefinitionExt, Impl::PhiReadNode { } override Location getLocation() { result = this.getBasicBlock().getLocation() } + + override Callable getEnclosingCallable() { + result = this.getSourceVariable().getEnclosingCallable() + } } diff --git a/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected b/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected index d5302764f5c..af72c3e5e38 100644 --- a/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected +++ b/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected @@ -160,7 +160,7 @@ | CSharp7.cs:232:20:232:23 | null | CSharp7.cs:232:16:232:23 | SSA def(o) | | CSharp7.cs:233:13:233:13 | access to local variable o | CSharp7.cs:233:18:233:23 | SSA def(i1) | | CSharp7.cs:233:13:233:13 | access to local variable o | CSharp7.cs:237:18:237:18 | access to local variable o | -| CSharp7.cs:233:13:233:13 | access to local variable o | CSharp7.cs:248:17:248:17 | access to local variable o | +| CSharp7.cs:233:13:233:13 | access to local variable o | CSharp7.cs:248:9:274:9 | SSA phi read(o) | | CSharp7.cs:233:13:233:23 | [false] ... is ... | CSharp7.cs:233:13:233:33 | [false] ... && ... | | CSharp7.cs:233:13:233:23 | [true] ... is ... | CSharp7.cs:233:13:233:33 | [false] ... && ... | | CSharp7.cs:233:13:233:23 | [true] ... is ... | CSharp7.cs:233:13:233:33 | [true] ... && ... | @@ -173,13 +173,14 @@ | CSharp7.cs:235:38:235:39 | access to local variable i1 | CSharp7.cs:235:31:235:41 | $"..." | | CSharp7.cs:237:18:237:18 | access to local variable o | CSharp7.cs:237:23:237:31 | SSA def(s1) | | CSharp7.cs:237:18:237:18 | access to local variable o | CSharp7.cs:241:18:241:18 | access to local variable o | -| CSharp7.cs:237:18:237:18 | access to local variable o | CSharp7.cs:248:17:248:17 | access to local variable o | +| CSharp7.cs:237:18:237:18 | access to local variable o | CSharp7.cs:248:9:274:9 | SSA phi read(o) | | CSharp7.cs:237:23:237:31 | SSA def(s1) | CSharp7.cs:239:41:239:42 | access to local variable s1 | | CSharp7.cs:239:33:239:39 | "string " | CSharp7.cs:239:31:239:44 | $"..." | | CSharp7.cs:239:41:239:42 | access to local variable s1 | CSharp7.cs:239:31:239:44 | $"..." | | CSharp7.cs:241:18:241:18 | access to local variable o | CSharp7.cs:244:18:244:18 | access to local variable o | -| CSharp7.cs:241:18:241:18 | access to local variable o | CSharp7.cs:248:17:248:17 | access to local variable o | -| CSharp7.cs:244:18:244:18 | access to local variable o | CSharp7.cs:248:17:248:17 | access to local variable o | +| CSharp7.cs:241:18:241:18 | access to local variable o | CSharp7.cs:248:9:274:9 | SSA phi read(o) | +| CSharp7.cs:244:18:244:18 | access to local variable o | CSharp7.cs:248:9:274:9 | SSA phi read(o) | +| CSharp7.cs:248:9:274:9 | SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o | | CSharp7.cs:248:17:248:17 | access to local variable o | CSharp7.cs:254:27:254:27 | access to local variable o | | CSharp7.cs:248:17:248:17 | access to local variable o | CSharp7.cs:257:18:257:23 | SSA def(i2) | | CSharp7.cs:248:17:248:17 | access to local variable o | CSharp7.cs:260:18:260:23 | SSA def(i3) | diff --git a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 92d2013bfbe..ad28e92e626 100644 --- a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -373,8 +373,8 @@ | LocalDataFlow.cs:278:15:278:22 | access to local variable nonSink0 | LocalDataFlow.cs:285:31:285:38 | access to local variable nonSink0 | | LocalDataFlow.cs:281:13:281:34 | SSA def(sink70) | LocalDataFlow.cs:282:15:282:20 | access to local variable sink70 | | LocalDataFlow.cs:281:22:281:34 | ... = ... | LocalDataFlow.cs:281:13:281:34 | SSA def(sink70) | +| LocalDataFlow.cs:281:22:281:34 | SSA def(sink0) | LocalDataFlow.cs:313:22:313:38 | SSA phi read(sink0) | | LocalDataFlow.cs:281:22:281:34 | SSA def(sink0) | LocalDataFlow.cs:313:34:313:38 | access to local variable sink0 | -| LocalDataFlow.cs:281:22:281:34 | SSA def(sink0) | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | | LocalDataFlow.cs:281:30:281:34 | access to local variable sink0 | LocalDataFlow.cs:281:22:281:34 | ... = ... | | LocalDataFlow.cs:281:30:281:34 | access to local variable sink0 | LocalDataFlow.cs:281:22:281:34 | SSA def(sink0) | | LocalDataFlow.cs:282:15:282:20 | [post] access to local variable sink70 | LocalDataFlow.cs:289:13:289:18 | access to local variable sink70 | @@ -399,8 +399,9 @@ | LocalDataFlow.cs:313:22:313:29 | access to local variable nonSink0 | LocalDataFlow.cs:313:22:313:38 | ... ?? ... | | LocalDataFlow.cs:313:22:313:29 | access to local variable nonSink0 | LocalDataFlow.cs:314:31:314:38 | access to local variable nonSink0 | | LocalDataFlow.cs:313:22:313:38 | ... ?? ... | LocalDataFlow.cs:313:13:313:38 | SSA def(sink73) | +| LocalDataFlow.cs:313:22:313:38 | SSA phi read(sink0) | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | | LocalDataFlow.cs:313:34:313:38 | access to local variable sink0 | LocalDataFlow.cs:313:22:313:38 | ... ?? ... | -| LocalDataFlow.cs:313:34:313:38 | access to local variable sink0 | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | +| LocalDataFlow.cs:313:34:313:38 | access to local variable sink0 | LocalDataFlow.cs:313:22:313:38 | SSA phi read(sink0) | | LocalDataFlow.cs:314:13:314:38 | SSA def(sink74) | LocalDataFlow.cs:316:15:316:20 | access to local variable sink74 | | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | LocalDataFlow.cs:314:22:314:38 | ... ?? ... | | LocalDataFlow.cs:314:22:314:38 | ... ?? ... | LocalDataFlow.cs:314:13:314:38 | SSA def(sink74) | @@ -441,28 +442,22 @@ | SSA.cs:13:15:13:22 | [post] access to local variable nonSink0 | SSA.cs:19:13:19:20 | access to local variable nonSink0 | | SSA.cs:13:15:13:22 | access to local variable nonSink0 | SSA.cs:19:13:19:20 | access to local variable nonSink0 | | SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:24:24:24:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | +| SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | | SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:24:24:24:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | +| SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | | SSA.cs:19:13:19:20 | [post] access to local variable nonSink0 | SSA.cs:30:24:30:31 | access to local variable nonSink0 | -| SSA.cs:19:13:19:20 | [post] access to local variable nonSink0 | SSA.cs:49:24:49:31 | access to local variable nonSink0 | -| SSA.cs:19:13:19:20 | [post] access to local variable nonSink0 | SSA.cs:63:23:63:30 | access to local variable nonSink0 | +| SSA.cs:19:13:19:20 | [post] access to local variable nonSink0 | SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | | SSA.cs:19:13:19:20 | access to local variable nonSink0 | SSA.cs:30:24:30:31 | access to local variable nonSink0 | -| SSA.cs:19:13:19:20 | access to local variable nonSink0 | SSA.cs:49:24:49:31 | access to local variable nonSink0 | -| SSA.cs:19:13:19:20 | access to local variable nonSink0 | SSA.cs:63:23:63:30 | access to local variable nonSink0 | +| SSA.cs:19:13:19:20 | access to local variable nonSink0 | SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | | SSA.cs:22:16:22:28 | SSA def(ssaSink1) | SSA.cs:25:9:25:24 | SSA phi(ssaSink1) | | SSA.cs:22:27:22:28 | "" | SSA.cs:22:16:22:28 | SSA def(ssaSink1) | | SSA.cs:23:13:23:22 | [post] access to parameter nonTainted | SSA.cs:29:13:29:22 | access to parameter nonTainted | | SSA.cs:23:13:23:22 | access to parameter nonTainted | SSA.cs:29:13:29:22 | access to parameter nonTainted | | SSA.cs:24:13:24:31 | SSA def(ssaSink1) | SSA.cs:25:9:25:24 | SSA phi(ssaSink1) | | SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:24:13:24:31 | SSA def(ssaSink1) | -| SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | -| SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | -| SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | +| SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | +| SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | +| SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | SSA.cs:43:9:43:24 | SSA phi read(ssaSink0) | | SSA.cs:25:9:25:24 | SSA phi(ssaSink1) | SSA.cs:25:15:25:22 | access to local variable ssaSink1 | | SSA.cs:28:16:28:28 | SSA def(nonSink1) | SSA.cs:31:9:31:24 | SSA phi(nonSink1) | | SSA.cs:28:27:28:28 | "" | SSA.cs:28:16:28:28 | SSA def(nonSink1) | @@ -470,43 +465,48 @@ | SSA.cs:29:13:29:22 | access to parameter nonTainted | SSA.cs:35:13:35:22 | access to parameter nonTainted | | SSA.cs:30:13:30:31 | SSA def(nonSink1) | SSA.cs:31:9:31:24 | SSA phi(nonSink1) | | SSA.cs:30:24:30:31 | access to local variable nonSink0 | SSA.cs:30:13:30:31 | SSA def(nonSink1) | -| SSA.cs:30:24:30:31 | access to local variable nonSink0 | SSA.cs:49:24:49:31 | access to local variable nonSink0 | -| SSA.cs:30:24:30:31 | access to local variable nonSink0 | SSA.cs:63:23:63:30 | access to local variable nonSink0 | +| SSA.cs:30:24:30:31 | access to local variable nonSink0 | SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | +| SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | SSA.cs:49:24:49:31 | access to local variable nonSink0 | +| SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | SSA.cs:55:9:55:24 | SSA phi read(nonSink0) | | SSA.cs:31:9:31:24 | SSA phi(nonSink1) | SSA.cs:31:15:31:22 | access to local variable nonSink1 | | SSA.cs:34:16:34:28 | SSA def(ssaSink2) | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | | SSA.cs:34:27:34:28 | "" | SSA.cs:34:16:34:28 | SSA def(ssaSink2) | | SSA.cs:35:13:35:22 | [post] access to parameter nonTainted | SSA.cs:38:17:38:26 | access to parameter nonTainted | -| SSA.cs:35:13:35:22 | [post] access to parameter nonTainted | SSA.cs:47:13:47:22 | access to parameter nonTainted | +| SSA.cs:35:13:35:22 | [post] access to parameter nonTainted | SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | | SSA.cs:35:13:35:22 | access to parameter nonTainted | SSA.cs:38:17:38:26 | access to parameter nonTainted | -| SSA.cs:35:13:35:22 | access to parameter nonTainted | SSA.cs:47:13:47:22 | access to parameter nonTainted | +| SSA.cs:35:13:35:22 | access to parameter nonTainted | SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | | SSA.cs:37:13:37:31 | SSA def(ssaSink2) | SSA.cs:39:21:39:28 | access to local variable ssaSink2 | | SSA.cs:37:13:37:31 | SSA def(ssaSink2) | SSA.cs:41:21:41:28 | access to local variable ssaSink2 | | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | SSA.cs:37:13:37:31 | SSA def(ssaSink2) | -| SSA.cs:37:24:37:31 | access to local variable ssaSink0 | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | -| SSA.cs:37:24:37:31 | access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | -| SSA.cs:38:17:38:26 | [post] access to parameter nonTainted | SSA.cs:47:13:47:22 | access to parameter nonTainted | -| SSA.cs:38:17:38:26 | access to parameter nonTainted | SSA.cs:47:13:47:22 | access to parameter nonTainted | +| SSA.cs:37:24:37:31 | access to local variable ssaSink0 | SSA.cs:43:9:43:24 | SSA phi read(ssaSink0) | +| SSA.cs:38:17:38:26 | [post] access to parameter nonTainted | SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | +| SSA.cs:38:17:38:26 | access to parameter nonTainted | SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | | SSA.cs:39:21:39:28 | [post] access to local variable ssaSink2 | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | | SSA.cs:39:21:39:28 | access to local variable ssaSink2 | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | | SSA.cs:41:21:41:28 | [post] access to local variable ssaSink2 | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | | SSA.cs:41:21:41:28 | access to local variable ssaSink2 | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | +| SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | SSA.cs:47:13:47:22 | access to parameter nonTainted | +| SSA.cs:43:9:43:24 | SSA phi read(ssaSink0) | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | +| SSA.cs:43:9:43:24 | SSA phi read(ssaSink0) | SSA.cs:97:9:97:32 | SSA phi read(ssaSink0) | | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | SSA.cs:43:15:43:22 | access to local variable ssaSink2 | | SSA.cs:46:16:46:28 | SSA def(nonSink2) | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | | SSA.cs:46:27:46:28 | "" | SSA.cs:46:16:46:28 | SSA def(nonSink2) | | SSA.cs:47:13:47:22 | [post] access to parameter nonTainted | SSA.cs:50:17:50:26 | access to parameter nonTainted | -| SSA.cs:47:13:47:22 | [post] access to parameter nonTainted | SSA.cs:89:13:89:22 | access to parameter nonTainted | +| SSA.cs:47:13:47:22 | [post] access to parameter nonTainted | SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | | SSA.cs:47:13:47:22 | access to parameter nonTainted | SSA.cs:50:17:50:26 | access to parameter nonTainted | -| SSA.cs:47:13:47:22 | access to parameter nonTainted | SSA.cs:89:13:89:22 | access to parameter nonTainted | +| SSA.cs:47:13:47:22 | access to parameter nonTainted | SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | | SSA.cs:49:13:49:31 | SSA def(nonSink2) | SSA.cs:51:21:51:28 | access to local variable nonSink2 | | SSA.cs:49:13:49:31 | SSA def(nonSink2) | SSA.cs:53:21:53:28 | access to local variable nonSink2 | | SSA.cs:49:24:49:31 | access to local variable nonSink0 | SSA.cs:49:13:49:31 | SSA def(nonSink2) | -| SSA.cs:49:24:49:31 | access to local variable nonSink0 | SSA.cs:63:23:63:30 | access to local variable nonSink0 | -| SSA.cs:50:17:50:26 | [post] access to parameter nonTainted | SSA.cs:89:13:89:22 | access to parameter nonTainted | -| SSA.cs:50:17:50:26 | access to parameter nonTainted | SSA.cs:89:13:89:22 | access to parameter nonTainted | +| SSA.cs:49:24:49:31 | access to local variable nonSink0 | SSA.cs:55:9:55:24 | SSA phi read(nonSink0) | +| SSA.cs:50:17:50:26 | [post] access to parameter nonTainted | SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | +| SSA.cs:50:17:50:26 | access to parameter nonTainted | SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | | SSA.cs:51:21:51:28 | [post] access to local variable nonSink2 | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | | SSA.cs:51:21:51:28 | access to local variable nonSink2 | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | | SSA.cs:53:21:53:28 | [post] access to local variable nonSink2 | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | | SSA.cs:53:21:53:28 | access to local variable nonSink2 | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | +| SSA.cs:55:9:55:24 | SSA phi read(nonSink0) | SSA.cs:63:23:63:30 | access to local variable nonSink0 | +| SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | SSA.cs:89:13:89:22 | access to parameter nonTainted | | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | SSA.cs:55:15:55:22 | access to local variable nonSink2 | | SSA.cs:58:16:58:33 | SSA def(ssaSink3) | SSA.cs:59:23:59:30 | access to local variable ssaSink3 | | SSA.cs:58:27:58:33 | access to parameter tainted | SSA.cs:58:16:58:33 | SSA def(ssaSink3) | @@ -555,9 +555,9 @@ | SSA.cs:77:20:77:26 | access to parameter tainted | SSA.cs:80:35:80:41 | access to parameter tainted | | SSA.cs:78:21:78:28 | SSA def(nonSink0) | SSA.cs:79:15:79:22 | access to local variable nonSink0 | | SSA.cs:79:15:79:22 | [post] access to local variable nonSink0 | SSA.cs:104:24:104:31 | access to local variable nonSink0 | -| SSA.cs:79:15:79:22 | [post] access to local variable nonSink0 | SSA.cs:130:39:130:46 | access to local variable nonSink0 | +| SSA.cs:79:15:79:22 | [post] access to local variable nonSink0 | SSA.cs:110:9:110:32 | SSA phi read(nonSink0) | | SSA.cs:79:15:79:22 | access to local variable nonSink0 | SSA.cs:104:24:104:31 | access to local variable nonSink0 | -| SSA.cs:79:15:79:22 | access to local variable nonSink0 | SSA.cs:130:39:130:46 | access to local variable nonSink0 | +| SSA.cs:79:15:79:22 | access to local variable nonSink0 | SSA.cs:110:9:110:32 | SSA phi read(nonSink0) | | SSA.cs:80:9:80:12 | [post] this access | SSA.cs:81:21:81:24 | this access | | SSA.cs:80:9:80:12 | this access | SSA.cs:81:21:81:24 | this access | | SSA.cs:80:9:80:14 | [post] access to field S | SSA.cs:81:21:81:26 | access to field S | @@ -585,19 +585,21 @@ | SSA.cs:88:16:88:28 | SSA def(ssaSink4) | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | | SSA.cs:88:27:88:28 | "" | SSA.cs:88:16:88:28 | SSA def(ssaSink4) | | SSA.cs:89:13:89:22 | [post] access to parameter nonTainted | SSA.cs:92:17:92:26 | access to parameter nonTainted | -| SSA.cs:89:13:89:22 | [post] access to parameter nonTainted | SSA.cs:102:13:102:22 | access to parameter nonTainted | +| SSA.cs:89:13:89:22 | [post] access to parameter nonTainted | SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | | SSA.cs:89:13:89:22 | access to parameter nonTainted | SSA.cs:92:17:92:26 | access to parameter nonTainted | -| SSA.cs:89:13:89:22 | access to parameter nonTainted | SSA.cs:102:13:102:22 | access to parameter nonTainted | +| SSA.cs:89:13:89:22 | access to parameter nonTainted | SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | | SSA.cs:91:13:91:31 | SSA def(ssaSink4) | SSA.cs:93:21:93:28 | access to local variable ssaSink4 | | SSA.cs:91:13:91:31 | SSA def(ssaSink4) | SSA.cs:95:21:95:28 | access to local variable ssaSink4 | | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | SSA.cs:91:13:91:31 | SSA def(ssaSink4) | -| SSA.cs:91:24:91:31 | access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | -| SSA.cs:92:17:92:26 | [post] access to parameter nonTainted | SSA.cs:102:13:102:22 | access to parameter nonTainted | -| SSA.cs:92:17:92:26 | access to parameter nonTainted | SSA.cs:102:13:102:22 | access to parameter nonTainted | +| SSA.cs:91:24:91:31 | access to local variable ssaSink0 | SSA.cs:97:9:97:32 | SSA phi read(ssaSink0) | +| SSA.cs:92:17:92:26 | [post] access to parameter nonTainted | SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | +| SSA.cs:92:17:92:26 | access to parameter nonTainted | SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | | SSA.cs:93:21:93:28 | [post] access to local variable ssaSink4 | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | | SSA.cs:93:21:93:28 | access to local variable ssaSink4 | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | | SSA.cs:95:21:95:28 | [post] access to local variable ssaSink4 | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | | SSA.cs:95:21:95:28 | access to local variable ssaSink4 | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | +| SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | SSA.cs:102:13:102:22 | access to parameter nonTainted | +| SSA.cs:97:9:97:32 | SSA phi read(ssaSink0) | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | SSA.cs:97:23:97:30 | access to local variable ssaSink4 | | SSA.cs:97:23:97:30 | SSA def(ssaSink4) | SSA.cs:98:15:98:22 | access to local variable ssaSink4 | | SSA.cs:97:23:97:30 | [post] access to local variable ssaSink4 | SSA.cs:97:23:97:30 | SSA def(ssaSink4) | @@ -605,19 +607,21 @@ | SSA.cs:101:16:101:28 | SSA def(nonSink3) | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | | SSA.cs:101:27:101:28 | "" | SSA.cs:101:16:101:28 | SSA def(nonSink3) | | SSA.cs:102:13:102:22 | [post] access to parameter nonTainted | SSA.cs:105:17:105:26 | access to parameter nonTainted | -| SSA.cs:102:13:102:22 | [post] access to parameter nonTainted | SSA.cs:115:13:115:22 | access to parameter nonTainted | +| SSA.cs:102:13:102:22 | [post] access to parameter nonTainted | SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | | SSA.cs:102:13:102:22 | access to parameter nonTainted | SSA.cs:105:17:105:26 | access to parameter nonTainted | -| SSA.cs:102:13:102:22 | access to parameter nonTainted | SSA.cs:115:13:115:22 | access to parameter nonTainted | +| SSA.cs:102:13:102:22 | access to parameter nonTainted | SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | | SSA.cs:104:13:104:31 | SSA def(nonSink3) | SSA.cs:106:21:106:28 | access to local variable nonSink3 | | SSA.cs:104:13:104:31 | SSA def(nonSink3) | SSA.cs:108:21:108:28 | access to local variable nonSink3 | | SSA.cs:104:24:104:31 | access to local variable nonSink0 | SSA.cs:104:13:104:31 | SSA def(nonSink3) | -| SSA.cs:104:24:104:31 | access to local variable nonSink0 | SSA.cs:130:39:130:46 | access to local variable nonSink0 | -| SSA.cs:105:17:105:26 | [post] access to parameter nonTainted | SSA.cs:115:13:115:22 | access to parameter nonTainted | -| SSA.cs:105:17:105:26 | access to parameter nonTainted | SSA.cs:115:13:115:22 | access to parameter nonTainted | +| SSA.cs:104:24:104:31 | access to local variable nonSink0 | SSA.cs:110:9:110:32 | SSA phi read(nonSink0) | +| SSA.cs:105:17:105:26 | [post] access to parameter nonTainted | SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | +| SSA.cs:105:17:105:26 | access to parameter nonTainted | SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | | SSA.cs:106:21:106:28 | [post] access to local variable nonSink3 | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | | SSA.cs:106:21:106:28 | access to local variable nonSink3 | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | | SSA.cs:108:21:108:28 | [post] access to local variable nonSink3 | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | | SSA.cs:108:21:108:28 | access to local variable nonSink3 | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | +| SSA.cs:110:9:110:32 | SSA phi read(nonSink0) | SSA.cs:130:39:130:46 | access to local variable nonSink0 | +| SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | SSA.cs:115:13:115:22 | access to parameter nonTainted | | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | SSA.cs:110:23:110:30 | access to local variable nonSink3 | | SSA.cs:110:23:110:30 | SSA def(nonSink3) | SSA.cs:111:15:111:22 | access to local variable nonSink3 | | SSA.cs:110:23:110:30 | [post] access to local variable nonSink3 | SSA.cs:110:23:110:30 | SSA def(nonSink3) | @@ -627,15 +631,15 @@ | SSA.cs:114:9:114:12 | this access | SSA.cs:117:13:117:16 | this access | | SSA.cs:114:9:114:12 | this access | SSA.cs:123:23:123:26 | this access | | SSA.cs:114:9:114:14 | [post] access to field S | SSA.cs:117:13:117:18 | access to field S | -| SSA.cs:114:9:114:14 | [post] access to field S | SSA.cs:123:23:123:28 | access to field S | +| SSA.cs:114:9:114:14 | [post] access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | | SSA.cs:114:9:114:14 | access to field S | SSA.cs:117:13:117:18 | access to field S | -| SSA.cs:114:9:114:14 | access to field S | SSA.cs:123:23:123:28 | access to field S | +| SSA.cs:114:9:114:14 | access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | | SSA.cs:114:9:114:33 | SSA def(this.S.SsaFieldSink1) | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | | SSA.cs:114:32:114:33 | "" | SSA.cs:114:9:114:33 | SSA def(this.S.SsaFieldSink1) | | SSA.cs:115:13:115:22 | [post] access to parameter nonTainted | SSA.cs:118:17:118:26 | access to parameter nonTainted | -| SSA.cs:115:13:115:22 | [post] access to parameter nonTainted | SSA.cs:128:13:128:22 | access to parameter nonTainted | +| SSA.cs:115:13:115:22 | [post] access to parameter nonTainted | SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | | SSA.cs:115:13:115:22 | access to parameter nonTainted | SSA.cs:118:17:118:26 | access to parameter nonTainted | -| SSA.cs:115:13:115:22 | access to parameter nonTainted | SSA.cs:128:13:128:22 | access to parameter nonTainted | +| SSA.cs:115:13:115:22 | access to parameter nonTainted | SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | | SSA.cs:117:13:117:16 | [post] this access | SSA.cs:119:21:119:24 | this access | | SSA.cs:117:13:117:16 | [post] this access | SSA.cs:121:21:121:24 | this access | | SSA.cs:117:13:117:16 | this access | SSA.cs:119:21:119:24 | this access | @@ -647,20 +651,22 @@ | SSA.cs:117:13:117:43 | SSA def(this.S.SsaFieldSink1) | SSA.cs:119:21:119:40 | access to field SsaFieldSink1 | | SSA.cs:117:13:117:43 | SSA def(this.S.SsaFieldSink1) | SSA.cs:121:21:121:40 | access to field SsaFieldSink1 | | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | SSA.cs:117:13:117:43 | SSA def(this.S.SsaFieldSink1) | -| SSA.cs:118:17:118:26 | [post] access to parameter nonTainted | SSA.cs:128:13:128:22 | access to parameter nonTainted | -| SSA.cs:118:17:118:26 | access to parameter nonTainted | SSA.cs:128:13:128:22 | access to parameter nonTainted | +| SSA.cs:118:17:118:26 | [post] access to parameter nonTainted | SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | +| SSA.cs:118:17:118:26 | access to parameter nonTainted | SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | | SSA.cs:119:21:119:24 | [post] this access | SSA.cs:123:23:123:26 | this access | | SSA.cs:119:21:119:24 | this access | SSA.cs:123:23:123:26 | this access | -| SSA.cs:119:21:119:26 | [post] access to field S | SSA.cs:123:23:123:28 | access to field S | -| SSA.cs:119:21:119:26 | access to field S | SSA.cs:123:23:123:28 | access to field S | +| SSA.cs:119:21:119:26 | [post] access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | +| SSA.cs:119:21:119:26 | access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | | SSA.cs:119:21:119:40 | [post] access to field SsaFieldSink1 | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | | SSA.cs:119:21:119:40 | access to field SsaFieldSink1 | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | | SSA.cs:121:21:121:24 | [post] this access | SSA.cs:123:23:123:26 | this access | | SSA.cs:121:21:121:24 | this access | SSA.cs:123:23:123:26 | this access | -| SSA.cs:121:21:121:26 | [post] access to field S | SSA.cs:123:23:123:28 | access to field S | -| SSA.cs:121:21:121:26 | access to field S | SSA.cs:123:23:123:28 | access to field S | +| SSA.cs:121:21:121:26 | [post] access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | +| SSA.cs:121:21:121:26 | access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | | SSA.cs:121:21:121:40 | [post] access to field SsaFieldSink1 | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | | SSA.cs:121:21:121:40 | access to field SsaFieldSink1 | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | +| SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | SSA.cs:128:13:128:22 | access to parameter nonTainted | +| SSA.cs:123:9:123:30 | SSA phi read(this.S) | SSA.cs:123:23:123:28 | access to field S | | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | SSA.cs:123:23:123:28 | SSA qualifier def(this.S.SsaFieldSink1) | | SSA.cs:123:23:123:26 | [post] this access | SSA.cs:124:15:124:18 | this access | | SSA.cs:123:23:123:26 | this access | SSA.cs:124:15:124:18 | this access | @@ -677,9 +683,9 @@ | SSA.cs:127:9:127:12 | this access | SSA.cs:130:13:130:16 | this access | | SSA.cs:127:9:127:12 | this access | SSA.cs:136:23:136:26 | this access | | SSA.cs:127:9:127:14 | [post] access to field S | SSA.cs:130:13:130:18 | access to field S | -| SSA.cs:127:9:127:14 | [post] access to field S | SSA.cs:136:23:136:28 | access to field S | +| SSA.cs:127:9:127:14 | [post] access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | | SSA.cs:127:9:127:14 | access to field S | SSA.cs:130:13:130:18 | access to field S | -| SSA.cs:127:9:127:14 | access to field S | SSA.cs:136:23:136:28 | access to field S | +| SSA.cs:127:9:127:14 | access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | | SSA.cs:127:9:127:36 | SSA def(this.S.SsaFieldNonSink0) | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | | SSA.cs:127:35:127:36 | "" | SSA.cs:127:9:127:36 | SSA def(this.S.SsaFieldNonSink0) | | SSA.cs:128:13:128:22 | [post] access to parameter nonTainted | SSA.cs:131:17:131:26 | access to parameter nonTainted | @@ -697,16 +703,17 @@ | SSA.cs:130:39:130:46 | access to local variable nonSink0 | SSA.cs:130:13:130:46 | SSA def(this.S.SsaFieldNonSink0) | | SSA.cs:132:21:132:24 | [post] this access | SSA.cs:136:23:136:26 | this access | | SSA.cs:132:21:132:24 | this access | SSA.cs:136:23:136:26 | this access | -| SSA.cs:132:21:132:26 | [post] access to field S | SSA.cs:136:23:136:28 | access to field S | -| SSA.cs:132:21:132:26 | access to field S | SSA.cs:136:23:136:28 | access to field S | +| SSA.cs:132:21:132:26 | [post] access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | +| SSA.cs:132:21:132:26 | access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | | SSA.cs:132:21:132:43 | [post] access to field SsaFieldNonSink0 | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | | SSA.cs:132:21:132:43 | access to field SsaFieldNonSink0 | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | | SSA.cs:134:21:134:24 | [post] this access | SSA.cs:136:23:136:26 | this access | | SSA.cs:134:21:134:24 | this access | SSA.cs:136:23:136:26 | this access | -| SSA.cs:134:21:134:26 | [post] access to field S | SSA.cs:136:23:136:28 | access to field S | -| SSA.cs:134:21:134:26 | access to field S | SSA.cs:136:23:136:28 | access to field S | +| SSA.cs:134:21:134:26 | [post] access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | +| SSA.cs:134:21:134:26 | access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | | SSA.cs:134:21:134:43 | [post] access to field SsaFieldNonSink0 | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | | SSA.cs:134:21:134:43 | access to field SsaFieldNonSink0 | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | +| SSA.cs:136:9:136:30 | SSA phi read(this.S) | SSA.cs:136:23:136:28 | access to field S | | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | SSA.cs:136:23:136:28 | SSA qualifier def(this.S.SsaFieldNonSink0) | | SSA.cs:136:23:136:26 | [post] this access | SSA.cs:137:15:137:18 | this access | | SSA.cs:136:23:136:26 | this access | SSA.cs:137:15:137:18 | this access | @@ -732,17 +739,16 @@ | SSA.cs:170:16:170:28 | SSA def(ssaSink5) | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | | SSA.cs:170:27:170:28 | "" | SSA.cs:170:16:170:28 | SSA def(ssaSink5) | | SSA.cs:171:13:171:15 | SSA def(i) | SSA.cs:174:20:174:20 | SSA phi(i) | -| SSA.cs:173:13:173:30 | SSA def(ssaSink5) | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | -| SSA.cs:173:13:173:30 | SSA def(ssaSink5) | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | +| SSA.cs:173:13:173:30 | SSA def(ssaSink5) | SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | | SSA.cs:173:24:173:30 | access to parameter tainted | SSA.cs:173:13:173:30 | SSA def(ssaSink5) | +| SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | +| SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | | SSA.cs:174:20:174:20 | SSA phi(i) | SSA.cs:174:20:174:20 | access to parameter i | | SSA.cs:174:20:174:22 | SSA def(i) | SSA.cs:174:20:174:20 | SSA phi(i) | | SSA.cs:176:21:176:28 | [post] access to local variable ssaSink5 | SSA.cs:177:21:177:28 | access to local variable ssaSink5 | | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | SSA.cs:177:21:177:28 | access to local variable ssaSink5 | -| SSA.cs:177:21:177:28 | [post] access to local variable ssaSink5 | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | -| SSA.cs:177:21:177:28 | [post] access to local variable ssaSink5 | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | -| SSA.cs:177:21:177:28 | access to local variable ssaSink5 | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | -| SSA.cs:177:21:177:28 | access to local variable ssaSink5 | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | +| SSA.cs:177:21:177:28 | [post] access to local variable ssaSink5 | SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | +| SSA.cs:177:21:177:28 | access to local variable ssaSink5 | SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | SSA.cs:180:15:180:22 | access to local variable ssaSink5 | | Splitting.cs:3:18:3:18 | b | Splitting.cs:6:13:6:13 | access to parameter b | | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:5:17:5:23 | access to parameter tainted | diff --git a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected index a2767b538f5..6627f70e735 100644 --- a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected +++ b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected @@ -482,8 +482,8 @@ | LocalDataFlow.cs:278:15:278:22 | access to local variable nonSink0 | LocalDataFlow.cs:285:31:285:38 | access to local variable nonSink0 | | LocalDataFlow.cs:281:13:281:34 | SSA def(sink70) | LocalDataFlow.cs:282:15:282:20 | access to local variable sink70 | | LocalDataFlow.cs:281:22:281:34 | ... = ... | LocalDataFlow.cs:281:13:281:34 | SSA def(sink70) | +| LocalDataFlow.cs:281:22:281:34 | SSA def(sink0) | LocalDataFlow.cs:313:22:313:38 | SSA phi read(sink0) | | LocalDataFlow.cs:281:22:281:34 | SSA def(sink0) | LocalDataFlow.cs:313:34:313:38 | access to local variable sink0 | -| LocalDataFlow.cs:281:22:281:34 | SSA def(sink0) | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | | LocalDataFlow.cs:281:30:281:34 | access to local variable sink0 | LocalDataFlow.cs:281:22:281:34 | ... = ... | | LocalDataFlow.cs:281:30:281:34 | access to local variable sink0 | LocalDataFlow.cs:281:22:281:34 | SSA def(sink0) | | LocalDataFlow.cs:282:15:282:20 | [post] access to local variable sink70 | LocalDataFlow.cs:289:13:289:18 | access to local variable sink70 | @@ -508,8 +508,9 @@ | LocalDataFlow.cs:313:22:313:29 | access to local variable nonSink0 | LocalDataFlow.cs:313:22:313:38 | ... ?? ... | | LocalDataFlow.cs:313:22:313:29 | access to local variable nonSink0 | LocalDataFlow.cs:314:31:314:38 | access to local variable nonSink0 | | LocalDataFlow.cs:313:22:313:38 | ... ?? ... | LocalDataFlow.cs:313:13:313:38 | SSA def(sink73) | +| LocalDataFlow.cs:313:22:313:38 | SSA phi read(sink0) | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | | LocalDataFlow.cs:313:34:313:38 | access to local variable sink0 | LocalDataFlow.cs:313:22:313:38 | ... ?? ... | -| LocalDataFlow.cs:313:34:313:38 | access to local variable sink0 | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | +| LocalDataFlow.cs:313:34:313:38 | access to local variable sink0 | LocalDataFlow.cs:313:22:313:38 | SSA phi read(sink0) | | LocalDataFlow.cs:314:13:314:38 | SSA def(sink74) | LocalDataFlow.cs:316:15:316:20 | access to local variable sink74 | | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | LocalDataFlow.cs:314:22:314:38 | ... ?? ... | | LocalDataFlow.cs:314:22:314:38 | ... ?? ... | LocalDataFlow.cs:314:13:314:38 | SSA def(sink74) | @@ -551,19 +552,13 @@ | SSA.cs:13:15:13:22 | [post] access to local variable nonSink0 | SSA.cs:19:13:19:20 | access to local variable nonSink0 | | SSA.cs:13:15:13:22 | access to local variable nonSink0 | SSA.cs:19:13:19:20 | access to local variable nonSink0 | | SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:24:24:24:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | +| SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | | SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:24:24:24:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | +| SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | | SSA.cs:19:13:19:20 | [post] access to local variable nonSink0 | SSA.cs:30:24:30:31 | access to local variable nonSink0 | -| SSA.cs:19:13:19:20 | [post] access to local variable nonSink0 | SSA.cs:49:24:49:31 | access to local variable nonSink0 | -| SSA.cs:19:13:19:20 | [post] access to local variable nonSink0 | SSA.cs:63:23:63:30 | access to local variable nonSink0 | +| SSA.cs:19:13:19:20 | [post] access to local variable nonSink0 | SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | | SSA.cs:19:13:19:20 | access to local variable nonSink0 | SSA.cs:30:24:30:31 | access to local variable nonSink0 | -| SSA.cs:19:13:19:20 | access to local variable nonSink0 | SSA.cs:49:24:49:31 | access to local variable nonSink0 | -| SSA.cs:19:13:19:20 | access to local variable nonSink0 | SSA.cs:63:23:63:30 | access to local variable nonSink0 | +| SSA.cs:19:13:19:20 | access to local variable nonSink0 | SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | | SSA.cs:22:16:22:28 | SSA def(ssaSink1) | SSA.cs:25:9:25:24 | SSA phi(ssaSink1) | | SSA.cs:22:27:22:28 | "" | SSA.cs:22:16:22:28 | SSA def(ssaSink1) | | SSA.cs:23:13:23:22 | [post] access to parameter nonTainted | SSA.cs:29:13:29:22 | access to parameter nonTainted | @@ -571,9 +566,9 @@ | SSA.cs:23:13:23:29 | access to property Length | SSA.cs:23:13:23:33 | ... > ... | | SSA.cs:24:13:24:31 | SSA def(ssaSink1) | SSA.cs:25:9:25:24 | SSA phi(ssaSink1) | | SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:24:13:24:31 | SSA def(ssaSink1) | -| SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | -| SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | -| SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | +| SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | +| SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | +| SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | SSA.cs:43:9:43:24 | SSA phi read(ssaSink0) | | SSA.cs:25:9:25:24 | SSA phi(ssaSink1) | SSA.cs:25:15:25:22 | access to local variable ssaSink1 | | SSA.cs:28:16:28:28 | SSA def(nonSink1) | SSA.cs:31:9:31:24 | SSA phi(nonSink1) | | SSA.cs:28:27:28:28 | "" | SSA.cs:28:16:28:28 | SSA def(nonSink1) | @@ -582,47 +577,52 @@ | SSA.cs:29:13:29:29 | access to property Length | SSA.cs:29:13:29:33 | ... > ... | | SSA.cs:30:13:30:31 | SSA def(nonSink1) | SSA.cs:31:9:31:24 | SSA phi(nonSink1) | | SSA.cs:30:24:30:31 | access to local variable nonSink0 | SSA.cs:30:13:30:31 | SSA def(nonSink1) | -| SSA.cs:30:24:30:31 | access to local variable nonSink0 | SSA.cs:49:24:49:31 | access to local variable nonSink0 | -| SSA.cs:30:24:30:31 | access to local variable nonSink0 | SSA.cs:63:23:63:30 | access to local variable nonSink0 | +| SSA.cs:30:24:30:31 | access to local variable nonSink0 | SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | +| SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | SSA.cs:49:24:49:31 | access to local variable nonSink0 | +| SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | SSA.cs:55:9:55:24 | SSA phi read(nonSink0) | | SSA.cs:31:9:31:24 | SSA phi(nonSink1) | SSA.cs:31:15:31:22 | access to local variable nonSink1 | | SSA.cs:34:16:34:28 | SSA def(ssaSink2) | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | | SSA.cs:34:27:34:28 | "" | SSA.cs:34:16:34:28 | SSA def(ssaSink2) | | SSA.cs:35:13:35:22 | [post] access to parameter nonTainted | SSA.cs:38:17:38:26 | access to parameter nonTainted | -| SSA.cs:35:13:35:22 | [post] access to parameter nonTainted | SSA.cs:47:13:47:22 | access to parameter nonTainted | +| SSA.cs:35:13:35:22 | [post] access to parameter nonTainted | SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | | SSA.cs:35:13:35:22 | access to parameter nonTainted | SSA.cs:38:17:38:26 | access to parameter nonTainted | -| SSA.cs:35:13:35:22 | access to parameter nonTainted | SSA.cs:47:13:47:22 | access to parameter nonTainted | +| SSA.cs:35:13:35:22 | access to parameter nonTainted | SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | | SSA.cs:35:13:35:29 | access to property Length | SSA.cs:35:13:35:33 | ... > ... | | SSA.cs:37:13:37:31 | SSA def(ssaSink2) | SSA.cs:39:21:39:28 | access to local variable ssaSink2 | | SSA.cs:37:13:37:31 | SSA def(ssaSink2) | SSA.cs:41:21:41:28 | access to local variable ssaSink2 | | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | SSA.cs:37:13:37:31 | SSA def(ssaSink2) | -| SSA.cs:37:24:37:31 | access to local variable ssaSink0 | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | -| SSA.cs:37:24:37:31 | access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | -| SSA.cs:38:17:38:26 | [post] access to parameter nonTainted | SSA.cs:47:13:47:22 | access to parameter nonTainted | -| SSA.cs:38:17:38:26 | access to parameter nonTainted | SSA.cs:47:13:47:22 | access to parameter nonTainted | +| SSA.cs:37:24:37:31 | access to local variable ssaSink0 | SSA.cs:43:9:43:24 | SSA phi read(ssaSink0) | +| SSA.cs:38:17:38:26 | [post] access to parameter nonTainted | SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | +| SSA.cs:38:17:38:26 | access to parameter nonTainted | SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | | SSA.cs:38:17:38:33 | access to property Length | SSA.cs:38:17:38:37 | ... > ... | | SSA.cs:39:21:39:28 | [post] access to local variable ssaSink2 | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | | SSA.cs:39:21:39:28 | access to local variable ssaSink2 | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | | SSA.cs:41:21:41:28 | [post] access to local variable ssaSink2 | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | | SSA.cs:41:21:41:28 | access to local variable ssaSink2 | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | +| SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | SSA.cs:47:13:47:22 | access to parameter nonTainted | +| SSA.cs:43:9:43:24 | SSA phi read(ssaSink0) | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | +| SSA.cs:43:9:43:24 | SSA phi read(ssaSink0) | SSA.cs:97:9:97:32 | SSA phi read(ssaSink0) | | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | SSA.cs:43:15:43:22 | access to local variable ssaSink2 | | SSA.cs:46:16:46:28 | SSA def(nonSink2) | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | | SSA.cs:46:27:46:28 | "" | SSA.cs:46:16:46:28 | SSA def(nonSink2) | | SSA.cs:47:13:47:22 | [post] access to parameter nonTainted | SSA.cs:50:17:50:26 | access to parameter nonTainted | -| SSA.cs:47:13:47:22 | [post] access to parameter nonTainted | SSA.cs:89:13:89:22 | access to parameter nonTainted | +| SSA.cs:47:13:47:22 | [post] access to parameter nonTainted | SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | | SSA.cs:47:13:47:22 | access to parameter nonTainted | SSA.cs:50:17:50:26 | access to parameter nonTainted | -| SSA.cs:47:13:47:22 | access to parameter nonTainted | SSA.cs:89:13:89:22 | access to parameter nonTainted | +| SSA.cs:47:13:47:22 | access to parameter nonTainted | SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | | SSA.cs:47:13:47:29 | access to property Length | SSA.cs:47:13:47:33 | ... > ... | | SSA.cs:49:13:49:31 | SSA def(nonSink2) | SSA.cs:51:21:51:28 | access to local variable nonSink2 | | SSA.cs:49:13:49:31 | SSA def(nonSink2) | SSA.cs:53:21:53:28 | access to local variable nonSink2 | | SSA.cs:49:24:49:31 | access to local variable nonSink0 | SSA.cs:49:13:49:31 | SSA def(nonSink2) | -| SSA.cs:49:24:49:31 | access to local variable nonSink0 | SSA.cs:63:23:63:30 | access to local variable nonSink0 | -| SSA.cs:50:17:50:26 | [post] access to parameter nonTainted | SSA.cs:89:13:89:22 | access to parameter nonTainted | -| SSA.cs:50:17:50:26 | access to parameter nonTainted | SSA.cs:89:13:89:22 | access to parameter nonTainted | +| SSA.cs:49:24:49:31 | access to local variable nonSink0 | SSA.cs:55:9:55:24 | SSA phi read(nonSink0) | +| SSA.cs:50:17:50:26 | [post] access to parameter nonTainted | SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | +| SSA.cs:50:17:50:26 | access to parameter nonTainted | SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | | SSA.cs:50:17:50:33 | access to property Length | SSA.cs:50:17:50:37 | ... > ... | | SSA.cs:51:21:51:28 | [post] access to local variable nonSink2 | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | | SSA.cs:51:21:51:28 | access to local variable nonSink2 | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | | SSA.cs:53:21:53:28 | [post] access to local variable nonSink2 | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | | SSA.cs:53:21:53:28 | access to local variable nonSink2 | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | +| SSA.cs:55:9:55:24 | SSA phi read(nonSink0) | SSA.cs:63:23:63:30 | access to local variable nonSink0 | +| SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | SSA.cs:89:13:89:22 | access to parameter nonTainted | | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | SSA.cs:55:15:55:22 | access to local variable nonSink2 | | SSA.cs:58:16:58:33 | SSA def(ssaSink3) | SSA.cs:59:23:59:30 | access to local variable ssaSink3 | | SSA.cs:58:27:58:33 | access to parameter tainted | SSA.cs:58:16:58:33 | SSA def(ssaSink3) | @@ -671,9 +671,9 @@ | SSA.cs:77:20:77:26 | access to parameter tainted | SSA.cs:80:35:80:41 | access to parameter tainted | | SSA.cs:78:21:78:28 | SSA def(nonSink0) | SSA.cs:79:15:79:22 | access to local variable nonSink0 | | SSA.cs:79:15:79:22 | [post] access to local variable nonSink0 | SSA.cs:104:24:104:31 | access to local variable nonSink0 | -| SSA.cs:79:15:79:22 | [post] access to local variable nonSink0 | SSA.cs:130:39:130:46 | access to local variable nonSink0 | +| SSA.cs:79:15:79:22 | [post] access to local variable nonSink0 | SSA.cs:110:9:110:32 | SSA phi read(nonSink0) | | SSA.cs:79:15:79:22 | access to local variable nonSink0 | SSA.cs:104:24:104:31 | access to local variable nonSink0 | -| SSA.cs:79:15:79:22 | access to local variable nonSink0 | SSA.cs:130:39:130:46 | access to local variable nonSink0 | +| SSA.cs:79:15:79:22 | access to local variable nonSink0 | SSA.cs:110:9:110:32 | SSA phi read(nonSink0) | | SSA.cs:80:9:80:12 | [post] this access | SSA.cs:81:21:81:24 | this access | | SSA.cs:80:9:80:12 | this access | SSA.cs:81:21:81:24 | this access | | SSA.cs:80:9:80:14 | [post] access to field S | SSA.cs:81:21:81:26 | access to field S | @@ -701,21 +701,23 @@ | SSA.cs:88:16:88:28 | SSA def(ssaSink4) | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | | SSA.cs:88:27:88:28 | "" | SSA.cs:88:16:88:28 | SSA def(ssaSink4) | | SSA.cs:89:13:89:22 | [post] access to parameter nonTainted | SSA.cs:92:17:92:26 | access to parameter nonTainted | -| SSA.cs:89:13:89:22 | [post] access to parameter nonTainted | SSA.cs:102:13:102:22 | access to parameter nonTainted | +| SSA.cs:89:13:89:22 | [post] access to parameter nonTainted | SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | | SSA.cs:89:13:89:22 | access to parameter nonTainted | SSA.cs:92:17:92:26 | access to parameter nonTainted | -| SSA.cs:89:13:89:22 | access to parameter nonTainted | SSA.cs:102:13:102:22 | access to parameter nonTainted | +| SSA.cs:89:13:89:22 | access to parameter nonTainted | SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | | SSA.cs:89:13:89:29 | access to property Length | SSA.cs:89:13:89:33 | ... > ... | | SSA.cs:91:13:91:31 | SSA def(ssaSink4) | SSA.cs:93:21:93:28 | access to local variable ssaSink4 | | SSA.cs:91:13:91:31 | SSA def(ssaSink4) | SSA.cs:95:21:95:28 | access to local variable ssaSink4 | | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | SSA.cs:91:13:91:31 | SSA def(ssaSink4) | -| SSA.cs:91:24:91:31 | access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | -| SSA.cs:92:17:92:26 | [post] access to parameter nonTainted | SSA.cs:102:13:102:22 | access to parameter nonTainted | -| SSA.cs:92:17:92:26 | access to parameter nonTainted | SSA.cs:102:13:102:22 | access to parameter nonTainted | +| SSA.cs:91:24:91:31 | access to local variable ssaSink0 | SSA.cs:97:9:97:32 | SSA phi read(ssaSink0) | +| SSA.cs:92:17:92:26 | [post] access to parameter nonTainted | SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | +| SSA.cs:92:17:92:26 | access to parameter nonTainted | SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | | SSA.cs:92:17:92:33 | access to property Length | SSA.cs:92:17:92:37 | ... > ... | | SSA.cs:93:21:93:28 | [post] access to local variable ssaSink4 | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | | SSA.cs:93:21:93:28 | access to local variable ssaSink4 | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | | SSA.cs:95:21:95:28 | [post] access to local variable ssaSink4 | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | | SSA.cs:95:21:95:28 | access to local variable ssaSink4 | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | +| SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | SSA.cs:102:13:102:22 | access to parameter nonTainted | +| SSA.cs:97:9:97:32 | SSA phi read(ssaSink0) | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | SSA.cs:97:23:97:30 | access to local variable ssaSink4 | | SSA.cs:97:23:97:30 | SSA def(ssaSink4) | SSA.cs:98:15:98:22 | access to local variable ssaSink4 | | SSA.cs:97:23:97:30 | [post] access to local variable ssaSink4 | SSA.cs:97:23:97:30 | SSA def(ssaSink4) | @@ -723,21 +725,23 @@ | SSA.cs:101:16:101:28 | SSA def(nonSink3) | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | | SSA.cs:101:27:101:28 | "" | SSA.cs:101:16:101:28 | SSA def(nonSink3) | | SSA.cs:102:13:102:22 | [post] access to parameter nonTainted | SSA.cs:105:17:105:26 | access to parameter nonTainted | -| SSA.cs:102:13:102:22 | [post] access to parameter nonTainted | SSA.cs:115:13:115:22 | access to parameter nonTainted | +| SSA.cs:102:13:102:22 | [post] access to parameter nonTainted | SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | | SSA.cs:102:13:102:22 | access to parameter nonTainted | SSA.cs:105:17:105:26 | access to parameter nonTainted | -| SSA.cs:102:13:102:22 | access to parameter nonTainted | SSA.cs:115:13:115:22 | access to parameter nonTainted | +| SSA.cs:102:13:102:22 | access to parameter nonTainted | SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | | SSA.cs:102:13:102:29 | access to property Length | SSA.cs:102:13:102:33 | ... > ... | | SSA.cs:104:13:104:31 | SSA def(nonSink3) | SSA.cs:106:21:106:28 | access to local variable nonSink3 | | SSA.cs:104:13:104:31 | SSA def(nonSink3) | SSA.cs:108:21:108:28 | access to local variable nonSink3 | | SSA.cs:104:24:104:31 | access to local variable nonSink0 | SSA.cs:104:13:104:31 | SSA def(nonSink3) | -| SSA.cs:104:24:104:31 | access to local variable nonSink0 | SSA.cs:130:39:130:46 | access to local variable nonSink0 | -| SSA.cs:105:17:105:26 | [post] access to parameter nonTainted | SSA.cs:115:13:115:22 | access to parameter nonTainted | -| SSA.cs:105:17:105:26 | access to parameter nonTainted | SSA.cs:115:13:115:22 | access to parameter nonTainted | +| SSA.cs:104:24:104:31 | access to local variable nonSink0 | SSA.cs:110:9:110:32 | SSA phi read(nonSink0) | +| SSA.cs:105:17:105:26 | [post] access to parameter nonTainted | SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | +| SSA.cs:105:17:105:26 | access to parameter nonTainted | SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | | SSA.cs:105:17:105:33 | access to property Length | SSA.cs:105:17:105:37 | ... > ... | | SSA.cs:106:21:106:28 | [post] access to local variable nonSink3 | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | | SSA.cs:106:21:106:28 | access to local variable nonSink3 | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | | SSA.cs:108:21:108:28 | [post] access to local variable nonSink3 | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | | SSA.cs:108:21:108:28 | access to local variable nonSink3 | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | +| SSA.cs:110:9:110:32 | SSA phi read(nonSink0) | SSA.cs:130:39:130:46 | access to local variable nonSink0 | +| SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | SSA.cs:115:13:115:22 | access to parameter nonTainted | | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | SSA.cs:110:23:110:30 | access to local variable nonSink3 | | SSA.cs:110:23:110:30 | SSA def(nonSink3) | SSA.cs:111:15:111:22 | access to local variable nonSink3 | | SSA.cs:110:23:110:30 | [post] access to local variable nonSink3 | SSA.cs:110:23:110:30 | SSA def(nonSink3) | @@ -747,15 +751,15 @@ | SSA.cs:114:9:114:12 | this access | SSA.cs:117:13:117:16 | this access | | SSA.cs:114:9:114:12 | this access | SSA.cs:123:23:123:26 | this access | | SSA.cs:114:9:114:14 | [post] access to field S | SSA.cs:117:13:117:18 | access to field S | -| SSA.cs:114:9:114:14 | [post] access to field S | SSA.cs:123:23:123:28 | access to field S | +| SSA.cs:114:9:114:14 | [post] access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | | SSA.cs:114:9:114:14 | access to field S | SSA.cs:117:13:117:18 | access to field S | -| SSA.cs:114:9:114:14 | access to field S | SSA.cs:123:23:123:28 | access to field S | +| SSA.cs:114:9:114:14 | access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | | SSA.cs:114:9:114:33 | SSA def(this.S.SsaFieldSink1) | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | | SSA.cs:114:32:114:33 | "" | SSA.cs:114:9:114:33 | SSA def(this.S.SsaFieldSink1) | | SSA.cs:115:13:115:22 | [post] access to parameter nonTainted | SSA.cs:118:17:118:26 | access to parameter nonTainted | -| SSA.cs:115:13:115:22 | [post] access to parameter nonTainted | SSA.cs:128:13:128:22 | access to parameter nonTainted | +| SSA.cs:115:13:115:22 | [post] access to parameter nonTainted | SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | | SSA.cs:115:13:115:22 | access to parameter nonTainted | SSA.cs:118:17:118:26 | access to parameter nonTainted | -| SSA.cs:115:13:115:22 | access to parameter nonTainted | SSA.cs:128:13:128:22 | access to parameter nonTainted | +| SSA.cs:115:13:115:22 | access to parameter nonTainted | SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | | SSA.cs:115:13:115:29 | access to property Length | SSA.cs:115:13:115:33 | ... > ... | | SSA.cs:117:13:117:16 | [post] this access | SSA.cs:119:21:119:24 | this access | | SSA.cs:117:13:117:16 | [post] this access | SSA.cs:121:21:121:24 | this access | @@ -768,21 +772,23 @@ | SSA.cs:117:13:117:43 | SSA def(this.S.SsaFieldSink1) | SSA.cs:119:21:119:40 | access to field SsaFieldSink1 | | SSA.cs:117:13:117:43 | SSA def(this.S.SsaFieldSink1) | SSA.cs:121:21:121:40 | access to field SsaFieldSink1 | | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | SSA.cs:117:13:117:43 | SSA def(this.S.SsaFieldSink1) | -| SSA.cs:118:17:118:26 | [post] access to parameter nonTainted | SSA.cs:128:13:128:22 | access to parameter nonTainted | -| SSA.cs:118:17:118:26 | access to parameter nonTainted | SSA.cs:128:13:128:22 | access to parameter nonTainted | +| SSA.cs:118:17:118:26 | [post] access to parameter nonTainted | SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | +| SSA.cs:118:17:118:26 | access to parameter nonTainted | SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | | SSA.cs:118:17:118:33 | access to property Length | SSA.cs:118:17:118:37 | ... > ... | | SSA.cs:119:21:119:24 | [post] this access | SSA.cs:123:23:123:26 | this access | | SSA.cs:119:21:119:24 | this access | SSA.cs:123:23:123:26 | this access | -| SSA.cs:119:21:119:26 | [post] access to field S | SSA.cs:123:23:123:28 | access to field S | -| SSA.cs:119:21:119:26 | access to field S | SSA.cs:123:23:123:28 | access to field S | +| SSA.cs:119:21:119:26 | [post] access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | +| SSA.cs:119:21:119:26 | access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | | SSA.cs:119:21:119:40 | [post] access to field SsaFieldSink1 | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | | SSA.cs:119:21:119:40 | access to field SsaFieldSink1 | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | | SSA.cs:121:21:121:24 | [post] this access | SSA.cs:123:23:123:26 | this access | | SSA.cs:121:21:121:24 | this access | SSA.cs:123:23:123:26 | this access | -| SSA.cs:121:21:121:26 | [post] access to field S | SSA.cs:123:23:123:28 | access to field S | -| SSA.cs:121:21:121:26 | access to field S | SSA.cs:123:23:123:28 | access to field S | +| SSA.cs:121:21:121:26 | [post] access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | +| SSA.cs:121:21:121:26 | access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | | SSA.cs:121:21:121:40 | [post] access to field SsaFieldSink1 | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | | SSA.cs:121:21:121:40 | access to field SsaFieldSink1 | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | +| SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | SSA.cs:128:13:128:22 | access to parameter nonTainted | +| SSA.cs:123:9:123:30 | SSA phi read(this.S) | SSA.cs:123:23:123:28 | access to field S | | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | SSA.cs:123:23:123:28 | SSA qualifier def(this.S.SsaFieldSink1) | | SSA.cs:123:23:123:26 | [post] this access | SSA.cs:124:15:124:18 | this access | | SSA.cs:123:23:123:26 | this access | SSA.cs:124:15:124:18 | this access | @@ -799,9 +805,9 @@ | SSA.cs:127:9:127:12 | this access | SSA.cs:130:13:130:16 | this access | | SSA.cs:127:9:127:12 | this access | SSA.cs:136:23:136:26 | this access | | SSA.cs:127:9:127:14 | [post] access to field S | SSA.cs:130:13:130:18 | access to field S | -| SSA.cs:127:9:127:14 | [post] access to field S | SSA.cs:136:23:136:28 | access to field S | +| SSA.cs:127:9:127:14 | [post] access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | | SSA.cs:127:9:127:14 | access to field S | SSA.cs:130:13:130:18 | access to field S | -| SSA.cs:127:9:127:14 | access to field S | SSA.cs:136:23:136:28 | access to field S | +| SSA.cs:127:9:127:14 | access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | | SSA.cs:127:9:127:36 | SSA def(this.S.SsaFieldNonSink0) | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | | SSA.cs:127:35:127:36 | "" | SSA.cs:127:9:127:36 | SSA def(this.S.SsaFieldNonSink0) | | SSA.cs:128:13:128:22 | [post] access to parameter nonTainted | SSA.cs:131:17:131:26 | access to parameter nonTainted | @@ -821,16 +827,17 @@ | SSA.cs:131:17:131:33 | access to property Length | SSA.cs:131:17:131:37 | ... > ... | | SSA.cs:132:21:132:24 | [post] this access | SSA.cs:136:23:136:26 | this access | | SSA.cs:132:21:132:24 | this access | SSA.cs:136:23:136:26 | this access | -| SSA.cs:132:21:132:26 | [post] access to field S | SSA.cs:136:23:136:28 | access to field S | -| SSA.cs:132:21:132:26 | access to field S | SSA.cs:136:23:136:28 | access to field S | +| SSA.cs:132:21:132:26 | [post] access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | +| SSA.cs:132:21:132:26 | access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | | SSA.cs:132:21:132:43 | [post] access to field SsaFieldNonSink0 | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | | SSA.cs:132:21:132:43 | access to field SsaFieldNonSink0 | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | | SSA.cs:134:21:134:24 | [post] this access | SSA.cs:136:23:136:26 | this access | | SSA.cs:134:21:134:24 | this access | SSA.cs:136:23:136:26 | this access | -| SSA.cs:134:21:134:26 | [post] access to field S | SSA.cs:136:23:136:28 | access to field S | -| SSA.cs:134:21:134:26 | access to field S | SSA.cs:136:23:136:28 | access to field S | +| SSA.cs:134:21:134:26 | [post] access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | +| SSA.cs:134:21:134:26 | access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | | SSA.cs:134:21:134:43 | [post] access to field SsaFieldNonSink0 | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | | SSA.cs:134:21:134:43 | access to field SsaFieldNonSink0 | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | +| SSA.cs:136:9:136:30 | SSA phi read(this.S) | SSA.cs:136:23:136:28 | access to field S | | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | SSA.cs:136:23:136:28 | SSA qualifier def(this.S.SsaFieldNonSink0) | | SSA.cs:136:23:136:26 | [post] this access | SSA.cs:137:15:137:18 | this access | | SSA.cs:136:23:136:26 | this access | SSA.cs:137:15:137:18 | this access | @@ -859,18 +866,17 @@ | SSA.cs:170:27:170:28 | "" | SSA.cs:170:16:170:28 | SSA def(ssaSink5) | | SSA.cs:171:13:171:15 | ...-- | SSA.cs:171:13:171:19 | ... > ... | | SSA.cs:171:13:171:15 | SSA def(i) | SSA.cs:174:20:174:20 | SSA phi(i) | -| SSA.cs:173:13:173:30 | SSA def(ssaSink5) | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | -| SSA.cs:173:13:173:30 | SSA def(ssaSink5) | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | +| SSA.cs:173:13:173:30 | SSA def(ssaSink5) | SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | | SSA.cs:173:24:173:30 | access to parameter tainted | SSA.cs:173:13:173:30 | SSA def(ssaSink5) | +| SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | +| SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | | SSA.cs:174:20:174:20 | SSA phi(i) | SSA.cs:174:20:174:20 | access to parameter i | | SSA.cs:174:20:174:22 | ...-- | SSA.cs:174:20:174:26 | ... > ... | | SSA.cs:174:20:174:22 | SSA def(i) | SSA.cs:174:20:174:20 | SSA phi(i) | | SSA.cs:176:21:176:28 | [post] access to local variable ssaSink5 | SSA.cs:177:21:177:28 | access to local variable ssaSink5 | | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | SSA.cs:177:21:177:28 | access to local variable ssaSink5 | -| SSA.cs:177:21:177:28 | [post] access to local variable ssaSink5 | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | -| SSA.cs:177:21:177:28 | [post] access to local variable ssaSink5 | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | -| SSA.cs:177:21:177:28 | access to local variable ssaSink5 | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | -| SSA.cs:177:21:177:28 | access to local variable ssaSink5 | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | +| SSA.cs:177:21:177:28 | [post] access to local variable ssaSink5 | SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | +| SSA.cs:177:21:177:28 | access to local variable ssaSink5 | SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | SSA.cs:180:15:180:22 | access to local variable ssaSink5 | | Splitting.cs:3:18:3:18 | b | Splitting.cs:6:13:6:13 | access to parameter b | | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:5:17:5:23 | access to parameter tainted | From e4b0d8dbf3ad3ffca4f13cb381d4bfc9c2676ad8 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 16 Nov 2022 16:07:49 +0100 Subject: [PATCH 318/796] simplify the copy-logic, because cp -r actually creates the folders --- .github/workflows/compile-queries.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/compile-queries.yml b/.github/workflows/compile-queries.yml index 73b674aff30..94378250c85 100644 --- a/.github/workflows/compile-queries.yml +++ b/.github/workflows/compile-queries.yml @@ -60,14 +60,10 @@ jobs: # Move all the existing cache into another folder, so we only preserve the cache for the current queries. mkdir -p ${COMBINED_CACHE_DIR} rm */ql/src/.cache/{lock,size} - # replicate the folder structure from the .cache folders into the combined cache folder. (because cp doesn't have a "create missing folders" option) - find */ql/src/.cache -type d | cut -d "/" -f 6,7 | sort | uniq > folders.txt - cat folders.txt | xargs -I {} mkdir -p ${COMBINED_CACHE_DIR}/{} # copy the contents of the .cache folders into the combined cache folder. cp -r */ql/src/.cache/* ${COMBINED_CACHE_DIR}/ # clean up the .cache folders rm -rf */ql/src/.cache/* - rm folders.txt # compile the queries codeql query compile -j0 */ql/src --keep-going --warnings=error --compilation-cache ${COMBINED_CACHE_DIR} From 983851fc6048554b87d3627c6bd16d7e4f8a514c Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 16:18:37 +0100 Subject: [PATCH 319/796] Kotlin: Add FP test case for dead code queries --- java/ql/src/DeadCode/DeadClass.ql | 2 ++ java/ql/src/DeadCode/DeadField.ql | 2 ++ java/ql/src/DeadCode/DeadMethod.ql | 2 ++ .../query-tests/DeadCode/DeadClass.expected | 4 +++ .../query-tests/DeadCode/DeadClass.qlref | 1 + .../query-tests/DeadCode/DeadMethod.expected | 8 +++++ .../query-tests/DeadCode/DeadMethod.qlref | 1 + .../test/kotlin/query-tests/DeadCode/Test.kt | 31 +++++++++++++++++++ 8 files changed, 51 insertions(+) create mode 100644 java/ql/test/kotlin/query-tests/DeadCode/DeadClass.expected create mode 100644 java/ql/test/kotlin/query-tests/DeadCode/DeadClass.qlref create mode 100644 java/ql/test/kotlin/query-tests/DeadCode/DeadMethod.expected create mode 100644 java/ql/test/kotlin/query-tests/DeadCode/DeadMethod.qlref create mode 100644 java/ql/test/kotlin/query-tests/DeadCode/Test.kt diff --git a/java/ql/src/DeadCode/DeadClass.ql b/java/ql/src/DeadCode/DeadClass.ql index 8a1b5e0be77..23f08fec3b8 100644 --- a/java/ql/src/DeadCode/DeadClass.ql +++ b/java/ql/src/DeadCode/DeadClass.ql @@ -14,6 +14,8 @@ import semmle.code.java.deadcode.DeadCode from DeadClass c, Element origin, string reason where + not c.getFile().isKotlinSourceFile() and + not origin.getFile().isKotlinSourceFile() and if exists(DeadRoot root | root = c.getADeadRoot() | not root = c.getACallable()) then ( // Report a list of the dead roots. diff --git a/java/ql/src/DeadCode/DeadField.ql b/java/ql/src/DeadCode/DeadField.ql index 6a80e13e716..7a8bca7ac7b 100644 --- a/java/ql/src/DeadCode/DeadField.ql +++ b/java/ql/src/DeadCode/DeadField.ql @@ -15,6 +15,8 @@ import semmle.code.java.deadcode.DeadCode from DeadField f, Element origin, string reason where + not f.getFile().isKotlinSourceFile() and + not origin.getFile().isKotlinSourceFile() and not f.isInDeadScope() and if f.getAnAccess() instanceof FieldRead then ( diff --git a/java/ql/src/DeadCode/DeadMethod.ql b/java/ql/src/DeadCode/DeadMethod.ql index 8b5d0f155ef..77401341b6c 100644 --- a/java/ql/src/DeadCode/DeadMethod.ql +++ b/java/ql/src/DeadCode/DeadMethod.ql @@ -15,6 +15,8 @@ import semmle.code.java.deadcode.DeadCode from DeadMethod c, Callable origin, string reason where + not c.getFile().isKotlinSourceFile() and + not origin.getFile().isKotlinSourceFile() and not c.isInDeadScope() and if exists(DeadRoot deadRoot | deadRoot = getADeadRoot(c) | deadRoot.getSourceDeclaration() != c) then ( diff --git a/java/ql/test/kotlin/query-tests/DeadCode/DeadClass.expected b/java/ql/test/kotlin/query-tests/DeadCode/DeadClass.expected new file mode 100644 index 00000000000..417cfb36df0 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/DeadCode/DeadClass.expected @@ -0,0 +1,4 @@ +| Test.kt:0:0:0:0 | TestKt | The class TestKt is entirely unused. | Test.kt:0:0:0:0 | TestKt | TestKt | +| Test.kt:1:1:1:26 | DbAddexpr | The class DbAddexpr is entirely unused. | Test.kt:1:1:1:26 | DbAddexpr | DbAddexpr | +| Test.kt:3:1:4:1 | Label | The class Label is only used from dead code originating at $@. | Test.kt:15:1:17:1 | main1 | main1 | +| Test.kt:19:1:27:1 | Foo | The class Foo is only used from dead code originating at $@. | Test.kt:29:1:31:1 | main2 | main2 | diff --git a/java/ql/test/kotlin/query-tests/DeadCode/DeadClass.qlref b/java/ql/test/kotlin/query-tests/DeadCode/DeadClass.qlref new file mode 100644 index 00000000000..d726e7e0849 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/DeadCode/DeadClass.qlref @@ -0,0 +1 @@ +DeadCode/DeadClass.ql diff --git a/java/ql/test/kotlin/query-tests/DeadCode/DeadMethod.expected b/java/ql/test/kotlin/query-tests/DeadCode/DeadMethod.expected new file mode 100644 index 00000000000..3478791023a --- /dev/null +++ b/java/ql/test/kotlin/query-tests/DeadCode/DeadMethod.expected @@ -0,0 +1,8 @@ +| Test.kt:0:0:0:0 | component1 | The method component1 is entirely unused. | Test.kt:0:0:0:0 | component1 | component1 | +| Test.kt:0:0:0:0 | component2 | The method component2 is entirely unused. | Test.kt:0:0:0:0 | component2 | component2 | +| Test.kt:0:0:0:0 | copy | The method copy is only used from dead code originating at $@. | Test.kt:0:0:0:0 | copy$default | copy$default | +| Test.kt:0:0:0:0 | copy$default | The method copy$default is entirely unused. | Test.kt:0:0:0:0 | copy$default | copy$default | +| Test.kt:20:10:20:41 | DC | The method DC is only used from dead code originating at $@. | Test.kt:0:0:0:0 | copy$default | copy$default | +| Test.kt:20:10:20:41 | DC | The method DC is only used from dead code originating at $@. | Test.kt:29:1:31:1 | main2 | main2 | +| Test.kt:20:19:20:28 | getX | The method getX is only used from dead code originating at $@. | Test.kt:29:1:31:1 | main2 | main2 | +| Test.kt:20:31:20:40 | getY | The method getY is only used from dead code originating at $@. | Test.kt:29:1:31:1 | main2 | main2 | diff --git a/java/ql/test/kotlin/query-tests/DeadCode/DeadMethod.qlref b/java/ql/test/kotlin/query-tests/DeadCode/DeadMethod.qlref new file mode 100644 index 00000000000..76204a1df5a --- /dev/null +++ b/java/ql/test/kotlin/query-tests/DeadCode/DeadMethod.qlref @@ -0,0 +1 @@ +DeadCode/DeadMethod.ql diff --git a/java/ql/test/kotlin/query-tests/DeadCode/Test.kt b/java/ql/test/kotlin/query-tests/DeadCode/Test.kt new file mode 100644 index 00000000000..67c4a2ae4a7 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/DeadCode/Test.kt @@ -0,0 +1,31 @@ +sealed interface DbAddexpr + +class Label { +} + +fun getFreshIdLabel(): Label { + return Label() +} + +fun foo(): Label { + val x = getFreshIdLabel() + return x +} + +fun main1() { + print(foo()) +} + +class Foo { + data class DC(val x: Int, val y: Int) + + fun foo() { + val dc = DC(3, 4) + print(dc.x) + print(dc.y) + } +} + +fun main2() { + Foo().foo() +} From 8b6bf910bafea716b9f32c053b10bb21813770b6 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 16 Nov 2022 16:20:09 +0100 Subject: [PATCH 320/796] Kotlin: Exclude .kt files from dead code queries --- .../test/kotlin/query-tests/DeadCode/DeadClass.expected | 4 ---- .../test/kotlin/query-tests/DeadCode/DeadMethod.expected | 8 -------- 2 files changed, 12 deletions(-) diff --git a/java/ql/test/kotlin/query-tests/DeadCode/DeadClass.expected b/java/ql/test/kotlin/query-tests/DeadCode/DeadClass.expected index 417cfb36df0..e69de29bb2d 100644 --- a/java/ql/test/kotlin/query-tests/DeadCode/DeadClass.expected +++ b/java/ql/test/kotlin/query-tests/DeadCode/DeadClass.expected @@ -1,4 +0,0 @@ -| Test.kt:0:0:0:0 | TestKt | The class TestKt is entirely unused. | Test.kt:0:0:0:0 | TestKt | TestKt | -| Test.kt:1:1:1:26 | DbAddexpr | The class DbAddexpr is entirely unused. | Test.kt:1:1:1:26 | DbAddexpr | DbAddexpr | -| Test.kt:3:1:4:1 | Label | The class Label is only used from dead code originating at $@. | Test.kt:15:1:17:1 | main1 | main1 | -| Test.kt:19:1:27:1 | Foo | The class Foo is only used from dead code originating at $@. | Test.kt:29:1:31:1 | main2 | main2 | diff --git a/java/ql/test/kotlin/query-tests/DeadCode/DeadMethod.expected b/java/ql/test/kotlin/query-tests/DeadCode/DeadMethod.expected index 3478791023a..e69de29bb2d 100644 --- a/java/ql/test/kotlin/query-tests/DeadCode/DeadMethod.expected +++ b/java/ql/test/kotlin/query-tests/DeadCode/DeadMethod.expected @@ -1,8 +0,0 @@ -| Test.kt:0:0:0:0 | component1 | The method component1 is entirely unused. | Test.kt:0:0:0:0 | component1 | component1 | -| Test.kt:0:0:0:0 | component2 | The method component2 is entirely unused. | Test.kt:0:0:0:0 | component2 | component2 | -| Test.kt:0:0:0:0 | copy | The method copy is only used from dead code originating at $@. | Test.kt:0:0:0:0 | copy$default | copy$default | -| Test.kt:0:0:0:0 | copy$default | The method copy$default is entirely unused. | Test.kt:0:0:0:0 | copy$default | copy$default | -| Test.kt:20:10:20:41 | DC | The method DC is only used from dead code originating at $@. | Test.kt:0:0:0:0 | copy$default | copy$default | -| Test.kt:20:10:20:41 | DC | The method DC is only used from dead code originating at $@. | Test.kt:29:1:31:1 | main2 | main2 | -| Test.kt:20:19:20:28 | getX | The method getX is only used from dead code originating at $@. | Test.kt:29:1:31:1 | main2 | main2 | -| Test.kt:20:31:20:40 | getY | The method getY is only used from dead code originating at $@. | Test.kt:29:1:31:1 | main2 | main2 | From 27df44f5ad9406850d7d7a4c38730b1c647b5734 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 16 Nov 2022 16:35:17 +0100 Subject: [PATCH 321/796] Swift: replace empty `IpaInfo()` with a clearer `True` value --- swift/codegen/lib/schema/schema.py | 9 +++++++-- swift/codegen/test/test_schema.py | 8 ++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/swift/codegen/lib/schema/schema.py b/swift/codegen/lib/schema/schema.py index fe0b9e26660..3611b2336bd 100644 --- a/swift/codegen/lib/schema/schema.py +++ b/swift/codegen/lib/schema/schema.py @@ -86,7 +86,8 @@ class Class: properties: List[Property] = field(default_factory=list) group: str = "" pragmas: List[str] = field(default_factory=list) - ipa: Optional[IpaInfo] = None + ipa: Optional[Union[IpaInfo, bool]] = None + """^^^ filled with `True` for non-final classes with only synthesized final descendants """ doc: List[str] = field(default_factory=list) default_doc_name: Optional[str] = None @@ -248,6 +249,10 @@ def _toposort_classes_by_group(classes: typing.Dict[str, Class]) -> typing.Dict[ def _fill_ipa_information(classes: typing.Dict[str, Class]): + """ Take a dictionary where the `ipa` field is filled for all explicitly synthesized classes + and updated it so that all non-final classes that have only synthesized final descendants + get `True` as` value for the `ipa` field + """ if not classes: return @@ -270,7 +275,7 @@ def _fill_ipa_information(classes: typing.Dict[str, Class]): for name, cls in classes.items(): if cls.ipa is None and is_ipa[name]: - cls.ipa = IpaInfo() + cls.ipa = True def load(m: types.ModuleType) -> Schema: diff --git a/swift/codegen/test/test_schema.py b/swift/codegen/test/test_schema.py index 439d007d137..7ba84b4a292 100644 --- a/swift/codegen/test/test_schema.py +++ b/swift/codegen/test/test_schema.py @@ -340,7 +340,7 @@ def test_ipa_from_class(): pass assert data.classes == { - 'A': schema.Class('A', derived={'B'}, ipa=schema.IpaInfo()), + 'A': schema.Class('A', derived={'B'}, ipa=True), 'B': schema.Class('B', bases=['A'], ipa=schema.IpaInfo(from_class="A")), } @@ -381,7 +381,7 @@ def test_ipa_class_on(): pass assert data.classes == { - 'A': schema.Class('A', derived={'B'}, ipa=schema.IpaInfo()), + 'A': schema.Class('A', derived={'B'}, ipa=True), 'B': schema.Class('B', bases=['A'], ipa=schema.IpaInfo(on_arguments={'a': 'A', 'i': 'int'})), } @@ -439,8 +439,8 @@ def test_ipa_class_hierarchy(): assert data.classes == { 'Root': schema.Class('Root', derived={'Base', 'C'}), - 'Base': schema.Class('Base', bases=['Root'], derived={'Intermediate', 'B'}, ipa=schema.IpaInfo()), - 'Intermediate': schema.Class('Intermediate', bases=['Base'], derived={'A'}, ipa=schema.IpaInfo()), + 'Base': schema.Class('Base', bases=['Root'], derived={'Intermediate', 'B'}, ipa=True), + 'Intermediate': schema.Class('Intermediate', bases=['Base'], derived={'A'}, ipa=True), 'A': schema.Class('A', bases=['Intermediate'], ipa=schema.IpaInfo(on_arguments={'a': 'Base', 'i': 'int'})), 'B': schema.Class('B', bases=['Base'], ipa=schema.IpaInfo(from_class='Base')), 'C': schema.Class('C', bases=['Root']), From 1c69a1f012b568324e41f10b06f628c861a8ffa5 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 16 Nov 2022 16:36:48 +0100 Subject: [PATCH 322/796] Swift: fix typo in docstring --- swift/codegen/lib/schema/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/codegen/lib/schema/schema.py b/swift/codegen/lib/schema/schema.py index 3611b2336bd..94b4a2279ef 100644 --- a/swift/codegen/lib/schema/schema.py +++ b/swift/codegen/lib/schema/schema.py @@ -250,7 +250,7 @@ def _toposort_classes_by_group(classes: typing.Dict[str, Class]) -> typing.Dict[ def _fill_ipa_information(classes: typing.Dict[str, Class]): """ Take a dictionary where the `ipa` field is filled for all explicitly synthesized classes - and updated it so that all non-final classes that have only synthesized final descendants + and update it so that all non-final classes that have only synthesized final descendants get `True` as` value for the `ipa` field """ if not classes: From 2717b9a47df49f6eaae0b7671425598117a64130 Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 16 Nov 2022 17:58:24 +0000 Subject: [PATCH 323/796] Python: Extend import resolution tests Extends the tests to 1. Account parts of the test code that may be specific to Python 2 or 3, 2. Also track which arguments passed to `check` are references to modules. The latter revealed a bunch of spurious results, which I have annotated accordingly. --- .../import-resolution/importflow.ql | 70 +++++++++++++++++-- .../experimental/import-resolution/main.py | 14 ++-- .../package/subpackage/__init__.py | 2 +- 3 files changed, 72 insertions(+), 14 deletions(-) diff --git a/python/ql/test/experimental/import-resolution/importflow.ql b/python/ql/test/experimental/import-resolution/importflow.ql index 9439ffe0693..852ded243b3 100644 --- a/python/ql/test/experimental/import-resolution/importflow.ql +++ b/python/ql/test/experimental/import-resolution/importflow.ql @@ -2,7 +2,9 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.ApiGraphs import TestUtilities.InlineExpectationsTest +import semmle.python.dataflow.new.internal.ImportResolution +/** A string that appears on the right hand side of an assignment. */ private class SourceString extends DataFlow::Node { string contents; @@ -14,6 +16,45 @@ private class SourceString extends DataFlow::Node { string getContents() { result = contents } } +/** An argument that is checked using the `check` function. */ +private class CheckArgument extends DataFlow::Node { + CheckArgument() { this = API::moduleImport("trace").getMember("check").getACall().getArg(1) } +} + +/** A data-flow node that is a reference to a module. */ +private class ModuleRef extends DataFlow::Node { + Module mod; + + ModuleRef() { + this = ImportResolution::getModuleReference(mod) and + not mod.getName() in ["__future__", "trace"] + } + + string getName() { result = mod.getName() } +} + +/** + * A data-flow node that is guarded by a version check. Only supports checks of the form `if + *sys.version_info[0] == ...` where the right hand side is either `2` or `3`. + */ +private class VersionGuardedNode extends DataFlow::Node { + int version; + + VersionGuardedNode() { + version in [2, 3] and + exists(If parent, CompareNode c | parent.getBody().contains(this.asExpr()) | + c.operands(API::moduleImport("sys") + .getMember("version_info") + .getASubscript() + .asSource() + .asCfgNode(), any(Eq eq), + any(IntegerLiteral lit | lit.getValue() = version).getAFlowNode()) + ) + } + + int getVersion() { result = version } +} + private class ImportConfiguration extends DataFlow::Configuration { ImportConfiguration() { this = "ImportConfiguration" } @@ -30,12 +71,29 @@ class ResolutionTest extends InlineExpectationsTest { override string getARelevantTag() { result = "prints" } override predicate hasActualResult(Location location, string element, string tag, string value) { - exists(DataFlow::PathNode source, DataFlow::PathNode sink, ImportConfiguration config | - config.hasFlowPath(source, sink) and - tag = "prints" and - location = sink.getNode().getLocation() and - value = source.getNode().(SourceString).getContents() and - element = sink.getNode().toString() + ( + exists(DataFlow::PathNode source, DataFlow::PathNode sink, ImportConfiguration config | + config.hasFlowPath(source, sink) and + correct_version(sink.getNode()) and + tag = "prints" and + location = sink.getNode().getLocation() and + value = source.getNode().(SourceString).getContents() and + element = sink.getNode().toString() + ) + or + exists(ModuleRef ref | + correct_version(ref) and + ref instanceof CheckArgument and + tag = "prints" and + location = ref.getLocation() and + value = "\"\"" and + element = ref.toString() + ) ) } } + +private predicate correct_version(DataFlow::Node n) { + not n instanceof VersionGuardedNode or + n.(VersionGuardedNode).getVersion() = major_version() +} diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index d2ad1b9e337..aefe69f4d64 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -39,15 +39,15 @@ check("foo.bar_reexported.bar_attr", foo.bar_reexported.bar_attr, "bar_attr", gl # A simple "import from" statement. from bar import bar_attr -check("bar_attr", bar_attr, "bar_attr", globals()) #$ prints=bar_attr +check("bar_attr", bar_attr, "bar_attr", globals()) #$ prints=bar_attr SPURIOUS: prints="" # Importing an attribute from a subpackage of a package. from package.subpackage import subpackage_attr -check("subpackage_attr", subpackage_attr, "subpackage_attr", globals()) #$ prints=subpackage_attr +check("subpackage_attr", subpackage_attr, "subpackage_attr", globals()) #$ prints=subpackage_attr SPURIOUS: prints="" # Importing a package attribute under an alias. from package import package_attr as package_attr_alias -check("package_attr_alias", package_attr_alias, "package_attr", globals()) #$ prints=package_attr +check("package_attr_alias", package_attr_alias, "package_attr", globals()) #$ prints=package_attr SPURIOUS: prints="" # Importing a subpackage under an alias. from package import subpackage as aliased_subpackage #$ imports=package.subpackage.__init__ as=aliased_subpackage @@ -68,15 +68,15 @@ check("aliased_subpackage.subpackage_attr", aliased_subpackage.subpackage_attr, import package.subpackage #$ imports=package.__init__ as=package check("package.package_attr", package.package_attr, "package_attr", globals()) #$ prints=package_attr -if sys.version_info[0] >= 3: +if sys.version_info[0] == 3: # Importing from a namespace module. from namespace_package.namespace_module import namespace_module_attr - check("namespace_module_attr", namespace_module_attr, "namespace_module_attr", globals()) #$ prints=namespace_module_attr + check("namespace_module_attr", namespace_module_attr, "namespace_module_attr", globals()) #$ prints=namespace_module_attr SPURIOUS: prints="" from attr_clash import clashing_attr, non_clashing_submodule #$ imports=attr_clash.clashing_attr as=clashing_attr imports=attr_clash.non_clashing_submodule as=non_clashing_submodule -check("clashing_attr", clashing_attr, "clashing_attr", globals()) #$ prints=clashing_attr -check("non_clashing_submodule", non_clashing_submodule, "", globals()) +check("clashing_attr", clashing_attr, "clashing_attr", globals()) #$ prints=clashing_attr SPURIOUS: prints="" SPURIOUS: prints="" +check("non_clashing_submodule", non_clashing_submodule, "", globals()) #$ prints="" SPURIOUS: prints="" exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/package/subpackage/__init__.py b/python/ql/test/experimental/import-resolution/package/subpackage/__init__.py index 86cc92dd37b..387e0514fd1 100644 --- a/python/ql/test/experimental/import-resolution/package/subpackage/__init__.py +++ b/python/ql/test/experimental/import-resolution/package/subpackage/__init__.py @@ -5,7 +5,7 @@ subpackage_attr = "subpackage_attr" # Importing an attribute from the parent package. from .. import attr_used_in_subpackage as imported_attr -check("imported_attr", imported_attr, "attr_used_in_subpackage", globals()) #$ prints=attr_used_in_subpackage +check("imported_attr", imported_attr, "attr_used_in_subpackage", globals()) #$ prints=attr_used_in_subpackage SPURIOUS: prints="" # Importing an irrelevant attribute from a sibling module binds the name to the module. from .submodule import irrelevant_attr From 19261ecfbfdb6b1e1b42ffe76e9a72d48716ac32 Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 16 Nov 2022 18:19:54 +0000 Subject: [PATCH 324/796] Python: Remove spurious module references --- .../dataflow/new/internal/ImportResolution.qll | 2 -- .../ql/test/experimental/import-resolution/main.py | 12 ++++++------ .../import-resolution/package/subpackage/__init__.py | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll index 9e04d3f9681..ec4c87f560f 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -209,8 +209,6 @@ module ImportResolution { or result.asExpr() = any(ImportMember i | - i.getModule().(ImportExpr).getImportedModuleName() = module_name - or i.getModule().(ImportExpr).getImportedModuleName() + "." + i.getName() = module_name ) } diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index aefe69f4d64..cc634e41cc0 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -39,15 +39,15 @@ check("foo.bar_reexported.bar_attr", foo.bar_reexported.bar_attr, "bar_attr", gl # A simple "import from" statement. from bar import bar_attr -check("bar_attr", bar_attr, "bar_attr", globals()) #$ prints=bar_attr SPURIOUS: prints="" +check("bar_attr", bar_attr, "bar_attr", globals()) #$ prints=bar_attr # Importing an attribute from a subpackage of a package. from package.subpackage import subpackage_attr -check("subpackage_attr", subpackage_attr, "subpackage_attr", globals()) #$ prints=subpackage_attr SPURIOUS: prints="" +check("subpackage_attr", subpackage_attr, "subpackage_attr", globals()) #$ prints=subpackage_attr # Importing a package attribute under an alias. from package import package_attr as package_attr_alias -check("package_attr_alias", package_attr_alias, "package_attr", globals()) #$ prints=package_attr SPURIOUS: prints="" +check("package_attr_alias", package_attr_alias, "package_attr", globals()) #$ prints=package_attr # Importing a subpackage under an alias. from package import subpackage as aliased_subpackage #$ imports=package.subpackage.__init__ as=aliased_subpackage @@ -71,12 +71,12 @@ check("package.package_attr", package.package_attr, "package_attr", globals()) # if sys.version_info[0] == 3: # Importing from a namespace module. from namespace_package.namespace_module import namespace_module_attr - check("namespace_module_attr", namespace_module_attr, "namespace_module_attr", globals()) #$ prints=namespace_module_attr SPURIOUS: prints="" + check("namespace_module_attr", namespace_module_attr, "namespace_module_attr", globals()) #$ prints=namespace_module_attr from attr_clash import clashing_attr, non_clashing_submodule #$ imports=attr_clash.clashing_attr as=clashing_attr imports=attr_clash.non_clashing_submodule as=non_clashing_submodule -check("clashing_attr", clashing_attr, "clashing_attr", globals()) #$ prints=clashing_attr SPURIOUS: prints="" SPURIOUS: prints="" -check("non_clashing_submodule", non_clashing_submodule, "", globals()) #$ prints="" SPURIOUS: prints="" +check("clashing_attr", clashing_attr, "clashing_attr", globals()) #$ prints=clashing_attr SPURIOUS: prints="" +check("non_clashing_submodule", non_clashing_submodule, "", globals()) #$ prints="" exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/package/subpackage/__init__.py b/python/ql/test/experimental/import-resolution/package/subpackage/__init__.py index 387e0514fd1..86cc92dd37b 100644 --- a/python/ql/test/experimental/import-resolution/package/subpackage/__init__.py +++ b/python/ql/test/experimental/import-resolution/package/subpackage/__init__.py @@ -5,7 +5,7 @@ subpackage_attr = "subpackage_attr" # Importing an attribute from the parent package. from .. import attr_used_in_subpackage as imported_attr -check("imported_attr", imported_attr, "attr_used_in_subpackage", globals()) #$ prints=attr_used_in_subpackage SPURIOUS: prints="" +check("imported_attr", imported_attr, "attr_used_in_subpackage", globals()) #$ prints=attr_used_in_subpackage # Importing an irrelevant attribute from a sibling module binds the name to the module. from .submodule import irrelevant_attr From fc56c5a022bf56e962f7a9052313f253dcee603d Mon Sep 17 00:00:00 2001 From: tiferet Date: Wed, 16 Nov 2022 11:14:25 -0800 Subject: [PATCH 325/796] Implement the type-specific endpoint filters as EndpointCharacteristics. Also disambiguate three filters from three different sink types that all have the same name, "not a direct argument to a likely external library call or a heuristic sink". --- .../EndpointCharacteristics.qll | 309 ++++++++++++++++++ 1 file changed, 309 insertions(+) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index 19a982e2083..0999f59fb5b 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -10,6 +10,7 @@ private import semmle.javascript.security.dataflow.TaintedPathCustomizations private import CoreKnowledge as CoreKnowledge private import semmle.javascript.heuristics.SyntacticHeuristics private import semmle.javascript.filters.ClassifyFiles as ClassifyFiles +private import StandardEndpointFilters as StandardEndpointFilters /** * A set of characteristics that a particular endpoint might have. This set of characteristics is used to make decisions @@ -555,3 +556,311 @@ private class InIrrelevantFileCharacteristic extends StandardEndpointFilterChara this = "in " + category + " file" } } + +/** An EndpointFilterCharacteristic that indicates that an endpoint is unlikely to be a NoSQL injection sink. */ +abstract private class NosqlInjectionSinkEndpointFilterCharacteristic extends EndpointFilterCharacteristic { + bindingset[this] + NosqlInjectionSinkEndpointFilterCharacteristic() { any() } + + override predicate getImplications( + EndpointType endpointClass, boolean isPositiveIndicator, float confidence + ) { + endpointClass instanceof NosqlInjectionSinkType and + isPositiveIndicator = false and + confidence = mediumConfidence() + } +} + +private class DatabaseAccessCallHeuristicCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { + DatabaseAccessCallHeuristicCharacteristic() { this = "matches database access call heuristic" } + + override predicate getEndpoints(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + // additional databases accesses that aren't modeled yet + call.(DataFlow::MethodCallNode).getMethodName() = + ["create", "createCollection", "createIndexes"] + ) + } +} + +private class ModeledSinkCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { + ModeledSinkCharacteristic() { this = "modeled sink" } + + override predicate getEndpoints(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + // Remove modeled sinks + CoreKnowledge::isArgumentToKnownLibrarySinkFunction(n) + ) + } +} + +private class PredecessorInModeledFlowStepCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { + PredecessorInModeledFlowStepCharacteristic() { this = "predecessor in a modeled flow step" } + + override predicate getEndpoints(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + // Remove common kinds of unlikely sinks + CoreKnowledge::isKnownStepSrc(n) + ) + } +} + +private class ModeledDatabaseAccessCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { + ModeledDatabaseAccessCharacteristic() { this = "modeled database access" } + + override predicate getEndpoints(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + // Remove modeled database calls. Arguments to modeled calls are very likely to be modeled + // as sinks if they are true positives. Therefore arguments that are not modeled as sinks + // are unlikely to be true positives. + call instanceof DatabaseAccess + ) + } +} + +private class ReceiverIsHTTPRequestExpressionCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { + ReceiverIsHTTPRequestExpressionCharacteristic() { this = "receiver is a HTTP request expression" } + + override predicate getEndpoints(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + // Remove calls to APIs that aren't relevant to NoSQL injection + call.getReceiver() instanceof Http::RequestNode + ) + } +} + +private class ReceiverIsHTTPResponseExpressionCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { + ReceiverIsHTTPResponseExpressionCharacteristic() { + this = "receiver is a HTTP response expression" + } + + override predicate getEndpoints(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + // Remove calls to APIs that aren't relevant to NoSQL injection + call.getReceiver() instanceof Http::ResponseNode + ) + } +} + +private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkNosqlCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { + NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkNosqlCharacteristic() { + this = "not a direct argument to a likely external library call or a heuristic sink (nosql)" + } + + override predicate getEndpoints(DataFlow::Node n) { + // Require NoSQL injection sink candidates to be (a) direct arguments to external library calls + // or (b) heuristic sinks for NoSQL injection. + // + // ## Direct arguments to external library calls + // + // The `StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall` endpoint filter + // allows sink candidates which are within object literals or array literals, for example + // `req.sendFile(_, { path: ENDPOINT })`. + // + // However, the NoSQL injection query deals differently with these types of sinks compared to + // other security queries. Other security queries such as SQL injection tend to treat + // `ENDPOINT` as the ground truth sink, but the NoSQL injection query instead treats + // `{ path: ENDPOINT }` as the ground truth sink and defines an additional flow step to ensure + // data flows from `ENDPOINT` to the ground truth sink `{ path: ENDPOINT }`. + // + // Therefore for the NoSQL injection boosted query, we must ignore sink candidates within object + // literals or array literals, to avoid having multiple alerts for the same security + // vulnerability (one FP where the sink is `ENDPOINT` and one TP where the sink is + // `{ path: ENDPOINT }`). We accomplish this by directly testing that the sink candidate is an + // argument of a likely external library call. + // + // ## Heuristic sinks + // + // We also allow heuristic sinks in addition to direct arguments to external library calls. + // These are copied from the `HeuristicNosqlInjectionSink` class defined within + // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. + // We can't reuse the class because importing that file would cause us to treat these + // heuristic sinks as known sinks. + not n = StandardEndpointFilters::getALikelyExternalLibraryCall().getAnArgument() and + not ( + isAssignedToOrConcatenatedWith(n, "(?i)(nosql|query)") or + isArgTo(n, "(?i)(query)") + ) + } +} + +/** An EndpointFilterCharacteristic that indicates that an endpoint is unlikely to be a SQL injection sink. */ +abstract private class SqlInjectionSinkEndpointFilterCharacteristic extends EndpointFilterCharacteristic { + bindingset[this] + SqlInjectionSinkEndpointFilterCharacteristic() { any() } + + override predicate getImplications( + EndpointType endpointClass, boolean isPositiveIndicator, float confidence + ) { + endpointClass instanceof SqlInjectionSinkType and + isPositiveIndicator = false and + confidence = mediumConfidence() + } +} + +private class PreparedSQLStatementCharacteristic extends SqlInjectionSinkEndpointFilterCharacteristic { + PreparedSQLStatementCharacteristic() { this = "prepared SQL statement" } + + override predicate getEndpoints(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + // prepared statements for SQL + any(DataFlow::CallNode cn | cn.getCalleeName() = "prepare") + .getAMethodCall("run") + .getAnArgument() = n + ) + } +} + +private class ArrayCreationCharacteristic extends SqlInjectionSinkEndpointFilterCharacteristic { + ArrayCreationCharacteristic() { this = "array creation" } + + override predicate getEndpoints(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + n instanceof DataFlow::ArrayCreationNode + ) + } +} + +private class HTMLOrRenderingCharacteristic extends SqlInjectionSinkEndpointFilterCharacteristic { + HTMLOrRenderingCharacteristic() { this = "HTML / rendering" } + + override predicate getEndpoints(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + // UI is unrelated to SQL + call.getCalleeName().regexpMatch("(?i).*(render|html).*") + ) + } +} + +private class NotAnArgumentToLikelyExternalLibraryCallOrHeuristicSinkCharacteristic extends SqlInjectionSinkEndpointFilterCharacteristic { + NotAnArgumentToLikelyExternalLibraryCallOrHeuristicSinkCharacteristic() { + this = "not an argument to a likely external library call or a heuristic sink" + } + + override predicate getEndpoints(DataFlow::Node n) { + // Require SQL injection sink candidates to be (a) arguments to external library calls + // (possibly indirectly), or (b) heuristic sinks. + // + // Heuristic sinks are copied from the `HeuristicSqlInjectionSink` class defined within + // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. + // We can't reuse the class because importing that file would cause us to treat these + // heuristic sinks as known sinks. + not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(n) and + not ( + isAssignedToOrConcatenatedWith(n, "(?i)(sql|query)") or + isArgTo(n, "(?i)(query)") or + isConcatenatedWithString(n, + "(?s).*(ALTER|COUNT|CREATE|DATABASE|DELETE|DISTINCT|DROP|FROM|GROUP|INSERT|INTO|LIMIT|ORDER|SELECT|TABLE|UPDATE|WHERE).*") + ) + } +} + +/** An EndpointFilterCharacteristic that indicates that an endpoint is unlikely to be a tainted path injection sink. */ +abstract private class TaintedPathSinkEndpointFilterCharacteristic extends EndpointFilterCharacteristic { + bindingset[this] + TaintedPathSinkEndpointFilterCharacteristic() { any() } + + override predicate getImplications( + EndpointType endpointClass, boolean isPositiveIndicator, float confidence + ) { + endpointClass instanceof TaintedPathSinkType and + isPositiveIndicator = false and + confidence = mediumConfidence() + } +} + +private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkTaintedPathCharacteristic extends TaintedPathSinkEndpointFilterCharacteristic { + NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkTaintedPathCharacteristic() { + this = + "not a direct argument to a likely external library call or a heuristic sink (tainted path)" + } + + override predicate getEndpoints(DataFlow::Node n) { + // Require path injection sink candidates to be (a) arguments to external library calls + // (possibly indirectly), or (b) heuristic sinks. + // + // Heuristic sinks are mostly copied from the `HeuristicTaintedPathSink` class defined within + // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. + // We can't reuse the class because importing that file would cause us to treat these + // heuristic sinks as known sinks. + not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(n) and + not ( + isAssignedToOrConcatenatedWith(n, "(?i)(file|folder|dir|absolute)") + or + isArgTo(n, "(?i)(get|read)file") + or + exists(string pathPattern | + // paths with at least two parts, and either a trailing or leading slash + pathPattern = "(?i)([a-z0-9_.-]+/){2,}" or + pathPattern = "(?i)(/[a-z0-9_.-]+){2,}" + | + isConcatenatedWithString(n, pathPattern) + ) + or + isConcatenatedWithStrings(".*/", n, "/.*") + or + // In addition to the names from `HeuristicTaintedPathSink` in the + // `isAssignedToOrConcatenatedWith` predicate call above, we also allow the noisier "path" + // name. + isAssignedToOrConcatenatedWith(n, "(?i)path") + ) + } +} + +/** An EndpointFilterCharacteristic that indicates that an endpoint is unlikely to be an XSS sink. */ +abstract private class XssSinkEndpointFilterCharacteristic extends EndpointFilterCharacteristic { + bindingset[this] + XssSinkEndpointFilterCharacteristic() { any() } + + override predicate getImplications( + EndpointType endpointClass, boolean isPositiveIndicator, float confidence + ) { + endpointClass instanceof XssSinkType and + isPositiveIndicator = false and + confidence = mediumConfidence() + } +} + +private class SetStateCallsInReactApplicationsCharacteristic extends XssSinkEndpointFilterCharacteristic { + SetStateCallsInReactApplicationsCharacteristic() { + this = "setState calls ought to be safe in react applications" + } + + override predicate getEndpoints(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | call.getCalleeName() = "setState") + } +} + +private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkXssCharacteristic extends XssSinkEndpointFilterCharacteristic { + NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkXssCharacteristic() { + this = "not a direct argument to a likely external library call or a heuristic sink (XSS)" + } + + override predicate getEndpoints(DataFlow::Node n) { + // Require XSS sink candidates to be (a) arguments to external library calls (possibly + // indirectly), or (b) heuristic sinks. + // + // Heuristic sinks are copied from the `HeuristicDomBasedXssSink` class defined within + // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. + // We can't reuse the class because importing that file would cause us to treat these + // heuristic sinks as known sinks. + not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(n) and + not ( + isAssignedToOrConcatenatedWith(n, "(?i)(html|innerhtml)") + or + isArgTo(n, "(?i)(html|render)") + or + n instanceof StringOps::HtmlConcatenationLeaf + or + isConcatenatedWithStrings("(?is).*<[a-z ]+.*", n, "(?s).*>.*") + or + // In addition to the heuristic sinks from `HeuristicDomBasedXssSink`, explicitly allow + // property writes like `elem.innerHTML = ` that may not be picked up as HTML + // concatenation leaves. + exists(DataFlow::PropWrite pw | + pw.getPropertyName().regexpMatch("(?i).*html*") and + pw.getRhs() = n + ) + ) + } +} From de2ebe3618d34d33ef09dfcb1190a70230085c6f Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 16 Nov 2022 16:25:01 +0100 Subject: [PATCH 326/796] QL: fix the same QLDoc being QLDoc for multiple things --- ql/ql/src/codeql_ql/ast/Ast.qll | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll index fd7e416f291..fe81ccae7fe 100644 --- a/ql/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/ql/src/codeql_ql/ast/Ast.qll @@ -156,13 +156,22 @@ class TopLevel extends TTopLevel, AstNode { } QLDoc getQLDocFor(ModuleMember m) { - exists(int i | result = this.getMember(i) and m = this.getMember(i + 1)) + exists(int i | result = this.getMember(i) and m = this.getMember(i + 1)) and + ( + m instanceof ClasslessPredicate + or + m instanceof Class + or + m instanceof Module + ) } override string getAPrimaryQlClass() { result = "TopLevel" } override QLDoc getQLDoc() { result = this.getMember(0) and + // it's not the QLDoc for a module member + not this.getQLDocFor(_) = result and result.getLocation().getStartLine() = 1 // this might not hold if there is a block comment above, and that's the point. } } From eab270eb8499eedb134c3263a44b0812b1d9358c Mon Sep 17 00:00:00 2001 From: tiferet Date: Wed, 16 Nov 2022 11:47:24 -0800 Subject: [PATCH 327/796] Move the definitions of `isEffectiveSink` and `getAReasonSinkExcluded` to the base class. They can now be implemented generically for all sink types. --- .../adaptivethreatmodeling/ATMConfig.qll | 25 +++++- .../NosqlInjectionATM.qll | 79 ------------------- .../SqlInjectionATM.qll | 54 ------------- .../StandardEndpointFilters.qll | 10 +-- .../adaptivethreatmodeling/TaintedPathATM.qll | 53 ------------- .../adaptivethreatmodeling/XssATM.qll | 54 ------------- .../modelbuilding/DebugResultInclusion.ql | 12 ++- .../ExtractEndpointDataTraining.qll | 8 +- .../endpoint_large_scale/EndpointFeatures.ql | 8 +- .../FilteredTruePositives.ql | 8 +- ...ql_endpoint_filter_ignores_modeled_apis.ql | 2 +- 11 files changed, 44 insertions(+), 269 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index 55d75ad2e4d..0ca7260f12a 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -6,7 +6,7 @@ private import javascript as JS import EndpointTypes -import EndpointCharacteristics +import EndpointCharacteristics as EndpointCharacteristics /** * EXPERIMENTAL. This API may change in the future. @@ -48,7 +48,7 @@ abstract class AtmConfig extends string { final predicate isKnownSink(JS::DataFlow::Node sink) { // If the list of characteristics includes positive indicators with maximal confidence for this class, then it's a // known sink for the class. - exists(EndpointCharacteristic characteristic | + exists(EndpointCharacteristics::EndpointCharacteristic characteristic | characteristic.getEndpoints(sink) and characteristic .getImplications(this.getASinkEndpointType(), true, characteristic.maximalConfidence()) @@ -69,7 +69,26 @@ abstract class AtmConfig extends string { * Holds if the candidate sink `candidateSink` predicted by the machine learning model should be * an effective sink, i.e. one considered as a possible sink of flow in the boosted query. */ - predicate isEffectiveSink(JS::DataFlow::Node candidateSink) { none() } + final predicate isEffectiveSink(JS::DataFlow::Node candidateSink) { + not exists(getAReasonSinkExcluded(candidateSink)) + } + + final EndpointCharacteristics::EndpointCharacteristic getAReasonSinkExcluded( + JS::DataFlow::Node candidateSink + ) { + // An endpoint is an effective sink if it has neither standard endpoint filter characteristics nor endpoint filter + // characteristics that are specific to this sink type. + exists(EndpointCharacteristics::StandardEndpointFilterCharacteristic standardFilter | + standardFilter.getEndpoints(candidateSink) and + result = standardFilter + ) + or + exists(EndpointCharacteristics::EndpointFilterCharacteristic specificFilter | + specificFilter.getEndpoints(candidateSink) and + specificFilter.getImplications(getASinkEndpointType(), false, _) and + result = specificFilter + ) + } /** * EXPERIMENTAL. This API may change in the future. diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll index 43d74d5334c..0548cdb66b8 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll @@ -11,81 +11,6 @@ import AdaptiveThreatModeling private import CoreKnowledge as CoreKnowledge private import StandardEndpointFilters as StandardEndpointFilters -module SinkEndpointFilter { - /** - * Provides a set of reasons why a given data flow node should be excluded as a sink candidate. - * - * If this predicate has no results for a sink candidate `n`, then we should treat `n` as an - * effective sink. - */ - string getAReasonSinkExcluded(DataFlow::Node sinkCandidate) { - result = StandardEndpointFilters::getAReasonSinkExcluded(sinkCandidate) - or - exists(DataFlow::CallNode call | sinkCandidate = call.getAnArgument() | - // additional databases accesses that aren't modeled yet - call.(DataFlow::MethodCallNode).getMethodName() = - ["create", "createCollection", "createIndexes"] and - result = "matches database access call heuristic" - or - // Remove modeled sinks - CoreKnowledge::isArgumentToKnownLibrarySinkFunction(sinkCandidate) and - result = "modeled sink" - or - // Remove common kinds of unlikely sinks - CoreKnowledge::isKnownStepSrc(sinkCandidate) and - result = "predecessor in a modeled flow step" - or - // Remove modeled database calls. Arguments to modeled calls are very likely to be modeled - // as sinks if they are true positives. Therefore arguments that are not modeled as sinks - // are unlikely to be true positives. - call instanceof DatabaseAccess and - result = "modeled database access" - or - // Remove calls to APIs that aren't relevant to NoSQL injection - call.getReceiver() instanceof Http::RequestNode and - result = "receiver is a HTTP request expression" - or - call.getReceiver() instanceof Http::ResponseNode and - result = "receiver is a HTTP response expression" - ) - or - // Require NoSQL injection sink candidates to be (a) direct arguments to external library calls - // or (b) heuristic sinks for NoSQL injection. - // - // ## Direct arguments to external library calls - // - // The `StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall` endpoint filter - // allows sink candidates which are within object literals or array literals, for example - // `req.sendFile(_, { path: ENDPOINT })`. - // - // However, the NoSQL injection query deals differently with these types of sinks compared to - // other security queries. Other security queries such as SQL injection tend to treat - // `ENDPOINT` as the ground truth sink, but the NoSQL injection query instead treats - // `{ path: ENDPOINT }` as the ground truth sink and defines an additional flow step to ensure - // data flows from `ENDPOINT` to the ground truth sink `{ path: ENDPOINT }`. - // - // Therefore for the NoSQL injection boosted query, we must ignore sink candidates within object - // literals or array literals, to avoid having multiple alerts for the same security - // vulnerability (one FP where the sink is `ENDPOINT` and one TP where the sink is - // `{ path: ENDPOINT }`). We accomplish this by directly testing that the sink candidate is an - // argument of a likely external library call. - // - // ## Heuristic sinks - // - // We also allow heuristic sinks in addition to direct arguments to external library calls. - // These are copied from the `HeuristicNosqlInjectionSink` class defined within - // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. - // We can't reuse the class because importing that file would cause us to treat these - // heuristic sinks as known sinks. - not sinkCandidate = StandardEndpointFilters::getALikelyExternalLibraryCall().getAnArgument() and - not ( - isAssignedToOrConcatenatedWith(sinkCandidate, "(?i)(nosql|query)") or - isArgTo(sinkCandidate, "(?i)(query)") - ) and - result = "not a direct argument to a likely external library call or a heuristic sink" - } -} - class NosqlInjectionAtmConfig extends AtmConfig { NosqlInjectionAtmConfig() { this = "NosqlInjectionATMConfig" } @@ -93,10 +18,6 @@ class NosqlInjectionAtmConfig extends AtmConfig { source instanceof NosqlInjection::Source or TaintedObject::isSource(source, _) } - override predicate isEffectiveSink(DataFlow::Node sinkCandidate) { - not exists(SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate)) - } - override EndpointType getASinkEndpointType() { result instanceof NosqlInjectionSinkType } } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll index 3c78a456f21..2d7cdca5f83 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll @@ -10,65 +10,11 @@ import AdaptiveThreatModeling import CoreKnowledge as CoreKnowledge import StandardEndpointFilters as StandardEndpointFilters -/** - * This module provides logic to filter candidate sinks to those which are likely SQL injection - * sinks. - */ -module SinkEndpointFilter { - private import javascript - private import SQL - - /** - * Provides a set of reasons why a given data flow node should be excluded as a sink candidate. - * - * If this predicate has no results for a sink candidate `n`, then we should treat `n` as an - * effective sink. - */ - string getAReasonSinkExcluded(DataFlow::Node sinkCandidate) { - result = StandardEndpointFilters::getAReasonSinkExcluded(sinkCandidate) - or - exists(DataFlow::CallNode call | sinkCandidate = call.getAnArgument() | - // prepared statements for SQL - any(DataFlow::CallNode cn | cn.getCalleeName() = "prepare") - .getAMethodCall("run") - .getAnArgument() = sinkCandidate and - result = "prepared SQL statement" - or - sinkCandidate instanceof DataFlow::ArrayCreationNode and - result = "array creation" - or - // UI is unrelated to SQL - call.getCalleeName().regexpMatch("(?i).*(render|html).*") and - result = "HTML / rendering" - ) - or - // Require SQL injection sink candidates to be (a) arguments to external library calls - // (possibly indirectly), or (b) heuristic sinks. - // - // Heuristic sinks are copied from the `HeuristicSqlInjectionSink` class defined within - // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. - // We can't reuse the class because importing that file would cause us to treat these - // heuristic sinks as known sinks. - not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(sinkCandidate) and - not ( - isAssignedToOrConcatenatedWith(sinkCandidate, "(?i)(sql|query)") or - isArgTo(sinkCandidate, "(?i)(query)") or - isConcatenatedWithString(sinkCandidate, - "(?s).*(ALTER|COUNT|CREATE|DATABASE|DELETE|DISTINCT|DROP|FROM|GROUP|INSERT|INTO|LIMIT|ORDER|SELECT|TABLE|UPDATE|WHERE).*") - ) and - result = "not an argument to a likely external library call or a heuristic sink" - } -} - class SqlInjectionAtmConfig extends AtmConfig { SqlInjectionAtmConfig() { this = "SqlInjectionATMConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof SqlInjection::Source } - override predicate isEffectiveSink(DataFlow::Node sinkCandidate) { - not exists(SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate)) - } - override EndpointType getASinkEndpointType() { result instanceof SqlInjectionSinkType } } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll index 3ed0a8fde4c..11041937a3a 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll @@ -12,14 +12,6 @@ private import semmle.javascript.heuristics.SyntacticHeuristics private import CoreKnowledge as CoreKnowledge import EndpointCharacteristics as EndpointCharacteristics -/** Provides a set of reasons why a given data flow node should be excluded as a sink candidate. */ -string getAReasonSinkExcluded(DataFlow::Node n) { - exists(EndpointCharacteristics::StandardEndpointFilterCharacteristic characteristic | - characteristic.getEndpoints(n) and - result = characteristic - ) -} - /** * Holds if the node `n` is an argument to a function that has a manual model. */ @@ -77,7 +69,7 @@ private DataFlow::SourceNode getACallback(DataFlow::ParameterNode p, DataFlow::T * Get calls for which we do not have the callee (i.e. the definition of the called function). This * acts as a heuristic for identifying calls to external library functions. */ -private DataFlow::CallNode getACallWithoutCallee() { +DataFlow::CallNode getACallWithoutCallee() { forall(Function callee | callee = result.getACallee() | callee.getTopLevel().isExterns()) and not exists(DataFlow::ParameterNode param, DataFlow::FunctionNode callback | param.flowsTo(result.getCalleeNode()) and diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll index 8b0ce249f89..1e5d3408405 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll @@ -10,64 +10,11 @@ import AdaptiveThreatModeling import CoreKnowledge as CoreKnowledge import StandardEndpointFilters as StandardEndpointFilters -/** - * This module provides logic to filter candidate sinks to those which are likely path injection - * sinks. - */ -module SinkEndpointFilter { - private import javascript - private import TaintedPath - - /** - * Provides a set of reasons why a given data flow node should be excluded as a sink candidate. - * - * If this predicate has no results for a sink candidate `n`, then we should treat `n` as an - * effective sink. - */ - string getAReasonSinkExcluded(DataFlow::Node sinkCandidate) { - result = StandardEndpointFilters::getAReasonSinkExcluded(sinkCandidate) - or - // Require path injection sink candidates to be (a) arguments to external library calls - // (possibly indirectly), or (b) heuristic sinks. - // - // Heuristic sinks are mostly copied from the `HeuristicTaintedPathSink` class defined within - // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. - // We can't reuse the class because importing that file would cause us to treat these - // heuristic sinks as known sinks. - not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(sinkCandidate) and - not ( - isAssignedToOrConcatenatedWith(sinkCandidate, "(?i)(file|folder|dir|absolute)") - or - isArgTo(sinkCandidate, "(?i)(get|read)file") - or - exists(string pathPattern | - // paths with at least two parts, and either a trailing or leading slash - pathPattern = "(?i)([a-z0-9_.-]+/){2,}" or - pathPattern = "(?i)(/[a-z0-9_.-]+){2,}" - | - isConcatenatedWithString(sinkCandidate, pathPattern) - ) - or - isConcatenatedWithStrings(".*/", sinkCandidate, "/.*") - or - // In addition to the names from `HeuristicTaintedPathSink` in the - // `isAssignedToOrConcatenatedWith` predicate call above, we also allow the noisier "path" - // name. - isAssignedToOrConcatenatedWith(sinkCandidate, "(?i)path") - ) and - result = "not a direct argument to a likely external library call or a heuristic sink" - } -} - class TaintedPathAtmConfig extends AtmConfig { TaintedPathAtmConfig() { this = "TaintedPathATMConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof TaintedPath::Source } - override predicate isEffectiveSink(DataFlow::Node sinkCandidate) { - not exists(SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate)) - } - override EndpointType getASinkEndpointType() { result instanceof TaintedPathSinkType } } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll index cdd49ca302e..64b4b65207b 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll @@ -10,65 +10,11 @@ import AdaptiveThreatModeling import CoreKnowledge as CoreKnowledge import StandardEndpointFilters as StandardEndpointFilters -/** - * This module provides logic to filter candidate sinks to those which are likely XSS sinks. - */ -module SinkEndpointFilter { - private import javascript - private import DomBasedXss - - /** - * Provides a set of reasons why a given data flow node should be excluded as a sink candidate. - * - * If this predicate has no results for a sink candidate `n`, then we should treat `n` as an - * effective sink. - */ - string getAReasonSinkExcluded(DataFlow::Node sinkCandidate) { - result = StandardEndpointFilters::getAReasonSinkExcluded(sinkCandidate) - or - exists(DataFlow::CallNode call | sinkCandidate = call.getAnArgument() | - call.getCalleeName() = "setState" - ) and - result = "setState calls ought to be safe in react applications" - or - // Require XSS sink candidates to be (a) arguments to external library calls (possibly - // indirectly), or (b) heuristic sinks. - // - // Heuristic sinks are copied from the `HeuristicDomBasedXssSink` class defined within - // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. - // We can't reuse the class because importing that file would cause us to treat these - // heuristic sinks as known sinks. - not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(sinkCandidate) and - not ( - isAssignedToOrConcatenatedWith(sinkCandidate, "(?i)(html|innerhtml)") - or - isArgTo(sinkCandidate, "(?i)(html|render)") - or - sinkCandidate instanceof StringOps::HtmlConcatenationLeaf - or - isConcatenatedWithStrings("(?is).*<[a-z ]+.*", sinkCandidate, "(?s).*>.*") - or - // In addition to the heuristic sinks from `HeuristicDomBasedXssSink`, explicitly allow - // property writes like `elem.innerHTML = ` that may not be picked up as HTML - // concatenation leaves. - exists(DataFlow::PropWrite pw | - pw.getPropertyName().regexpMatch("(?i).*html*") and - pw.getRhs() = sinkCandidate - ) - ) and - result = "not a direct argument to a likely external library call or a heuristic sink" - } -} - class DomBasedXssAtmConfig extends AtmConfig { DomBasedXssAtmConfig() { this = "DomBasedXssATMConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof DomBasedXss::Source } - override predicate isEffectiveSink(DataFlow::Node sinkCandidate) { - not exists(SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate)) - } - override EndpointType getASinkEndpointType() { result instanceof XssSinkType } } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql index c5654e86a12..444f682304d 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql @@ -12,19 +12,23 @@ import javascript import experimental.adaptivethreatmodeling.ATMConfig import extraction.ExtractEndpointDataTraining +private import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm +private import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm +private import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm +private import experimental.adaptivethreatmodeling.XssATM as XssAtm string getAReasonSinkExcluded(DataFlow::Node sinkCandidate, Query query) { query instanceof NosqlInjectionQuery and - result = NosqlInjectionAtm::SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate) + result = any(NosqlInjectionAtm::NosqlInjectionAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) or query instanceof SqlInjectionQuery and - result = SqlInjectionAtm::SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate) + result = any(SqlInjectionAtm::SqlInjectionAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) or query instanceof TaintedPathQuery and - result = TaintedPathAtm::SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate) + result = any(TaintedPathAtm::TaintedPathAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) or query instanceof XssQuery and - result = XssAtm::SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate) + result = any(XssAtm::DomBasedXssAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) } pragma[inline] diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll index a379be6be70..16b6acdb84d 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll @@ -10,10 +10,10 @@ import experimental.adaptivethreatmodeling.EndpointFeatures as EndpointFeatures import NoFeaturizationRestrictionsConfig private import Exclusions as Exclusions import Queries -import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm -import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm -import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm -import experimental.adaptivethreatmodeling.XssATM as XssAtm +private import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm +private import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm +private import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm +private import experimental.adaptivethreatmodeling.XssATM as XssAtm /** * Gets the set of featureName-featureValue pairs for each endpoint in the training set. diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql index 9985625d85c..6c1d88443d0 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql @@ -17,10 +17,10 @@ import extraction.NoFeaturizationRestrictionsConfig query predicate tokenFeatures(DataFlow::Node endpoint, string featureName, string featureValue) { ( - not exists(NosqlInjectionAtm::SinkEndpointFilter::getAReasonSinkExcluded(endpoint)) or - not exists(SqlInjectionAtm::SinkEndpointFilter::getAReasonSinkExcluded(endpoint)) or - not exists(TaintedPathAtm::SinkEndpointFilter::getAReasonSinkExcluded(endpoint)) or - not exists(XssAtm::SinkEndpointFilter::getAReasonSinkExcluded(endpoint)) or + not exists(any(NosqlInjectionAtm::NosqlInjectionAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or + not exists(any(SqlInjectionAtm::SqlInjectionAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or + not exists(any(TaintedPathAtm::TaintedPathAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or + not exists(any(XssAtm::DomBasedXssAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or StandardEndpointFilters::isArgumentToModeledFunction(endpoint) ) and EndpointFeatures::tokenFeatures(endpoint, featureName, featureValue) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql index 8ae82446403..f56bda6e2d4 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql @@ -24,24 +24,24 @@ import experimental.adaptivethreatmodeling.XssATM as XssAtm query predicate nosqlFilteredTruePositives(DataFlow::Node endpoint, string reason) { endpoint instanceof NosqlInjection::Sink and - reason = NosqlInjectionAtm::SinkEndpointFilter::getAReasonSinkExcluded(endpoint) and + reason = any(NosqlInjectionAtm::NosqlInjectionAtmConfig cfg).getAReasonSinkExcluded(endpoint) and not reason = ["argument to modeled function", "modeled sink", "modeled database access"] } query predicate sqlFilteredTruePositives(DataFlow::Node endpoint, string reason) { endpoint instanceof SqlInjection::Sink and - reason = SqlInjectionAtm::SinkEndpointFilter::getAReasonSinkExcluded(endpoint) and + reason = any(SqlInjectionAtm::SqlInjectionAtmConfig cfg).getAReasonSinkExcluded(endpoint) and reason != "argument to modeled function" } query predicate taintedPathFilteredTruePositives(DataFlow::Node endpoint, string reason) { endpoint instanceof TaintedPath::Sink and - reason = TaintedPathAtm::SinkEndpointFilter::getAReasonSinkExcluded(endpoint) and + reason = any(TaintedPathAtm::TaintedPathAtmConfig cfg).getAReasonSinkExcluded(endpoint) and reason != "argument to modeled function" } query predicate xssFilteredTruePositives(DataFlow::Node endpoint, string reason) { endpoint instanceof DomBasedXss::Sink and - reason = XssAtm::SinkEndpointFilter::getAReasonSinkExcluded(endpoint) and + reason = any(XssAtm::DomBasedXssAtmConfig cfg).getAReasonSinkExcluded(endpoint) and reason != "argument to modeled function" } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/modeled_apis/nosql_endpoint_filter_ignores_modeled_apis.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/modeled_apis/nosql_endpoint_filter_ignores_modeled_apis.ql index 9a81ce73d91..a1d06d2881d 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/modeled_apis/nosql_endpoint_filter_ignores_modeled_apis.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/modeled_apis/nosql_endpoint_filter_ignores_modeled_apis.ql @@ -2,5 +2,5 @@ import javascript import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm query predicate effectiveSinks(DataFlow::Node node) { - not exists(NosqlInjectionAtm::SinkEndpointFilter::getAReasonSinkExcluded(node)) + not exists(any(NosqlInjectionAtm::NosqlInjectionAtmConfig cfg).getAReasonSinkExcluded(node)) } From 0fd013f9fd83d74e0fb443708c7d999957fda99c Mon Sep 17 00:00:00 2001 From: tiferet Date: Wed, 16 Nov 2022 11:54:10 -0800 Subject: [PATCH 328/796] Update the reason names in `FilteredTruePositives.expected`. This is needed because we changed the names of three endpoint filters that were all called "not a direct argument to a likely external library call or a heuristic sink" in order to disambiguate them (fc56c5a022bf56e962f7a9052313f253dcee603d). --- .../EndpointCharacteristics.qll | 2 +- .../FilteredTruePositives.expected | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index 0999f59fb5b..06fd6954f3a 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -833,7 +833,7 @@ private class SetStateCallsInReactApplicationsCharacteristic extends XssSinkEndp private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkXssCharacteristic extends XssSinkEndpointFilterCharacteristic { NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkXssCharacteristic() { - this = "not a direct argument to a likely external library call or a heuristic sink (XSS)" + this = "not a direct argument to a likely external library call or a heuristic sink (xss)" } override predicate getEndpoints(DataFlow::Node n) { diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.expected b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.expected index 46abea4045f..cb29a7ee955 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.expected +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.expected @@ -1,16 +1,16 @@ nosqlFilteredTruePositives -| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:111:14:111:18 | query | not a direct argument to a likely external library call or a heuristic sink | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:111:14:111:18 | query | not a direct argument to a likely external library call or a heuristic sink (nosql) | sqlFilteredTruePositives | autogenerated/NosqlAndSqlInjection/untyped/tst2.js:7:13:7:45 | select ... e id = | not an argument to a likely external library call or a heuristic sink | | autogenerated/NosqlAndSqlInjection/untyped/tst2.js:7:48:7:60 | req.params.id | not an argument to a likely external library call or a heuristic sink | taintedPathFilteredTruePositives -| autogenerated/TaintedPath/TaintedPath.js:66:26:66:31 | "SAFE" | not a direct argument to a likely external library call or a heuristic sink | -| autogenerated/TaintedPath/TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | not a direct argument to a likely external library call or a heuristic sink | +| autogenerated/TaintedPath/TaintedPath.js:66:26:66:31 | "SAFE" | not a direct argument to a likely external library call or a heuristic sink (tainted path) | +| autogenerated/TaintedPath/TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | not a direct argument to a likely external library call or a heuristic sink (tainted path) | xssFilteredTruePositives -| autogenerated/Xss/DomBasedXss/d3.js:12:20:12:29 | getTaint() | not a direct argument to a likely external library call or a heuristic sink | -| autogenerated/Xss/DomBasedXss/d3.js:14:20:14:29 | getTaint() | not a direct argument to a likely external library call or a heuristic sink | -| autogenerated/Xss/DomBasedXss/express.js:7:15:7:33 | req.param("wobble") | not a direct argument to a likely external library call or a heuristic sink | -| autogenerated/Xss/DomBasedXss/jwt-server.js:11:19:11:29 | decoded.foo | not a direct argument to a likely external library call or a heuristic sink | -| autogenerated/Xss/DomBasedXss/tst.js:316:35:316:42 | location | not a direct argument to a likely external library call or a heuristic sink | -| autogenerated/Xss/DomBasedXss/typeahead.js:10:16:10:18 | loc | not a direct argument to a likely external library call or a heuristic sink | -| autogenerated/Xss/DomBasedXss/typeahead.js:25:18:25:20 | val | not a direct argument to a likely external library call or a heuristic sink | +| autogenerated/Xss/DomBasedXss/d3.js:12:20:12:29 | getTaint() | not a direct argument to a likely external library call or a heuristic sink (xss) | +| autogenerated/Xss/DomBasedXss/d3.js:14:20:14:29 | getTaint() | not a direct argument to a likely external library call or a heuristic sink (xss) | +| autogenerated/Xss/DomBasedXss/express.js:7:15:7:33 | req.param("wobble") | not a direct argument to a likely external library call or a heuristic sink (xss) | +| autogenerated/Xss/DomBasedXss/jwt-server.js:11:19:11:29 | decoded.foo | not a direct argument to a likely external library call or a heuristic sink (xss) | +| autogenerated/Xss/DomBasedXss/tst.js:316:35:316:42 | location | not a direct argument to a likely external library call or a heuristic sink (xss) | +| autogenerated/Xss/DomBasedXss/typeahead.js:10:16:10:18 | loc | not a direct argument to a likely external library call or a heuristic sink (xss) | +| autogenerated/Xss/DomBasedXss/typeahead.js:25:18:25:20 | val | not a direct argument to a likely external library call or a heuristic sink (xss) | From c2035e85d2bef276a8da5d84e88e390fa1ceaf9c Mon Sep 17 00:00:00 2001 From: tiferet Date: Wed, 16 Nov 2022 11:55:23 -0800 Subject: [PATCH 329/796] Be explicit in requiring that each ATM config set its endpoint type. --- .../lib/experimental/adaptivethreatmodeling/ATMConfig.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index 0ca7260f12a..571673639ee 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -104,7 +104,7 @@ abstract class AtmConfig extends string { * Get an endpoint type for the sinks of this query. A query may have multiple applicable * endpoint types for its sinks. */ - EndpointType getASinkEndpointType() { none() } + abstract EndpointType getASinkEndpointType(); /** * EXPERIMENTAL. This API may change in the future. From 81348049df420816e122792b754c260f535bcc87 Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 16 Nov 2022 19:58:32 +0000 Subject: [PATCH 330/796] Python: Fix missing module resolution This was due to bad manual magic: restricting the attribute name makes sense when we're talking about submodules of a package, but it doesn't when we're talking about reexported modules. Also (hopefully) fixes the tests so that the Python 3-specific bits are ignored under Python 2. --- .../new/internal/ImportResolution.qll | 9 +++-- .../import-resolution/importflow.ql | 33 ++++++++++++++++--- .../experimental/import-resolution/main.py | 5 +-- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll index ec4c87f560f..53f41bd945e 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -235,9 +235,12 @@ module ImportResolution { result = ar | isPreferredModuleForName(m.getFile(), p.getPackageName() + "." + attr_name + ["", ".__init__"]) - or - // This is also true for attributes that come from reexports. - module_reexport(p, attr_name, m) + ) + or + // This is also true for attributes that come from reexports. + exists(Module reexporter, string attr_name | + result.(DataFlow::AttrRead).accesses(getModuleReference(reexporter), attr_name) and + module_reexport(reexporter, attr_name, m) ) or // Submodules that are implicitly defined with relative imports of the form `from .foo import ...`. diff --git a/python/ql/test/experimental/import-resolution/importflow.ql b/python/ql/test/experimental/import-resolution/importflow.ql index 852ded243b3..4d60594bbfa 100644 --- a/python/ql/test/experimental/import-resolution/importflow.ql +++ b/python/ql/test/experimental/import-resolution/importflow.ql @@ -74,7 +74,7 @@ class ResolutionTest extends InlineExpectationsTest { ( exists(DataFlow::PathNode source, DataFlow::PathNode sink, ImportConfiguration config | config.hasFlowPath(source, sink) and - correct_version(sink.getNode()) and + not sink.getNode() instanceof VersionGuardedNode and tag = "prints" and location = sink.getNode().getLocation() and value = source.getNode().(SourceString).getContents() and @@ -82,7 +82,7 @@ class ResolutionTest extends InlineExpectationsTest { ) or exists(ModuleRef ref | - correct_version(ref) and + not ref instanceof VersionGuardedNode and ref instanceof CheckArgument and tag = "prints" and location = ref.getLocation() and @@ -93,7 +93,30 @@ class ResolutionTest extends InlineExpectationsTest { } } -private predicate correct_version(DataFlow::Node n) { - not n instanceof VersionGuardedNode or - n.(VersionGuardedNode).getVersion() = major_version() +class ResolutionTest3 extends InlineExpectationsTest { + ResolutionTest3() { this = "ResolutionTest3" } + + override string getARelevantTag() { result = "prints3" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + ( + exists(DataFlow::PathNode source, DataFlow::PathNode sink, ImportConfiguration config | + config.hasFlowPath(source, sink) and + sink.getNode().(VersionGuardedNode).getVersion() = 3 and + tag = "prints3" and + location = sink.getNode().getLocation() and + value = source.getNode().(SourceString).getContents() and + element = sink.getNode().toString() + ) + or + exists(ModuleRef ref | + ref.(VersionGuardedNode).getVersion() = 3 and + ref instanceof CheckArgument and + tag = "prints3" and + location = ref.getLocation() and + value = "\"\"" and + element = ref.toString() + ) + ) + } } diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index cc634e41cc0..27c6ffff7c1 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -35,7 +35,8 @@ import foo as foo_alias #$ imports=foo as=foo_alias check("foo_alias.foo_attr", foo_alias.foo_attr, "foo_attr", globals()) #$ prints=foo_attr # A reference to a reexported module -check("foo.bar_reexported.bar_attr", foo.bar_reexported.bar_attr, "bar_attr", globals()) #$ MISSING: prints=bar_attr +check("foo.bar_reexported", foo.bar_reexported, "", globals()) #$ prints="" +check("foo.bar_reexported.bar_attr", foo.bar_reexported.bar_attr, "bar_attr", globals()) #$ prints=bar_attr # A simple "import from" statement. from bar import bar_attr @@ -71,7 +72,7 @@ check("package.package_attr", package.package_attr, "package_attr", globals()) # if sys.version_info[0] == 3: # Importing from a namespace module. from namespace_package.namespace_module import namespace_module_attr - check("namespace_module_attr", namespace_module_attr, "namespace_module_attr", globals()) #$ prints=namespace_module_attr + check("namespace_module_attr", namespace_module_attr, "namespace_module_attr", globals()) #$ prints3=namespace_module_attr from attr_clash import clashing_attr, non_clashing_submodule #$ imports=attr_clash.clashing_attr as=clashing_attr imports=attr_clash.non_clashing_submodule as=non_clashing_submodule From 8fee9cb0d5e68d7adc51ad8c5013c0a17cf70ef1 Mon Sep 17 00:00:00 2001 From: tiferet Date: Wed, 16 Nov 2022 12:06:52 -0800 Subject: [PATCH 331/796] Fix CodeQL warnings --- .../adaptivethreatmodeling/ATMConfig.qll | 4 ++-- .../EndpointCharacteristics.qll | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index 571673639ee..ab0b936544e 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -70,7 +70,7 @@ abstract class AtmConfig extends string { * an effective sink, i.e. one considered as a possible sink of flow in the boosted query. */ final predicate isEffectiveSink(JS::DataFlow::Node candidateSink) { - not exists(getAReasonSinkExcluded(candidateSink)) + not exists(this.getAReasonSinkExcluded(candidateSink)) } final EndpointCharacteristics::EndpointCharacteristic getAReasonSinkExcluded( @@ -85,7 +85,7 @@ abstract class AtmConfig extends string { or exists(EndpointCharacteristics::EndpointFilterCharacteristic specificFilter | specificFilter.getEndpoints(candidateSink) and - specificFilter.getImplications(getASinkEndpointType(), false, _) and + specificFilter.getImplications(this.getASinkEndpointType(), false, _) and result = specificFilter ) } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index 06fd6954f3a..5218f65b337 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -618,8 +618,8 @@ private class ModeledDatabaseAccessCharacteristic extends NosqlInjectionSinkEndp } } -private class ReceiverIsHTTPRequestExpressionCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { - ReceiverIsHTTPRequestExpressionCharacteristic() { this = "receiver is a HTTP request expression" } +private class ReceiverIsHttpRequestExpressionCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { + ReceiverIsHttpRequestExpressionCharacteristic() { this = "receiver is a HTTP request expression" } override predicate getEndpoints(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | @@ -629,8 +629,8 @@ private class ReceiverIsHTTPRequestExpressionCharacteristic extends NosqlInjecti } } -private class ReceiverIsHTTPResponseExpressionCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { - ReceiverIsHTTPResponseExpressionCharacteristic() { +private class ReceiverIsHttpResponseExpressionCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { + ReceiverIsHttpResponseExpressionCharacteristic() { this = "receiver is a HTTP response expression" } @@ -698,8 +698,8 @@ abstract private class SqlInjectionSinkEndpointFilterCharacteristic extends Endp } } -private class PreparedSQLStatementCharacteristic extends SqlInjectionSinkEndpointFilterCharacteristic { - PreparedSQLStatementCharacteristic() { this = "prepared SQL statement" } +private class PreparedSqlStatementCharacteristic extends SqlInjectionSinkEndpointFilterCharacteristic { + PreparedSqlStatementCharacteristic() { this = "prepared SQL statement" } override predicate getEndpoints(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | @@ -721,8 +721,8 @@ private class ArrayCreationCharacteristic extends SqlInjectionSinkEndpointFilter } } -private class HTMLOrRenderingCharacteristic extends SqlInjectionSinkEndpointFilterCharacteristic { - HTMLOrRenderingCharacteristic() { this = "HTML / rendering" } +private class HtmlOrRenderingCharacteristic extends SqlInjectionSinkEndpointFilterCharacteristic { + HtmlOrRenderingCharacteristic() { this = "HTML / rendering" } override predicate getEndpoints(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | From 38c40a7192068fb8b49c84e0333a16c5fe62e514 Mon Sep 17 00:00:00 2001 From: tiferet Date: Wed, 16 Nov 2022 12:12:50 -0800 Subject: [PATCH 332/796] `isEffectiveSink` can't be final because `ExtractMisclassifiedEndpointFeatures` overrides it. --- .../lib/experimental/adaptivethreatmodeling/ATMConfig.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index ab0b936544e..67b702745ef 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -69,7 +69,7 @@ abstract class AtmConfig extends string { * Holds if the candidate sink `candidateSink` predicted by the machine learning model should be * an effective sink, i.e. one considered as a possible sink of flow in the boosted query. */ - final predicate isEffectiveSink(JS::DataFlow::Node candidateSink) { + predicate isEffectiveSink(JS::DataFlow::Node candidateSink) { not exists(this.getAReasonSinkExcluded(candidateSink)) } From ccbf1ca2a9f6850335001889328b04d1f31ca037 Mon Sep 17 00:00:00 2001 From: tiferet Date: Wed, 16 Nov 2022 13:05:06 -0800 Subject: [PATCH 333/796] Add a comment --- .../lib/experimental/adaptivethreatmodeling/ATMConfig.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index 67b702745ef..bce5a3172d6 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -78,6 +78,8 @@ abstract class AtmConfig extends string { ) { // An endpoint is an effective sink if it has neither standard endpoint filter characteristics nor endpoint filter // characteristics that are specific to this sink type. + // TODO: Experiment with excluding all endpoints that have a medium- or high-confidence characteristic that implies + // they're not sinks for this sink type (or not sinks for any sink type), not just the EndpointFilterCharacteristics. exists(EndpointCharacteristics::StandardEndpointFilterCharacteristic standardFilter | standardFilter.getEndpoints(candidateSink) and result = standardFilter From 4a1382925e34c01a57448dedd6e44795f362ee6e Mon Sep 17 00:00:00 2001 From: tiferet Date: Wed, 16 Nov 2022 14:01:16 -0800 Subject: [PATCH 334/796] Remove some imports that are no longer used --- .../experimental/adaptivethreatmodeling/NosqlInjectionATM.qll | 1 - .../lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll | 1 - .../lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll | 1 - .../lib/experimental/adaptivethreatmodeling/XssATM.qll | 1 - .../test/endpoint_large_scale/FilteredTruePositives.ql | 1 - 5 files changed, 5 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll index 0548cdb66b8..85b3d14d7e9 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll @@ -9,7 +9,6 @@ private import semmle.javascript.heuristics.SyntacticHeuristics private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations import AdaptiveThreatModeling private import CoreKnowledge as CoreKnowledge -private import StandardEndpointFilters as StandardEndpointFilters class NosqlInjectionAtmConfig extends AtmConfig { NosqlInjectionAtmConfig() { this = "NosqlInjectionATMConfig" } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll index 2d7cdca5f83..f52e1898667 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll @@ -8,7 +8,6 @@ import semmle.javascript.heuristics.SyntacticHeuristics import semmle.javascript.security.dataflow.SqlInjectionCustomizations import AdaptiveThreatModeling import CoreKnowledge as CoreKnowledge -import StandardEndpointFilters as StandardEndpointFilters class SqlInjectionAtmConfig extends AtmConfig { SqlInjectionAtmConfig() { this = "SqlInjectionATMConfig" } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll index 1e5d3408405..e83938071df 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll @@ -8,7 +8,6 @@ import semmle.javascript.heuristics.SyntacticHeuristics import semmle.javascript.security.dataflow.TaintedPathCustomizations import AdaptiveThreatModeling import CoreKnowledge as CoreKnowledge -import StandardEndpointFilters as StandardEndpointFilters class TaintedPathAtmConfig extends AtmConfig { TaintedPathAtmConfig() { this = "TaintedPathATMConfig" } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll index 64b4b65207b..508cac4544f 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll @@ -8,7 +8,6 @@ private import semmle.javascript.heuristics.SyntacticHeuristics private import semmle.javascript.security.dataflow.DomBasedXssCustomizations import AdaptiveThreatModeling import CoreKnowledge as CoreKnowledge -import StandardEndpointFilters as StandardEndpointFilters class DomBasedXssAtmConfig extends AtmConfig { DomBasedXssAtmConfig() { this = "DomBasedXssATMConfig" } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql index f56bda6e2d4..d8de88e3454 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql @@ -16,7 +16,6 @@ import semmle.javascript.security.dataflow.NosqlInjectionCustomizations import semmle.javascript.security.dataflow.SqlInjectionCustomizations import semmle.javascript.security.dataflow.TaintedPathCustomizations import semmle.javascript.security.dataflow.DomBasedXssCustomizations -import experimental.adaptivethreatmodeling.StandardEndpointFilters as StandardEndpointFilters import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm From 8ed8161d5c4b00d959861e831293bfe4d95e908d Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 16 Nov 2022 22:20:08 +0000 Subject: [PATCH 335/796] Python: Fix tests for Python 2 This should make it so that the `prints3` tag is skipped when running then Python 2 Language tests. --- python/ql/test/experimental/import-resolution/importflow.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/test/experimental/import-resolution/importflow.ql b/python/ql/test/experimental/import-resolution/importflow.ql index 4d60594bbfa..6160560a3ee 100644 --- a/python/ql/test/experimental/import-resolution/importflow.ql +++ b/python/ql/test/experimental/import-resolution/importflow.ql @@ -96,7 +96,7 @@ class ResolutionTest extends InlineExpectationsTest { class ResolutionTest3 extends InlineExpectationsTest { ResolutionTest3() { this = "ResolutionTest3" } - override string getARelevantTag() { result = "prints3" } + override string getARelevantTag() { result = "prints3" and major_version() = 3 } override predicate hasActualResult(Location location, string element, string tag, string value) { ( From 49f476d3b4f3bd22a11eecbc131a1b77bd2b9034 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Wed, 16 Nov 2022 23:53:07 +0100 Subject: [PATCH 336/796] Update javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll Co-authored-by: Erik Krogh Kristensen --- javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll index 46bbb624839..f38740a490d 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll @@ -29,11 +29,8 @@ module Hapi { or // `const after = function (server) {...};` // `server.dependency('name', after);` - exists(ServerDefinition server, DataFlow::MethodCallNode call | - call = server.ref().getAMethodCall() and - call.getMethodName() = "dependency" and - this = call.getABoundCallbackParameter(1, 0) - ) + this = + any(ServerDefinition s).ref().getAMethodCall("dependency").getABoundCallbackParameter(1, 0) } } From f24fa402f362101d10e89803b8569a07ea823586 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 17 Nov 2022 08:18:20 +0100 Subject: [PATCH 337/796] Adjust CFG --- .../lib/codeql/ruby/controlflow/CfgNodes.qll | 42 +++++++++++++++++-- .../ruby/controlflow/internal/Completion.qll | 16 +++---- .../internal/ControlFlowGraphImpl.qll | 2 + .../ruby/controlflow/internal/Splitting.qll | 3 -- .../controlflow/graph/Cfg.expected | 16 ++++--- .../barrier-guards/barrier-guards.expected | 40 ++++++++++++++---- 6 files changed, 88 insertions(+), 31 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll b/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll index b411c766f03..5007acf4e31 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll @@ -432,8 +432,36 @@ module ExprNodes { final ExprCfgNode getBody() { e.hasCfgChild(e.getBody(), this, result) } } - private class WhenClauseChildMapping extends NonExprChildMapping, WhenClause { - override predicate relevantChild(AstNode e) { e = [this.getBody(), this.getAPattern()] } + // `when` clauses need special treatment, since they are neither pre-order + // nor post-order + private class WhenClauseChildMapping extends WhenClause { + predicate patternReachesBasicBlock(int i, CfgNode cfnPattern, BasicBlock bb) { + exists(Expr pattern | + pattern = this.getPattern(i) and + cfnPattern.getNode() = pattern and + bb.getANode() = cfnPattern + ) + or + exists(BasicBlock mid | + this.patternReachesBasicBlock(i, cfnPattern, mid) and + bb = mid.getASuccessor() and + not mid.getANode().getNode() = this + ) + } + + predicate bodyReachesBasicBlock(CfgNode cfnBody, BasicBlock bb) { + exists(Stmt body | + body = this.getBody() and + cfnBody.getNode() = body and + bb.getANode() = cfnBody + ) + or + exists(BasicBlock mid | + this.bodyReachesBasicBlock(cfnBody, mid) and + bb = mid.getAPredecessor() and + not mid.getANode().getNode() = this + ) + } } /** A control-flow node that wraps a `WhenClause` AST expression. */ @@ -443,10 +471,16 @@ module ExprNodes { override WhenClauseChildMapping e; /** Gets the body of this `when`-clause. */ - final ExprCfgNode getBody() { e.hasCfgChild(e.getBody(), this, result) } + final ExprCfgNode getBody() { + result.getNode() = desugar(e.getBody()) and + e.bodyReachesBasicBlock(result, this.getBasicBlock()) + } /** Gets the `i`th pattern this `when`-clause. */ - final ExprCfgNode getPattern(int i) { result.getExpr() = e.getPattern(i) } + final ExprCfgNode getPattern(int i) { + result.getNode() = desugar(e.getPattern(i)) and + e.patternReachesBasicBlock(i, result, this.getBasicBlock()) + } } /** A control-flow node that wraps a `CasePattern`. */ diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll index d727b99d6cf..26e62e0c077 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll @@ -211,8 +211,11 @@ private predicate inBooleanContext(AstNode n) { or exists(CaseExpr c, WhenClause w | not exists(c.getValue()) and - c.getABranch() = w and + c.getABranch() = w + | w.getPattern(_) = n + or + w = n ) } @@ -233,12 +236,11 @@ private predicate inMatchingContext(AstNode n) { or exists(CaseExpr c, WhenClause w | exists(c.getValue()) and - ( - c.getABranch() = w and - w.getPattern(_) = n - or - w = n - ) + c.getABranch() = w + | + w.getPattern(_) = n + or + w = n ) or n instanceof CasePattern diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll index 1ca24d43ab8..a8bd2e3feac 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll @@ -402,6 +402,7 @@ module Trees { exists(int i, WhenTree branch | branch = this.getBranch(i) | pred = branch and first(this.getBranch(i + 1), succ) and + c.isValidFor(branch) and c.(ConditionalCompletion).getValue() = false ) or @@ -1411,6 +1412,7 @@ module Trees { final override predicate last(AstNode last, Completion c) { last = this and + c.isValidFor(this) and c.(ConditionalCompletion).getValue() = false or last(this.getBody(), last, c) and diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/Splitting.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/Splitting.qll index 5e24616ac4a..a048e2d4044 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/internal/Splitting.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/Splitting.qll @@ -85,12 +85,9 @@ private module ConditionalCompletionSplitting { or last(succ.(ConditionalExpr).getBranch(_), pred, c) and completion = c - or - last(succ.(WhenClause).getAPattern(), pred, c) and completion = c ) or succ(pred, succ, c) and - succ(succ, _, completion) and succ instanceof WhenClause and completion = c } diff --git a/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected b/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected index 69e4cc294de..9b60a403a30 100644 --- a/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -1916,16 +1916,15 @@ cfg.rb: # 48| [false] when ... #-----| false -> b -# 48| when ... -#-----| match -> self -#-----| no-match -> b +# 48| [true] when ... +#-----| true -> self # 48| b #-----| -> 1 # 48| ... == ... #-----| false -> [false] when ... -#-----| true -> when ... +#-----| true -> [true] when ... # 48| 1 #-----| -> ... == ... @@ -1948,15 +1947,14 @@ cfg.rb: # 49| [false] when ... #-----| false -> case ... -# 49| when ... -#-----| no-match -> case ... -#-----| match -> self +# 49| [true] when ... +#-----| true -> self # 49| b #-----| -> 0 # 49| ... == ... -#-----| true -> when ... +#-----| true -> [true] when ... #-----| false -> b # 49| 0 @@ -1967,7 +1965,7 @@ cfg.rb: # 49| ... > ... #-----| false -> [false] when ... -#-----| true -> when ... +#-----| true -> [true] when ... # 49| 1 #-----| -> ... > ... diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected index 7804824ffb6..c308ce9d820 100644 --- a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected @@ -262,21 +262,45 @@ controls | barrier-guards.rb:227:4:227:21 | [true] ... and ... | barrier-guards.rb:228:5:228:7 | self | true | | barrier-guards.rb:227:21:227:21 | call to y | barrier-guards.rb:227:4:227:21 | [true] ... and ... | true | | barrier-guards.rb:227:21:227:21 | call to y | barrier-guards.rb:228:5:228:7 | self | true | -| barrier-guards.rb:232:1:233:19 | when ... | barrier-guards.rb:233:5:233:7 | foo | match | +| barrier-guards.rb:232:1:233:19 | [true] when ... | barrier-guards.rb:233:5:233:7 | foo | true | | barrier-guards.rb:232:6:232:17 | ... == ... | barrier-guards.rb:232:1:233:19 | [false] when ... | false | -| barrier-guards.rb:232:6:232:17 | ... == ... | barrier-guards.rb:232:1:233:19 | when ... | true | +| barrier-guards.rb:232:6:232:17 | ... == ... | barrier-guards.rb:232:1:233:19 | [true] when ... | true | | barrier-guards.rb:232:6:232:17 | ... == ... | barrier-guards.rb:233:5:233:7 | foo | true | -| barrier-guards.rb:237:1:237:38 | when ... | barrier-guards.rb:237:24:237:26 | foo | match | +| barrier-guards.rb:237:1:237:38 | [false] when ... | barrier-guards.rb:238:1:238:26 | [false] when ... | false | +| barrier-guards.rb:237:1:237:38 | [false] when ... | barrier-guards.rb:238:1:238:26 | [true] when ... | false | +| barrier-guards.rb:237:1:237:38 | [false] when ... | barrier-guards.rb:238:6:238:8 | self | false | +| barrier-guards.rb:237:1:237:38 | [false] when ... | barrier-guards.rb:238:24:238:26 | foo | false | +| barrier-guards.rb:237:1:237:38 | [false] when ... | barrier-guards.rb:239:1:239:22 | [false] when ... | false | +| barrier-guards.rb:237:1:237:38 | [false] when ... | barrier-guards.rb:239:1:239:22 | [true] when ... | false | +| barrier-guards.rb:237:1:237:38 | [false] when ... | barrier-guards.rb:239:6:239:8 | foo | false | +| barrier-guards.rb:237:1:237:38 | [false] when ... | barrier-guards.rb:239:20:239:22 | foo | false | +| barrier-guards.rb:237:1:237:38 | [true] when ... | barrier-guards.rb:237:24:237:26 | foo | true | | barrier-guards.rb:237:6:237:17 | ... == ... | barrier-guards.rb:237:1:237:38 | [false] when ... | false | -| barrier-guards.rb:237:6:237:17 | ... == ... | barrier-guards.rb:237:1:237:38 | when ... | true | +| barrier-guards.rb:237:6:237:17 | ... == ... | barrier-guards.rb:237:1:237:38 | [true] when ... | true | | barrier-guards.rb:237:6:237:17 | ... == ... | barrier-guards.rb:237:24:237:26 | foo | true | -| barrier-guards.rb:238:1:238:26 | when ... | barrier-guards.rb:238:24:238:26 | foo | match | +| barrier-guards.rb:237:6:237:17 | ... == ... | barrier-guards.rb:238:1:238:26 | [false] when ... | false | +| barrier-guards.rb:237:6:237:17 | ... == ... | barrier-guards.rb:238:1:238:26 | [true] when ... | false | +| barrier-guards.rb:237:6:237:17 | ... == ... | barrier-guards.rb:238:6:238:8 | self | false | +| barrier-guards.rb:237:6:237:17 | ... == ... | barrier-guards.rb:238:24:238:26 | foo | false | +| barrier-guards.rb:237:6:237:17 | ... == ... | barrier-guards.rb:239:1:239:22 | [false] when ... | false | +| barrier-guards.rb:237:6:237:17 | ... == ... | barrier-guards.rb:239:1:239:22 | [true] when ... | false | +| barrier-guards.rb:237:6:237:17 | ... == ... | barrier-guards.rb:239:6:239:8 | foo | false | +| barrier-guards.rb:237:6:237:17 | ... == ... | barrier-guards.rb:239:20:239:22 | foo | false | +| barrier-guards.rb:238:1:238:26 | [false] when ... | barrier-guards.rb:239:1:239:22 | [false] when ... | false | +| barrier-guards.rb:238:1:238:26 | [false] when ... | barrier-guards.rb:239:1:239:22 | [true] when ... | false | +| barrier-guards.rb:238:1:238:26 | [false] when ... | barrier-guards.rb:239:6:239:8 | foo | false | +| barrier-guards.rb:238:1:238:26 | [false] when ... | barrier-guards.rb:239:20:239:22 | foo | false | +| barrier-guards.rb:238:1:238:26 | [true] when ... | barrier-guards.rb:238:24:238:26 | foo | true | | barrier-guards.rb:238:6:238:17 | ... == ... | barrier-guards.rb:238:1:238:26 | [false] when ... | false | -| barrier-guards.rb:238:6:238:17 | ... == ... | barrier-guards.rb:238:1:238:26 | when ... | true | +| barrier-guards.rb:238:6:238:17 | ... == ... | barrier-guards.rb:238:1:238:26 | [true] when ... | true | | barrier-guards.rb:238:6:238:17 | ... == ... | barrier-guards.rb:238:24:238:26 | foo | true | -| barrier-guards.rb:239:1:239:22 | when ... | barrier-guards.rb:239:20:239:22 | foo | match | +| barrier-guards.rb:238:6:238:17 | ... == ... | barrier-guards.rb:239:1:239:22 | [false] when ... | false | +| barrier-guards.rb:238:6:238:17 | ... == ... | barrier-guards.rb:239:1:239:22 | [true] when ... | false | +| barrier-guards.rb:238:6:238:17 | ... == ... | barrier-guards.rb:239:6:239:8 | foo | false | +| barrier-guards.rb:238:6:238:17 | ... == ... | barrier-guards.rb:239:20:239:22 | foo | false | +| barrier-guards.rb:239:1:239:22 | [true] when ... | barrier-guards.rb:239:20:239:22 | foo | true | | barrier-guards.rb:239:6:239:13 | ... == ... | barrier-guards.rb:239:1:239:22 | [false] when ... | false | -| barrier-guards.rb:239:6:239:13 | ... == ... | barrier-guards.rb:239:1:239:22 | when ... | true | +| barrier-guards.rb:239:6:239:13 | ... == ... | barrier-guards.rb:239:1:239:22 | [true] when ... | true | | barrier-guards.rb:239:6:239:13 | ... == ... | barrier-guards.rb:239:20:239:22 | foo | true | | barrier-guards.rb:243:4:243:8 | "foo" | barrier-guards.rb:244:5:244:7 | foo | match | | barrier-guards.rb:243:4:243:8 | "foo" | barrier-guards.rb:245:1:246:7 | in ... then ... | no-match | From 5ab77600b862b1e041059a1df4e0764ff32ef853 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 17 Nov 2022 10:44:23 +0100 Subject: [PATCH 338/796] C++: Update auto-builder nuget packages --- .../Semmle.Autobuild.Cpp.Tests.csproj | 5 +++-- .../Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/Semmle.Autobuild.Cpp.Tests.csproj b/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/Semmle.Autobuild.Cpp.Tests.csproj index dc1d945521b..421ffdd96f4 100644 --- a/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/Semmle.Autobuild.Cpp.Tests.csproj +++ b/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/Semmle.Autobuild.Cpp.Tests.csproj @@ -11,11 +11,12 @@ - - + + all runtime; build; native; contentfiles; analyzers + diff --git a/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj b/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj index e417622707a..83ec5dde7cf 100644 --- a/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj +++ b/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj @@ -17,7 +17,7 @@ - + From 780297152c46c858a31c924b43da7641c56748a2 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 17 Nov 2022 11:00:25 +0100 Subject: [PATCH 339/796] C#: Downgrade `Microsoft.Build` nuget package 17.4.0 does not officially support .NET 6 (it supports .NET 7), so downgrade to avoid warnings. --- .../Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj | 2 +- .../Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj | 2 +- .../Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj | 2 +- .../Semmle.Extraction.CSharp.Standalone.csproj | 2 +- .../Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj b/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj index 83ec5dde7cf..393d4141ab9 100644 --- a/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj +++ b/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj @@ -17,7 +17,7 @@ - + diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj b/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj index d05daec1de0..ec2aae685e8 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj @@ -14,7 +14,7 @@ - + diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj b/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj index f76a28f6a0b..6aceac93f97 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj @@ -11,7 +11,7 @@ - + diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj index c02999c9acd..09a36029f13 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj @@ -19,7 +19,7 @@ - + diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj b/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj index 02d1e96558d..6ef0e4aa1ce 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj +++ b/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj @@ -19,6 +19,6 @@ - + \ No newline at end of file From 9f13cdadcb6233677a3609de8445a87d72b0ba96 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 17 Nov 2022 13:42:30 +0100 Subject: [PATCH 340/796] C#: Add use-use stress test --- .../dataflow/local/DataFlowStep.expected | 1601 +++++++++++++++ .../dataflow/local/TaintTrackingStep.expected | 1801 +++++++++++++++++ .../dataflow/local/UseUseExplosion.cs | 29 + .../library-tests/dataflow/ssa-large/Large.cs | 2 +- 4 files changed, 3432 insertions(+), 1 deletion(-) create mode 100644 csharp/ql/test/library-tests/dataflow/local/UseUseExplosion.cs diff --git a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected index ad28e92e626..afb49ad2bce 100644 --- a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -832,3 +832,1604 @@ | Splitting.cs:57:17:57:17 | [b (line 46): true] access to local variable y | Splitting.cs:58:27:58:27 | [b (line 46): true] access to local variable y | | Splitting.cs:58:22:58:22 | [b (line 46): false] SSA def(s) | Splitting.cs:59:19:59:19 | [b (line 46): false] access to local variable s | | Splitting.cs:58:22:58:22 | [b (line 46): true] SSA def(s) | Splitting.cs:59:19:59:19 | [b (line 46): true] access to local variable s | +| UseUseExplosion.cs:21:10:21:10 | SSA entry def(this.Prop) | UseUseExplosion.cs:24:13:24:16 | access to property Prop | +| UseUseExplosion.cs:21:10:21:10 | this | UseUseExplosion.cs:24:13:24:16 | this access | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1712:24:1712 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1727:24:1727 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1742:24:1742 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1757:24:1757 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1772:24:1772 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1787:24:1787 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1802:24:1802 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1817:24:1817 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1832:24:1832 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1847:24:1847 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1862:24:1862 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1877:24:1877 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1892:24:1892 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1907:24:1907 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1922:24:1922 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1937:24:1937 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1952:24:1952 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1967:24:1967 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1982:24:1982 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1997:24:1997 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2012:24:2012 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2027:24:2027 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2042:24:2042 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2057:24:2057 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2072:24:2072 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2087:24:2087 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2102:24:2102 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2117:24:2117 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2132:24:2132 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2147:24:2147 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2162:24:2162 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2177:24:2177 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2192:24:2192 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2207:24:2207 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2222:24:2222 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2237:24:2237 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2252:24:2252 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2267:24:2267 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2282:24:2282 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2297:24:2297 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2312:24:2312 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2327:24:2327 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2342:24:2342 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2357:24:2357 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2372:24:2372 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2387:24:2387 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2402:24:2402 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2417:24:2417 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2432:24:2432 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2447:24:2447 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2462:24:2462 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2477:24:2477 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2492:24:2492 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2507:24:2507 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2522:24:2522 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2537:24:2537 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2552:24:2552 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2567:24:2567 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2582:24:2582 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2597:24:2597 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2612:24:2612 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2627:24:2627 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2642:24:2642 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2657:24:2657 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2672:24:2672 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2687:24:2687 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2702:24:2702 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2717:24:2717 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2732:24:2732 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2747:24:2747 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2762:24:2762 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2777:24:2777 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2792:24:2792 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2807:24:2807 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2822:24:2822 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2837:24:2837 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2852:24:2852 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2867:24:2867 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2882:24:2882 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2897:24:2897 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2912:24:2912 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2927:24:2927 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2942:24:2942 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2957:24:2957 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2972:24:2972 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2987:24:2987 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3002:24:3002 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3017:24:3017 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3032:24:3032 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3047:24:3047 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3062:24:3062 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3077:24:3077 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3092:24:3092 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3107:24:3107 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3122:24:3122 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3137:24:3137 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3152:24:3152 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3167:24:3167 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3182:24:3182 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3197:24:3197 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:23:17:23:17 | 0 | UseUseExplosion.cs:23:13:23:17 | SSA def(x) | +| UseUseExplosion.cs:24:13:24:16 | [post] this access | UseUseExplosion.cs:24:31:24:34 | this access | +| UseUseExplosion.cs:24:13:24:16 | [post] this access | UseUseExplosion.cs:24:3193:24:3198 | this access | +| UseUseExplosion.cs:24:13:24:16 | access to property Prop | UseUseExplosion.cs:24:31:24:34 | access to property Prop | +| UseUseExplosion.cs:24:13:24:16 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:13:24:16 | this access | UseUseExplosion.cs:24:31:24:34 | this access | +| UseUseExplosion.cs:24:13:24:16 | this access | UseUseExplosion.cs:24:3193:24:3198 | this access | +| UseUseExplosion.cs:24:31:24:34 | [post] this access | UseUseExplosion.cs:24:48:24:51 | this access | +| UseUseExplosion.cs:24:31:24:34 | [post] this access | UseUseExplosion.cs:24:3178:24:3183 | this access | +| UseUseExplosion.cs:24:31:24:34 | access to property Prop | UseUseExplosion.cs:24:48:24:51 | access to property Prop | +| UseUseExplosion.cs:24:31:24:34 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:31:24:34 | this access | UseUseExplosion.cs:24:48:24:51 | this access | +| UseUseExplosion.cs:24:31:24:34 | this access | UseUseExplosion.cs:24:3178:24:3183 | this access | +| UseUseExplosion.cs:24:48:24:51 | [post] this access | UseUseExplosion.cs:24:65:24:68 | this access | +| UseUseExplosion.cs:24:48:24:51 | [post] this access | UseUseExplosion.cs:24:3163:24:3168 | this access | +| UseUseExplosion.cs:24:48:24:51 | access to property Prop | UseUseExplosion.cs:24:65:24:68 | access to property Prop | +| UseUseExplosion.cs:24:48:24:51 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:48:24:51 | this access | UseUseExplosion.cs:24:65:24:68 | this access | +| UseUseExplosion.cs:24:48:24:51 | this access | UseUseExplosion.cs:24:3163:24:3168 | this access | +| UseUseExplosion.cs:24:65:24:68 | [post] this access | UseUseExplosion.cs:24:82:24:85 | this access | +| UseUseExplosion.cs:24:65:24:68 | [post] this access | UseUseExplosion.cs:24:3148:24:3153 | this access | +| UseUseExplosion.cs:24:65:24:68 | access to property Prop | UseUseExplosion.cs:24:82:24:85 | access to property Prop | +| UseUseExplosion.cs:24:65:24:68 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:65:24:68 | this access | UseUseExplosion.cs:24:82:24:85 | this access | +| UseUseExplosion.cs:24:65:24:68 | this access | UseUseExplosion.cs:24:3148:24:3153 | this access | +| UseUseExplosion.cs:24:82:24:85 | [post] this access | UseUseExplosion.cs:24:99:24:102 | this access | +| UseUseExplosion.cs:24:82:24:85 | [post] this access | UseUseExplosion.cs:24:3133:24:3138 | this access | +| UseUseExplosion.cs:24:82:24:85 | access to property Prop | UseUseExplosion.cs:24:99:24:102 | access to property Prop | +| UseUseExplosion.cs:24:82:24:85 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:82:24:85 | this access | UseUseExplosion.cs:24:99:24:102 | this access | +| UseUseExplosion.cs:24:82:24:85 | this access | UseUseExplosion.cs:24:3133:24:3138 | this access | +| UseUseExplosion.cs:24:99:24:102 | [post] this access | UseUseExplosion.cs:24:116:24:119 | this access | +| UseUseExplosion.cs:24:99:24:102 | [post] this access | UseUseExplosion.cs:24:3118:24:3123 | this access | +| UseUseExplosion.cs:24:99:24:102 | access to property Prop | UseUseExplosion.cs:24:116:24:119 | access to property Prop | +| UseUseExplosion.cs:24:99:24:102 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:99:24:102 | this access | UseUseExplosion.cs:24:116:24:119 | this access | +| UseUseExplosion.cs:24:99:24:102 | this access | UseUseExplosion.cs:24:3118:24:3123 | this access | +| UseUseExplosion.cs:24:116:24:119 | [post] this access | UseUseExplosion.cs:24:133:24:136 | this access | +| UseUseExplosion.cs:24:116:24:119 | [post] this access | UseUseExplosion.cs:24:3103:24:3108 | this access | +| UseUseExplosion.cs:24:116:24:119 | access to property Prop | UseUseExplosion.cs:24:133:24:136 | access to property Prop | +| UseUseExplosion.cs:24:116:24:119 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:116:24:119 | this access | UseUseExplosion.cs:24:133:24:136 | this access | +| UseUseExplosion.cs:24:116:24:119 | this access | UseUseExplosion.cs:24:3103:24:3108 | this access | +| UseUseExplosion.cs:24:133:24:136 | [post] this access | UseUseExplosion.cs:24:150:24:153 | this access | +| UseUseExplosion.cs:24:133:24:136 | [post] this access | UseUseExplosion.cs:24:3088:24:3093 | this access | +| UseUseExplosion.cs:24:133:24:136 | access to property Prop | UseUseExplosion.cs:24:150:24:153 | access to property Prop | +| UseUseExplosion.cs:24:133:24:136 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:133:24:136 | this access | UseUseExplosion.cs:24:150:24:153 | this access | +| UseUseExplosion.cs:24:133:24:136 | this access | UseUseExplosion.cs:24:3088:24:3093 | this access | +| UseUseExplosion.cs:24:150:24:153 | [post] this access | UseUseExplosion.cs:24:167:24:170 | this access | +| UseUseExplosion.cs:24:150:24:153 | [post] this access | UseUseExplosion.cs:24:3073:24:3078 | this access | +| UseUseExplosion.cs:24:150:24:153 | access to property Prop | UseUseExplosion.cs:24:167:24:170 | access to property Prop | +| UseUseExplosion.cs:24:150:24:153 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:150:24:153 | this access | UseUseExplosion.cs:24:167:24:170 | this access | +| UseUseExplosion.cs:24:150:24:153 | this access | UseUseExplosion.cs:24:3073:24:3078 | this access | +| UseUseExplosion.cs:24:167:24:170 | [post] this access | UseUseExplosion.cs:24:184:24:187 | this access | +| UseUseExplosion.cs:24:167:24:170 | [post] this access | UseUseExplosion.cs:24:3058:24:3063 | this access | +| UseUseExplosion.cs:24:167:24:170 | access to property Prop | UseUseExplosion.cs:24:184:24:187 | access to property Prop | +| UseUseExplosion.cs:24:167:24:170 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:167:24:170 | this access | UseUseExplosion.cs:24:184:24:187 | this access | +| UseUseExplosion.cs:24:167:24:170 | this access | UseUseExplosion.cs:24:3058:24:3063 | this access | +| UseUseExplosion.cs:24:184:24:187 | [post] this access | UseUseExplosion.cs:24:201:24:204 | this access | +| UseUseExplosion.cs:24:184:24:187 | [post] this access | UseUseExplosion.cs:24:3043:24:3048 | this access | +| UseUseExplosion.cs:24:184:24:187 | access to property Prop | UseUseExplosion.cs:24:201:24:204 | access to property Prop | +| UseUseExplosion.cs:24:184:24:187 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:184:24:187 | this access | UseUseExplosion.cs:24:201:24:204 | this access | +| UseUseExplosion.cs:24:184:24:187 | this access | UseUseExplosion.cs:24:3043:24:3048 | this access | +| UseUseExplosion.cs:24:201:24:204 | [post] this access | UseUseExplosion.cs:24:218:24:221 | this access | +| UseUseExplosion.cs:24:201:24:204 | [post] this access | UseUseExplosion.cs:24:3028:24:3033 | this access | +| UseUseExplosion.cs:24:201:24:204 | access to property Prop | UseUseExplosion.cs:24:218:24:221 | access to property Prop | +| UseUseExplosion.cs:24:201:24:204 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:201:24:204 | this access | UseUseExplosion.cs:24:218:24:221 | this access | +| UseUseExplosion.cs:24:201:24:204 | this access | UseUseExplosion.cs:24:3028:24:3033 | this access | +| UseUseExplosion.cs:24:218:24:221 | [post] this access | UseUseExplosion.cs:24:235:24:238 | this access | +| UseUseExplosion.cs:24:218:24:221 | [post] this access | UseUseExplosion.cs:24:3013:24:3018 | this access | +| UseUseExplosion.cs:24:218:24:221 | access to property Prop | UseUseExplosion.cs:24:235:24:238 | access to property Prop | +| UseUseExplosion.cs:24:218:24:221 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:218:24:221 | this access | UseUseExplosion.cs:24:235:24:238 | this access | +| UseUseExplosion.cs:24:218:24:221 | this access | UseUseExplosion.cs:24:3013:24:3018 | this access | +| UseUseExplosion.cs:24:235:24:238 | [post] this access | UseUseExplosion.cs:24:252:24:255 | this access | +| UseUseExplosion.cs:24:235:24:238 | [post] this access | UseUseExplosion.cs:24:2998:24:3003 | this access | +| UseUseExplosion.cs:24:235:24:238 | access to property Prop | UseUseExplosion.cs:24:252:24:255 | access to property Prop | +| UseUseExplosion.cs:24:235:24:238 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:235:24:238 | this access | UseUseExplosion.cs:24:252:24:255 | this access | +| UseUseExplosion.cs:24:235:24:238 | this access | UseUseExplosion.cs:24:2998:24:3003 | this access | +| UseUseExplosion.cs:24:252:24:255 | [post] this access | UseUseExplosion.cs:24:269:24:272 | this access | +| UseUseExplosion.cs:24:252:24:255 | [post] this access | UseUseExplosion.cs:24:2983:24:2988 | this access | +| UseUseExplosion.cs:24:252:24:255 | access to property Prop | UseUseExplosion.cs:24:269:24:272 | access to property Prop | +| UseUseExplosion.cs:24:252:24:255 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:252:24:255 | this access | UseUseExplosion.cs:24:269:24:272 | this access | +| UseUseExplosion.cs:24:252:24:255 | this access | UseUseExplosion.cs:24:2983:24:2988 | this access | +| UseUseExplosion.cs:24:269:24:272 | [post] this access | UseUseExplosion.cs:24:286:24:289 | this access | +| UseUseExplosion.cs:24:269:24:272 | [post] this access | UseUseExplosion.cs:24:2968:24:2973 | this access | +| UseUseExplosion.cs:24:269:24:272 | access to property Prop | UseUseExplosion.cs:24:286:24:289 | access to property Prop | +| UseUseExplosion.cs:24:269:24:272 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:269:24:272 | this access | UseUseExplosion.cs:24:286:24:289 | this access | +| UseUseExplosion.cs:24:269:24:272 | this access | UseUseExplosion.cs:24:2968:24:2973 | this access | +| UseUseExplosion.cs:24:286:24:289 | [post] this access | UseUseExplosion.cs:24:303:24:306 | this access | +| UseUseExplosion.cs:24:286:24:289 | [post] this access | UseUseExplosion.cs:24:2953:24:2958 | this access | +| UseUseExplosion.cs:24:286:24:289 | access to property Prop | UseUseExplosion.cs:24:303:24:306 | access to property Prop | +| UseUseExplosion.cs:24:286:24:289 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:286:24:289 | this access | UseUseExplosion.cs:24:303:24:306 | this access | +| UseUseExplosion.cs:24:286:24:289 | this access | UseUseExplosion.cs:24:2953:24:2958 | this access | +| UseUseExplosion.cs:24:303:24:306 | [post] this access | UseUseExplosion.cs:24:320:24:323 | this access | +| UseUseExplosion.cs:24:303:24:306 | [post] this access | UseUseExplosion.cs:24:2938:24:2943 | this access | +| UseUseExplosion.cs:24:303:24:306 | access to property Prop | UseUseExplosion.cs:24:320:24:323 | access to property Prop | +| UseUseExplosion.cs:24:303:24:306 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:303:24:306 | this access | UseUseExplosion.cs:24:320:24:323 | this access | +| UseUseExplosion.cs:24:303:24:306 | this access | UseUseExplosion.cs:24:2938:24:2943 | this access | +| UseUseExplosion.cs:24:320:24:323 | [post] this access | UseUseExplosion.cs:24:337:24:340 | this access | +| UseUseExplosion.cs:24:320:24:323 | [post] this access | UseUseExplosion.cs:24:2923:24:2928 | this access | +| UseUseExplosion.cs:24:320:24:323 | access to property Prop | UseUseExplosion.cs:24:337:24:340 | access to property Prop | +| UseUseExplosion.cs:24:320:24:323 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:320:24:323 | this access | UseUseExplosion.cs:24:337:24:340 | this access | +| UseUseExplosion.cs:24:320:24:323 | this access | UseUseExplosion.cs:24:2923:24:2928 | this access | +| UseUseExplosion.cs:24:337:24:340 | [post] this access | UseUseExplosion.cs:24:354:24:357 | this access | +| UseUseExplosion.cs:24:337:24:340 | [post] this access | UseUseExplosion.cs:24:2908:24:2913 | this access | +| UseUseExplosion.cs:24:337:24:340 | access to property Prop | UseUseExplosion.cs:24:354:24:357 | access to property Prop | +| UseUseExplosion.cs:24:337:24:340 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:337:24:340 | this access | UseUseExplosion.cs:24:354:24:357 | this access | +| UseUseExplosion.cs:24:337:24:340 | this access | UseUseExplosion.cs:24:2908:24:2913 | this access | +| UseUseExplosion.cs:24:354:24:357 | [post] this access | UseUseExplosion.cs:24:371:24:374 | this access | +| UseUseExplosion.cs:24:354:24:357 | [post] this access | UseUseExplosion.cs:24:2893:24:2898 | this access | +| UseUseExplosion.cs:24:354:24:357 | access to property Prop | UseUseExplosion.cs:24:371:24:374 | access to property Prop | +| UseUseExplosion.cs:24:354:24:357 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:354:24:357 | this access | UseUseExplosion.cs:24:371:24:374 | this access | +| UseUseExplosion.cs:24:354:24:357 | this access | UseUseExplosion.cs:24:2893:24:2898 | this access | +| UseUseExplosion.cs:24:371:24:374 | [post] this access | UseUseExplosion.cs:24:388:24:391 | this access | +| UseUseExplosion.cs:24:371:24:374 | [post] this access | UseUseExplosion.cs:24:2878:24:2883 | this access | +| UseUseExplosion.cs:24:371:24:374 | access to property Prop | UseUseExplosion.cs:24:388:24:391 | access to property Prop | +| UseUseExplosion.cs:24:371:24:374 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:371:24:374 | this access | UseUseExplosion.cs:24:388:24:391 | this access | +| UseUseExplosion.cs:24:371:24:374 | this access | UseUseExplosion.cs:24:2878:24:2883 | this access | +| UseUseExplosion.cs:24:388:24:391 | [post] this access | UseUseExplosion.cs:24:405:24:408 | this access | +| UseUseExplosion.cs:24:388:24:391 | [post] this access | UseUseExplosion.cs:24:2863:24:2868 | this access | +| UseUseExplosion.cs:24:388:24:391 | access to property Prop | UseUseExplosion.cs:24:405:24:408 | access to property Prop | +| UseUseExplosion.cs:24:388:24:391 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:388:24:391 | this access | UseUseExplosion.cs:24:405:24:408 | this access | +| UseUseExplosion.cs:24:388:24:391 | this access | UseUseExplosion.cs:24:2863:24:2868 | this access | +| UseUseExplosion.cs:24:405:24:408 | [post] this access | UseUseExplosion.cs:24:422:24:425 | this access | +| UseUseExplosion.cs:24:405:24:408 | [post] this access | UseUseExplosion.cs:24:2848:24:2853 | this access | +| UseUseExplosion.cs:24:405:24:408 | access to property Prop | UseUseExplosion.cs:24:422:24:425 | access to property Prop | +| UseUseExplosion.cs:24:405:24:408 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:405:24:408 | this access | UseUseExplosion.cs:24:422:24:425 | this access | +| UseUseExplosion.cs:24:405:24:408 | this access | UseUseExplosion.cs:24:2848:24:2853 | this access | +| UseUseExplosion.cs:24:422:24:425 | [post] this access | UseUseExplosion.cs:24:439:24:442 | this access | +| UseUseExplosion.cs:24:422:24:425 | [post] this access | UseUseExplosion.cs:24:2833:24:2838 | this access | +| UseUseExplosion.cs:24:422:24:425 | access to property Prop | UseUseExplosion.cs:24:439:24:442 | access to property Prop | +| UseUseExplosion.cs:24:422:24:425 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:422:24:425 | this access | UseUseExplosion.cs:24:439:24:442 | this access | +| UseUseExplosion.cs:24:422:24:425 | this access | UseUseExplosion.cs:24:2833:24:2838 | this access | +| UseUseExplosion.cs:24:439:24:442 | [post] this access | UseUseExplosion.cs:24:456:24:459 | this access | +| UseUseExplosion.cs:24:439:24:442 | [post] this access | UseUseExplosion.cs:24:2818:24:2823 | this access | +| UseUseExplosion.cs:24:439:24:442 | access to property Prop | UseUseExplosion.cs:24:456:24:459 | access to property Prop | +| UseUseExplosion.cs:24:439:24:442 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:439:24:442 | this access | UseUseExplosion.cs:24:456:24:459 | this access | +| UseUseExplosion.cs:24:439:24:442 | this access | UseUseExplosion.cs:24:2818:24:2823 | this access | +| UseUseExplosion.cs:24:456:24:459 | [post] this access | UseUseExplosion.cs:24:473:24:476 | this access | +| UseUseExplosion.cs:24:456:24:459 | [post] this access | UseUseExplosion.cs:24:2803:24:2808 | this access | +| UseUseExplosion.cs:24:456:24:459 | access to property Prop | UseUseExplosion.cs:24:473:24:476 | access to property Prop | +| UseUseExplosion.cs:24:456:24:459 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:456:24:459 | this access | UseUseExplosion.cs:24:473:24:476 | this access | +| UseUseExplosion.cs:24:456:24:459 | this access | UseUseExplosion.cs:24:2803:24:2808 | this access | +| UseUseExplosion.cs:24:473:24:476 | [post] this access | UseUseExplosion.cs:24:490:24:493 | this access | +| UseUseExplosion.cs:24:473:24:476 | [post] this access | UseUseExplosion.cs:24:2788:24:2793 | this access | +| UseUseExplosion.cs:24:473:24:476 | access to property Prop | UseUseExplosion.cs:24:490:24:493 | access to property Prop | +| UseUseExplosion.cs:24:473:24:476 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:473:24:476 | this access | UseUseExplosion.cs:24:490:24:493 | this access | +| UseUseExplosion.cs:24:473:24:476 | this access | UseUseExplosion.cs:24:2788:24:2793 | this access | +| UseUseExplosion.cs:24:490:24:493 | [post] this access | UseUseExplosion.cs:24:507:24:510 | this access | +| UseUseExplosion.cs:24:490:24:493 | [post] this access | UseUseExplosion.cs:24:2773:24:2778 | this access | +| UseUseExplosion.cs:24:490:24:493 | access to property Prop | UseUseExplosion.cs:24:507:24:510 | access to property Prop | +| UseUseExplosion.cs:24:490:24:493 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:490:24:493 | this access | UseUseExplosion.cs:24:507:24:510 | this access | +| UseUseExplosion.cs:24:490:24:493 | this access | UseUseExplosion.cs:24:2773:24:2778 | this access | +| UseUseExplosion.cs:24:507:24:510 | [post] this access | UseUseExplosion.cs:24:524:24:527 | this access | +| UseUseExplosion.cs:24:507:24:510 | [post] this access | UseUseExplosion.cs:24:2758:24:2763 | this access | +| UseUseExplosion.cs:24:507:24:510 | access to property Prop | UseUseExplosion.cs:24:524:24:527 | access to property Prop | +| UseUseExplosion.cs:24:507:24:510 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:507:24:510 | this access | UseUseExplosion.cs:24:524:24:527 | this access | +| UseUseExplosion.cs:24:507:24:510 | this access | UseUseExplosion.cs:24:2758:24:2763 | this access | +| UseUseExplosion.cs:24:524:24:527 | [post] this access | UseUseExplosion.cs:24:541:24:544 | this access | +| UseUseExplosion.cs:24:524:24:527 | [post] this access | UseUseExplosion.cs:24:2743:24:2748 | this access | +| UseUseExplosion.cs:24:524:24:527 | access to property Prop | UseUseExplosion.cs:24:541:24:544 | access to property Prop | +| UseUseExplosion.cs:24:524:24:527 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:524:24:527 | this access | UseUseExplosion.cs:24:541:24:544 | this access | +| UseUseExplosion.cs:24:524:24:527 | this access | UseUseExplosion.cs:24:2743:24:2748 | this access | +| UseUseExplosion.cs:24:541:24:544 | [post] this access | UseUseExplosion.cs:24:558:24:561 | this access | +| UseUseExplosion.cs:24:541:24:544 | [post] this access | UseUseExplosion.cs:24:2728:24:2733 | this access | +| UseUseExplosion.cs:24:541:24:544 | access to property Prop | UseUseExplosion.cs:24:558:24:561 | access to property Prop | +| UseUseExplosion.cs:24:541:24:544 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:541:24:544 | this access | UseUseExplosion.cs:24:558:24:561 | this access | +| UseUseExplosion.cs:24:541:24:544 | this access | UseUseExplosion.cs:24:2728:24:2733 | this access | +| UseUseExplosion.cs:24:558:24:561 | [post] this access | UseUseExplosion.cs:24:575:24:578 | this access | +| UseUseExplosion.cs:24:558:24:561 | [post] this access | UseUseExplosion.cs:24:2713:24:2718 | this access | +| UseUseExplosion.cs:24:558:24:561 | access to property Prop | UseUseExplosion.cs:24:575:24:578 | access to property Prop | +| UseUseExplosion.cs:24:558:24:561 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:558:24:561 | this access | UseUseExplosion.cs:24:575:24:578 | this access | +| UseUseExplosion.cs:24:558:24:561 | this access | UseUseExplosion.cs:24:2713:24:2718 | this access | +| UseUseExplosion.cs:24:575:24:578 | [post] this access | UseUseExplosion.cs:24:592:24:595 | this access | +| UseUseExplosion.cs:24:575:24:578 | [post] this access | UseUseExplosion.cs:24:2698:24:2703 | this access | +| UseUseExplosion.cs:24:575:24:578 | access to property Prop | UseUseExplosion.cs:24:592:24:595 | access to property Prop | +| UseUseExplosion.cs:24:575:24:578 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:575:24:578 | this access | UseUseExplosion.cs:24:592:24:595 | this access | +| UseUseExplosion.cs:24:575:24:578 | this access | UseUseExplosion.cs:24:2698:24:2703 | this access | +| UseUseExplosion.cs:24:592:24:595 | [post] this access | UseUseExplosion.cs:24:609:24:612 | this access | +| UseUseExplosion.cs:24:592:24:595 | [post] this access | UseUseExplosion.cs:24:2683:24:2688 | this access | +| UseUseExplosion.cs:24:592:24:595 | access to property Prop | UseUseExplosion.cs:24:609:24:612 | access to property Prop | +| UseUseExplosion.cs:24:592:24:595 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:592:24:595 | this access | UseUseExplosion.cs:24:609:24:612 | this access | +| UseUseExplosion.cs:24:592:24:595 | this access | UseUseExplosion.cs:24:2683:24:2688 | this access | +| UseUseExplosion.cs:24:609:24:612 | [post] this access | UseUseExplosion.cs:24:626:24:629 | this access | +| UseUseExplosion.cs:24:609:24:612 | [post] this access | UseUseExplosion.cs:24:2668:24:2673 | this access | +| UseUseExplosion.cs:24:609:24:612 | access to property Prop | UseUseExplosion.cs:24:626:24:629 | access to property Prop | +| UseUseExplosion.cs:24:609:24:612 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:609:24:612 | this access | UseUseExplosion.cs:24:626:24:629 | this access | +| UseUseExplosion.cs:24:609:24:612 | this access | UseUseExplosion.cs:24:2668:24:2673 | this access | +| UseUseExplosion.cs:24:626:24:629 | [post] this access | UseUseExplosion.cs:24:643:24:646 | this access | +| UseUseExplosion.cs:24:626:24:629 | [post] this access | UseUseExplosion.cs:24:2653:24:2658 | this access | +| UseUseExplosion.cs:24:626:24:629 | access to property Prop | UseUseExplosion.cs:24:643:24:646 | access to property Prop | +| UseUseExplosion.cs:24:626:24:629 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:626:24:629 | this access | UseUseExplosion.cs:24:643:24:646 | this access | +| UseUseExplosion.cs:24:626:24:629 | this access | UseUseExplosion.cs:24:2653:24:2658 | this access | +| UseUseExplosion.cs:24:643:24:646 | [post] this access | UseUseExplosion.cs:24:660:24:663 | this access | +| UseUseExplosion.cs:24:643:24:646 | [post] this access | UseUseExplosion.cs:24:2638:24:2643 | this access | +| UseUseExplosion.cs:24:643:24:646 | access to property Prop | UseUseExplosion.cs:24:660:24:663 | access to property Prop | +| UseUseExplosion.cs:24:643:24:646 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:643:24:646 | this access | UseUseExplosion.cs:24:660:24:663 | this access | +| UseUseExplosion.cs:24:643:24:646 | this access | UseUseExplosion.cs:24:2638:24:2643 | this access | +| UseUseExplosion.cs:24:660:24:663 | [post] this access | UseUseExplosion.cs:24:677:24:680 | this access | +| UseUseExplosion.cs:24:660:24:663 | [post] this access | UseUseExplosion.cs:24:2623:24:2628 | this access | +| UseUseExplosion.cs:24:660:24:663 | access to property Prop | UseUseExplosion.cs:24:677:24:680 | access to property Prop | +| UseUseExplosion.cs:24:660:24:663 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:660:24:663 | this access | UseUseExplosion.cs:24:677:24:680 | this access | +| UseUseExplosion.cs:24:660:24:663 | this access | UseUseExplosion.cs:24:2623:24:2628 | this access | +| UseUseExplosion.cs:24:677:24:680 | [post] this access | UseUseExplosion.cs:24:694:24:697 | this access | +| UseUseExplosion.cs:24:677:24:680 | [post] this access | UseUseExplosion.cs:24:2608:24:2613 | this access | +| UseUseExplosion.cs:24:677:24:680 | access to property Prop | UseUseExplosion.cs:24:694:24:697 | access to property Prop | +| UseUseExplosion.cs:24:677:24:680 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:677:24:680 | this access | UseUseExplosion.cs:24:694:24:697 | this access | +| UseUseExplosion.cs:24:677:24:680 | this access | UseUseExplosion.cs:24:2608:24:2613 | this access | +| UseUseExplosion.cs:24:694:24:697 | [post] this access | UseUseExplosion.cs:24:711:24:714 | this access | +| UseUseExplosion.cs:24:694:24:697 | [post] this access | UseUseExplosion.cs:24:2593:24:2598 | this access | +| UseUseExplosion.cs:24:694:24:697 | access to property Prop | UseUseExplosion.cs:24:711:24:714 | access to property Prop | +| UseUseExplosion.cs:24:694:24:697 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:694:24:697 | this access | UseUseExplosion.cs:24:711:24:714 | this access | +| UseUseExplosion.cs:24:694:24:697 | this access | UseUseExplosion.cs:24:2593:24:2598 | this access | +| UseUseExplosion.cs:24:711:24:714 | [post] this access | UseUseExplosion.cs:24:728:24:731 | this access | +| UseUseExplosion.cs:24:711:24:714 | [post] this access | UseUseExplosion.cs:24:2578:24:2583 | this access | +| UseUseExplosion.cs:24:711:24:714 | access to property Prop | UseUseExplosion.cs:24:728:24:731 | access to property Prop | +| UseUseExplosion.cs:24:711:24:714 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:711:24:714 | this access | UseUseExplosion.cs:24:728:24:731 | this access | +| UseUseExplosion.cs:24:711:24:714 | this access | UseUseExplosion.cs:24:2578:24:2583 | this access | +| UseUseExplosion.cs:24:728:24:731 | [post] this access | UseUseExplosion.cs:24:745:24:748 | this access | +| UseUseExplosion.cs:24:728:24:731 | [post] this access | UseUseExplosion.cs:24:2563:24:2568 | this access | +| UseUseExplosion.cs:24:728:24:731 | access to property Prop | UseUseExplosion.cs:24:745:24:748 | access to property Prop | +| UseUseExplosion.cs:24:728:24:731 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:728:24:731 | this access | UseUseExplosion.cs:24:745:24:748 | this access | +| UseUseExplosion.cs:24:728:24:731 | this access | UseUseExplosion.cs:24:2563:24:2568 | this access | +| UseUseExplosion.cs:24:745:24:748 | [post] this access | UseUseExplosion.cs:24:762:24:765 | this access | +| UseUseExplosion.cs:24:745:24:748 | [post] this access | UseUseExplosion.cs:24:2548:24:2553 | this access | +| UseUseExplosion.cs:24:745:24:748 | access to property Prop | UseUseExplosion.cs:24:762:24:765 | access to property Prop | +| UseUseExplosion.cs:24:745:24:748 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:745:24:748 | this access | UseUseExplosion.cs:24:762:24:765 | this access | +| UseUseExplosion.cs:24:745:24:748 | this access | UseUseExplosion.cs:24:2548:24:2553 | this access | +| UseUseExplosion.cs:24:762:24:765 | [post] this access | UseUseExplosion.cs:24:779:24:782 | this access | +| UseUseExplosion.cs:24:762:24:765 | [post] this access | UseUseExplosion.cs:24:2533:24:2538 | this access | +| UseUseExplosion.cs:24:762:24:765 | access to property Prop | UseUseExplosion.cs:24:779:24:782 | access to property Prop | +| UseUseExplosion.cs:24:762:24:765 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:762:24:765 | this access | UseUseExplosion.cs:24:779:24:782 | this access | +| UseUseExplosion.cs:24:762:24:765 | this access | UseUseExplosion.cs:24:2533:24:2538 | this access | +| UseUseExplosion.cs:24:779:24:782 | [post] this access | UseUseExplosion.cs:24:796:24:799 | this access | +| UseUseExplosion.cs:24:779:24:782 | [post] this access | UseUseExplosion.cs:24:2518:24:2523 | this access | +| UseUseExplosion.cs:24:779:24:782 | access to property Prop | UseUseExplosion.cs:24:796:24:799 | access to property Prop | +| UseUseExplosion.cs:24:779:24:782 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:779:24:782 | this access | UseUseExplosion.cs:24:796:24:799 | this access | +| UseUseExplosion.cs:24:779:24:782 | this access | UseUseExplosion.cs:24:2518:24:2523 | this access | +| UseUseExplosion.cs:24:796:24:799 | [post] this access | UseUseExplosion.cs:24:813:24:816 | this access | +| UseUseExplosion.cs:24:796:24:799 | [post] this access | UseUseExplosion.cs:24:2503:24:2508 | this access | +| UseUseExplosion.cs:24:796:24:799 | access to property Prop | UseUseExplosion.cs:24:813:24:816 | access to property Prop | +| UseUseExplosion.cs:24:796:24:799 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:796:24:799 | this access | UseUseExplosion.cs:24:813:24:816 | this access | +| UseUseExplosion.cs:24:796:24:799 | this access | UseUseExplosion.cs:24:2503:24:2508 | this access | +| UseUseExplosion.cs:24:813:24:816 | [post] this access | UseUseExplosion.cs:24:830:24:833 | this access | +| UseUseExplosion.cs:24:813:24:816 | [post] this access | UseUseExplosion.cs:24:2488:24:2493 | this access | +| UseUseExplosion.cs:24:813:24:816 | access to property Prop | UseUseExplosion.cs:24:830:24:833 | access to property Prop | +| UseUseExplosion.cs:24:813:24:816 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:813:24:816 | this access | UseUseExplosion.cs:24:830:24:833 | this access | +| UseUseExplosion.cs:24:813:24:816 | this access | UseUseExplosion.cs:24:2488:24:2493 | this access | +| UseUseExplosion.cs:24:830:24:833 | [post] this access | UseUseExplosion.cs:24:847:24:850 | this access | +| UseUseExplosion.cs:24:830:24:833 | [post] this access | UseUseExplosion.cs:24:2473:24:2478 | this access | +| UseUseExplosion.cs:24:830:24:833 | access to property Prop | UseUseExplosion.cs:24:847:24:850 | access to property Prop | +| UseUseExplosion.cs:24:830:24:833 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:830:24:833 | this access | UseUseExplosion.cs:24:847:24:850 | this access | +| UseUseExplosion.cs:24:830:24:833 | this access | UseUseExplosion.cs:24:2473:24:2478 | this access | +| UseUseExplosion.cs:24:847:24:850 | [post] this access | UseUseExplosion.cs:24:864:24:867 | this access | +| UseUseExplosion.cs:24:847:24:850 | [post] this access | UseUseExplosion.cs:24:2458:24:2463 | this access | +| UseUseExplosion.cs:24:847:24:850 | access to property Prop | UseUseExplosion.cs:24:864:24:867 | access to property Prop | +| UseUseExplosion.cs:24:847:24:850 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:847:24:850 | this access | UseUseExplosion.cs:24:864:24:867 | this access | +| UseUseExplosion.cs:24:847:24:850 | this access | UseUseExplosion.cs:24:2458:24:2463 | this access | +| UseUseExplosion.cs:24:864:24:867 | [post] this access | UseUseExplosion.cs:24:881:24:884 | this access | +| UseUseExplosion.cs:24:864:24:867 | [post] this access | UseUseExplosion.cs:24:2443:24:2448 | this access | +| UseUseExplosion.cs:24:864:24:867 | access to property Prop | UseUseExplosion.cs:24:881:24:884 | access to property Prop | +| UseUseExplosion.cs:24:864:24:867 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:864:24:867 | this access | UseUseExplosion.cs:24:881:24:884 | this access | +| UseUseExplosion.cs:24:864:24:867 | this access | UseUseExplosion.cs:24:2443:24:2448 | this access | +| UseUseExplosion.cs:24:881:24:884 | [post] this access | UseUseExplosion.cs:24:898:24:901 | this access | +| UseUseExplosion.cs:24:881:24:884 | [post] this access | UseUseExplosion.cs:24:2428:24:2433 | this access | +| UseUseExplosion.cs:24:881:24:884 | access to property Prop | UseUseExplosion.cs:24:898:24:901 | access to property Prop | +| UseUseExplosion.cs:24:881:24:884 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:881:24:884 | this access | UseUseExplosion.cs:24:898:24:901 | this access | +| UseUseExplosion.cs:24:881:24:884 | this access | UseUseExplosion.cs:24:2428:24:2433 | this access | +| UseUseExplosion.cs:24:898:24:901 | [post] this access | UseUseExplosion.cs:24:915:24:918 | this access | +| UseUseExplosion.cs:24:898:24:901 | [post] this access | UseUseExplosion.cs:24:2413:24:2418 | this access | +| UseUseExplosion.cs:24:898:24:901 | access to property Prop | UseUseExplosion.cs:24:915:24:918 | access to property Prop | +| UseUseExplosion.cs:24:898:24:901 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:898:24:901 | this access | UseUseExplosion.cs:24:915:24:918 | this access | +| UseUseExplosion.cs:24:898:24:901 | this access | UseUseExplosion.cs:24:2413:24:2418 | this access | +| UseUseExplosion.cs:24:915:24:918 | [post] this access | UseUseExplosion.cs:24:932:24:935 | this access | +| UseUseExplosion.cs:24:915:24:918 | [post] this access | UseUseExplosion.cs:24:2398:24:2403 | this access | +| UseUseExplosion.cs:24:915:24:918 | access to property Prop | UseUseExplosion.cs:24:932:24:935 | access to property Prop | +| UseUseExplosion.cs:24:915:24:918 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:915:24:918 | this access | UseUseExplosion.cs:24:932:24:935 | this access | +| UseUseExplosion.cs:24:915:24:918 | this access | UseUseExplosion.cs:24:2398:24:2403 | this access | +| UseUseExplosion.cs:24:932:24:935 | [post] this access | UseUseExplosion.cs:24:949:24:952 | this access | +| UseUseExplosion.cs:24:932:24:935 | [post] this access | UseUseExplosion.cs:24:2383:24:2388 | this access | +| UseUseExplosion.cs:24:932:24:935 | access to property Prop | UseUseExplosion.cs:24:949:24:952 | access to property Prop | +| UseUseExplosion.cs:24:932:24:935 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:932:24:935 | this access | UseUseExplosion.cs:24:949:24:952 | this access | +| UseUseExplosion.cs:24:932:24:935 | this access | UseUseExplosion.cs:24:2383:24:2388 | this access | +| UseUseExplosion.cs:24:949:24:952 | [post] this access | UseUseExplosion.cs:24:966:24:969 | this access | +| UseUseExplosion.cs:24:949:24:952 | [post] this access | UseUseExplosion.cs:24:2368:24:2373 | this access | +| UseUseExplosion.cs:24:949:24:952 | access to property Prop | UseUseExplosion.cs:24:966:24:969 | access to property Prop | +| UseUseExplosion.cs:24:949:24:952 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:949:24:952 | this access | UseUseExplosion.cs:24:966:24:969 | this access | +| UseUseExplosion.cs:24:949:24:952 | this access | UseUseExplosion.cs:24:2368:24:2373 | this access | +| UseUseExplosion.cs:24:966:24:969 | [post] this access | UseUseExplosion.cs:24:983:24:986 | this access | +| UseUseExplosion.cs:24:966:24:969 | [post] this access | UseUseExplosion.cs:24:2353:24:2358 | this access | +| UseUseExplosion.cs:24:966:24:969 | access to property Prop | UseUseExplosion.cs:24:983:24:986 | access to property Prop | +| UseUseExplosion.cs:24:966:24:969 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:966:24:969 | this access | UseUseExplosion.cs:24:983:24:986 | this access | +| UseUseExplosion.cs:24:966:24:969 | this access | UseUseExplosion.cs:24:2353:24:2358 | this access | +| UseUseExplosion.cs:24:983:24:986 | [post] this access | UseUseExplosion.cs:24:1000:24:1003 | this access | +| UseUseExplosion.cs:24:983:24:986 | [post] this access | UseUseExplosion.cs:24:2338:24:2343 | this access | +| UseUseExplosion.cs:24:983:24:986 | access to property Prop | UseUseExplosion.cs:24:1000:24:1003 | access to property Prop | +| UseUseExplosion.cs:24:983:24:986 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:983:24:986 | this access | UseUseExplosion.cs:24:1000:24:1003 | this access | +| UseUseExplosion.cs:24:983:24:986 | this access | UseUseExplosion.cs:24:2338:24:2343 | this access | +| UseUseExplosion.cs:24:1000:24:1003 | [post] this access | UseUseExplosion.cs:24:1017:24:1020 | this access | +| UseUseExplosion.cs:24:1000:24:1003 | [post] this access | UseUseExplosion.cs:24:2323:24:2328 | this access | +| UseUseExplosion.cs:24:1000:24:1003 | access to property Prop | UseUseExplosion.cs:24:1017:24:1020 | access to property Prop | +| UseUseExplosion.cs:24:1000:24:1003 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1000:24:1003 | this access | UseUseExplosion.cs:24:1017:24:1020 | this access | +| UseUseExplosion.cs:24:1000:24:1003 | this access | UseUseExplosion.cs:24:2323:24:2328 | this access | +| UseUseExplosion.cs:24:1017:24:1020 | [post] this access | UseUseExplosion.cs:24:1034:24:1037 | this access | +| UseUseExplosion.cs:24:1017:24:1020 | [post] this access | UseUseExplosion.cs:24:2308:24:2313 | this access | +| UseUseExplosion.cs:24:1017:24:1020 | access to property Prop | UseUseExplosion.cs:24:1034:24:1037 | access to property Prop | +| UseUseExplosion.cs:24:1017:24:1020 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1017:24:1020 | this access | UseUseExplosion.cs:24:1034:24:1037 | this access | +| UseUseExplosion.cs:24:1017:24:1020 | this access | UseUseExplosion.cs:24:2308:24:2313 | this access | +| UseUseExplosion.cs:24:1034:24:1037 | [post] this access | UseUseExplosion.cs:24:1051:24:1054 | this access | +| UseUseExplosion.cs:24:1034:24:1037 | [post] this access | UseUseExplosion.cs:24:2293:24:2298 | this access | +| UseUseExplosion.cs:24:1034:24:1037 | access to property Prop | UseUseExplosion.cs:24:1051:24:1054 | access to property Prop | +| UseUseExplosion.cs:24:1034:24:1037 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1034:24:1037 | this access | UseUseExplosion.cs:24:1051:24:1054 | this access | +| UseUseExplosion.cs:24:1034:24:1037 | this access | UseUseExplosion.cs:24:2293:24:2298 | this access | +| UseUseExplosion.cs:24:1051:24:1054 | [post] this access | UseUseExplosion.cs:24:1068:24:1071 | this access | +| UseUseExplosion.cs:24:1051:24:1054 | [post] this access | UseUseExplosion.cs:24:2278:24:2283 | this access | +| UseUseExplosion.cs:24:1051:24:1054 | access to property Prop | UseUseExplosion.cs:24:1068:24:1071 | access to property Prop | +| UseUseExplosion.cs:24:1051:24:1054 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1051:24:1054 | this access | UseUseExplosion.cs:24:1068:24:1071 | this access | +| UseUseExplosion.cs:24:1051:24:1054 | this access | UseUseExplosion.cs:24:2278:24:2283 | this access | +| UseUseExplosion.cs:24:1068:24:1071 | [post] this access | UseUseExplosion.cs:24:1085:24:1088 | this access | +| UseUseExplosion.cs:24:1068:24:1071 | [post] this access | UseUseExplosion.cs:24:2263:24:2268 | this access | +| UseUseExplosion.cs:24:1068:24:1071 | access to property Prop | UseUseExplosion.cs:24:1085:24:1088 | access to property Prop | +| UseUseExplosion.cs:24:1068:24:1071 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1068:24:1071 | this access | UseUseExplosion.cs:24:1085:24:1088 | this access | +| UseUseExplosion.cs:24:1068:24:1071 | this access | UseUseExplosion.cs:24:2263:24:2268 | this access | +| UseUseExplosion.cs:24:1085:24:1088 | [post] this access | UseUseExplosion.cs:24:1102:24:1105 | this access | +| UseUseExplosion.cs:24:1085:24:1088 | [post] this access | UseUseExplosion.cs:24:2248:24:2253 | this access | +| UseUseExplosion.cs:24:1085:24:1088 | access to property Prop | UseUseExplosion.cs:24:1102:24:1105 | access to property Prop | +| UseUseExplosion.cs:24:1085:24:1088 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1085:24:1088 | this access | UseUseExplosion.cs:24:1102:24:1105 | this access | +| UseUseExplosion.cs:24:1085:24:1088 | this access | UseUseExplosion.cs:24:2248:24:2253 | this access | +| UseUseExplosion.cs:24:1102:24:1105 | [post] this access | UseUseExplosion.cs:24:1119:24:1122 | this access | +| UseUseExplosion.cs:24:1102:24:1105 | [post] this access | UseUseExplosion.cs:24:2233:24:2238 | this access | +| UseUseExplosion.cs:24:1102:24:1105 | access to property Prop | UseUseExplosion.cs:24:1119:24:1122 | access to property Prop | +| UseUseExplosion.cs:24:1102:24:1105 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1102:24:1105 | this access | UseUseExplosion.cs:24:1119:24:1122 | this access | +| UseUseExplosion.cs:24:1102:24:1105 | this access | UseUseExplosion.cs:24:2233:24:2238 | this access | +| UseUseExplosion.cs:24:1119:24:1122 | [post] this access | UseUseExplosion.cs:24:1136:24:1139 | this access | +| UseUseExplosion.cs:24:1119:24:1122 | [post] this access | UseUseExplosion.cs:24:2218:24:2223 | this access | +| UseUseExplosion.cs:24:1119:24:1122 | access to property Prop | UseUseExplosion.cs:24:1136:24:1139 | access to property Prop | +| UseUseExplosion.cs:24:1119:24:1122 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1119:24:1122 | this access | UseUseExplosion.cs:24:1136:24:1139 | this access | +| UseUseExplosion.cs:24:1119:24:1122 | this access | UseUseExplosion.cs:24:2218:24:2223 | this access | +| UseUseExplosion.cs:24:1136:24:1139 | [post] this access | UseUseExplosion.cs:24:1153:24:1156 | this access | +| UseUseExplosion.cs:24:1136:24:1139 | [post] this access | UseUseExplosion.cs:24:2203:24:2208 | this access | +| UseUseExplosion.cs:24:1136:24:1139 | access to property Prop | UseUseExplosion.cs:24:1153:24:1156 | access to property Prop | +| UseUseExplosion.cs:24:1136:24:1139 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1136:24:1139 | this access | UseUseExplosion.cs:24:1153:24:1156 | this access | +| UseUseExplosion.cs:24:1136:24:1139 | this access | UseUseExplosion.cs:24:2203:24:2208 | this access | +| UseUseExplosion.cs:24:1153:24:1156 | [post] this access | UseUseExplosion.cs:24:1170:24:1173 | this access | +| UseUseExplosion.cs:24:1153:24:1156 | [post] this access | UseUseExplosion.cs:24:2188:24:2193 | this access | +| UseUseExplosion.cs:24:1153:24:1156 | access to property Prop | UseUseExplosion.cs:24:1170:24:1173 | access to property Prop | +| UseUseExplosion.cs:24:1153:24:1156 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1153:24:1156 | this access | UseUseExplosion.cs:24:1170:24:1173 | this access | +| UseUseExplosion.cs:24:1153:24:1156 | this access | UseUseExplosion.cs:24:2188:24:2193 | this access | +| UseUseExplosion.cs:24:1170:24:1173 | [post] this access | UseUseExplosion.cs:24:1187:24:1190 | this access | +| UseUseExplosion.cs:24:1170:24:1173 | [post] this access | UseUseExplosion.cs:24:2173:24:2178 | this access | +| UseUseExplosion.cs:24:1170:24:1173 | access to property Prop | UseUseExplosion.cs:24:1187:24:1190 | access to property Prop | +| UseUseExplosion.cs:24:1170:24:1173 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1170:24:1173 | this access | UseUseExplosion.cs:24:1187:24:1190 | this access | +| UseUseExplosion.cs:24:1170:24:1173 | this access | UseUseExplosion.cs:24:2173:24:2178 | this access | +| UseUseExplosion.cs:24:1187:24:1190 | [post] this access | UseUseExplosion.cs:24:1204:24:1207 | this access | +| UseUseExplosion.cs:24:1187:24:1190 | [post] this access | UseUseExplosion.cs:24:2158:24:2163 | this access | +| UseUseExplosion.cs:24:1187:24:1190 | access to property Prop | UseUseExplosion.cs:24:1204:24:1207 | access to property Prop | +| UseUseExplosion.cs:24:1187:24:1190 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1187:24:1190 | this access | UseUseExplosion.cs:24:1204:24:1207 | this access | +| UseUseExplosion.cs:24:1187:24:1190 | this access | UseUseExplosion.cs:24:2158:24:2163 | this access | +| UseUseExplosion.cs:24:1204:24:1207 | [post] this access | UseUseExplosion.cs:24:1221:24:1224 | this access | +| UseUseExplosion.cs:24:1204:24:1207 | [post] this access | UseUseExplosion.cs:24:2143:24:2148 | this access | +| UseUseExplosion.cs:24:1204:24:1207 | access to property Prop | UseUseExplosion.cs:24:1221:24:1224 | access to property Prop | +| UseUseExplosion.cs:24:1204:24:1207 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1204:24:1207 | this access | UseUseExplosion.cs:24:1221:24:1224 | this access | +| UseUseExplosion.cs:24:1204:24:1207 | this access | UseUseExplosion.cs:24:2143:24:2148 | this access | +| UseUseExplosion.cs:24:1221:24:1224 | [post] this access | UseUseExplosion.cs:24:1238:24:1241 | this access | +| UseUseExplosion.cs:24:1221:24:1224 | [post] this access | UseUseExplosion.cs:24:2128:24:2133 | this access | +| UseUseExplosion.cs:24:1221:24:1224 | access to property Prop | UseUseExplosion.cs:24:1238:24:1241 | access to property Prop | +| UseUseExplosion.cs:24:1221:24:1224 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1221:24:1224 | this access | UseUseExplosion.cs:24:1238:24:1241 | this access | +| UseUseExplosion.cs:24:1221:24:1224 | this access | UseUseExplosion.cs:24:2128:24:2133 | this access | +| UseUseExplosion.cs:24:1238:24:1241 | [post] this access | UseUseExplosion.cs:24:1255:24:1258 | this access | +| UseUseExplosion.cs:24:1238:24:1241 | [post] this access | UseUseExplosion.cs:24:2113:24:2118 | this access | +| UseUseExplosion.cs:24:1238:24:1241 | access to property Prop | UseUseExplosion.cs:24:1255:24:1258 | access to property Prop | +| UseUseExplosion.cs:24:1238:24:1241 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1238:24:1241 | this access | UseUseExplosion.cs:24:1255:24:1258 | this access | +| UseUseExplosion.cs:24:1238:24:1241 | this access | UseUseExplosion.cs:24:2113:24:2118 | this access | +| UseUseExplosion.cs:24:1255:24:1258 | [post] this access | UseUseExplosion.cs:24:1272:24:1275 | this access | +| UseUseExplosion.cs:24:1255:24:1258 | [post] this access | UseUseExplosion.cs:24:2098:24:2103 | this access | +| UseUseExplosion.cs:24:1255:24:1258 | access to property Prop | UseUseExplosion.cs:24:1272:24:1275 | access to property Prop | +| UseUseExplosion.cs:24:1255:24:1258 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1255:24:1258 | this access | UseUseExplosion.cs:24:1272:24:1275 | this access | +| UseUseExplosion.cs:24:1255:24:1258 | this access | UseUseExplosion.cs:24:2098:24:2103 | this access | +| UseUseExplosion.cs:24:1272:24:1275 | [post] this access | UseUseExplosion.cs:24:1289:24:1292 | this access | +| UseUseExplosion.cs:24:1272:24:1275 | [post] this access | UseUseExplosion.cs:24:2083:24:2088 | this access | +| UseUseExplosion.cs:24:1272:24:1275 | access to property Prop | UseUseExplosion.cs:24:1289:24:1292 | access to property Prop | +| UseUseExplosion.cs:24:1272:24:1275 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1272:24:1275 | this access | UseUseExplosion.cs:24:1289:24:1292 | this access | +| UseUseExplosion.cs:24:1272:24:1275 | this access | UseUseExplosion.cs:24:2083:24:2088 | this access | +| UseUseExplosion.cs:24:1289:24:1292 | [post] this access | UseUseExplosion.cs:24:1306:24:1309 | this access | +| UseUseExplosion.cs:24:1289:24:1292 | [post] this access | UseUseExplosion.cs:24:2068:24:2073 | this access | +| UseUseExplosion.cs:24:1289:24:1292 | access to property Prop | UseUseExplosion.cs:24:1306:24:1309 | access to property Prop | +| UseUseExplosion.cs:24:1289:24:1292 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1289:24:1292 | this access | UseUseExplosion.cs:24:1306:24:1309 | this access | +| UseUseExplosion.cs:24:1289:24:1292 | this access | UseUseExplosion.cs:24:2068:24:2073 | this access | +| UseUseExplosion.cs:24:1306:24:1309 | [post] this access | UseUseExplosion.cs:24:1323:24:1326 | this access | +| UseUseExplosion.cs:24:1306:24:1309 | [post] this access | UseUseExplosion.cs:24:2053:24:2058 | this access | +| UseUseExplosion.cs:24:1306:24:1309 | access to property Prop | UseUseExplosion.cs:24:1323:24:1326 | access to property Prop | +| UseUseExplosion.cs:24:1306:24:1309 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1306:24:1309 | this access | UseUseExplosion.cs:24:1323:24:1326 | this access | +| UseUseExplosion.cs:24:1306:24:1309 | this access | UseUseExplosion.cs:24:2053:24:2058 | this access | +| UseUseExplosion.cs:24:1323:24:1326 | [post] this access | UseUseExplosion.cs:24:1340:24:1343 | this access | +| UseUseExplosion.cs:24:1323:24:1326 | [post] this access | UseUseExplosion.cs:24:2038:24:2043 | this access | +| UseUseExplosion.cs:24:1323:24:1326 | access to property Prop | UseUseExplosion.cs:24:1340:24:1343 | access to property Prop | +| UseUseExplosion.cs:24:1323:24:1326 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1323:24:1326 | this access | UseUseExplosion.cs:24:1340:24:1343 | this access | +| UseUseExplosion.cs:24:1323:24:1326 | this access | UseUseExplosion.cs:24:2038:24:2043 | this access | +| UseUseExplosion.cs:24:1340:24:1343 | [post] this access | UseUseExplosion.cs:24:1357:24:1360 | this access | +| UseUseExplosion.cs:24:1340:24:1343 | [post] this access | UseUseExplosion.cs:24:2023:24:2028 | this access | +| UseUseExplosion.cs:24:1340:24:1343 | access to property Prop | UseUseExplosion.cs:24:1357:24:1360 | access to property Prop | +| UseUseExplosion.cs:24:1340:24:1343 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1340:24:1343 | this access | UseUseExplosion.cs:24:1357:24:1360 | this access | +| UseUseExplosion.cs:24:1340:24:1343 | this access | UseUseExplosion.cs:24:2023:24:2028 | this access | +| UseUseExplosion.cs:24:1357:24:1360 | [post] this access | UseUseExplosion.cs:24:1374:24:1377 | this access | +| UseUseExplosion.cs:24:1357:24:1360 | [post] this access | UseUseExplosion.cs:24:2008:24:2013 | this access | +| UseUseExplosion.cs:24:1357:24:1360 | access to property Prop | UseUseExplosion.cs:24:1374:24:1377 | access to property Prop | +| UseUseExplosion.cs:24:1357:24:1360 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1357:24:1360 | this access | UseUseExplosion.cs:24:1374:24:1377 | this access | +| UseUseExplosion.cs:24:1357:24:1360 | this access | UseUseExplosion.cs:24:2008:24:2013 | this access | +| UseUseExplosion.cs:24:1374:24:1377 | [post] this access | UseUseExplosion.cs:24:1391:24:1394 | this access | +| UseUseExplosion.cs:24:1374:24:1377 | [post] this access | UseUseExplosion.cs:24:1993:24:1998 | this access | +| UseUseExplosion.cs:24:1374:24:1377 | access to property Prop | UseUseExplosion.cs:24:1391:24:1394 | access to property Prop | +| UseUseExplosion.cs:24:1374:24:1377 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1374:24:1377 | this access | UseUseExplosion.cs:24:1391:24:1394 | this access | +| UseUseExplosion.cs:24:1374:24:1377 | this access | UseUseExplosion.cs:24:1993:24:1998 | this access | +| UseUseExplosion.cs:24:1391:24:1394 | [post] this access | UseUseExplosion.cs:24:1408:24:1411 | this access | +| UseUseExplosion.cs:24:1391:24:1394 | [post] this access | UseUseExplosion.cs:24:1978:24:1983 | this access | +| UseUseExplosion.cs:24:1391:24:1394 | access to property Prop | UseUseExplosion.cs:24:1408:24:1411 | access to property Prop | +| UseUseExplosion.cs:24:1391:24:1394 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1391:24:1394 | this access | UseUseExplosion.cs:24:1408:24:1411 | this access | +| UseUseExplosion.cs:24:1391:24:1394 | this access | UseUseExplosion.cs:24:1978:24:1983 | this access | +| UseUseExplosion.cs:24:1408:24:1411 | [post] this access | UseUseExplosion.cs:24:1425:24:1428 | this access | +| UseUseExplosion.cs:24:1408:24:1411 | [post] this access | UseUseExplosion.cs:24:1963:24:1968 | this access | +| UseUseExplosion.cs:24:1408:24:1411 | access to property Prop | UseUseExplosion.cs:24:1425:24:1428 | access to property Prop | +| UseUseExplosion.cs:24:1408:24:1411 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1408:24:1411 | this access | UseUseExplosion.cs:24:1425:24:1428 | this access | +| UseUseExplosion.cs:24:1408:24:1411 | this access | UseUseExplosion.cs:24:1963:24:1968 | this access | +| UseUseExplosion.cs:24:1425:24:1428 | [post] this access | UseUseExplosion.cs:24:1442:24:1445 | this access | +| UseUseExplosion.cs:24:1425:24:1428 | [post] this access | UseUseExplosion.cs:24:1948:24:1953 | this access | +| UseUseExplosion.cs:24:1425:24:1428 | access to property Prop | UseUseExplosion.cs:24:1442:24:1445 | access to property Prop | +| UseUseExplosion.cs:24:1425:24:1428 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1425:24:1428 | this access | UseUseExplosion.cs:24:1442:24:1445 | this access | +| UseUseExplosion.cs:24:1425:24:1428 | this access | UseUseExplosion.cs:24:1948:24:1953 | this access | +| UseUseExplosion.cs:24:1442:24:1445 | [post] this access | UseUseExplosion.cs:24:1459:24:1462 | this access | +| UseUseExplosion.cs:24:1442:24:1445 | [post] this access | UseUseExplosion.cs:24:1933:24:1938 | this access | +| UseUseExplosion.cs:24:1442:24:1445 | access to property Prop | UseUseExplosion.cs:24:1459:24:1462 | access to property Prop | +| UseUseExplosion.cs:24:1442:24:1445 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1442:24:1445 | this access | UseUseExplosion.cs:24:1459:24:1462 | this access | +| UseUseExplosion.cs:24:1442:24:1445 | this access | UseUseExplosion.cs:24:1933:24:1938 | this access | +| UseUseExplosion.cs:24:1459:24:1462 | [post] this access | UseUseExplosion.cs:24:1476:24:1479 | this access | +| UseUseExplosion.cs:24:1459:24:1462 | [post] this access | UseUseExplosion.cs:24:1918:24:1923 | this access | +| UseUseExplosion.cs:24:1459:24:1462 | access to property Prop | UseUseExplosion.cs:24:1476:24:1479 | access to property Prop | +| UseUseExplosion.cs:24:1459:24:1462 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1459:24:1462 | this access | UseUseExplosion.cs:24:1476:24:1479 | this access | +| UseUseExplosion.cs:24:1459:24:1462 | this access | UseUseExplosion.cs:24:1918:24:1923 | this access | +| UseUseExplosion.cs:24:1476:24:1479 | [post] this access | UseUseExplosion.cs:24:1493:24:1496 | this access | +| UseUseExplosion.cs:24:1476:24:1479 | [post] this access | UseUseExplosion.cs:24:1903:24:1908 | this access | +| UseUseExplosion.cs:24:1476:24:1479 | access to property Prop | UseUseExplosion.cs:24:1493:24:1496 | access to property Prop | +| UseUseExplosion.cs:24:1476:24:1479 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1476:24:1479 | this access | UseUseExplosion.cs:24:1493:24:1496 | this access | +| UseUseExplosion.cs:24:1476:24:1479 | this access | UseUseExplosion.cs:24:1903:24:1908 | this access | +| UseUseExplosion.cs:24:1493:24:1496 | [post] this access | UseUseExplosion.cs:24:1510:24:1513 | this access | +| UseUseExplosion.cs:24:1493:24:1496 | [post] this access | UseUseExplosion.cs:24:1888:24:1893 | this access | +| UseUseExplosion.cs:24:1493:24:1496 | access to property Prop | UseUseExplosion.cs:24:1510:24:1513 | access to property Prop | +| UseUseExplosion.cs:24:1493:24:1496 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1493:24:1496 | this access | UseUseExplosion.cs:24:1510:24:1513 | this access | +| UseUseExplosion.cs:24:1493:24:1496 | this access | UseUseExplosion.cs:24:1888:24:1893 | this access | +| UseUseExplosion.cs:24:1510:24:1513 | [post] this access | UseUseExplosion.cs:24:1527:24:1530 | this access | +| UseUseExplosion.cs:24:1510:24:1513 | [post] this access | UseUseExplosion.cs:24:1873:24:1878 | this access | +| UseUseExplosion.cs:24:1510:24:1513 | access to property Prop | UseUseExplosion.cs:24:1527:24:1530 | access to property Prop | +| UseUseExplosion.cs:24:1510:24:1513 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1510:24:1513 | this access | UseUseExplosion.cs:24:1527:24:1530 | this access | +| UseUseExplosion.cs:24:1510:24:1513 | this access | UseUseExplosion.cs:24:1873:24:1878 | this access | +| UseUseExplosion.cs:24:1527:24:1530 | [post] this access | UseUseExplosion.cs:24:1544:24:1547 | this access | +| UseUseExplosion.cs:24:1527:24:1530 | [post] this access | UseUseExplosion.cs:24:1858:24:1863 | this access | +| UseUseExplosion.cs:24:1527:24:1530 | access to property Prop | UseUseExplosion.cs:24:1544:24:1547 | access to property Prop | +| UseUseExplosion.cs:24:1527:24:1530 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1527:24:1530 | this access | UseUseExplosion.cs:24:1544:24:1547 | this access | +| UseUseExplosion.cs:24:1527:24:1530 | this access | UseUseExplosion.cs:24:1858:24:1863 | this access | +| UseUseExplosion.cs:24:1544:24:1547 | [post] this access | UseUseExplosion.cs:24:1561:24:1564 | this access | +| UseUseExplosion.cs:24:1544:24:1547 | [post] this access | UseUseExplosion.cs:24:1843:24:1848 | this access | +| UseUseExplosion.cs:24:1544:24:1547 | access to property Prop | UseUseExplosion.cs:24:1561:24:1564 | access to property Prop | +| UseUseExplosion.cs:24:1544:24:1547 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1544:24:1547 | this access | UseUseExplosion.cs:24:1561:24:1564 | this access | +| UseUseExplosion.cs:24:1544:24:1547 | this access | UseUseExplosion.cs:24:1843:24:1848 | this access | +| UseUseExplosion.cs:24:1561:24:1564 | [post] this access | UseUseExplosion.cs:24:1577:24:1580 | this access | +| UseUseExplosion.cs:24:1561:24:1564 | [post] this access | UseUseExplosion.cs:24:1828:24:1833 | this access | +| UseUseExplosion.cs:24:1561:24:1564 | access to property Prop | UseUseExplosion.cs:24:1577:24:1580 | access to property Prop | +| UseUseExplosion.cs:24:1561:24:1564 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1561:24:1564 | this access | UseUseExplosion.cs:24:1577:24:1580 | this access | +| UseUseExplosion.cs:24:1561:24:1564 | this access | UseUseExplosion.cs:24:1828:24:1833 | this access | +| UseUseExplosion.cs:24:1577:24:1580 | [post] this access | UseUseExplosion.cs:24:1593:24:1596 | this access | +| UseUseExplosion.cs:24:1577:24:1580 | [post] this access | UseUseExplosion.cs:24:1813:24:1818 | this access | +| UseUseExplosion.cs:24:1577:24:1580 | access to property Prop | UseUseExplosion.cs:24:1593:24:1596 | access to property Prop | +| UseUseExplosion.cs:24:1577:24:1580 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1577:24:1580 | this access | UseUseExplosion.cs:24:1593:24:1596 | this access | +| UseUseExplosion.cs:24:1577:24:1580 | this access | UseUseExplosion.cs:24:1813:24:1818 | this access | +| UseUseExplosion.cs:24:1593:24:1596 | [post] this access | UseUseExplosion.cs:24:1609:24:1612 | this access | +| UseUseExplosion.cs:24:1593:24:1596 | [post] this access | UseUseExplosion.cs:24:1798:24:1803 | this access | +| UseUseExplosion.cs:24:1593:24:1596 | access to property Prop | UseUseExplosion.cs:24:1609:24:1612 | access to property Prop | +| UseUseExplosion.cs:24:1593:24:1596 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1593:24:1596 | this access | UseUseExplosion.cs:24:1609:24:1612 | this access | +| UseUseExplosion.cs:24:1593:24:1596 | this access | UseUseExplosion.cs:24:1798:24:1803 | this access | +| UseUseExplosion.cs:24:1609:24:1612 | [post] this access | UseUseExplosion.cs:24:1625:24:1628 | this access | +| UseUseExplosion.cs:24:1609:24:1612 | [post] this access | UseUseExplosion.cs:24:1783:24:1788 | this access | +| UseUseExplosion.cs:24:1609:24:1612 | access to property Prop | UseUseExplosion.cs:24:1625:24:1628 | access to property Prop | +| UseUseExplosion.cs:24:1609:24:1612 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1609:24:1612 | this access | UseUseExplosion.cs:24:1625:24:1628 | this access | +| UseUseExplosion.cs:24:1609:24:1612 | this access | UseUseExplosion.cs:24:1783:24:1788 | this access | +| UseUseExplosion.cs:24:1625:24:1628 | [post] this access | UseUseExplosion.cs:24:1641:24:1644 | this access | +| UseUseExplosion.cs:24:1625:24:1628 | [post] this access | UseUseExplosion.cs:24:1768:24:1773 | this access | +| UseUseExplosion.cs:24:1625:24:1628 | access to property Prop | UseUseExplosion.cs:24:1641:24:1644 | access to property Prop | +| UseUseExplosion.cs:24:1625:24:1628 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1625:24:1628 | this access | UseUseExplosion.cs:24:1641:24:1644 | this access | +| UseUseExplosion.cs:24:1625:24:1628 | this access | UseUseExplosion.cs:24:1768:24:1773 | this access | +| UseUseExplosion.cs:24:1641:24:1644 | [post] this access | UseUseExplosion.cs:24:1657:24:1660 | this access | +| UseUseExplosion.cs:24:1641:24:1644 | [post] this access | UseUseExplosion.cs:24:1753:24:1758 | this access | +| UseUseExplosion.cs:24:1641:24:1644 | access to property Prop | UseUseExplosion.cs:24:1657:24:1660 | access to property Prop | +| UseUseExplosion.cs:24:1641:24:1644 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1641:24:1644 | this access | UseUseExplosion.cs:24:1657:24:1660 | this access | +| UseUseExplosion.cs:24:1641:24:1644 | this access | UseUseExplosion.cs:24:1753:24:1758 | this access | +| UseUseExplosion.cs:24:1657:24:1660 | [post] this access | UseUseExplosion.cs:24:1673:24:1676 | this access | +| UseUseExplosion.cs:24:1657:24:1660 | [post] this access | UseUseExplosion.cs:24:1738:24:1743 | this access | +| UseUseExplosion.cs:24:1657:24:1660 | access to property Prop | UseUseExplosion.cs:24:1673:24:1676 | access to property Prop | +| UseUseExplosion.cs:24:1657:24:1660 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1657:24:1660 | this access | UseUseExplosion.cs:24:1673:24:1676 | this access | +| UseUseExplosion.cs:24:1657:24:1660 | this access | UseUseExplosion.cs:24:1738:24:1743 | this access | +| UseUseExplosion.cs:24:1673:24:1676 | [post] this access | UseUseExplosion.cs:24:1689:24:1692 | this access | +| UseUseExplosion.cs:24:1673:24:1676 | [post] this access | UseUseExplosion.cs:24:1723:24:1728 | this access | +| UseUseExplosion.cs:24:1673:24:1676 | access to property Prop | UseUseExplosion.cs:24:1689:24:1692 | access to property Prop | +| UseUseExplosion.cs:24:1673:24:1676 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1673:24:1676 | this access | UseUseExplosion.cs:24:1689:24:1692 | this access | +| UseUseExplosion.cs:24:1673:24:1676 | this access | UseUseExplosion.cs:24:1723:24:1728 | this access | +| UseUseExplosion.cs:24:1689:24:1692 | [post] this access | UseUseExplosion.cs:24:1708:24:1713 | this access | +| UseUseExplosion.cs:24:1689:24:1692 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1689:24:1692 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1689:24:1692 | this access | UseUseExplosion.cs:24:1708:24:1713 | this access | +| UseUseExplosion.cs:24:1689:24:1692 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1708:24:1713 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1708:24:1713 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1712:24:1712 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1723:24:1728 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1723:24:1728 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1727:24:1727 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1738:24:1743 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1738:24:1743 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1742:24:1742 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1753:24:1758 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1753:24:1758 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1757:24:1757 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1768:24:1773 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1768:24:1773 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1772:24:1772 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1783:24:1788 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1783:24:1788 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1787:24:1787 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1798:24:1803 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1798:24:1803 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1802:24:1802 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1813:24:1818 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1813:24:1818 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1817:24:1817 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1828:24:1833 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1828:24:1833 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1832:24:1832 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1843:24:1848 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1843:24:1848 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1847:24:1847 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1858:24:1863 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1858:24:1863 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1862:24:1862 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1873:24:1878 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1873:24:1878 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1877:24:1877 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1888:24:1893 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1888:24:1893 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1892:24:1892 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1903:24:1908 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1903:24:1908 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1907:24:1907 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1918:24:1923 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1918:24:1923 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1922:24:1922 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1933:24:1938 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1933:24:1938 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1937:24:1937 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1948:24:1953 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1948:24:1953 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1952:24:1952 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1963:24:1968 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1963:24:1968 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1967:24:1967 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1978:24:1983 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1978:24:1983 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1982:24:1982 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1993:24:1998 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1993:24:1998 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1997:24:1997 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2008:24:2013 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2008:24:2013 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2012:24:2012 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2023:24:2028 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2023:24:2028 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2027:24:2027 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2038:24:2043 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2038:24:2043 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2042:24:2042 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2053:24:2058 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2053:24:2058 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2057:24:2057 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2068:24:2073 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2068:24:2073 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2072:24:2072 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2083:24:2088 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2083:24:2088 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2087:24:2087 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2098:24:2103 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2098:24:2103 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2102:24:2102 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2113:24:2118 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2113:24:2118 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2117:24:2117 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2128:24:2133 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2128:24:2133 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2132:24:2132 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2143:24:2148 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2143:24:2148 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2147:24:2147 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2158:24:2163 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2158:24:2163 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2162:24:2162 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2173:24:2178 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2173:24:2178 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2177:24:2177 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2188:24:2193 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2188:24:2193 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2192:24:2192 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2203:24:2208 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2203:24:2208 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2207:24:2207 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2218:24:2223 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2218:24:2223 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2222:24:2222 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2233:24:2238 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2233:24:2238 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2237:24:2237 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2248:24:2253 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2248:24:2253 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2252:24:2252 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2263:24:2268 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2263:24:2268 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2267:24:2267 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2278:24:2283 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2278:24:2283 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2282:24:2282 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2293:24:2298 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2293:24:2298 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2297:24:2297 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2308:24:2313 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2308:24:2313 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2312:24:2312 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2323:24:2328 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2323:24:2328 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2327:24:2327 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2338:24:2343 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2338:24:2343 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2342:24:2342 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2353:24:2358 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2353:24:2358 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2357:24:2357 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2368:24:2373 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2368:24:2373 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2372:24:2372 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2383:24:2388 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2383:24:2388 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2387:24:2387 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2398:24:2403 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2398:24:2403 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2402:24:2402 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2413:24:2418 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2413:24:2418 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2417:24:2417 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2428:24:2433 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2428:24:2433 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2432:24:2432 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2443:24:2448 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2443:24:2448 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2447:24:2447 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2458:24:2463 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2458:24:2463 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2462:24:2462 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2473:24:2478 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2473:24:2478 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2477:24:2477 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2488:24:2493 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2488:24:2493 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2492:24:2492 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2503:24:2508 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2503:24:2508 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2507:24:2507 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2518:24:2523 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2518:24:2523 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2522:24:2522 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2533:24:2538 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2533:24:2538 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2537:24:2537 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2548:24:2553 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2548:24:2553 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2552:24:2552 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2563:24:2568 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2563:24:2568 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2567:24:2567 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2578:24:2583 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2578:24:2583 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2582:24:2582 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2593:24:2598 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2593:24:2598 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2597:24:2597 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2608:24:2613 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2608:24:2613 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2612:24:2612 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2623:24:2628 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2623:24:2628 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2627:24:2627 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2638:24:2643 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2638:24:2643 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2642:24:2642 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2653:24:2658 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2653:24:2658 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2657:24:2657 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2668:24:2673 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2668:24:2673 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2672:24:2672 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2683:24:2688 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2683:24:2688 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2687:24:2687 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2698:24:2703 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2698:24:2703 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2702:24:2702 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2713:24:2718 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2713:24:2718 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2717:24:2717 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2728:24:2733 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2728:24:2733 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2732:24:2732 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2743:24:2748 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2743:24:2748 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2747:24:2747 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2758:24:2763 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2758:24:2763 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2762:24:2762 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2773:24:2778 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2773:24:2778 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2777:24:2777 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2788:24:2793 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2788:24:2793 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2792:24:2792 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2803:24:2808 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2803:24:2808 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2807:24:2807 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2818:24:2823 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2818:24:2823 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2822:24:2822 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2833:24:2838 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2833:24:2838 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2837:24:2837 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2848:24:2853 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2848:24:2853 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2852:24:2852 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2863:24:2868 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2863:24:2868 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2867:24:2867 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2878:24:2883 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2878:24:2883 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2882:24:2882 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2893:24:2898 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2893:24:2898 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2897:24:2897 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2908:24:2913 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2908:24:2913 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2912:24:2912 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2923:24:2928 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2923:24:2928 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2927:24:2927 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2938:24:2943 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2938:24:2943 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2942:24:2942 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2953:24:2958 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2953:24:2958 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2957:24:2957 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2968:24:2973 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2968:24:2973 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2972:24:2972 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2983:24:2988 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2983:24:2988 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2987:24:2987 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2998:24:3003 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2998:24:3003 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3002:24:3002 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3013:24:3018 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3013:24:3018 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3017:24:3017 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3028:24:3033 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3028:24:3033 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3032:24:3032 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3043:24:3048 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3043:24:3048 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3047:24:3047 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3058:24:3063 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3058:24:3063 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3062:24:3062 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3073:24:3078 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3073:24:3078 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3077:24:3077 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3088:24:3093 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3088:24:3093 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3092:24:3092 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3103:24:3108 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3103:24:3108 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3107:24:3107 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3118:24:3123 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3118:24:3123 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3122:24:3122 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3133:24:3138 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3133:24:3138 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3137:24:3137 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3148:24:3153 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3148:24:3153 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3152:24:3152 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3163:24:3168 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3163:24:3168 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3167:24:3167 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3178:24:3183 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3178:24:3183 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3182:24:3182 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3193:24:3198 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3193:24:3198 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3197:24:3197 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | UseUseExplosion.cs:25:13:25:16 | access to property Prop | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1712:25:1712 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1727:25:1727 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1742:25:1742 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1757:25:1757 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1772:25:1772 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1787:25:1787 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1802:25:1802 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1817:25:1817 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1832:25:1832 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1847:25:1847 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1862:25:1862 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1877:25:1877 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1892:25:1892 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1907:25:1907 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1922:25:1922 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1937:25:1937 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1952:25:1952 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1967:25:1967 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1982:25:1982 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1997:25:1997 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2012:25:2012 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2027:25:2027 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2042:25:2042 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2057:25:2057 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2072:25:2072 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2087:25:2087 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2102:25:2102 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2117:25:2117 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2132:25:2132 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2147:25:2147 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2162:25:2162 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2177:25:2177 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2192:25:2192 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2207:25:2207 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2222:25:2222 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2237:25:2237 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2252:25:2252 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2267:25:2267 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2282:25:2282 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2297:25:2297 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2312:25:2312 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2327:25:2327 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2342:25:2342 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2357:25:2357 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2372:25:2372 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2387:25:2387 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2402:25:2402 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2417:25:2417 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2432:25:2432 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2447:25:2447 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2462:25:2462 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2477:25:2477 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2492:25:2492 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2507:25:2507 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2522:25:2522 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2537:25:2537 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2552:25:2552 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2567:25:2567 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2582:25:2582 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2597:25:2597 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2612:25:2612 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2627:25:2627 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2642:25:2642 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2657:25:2657 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2672:25:2672 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2687:25:2687 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2702:25:2702 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2717:25:2717 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2732:25:2732 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2747:25:2747 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2762:25:2762 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2777:25:2777 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2792:25:2792 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2807:25:2807 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2822:25:2822 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2837:25:2837 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2852:25:2852 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2867:25:2867 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2882:25:2882 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2897:25:2897 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2912:25:2912 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2927:25:2927 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2942:25:2942 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2957:25:2957 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2972:25:2972 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2987:25:2987 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3002:25:3002 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3017:25:3017 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3032:25:3032 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3047:25:3047 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3062:25:3062 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3077:25:3077 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3092:25:3092 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3107:25:3107 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3122:25:3122 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3137:25:3137 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3152:25:3152 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3167:25:3167 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3182:25:3182 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3197:25:3197 | access to local variable x | +| UseUseExplosion.cs:25:13:25:16 | [post] this access | UseUseExplosion.cs:25:31:25:34 | this access | +| UseUseExplosion.cs:25:13:25:16 | [post] this access | UseUseExplosion.cs:25:3193:25:3198 | this access | +| UseUseExplosion.cs:25:13:25:16 | access to property Prop | UseUseExplosion.cs:25:31:25:34 | access to property Prop | +| UseUseExplosion.cs:25:13:25:16 | this access | UseUseExplosion.cs:25:31:25:34 | this access | +| UseUseExplosion.cs:25:13:25:16 | this access | UseUseExplosion.cs:25:3193:25:3198 | this access | +| UseUseExplosion.cs:25:31:25:34 | [post] this access | UseUseExplosion.cs:25:48:25:51 | this access | +| UseUseExplosion.cs:25:31:25:34 | [post] this access | UseUseExplosion.cs:25:3178:25:3183 | this access | +| UseUseExplosion.cs:25:31:25:34 | access to property Prop | UseUseExplosion.cs:25:48:25:51 | access to property Prop | +| UseUseExplosion.cs:25:31:25:34 | this access | UseUseExplosion.cs:25:48:25:51 | this access | +| UseUseExplosion.cs:25:31:25:34 | this access | UseUseExplosion.cs:25:3178:25:3183 | this access | +| UseUseExplosion.cs:25:48:25:51 | [post] this access | UseUseExplosion.cs:25:65:25:68 | this access | +| UseUseExplosion.cs:25:48:25:51 | [post] this access | UseUseExplosion.cs:25:3163:25:3168 | this access | +| UseUseExplosion.cs:25:48:25:51 | access to property Prop | UseUseExplosion.cs:25:65:25:68 | access to property Prop | +| UseUseExplosion.cs:25:48:25:51 | this access | UseUseExplosion.cs:25:65:25:68 | this access | +| UseUseExplosion.cs:25:48:25:51 | this access | UseUseExplosion.cs:25:3163:25:3168 | this access | +| UseUseExplosion.cs:25:65:25:68 | [post] this access | UseUseExplosion.cs:25:82:25:85 | this access | +| UseUseExplosion.cs:25:65:25:68 | [post] this access | UseUseExplosion.cs:25:3148:25:3153 | this access | +| UseUseExplosion.cs:25:65:25:68 | access to property Prop | UseUseExplosion.cs:25:82:25:85 | access to property Prop | +| UseUseExplosion.cs:25:65:25:68 | this access | UseUseExplosion.cs:25:82:25:85 | this access | +| UseUseExplosion.cs:25:65:25:68 | this access | UseUseExplosion.cs:25:3148:25:3153 | this access | +| UseUseExplosion.cs:25:82:25:85 | [post] this access | UseUseExplosion.cs:25:99:25:102 | this access | +| UseUseExplosion.cs:25:82:25:85 | [post] this access | UseUseExplosion.cs:25:3133:25:3138 | this access | +| UseUseExplosion.cs:25:82:25:85 | access to property Prop | UseUseExplosion.cs:25:99:25:102 | access to property Prop | +| UseUseExplosion.cs:25:82:25:85 | this access | UseUseExplosion.cs:25:99:25:102 | this access | +| UseUseExplosion.cs:25:82:25:85 | this access | UseUseExplosion.cs:25:3133:25:3138 | this access | +| UseUseExplosion.cs:25:99:25:102 | [post] this access | UseUseExplosion.cs:25:116:25:119 | this access | +| UseUseExplosion.cs:25:99:25:102 | [post] this access | UseUseExplosion.cs:25:3118:25:3123 | this access | +| UseUseExplosion.cs:25:99:25:102 | access to property Prop | UseUseExplosion.cs:25:116:25:119 | access to property Prop | +| UseUseExplosion.cs:25:99:25:102 | this access | UseUseExplosion.cs:25:116:25:119 | this access | +| UseUseExplosion.cs:25:99:25:102 | this access | UseUseExplosion.cs:25:3118:25:3123 | this access | +| UseUseExplosion.cs:25:116:25:119 | [post] this access | UseUseExplosion.cs:25:133:25:136 | this access | +| UseUseExplosion.cs:25:116:25:119 | [post] this access | UseUseExplosion.cs:25:3103:25:3108 | this access | +| UseUseExplosion.cs:25:116:25:119 | access to property Prop | UseUseExplosion.cs:25:133:25:136 | access to property Prop | +| UseUseExplosion.cs:25:116:25:119 | this access | UseUseExplosion.cs:25:133:25:136 | this access | +| UseUseExplosion.cs:25:116:25:119 | this access | UseUseExplosion.cs:25:3103:25:3108 | this access | +| UseUseExplosion.cs:25:133:25:136 | [post] this access | UseUseExplosion.cs:25:150:25:153 | this access | +| UseUseExplosion.cs:25:133:25:136 | [post] this access | UseUseExplosion.cs:25:3088:25:3093 | this access | +| UseUseExplosion.cs:25:133:25:136 | access to property Prop | UseUseExplosion.cs:25:150:25:153 | access to property Prop | +| UseUseExplosion.cs:25:133:25:136 | this access | UseUseExplosion.cs:25:150:25:153 | this access | +| UseUseExplosion.cs:25:133:25:136 | this access | UseUseExplosion.cs:25:3088:25:3093 | this access | +| UseUseExplosion.cs:25:150:25:153 | [post] this access | UseUseExplosion.cs:25:167:25:170 | this access | +| UseUseExplosion.cs:25:150:25:153 | [post] this access | UseUseExplosion.cs:25:3073:25:3078 | this access | +| UseUseExplosion.cs:25:150:25:153 | access to property Prop | UseUseExplosion.cs:25:167:25:170 | access to property Prop | +| UseUseExplosion.cs:25:150:25:153 | this access | UseUseExplosion.cs:25:167:25:170 | this access | +| UseUseExplosion.cs:25:150:25:153 | this access | UseUseExplosion.cs:25:3073:25:3078 | this access | +| UseUseExplosion.cs:25:167:25:170 | [post] this access | UseUseExplosion.cs:25:184:25:187 | this access | +| UseUseExplosion.cs:25:167:25:170 | [post] this access | UseUseExplosion.cs:25:3058:25:3063 | this access | +| UseUseExplosion.cs:25:167:25:170 | access to property Prop | UseUseExplosion.cs:25:184:25:187 | access to property Prop | +| UseUseExplosion.cs:25:167:25:170 | this access | UseUseExplosion.cs:25:184:25:187 | this access | +| UseUseExplosion.cs:25:167:25:170 | this access | UseUseExplosion.cs:25:3058:25:3063 | this access | +| UseUseExplosion.cs:25:184:25:187 | [post] this access | UseUseExplosion.cs:25:201:25:204 | this access | +| UseUseExplosion.cs:25:184:25:187 | [post] this access | UseUseExplosion.cs:25:3043:25:3048 | this access | +| UseUseExplosion.cs:25:184:25:187 | access to property Prop | UseUseExplosion.cs:25:201:25:204 | access to property Prop | +| UseUseExplosion.cs:25:184:25:187 | this access | UseUseExplosion.cs:25:201:25:204 | this access | +| UseUseExplosion.cs:25:184:25:187 | this access | UseUseExplosion.cs:25:3043:25:3048 | this access | +| UseUseExplosion.cs:25:201:25:204 | [post] this access | UseUseExplosion.cs:25:218:25:221 | this access | +| UseUseExplosion.cs:25:201:25:204 | [post] this access | UseUseExplosion.cs:25:3028:25:3033 | this access | +| UseUseExplosion.cs:25:201:25:204 | access to property Prop | UseUseExplosion.cs:25:218:25:221 | access to property Prop | +| UseUseExplosion.cs:25:201:25:204 | this access | UseUseExplosion.cs:25:218:25:221 | this access | +| UseUseExplosion.cs:25:201:25:204 | this access | UseUseExplosion.cs:25:3028:25:3033 | this access | +| UseUseExplosion.cs:25:218:25:221 | [post] this access | UseUseExplosion.cs:25:235:25:238 | this access | +| UseUseExplosion.cs:25:218:25:221 | [post] this access | UseUseExplosion.cs:25:3013:25:3018 | this access | +| UseUseExplosion.cs:25:218:25:221 | access to property Prop | UseUseExplosion.cs:25:235:25:238 | access to property Prop | +| UseUseExplosion.cs:25:218:25:221 | this access | UseUseExplosion.cs:25:235:25:238 | this access | +| UseUseExplosion.cs:25:218:25:221 | this access | UseUseExplosion.cs:25:3013:25:3018 | this access | +| UseUseExplosion.cs:25:235:25:238 | [post] this access | UseUseExplosion.cs:25:252:25:255 | this access | +| UseUseExplosion.cs:25:235:25:238 | [post] this access | UseUseExplosion.cs:25:2998:25:3003 | this access | +| UseUseExplosion.cs:25:235:25:238 | access to property Prop | UseUseExplosion.cs:25:252:25:255 | access to property Prop | +| UseUseExplosion.cs:25:235:25:238 | this access | UseUseExplosion.cs:25:252:25:255 | this access | +| UseUseExplosion.cs:25:235:25:238 | this access | UseUseExplosion.cs:25:2998:25:3003 | this access | +| UseUseExplosion.cs:25:252:25:255 | [post] this access | UseUseExplosion.cs:25:269:25:272 | this access | +| UseUseExplosion.cs:25:252:25:255 | [post] this access | UseUseExplosion.cs:25:2983:25:2988 | this access | +| UseUseExplosion.cs:25:252:25:255 | access to property Prop | UseUseExplosion.cs:25:269:25:272 | access to property Prop | +| UseUseExplosion.cs:25:252:25:255 | this access | UseUseExplosion.cs:25:269:25:272 | this access | +| UseUseExplosion.cs:25:252:25:255 | this access | UseUseExplosion.cs:25:2983:25:2988 | this access | +| UseUseExplosion.cs:25:269:25:272 | [post] this access | UseUseExplosion.cs:25:286:25:289 | this access | +| UseUseExplosion.cs:25:269:25:272 | [post] this access | UseUseExplosion.cs:25:2968:25:2973 | this access | +| UseUseExplosion.cs:25:269:25:272 | access to property Prop | UseUseExplosion.cs:25:286:25:289 | access to property Prop | +| UseUseExplosion.cs:25:269:25:272 | this access | UseUseExplosion.cs:25:286:25:289 | this access | +| UseUseExplosion.cs:25:269:25:272 | this access | UseUseExplosion.cs:25:2968:25:2973 | this access | +| UseUseExplosion.cs:25:286:25:289 | [post] this access | UseUseExplosion.cs:25:303:25:306 | this access | +| UseUseExplosion.cs:25:286:25:289 | [post] this access | UseUseExplosion.cs:25:2953:25:2958 | this access | +| UseUseExplosion.cs:25:286:25:289 | access to property Prop | UseUseExplosion.cs:25:303:25:306 | access to property Prop | +| UseUseExplosion.cs:25:286:25:289 | this access | UseUseExplosion.cs:25:303:25:306 | this access | +| UseUseExplosion.cs:25:286:25:289 | this access | UseUseExplosion.cs:25:2953:25:2958 | this access | +| UseUseExplosion.cs:25:303:25:306 | [post] this access | UseUseExplosion.cs:25:320:25:323 | this access | +| UseUseExplosion.cs:25:303:25:306 | [post] this access | UseUseExplosion.cs:25:2938:25:2943 | this access | +| UseUseExplosion.cs:25:303:25:306 | access to property Prop | UseUseExplosion.cs:25:320:25:323 | access to property Prop | +| UseUseExplosion.cs:25:303:25:306 | this access | UseUseExplosion.cs:25:320:25:323 | this access | +| UseUseExplosion.cs:25:303:25:306 | this access | UseUseExplosion.cs:25:2938:25:2943 | this access | +| UseUseExplosion.cs:25:320:25:323 | [post] this access | UseUseExplosion.cs:25:337:25:340 | this access | +| UseUseExplosion.cs:25:320:25:323 | [post] this access | UseUseExplosion.cs:25:2923:25:2928 | this access | +| UseUseExplosion.cs:25:320:25:323 | access to property Prop | UseUseExplosion.cs:25:337:25:340 | access to property Prop | +| UseUseExplosion.cs:25:320:25:323 | this access | UseUseExplosion.cs:25:337:25:340 | this access | +| UseUseExplosion.cs:25:320:25:323 | this access | UseUseExplosion.cs:25:2923:25:2928 | this access | +| UseUseExplosion.cs:25:337:25:340 | [post] this access | UseUseExplosion.cs:25:354:25:357 | this access | +| UseUseExplosion.cs:25:337:25:340 | [post] this access | UseUseExplosion.cs:25:2908:25:2913 | this access | +| UseUseExplosion.cs:25:337:25:340 | access to property Prop | UseUseExplosion.cs:25:354:25:357 | access to property Prop | +| UseUseExplosion.cs:25:337:25:340 | this access | UseUseExplosion.cs:25:354:25:357 | this access | +| UseUseExplosion.cs:25:337:25:340 | this access | UseUseExplosion.cs:25:2908:25:2913 | this access | +| UseUseExplosion.cs:25:354:25:357 | [post] this access | UseUseExplosion.cs:25:371:25:374 | this access | +| UseUseExplosion.cs:25:354:25:357 | [post] this access | UseUseExplosion.cs:25:2893:25:2898 | this access | +| UseUseExplosion.cs:25:354:25:357 | access to property Prop | UseUseExplosion.cs:25:371:25:374 | access to property Prop | +| UseUseExplosion.cs:25:354:25:357 | this access | UseUseExplosion.cs:25:371:25:374 | this access | +| UseUseExplosion.cs:25:354:25:357 | this access | UseUseExplosion.cs:25:2893:25:2898 | this access | +| UseUseExplosion.cs:25:371:25:374 | [post] this access | UseUseExplosion.cs:25:388:25:391 | this access | +| UseUseExplosion.cs:25:371:25:374 | [post] this access | UseUseExplosion.cs:25:2878:25:2883 | this access | +| UseUseExplosion.cs:25:371:25:374 | access to property Prop | UseUseExplosion.cs:25:388:25:391 | access to property Prop | +| UseUseExplosion.cs:25:371:25:374 | this access | UseUseExplosion.cs:25:388:25:391 | this access | +| UseUseExplosion.cs:25:371:25:374 | this access | UseUseExplosion.cs:25:2878:25:2883 | this access | +| UseUseExplosion.cs:25:388:25:391 | [post] this access | UseUseExplosion.cs:25:405:25:408 | this access | +| UseUseExplosion.cs:25:388:25:391 | [post] this access | UseUseExplosion.cs:25:2863:25:2868 | this access | +| UseUseExplosion.cs:25:388:25:391 | access to property Prop | UseUseExplosion.cs:25:405:25:408 | access to property Prop | +| UseUseExplosion.cs:25:388:25:391 | this access | UseUseExplosion.cs:25:405:25:408 | this access | +| UseUseExplosion.cs:25:388:25:391 | this access | UseUseExplosion.cs:25:2863:25:2868 | this access | +| UseUseExplosion.cs:25:405:25:408 | [post] this access | UseUseExplosion.cs:25:422:25:425 | this access | +| UseUseExplosion.cs:25:405:25:408 | [post] this access | UseUseExplosion.cs:25:2848:25:2853 | this access | +| UseUseExplosion.cs:25:405:25:408 | access to property Prop | UseUseExplosion.cs:25:422:25:425 | access to property Prop | +| UseUseExplosion.cs:25:405:25:408 | this access | UseUseExplosion.cs:25:422:25:425 | this access | +| UseUseExplosion.cs:25:405:25:408 | this access | UseUseExplosion.cs:25:2848:25:2853 | this access | +| UseUseExplosion.cs:25:422:25:425 | [post] this access | UseUseExplosion.cs:25:439:25:442 | this access | +| UseUseExplosion.cs:25:422:25:425 | [post] this access | UseUseExplosion.cs:25:2833:25:2838 | this access | +| UseUseExplosion.cs:25:422:25:425 | access to property Prop | UseUseExplosion.cs:25:439:25:442 | access to property Prop | +| UseUseExplosion.cs:25:422:25:425 | this access | UseUseExplosion.cs:25:439:25:442 | this access | +| UseUseExplosion.cs:25:422:25:425 | this access | UseUseExplosion.cs:25:2833:25:2838 | this access | +| UseUseExplosion.cs:25:439:25:442 | [post] this access | UseUseExplosion.cs:25:456:25:459 | this access | +| UseUseExplosion.cs:25:439:25:442 | [post] this access | UseUseExplosion.cs:25:2818:25:2823 | this access | +| UseUseExplosion.cs:25:439:25:442 | access to property Prop | UseUseExplosion.cs:25:456:25:459 | access to property Prop | +| UseUseExplosion.cs:25:439:25:442 | this access | UseUseExplosion.cs:25:456:25:459 | this access | +| UseUseExplosion.cs:25:439:25:442 | this access | UseUseExplosion.cs:25:2818:25:2823 | this access | +| UseUseExplosion.cs:25:456:25:459 | [post] this access | UseUseExplosion.cs:25:473:25:476 | this access | +| UseUseExplosion.cs:25:456:25:459 | [post] this access | UseUseExplosion.cs:25:2803:25:2808 | this access | +| UseUseExplosion.cs:25:456:25:459 | access to property Prop | UseUseExplosion.cs:25:473:25:476 | access to property Prop | +| UseUseExplosion.cs:25:456:25:459 | this access | UseUseExplosion.cs:25:473:25:476 | this access | +| UseUseExplosion.cs:25:456:25:459 | this access | UseUseExplosion.cs:25:2803:25:2808 | this access | +| UseUseExplosion.cs:25:473:25:476 | [post] this access | UseUseExplosion.cs:25:490:25:493 | this access | +| UseUseExplosion.cs:25:473:25:476 | [post] this access | UseUseExplosion.cs:25:2788:25:2793 | this access | +| UseUseExplosion.cs:25:473:25:476 | access to property Prop | UseUseExplosion.cs:25:490:25:493 | access to property Prop | +| UseUseExplosion.cs:25:473:25:476 | this access | UseUseExplosion.cs:25:490:25:493 | this access | +| UseUseExplosion.cs:25:473:25:476 | this access | UseUseExplosion.cs:25:2788:25:2793 | this access | +| UseUseExplosion.cs:25:490:25:493 | [post] this access | UseUseExplosion.cs:25:507:25:510 | this access | +| UseUseExplosion.cs:25:490:25:493 | [post] this access | UseUseExplosion.cs:25:2773:25:2778 | this access | +| UseUseExplosion.cs:25:490:25:493 | access to property Prop | UseUseExplosion.cs:25:507:25:510 | access to property Prop | +| UseUseExplosion.cs:25:490:25:493 | this access | UseUseExplosion.cs:25:507:25:510 | this access | +| UseUseExplosion.cs:25:490:25:493 | this access | UseUseExplosion.cs:25:2773:25:2778 | this access | +| UseUseExplosion.cs:25:507:25:510 | [post] this access | UseUseExplosion.cs:25:524:25:527 | this access | +| UseUseExplosion.cs:25:507:25:510 | [post] this access | UseUseExplosion.cs:25:2758:25:2763 | this access | +| UseUseExplosion.cs:25:507:25:510 | access to property Prop | UseUseExplosion.cs:25:524:25:527 | access to property Prop | +| UseUseExplosion.cs:25:507:25:510 | this access | UseUseExplosion.cs:25:524:25:527 | this access | +| UseUseExplosion.cs:25:507:25:510 | this access | UseUseExplosion.cs:25:2758:25:2763 | this access | +| UseUseExplosion.cs:25:524:25:527 | [post] this access | UseUseExplosion.cs:25:541:25:544 | this access | +| UseUseExplosion.cs:25:524:25:527 | [post] this access | UseUseExplosion.cs:25:2743:25:2748 | this access | +| UseUseExplosion.cs:25:524:25:527 | access to property Prop | UseUseExplosion.cs:25:541:25:544 | access to property Prop | +| UseUseExplosion.cs:25:524:25:527 | this access | UseUseExplosion.cs:25:541:25:544 | this access | +| UseUseExplosion.cs:25:524:25:527 | this access | UseUseExplosion.cs:25:2743:25:2748 | this access | +| UseUseExplosion.cs:25:541:25:544 | [post] this access | UseUseExplosion.cs:25:558:25:561 | this access | +| UseUseExplosion.cs:25:541:25:544 | [post] this access | UseUseExplosion.cs:25:2728:25:2733 | this access | +| UseUseExplosion.cs:25:541:25:544 | access to property Prop | UseUseExplosion.cs:25:558:25:561 | access to property Prop | +| UseUseExplosion.cs:25:541:25:544 | this access | UseUseExplosion.cs:25:558:25:561 | this access | +| UseUseExplosion.cs:25:541:25:544 | this access | UseUseExplosion.cs:25:2728:25:2733 | this access | +| UseUseExplosion.cs:25:558:25:561 | [post] this access | UseUseExplosion.cs:25:575:25:578 | this access | +| UseUseExplosion.cs:25:558:25:561 | [post] this access | UseUseExplosion.cs:25:2713:25:2718 | this access | +| UseUseExplosion.cs:25:558:25:561 | access to property Prop | UseUseExplosion.cs:25:575:25:578 | access to property Prop | +| UseUseExplosion.cs:25:558:25:561 | this access | UseUseExplosion.cs:25:575:25:578 | this access | +| UseUseExplosion.cs:25:558:25:561 | this access | UseUseExplosion.cs:25:2713:25:2718 | this access | +| UseUseExplosion.cs:25:575:25:578 | [post] this access | UseUseExplosion.cs:25:592:25:595 | this access | +| UseUseExplosion.cs:25:575:25:578 | [post] this access | UseUseExplosion.cs:25:2698:25:2703 | this access | +| UseUseExplosion.cs:25:575:25:578 | access to property Prop | UseUseExplosion.cs:25:592:25:595 | access to property Prop | +| UseUseExplosion.cs:25:575:25:578 | this access | UseUseExplosion.cs:25:592:25:595 | this access | +| UseUseExplosion.cs:25:575:25:578 | this access | UseUseExplosion.cs:25:2698:25:2703 | this access | +| UseUseExplosion.cs:25:592:25:595 | [post] this access | UseUseExplosion.cs:25:609:25:612 | this access | +| UseUseExplosion.cs:25:592:25:595 | [post] this access | UseUseExplosion.cs:25:2683:25:2688 | this access | +| UseUseExplosion.cs:25:592:25:595 | access to property Prop | UseUseExplosion.cs:25:609:25:612 | access to property Prop | +| UseUseExplosion.cs:25:592:25:595 | this access | UseUseExplosion.cs:25:609:25:612 | this access | +| UseUseExplosion.cs:25:592:25:595 | this access | UseUseExplosion.cs:25:2683:25:2688 | this access | +| UseUseExplosion.cs:25:609:25:612 | [post] this access | UseUseExplosion.cs:25:626:25:629 | this access | +| UseUseExplosion.cs:25:609:25:612 | [post] this access | UseUseExplosion.cs:25:2668:25:2673 | this access | +| UseUseExplosion.cs:25:609:25:612 | access to property Prop | UseUseExplosion.cs:25:626:25:629 | access to property Prop | +| UseUseExplosion.cs:25:609:25:612 | this access | UseUseExplosion.cs:25:626:25:629 | this access | +| UseUseExplosion.cs:25:609:25:612 | this access | UseUseExplosion.cs:25:2668:25:2673 | this access | +| UseUseExplosion.cs:25:626:25:629 | [post] this access | UseUseExplosion.cs:25:643:25:646 | this access | +| UseUseExplosion.cs:25:626:25:629 | [post] this access | UseUseExplosion.cs:25:2653:25:2658 | this access | +| UseUseExplosion.cs:25:626:25:629 | access to property Prop | UseUseExplosion.cs:25:643:25:646 | access to property Prop | +| UseUseExplosion.cs:25:626:25:629 | this access | UseUseExplosion.cs:25:643:25:646 | this access | +| UseUseExplosion.cs:25:626:25:629 | this access | UseUseExplosion.cs:25:2653:25:2658 | this access | +| UseUseExplosion.cs:25:643:25:646 | [post] this access | UseUseExplosion.cs:25:660:25:663 | this access | +| UseUseExplosion.cs:25:643:25:646 | [post] this access | UseUseExplosion.cs:25:2638:25:2643 | this access | +| UseUseExplosion.cs:25:643:25:646 | access to property Prop | UseUseExplosion.cs:25:660:25:663 | access to property Prop | +| UseUseExplosion.cs:25:643:25:646 | this access | UseUseExplosion.cs:25:660:25:663 | this access | +| UseUseExplosion.cs:25:643:25:646 | this access | UseUseExplosion.cs:25:2638:25:2643 | this access | +| UseUseExplosion.cs:25:660:25:663 | [post] this access | UseUseExplosion.cs:25:677:25:680 | this access | +| UseUseExplosion.cs:25:660:25:663 | [post] this access | UseUseExplosion.cs:25:2623:25:2628 | this access | +| UseUseExplosion.cs:25:660:25:663 | access to property Prop | UseUseExplosion.cs:25:677:25:680 | access to property Prop | +| UseUseExplosion.cs:25:660:25:663 | this access | UseUseExplosion.cs:25:677:25:680 | this access | +| UseUseExplosion.cs:25:660:25:663 | this access | UseUseExplosion.cs:25:2623:25:2628 | this access | +| UseUseExplosion.cs:25:677:25:680 | [post] this access | UseUseExplosion.cs:25:694:25:697 | this access | +| UseUseExplosion.cs:25:677:25:680 | [post] this access | UseUseExplosion.cs:25:2608:25:2613 | this access | +| UseUseExplosion.cs:25:677:25:680 | access to property Prop | UseUseExplosion.cs:25:694:25:697 | access to property Prop | +| UseUseExplosion.cs:25:677:25:680 | this access | UseUseExplosion.cs:25:694:25:697 | this access | +| UseUseExplosion.cs:25:677:25:680 | this access | UseUseExplosion.cs:25:2608:25:2613 | this access | +| UseUseExplosion.cs:25:694:25:697 | [post] this access | UseUseExplosion.cs:25:711:25:714 | this access | +| UseUseExplosion.cs:25:694:25:697 | [post] this access | UseUseExplosion.cs:25:2593:25:2598 | this access | +| UseUseExplosion.cs:25:694:25:697 | access to property Prop | UseUseExplosion.cs:25:711:25:714 | access to property Prop | +| UseUseExplosion.cs:25:694:25:697 | this access | UseUseExplosion.cs:25:711:25:714 | this access | +| UseUseExplosion.cs:25:694:25:697 | this access | UseUseExplosion.cs:25:2593:25:2598 | this access | +| UseUseExplosion.cs:25:711:25:714 | [post] this access | UseUseExplosion.cs:25:728:25:731 | this access | +| UseUseExplosion.cs:25:711:25:714 | [post] this access | UseUseExplosion.cs:25:2578:25:2583 | this access | +| UseUseExplosion.cs:25:711:25:714 | access to property Prop | UseUseExplosion.cs:25:728:25:731 | access to property Prop | +| UseUseExplosion.cs:25:711:25:714 | this access | UseUseExplosion.cs:25:728:25:731 | this access | +| UseUseExplosion.cs:25:711:25:714 | this access | UseUseExplosion.cs:25:2578:25:2583 | this access | +| UseUseExplosion.cs:25:728:25:731 | [post] this access | UseUseExplosion.cs:25:745:25:748 | this access | +| UseUseExplosion.cs:25:728:25:731 | [post] this access | UseUseExplosion.cs:25:2563:25:2568 | this access | +| UseUseExplosion.cs:25:728:25:731 | access to property Prop | UseUseExplosion.cs:25:745:25:748 | access to property Prop | +| UseUseExplosion.cs:25:728:25:731 | this access | UseUseExplosion.cs:25:745:25:748 | this access | +| UseUseExplosion.cs:25:728:25:731 | this access | UseUseExplosion.cs:25:2563:25:2568 | this access | +| UseUseExplosion.cs:25:745:25:748 | [post] this access | UseUseExplosion.cs:25:762:25:765 | this access | +| UseUseExplosion.cs:25:745:25:748 | [post] this access | UseUseExplosion.cs:25:2548:25:2553 | this access | +| UseUseExplosion.cs:25:745:25:748 | access to property Prop | UseUseExplosion.cs:25:762:25:765 | access to property Prop | +| UseUseExplosion.cs:25:745:25:748 | this access | UseUseExplosion.cs:25:762:25:765 | this access | +| UseUseExplosion.cs:25:745:25:748 | this access | UseUseExplosion.cs:25:2548:25:2553 | this access | +| UseUseExplosion.cs:25:762:25:765 | [post] this access | UseUseExplosion.cs:25:779:25:782 | this access | +| UseUseExplosion.cs:25:762:25:765 | [post] this access | UseUseExplosion.cs:25:2533:25:2538 | this access | +| UseUseExplosion.cs:25:762:25:765 | access to property Prop | UseUseExplosion.cs:25:779:25:782 | access to property Prop | +| UseUseExplosion.cs:25:762:25:765 | this access | UseUseExplosion.cs:25:779:25:782 | this access | +| UseUseExplosion.cs:25:762:25:765 | this access | UseUseExplosion.cs:25:2533:25:2538 | this access | +| UseUseExplosion.cs:25:779:25:782 | [post] this access | UseUseExplosion.cs:25:796:25:799 | this access | +| UseUseExplosion.cs:25:779:25:782 | [post] this access | UseUseExplosion.cs:25:2518:25:2523 | this access | +| UseUseExplosion.cs:25:779:25:782 | access to property Prop | UseUseExplosion.cs:25:796:25:799 | access to property Prop | +| UseUseExplosion.cs:25:779:25:782 | this access | UseUseExplosion.cs:25:796:25:799 | this access | +| UseUseExplosion.cs:25:779:25:782 | this access | UseUseExplosion.cs:25:2518:25:2523 | this access | +| UseUseExplosion.cs:25:796:25:799 | [post] this access | UseUseExplosion.cs:25:813:25:816 | this access | +| UseUseExplosion.cs:25:796:25:799 | [post] this access | UseUseExplosion.cs:25:2503:25:2508 | this access | +| UseUseExplosion.cs:25:796:25:799 | access to property Prop | UseUseExplosion.cs:25:813:25:816 | access to property Prop | +| UseUseExplosion.cs:25:796:25:799 | this access | UseUseExplosion.cs:25:813:25:816 | this access | +| UseUseExplosion.cs:25:796:25:799 | this access | UseUseExplosion.cs:25:2503:25:2508 | this access | +| UseUseExplosion.cs:25:813:25:816 | [post] this access | UseUseExplosion.cs:25:830:25:833 | this access | +| UseUseExplosion.cs:25:813:25:816 | [post] this access | UseUseExplosion.cs:25:2488:25:2493 | this access | +| UseUseExplosion.cs:25:813:25:816 | access to property Prop | UseUseExplosion.cs:25:830:25:833 | access to property Prop | +| UseUseExplosion.cs:25:813:25:816 | this access | UseUseExplosion.cs:25:830:25:833 | this access | +| UseUseExplosion.cs:25:813:25:816 | this access | UseUseExplosion.cs:25:2488:25:2493 | this access | +| UseUseExplosion.cs:25:830:25:833 | [post] this access | UseUseExplosion.cs:25:847:25:850 | this access | +| UseUseExplosion.cs:25:830:25:833 | [post] this access | UseUseExplosion.cs:25:2473:25:2478 | this access | +| UseUseExplosion.cs:25:830:25:833 | access to property Prop | UseUseExplosion.cs:25:847:25:850 | access to property Prop | +| UseUseExplosion.cs:25:830:25:833 | this access | UseUseExplosion.cs:25:847:25:850 | this access | +| UseUseExplosion.cs:25:830:25:833 | this access | UseUseExplosion.cs:25:2473:25:2478 | this access | +| UseUseExplosion.cs:25:847:25:850 | [post] this access | UseUseExplosion.cs:25:864:25:867 | this access | +| UseUseExplosion.cs:25:847:25:850 | [post] this access | UseUseExplosion.cs:25:2458:25:2463 | this access | +| UseUseExplosion.cs:25:847:25:850 | access to property Prop | UseUseExplosion.cs:25:864:25:867 | access to property Prop | +| UseUseExplosion.cs:25:847:25:850 | this access | UseUseExplosion.cs:25:864:25:867 | this access | +| UseUseExplosion.cs:25:847:25:850 | this access | UseUseExplosion.cs:25:2458:25:2463 | this access | +| UseUseExplosion.cs:25:864:25:867 | [post] this access | UseUseExplosion.cs:25:881:25:884 | this access | +| UseUseExplosion.cs:25:864:25:867 | [post] this access | UseUseExplosion.cs:25:2443:25:2448 | this access | +| UseUseExplosion.cs:25:864:25:867 | access to property Prop | UseUseExplosion.cs:25:881:25:884 | access to property Prop | +| UseUseExplosion.cs:25:864:25:867 | this access | UseUseExplosion.cs:25:881:25:884 | this access | +| UseUseExplosion.cs:25:864:25:867 | this access | UseUseExplosion.cs:25:2443:25:2448 | this access | +| UseUseExplosion.cs:25:881:25:884 | [post] this access | UseUseExplosion.cs:25:898:25:901 | this access | +| UseUseExplosion.cs:25:881:25:884 | [post] this access | UseUseExplosion.cs:25:2428:25:2433 | this access | +| UseUseExplosion.cs:25:881:25:884 | access to property Prop | UseUseExplosion.cs:25:898:25:901 | access to property Prop | +| UseUseExplosion.cs:25:881:25:884 | this access | UseUseExplosion.cs:25:898:25:901 | this access | +| UseUseExplosion.cs:25:881:25:884 | this access | UseUseExplosion.cs:25:2428:25:2433 | this access | +| UseUseExplosion.cs:25:898:25:901 | [post] this access | UseUseExplosion.cs:25:915:25:918 | this access | +| UseUseExplosion.cs:25:898:25:901 | [post] this access | UseUseExplosion.cs:25:2413:25:2418 | this access | +| UseUseExplosion.cs:25:898:25:901 | access to property Prop | UseUseExplosion.cs:25:915:25:918 | access to property Prop | +| UseUseExplosion.cs:25:898:25:901 | this access | UseUseExplosion.cs:25:915:25:918 | this access | +| UseUseExplosion.cs:25:898:25:901 | this access | UseUseExplosion.cs:25:2413:25:2418 | this access | +| UseUseExplosion.cs:25:915:25:918 | [post] this access | UseUseExplosion.cs:25:932:25:935 | this access | +| UseUseExplosion.cs:25:915:25:918 | [post] this access | UseUseExplosion.cs:25:2398:25:2403 | this access | +| UseUseExplosion.cs:25:915:25:918 | access to property Prop | UseUseExplosion.cs:25:932:25:935 | access to property Prop | +| UseUseExplosion.cs:25:915:25:918 | this access | UseUseExplosion.cs:25:932:25:935 | this access | +| UseUseExplosion.cs:25:915:25:918 | this access | UseUseExplosion.cs:25:2398:25:2403 | this access | +| UseUseExplosion.cs:25:932:25:935 | [post] this access | UseUseExplosion.cs:25:949:25:952 | this access | +| UseUseExplosion.cs:25:932:25:935 | [post] this access | UseUseExplosion.cs:25:2383:25:2388 | this access | +| UseUseExplosion.cs:25:932:25:935 | access to property Prop | UseUseExplosion.cs:25:949:25:952 | access to property Prop | +| UseUseExplosion.cs:25:932:25:935 | this access | UseUseExplosion.cs:25:949:25:952 | this access | +| UseUseExplosion.cs:25:932:25:935 | this access | UseUseExplosion.cs:25:2383:25:2388 | this access | +| UseUseExplosion.cs:25:949:25:952 | [post] this access | UseUseExplosion.cs:25:966:25:969 | this access | +| UseUseExplosion.cs:25:949:25:952 | [post] this access | UseUseExplosion.cs:25:2368:25:2373 | this access | +| UseUseExplosion.cs:25:949:25:952 | access to property Prop | UseUseExplosion.cs:25:966:25:969 | access to property Prop | +| UseUseExplosion.cs:25:949:25:952 | this access | UseUseExplosion.cs:25:966:25:969 | this access | +| UseUseExplosion.cs:25:949:25:952 | this access | UseUseExplosion.cs:25:2368:25:2373 | this access | +| UseUseExplosion.cs:25:966:25:969 | [post] this access | UseUseExplosion.cs:25:983:25:986 | this access | +| UseUseExplosion.cs:25:966:25:969 | [post] this access | UseUseExplosion.cs:25:2353:25:2358 | this access | +| UseUseExplosion.cs:25:966:25:969 | access to property Prop | UseUseExplosion.cs:25:983:25:986 | access to property Prop | +| UseUseExplosion.cs:25:966:25:969 | this access | UseUseExplosion.cs:25:983:25:986 | this access | +| UseUseExplosion.cs:25:966:25:969 | this access | UseUseExplosion.cs:25:2353:25:2358 | this access | +| UseUseExplosion.cs:25:983:25:986 | [post] this access | UseUseExplosion.cs:25:1000:25:1003 | this access | +| UseUseExplosion.cs:25:983:25:986 | [post] this access | UseUseExplosion.cs:25:2338:25:2343 | this access | +| UseUseExplosion.cs:25:983:25:986 | access to property Prop | UseUseExplosion.cs:25:1000:25:1003 | access to property Prop | +| UseUseExplosion.cs:25:983:25:986 | this access | UseUseExplosion.cs:25:1000:25:1003 | this access | +| UseUseExplosion.cs:25:983:25:986 | this access | UseUseExplosion.cs:25:2338:25:2343 | this access | +| UseUseExplosion.cs:25:1000:25:1003 | [post] this access | UseUseExplosion.cs:25:1017:25:1020 | this access | +| UseUseExplosion.cs:25:1000:25:1003 | [post] this access | UseUseExplosion.cs:25:2323:25:2328 | this access | +| UseUseExplosion.cs:25:1000:25:1003 | access to property Prop | UseUseExplosion.cs:25:1017:25:1020 | access to property Prop | +| UseUseExplosion.cs:25:1000:25:1003 | this access | UseUseExplosion.cs:25:1017:25:1020 | this access | +| UseUseExplosion.cs:25:1000:25:1003 | this access | UseUseExplosion.cs:25:2323:25:2328 | this access | +| UseUseExplosion.cs:25:1017:25:1020 | [post] this access | UseUseExplosion.cs:25:1034:25:1037 | this access | +| UseUseExplosion.cs:25:1017:25:1020 | [post] this access | UseUseExplosion.cs:25:2308:25:2313 | this access | +| UseUseExplosion.cs:25:1017:25:1020 | access to property Prop | UseUseExplosion.cs:25:1034:25:1037 | access to property Prop | +| UseUseExplosion.cs:25:1017:25:1020 | this access | UseUseExplosion.cs:25:1034:25:1037 | this access | +| UseUseExplosion.cs:25:1017:25:1020 | this access | UseUseExplosion.cs:25:2308:25:2313 | this access | +| UseUseExplosion.cs:25:1034:25:1037 | [post] this access | UseUseExplosion.cs:25:1051:25:1054 | this access | +| UseUseExplosion.cs:25:1034:25:1037 | [post] this access | UseUseExplosion.cs:25:2293:25:2298 | this access | +| UseUseExplosion.cs:25:1034:25:1037 | access to property Prop | UseUseExplosion.cs:25:1051:25:1054 | access to property Prop | +| UseUseExplosion.cs:25:1034:25:1037 | this access | UseUseExplosion.cs:25:1051:25:1054 | this access | +| UseUseExplosion.cs:25:1034:25:1037 | this access | UseUseExplosion.cs:25:2293:25:2298 | this access | +| UseUseExplosion.cs:25:1051:25:1054 | [post] this access | UseUseExplosion.cs:25:1068:25:1071 | this access | +| UseUseExplosion.cs:25:1051:25:1054 | [post] this access | UseUseExplosion.cs:25:2278:25:2283 | this access | +| UseUseExplosion.cs:25:1051:25:1054 | access to property Prop | UseUseExplosion.cs:25:1068:25:1071 | access to property Prop | +| UseUseExplosion.cs:25:1051:25:1054 | this access | UseUseExplosion.cs:25:1068:25:1071 | this access | +| UseUseExplosion.cs:25:1051:25:1054 | this access | UseUseExplosion.cs:25:2278:25:2283 | this access | +| UseUseExplosion.cs:25:1068:25:1071 | [post] this access | UseUseExplosion.cs:25:1085:25:1088 | this access | +| UseUseExplosion.cs:25:1068:25:1071 | [post] this access | UseUseExplosion.cs:25:2263:25:2268 | this access | +| UseUseExplosion.cs:25:1068:25:1071 | access to property Prop | UseUseExplosion.cs:25:1085:25:1088 | access to property Prop | +| UseUseExplosion.cs:25:1068:25:1071 | this access | UseUseExplosion.cs:25:1085:25:1088 | this access | +| UseUseExplosion.cs:25:1068:25:1071 | this access | UseUseExplosion.cs:25:2263:25:2268 | this access | +| UseUseExplosion.cs:25:1085:25:1088 | [post] this access | UseUseExplosion.cs:25:1102:25:1105 | this access | +| UseUseExplosion.cs:25:1085:25:1088 | [post] this access | UseUseExplosion.cs:25:2248:25:2253 | this access | +| UseUseExplosion.cs:25:1085:25:1088 | access to property Prop | UseUseExplosion.cs:25:1102:25:1105 | access to property Prop | +| UseUseExplosion.cs:25:1085:25:1088 | this access | UseUseExplosion.cs:25:1102:25:1105 | this access | +| UseUseExplosion.cs:25:1085:25:1088 | this access | UseUseExplosion.cs:25:2248:25:2253 | this access | +| UseUseExplosion.cs:25:1102:25:1105 | [post] this access | UseUseExplosion.cs:25:1119:25:1122 | this access | +| UseUseExplosion.cs:25:1102:25:1105 | [post] this access | UseUseExplosion.cs:25:2233:25:2238 | this access | +| UseUseExplosion.cs:25:1102:25:1105 | access to property Prop | UseUseExplosion.cs:25:1119:25:1122 | access to property Prop | +| UseUseExplosion.cs:25:1102:25:1105 | this access | UseUseExplosion.cs:25:1119:25:1122 | this access | +| UseUseExplosion.cs:25:1102:25:1105 | this access | UseUseExplosion.cs:25:2233:25:2238 | this access | +| UseUseExplosion.cs:25:1119:25:1122 | [post] this access | UseUseExplosion.cs:25:1136:25:1139 | this access | +| UseUseExplosion.cs:25:1119:25:1122 | [post] this access | UseUseExplosion.cs:25:2218:25:2223 | this access | +| UseUseExplosion.cs:25:1119:25:1122 | access to property Prop | UseUseExplosion.cs:25:1136:25:1139 | access to property Prop | +| UseUseExplosion.cs:25:1119:25:1122 | this access | UseUseExplosion.cs:25:1136:25:1139 | this access | +| UseUseExplosion.cs:25:1119:25:1122 | this access | UseUseExplosion.cs:25:2218:25:2223 | this access | +| UseUseExplosion.cs:25:1136:25:1139 | [post] this access | UseUseExplosion.cs:25:1153:25:1156 | this access | +| UseUseExplosion.cs:25:1136:25:1139 | [post] this access | UseUseExplosion.cs:25:2203:25:2208 | this access | +| UseUseExplosion.cs:25:1136:25:1139 | access to property Prop | UseUseExplosion.cs:25:1153:25:1156 | access to property Prop | +| UseUseExplosion.cs:25:1136:25:1139 | this access | UseUseExplosion.cs:25:1153:25:1156 | this access | +| UseUseExplosion.cs:25:1136:25:1139 | this access | UseUseExplosion.cs:25:2203:25:2208 | this access | +| UseUseExplosion.cs:25:1153:25:1156 | [post] this access | UseUseExplosion.cs:25:1170:25:1173 | this access | +| UseUseExplosion.cs:25:1153:25:1156 | [post] this access | UseUseExplosion.cs:25:2188:25:2193 | this access | +| UseUseExplosion.cs:25:1153:25:1156 | access to property Prop | UseUseExplosion.cs:25:1170:25:1173 | access to property Prop | +| UseUseExplosion.cs:25:1153:25:1156 | this access | UseUseExplosion.cs:25:1170:25:1173 | this access | +| UseUseExplosion.cs:25:1153:25:1156 | this access | UseUseExplosion.cs:25:2188:25:2193 | this access | +| UseUseExplosion.cs:25:1170:25:1173 | [post] this access | UseUseExplosion.cs:25:1187:25:1190 | this access | +| UseUseExplosion.cs:25:1170:25:1173 | [post] this access | UseUseExplosion.cs:25:2173:25:2178 | this access | +| UseUseExplosion.cs:25:1170:25:1173 | access to property Prop | UseUseExplosion.cs:25:1187:25:1190 | access to property Prop | +| UseUseExplosion.cs:25:1170:25:1173 | this access | UseUseExplosion.cs:25:1187:25:1190 | this access | +| UseUseExplosion.cs:25:1170:25:1173 | this access | UseUseExplosion.cs:25:2173:25:2178 | this access | +| UseUseExplosion.cs:25:1187:25:1190 | [post] this access | UseUseExplosion.cs:25:1204:25:1207 | this access | +| UseUseExplosion.cs:25:1187:25:1190 | [post] this access | UseUseExplosion.cs:25:2158:25:2163 | this access | +| UseUseExplosion.cs:25:1187:25:1190 | access to property Prop | UseUseExplosion.cs:25:1204:25:1207 | access to property Prop | +| UseUseExplosion.cs:25:1187:25:1190 | this access | UseUseExplosion.cs:25:1204:25:1207 | this access | +| UseUseExplosion.cs:25:1187:25:1190 | this access | UseUseExplosion.cs:25:2158:25:2163 | this access | +| UseUseExplosion.cs:25:1204:25:1207 | [post] this access | UseUseExplosion.cs:25:1221:25:1224 | this access | +| UseUseExplosion.cs:25:1204:25:1207 | [post] this access | UseUseExplosion.cs:25:2143:25:2148 | this access | +| UseUseExplosion.cs:25:1204:25:1207 | access to property Prop | UseUseExplosion.cs:25:1221:25:1224 | access to property Prop | +| UseUseExplosion.cs:25:1204:25:1207 | this access | UseUseExplosion.cs:25:1221:25:1224 | this access | +| UseUseExplosion.cs:25:1204:25:1207 | this access | UseUseExplosion.cs:25:2143:25:2148 | this access | +| UseUseExplosion.cs:25:1221:25:1224 | [post] this access | UseUseExplosion.cs:25:1238:25:1241 | this access | +| UseUseExplosion.cs:25:1221:25:1224 | [post] this access | UseUseExplosion.cs:25:2128:25:2133 | this access | +| UseUseExplosion.cs:25:1221:25:1224 | access to property Prop | UseUseExplosion.cs:25:1238:25:1241 | access to property Prop | +| UseUseExplosion.cs:25:1221:25:1224 | this access | UseUseExplosion.cs:25:1238:25:1241 | this access | +| UseUseExplosion.cs:25:1221:25:1224 | this access | UseUseExplosion.cs:25:2128:25:2133 | this access | +| UseUseExplosion.cs:25:1238:25:1241 | [post] this access | UseUseExplosion.cs:25:1255:25:1258 | this access | +| UseUseExplosion.cs:25:1238:25:1241 | [post] this access | UseUseExplosion.cs:25:2113:25:2118 | this access | +| UseUseExplosion.cs:25:1238:25:1241 | access to property Prop | UseUseExplosion.cs:25:1255:25:1258 | access to property Prop | +| UseUseExplosion.cs:25:1238:25:1241 | this access | UseUseExplosion.cs:25:1255:25:1258 | this access | +| UseUseExplosion.cs:25:1238:25:1241 | this access | UseUseExplosion.cs:25:2113:25:2118 | this access | +| UseUseExplosion.cs:25:1255:25:1258 | [post] this access | UseUseExplosion.cs:25:1272:25:1275 | this access | +| UseUseExplosion.cs:25:1255:25:1258 | [post] this access | UseUseExplosion.cs:25:2098:25:2103 | this access | +| UseUseExplosion.cs:25:1255:25:1258 | access to property Prop | UseUseExplosion.cs:25:1272:25:1275 | access to property Prop | +| UseUseExplosion.cs:25:1255:25:1258 | this access | UseUseExplosion.cs:25:1272:25:1275 | this access | +| UseUseExplosion.cs:25:1255:25:1258 | this access | UseUseExplosion.cs:25:2098:25:2103 | this access | +| UseUseExplosion.cs:25:1272:25:1275 | [post] this access | UseUseExplosion.cs:25:1289:25:1292 | this access | +| UseUseExplosion.cs:25:1272:25:1275 | [post] this access | UseUseExplosion.cs:25:2083:25:2088 | this access | +| UseUseExplosion.cs:25:1272:25:1275 | access to property Prop | UseUseExplosion.cs:25:1289:25:1292 | access to property Prop | +| UseUseExplosion.cs:25:1272:25:1275 | this access | UseUseExplosion.cs:25:1289:25:1292 | this access | +| UseUseExplosion.cs:25:1272:25:1275 | this access | UseUseExplosion.cs:25:2083:25:2088 | this access | +| UseUseExplosion.cs:25:1289:25:1292 | [post] this access | UseUseExplosion.cs:25:1306:25:1309 | this access | +| UseUseExplosion.cs:25:1289:25:1292 | [post] this access | UseUseExplosion.cs:25:2068:25:2073 | this access | +| UseUseExplosion.cs:25:1289:25:1292 | access to property Prop | UseUseExplosion.cs:25:1306:25:1309 | access to property Prop | +| UseUseExplosion.cs:25:1289:25:1292 | this access | UseUseExplosion.cs:25:1306:25:1309 | this access | +| UseUseExplosion.cs:25:1289:25:1292 | this access | UseUseExplosion.cs:25:2068:25:2073 | this access | +| UseUseExplosion.cs:25:1306:25:1309 | [post] this access | UseUseExplosion.cs:25:1323:25:1326 | this access | +| UseUseExplosion.cs:25:1306:25:1309 | [post] this access | UseUseExplosion.cs:25:2053:25:2058 | this access | +| UseUseExplosion.cs:25:1306:25:1309 | access to property Prop | UseUseExplosion.cs:25:1323:25:1326 | access to property Prop | +| UseUseExplosion.cs:25:1306:25:1309 | this access | UseUseExplosion.cs:25:1323:25:1326 | this access | +| UseUseExplosion.cs:25:1306:25:1309 | this access | UseUseExplosion.cs:25:2053:25:2058 | this access | +| UseUseExplosion.cs:25:1323:25:1326 | [post] this access | UseUseExplosion.cs:25:1340:25:1343 | this access | +| UseUseExplosion.cs:25:1323:25:1326 | [post] this access | UseUseExplosion.cs:25:2038:25:2043 | this access | +| UseUseExplosion.cs:25:1323:25:1326 | access to property Prop | UseUseExplosion.cs:25:1340:25:1343 | access to property Prop | +| UseUseExplosion.cs:25:1323:25:1326 | this access | UseUseExplosion.cs:25:1340:25:1343 | this access | +| UseUseExplosion.cs:25:1323:25:1326 | this access | UseUseExplosion.cs:25:2038:25:2043 | this access | +| UseUseExplosion.cs:25:1340:25:1343 | [post] this access | UseUseExplosion.cs:25:1357:25:1360 | this access | +| UseUseExplosion.cs:25:1340:25:1343 | [post] this access | UseUseExplosion.cs:25:2023:25:2028 | this access | +| UseUseExplosion.cs:25:1340:25:1343 | access to property Prop | UseUseExplosion.cs:25:1357:25:1360 | access to property Prop | +| UseUseExplosion.cs:25:1340:25:1343 | this access | UseUseExplosion.cs:25:1357:25:1360 | this access | +| UseUseExplosion.cs:25:1340:25:1343 | this access | UseUseExplosion.cs:25:2023:25:2028 | this access | +| UseUseExplosion.cs:25:1357:25:1360 | [post] this access | UseUseExplosion.cs:25:1374:25:1377 | this access | +| UseUseExplosion.cs:25:1357:25:1360 | [post] this access | UseUseExplosion.cs:25:2008:25:2013 | this access | +| UseUseExplosion.cs:25:1357:25:1360 | access to property Prop | UseUseExplosion.cs:25:1374:25:1377 | access to property Prop | +| UseUseExplosion.cs:25:1357:25:1360 | this access | UseUseExplosion.cs:25:1374:25:1377 | this access | +| UseUseExplosion.cs:25:1357:25:1360 | this access | UseUseExplosion.cs:25:2008:25:2013 | this access | +| UseUseExplosion.cs:25:1374:25:1377 | [post] this access | UseUseExplosion.cs:25:1391:25:1394 | this access | +| UseUseExplosion.cs:25:1374:25:1377 | [post] this access | UseUseExplosion.cs:25:1993:25:1998 | this access | +| UseUseExplosion.cs:25:1374:25:1377 | access to property Prop | UseUseExplosion.cs:25:1391:25:1394 | access to property Prop | +| UseUseExplosion.cs:25:1374:25:1377 | this access | UseUseExplosion.cs:25:1391:25:1394 | this access | +| UseUseExplosion.cs:25:1374:25:1377 | this access | UseUseExplosion.cs:25:1993:25:1998 | this access | +| UseUseExplosion.cs:25:1391:25:1394 | [post] this access | UseUseExplosion.cs:25:1408:25:1411 | this access | +| UseUseExplosion.cs:25:1391:25:1394 | [post] this access | UseUseExplosion.cs:25:1978:25:1983 | this access | +| UseUseExplosion.cs:25:1391:25:1394 | access to property Prop | UseUseExplosion.cs:25:1408:25:1411 | access to property Prop | +| UseUseExplosion.cs:25:1391:25:1394 | this access | UseUseExplosion.cs:25:1408:25:1411 | this access | +| UseUseExplosion.cs:25:1391:25:1394 | this access | UseUseExplosion.cs:25:1978:25:1983 | this access | +| UseUseExplosion.cs:25:1408:25:1411 | [post] this access | UseUseExplosion.cs:25:1425:25:1428 | this access | +| UseUseExplosion.cs:25:1408:25:1411 | [post] this access | UseUseExplosion.cs:25:1963:25:1968 | this access | +| UseUseExplosion.cs:25:1408:25:1411 | access to property Prop | UseUseExplosion.cs:25:1425:25:1428 | access to property Prop | +| UseUseExplosion.cs:25:1408:25:1411 | this access | UseUseExplosion.cs:25:1425:25:1428 | this access | +| UseUseExplosion.cs:25:1408:25:1411 | this access | UseUseExplosion.cs:25:1963:25:1968 | this access | +| UseUseExplosion.cs:25:1425:25:1428 | [post] this access | UseUseExplosion.cs:25:1442:25:1445 | this access | +| UseUseExplosion.cs:25:1425:25:1428 | [post] this access | UseUseExplosion.cs:25:1948:25:1953 | this access | +| UseUseExplosion.cs:25:1425:25:1428 | access to property Prop | UseUseExplosion.cs:25:1442:25:1445 | access to property Prop | +| UseUseExplosion.cs:25:1425:25:1428 | this access | UseUseExplosion.cs:25:1442:25:1445 | this access | +| UseUseExplosion.cs:25:1425:25:1428 | this access | UseUseExplosion.cs:25:1948:25:1953 | this access | +| UseUseExplosion.cs:25:1442:25:1445 | [post] this access | UseUseExplosion.cs:25:1459:25:1462 | this access | +| UseUseExplosion.cs:25:1442:25:1445 | [post] this access | UseUseExplosion.cs:25:1933:25:1938 | this access | +| UseUseExplosion.cs:25:1442:25:1445 | access to property Prop | UseUseExplosion.cs:25:1459:25:1462 | access to property Prop | +| UseUseExplosion.cs:25:1442:25:1445 | this access | UseUseExplosion.cs:25:1459:25:1462 | this access | +| UseUseExplosion.cs:25:1442:25:1445 | this access | UseUseExplosion.cs:25:1933:25:1938 | this access | +| UseUseExplosion.cs:25:1459:25:1462 | [post] this access | UseUseExplosion.cs:25:1476:25:1479 | this access | +| UseUseExplosion.cs:25:1459:25:1462 | [post] this access | UseUseExplosion.cs:25:1918:25:1923 | this access | +| UseUseExplosion.cs:25:1459:25:1462 | access to property Prop | UseUseExplosion.cs:25:1476:25:1479 | access to property Prop | +| UseUseExplosion.cs:25:1459:25:1462 | this access | UseUseExplosion.cs:25:1476:25:1479 | this access | +| UseUseExplosion.cs:25:1459:25:1462 | this access | UseUseExplosion.cs:25:1918:25:1923 | this access | +| UseUseExplosion.cs:25:1476:25:1479 | [post] this access | UseUseExplosion.cs:25:1493:25:1496 | this access | +| UseUseExplosion.cs:25:1476:25:1479 | [post] this access | UseUseExplosion.cs:25:1903:25:1908 | this access | +| UseUseExplosion.cs:25:1476:25:1479 | access to property Prop | UseUseExplosion.cs:25:1493:25:1496 | access to property Prop | +| UseUseExplosion.cs:25:1476:25:1479 | this access | UseUseExplosion.cs:25:1493:25:1496 | this access | +| UseUseExplosion.cs:25:1476:25:1479 | this access | UseUseExplosion.cs:25:1903:25:1908 | this access | +| UseUseExplosion.cs:25:1493:25:1496 | [post] this access | UseUseExplosion.cs:25:1510:25:1513 | this access | +| UseUseExplosion.cs:25:1493:25:1496 | [post] this access | UseUseExplosion.cs:25:1888:25:1893 | this access | +| UseUseExplosion.cs:25:1493:25:1496 | access to property Prop | UseUseExplosion.cs:25:1510:25:1513 | access to property Prop | +| UseUseExplosion.cs:25:1493:25:1496 | this access | UseUseExplosion.cs:25:1510:25:1513 | this access | +| UseUseExplosion.cs:25:1493:25:1496 | this access | UseUseExplosion.cs:25:1888:25:1893 | this access | +| UseUseExplosion.cs:25:1510:25:1513 | [post] this access | UseUseExplosion.cs:25:1527:25:1530 | this access | +| UseUseExplosion.cs:25:1510:25:1513 | [post] this access | UseUseExplosion.cs:25:1873:25:1878 | this access | +| UseUseExplosion.cs:25:1510:25:1513 | access to property Prop | UseUseExplosion.cs:25:1527:25:1530 | access to property Prop | +| UseUseExplosion.cs:25:1510:25:1513 | this access | UseUseExplosion.cs:25:1527:25:1530 | this access | +| UseUseExplosion.cs:25:1510:25:1513 | this access | UseUseExplosion.cs:25:1873:25:1878 | this access | +| UseUseExplosion.cs:25:1527:25:1530 | [post] this access | UseUseExplosion.cs:25:1544:25:1547 | this access | +| UseUseExplosion.cs:25:1527:25:1530 | [post] this access | UseUseExplosion.cs:25:1858:25:1863 | this access | +| UseUseExplosion.cs:25:1527:25:1530 | access to property Prop | UseUseExplosion.cs:25:1544:25:1547 | access to property Prop | +| UseUseExplosion.cs:25:1527:25:1530 | this access | UseUseExplosion.cs:25:1544:25:1547 | this access | +| UseUseExplosion.cs:25:1527:25:1530 | this access | UseUseExplosion.cs:25:1858:25:1863 | this access | +| UseUseExplosion.cs:25:1544:25:1547 | [post] this access | UseUseExplosion.cs:25:1561:25:1564 | this access | +| UseUseExplosion.cs:25:1544:25:1547 | [post] this access | UseUseExplosion.cs:25:1843:25:1848 | this access | +| UseUseExplosion.cs:25:1544:25:1547 | access to property Prop | UseUseExplosion.cs:25:1561:25:1564 | access to property Prop | +| UseUseExplosion.cs:25:1544:25:1547 | this access | UseUseExplosion.cs:25:1561:25:1564 | this access | +| UseUseExplosion.cs:25:1544:25:1547 | this access | UseUseExplosion.cs:25:1843:25:1848 | this access | +| UseUseExplosion.cs:25:1561:25:1564 | [post] this access | UseUseExplosion.cs:25:1577:25:1580 | this access | +| UseUseExplosion.cs:25:1561:25:1564 | [post] this access | UseUseExplosion.cs:25:1828:25:1833 | this access | +| UseUseExplosion.cs:25:1561:25:1564 | access to property Prop | UseUseExplosion.cs:25:1577:25:1580 | access to property Prop | +| UseUseExplosion.cs:25:1561:25:1564 | this access | UseUseExplosion.cs:25:1577:25:1580 | this access | +| UseUseExplosion.cs:25:1561:25:1564 | this access | UseUseExplosion.cs:25:1828:25:1833 | this access | +| UseUseExplosion.cs:25:1577:25:1580 | [post] this access | UseUseExplosion.cs:25:1593:25:1596 | this access | +| UseUseExplosion.cs:25:1577:25:1580 | [post] this access | UseUseExplosion.cs:25:1813:25:1818 | this access | +| UseUseExplosion.cs:25:1577:25:1580 | access to property Prop | UseUseExplosion.cs:25:1593:25:1596 | access to property Prop | +| UseUseExplosion.cs:25:1577:25:1580 | this access | UseUseExplosion.cs:25:1593:25:1596 | this access | +| UseUseExplosion.cs:25:1577:25:1580 | this access | UseUseExplosion.cs:25:1813:25:1818 | this access | +| UseUseExplosion.cs:25:1593:25:1596 | [post] this access | UseUseExplosion.cs:25:1609:25:1612 | this access | +| UseUseExplosion.cs:25:1593:25:1596 | [post] this access | UseUseExplosion.cs:25:1798:25:1803 | this access | +| UseUseExplosion.cs:25:1593:25:1596 | access to property Prop | UseUseExplosion.cs:25:1609:25:1612 | access to property Prop | +| UseUseExplosion.cs:25:1593:25:1596 | this access | UseUseExplosion.cs:25:1609:25:1612 | this access | +| UseUseExplosion.cs:25:1593:25:1596 | this access | UseUseExplosion.cs:25:1798:25:1803 | this access | +| UseUseExplosion.cs:25:1609:25:1612 | [post] this access | UseUseExplosion.cs:25:1625:25:1628 | this access | +| UseUseExplosion.cs:25:1609:25:1612 | [post] this access | UseUseExplosion.cs:25:1783:25:1788 | this access | +| UseUseExplosion.cs:25:1609:25:1612 | access to property Prop | UseUseExplosion.cs:25:1625:25:1628 | access to property Prop | +| UseUseExplosion.cs:25:1609:25:1612 | this access | UseUseExplosion.cs:25:1625:25:1628 | this access | +| UseUseExplosion.cs:25:1609:25:1612 | this access | UseUseExplosion.cs:25:1783:25:1788 | this access | +| UseUseExplosion.cs:25:1625:25:1628 | [post] this access | UseUseExplosion.cs:25:1641:25:1644 | this access | +| UseUseExplosion.cs:25:1625:25:1628 | [post] this access | UseUseExplosion.cs:25:1768:25:1773 | this access | +| UseUseExplosion.cs:25:1625:25:1628 | access to property Prop | UseUseExplosion.cs:25:1641:25:1644 | access to property Prop | +| UseUseExplosion.cs:25:1625:25:1628 | this access | UseUseExplosion.cs:25:1641:25:1644 | this access | +| UseUseExplosion.cs:25:1625:25:1628 | this access | UseUseExplosion.cs:25:1768:25:1773 | this access | +| UseUseExplosion.cs:25:1641:25:1644 | [post] this access | UseUseExplosion.cs:25:1657:25:1660 | this access | +| UseUseExplosion.cs:25:1641:25:1644 | [post] this access | UseUseExplosion.cs:25:1753:25:1758 | this access | +| UseUseExplosion.cs:25:1641:25:1644 | access to property Prop | UseUseExplosion.cs:25:1657:25:1660 | access to property Prop | +| UseUseExplosion.cs:25:1641:25:1644 | this access | UseUseExplosion.cs:25:1657:25:1660 | this access | +| UseUseExplosion.cs:25:1641:25:1644 | this access | UseUseExplosion.cs:25:1753:25:1758 | this access | +| UseUseExplosion.cs:25:1657:25:1660 | [post] this access | UseUseExplosion.cs:25:1673:25:1676 | this access | +| UseUseExplosion.cs:25:1657:25:1660 | [post] this access | UseUseExplosion.cs:25:1738:25:1743 | this access | +| UseUseExplosion.cs:25:1657:25:1660 | access to property Prop | UseUseExplosion.cs:25:1673:25:1676 | access to property Prop | +| UseUseExplosion.cs:25:1657:25:1660 | this access | UseUseExplosion.cs:25:1673:25:1676 | this access | +| UseUseExplosion.cs:25:1657:25:1660 | this access | UseUseExplosion.cs:25:1738:25:1743 | this access | +| UseUseExplosion.cs:25:1673:25:1676 | [post] this access | UseUseExplosion.cs:25:1689:25:1692 | this access | +| UseUseExplosion.cs:25:1673:25:1676 | [post] this access | UseUseExplosion.cs:25:1723:25:1728 | this access | +| UseUseExplosion.cs:25:1673:25:1676 | access to property Prop | UseUseExplosion.cs:25:1689:25:1692 | access to property Prop | +| UseUseExplosion.cs:25:1673:25:1676 | this access | UseUseExplosion.cs:25:1689:25:1692 | this access | +| UseUseExplosion.cs:25:1673:25:1676 | this access | UseUseExplosion.cs:25:1723:25:1728 | this access | +| UseUseExplosion.cs:25:1689:25:1692 | [post] this access | UseUseExplosion.cs:25:1708:25:1713 | this access | +| UseUseExplosion.cs:25:1689:25:1692 | this access | UseUseExplosion.cs:25:1708:25:1713 | this access | diff --git a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected index 6627f70e735..dc8cdffaa36 100644 --- a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected +++ b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected @@ -981,3 +981,1804 @@ | Splitting.cs:58:22:58:22 | [b (line 46): true] SSA def(s) | Splitting.cs:59:19:59:19 | [b (line 46): true] access to local variable s | | Splitting.cs:58:27:58:27 | [b (line 46): false] access to local variable y | Splitting.cs:58:22:58:22 | [b (line 46): false] SSA def(s) | | Splitting.cs:58:27:58:27 | [b (line 46): true] access to local variable y | Splitting.cs:58:22:58:22 | [b (line 46): true] SSA def(s) | +| UseUseExplosion.cs:21:10:21:10 | SSA entry def(this.Prop) | UseUseExplosion.cs:24:13:24:16 | access to property Prop | +| UseUseExplosion.cs:21:10:21:10 | this | UseUseExplosion.cs:24:13:24:16 | this access | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1712:24:1712 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1727:24:1727 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1742:24:1742 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1757:24:1757 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1772:24:1772 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1787:24:1787 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1802:24:1802 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1817:24:1817 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1832:24:1832 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1847:24:1847 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1862:24:1862 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1877:24:1877 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1892:24:1892 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1907:24:1907 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1922:24:1922 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1937:24:1937 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1952:24:1952 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1967:24:1967 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1982:24:1982 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1997:24:1997 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2012:24:2012 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2027:24:2027 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2042:24:2042 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2057:24:2057 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2072:24:2072 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2087:24:2087 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2102:24:2102 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2117:24:2117 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2132:24:2132 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2147:24:2147 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2162:24:2162 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2177:24:2177 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2192:24:2192 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2207:24:2207 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2222:24:2222 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2237:24:2237 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2252:24:2252 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2267:24:2267 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2282:24:2282 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2297:24:2297 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2312:24:2312 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2327:24:2327 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2342:24:2342 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2357:24:2357 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2372:24:2372 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2387:24:2387 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2402:24:2402 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2417:24:2417 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2432:24:2432 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2447:24:2447 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2462:24:2462 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2477:24:2477 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2492:24:2492 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2507:24:2507 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2522:24:2522 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2537:24:2537 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2552:24:2552 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2567:24:2567 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2582:24:2582 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2597:24:2597 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2612:24:2612 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2627:24:2627 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2642:24:2642 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2657:24:2657 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2672:24:2672 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2687:24:2687 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2702:24:2702 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2717:24:2717 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2732:24:2732 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2747:24:2747 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2762:24:2762 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2777:24:2777 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2792:24:2792 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2807:24:2807 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2822:24:2822 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2837:24:2837 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2852:24:2852 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2867:24:2867 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2882:24:2882 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2897:24:2897 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2912:24:2912 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2927:24:2927 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2942:24:2942 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2957:24:2957 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2972:24:2972 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2987:24:2987 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3002:24:3002 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3017:24:3017 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3032:24:3032 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3047:24:3047 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3062:24:3062 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3077:24:3077 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3092:24:3092 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3107:24:3107 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3122:24:3122 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3137:24:3137 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3152:24:3152 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3167:24:3167 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3182:24:3182 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3197:24:3197 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:23:17:23:17 | 0 | UseUseExplosion.cs:23:13:23:17 | SSA def(x) | +| UseUseExplosion.cs:24:13:24:16 | [post] this access | UseUseExplosion.cs:24:31:24:34 | this access | +| UseUseExplosion.cs:24:13:24:16 | [post] this access | UseUseExplosion.cs:24:3193:24:3198 | this access | +| UseUseExplosion.cs:24:13:24:16 | access to property Prop | UseUseExplosion.cs:24:13:24:22 | ... > ... | +| UseUseExplosion.cs:24:13:24:16 | access to property Prop | UseUseExplosion.cs:24:31:24:34 | access to property Prop | +| UseUseExplosion.cs:24:13:24:16 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:13:24:16 | this access | UseUseExplosion.cs:24:31:24:34 | this access | +| UseUseExplosion.cs:24:13:24:16 | this access | UseUseExplosion.cs:24:3193:24:3198 | this access | +| UseUseExplosion.cs:24:31:24:34 | [post] this access | UseUseExplosion.cs:24:48:24:51 | this access | +| UseUseExplosion.cs:24:31:24:34 | [post] this access | UseUseExplosion.cs:24:3178:24:3183 | this access | +| UseUseExplosion.cs:24:31:24:34 | access to property Prop | UseUseExplosion.cs:24:31:24:39 | ... > ... | +| UseUseExplosion.cs:24:31:24:34 | access to property Prop | UseUseExplosion.cs:24:48:24:51 | access to property Prop | +| UseUseExplosion.cs:24:31:24:34 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:31:24:34 | this access | UseUseExplosion.cs:24:48:24:51 | this access | +| UseUseExplosion.cs:24:31:24:34 | this access | UseUseExplosion.cs:24:3178:24:3183 | this access | +| UseUseExplosion.cs:24:48:24:51 | [post] this access | UseUseExplosion.cs:24:65:24:68 | this access | +| UseUseExplosion.cs:24:48:24:51 | [post] this access | UseUseExplosion.cs:24:3163:24:3168 | this access | +| UseUseExplosion.cs:24:48:24:51 | access to property Prop | UseUseExplosion.cs:24:48:24:56 | ... > ... | +| UseUseExplosion.cs:24:48:24:51 | access to property Prop | UseUseExplosion.cs:24:65:24:68 | access to property Prop | +| UseUseExplosion.cs:24:48:24:51 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:48:24:51 | this access | UseUseExplosion.cs:24:65:24:68 | this access | +| UseUseExplosion.cs:24:48:24:51 | this access | UseUseExplosion.cs:24:3163:24:3168 | this access | +| UseUseExplosion.cs:24:65:24:68 | [post] this access | UseUseExplosion.cs:24:82:24:85 | this access | +| UseUseExplosion.cs:24:65:24:68 | [post] this access | UseUseExplosion.cs:24:3148:24:3153 | this access | +| UseUseExplosion.cs:24:65:24:68 | access to property Prop | UseUseExplosion.cs:24:65:24:73 | ... > ... | +| UseUseExplosion.cs:24:65:24:68 | access to property Prop | UseUseExplosion.cs:24:82:24:85 | access to property Prop | +| UseUseExplosion.cs:24:65:24:68 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:65:24:68 | this access | UseUseExplosion.cs:24:82:24:85 | this access | +| UseUseExplosion.cs:24:65:24:68 | this access | UseUseExplosion.cs:24:3148:24:3153 | this access | +| UseUseExplosion.cs:24:82:24:85 | [post] this access | UseUseExplosion.cs:24:99:24:102 | this access | +| UseUseExplosion.cs:24:82:24:85 | [post] this access | UseUseExplosion.cs:24:3133:24:3138 | this access | +| UseUseExplosion.cs:24:82:24:85 | access to property Prop | UseUseExplosion.cs:24:82:24:90 | ... > ... | +| UseUseExplosion.cs:24:82:24:85 | access to property Prop | UseUseExplosion.cs:24:99:24:102 | access to property Prop | +| UseUseExplosion.cs:24:82:24:85 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:82:24:85 | this access | UseUseExplosion.cs:24:99:24:102 | this access | +| UseUseExplosion.cs:24:82:24:85 | this access | UseUseExplosion.cs:24:3133:24:3138 | this access | +| UseUseExplosion.cs:24:99:24:102 | [post] this access | UseUseExplosion.cs:24:116:24:119 | this access | +| UseUseExplosion.cs:24:99:24:102 | [post] this access | UseUseExplosion.cs:24:3118:24:3123 | this access | +| UseUseExplosion.cs:24:99:24:102 | access to property Prop | UseUseExplosion.cs:24:99:24:107 | ... > ... | +| UseUseExplosion.cs:24:99:24:102 | access to property Prop | UseUseExplosion.cs:24:116:24:119 | access to property Prop | +| UseUseExplosion.cs:24:99:24:102 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:99:24:102 | this access | UseUseExplosion.cs:24:116:24:119 | this access | +| UseUseExplosion.cs:24:99:24:102 | this access | UseUseExplosion.cs:24:3118:24:3123 | this access | +| UseUseExplosion.cs:24:116:24:119 | [post] this access | UseUseExplosion.cs:24:133:24:136 | this access | +| UseUseExplosion.cs:24:116:24:119 | [post] this access | UseUseExplosion.cs:24:3103:24:3108 | this access | +| UseUseExplosion.cs:24:116:24:119 | access to property Prop | UseUseExplosion.cs:24:116:24:124 | ... > ... | +| UseUseExplosion.cs:24:116:24:119 | access to property Prop | UseUseExplosion.cs:24:133:24:136 | access to property Prop | +| UseUseExplosion.cs:24:116:24:119 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:116:24:119 | this access | UseUseExplosion.cs:24:133:24:136 | this access | +| UseUseExplosion.cs:24:116:24:119 | this access | UseUseExplosion.cs:24:3103:24:3108 | this access | +| UseUseExplosion.cs:24:133:24:136 | [post] this access | UseUseExplosion.cs:24:150:24:153 | this access | +| UseUseExplosion.cs:24:133:24:136 | [post] this access | UseUseExplosion.cs:24:3088:24:3093 | this access | +| UseUseExplosion.cs:24:133:24:136 | access to property Prop | UseUseExplosion.cs:24:133:24:141 | ... > ... | +| UseUseExplosion.cs:24:133:24:136 | access to property Prop | UseUseExplosion.cs:24:150:24:153 | access to property Prop | +| UseUseExplosion.cs:24:133:24:136 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:133:24:136 | this access | UseUseExplosion.cs:24:150:24:153 | this access | +| UseUseExplosion.cs:24:133:24:136 | this access | UseUseExplosion.cs:24:3088:24:3093 | this access | +| UseUseExplosion.cs:24:150:24:153 | [post] this access | UseUseExplosion.cs:24:167:24:170 | this access | +| UseUseExplosion.cs:24:150:24:153 | [post] this access | UseUseExplosion.cs:24:3073:24:3078 | this access | +| UseUseExplosion.cs:24:150:24:153 | access to property Prop | UseUseExplosion.cs:24:150:24:158 | ... > ... | +| UseUseExplosion.cs:24:150:24:153 | access to property Prop | UseUseExplosion.cs:24:167:24:170 | access to property Prop | +| UseUseExplosion.cs:24:150:24:153 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:150:24:153 | this access | UseUseExplosion.cs:24:167:24:170 | this access | +| UseUseExplosion.cs:24:150:24:153 | this access | UseUseExplosion.cs:24:3073:24:3078 | this access | +| UseUseExplosion.cs:24:167:24:170 | [post] this access | UseUseExplosion.cs:24:184:24:187 | this access | +| UseUseExplosion.cs:24:167:24:170 | [post] this access | UseUseExplosion.cs:24:3058:24:3063 | this access | +| UseUseExplosion.cs:24:167:24:170 | access to property Prop | UseUseExplosion.cs:24:167:24:175 | ... > ... | +| UseUseExplosion.cs:24:167:24:170 | access to property Prop | UseUseExplosion.cs:24:184:24:187 | access to property Prop | +| UseUseExplosion.cs:24:167:24:170 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:167:24:170 | this access | UseUseExplosion.cs:24:184:24:187 | this access | +| UseUseExplosion.cs:24:167:24:170 | this access | UseUseExplosion.cs:24:3058:24:3063 | this access | +| UseUseExplosion.cs:24:184:24:187 | [post] this access | UseUseExplosion.cs:24:201:24:204 | this access | +| UseUseExplosion.cs:24:184:24:187 | [post] this access | UseUseExplosion.cs:24:3043:24:3048 | this access | +| UseUseExplosion.cs:24:184:24:187 | access to property Prop | UseUseExplosion.cs:24:184:24:192 | ... > ... | +| UseUseExplosion.cs:24:184:24:187 | access to property Prop | UseUseExplosion.cs:24:201:24:204 | access to property Prop | +| UseUseExplosion.cs:24:184:24:187 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:184:24:187 | this access | UseUseExplosion.cs:24:201:24:204 | this access | +| UseUseExplosion.cs:24:184:24:187 | this access | UseUseExplosion.cs:24:3043:24:3048 | this access | +| UseUseExplosion.cs:24:201:24:204 | [post] this access | UseUseExplosion.cs:24:218:24:221 | this access | +| UseUseExplosion.cs:24:201:24:204 | [post] this access | UseUseExplosion.cs:24:3028:24:3033 | this access | +| UseUseExplosion.cs:24:201:24:204 | access to property Prop | UseUseExplosion.cs:24:201:24:209 | ... > ... | +| UseUseExplosion.cs:24:201:24:204 | access to property Prop | UseUseExplosion.cs:24:218:24:221 | access to property Prop | +| UseUseExplosion.cs:24:201:24:204 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:201:24:204 | this access | UseUseExplosion.cs:24:218:24:221 | this access | +| UseUseExplosion.cs:24:201:24:204 | this access | UseUseExplosion.cs:24:3028:24:3033 | this access | +| UseUseExplosion.cs:24:218:24:221 | [post] this access | UseUseExplosion.cs:24:235:24:238 | this access | +| UseUseExplosion.cs:24:218:24:221 | [post] this access | UseUseExplosion.cs:24:3013:24:3018 | this access | +| UseUseExplosion.cs:24:218:24:221 | access to property Prop | UseUseExplosion.cs:24:218:24:226 | ... > ... | +| UseUseExplosion.cs:24:218:24:221 | access to property Prop | UseUseExplosion.cs:24:235:24:238 | access to property Prop | +| UseUseExplosion.cs:24:218:24:221 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:218:24:221 | this access | UseUseExplosion.cs:24:235:24:238 | this access | +| UseUseExplosion.cs:24:218:24:221 | this access | UseUseExplosion.cs:24:3013:24:3018 | this access | +| UseUseExplosion.cs:24:235:24:238 | [post] this access | UseUseExplosion.cs:24:252:24:255 | this access | +| UseUseExplosion.cs:24:235:24:238 | [post] this access | UseUseExplosion.cs:24:2998:24:3003 | this access | +| UseUseExplosion.cs:24:235:24:238 | access to property Prop | UseUseExplosion.cs:24:235:24:243 | ... > ... | +| UseUseExplosion.cs:24:235:24:238 | access to property Prop | UseUseExplosion.cs:24:252:24:255 | access to property Prop | +| UseUseExplosion.cs:24:235:24:238 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:235:24:238 | this access | UseUseExplosion.cs:24:252:24:255 | this access | +| UseUseExplosion.cs:24:235:24:238 | this access | UseUseExplosion.cs:24:2998:24:3003 | this access | +| UseUseExplosion.cs:24:252:24:255 | [post] this access | UseUseExplosion.cs:24:269:24:272 | this access | +| UseUseExplosion.cs:24:252:24:255 | [post] this access | UseUseExplosion.cs:24:2983:24:2988 | this access | +| UseUseExplosion.cs:24:252:24:255 | access to property Prop | UseUseExplosion.cs:24:252:24:260 | ... > ... | +| UseUseExplosion.cs:24:252:24:255 | access to property Prop | UseUseExplosion.cs:24:269:24:272 | access to property Prop | +| UseUseExplosion.cs:24:252:24:255 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:252:24:255 | this access | UseUseExplosion.cs:24:269:24:272 | this access | +| UseUseExplosion.cs:24:252:24:255 | this access | UseUseExplosion.cs:24:2983:24:2988 | this access | +| UseUseExplosion.cs:24:269:24:272 | [post] this access | UseUseExplosion.cs:24:286:24:289 | this access | +| UseUseExplosion.cs:24:269:24:272 | [post] this access | UseUseExplosion.cs:24:2968:24:2973 | this access | +| UseUseExplosion.cs:24:269:24:272 | access to property Prop | UseUseExplosion.cs:24:269:24:277 | ... > ... | +| UseUseExplosion.cs:24:269:24:272 | access to property Prop | UseUseExplosion.cs:24:286:24:289 | access to property Prop | +| UseUseExplosion.cs:24:269:24:272 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:269:24:272 | this access | UseUseExplosion.cs:24:286:24:289 | this access | +| UseUseExplosion.cs:24:269:24:272 | this access | UseUseExplosion.cs:24:2968:24:2973 | this access | +| UseUseExplosion.cs:24:286:24:289 | [post] this access | UseUseExplosion.cs:24:303:24:306 | this access | +| UseUseExplosion.cs:24:286:24:289 | [post] this access | UseUseExplosion.cs:24:2953:24:2958 | this access | +| UseUseExplosion.cs:24:286:24:289 | access to property Prop | UseUseExplosion.cs:24:286:24:294 | ... > ... | +| UseUseExplosion.cs:24:286:24:289 | access to property Prop | UseUseExplosion.cs:24:303:24:306 | access to property Prop | +| UseUseExplosion.cs:24:286:24:289 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:286:24:289 | this access | UseUseExplosion.cs:24:303:24:306 | this access | +| UseUseExplosion.cs:24:286:24:289 | this access | UseUseExplosion.cs:24:2953:24:2958 | this access | +| UseUseExplosion.cs:24:303:24:306 | [post] this access | UseUseExplosion.cs:24:320:24:323 | this access | +| UseUseExplosion.cs:24:303:24:306 | [post] this access | UseUseExplosion.cs:24:2938:24:2943 | this access | +| UseUseExplosion.cs:24:303:24:306 | access to property Prop | UseUseExplosion.cs:24:303:24:311 | ... > ... | +| UseUseExplosion.cs:24:303:24:306 | access to property Prop | UseUseExplosion.cs:24:320:24:323 | access to property Prop | +| UseUseExplosion.cs:24:303:24:306 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:303:24:306 | this access | UseUseExplosion.cs:24:320:24:323 | this access | +| UseUseExplosion.cs:24:303:24:306 | this access | UseUseExplosion.cs:24:2938:24:2943 | this access | +| UseUseExplosion.cs:24:320:24:323 | [post] this access | UseUseExplosion.cs:24:337:24:340 | this access | +| UseUseExplosion.cs:24:320:24:323 | [post] this access | UseUseExplosion.cs:24:2923:24:2928 | this access | +| UseUseExplosion.cs:24:320:24:323 | access to property Prop | UseUseExplosion.cs:24:320:24:328 | ... > ... | +| UseUseExplosion.cs:24:320:24:323 | access to property Prop | UseUseExplosion.cs:24:337:24:340 | access to property Prop | +| UseUseExplosion.cs:24:320:24:323 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:320:24:323 | this access | UseUseExplosion.cs:24:337:24:340 | this access | +| UseUseExplosion.cs:24:320:24:323 | this access | UseUseExplosion.cs:24:2923:24:2928 | this access | +| UseUseExplosion.cs:24:337:24:340 | [post] this access | UseUseExplosion.cs:24:354:24:357 | this access | +| UseUseExplosion.cs:24:337:24:340 | [post] this access | UseUseExplosion.cs:24:2908:24:2913 | this access | +| UseUseExplosion.cs:24:337:24:340 | access to property Prop | UseUseExplosion.cs:24:337:24:345 | ... > ... | +| UseUseExplosion.cs:24:337:24:340 | access to property Prop | UseUseExplosion.cs:24:354:24:357 | access to property Prop | +| UseUseExplosion.cs:24:337:24:340 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:337:24:340 | this access | UseUseExplosion.cs:24:354:24:357 | this access | +| UseUseExplosion.cs:24:337:24:340 | this access | UseUseExplosion.cs:24:2908:24:2913 | this access | +| UseUseExplosion.cs:24:354:24:357 | [post] this access | UseUseExplosion.cs:24:371:24:374 | this access | +| UseUseExplosion.cs:24:354:24:357 | [post] this access | UseUseExplosion.cs:24:2893:24:2898 | this access | +| UseUseExplosion.cs:24:354:24:357 | access to property Prop | UseUseExplosion.cs:24:354:24:362 | ... > ... | +| UseUseExplosion.cs:24:354:24:357 | access to property Prop | UseUseExplosion.cs:24:371:24:374 | access to property Prop | +| UseUseExplosion.cs:24:354:24:357 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:354:24:357 | this access | UseUseExplosion.cs:24:371:24:374 | this access | +| UseUseExplosion.cs:24:354:24:357 | this access | UseUseExplosion.cs:24:2893:24:2898 | this access | +| UseUseExplosion.cs:24:371:24:374 | [post] this access | UseUseExplosion.cs:24:388:24:391 | this access | +| UseUseExplosion.cs:24:371:24:374 | [post] this access | UseUseExplosion.cs:24:2878:24:2883 | this access | +| UseUseExplosion.cs:24:371:24:374 | access to property Prop | UseUseExplosion.cs:24:371:24:379 | ... > ... | +| UseUseExplosion.cs:24:371:24:374 | access to property Prop | UseUseExplosion.cs:24:388:24:391 | access to property Prop | +| UseUseExplosion.cs:24:371:24:374 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:371:24:374 | this access | UseUseExplosion.cs:24:388:24:391 | this access | +| UseUseExplosion.cs:24:371:24:374 | this access | UseUseExplosion.cs:24:2878:24:2883 | this access | +| UseUseExplosion.cs:24:388:24:391 | [post] this access | UseUseExplosion.cs:24:405:24:408 | this access | +| UseUseExplosion.cs:24:388:24:391 | [post] this access | UseUseExplosion.cs:24:2863:24:2868 | this access | +| UseUseExplosion.cs:24:388:24:391 | access to property Prop | UseUseExplosion.cs:24:388:24:396 | ... > ... | +| UseUseExplosion.cs:24:388:24:391 | access to property Prop | UseUseExplosion.cs:24:405:24:408 | access to property Prop | +| UseUseExplosion.cs:24:388:24:391 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:388:24:391 | this access | UseUseExplosion.cs:24:405:24:408 | this access | +| UseUseExplosion.cs:24:388:24:391 | this access | UseUseExplosion.cs:24:2863:24:2868 | this access | +| UseUseExplosion.cs:24:405:24:408 | [post] this access | UseUseExplosion.cs:24:422:24:425 | this access | +| UseUseExplosion.cs:24:405:24:408 | [post] this access | UseUseExplosion.cs:24:2848:24:2853 | this access | +| UseUseExplosion.cs:24:405:24:408 | access to property Prop | UseUseExplosion.cs:24:405:24:413 | ... > ... | +| UseUseExplosion.cs:24:405:24:408 | access to property Prop | UseUseExplosion.cs:24:422:24:425 | access to property Prop | +| UseUseExplosion.cs:24:405:24:408 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:405:24:408 | this access | UseUseExplosion.cs:24:422:24:425 | this access | +| UseUseExplosion.cs:24:405:24:408 | this access | UseUseExplosion.cs:24:2848:24:2853 | this access | +| UseUseExplosion.cs:24:422:24:425 | [post] this access | UseUseExplosion.cs:24:439:24:442 | this access | +| UseUseExplosion.cs:24:422:24:425 | [post] this access | UseUseExplosion.cs:24:2833:24:2838 | this access | +| UseUseExplosion.cs:24:422:24:425 | access to property Prop | UseUseExplosion.cs:24:422:24:430 | ... > ... | +| UseUseExplosion.cs:24:422:24:425 | access to property Prop | UseUseExplosion.cs:24:439:24:442 | access to property Prop | +| UseUseExplosion.cs:24:422:24:425 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:422:24:425 | this access | UseUseExplosion.cs:24:439:24:442 | this access | +| UseUseExplosion.cs:24:422:24:425 | this access | UseUseExplosion.cs:24:2833:24:2838 | this access | +| UseUseExplosion.cs:24:439:24:442 | [post] this access | UseUseExplosion.cs:24:456:24:459 | this access | +| UseUseExplosion.cs:24:439:24:442 | [post] this access | UseUseExplosion.cs:24:2818:24:2823 | this access | +| UseUseExplosion.cs:24:439:24:442 | access to property Prop | UseUseExplosion.cs:24:439:24:447 | ... > ... | +| UseUseExplosion.cs:24:439:24:442 | access to property Prop | UseUseExplosion.cs:24:456:24:459 | access to property Prop | +| UseUseExplosion.cs:24:439:24:442 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:439:24:442 | this access | UseUseExplosion.cs:24:456:24:459 | this access | +| UseUseExplosion.cs:24:439:24:442 | this access | UseUseExplosion.cs:24:2818:24:2823 | this access | +| UseUseExplosion.cs:24:456:24:459 | [post] this access | UseUseExplosion.cs:24:473:24:476 | this access | +| UseUseExplosion.cs:24:456:24:459 | [post] this access | UseUseExplosion.cs:24:2803:24:2808 | this access | +| UseUseExplosion.cs:24:456:24:459 | access to property Prop | UseUseExplosion.cs:24:456:24:464 | ... > ... | +| UseUseExplosion.cs:24:456:24:459 | access to property Prop | UseUseExplosion.cs:24:473:24:476 | access to property Prop | +| UseUseExplosion.cs:24:456:24:459 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:456:24:459 | this access | UseUseExplosion.cs:24:473:24:476 | this access | +| UseUseExplosion.cs:24:456:24:459 | this access | UseUseExplosion.cs:24:2803:24:2808 | this access | +| UseUseExplosion.cs:24:473:24:476 | [post] this access | UseUseExplosion.cs:24:490:24:493 | this access | +| UseUseExplosion.cs:24:473:24:476 | [post] this access | UseUseExplosion.cs:24:2788:24:2793 | this access | +| UseUseExplosion.cs:24:473:24:476 | access to property Prop | UseUseExplosion.cs:24:473:24:481 | ... > ... | +| UseUseExplosion.cs:24:473:24:476 | access to property Prop | UseUseExplosion.cs:24:490:24:493 | access to property Prop | +| UseUseExplosion.cs:24:473:24:476 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:473:24:476 | this access | UseUseExplosion.cs:24:490:24:493 | this access | +| UseUseExplosion.cs:24:473:24:476 | this access | UseUseExplosion.cs:24:2788:24:2793 | this access | +| UseUseExplosion.cs:24:490:24:493 | [post] this access | UseUseExplosion.cs:24:507:24:510 | this access | +| UseUseExplosion.cs:24:490:24:493 | [post] this access | UseUseExplosion.cs:24:2773:24:2778 | this access | +| UseUseExplosion.cs:24:490:24:493 | access to property Prop | UseUseExplosion.cs:24:490:24:498 | ... > ... | +| UseUseExplosion.cs:24:490:24:493 | access to property Prop | UseUseExplosion.cs:24:507:24:510 | access to property Prop | +| UseUseExplosion.cs:24:490:24:493 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:490:24:493 | this access | UseUseExplosion.cs:24:507:24:510 | this access | +| UseUseExplosion.cs:24:490:24:493 | this access | UseUseExplosion.cs:24:2773:24:2778 | this access | +| UseUseExplosion.cs:24:507:24:510 | [post] this access | UseUseExplosion.cs:24:524:24:527 | this access | +| UseUseExplosion.cs:24:507:24:510 | [post] this access | UseUseExplosion.cs:24:2758:24:2763 | this access | +| UseUseExplosion.cs:24:507:24:510 | access to property Prop | UseUseExplosion.cs:24:507:24:515 | ... > ... | +| UseUseExplosion.cs:24:507:24:510 | access to property Prop | UseUseExplosion.cs:24:524:24:527 | access to property Prop | +| UseUseExplosion.cs:24:507:24:510 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:507:24:510 | this access | UseUseExplosion.cs:24:524:24:527 | this access | +| UseUseExplosion.cs:24:507:24:510 | this access | UseUseExplosion.cs:24:2758:24:2763 | this access | +| UseUseExplosion.cs:24:524:24:527 | [post] this access | UseUseExplosion.cs:24:541:24:544 | this access | +| UseUseExplosion.cs:24:524:24:527 | [post] this access | UseUseExplosion.cs:24:2743:24:2748 | this access | +| UseUseExplosion.cs:24:524:24:527 | access to property Prop | UseUseExplosion.cs:24:524:24:532 | ... > ... | +| UseUseExplosion.cs:24:524:24:527 | access to property Prop | UseUseExplosion.cs:24:541:24:544 | access to property Prop | +| UseUseExplosion.cs:24:524:24:527 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:524:24:527 | this access | UseUseExplosion.cs:24:541:24:544 | this access | +| UseUseExplosion.cs:24:524:24:527 | this access | UseUseExplosion.cs:24:2743:24:2748 | this access | +| UseUseExplosion.cs:24:541:24:544 | [post] this access | UseUseExplosion.cs:24:558:24:561 | this access | +| UseUseExplosion.cs:24:541:24:544 | [post] this access | UseUseExplosion.cs:24:2728:24:2733 | this access | +| UseUseExplosion.cs:24:541:24:544 | access to property Prop | UseUseExplosion.cs:24:541:24:549 | ... > ... | +| UseUseExplosion.cs:24:541:24:544 | access to property Prop | UseUseExplosion.cs:24:558:24:561 | access to property Prop | +| UseUseExplosion.cs:24:541:24:544 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:541:24:544 | this access | UseUseExplosion.cs:24:558:24:561 | this access | +| UseUseExplosion.cs:24:541:24:544 | this access | UseUseExplosion.cs:24:2728:24:2733 | this access | +| UseUseExplosion.cs:24:558:24:561 | [post] this access | UseUseExplosion.cs:24:575:24:578 | this access | +| UseUseExplosion.cs:24:558:24:561 | [post] this access | UseUseExplosion.cs:24:2713:24:2718 | this access | +| UseUseExplosion.cs:24:558:24:561 | access to property Prop | UseUseExplosion.cs:24:558:24:566 | ... > ... | +| UseUseExplosion.cs:24:558:24:561 | access to property Prop | UseUseExplosion.cs:24:575:24:578 | access to property Prop | +| UseUseExplosion.cs:24:558:24:561 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:558:24:561 | this access | UseUseExplosion.cs:24:575:24:578 | this access | +| UseUseExplosion.cs:24:558:24:561 | this access | UseUseExplosion.cs:24:2713:24:2718 | this access | +| UseUseExplosion.cs:24:575:24:578 | [post] this access | UseUseExplosion.cs:24:592:24:595 | this access | +| UseUseExplosion.cs:24:575:24:578 | [post] this access | UseUseExplosion.cs:24:2698:24:2703 | this access | +| UseUseExplosion.cs:24:575:24:578 | access to property Prop | UseUseExplosion.cs:24:575:24:583 | ... > ... | +| UseUseExplosion.cs:24:575:24:578 | access to property Prop | UseUseExplosion.cs:24:592:24:595 | access to property Prop | +| UseUseExplosion.cs:24:575:24:578 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:575:24:578 | this access | UseUseExplosion.cs:24:592:24:595 | this access | +| UseUseExplosion.cs:24:575:24:578 | this access | UseUseExplosion.cs:24:2698:24:2703 | this access | +| UseUseExplosion.cs:24:592:24:595 | [post] this access | UseUseExplosion.cs:24:609:24:612 | this access | +| UseUseExplosion.cs:24:592:24:595 | [post] this access | UseUseExplosion.cs:24:2683:24:2688 | this access | +| UseUseExplosion.cs:24:592:24:595 | access to property Prop | UseUseExplosion.cs:24:592:24:600 | ... > ... | +| UseUseExplosion.cs:24:592:24:595 | access to property Prop | UseUseExplosion.cs:24:609:24:612 | access to property Prop | +| UseUseExplosion.cs:24:592:24:595 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:592:24:595 | this access | UseUseExplosion.cs:24:609:24:612 | this access | +| UseUseExplosion.cs:24:592:24:595 | this access | UseUseExplosion.cs:24:2683:24:2688 | this access | +| UseUseExplosion.cs:24:609:24:612 | [post] this access | UseUseExplosion.cs:24:626:24:629 | this access | +| UseUseExplosion.cs:24:609:24:612 | [post] this access | UseUseExplosion.cs:24:2668:24:2673 | this access | +| UseUseExplosion.cs:24:609:24:612 | access to property Prop | UseUseExplosion.cs:24:609:24:617 | ... > ... | +| UseUseExplosion.cs:24:609:24:612 | access to property Prop | UseUseExplosion.cs:24:626:24:629 | access to property Prop | +| UseUseExplosion.cs:24:609:24:612 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:609:24:612 | this access | UseUseExplosion.cs:24:626:24:629 | this access | +| UseUseExplosion.cs:24:609:24:612 | this access | UseUseExplosion.cs:24:2668:24:2673 | this access | +| UseUseExplosion.cs:24:626:24:629 | [post] this access | UseUseExplosion.cs:24:643:24:646 | this access | +| UseUseExplosion.cs:24:626:24:629 | [post] this access | UseUseExplosion.cs:24:2653:24:2658 | this access | +| UseUseExplosion.cs:24:626:24:629 | access to property Prop | UseUseExplosion.cs:24:626:24:634 | ... > ... | +| UseUseExplosion.cs:24:626:24:629 | access to property Prop | UseUseExplosion.cs:24:643:24:646 | access to property Prop | +| UseUseExplosion.cs:24:626:24:629 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:626:24:629 | this access | UseUseExplosion.cs:24:643:24:646 | this access | +| UseUseExplosion.cs:24:626:24:629 | this access | UseUseExplosion.cs:24:2653:24:2658 | this access | +| UseUseExplosion.cs:24:643:24:646 | [post] this access | UseUseExplosion.cs:24:660:24:663 | this access | +| UseUseExplosion.cs:24:643:24:646 | [post] this access | UseUseExplosion.cs:24:2638:24:2643 | this access | +| UseUseExplosion.cs:24:643:24:646 | access to property Prop | UseUseExplosion.cs:24:643:24:651 | ... > ... | +| UseUseExplosion.cs:24:643:24:646 | access to property Prop | UseUseExplosion.cs:24:660:24:663 | access to property Prop | +| UseUseExplosion.cs:24:643:24:646 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:643:24:646 | this access | UseUseExplosion.cs:24:660:24:663 | this access | +| UseUseExplosion.cs:24:643:24:646 | this access | UseUseExplosion.cs:24:2638:24:2643 | this access | +| UseUseExplosion.cs:24:660:24:663 | [post] this access | UseUseExplosion.cs:24:677:24:680 | this access | +| UseUseExplosion.cs:24:660:24:663 | [post] this access | UseUseExplosion.cs:24:2623:24:2628 | this access | +| UseUseExplosion.cs:24:660:24:663 | access to property Prop | UseUseExplosion.cs:24:660:24:668 | ... > ... | +| UseUseExplosion.cs:24:660:24:663 | access to property Prop | UseUseExplosion.cs:24:677:24:680 | access to property Prop | +| UseUseExplosion.cs:24:660:24:663 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:660:24:663 | this access | UseUseExplosion.cs:24:677:24:680 | this access | +| UseUseExplosion.cs:24:660:24:663 | this access | UseUseExplosion.cs:24:2623:24:2628 | this access | +| UseUseExplosion.cs:24:677:24:680 | [post] this access | UseUseExplosion.cs:24:694:24:697 | this access | +| UseUseExplosion.cs:24:677:24:680 | [post] this access | UseUseExplosion.cs:24:2608:24:2613 | this access | +| UseUseExplosion.cs:24:677:24:680 | access to property Prop | UseUseExplosion.cs:24:677:24:685 | ... > ... | +| UseUseExplosion.cs:24:677:24:680 | access to property Prop | UseUseExplosion.cs:24:694:24:697 | access to property Prop | +| UseUseExplosion.cs:24:677:24:680 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:677:24:680 | this access | UseUseExplosion.cs:24:694:24:697 | this access | +| UseUseExplosion.cs:24:677:24:680 | this access | UseUseExplosion.cs:24:2608:24:2613 | this access | +| UseUseExplosion.cs:24:694:24:697 | [post] this access | UseUseExplosion.cs:24:711:24:714 | this access | +| UseUseExplosion.cs:24:694:24:697 | [post] this access | UseUseExplosion.cs:24:2593:24:2598 | this access | +| UseUseExplosion.cs:24:694:24:697 | access to property Prop | UseUseExplosion.cs:24:694:24:702 | ... > ... | +| UseUseExplosion.cs:24:694:24:697 | access to property Prop | UseUseExplosion.cs:24:711:24:714 | access to property Prop | +| UseUseExplosion.cs:24:694:24:697 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:694:24:697 | this access | UseUseExplosion.cs:24:711:24:714 | this access | +| UseUseExplosion.cs:24:694:24:697 | this access | UseUseExplosion.cs:24:2593:24:2598 | this access | +| UseUseExplosion.cs:24:711:24:714 | [post] this access | UseUseExplosion.cs:24:728:24:731 | this access | +| UseUseExplosion.cs:24:711:24:714 | [post] this access | UseUseExplosion.cs:24:2578:24:2583 | this access | +| UseUseExplosion.cs:24:711:24:714 | access to property Prop | UseUseExplosion.cs:24:711:24:719 | ... > ... | +| UseUseExplosion.cs:24:711:24:714 | access to property Prop | UseUseExplosion.cs:24:728:24:731 | access to property Prop | +| UseUseExplosion.cs:24:711:24:714 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:711:24:714 | this access | UseUseExplosion.cs:24:728:24:731 | this access | +| UseUseExplosion.cs:24:711:24:714 | this access | UseUseExplosion.cs:24:2578:24:2583 | this access | +| UseUseExplosion.cs:24:728:24:731 | [post] this access | UseUseExplosion.cs:24:745:24:748 | this access | +| UseUseExplosion.cs:24:728:24:731 | [post] this access | UseUseExplosion.cs:24:2563:24:2568 | this access | +| UseUseExplosion.cs:24:728:24:731 | access to property Prop | UseUseExplosion.cs:24:728:24:736 | ... > ... | +| UseUseExplosion.cs:24:728:24:731 | access to property Prop | UseUseExplosion.cs:24:745:24:748 | access to property Prop | +| UseUseExplosion.cs:24:728:24:731 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:728:24:731 | this access | UseUseExplosion.cs:24:745:24:748 | this access | +| UseUseExplosion.cs:24:728:24:731 | this access | UseUseExplosion.cs:24:2563:24:2568 | this access | +| UseUseExplosion.cs:24:745:24:748 | [post] this access | UseUseExplosion.cs:24:762:24:765 | this access | +| UseUseExplosion.cs:24:745:24:748 | [post] this access | UseUseExplosion.cs:24:2548:24:2553 | this access | +| UseUseExplosion.cs:24:745:24:748 | access to property Prop | UseUseExplosion.cs:24:745:24:753 | ... > ... | +| UseUseExplosion.cs:24:745:24:748 | access to property Prop | UseUseExplosion.cs:24:762:24:765 | access to property Prop | +| UseUseExplosion.cs:24:745:24:748 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:745:24:748 | this access | UseUseExplosion.cs:24:762:24:765 | this access | +| UseUseExplosion.cs:24:745:24:748 | this access | UseUseExplosion.cs:24:2548:24:2553 | this access | +| UseUseExplosion.cs:24:762:24:765 | [post] this access | UseUseExplosion.cs:24:779:24:782 | this access | +| UseUseExplosion.cs:24:762:24:765 | [post] this access | UseUseExplosion.cs:24:2533:24:2538 | this access | +| UseUseExplosion.cs:24:762:24:765 | access to property Prop | UseUseExplosion.cs:24:762:24:770 | ... > ... | +| UseUseExplosion.cs:24:762:24:765 | access to property Prop | UseUseExplosion.cs:24:779:24:782 | access to property Prop | +| UseUseExplosion.cs:24:762:24:765 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:762:24:765 | this access | UseUseExplosion.cs:24:779:24:782 | this access | +| UseUseExplosion.cs:24:762:24:765 | this access | UseUseExplosion.cs:24:2533:24:2538 | this access | +| UseUseExplosion.cs:24:779:24:782 | [post] this access | UseUseExplosion.cs:24:796:24:799 | this access | +| UseUseExplosion.cs:24:779:24:782 | [post] this access | UseUseExplosion.cs:24:2518:24:2523 | this access | +| UseUseExplosion.cs:24:779:24:782 | access to property Prop | UseUseExplosion.cs:24:779:24:787 | ... > ... | +| UseUseExplosion.cs:24:779:24:782 | access to property Prop | UseUseExplosion.cs:24:796:24:799 | access to property Prop | +| UseUseExplosion.cs:24:779:24:782 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:779:24:782 | this access | UseUseExplosion.cs:24:796:24:799 | this access | +| UseUseExplosion.cs:24:779:24:782 | this access | UseUseExplosion.cs:24:2518:24:2523 | this access | +| UseUseExplosion.cs:24:796:24:799 | [post] this access | UseUseExplosion.cs:24:813:24:816 | this access | +| UseUseExplosion.cs:24:796:24:799 | [post] this access | UseUseExplosion.cs:24:2503:24:2508 | this access | +| UseUseExplosion.cs:24:796:24:799 | access to property Prop | UseUseExplosion.cs:24:796:24:804 | ... > ... | +| UseUseExplosion.cs:24:796:24:799 | access to property Prop | UseUseExplosion.cs:24:813:24:816 | access to property Prop | +| UseUseExplosion.cs:24:796:24:799 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:796:24:799 | this access | UseUseExplosion.cs:24:813:24:816 | this access | +| UseUseExplosion.cs:24:796:24:799 | this access | UseUseExplosion.cs:24:2503:24:2508 | this access | +| UseUseExplosion.cs:24:813:24:816 | [post] this access | UseUseExplosion.cs:24:830:24:833 | this access | +| UseUseExplosion.cs:24:813:24:816 | [post] this access | UseUseExplosion.cs:24:2488:24:2493 | this access | +| UseUseExplosion.cs:24:813:24:816 | access to property Prop | UseUseExplosion.cs:24:813:24:821 | ... > ... | +| UseUseExplosion.cs:24:813:24:816 | access to property Prop | UseUseExplosion.cs:24:830:24:833 | access to property Prop | +| UseUseExplosion.cs:24:813:24:816 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:813:24:816 | this access | UseUseExplosion.cs:24:830:24:833 | this access | +| UseUseExplosion.cs:24:813:24:816 | this access | UseUseExplosion.cs:24:2488:24:2493 | this access | +| UseUseExplosion.cs:24:830:24:833 | [post] this access | UseUseExplosion.cs:24:847:24:850 | this access | +| UseUseExplosion.cs:24:830:24:833 | [post] this access | UseUseExplosion.cs:24:2473:24:2478 | this access | +| UseUseExplosion.cs:24:830:24:833 | access to property Prop | UseUseExplosion.cs:24:830:24:838 | ... > ... | +| UseUseExplosion.cs:24:830:24:833 | access to property Prop | UseUseExplosion.cs:24:847:24:850 | access to property Prop | +| UseUseExplosion.cs:24:830:24:833 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:830:24:833 | this access | UseUseExplosion.cs:24:847:24:850 | this access | +| UseUseExplosion.cs:24:830:24:833 | this access | UseUseExplosion.cs:24:2473:24:2478 | this access | +| UseUseExplosion.cs:24:847:24:850 | [post] this access | UseUseExplosion.cs:24:864:24:867 | this access | +| UseUseExplosion.cs:24:847:24:850 | [post] this access | UseUseExplosion.cs:24:2458:24:2463 | this access | +| UseUseExplosion.cs:24:847:24:850 | access to property Prop | UseUseExplosion.cs:24:847:24:855 | ... > ... | +| UseUseExplosion.cs:24:847:24:850 | access to property Prop | UseUseExplosion.cs:24:864:24:867 | access to property Prop | +| UseUseExplosion.cs:24:847:24:850 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:847:24:850 | this access | UseUseExplosion.cs:24:864:24:867 | this access | +| UseUseExplosion.cs:24:847:24:850 | this access | UseUseExplosion.cs:24:2458:24:2463 | this access | +| UseUseExplosion.cs:24:864:24:867 | [post] this access | UseUseExplosion.cs:24:881:24:884 | this access | +| UseUseExplosion.cs:24:864:24:867 | [post] this access | UseUseExplosion.cs:24:2443:24:2448 | this access | +| UseUseExplosion.cs:24:864:24:867 | access to property Prop | UseUseExplosion.cs:24:864:24:872 | ... > ... | +| UseUseExplosion.cs:24:864:24:867 | access to property Prop | UseUseExplosion.cs:24:881:24:884 | access to property Prop | +| UseUseExplosion.cs:24:864:24:867 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:864:24:867 | this access | UseUseExplosion.cs:24:881:24:884 | this access | +| UseUseExplosion.cs:24:864:24:867 | this access | UseUseExplosion.cs:24:2443:24:2448 | this access | +| UseUseExplosion.cs:24:881:24:884 | [post] this access | UseUseExplosion.cs:24:898:24:901 | this access | +| UseUseExplosion.cs:24:881:24:884 | [post] this access | UseUseExplosion.cs:24:2428:24:2433 | this access | +| UseUseExplosion.cs:24:881:24:884 | access to property Prop | UseUseExplosion.cs:24:881:24:889 | ... > ... | +| UseUseExplosion.cs:24:881:24:884 | access to property Prop | UseUseExplosion.cs:24:898:24:901 | access to property Prop | +| UseUseExplosion.cs:24:881:24:884 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:881:24:884 | this access | UseUseExplosion.cs:24:898:24:901 | this access | +| UseUseExplosion.cs:24:881:24:884 | this access | UseUseExplosion.cs:24:2428:24:2433 | this access | +| UseUseExplosion.cs:24:898:24:901 | [post] this access | UseUseExplosion.cs:24:915:24:918 | this access | +| UseUseExplosion.cs:24:898:24:901 | [post] this access | UseUseExplosion.cs:24:2413:24:2418 | this access | +| UseUseExplosion.cs:24:898:24:901 | access to property Prop | UseUseExplosion.cs:24:898:24:906 | ... > ... | +| UseUseExplosion.cs:24:898:24:901 | access to property Prop | UseUseExplosion.cs:24:915:24:918 | access to property Prop | +| UseUseExplosion.cs:24:898:24:901 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:898:24:901 | this access | UseUseExplosion.cs:24:915:24:918 | this access | +| UseUseExplosion.cs:24:898:24:901 | this access | UseUseExplosion.cs:24:2413:24:2418 | this access | +| UseUseExplosion.cs:24:915:24:918 | [post] this access | UseUseExplosion.cs:24:932:24:935 | this access | +| UseUseExplosion.cs:24:915:24:918 | [post] this access | UseUseExplosion.cs:24:2398:24:2403 | this access | +| UseUseExplosion.cs:24:915:24:918 | access to property Prop | UseUseExplosion.cs:24:915:24:923 | ... > ... | +| UseUseExplosion.cs:24:915:24:918 | access to property Prop | UseUseExplosion.cs:24:932:24:935 | access to property Prop | +| UseUseExplosion.cs:24:915:24:918 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:915:24:918 | this access | UseUseExplosion.cs:24:932:24:935 | this access | +| UseUseExplosion.cs:24:915:24:918 | this access | UseUseExplosion.cs:24:2398:24:2403 | this access | +| UseUseExplosion.cs:24:932:24:935 | [post] this access | UseUseExplosion.cs:24:949:24:952 | this access | +| UseUseExplosion.cs:24:932:24:935 | [post] this access | UseUseExplosion.cs:24:2383:24:2388 | this access | +| UseUseExplosion.cs:24:932:24:935 | access to property Prop | UseUseExplosion.cs:24:932:24:940 | ... > ... | +| UseUseExplosion.cs:24:932:24:935 | access to property Prop | UseUseExplosion.cs:24:949:24:952 | access to property Prop | +| UseUseExplosion.cs:24:932:24:935 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:932:24:935 | this access | UseUseExplosion.cs:24:949:24:952 | this access | +| UseUseExplosion.cs:24:932:24:935 | this access | UseUseExplosion.cs:24:2383:24:2388 | this access | +| UseUseExplosion.cs:24:949:24:952 | [post] this access | UseUseExplosion.cs:24:966:24:969 | this access | +| UseUseExplosion.cs:24:949:24:952 | [post] this access | UseUseExplosion.cs:24:2368:24:2373 | this access | +| UseUseExplosion.cs:24:949:24:952 | access to property Prop | UseUseExplosion.cs:24:949:24:957 | ... > ... | +| UseUseExplosion.cs:24:949:24:952 | access to property Prop | UseUseExplosion.cs:24:966:24:969 | access to property Prop | +| UseUseExplosion.cs:24:949:24:952 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:949:24:952 | this access | UseUseExplosion.cs:24:966:24:969 | this access | +| UseUseExplosion.cs:24:949:24:952 | this access | UseUseExplosion.cs:24:2368:24:2373 | this access | +| UseUseExplosion.cs:24:966:24:969 | [post] this access | UseUseExplosion.cs:24:983:24:986 | this access | +| UseUseExplosion.cs:24:966:24:969 | [post] this access | UseUseExplosion.cs:24:2353:24:2358 | this access | +| UseUseExplosion.cs:24:966:24:969 | access to property Prop | UseUseExplosion.cs:24:966:24:974 | ... > ... | +| UseUseExplosion.cs:24:966:24:969 | access to property Prop | UseUseExplosion.cs:24:983:24:986 | access to property Prop | +| UseUseExplosion.cs:24:966:24:969 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:966:24:969 | this access | UseUseExplosion.cs:24:983:24:986 | this access | +| UseUseExplosion.cs:24:966:24:969 | this access | UseUseExplosion.cs:24:2353:24:2358 | this access | +| UseUseExplosion.cs:24:983:24:986 | [post] this access | UseUseExplosion.cs:24:1000:24:1003 | this access | +| UseUseExplosion.cs:24:983:24:986 | [post] this access | UseUseExplosion.cs:24:2338:24:2343 | this access | +| UseUseExplosion.cs:24:983:24:986 | access to property Prop | UseUseExplosion.cs:24:983:24:991 | ... > ... | +| UseUseExplosion.cs:24:983:24:986 | access to property Prop | UseUseExplosion.cs:24:1000:24:1003 | access to property Prop | +| UseUseExplosion.cs:24:983:24:986 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:983:24:986 | this access | UseUseExplosion.cs:24:1000:24:1003 | this access | +| UseUseExplosion.cs:24:983:24:986 | this access | UseUseExplosion.cs:24:2338:24:2343 | this access | +| UseUseExplosion.cs:24:1000:24:1003 | [post] this access | UseUseExplosion.cs:24:1017:24:1020 | this access | +| UseUseExplosion.cs:24:1000:24:1003 | [post] this access | UseUseExplosion.cs:24:2323:24:2328 | this access | +| UseUseExplosion.cs:24:1000:24:1003 | access to property Prop | UseUseExplosion.cs:24:1000:24:1008 | ... > ... | +| UseUseExplosion.cs:24:1000:24:1003 | access to property Prop | UseUseExplosion.cs:24:1017:24:1020 | access to property Prop | +| UseUseExplosion.cs:24:1000:24:1003 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1000:24:1003 | this access | UseUseExplosion.cs:24:1017:24:1020 | this access | +| UseUseExplosion.cs:24:1000:24:1003 | this access | UseUseExplosion.cs:24:2323:24:2328 | this access | +| UseUseExplosion.cs:24:1017:24:1020 | [post] this access | UseUseExplosion.cs:24:1034:24:1037 | this access | +| UseUseExplosion.cs:24:1017:24:1020 | [post] this access | UseUseExplosion.cs:24:2308:24:2313 | this access | +| UseUseExplosion.cs:24:1017:24:1020 | access to property Prop | UseUseExplosion.cs:24:1017:24:1025 | ... > ... | +| UseUseExplosion.cs:24:1017:24:1020 | access to property Prop | UseUseExplosion.cs:24:1034:24:1037 | access to property Prop | +| UseUseExplosion.cs:24:1017:24:1020 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1017:24:1020 | this access | UseUseExplosion.cs:24:1034:24:1037 | this access | +| UseUseExplosion.cs:24:1017:24:1020 | this access | UseUseExplosion.cs:24:2308:24:2313 | this access | +| UseUseExplosion.cs:24:1034:24:1037 | [post] this access | UseUseExplosion.cs:24:1051:24:1054 | this access | +| UseUseExplosion.cs:24:1034:24:1037 | [post] this access | UseUseExplosion.cs:24:2293:24:2298 | this access | +| UseUseExplosion.cs:24:1034:24:1037 | access to property Prop | UseUseExplosion.cs:24:1034:24:1042 | ... > ... | +| UseUseExplosion.cs:24:1034:24:1037 | access to property Prop | UseUseExplosion.cs:24:1051:24:1054 | access to property Prop | +| UseUseExplosion.cs:24:1034:24:1037 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1034:24:1037 | this access | UseUseExplosion.cs:24:1051:24:1054 | this access | +| UseUseExplosion.cs:24:1034:24:1037 | this access | UseUseExplosion.cs:24:2293:24:2298 | this access | +| UseUseExplosion.cs:24:1051:24:1054 | [post] this access | UseUseExplosion.cs:24:1068:24:1071 | this access | +| UseUseExplosion.cs:24:1051:24:1054 | [post] this access | UseUseExplosion.cs:24:2278:24:2283 | this access | +| UseUseExplosion.cs:24:1051:24:1054 | access to property Prop | UseUseExplosion.cs:24:1051:24:1059 | ... > ... | +| UseUseExplosion.cs:24:1051:24:1054 | access to property Prop | UseUseExplosion.cs:24:1068:24:1071 | access to property Prop | +| UseUseExplosion.cs:24:1051:24:1054 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1051:24:1054 | this access | UseUseExplosion.cs:24:1068:24:1071 | this access | +| UseUseExplosion.cs:24:1051:24:1054 | this access | UseUseExplosion.cs:24:2278:24:2283 | this access | +| UseUseExplosion.cs:24:1068:24:1071 | [post] this access | UseUseExplosion.cs:24:1085:24:1088 | this access | +| UseUseExplosion.cs:24:1068:24:1071 | [post] this access | UseUseExplosion.cs:24:2263:24:2268 | this access | +| UseUseExplosion.cs:24:1068:24:1071 | access to property Prop | UseUseExplosion.cs:24:1068:24:1076 | ... > ... | +| UseUseExplosion.cs:24:1068:24:1071 | access to property Prop | UseUseExplosion.cs:24:1085:24:1088 | access to property Prop | +| UseUseExplosion.cs:24:1068:24:1071 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1068:24:1071 | this access | UseUseExplosion.cs:24:1085:24:1088 | this access | +| UseUseExplosion.cs:24:1068:24:1071 | this access | UseUseExplosion.cs:24:2263:24:2268 | this access | +| UseUseExplosion.cs:24:1085:24:1088 | [post] this access | UseUseExplosion.cs:24:1102:24:1105 | this access | +| UseUseExplosion.cs:24:1085:24:1088 | [post] this access | UseUseExplosion.cs:24:2248:24:2253 | this access | +| UseUseExplosion.cs:24:1085:24:1088 | access to property Prop | UseUseExplosion.cs:24:1085:24:1093 | ... > ... | +| UseUseExplosion.cs:24:1085:24:1088 | access to property Prop | UseUseExplosion.cs:24:1102:24:1105 | access to property Prop | +| UseUseExplosion.cs:24:1085:24:1088 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1085:24:1088 | this access | UseUseExplosion.cs:24:1102:24:1105 | this access | +| UseUseExplosion.cs:24:1085:24:1088 | this access | UseUseExplosion.cs:24:2248:24:2253 | this access | +| UseUseExplosion.cs:24:1102:24:1105 | [post] this access | UseUseExplosion.cs:24:1119:24:1122 | this access | +| UseUseExplosion.cs:24:1102:24:1105 | [post] this access | UseUseExplosion.cs:24:2233:24:2238 | this access | +| UseUseExplosion.cs:24:1102:24:1105 | access to property Prop | UseUseExplosion.cs:24:1102:24:1110 | ... > ... | +| UseUseExplosion.cs:24:1102:24:1105 | access to property Prop | UseUseExplosion.cs:24:1119:24:1122 | access to property Prop | +| UseUseExplosion.cs:24:1102:24:1105 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1102:24:1105 | this access | UseUseExplosion.cs:24:1119:24:1122 | this access | +| UseUseExplosion.cs:24:1102:24:1105 | this access | UseUseExplosion.cs:24:2233:24:2238 | this access | +| UseUseExplosion.cs:24:1119:24:1122 | [post] this access | UseUseExplosion.cs:24:1136:24:1139 | this access | +| UseUseExplosion.cs:24:1119:24:1122 | [post] this access | UseUseExplosion.cs:24:2218:24:2223 | this access | +| UseUseExplosion.cs:24:1119:24:1122 | access to property Prop | UseUseExplosion.cs:24:1119:24:1127 | ... > ... | +| UseUseExplosion.cs:24:1119:24:1122 | access to property Prop | UseUseExplosion.cs:24:1136:24:1139 | access to property Prop | +| UseUseExplosion.cs:24:1119:24:1122 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1119:24:1122 | this access | UseUseExplosion.cs:24:1136:24:1139 | this access | +| UseUseExplosion.cs:24:1119:24:1122 | this access | UseUseExplosion.cs:24:2218:24:2223 | this access | +| UseUseExplosion.cs:24:1136:24:1139 | [post] this access | UseUseExplosion.cs:24:1153:24:1156 | this access | +| UseUseExplosion.cs:24:1136:24:1139 | [post] this access | UseUseExplosion.cs:24:2203:24:2208 | this access | +| UseUseExplosion.cs:24:1136:24:1139 | access to property Prop | UseUseExplosion.cs:24:1136:24:1144 | ... > ... | +| UseUseExplosion.cs:24:1136:24:1139 | access to property Prop | UseUseExplosion.cs:24:1153:24:1156 | access to property Prop | +| UseUseExplosion.cs:24:1136:24:1139 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1136:24:1139 | this access | UseUseExplosion.cs:24:1153:24:1156 | this access | +| UseUseExplosion.cs:24:1136:24:1139 | this access | UseUseExplosion.cs:24:2203:24:2208 | this access | +| UseUseExplosion.cs:24:1153:24:1156 | [post] this access | UseUseExplosion.cs:24:1170:24:1173 | this access | +| UseUseExplosion.cs:24:1153:24:1156 | [post] this access | UseUseExplosion.cs:24:2188:24:2193 | this access | +| UseUseExplosion.cs:24:1153:24:1156 | access to property Prop | UseUseExplosion.cs:24:1153:24:1161 | ... > ... | +| UseUseExplosion.cs:24:1153:24:1156 | access to property Prop | UseUseExplosion.cs:24:1170:24:1173 | access to property Prop | +| UseUseExplosion.cs:24:1153:24:1156 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1153:24:1156 | this access | UseUseExplosion.cs:24:1170:24:1173 | this access | +| UseUseExplosion.cs:24:1153:24:1156 | this access | UseUseExplosion.cs:24:2188:24:2193 | this access | +| UseUseExplosion.cs:24:1170:24:1173 | [post] this access | UseUseExplosion.cs:24:1187:24:1190 | this access | +| UseUseExplosion.cs:24:1170:24:1173 | [post] this access | UseUseExplosion.cs:24:2173:24:2178 | this access | +| UseUseExplosion.cs:24:1170:24:1173 | access to property Prop | UseUseExplosion.cs:24:1170:24:1178 | ... > ... | +| UseUseExplosion.cs:24:1170:24:1173 | access to property Prop | UseUseExplosion.cs:24:1187:24:1190 | access to property Prop | +| UseUseExplosion.cs:24:1170:24:1173 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1170:24:1173 | this access | UseUseExplosion.cs:24:1187:24:1190 | this access | +| UseUseExplosion.cs:24:1170:24:1173 | this access | UseUseExplosion.cs:24:2173:24:2178 | this access | +| UseUseExplosion.cs:24:1187:24:1190 | [post] this access | UseUseExplosion.cs:24:1204:24:1207 | this access | +| UseUseExplosion.cs:24:1187:24:1190 | [post] this access | UseUseExplosion.cs:24:2158:24:2163 | this access | +| UseUseExplosion.cs:24:1187:24:1190 | access to property Prop | UseUseExplosion.cs:24:1187:24:1195 | ... > ... | +| UseUseExplosion.cs:24:1187:24:1190 | access to property Prop | UseUseExplosion.cs:24:1204:24:1207 | access to property Prop | +| UseUseExplosion.cs:24:1187:24:1190 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1187:24:1190 | this access | UseUseExplosion.cs:24:1204:24:1207 | this access | +| UseUseExplosion.cs:24:1187:24:1190 | this access | UseUseExplosion.cs:24:2158:24:2163 | this access | +| UseUseExplosion.cs:24:1204:24:1207 | [post] this access | UseUseExplosion.cs:24:1221:24:1224 | this access | +| UseUseExplosion.cs:24:1204:24:1207 | [post] this access | UseUseExplosion.cs:24:2143:24:2148 | this access | +| UseUseExplosion.cs:24:1204:24:1207 | access to property Prop | UseUseExplosion.cs:24:1204:24:1212 | ... > ... | +| UseUseExplosion.cs:24:1204:24:1207 | access to property Prop | UseUseExplosion.cs:24:1221:24:1224 | access to property Prop | +| UseUseExplosion.cs:24:1204:24:1207 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1204:24:1207 | this access | UseUseExplosion.cs:24:1221:24:1224 | this access | +| UseUseExplosion.cs:24:1204:24:1207 | this access | UseUseExplosion.cs:24:2143:24:2148 | this access | +| UseUseExplosion.cs:24:1221:24:1224 | [post] this access | UseUseExplosion.cs:24:1238:24:1241 | this access | +| UseUseExplosion.cs:24:1221:24:1224 | [post] this access | UseUseExplosion.cs:24:2128:24:2133 | this access | +| UseUseExplosion.cs:24:1221:24:1224 | access to property Prop | UseUseExplosion.cs:24:1221:24:1229 | ... > ... | +| UseUseExplosion.cs:24:1221:24:1224 | access to property Prop | UseUseExplosion.cs:24:1238:24:1241 | access to property Prop | +| UseUseExplosion.cs:24:1221:24:1224 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1221:24:1224 | this access | UseUseExplosion.cs:24:1238:24:1241 | this access | +| UseUseExplosion.cs:24:1221:24:1224 | this access | UseUseExplosion.cs:24:2128:24:2133 | this access | +| UseUseExplosion.cs:24:1238:24:1241 | [post] this access | UseUseExplosion.cs:24:1255:24:1258 | this access | +| UseUseExplosion.cs:24:1238:24:1241 | [post] this access | UseUseExplosion.cs:24:2113:24:2118 | this access | +| UseUseExplosion.cs:24:1238:24:1241 | access to property Prop | UseUseExplosion.cs:24:1238:24:1246 | ... > ... | +| UseUseExplosion.cs:24:1238:24:1241 | access to property Prop | UseUseExplosion.cs:24:1255:24:1258 | access to property Prop | +| UseUseExplosion.cs:24:1238:24:1241 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1238:24:1241 | this access | UseUseExplosion.cs:24:1255:24:1258 | this access | +| UseUseExplosion.cs:24:1238:24:1241 | this access | UseUseExplosion.cs:24:2113:24:2118 | this access | +| UseUseExplosion.cs:24:1255:24:1258 | [post] this access | UseUseExplosion.cs:24:1272:24:1275 | this access | +| UseUseExplosion.cs:24:1255:24:1258 | [post] this access | UseUseExplosion.cs:24:2098:24:2103 | this access | +| UseUseExplosion.cs:24:1255:24:1258 | access to property Prop | UseUseExplosion.cs:24:1255:24:1263 | ... > ... | +| UseUseExplosion.cs:24:1255:24:1258 | access to property Prop | UseUseExplosion.cs:24:1272:24:1275 | access to property Prop | +| UseUseExplosion.cs:24:1255:24:1258 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1255:24:1258 | this access | UseUseExplosion.cs:24:1272:24:1275 | this access | +| UseUseExplosion.cs:24:1255:24:1258 | this access | UseUseExplosion.cs:24:2098:24:2103 | this access | +| UseUseExplosion.cs:24:1272:24:1275 | [post] this access | UseUseExplosion.cs:24:1289:24:1292 | this access | +| UseUseExplosion.cs:24:1272:24:1275 | [post] this access | UseUseExplosion.cs:24:2083:24:2088 | this access | +| UseUseExplosion.cs:24:1272:24:1275 | access to property Prop | UseUseExplosion.cs:24:1272:24:1280 | ... > ... | +| UseUseExplosion.cs:24:1272:24:1275 | access to property Prop | UseUseExplosion.cs:24:1289:24:1292 | access to property Prop | +| UseUseExplosion.cs:24:1272:24:1275 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1272:24:1275 | this access | UseUseExplosion.cs:24:1289:24:1292 | this access | +| UseUseExplosion.cs:24:1272:24:1275 | this access | UseUseExplosion.cs:24:2083:24:2088 | this access | +| UseUseExplosion.cs:24:1289:24:1292 | [post] this access | UseUseExplosion.cs:24:1306:24:1309 | this access | +| UseUseExplosion.cs:24:1289:24:1292 | [post] this access | UseUseExplosion.cs:24:2068:24:2073 | this access | +| UseUseExplosion.cs:24:1289:24:1292 | access to property Prop | UseUseExplosion.cs:24:1289:24:1297 | ... > ... | +| UseUseExplosion.cs:24:1289:24:1292 | access to property Prop | UseUseExplosion.cs:24:1306:24:1309 | access to property Prop | +| UseUseExplosion.cs:24:1289:24:1292 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1289:24:1292 | this access | UseUseExplosion.cs:24:1306:24:1309 | this access | +| UseUseExplosion.cs:24:1289:24:1292 | this access | UseUseExplosion.cs:24:2068:24:2073 | this access | +| UseUseExplosion.cs:24:1306:24:1309 | [post] this access | UseUseExplosion.cs:24:1323:24:1326 | this access | +| UseUseExplosion.cs:24:1306:24:1309 | [post] this access | UseUseExplosion.cs:24:2053:24:2058 | this access | +| UseUseExplosion.cs:24:1306:24:1309 | access to property Prop | UseUseExplosion.cs:24:1306:24:1314 | ... > ... | +| UseUseExplosion.cs:24:1306:24:1309 | access to property Prop | UseUseExplosion.cs:24:1323:24:1326 | access to property Prop | +| UseUseExplosion.cs:24:1306:24:1309 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1306:24:1309 | this access | UseUseExplosion.cs:24:1323:24:1326 | this access | +| UseUseExplosion.cs:24:1306:24:1309 | this access | UseUseExplosion.cs:24:2053:24:2058 | this access | +| UseUseExplosion.cs:24:1323:24:1326 | [post] this access | UseUseExplosion.cs:24:1340:24:1343 | this access | +| UseUseExplosion.cs:24:1323:24:1326 | [post] this access | UseUseExplosion.cs:24:2038:24:2043 | this access | +| UseUseExplosion.cs:24:1323:24:1326 | access to property Prop | UseUseExplosion.cs:24:1323:24:1331 | ... > ... | +| UseUseExplosion.cs:24:1323:24:1326 | access to property Prop | UseUseExplosion.cs:24:1340:24:1343 | access to property Prop | +| UseUseExplosion.cs:24:1323:24:1326 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1323:24:1326 | this access | UseUseExplosion.cs:24:1340:24:1343 | this access | +| UseUseExplosion.cs:24:1323:24:1326 | this access | UseUseExplosion.cs:24:2038:24:2043 | this access | +| UseUseExplosion.cs:24:1340:24:1343 | [post] this access | UseUseExplosion.cs:24:1357:24:1360 | this access | +| UseUseExplosion.cs:24:1340:24:1343 | [post] this access | UseUseExplosion.cs:24:2023:24:2028 | this access | +| UseUseExplosion.cs:24:1340:24:1343 | access to property Prop | UseUseExplosion.cs:24:1340:24:1348 | ... > ... | +| UseUseExplosion.cs:24:1340:24:1343 | access to property Prop | UseUseExplosion.cs:24:1357:24:1360 | access to property Prop | +| UseUseExplosion.cs:24:1340:24:1343 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1340:24:1343 | this access | UseUseExplosion.cs:24:1357:24:1360 | this access | +| UseUseExplosion.cs:24:1340:24:1343 | this access | UseUseExplosion.cs:24:2023:24:2028 | this access | +| UseUseExplosion.cs:24:1357:24:1360 | [post] this access | UseUseExplosion.cs:24:1374:24:1377 | this access | +| UseUseExplosion.cs:24:1357:24:1360 | [post] this access | UseUseExplosion.cs:24:2008:24:2013 | this access | +| UseUseExplosion.cs:24:1357:24:1360 | access to property Prop | UseUseExplosion.cs:24:1357:24:1365 | ... > ... | +| UseUseExplosion.cs:24:1357:24:1360 | access to property Prop | UseUseExplosion.cs:24:1374:24:1377 | access to property Prop | +| UseUseExplosion.cs:24:1357:24:1360 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1357:24:1360 | this access | UseUseExplosion.cs:24:1374:24:1377 | this access | +| UseUseExplosion.cs:24:1357:24:1360 | this access | UseUseExplosion.cs:24:2008:24:2013 | this access | +| UseUseExplosion.cs:24:1374:24:1377 | [post] this access | UseUseExplosion.cs:24:1391:24:1394 | this access | +| UseUseExplosion.cs:24:1374:24:1377 | [post] this access | UseUseExplosion.cs:24:1993:24:1998 | this access | +| UseUseExplosion.cs:24:1374:24:1377 | access to property Prop | UseUseExplosion.cs:24:1374:24:1382 | ... > ... | +| UseUseExplosion.cs:24:1374:24:1377 | access to property Prop | UseUseExplosion.cs:24:1391:24:1394 | access to property Prop | +| UseUseExplosion.cs:24:1374:24:1377 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1374:24:1377 | this access | UseUseExplosion.cs:24:1391:24:1394 | this access | +| UseUseExplosion.cs:24:1374:24:1377 | this access | UseUseExplosion.cs:24:1993:24:1998 | this access | +| UseUseExplosion.cs:24:1391:24:1394 | [post] this access | UseUseExplosion.cs:24:1408:24:1411 | this access | +| UseUseExplosion.cs:24:1391:24:1394 | [post] this access | UseUseExplosion.cs:24:1978:24:1983 | this access | +| UseUseExplosion.cs:24:1391:24:1394 | access to property Prop | UseUseExplosion.cs:24:1391:24:1399 | ... > ... | +| UseUseExplosion.cs:24:1391:24:1394 | access to property Prop | UseUseExplosion.cs:24:1408:24:1411 | access to property Prop | +| UseUseExplosion.cs:24:1391:24:1394 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1391:24:1394 | this access | UseUseExplosion.cs:24:1408:24:1411 | this access | +| UseUseExplosion.cs:24:1391:24:1394 | this access | UseUseExplosion.cs:24:1978:24:1983 | this access | +| UseUseExplosion.cs:24:1408:24:1411 | [post] this access | UseUseExplosion.cs:24:1425:24:1428 | this access | +| UseUseExplosion.cs:24:1408:24:1411 | [post] this access | UseUseExplosion.cs:24:1963:24:1968 | this access | +| UseUseExplosion.cs:24:1408:24:1411 | access to property Prop | UseUseExplosion.cs:24:1408:24:1416 | ... > ... | +| UseUseExplosion.cs:24:1408:24:1411 | access to property Prop | UseUseExplosion.cs:24:1425:24:1428 | access to property Prop | +| UseUseExplosion.cs:24:1408:24:1411 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1408:24:1411 | this access | UseUseExplosion.cs:24:1425:24:1428 | this access | +| UseUseExplosion.cs:24:1408:24:1411 | this access | UseUseExplosion.cs:24:1963:24:1968 | this access | +| UseUseExplosion.cs:24:1425:24:1428 | [post] this access | UseUseExplosion.cs:24:1442:24:1445 | this access | +| UseUseExplosion.cs:24:1425:24:1428 | [post] this access | UseUseExplosion.cs:24:1948:24:1953 | this access | +| UseUseExplosion.cs:24:1425:24:1428 | access to property Prop | UseUseExplosion.cs:24:1425:24:1433 | ... > ... | +| UseUseExplosion.cs:24:1425:24:1428 | access to property Prop | UseUseExplosion.cs:24:1442:24:1445 | access to property Prop | +| UseUseExplosion.cs:24:1425:24:1428 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1425:24:1428 | this access | UseUseExplosion.cs:24:1442:24:1445 | this access | +| UseUseExplosion.cs:24:1425:24:1428 | this access | UseUseExplosion.cs:24:1948:24:1953 | this access | +| UseUseExplosion.cs:24:1442:24:1445 | [post] this access | UseUseExplosion.cs:24:1459:24:1462 | this access | +| UseUseExplosion.cs:24:1442:24:1445 | [post] this access | UseUseExplosion.cs:24:1933:24:1938 | this access | +| UseUseExplosion.cs:24:1442:24:1445 | access to property Prop | UseUseExplosion.cs:24:1442:24:1450 | ... > ... | +| UseUseExplosion.cs:24:1442:24:1445 | access to property Prop | UseUseExplosion.cs:24:1459:24:1462 | access to property Prop | +| UseUseExplosion.cs:24:1442:24:1445 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1442:24:1445 | this access | UseUseExplosion.cs:24:1459:24:1462 | this access | +| UseUseExplosion.cs:24:1442:24:1445 | this access | UseUseExplosion.cs:24:1933:24:1938 | this access | +| UseUseExplosion.cs:24:1459:24:1462 | [post] this access | UseUseExplosion.cs:24:1476:24:1479 | this access | +| UseUseExplosion.cs:24:1459:24:1462 | [post] this access | UseUseExplosion.cs:24:1918:24:1923 | this access | +| UseUseExplosion.cs:24:1459:24:1462 | access to property Prop | UseUseExplosion.cs:24:1459:24:1467 | ... > ... | +| UseUseExplosion.cs:24:1459:24:1462 | access to property Prop | UseUseExplosion.cs:24:1476:24:1479 | access to property Prop | +| UseUseExplosion.cs:24:1459:24:1462 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1459:24:1462 | this access | UseUseExplosion.cs:24:1476:24:1479 | this access | +| UseUseExplosion.cs:24:1459:24:1462 | this access | UseUseExplosion.cs:24:1918:24:1923 | this access | +| UseUseExplosion.cs:24:1476:24:1479 | [post] this access | UseUseExplosion.cs:24:1493:24:1496 | this access | +| UseUseExplosion.cs:24:1476:24:1479 | [post] this access | UseUseExplosion.cs:24:1903:24:1908 | this access | +| UseUseExplosion.cs:24:1476:24:1479 | access to property Prop | UseUseExplosion.cs:24:1476:24:1484 | ... > ... | +| UseUseExplosion.cs:24:1476:24:1479 | access to property Prop | UseUseExplosion.cs:24:1493:24:1496 | access to property Prop | +| UseUseExplosion.cs:24:1476:24:1479 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1476:24:1479 | this access | UseUseExplosion.cs:24:1493:24:1496 | this access | +| UseUseExplosion.cs:24:1476:24:1479 | this access | UseUseExplosion.cs:24:1903:24:1908 | this access | +| UseUseExplosion.cs:24:1493:24:1496 | [post] this access | UseUseExplosion.cs:24:1510:24:1513 | this access | +| UseUseExplosion.cs:24:1493:24:1496 | [post] this access | UseUseExplosion.cs:24:1888:24:1893 | this access | +| UseUseExplosion.cs:24:1493:24:1496 | access to property Prop | UseUseExplosion.cs:24:1493:24:1501 | ... > ... | +| UseUseExplosion.cs:24:1493:24:1496 | access to property Prop | UseUseExplosion.cs:24:1510:24:1513 | access to property Prop | +| UseUseExplosion.cs:24:1493:24:1496 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1493:24:1496 | this access | UseUseExplosion.cs:24:1510:24:1513 | this access | +| UseUseExplosion.cs:24:1493:24:1496 | this access | UseUseExplosion.cs:24:1888:24:1893 | this access | +| UseUseExplosion.cs:24:1510:24:1513 | [post] this access | UseUseExplosion.cs:24:1527:24:1530 | this access | +| UseUseExplosion.cs:24:1510:24:1513 | [post] this access | UseUseExplosion.cs:24:1873:24:1878 | this access | +| UseUseExplosion.cs:24:1510:24:1513 | access to property Prop | UseUseExplosion.cs:24:1510:24:1518 | ... > ... | +| UseUseExplosion.cs:24:1510:24:1513 | access to property Prop | UseUseExplosion.cs:24:1527:24:1530 | access to property Prop | +| UseUseExplosion.cs:24:1510:24:1513 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1510:24:1513 | this access | UseUseExplosion.cs:24:1527:24:1530 | this access | +| UseUseExplosion.cs:24:1510:24:1513 | this access | UseUseExplosion.cs:24:1873:24:1878 | this access | +| UseUseExplosion.cs:24:1527:24:1530 | [post] this access | UseUseExplosion.cs:24:1544:24:1547 | this access | +| UseUseExplosion.cs:24:1527:24:1530 | [post] this access | UseUseExplosion.cs:24:1858:24:1863 | this access | +| UseUseExplosion.cs:24:1527:24:1530 | access to property Prop | UseUseExplosion.cs:24:1527:24:1535 | ... > ... | +| UseUseExplosion.cs:24:1527:24:1530 | access to property Prop | UseUseExplosion.cs:24:1544:24:1547 | access to property Prop | +| UseUseExplosion.cs:24:1527:24:1530 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1527:24:1530 | this access | UseUseExplosion.cs:24:1544:24:1547 | this access | +| UseUseExplosion.cs:24:1527:24:1530 | this access | UseUseExplosion.cs:24:1858:24:1863 | this access | +| UseUseExplosion.cs:24:1544:24:1547 | [post] this access | UseUseExplosion.cs:24:1561:24:1564 | this access | +| UseUseExplosion.cs:24:1544:24:1547 | [post] this access | UseUseExplosion.cs:24:1843:24:1848 | this access | +| UseUseExplosion.cs:24:1544:24:1547 | access to property Prop | UseUseExplosion.cs:24:1544:24:1552 | ... > ... | +| UseUseExplosion.cs:24:1544:24:1547 | access to property Prop | UseUseExplosion.cs:24:1561:24:1564 | access to property Prop | +| UseUseExplosion.cs:24:1544:24:1547 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1544:24:1547 | this access | UseUseExplosion.cs:24:1561:24:1564 | this access | +| UseUseExplosion.cs:24:1544:24:1547 | this access | UseUseExplosion.cs:24:1843:24:1848 | this access | +| UseUseExplosion.cs:24:1561:24:1564 | [post] this access | UseUseExplosion.cs:24:1577:24:1580 | this access | +| UseUseExplosion.cs:24:1561:24:1564 | [post] this access | UseUseExplosion.cs:24:1828:24:1833 | this access | +| UseUseExplosion.cs:24:1561:24:1564 | access to property Prop | UseUseExplosion.cs:24:1561:24:1568 | ... > ... | +| UseUseExplosion.cs:24:1561:24:1564 | access to property Prop | UseUseExplosion.cs:24:1577:24:1580 | access to property Prop | +| UseUseExplosion.cs:24:1561:24:1564 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1561:24:1564 | this access | UseUseExplosion.cs:24:1577:24:1580 | this access | +| UseUseExplosion.cs:24:1561:24:1564 | this access | UseUseExplosion.cs:24:1828:24:1833 | this access | +| UseUseExplosion.cs:24:1577:24:1580 | [post] this access | UseUseExplosion.cs:24:1593:24:1596 | this access | +| UseUseExplosion.cs:24:1577:24:1580 | [post] this access | UseUseExplosion.cs:24:1813:24:1818 | this access | +| UseUseExplosion.cs:24:1577:24:1580 | access to property Prop | UseUseExplosion.cs:24:1577:24:1584 | ... > ... | +| UseUseExplosion.cs:24:1577:24:1580 | access to property Prop | UseUseExplosion.cs:24:1593:24:1596 | access to property Prop | +| UseUseExplosion.cs:24:1577:24:1580 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1577:24:1580 | this access | UseUseExplosion.cs:24:1593:24:1596 | this access | +| UseUseExplosion.cs:24:1577:24:1580 | this access | UseUseExplosion.cs:24:1813:24:1818 | this access | +| UseUseExplosion.cs:24:1593:24:1596 | [post] this access | UseUseExplosion.cs:24:1609:24:1612 | this access | +| UseUseExplosion.cs:24:1593:24:1596 | [post] this access | UseUseExplosion.cs:24:1798:24:1803 | this access | +| UseUseExplosion.cs:24:1593:24:1596 | access to property Prop | UseUseExplosion.cs:24:1593:24:1600 | ... > ... | +| UseUseExplosion.cs:24:1593:24:1596 | access to property Prop | UseUseExplosion.cs:24:1609:24:1612 | access to property Prop | +| UseUseExplosion.cs:24:1593:24:1596 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1593:24:1596 | this access | UseUseExplosion.cs:24:1609:24:1612 | this access | +| UseUseExplosion.cs:24:1593:24:1596 | this access | UseUseExplosion.cs:24:1798:24:1803 | this access | +| UseUseExplosion.cs:24:1609:24:1612 | [post] this access | UseUseExplosion.cs:24:1625:24:1628 | this access | +| UseUseExplosion.cs:24:1609:24:1612 | [post] this access | UseUseExplosion.cs:24:1783:24:1788 | this access | +| UseUseExplosion.cs:24:1609:24:1612 | access to property Prop | UseUseExplosion.cs:24:1609:24:1616 | ... > ... | +| UseUseExplosion.cs:24:1609:24:1612 | access to property Prop | UseUseExplosion.cs:24:1625:24:1628 | access to property Prop | +| UseUseExplosion.cs:24:1609:24:1612 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1609:24:1612 | this access | UseUseExplosion.cs:24:1625:24:1628 | this access | +| UseUseExplosion.cs:24:1609:24:1612 | this access | UseUseExplosion.cs:24:1783:24:1788 | this access | +| UseUseExplosion.cs:24:1625:24:1628 | [post] this access | UseUseExplosion.cs:24:1641:24:1644 | this access | +| UseUseExplosion.cs:24:1625:24:1628 | [post] this access | UseUseExplosion.cs:24:1768:24:1773 | this access | +| UseUseExplosion.cs:24:1625:24:1628 | access to property Prop | UseUseExplosion.cs:24:1625:24:1632 | ... > ... | +| UseUseExplosion.cs:24:1625:24:1628 | access to property Prop | UseUseExplosion.cs:24:1641:24:1644 | access to property Prop | +| UseUseExplosion.cs:24:1625:24:1628 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1625:24:1628 | this access | UseUseExplosion.cs:24:1641:24:1644 | this access | +| UseUseExplosion.cs:24:1625:24:1628 | this access | UseUseExplosion.cs:24:1768:24:1773 | this access | +| UseUseExplosion.cs:24:1641:24:1644 | [post] this access | UseUseExplosion.cs:24:1657:24:1660 | this access | +| UseUseExplosion.cs:24:1641:24:1644 | [post] this access | UseUseExplosion.cs:24:1753:24:1758 | this access | +| UseUseExplosion.cs:24:1641:24:1644 | access to property Prop | UseUseExplosion.cs:24:1641:24:1648 | ... > ... | +| UseUseExplosion.cs:24:1641:24:1644 | access to property Prop | UseUseExplosion.cs:24:1657:24:1660 | access to property Prop | +| UseUseExplosion.cs:24:1641:24:1644 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1641:24:1644 | this access | UseUseExplosion.cs:24:1657:24:1660 | this access | +| UseUseExplosion.cs:24:1641:24:1644 | this access | UseUseExplosion.cs:24:1753:24:1758 | this access | +| UseUseExplosion.cs:24:1657:24:1660 | [post] this access | UseUseExplosion.cs:24:1673:24:1676 | this access | +| UseUseExplosion.cs:24:1657:24:1660 | [post] this access | UseUseExplosion.cs:24:1738:24:1743 | this access | +| UseUseExplosion.cs:24:1657:24:1660 | access to property Prop | UseUseExplosion.cs:24:1657:24:1664 | ... > ... | +| UseUseExplosion.cs:24:1657:24:1660 | access to property Prop | UseUseExplosion.cs:24:1673:24:1676 | access to property Prop | +| UseUseExplosion.cs:24:1657:24:1660 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1657:24:1660 | this access | UseUseExplosion.cs:24:1673:24:1676 | this access | +| UseUseExplosion.cs:24:1657:24:1660 | this access | UseUseExplosion.cs:24:1738:24:1743 | this access | +| UseUseExplosion.cs:24:1673:24:1676 | [post] this access | UseUseExplosion.cs:24:1689:24:1692 | this access | +| UseUseExplosion.cs:24:1673:24:1676 | [post] this access | UseUseExplosion.cs:24:1723:24:1728 | this access | +| UseUseExplosion.cs:24:1673:24:1676 | access to property Prop | UseUseExplosion.cs:24:1673:24:1680 | ... > ... | +| UseUseExplosion.cs:24:1673:24:1676 | access to property Prop | UseUseExplosion.cs:24:1689:24:1692 | access to property Prop | +| UseUseExplosion.cs:24:1673:24:1676 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1673:24:1676 | this access | UseUseExplosion.cs:24:1689:24:1692 | this access | +| UseUseExplosion.cs:24:1673:24:1676 | this access | UseUseExplosion.cs:24:1723:24:1728 | this access | +| UseUseExplosion.cs:24:1689:24:1692 | [post] this access | UseUseExplosion.cs:24:1708:24:1713 | this access | +| UseUseExplosion.cs:24:1689:24:1692 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1689:24:1692 | access to property Prop | UseUseExplosion.cs:24:1689:24:1696 | ... > ... | +| UseUseExplosion.cs:24:1689:24:1692 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1689:24:1692 | this access | UseUseExplosion.cs:24:1708:24:1713 | this access | +| UseUseExplosion.cs:24:1689:24:1692 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1708:24:1713 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1708:24:1713 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1712:24:1712 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1723:24:1728 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1723:24:1728 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1727:24:1727 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1738:24:1743 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1738:24:1743 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1742:24:1742 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1753:24:1758 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1753:24:1758 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1757:24:1757 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1768:24:1773 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1768:24:1773 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1772:24:1772 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1783:24:1788 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1783:24:1788 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1787:24:1787 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1798:24:1803 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1798:24:1803 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1802:24:1802 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1813:24:1818 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1813:24:1818 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1817:24:1817 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1828:24:1833 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1828:24:1833 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1832:24:1832 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1843:24:1848 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1843:24:1848 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1847:24:1847 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1858:24:1863 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1858:24:1863 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1862:24:1862 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1873:24:1878 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1873:24:1878 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1877:24:1877 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1888:24:1893 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1888:24:1893 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1892:24:1892 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1903:24:1908 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1903:24:1908 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1907:24:1907 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1918:24:1923 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1918:24:1923 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1922:24:1922 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1933:24:1938 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1933:24:1938 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1937:24:1937 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1948:24:1953 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1948:24:1953 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1952:24:1952 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1963:24:1968 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1963:24:1968 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1967:24:1967 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1978:24:1983 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1978:24:1983 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1982:24:1982 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1993:24:1998 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1993:24:1998 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1997:24:1997 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2008:24:2013 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2008:24:2013 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2012:24:2012 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2023:24:2028 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2023:24:2028 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2027:24:2027 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2038:24:2043 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2038:24:2043 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2042:24:2042 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2053:24:2058 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2053:24:2058 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2057:24:2057 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2068:24:2073 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2068:24:2073 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2072:24:2072 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2083:24:2088 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2083:24:2088 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2087:24:2087 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2098:24:2103 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2098:24:2103 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2102:24:2102 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2113:24:2118 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2113:24:2118 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2117:24:2117 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2128:24:2133 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2128:24:2133 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2132:24:2132 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2143:24:2148 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2143:24:2148 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2147:24:2147 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2158:24:2163 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2158:24:2163 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2162:24:2162 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2173:24:2178 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2173:24:2178 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2177:24:2177 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2188:24:2193 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2188:24:2193 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2192:24:2192 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2203:24:2208 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2203:24:2208 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2207:24:2207 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2218:24:2223 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2218:24:2223 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2222:24:2222 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2233:24:2238 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2233:24:2238 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2237:24:2237 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2248:24:2253 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2248:24:2253 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2252:24:2252 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2263:24:2268 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2263:24:2268 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2267:24:2267 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2278:24:2283 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2278:24:2283 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2282:24:2282 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2293:24:2298 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2293:24:2298 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2297:24:2297 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2308:24:2313 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2308:24:2313 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2312:24:2312 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2323:24:2328 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2323:24:2328 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2327:24:2327 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2338:24:2343 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2338:24:2343 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2342:24:2342 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2353:24:2358 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2353:24:2358 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2357:24:2357 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2368:24:2373 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2368:24:2373 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2372:24:2372 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2383:24:2388 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2383:24:2388 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2387:24:2387 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2398:24:2403 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2398:24:2403 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2402:24:2402 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2413:24:2418 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2413:24:2418 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2417:24:2417 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2428:24:2433 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2428:24:2433 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2432:24:2432 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2443:24:2448 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2443:24:2448 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2447:24:2447 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2458:24:2463 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2458:24:2463 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2462:24:2462 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2473:24:2478 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2473:24:2478 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2477:24:2477 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2488:24:2493 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2488:24:2493 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2492:24:2492 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2503:24:2508 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2503:24:2508 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2507:24:2507 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2518:24:2523 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2518:24:2523 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2522:24:2522 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2533:24:2538 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2533:24:2538 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2537:24:2537 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2548:24:2553 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2548:24:2553 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2552:24:2552 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2563:24:2568 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2563:24:2568 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2567:24:2567 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2578:24:2583 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2578:24:2583 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2582:24:2582 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2593:24:2598 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2593:24:2598 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2597:24:2597 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2608:24:2613 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2608:24:2613 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2612:24:2612 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2623:24:2628 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2623:24:2628 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2627:24:2627 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2638:24:2643 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2638:24:2643 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2642:24:2642 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2653:24:2658 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2653:24:2658 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2657:24:2657 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2668:24:2673 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2668:24:2673 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2672:24:2672 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2683:24:2688 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2683:24:2688 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2687:24:2687 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2698:24:2703 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2698:24:2703 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2702:24:2702 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2713:24:2718 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2713:24:2718 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2717:24:2717 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2728:24:2733 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2728:24:2733 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2732:24:2732 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2743:24:2748 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2743:24:2748 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2747:24:2747 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2758:24:2763 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2758:24:2763 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2762:24:2762 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2773:24:2778 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2773:24:2778 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2777:24:2777 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2788:24:2793 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2788:24:2793 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2792:24:2792 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2803:24:2808 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2803:24:2808 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2807:24:2807 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2818:24:2823 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2818:24:2823 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2822:24:2822 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2833:24:2838 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2833:24:2838 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2837:24:2837 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2848:24:2853 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2848:24:2853 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2852:24:2852 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2863:24:2868 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2863:24:2868 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2867:24:2867 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2878:24:2883 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2878:24:2883 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2882:24:2882 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2893:24:2898 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2893:24:2898 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2897:24:2897 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2908:24:2913 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2908:24:2913 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2912:24:2912 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2923:24:2928 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2923:24:2928 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2927:24:2927 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2938:24:2943 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2938:24:2943 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2942:24:2942 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2953:24:2958 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2953:24:2958 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2957:24:2957 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2968:24:2973 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2968:24:2973 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2972:24:2972 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2983:24:2988 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2983:24:2988 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2987:24:2987 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2998:24:3003 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2998:24:3003 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3002:24:3002 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3013:24:3018 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3013:24:3018 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3017:24:3017 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3028:24:3033 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3028:24:3033 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3032:24:3032 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3043:24:3048 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3043:24:3048 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3047:24:3047 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3058:24:3063 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3058:24:3063 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3062:24:3062 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3073:24:3078 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3073:24:3078 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3077:24:3077 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3088:24:3093 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3088:24:3093 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3092:24:3092 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3103:24:3108 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3103:24:3108 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3107:24:3107 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3118:24:3123 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3118:24:3123 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3122:24:3122 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3133:24:3138 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3133:24:3138 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3137:24:3137 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3148:24:3153 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3148:24:3153 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3152:24:3152 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3163:24:3168 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3163:24:3168 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3167:24:3167 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3178:24:3183 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3178:24:3183 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3182:24:3182 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3193:24:3198 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3193:24:3198 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3197:24:3197 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | UseUseExplosion.cs:25:13:25:16 | access to property Prop | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1712:25:1712 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1727:25:1727 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1742:25:1742 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1757:25:1757 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1772:25:1772 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1787:25:1787 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1802:25:1802 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1817:25:1817 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1832:25:1832 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1847:25:1847 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1862:25:1862 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1877:25:1877 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1892:25:1892 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1907:25:1907 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1922:25:1922 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1937:25:1937 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1952:25:1952 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1967:25:1967 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1982:25:1982 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1997:25:1997 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2012:25:2012 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2027:25:2027 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2042:25:2042 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2057:25:2057 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2072:25:2072 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2087:25:2087 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2102:25:2102 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2117:25:2117 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2132:25:2132 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2147:25:2147 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2162:25:2162 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2177:25:2177 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2192:25:2192 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2207:25:2207 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2222:25:2222 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2237:25:2237 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2252:25:2252 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2267:25:2267 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2282:25:2282 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2297:25:2297 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2312:25:2312 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2327:25:2327 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2342:25:2342 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2357:25:2357 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2372:25:2372 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2387:25:2387 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2402:25:2402 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2417:25:2417 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2432:25:2432 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2447:25:2447 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2462:25:2462 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2477:25:2477 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2492:25:2492 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2507:25:2507 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2522:25:2522 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2537:25:2537 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2552:25:2552 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2567:25:2567 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2582:25:2582 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2597:25:2597 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2612:25:2612 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2627:25:2627 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2642:25:2642 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2657:25:2657 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2672:25:2672 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2687:25:2687 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2702:25:2702 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2717:25:2717 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2732:25:2732 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2747:25:2747 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2762:25:2762 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2777:25:2777 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2792:25:2792 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2807:25:2807 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2822:25:2822 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2837:25:2837 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2852:25:2852 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2867:25:2867 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2882:25:2882 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2897:25:2897 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2912:25:2912 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2927:25:2927 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2942:25:2942 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2957:25:2957 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2972:25:2972 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2987:25:2987 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3002:25:3002 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3017:25:3017 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3032:25:3032 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3047:25:3047 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3062:25:3062 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3077:25:3077 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3092:25:3092 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3107:25:3107 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3122:25:3122 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3137:25:3137 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3152:25:3152 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3167:25:3167 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3182:25:3182 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3197:25:3197 | access to local variable x | +| UseUseExplosion.cs:25:13:25:16 | [post] this access | UseUseExplosion.cs:25:31:25:34 | this access | +| UseUseExplosion.cs:25:13:25:16 | [post] this access | UseUseExplosion.cs:25:3193:25:3198 | this access | +| UseUseExplosion.cs:25:13:25:16 | access to property Prop | UseUseExplosion.cs:25:13:25:22 | ... > ... | +| UseUseExplosion.cs:25:13:25:16 | access to property Prop | UseUseExplosion.cs:25:31:25:34 | access to property Prop | +| UseUseExplosion.cs:25:13:25:16 | this access | UseUseExplosion.cs:25:31:25:34 | this access | +| UseUseExplosion.cs:25:13:25:16 | this access | UseUseExplosion.cs:25:3193:25:3198 | this access | +| UseUseExplosion.cs:25:31:25:34 | [post] this access | UseUseExplosion.cs:25:48:25:51 | this access | +| UseUseExplosion.cs:25:31:25:34 | [post] this access | UseUseExplosion.cs:25:3178:25:3183 | this access | +| UseUseExplosion.cs:25:31:25:34 | access to property Prop | UseUseExplosion.cs:25:31:25:39 | ... > ... | +| UseUseExplosion.cs:25:31:25:34 | access to property Prop | UseUseExplosion.cs:25:48:25:51 | access to property Prop | +| UseUseExplosion.cs:25:31:25:34 | this access | UseUseExplosion.cs:25:48:25:51 | this access | +| UseUseExplosion.cs:25:31:25:34 | this access | UseUseExplosion.cs:25:3178:25:3183 | this access | +| UseUseExplosion.cs:25:48:25:51 | [post] this access | UseUseExplosion.cs:25:65:25:68 | this access | +| UseUseExplosion.cs:25:48:25:51 | [post] this access | UseUseExplosion.cs:25:3163:25:3168 | this access | +| UseUseExplosion.cs:25:48:25:51 | access to property Prop | UseUseExplosion.cs:25:48:25:56 | ... > ... | +| UseUseExplosion.cs:25:48:25:51 | access to property Prop | UseUseExplosion.cs:25:65:25:68 | access to property Prop | +| UseUseExplosion.cs:25:48:25:51 | this access | UseUseExplosion.cs:25:65:25:68 | this access | +| UseUseExplosion.cs:25:48:25:51 | this access | UseUseExplosion.cs:25:3163:25:3168 | this access | +| UseUseExplosion.cs:25:65:25:68 | [post] this access | UseUseExplosion.cs:25:82:25:85 | this access | +| UseUseExplosion.cs:25:65:25:68 | [post] this access | UseUseExplosion.cs:25:3148:25:3153 | this access | +| UseUseExplosion.cs:25:65:25:68 | access to property Prop | UseUseExplosion.cs:25:65:25:73 | ... > ... | +| UseUseExplosion.cs:25:65:25:68 | access to property Prop | UseUseExplosion.cs:25:82:25:85 | access to property Prop | +| UseUseExplosion.cs:25:65:25:68 | this access | UseUseExplosion.cs:25:82:25:85 | this access | +| UseUseExplosion.cs:25:65:25:68 | this access | UseUseExplosion.cs:25:3148:25:3153 | this access | +| UseUseExplosion.cs:25:82:25:85 | [post] this access | UseUseExplosion.cs:25:99:25:102 | this access | +| UseUseExplosion.cs:25:82:25:85 | [post] this access | UseUseExplosion.cs:25:3133:25:3138 | this access | +| UseUseExplosion.cs:25:82:25:85 | access to property Prop | UseUseExplosion.cs:25:82:25:90 | ... > ... | +| UseUseExplosion.cs:25:82:25:85 | access to property Prop | UseUseExplosion.cs:25:99:25:102 | access to property Prop | +| UseUseExplosion.cs:25:82:25:85 | this access | UseUseExplosion.cs:25:99:25:102 | this access | +| UseUseExplosion.cs:25:82:25:85 | this access | UseUseExplosion.cs:25:3133:25:3138 | this access | +| UseUseExplosion.cs:25:99:25:102 | [post] this access | UseUseExplosion.cs:25:116:25:119 | this access | +| UseUseExplosion.cs:25:99:25:102 | [post] this access | UseUseExplosion.cs:25:3118:25:3123 | this access | +| UseUseExplosion.cs:25:99:25:102 | access to property Prop | UseUseExplosion.cs:25:99:25:107 | ... > ... | +| UseUseExplosion.cs:25:99:25:102 | access to property Prop | UseUseExplosion.cs:25:116:25:119 | access to property Prop | +| UseUseExplosion.cs:25:99:25:102 | this access | UseUseExplosion.cs:25:116:25:119 | this access | +| UseUseExplosion.cs:25:99:25:102 | this access | UseUseExplosion.cs:25:3118:25:3123 | this access | +| UseUseExplosion.cs:25:116:25:119 | [post] this access | UseUseExplosion.cs:25:133:25:136 | this access | +| UseUseExplosion.cs:25:116:25:119 | [post] this access | UseUseExplosion.cs:25:3103:25:3108 | this access | +| UseUseExplosion.cs:25:116:25:119 | access to property Prop | UseUseExplosion.cs:25:116:25:124 | ... > ... | +| UseUseExplosion.cs:25:116:25:119 | access to property Prop | UseUseExplosion.cs:25:133:25:136 | access to property Prop | +| UseUseExplosion.cs:25:116:25:119 | this access | UseUseExplosion.cs:25:133:25:136 | this access | +| UseUseExplosion.cs:25:116:25:119 | this access | UseUseExplosion.cs:25:3103:25:3108 | this access | +| UseUseExplosion.cs:25:133:25:136 | [post] this access | UseUseExplosion.cs:25:150:25:153 | this access | +| UseUseExplosion.cs:25:133:25:136 | [post] this access | UseUseExplosion.cs:25:3088:25:3093 | this access | +| UseUseExplosion.cs:25:133:25:136 | access to property Prop | UseUseExplosion.cs:25:133:25:141 | ... > ... | +| UseUseExplosion.cs:25:133:25:136 | access to property Prop | UseUseExplosion.cs:25:150:25:153 | access to property Prop | +| UseUseExplosion.cs:25:133:25:136 | this access | UseUseExplosion.cs:25:150:25:153 | this access | +| UseUseExplosion.cs:25:133:25:136 | this access | UseUseExplosion.cs:25:3088:25:3093 | this access | +| UseUseExplosion.cs:25:150:25:153 | [post] this access | UseUseExplosion.cs:25:167:25:170 | this access | +| UseUseExplosion.cs:25:150:25:153 | [post] this access | UseUseExplosion.cs:25:3073:25:3078 | this access | +| UseUseExplosion.cs:25:150:25:153 | access to property Prop | UseUseExplosion.cs:25:150:25:158 | ... > ... | +| UseUseExplosion.cs:25:150:25:153 | access to property Prop | UseUseExplosion.cs:25:167:25:170 | access to property Prop | +| UseUseExplosion.cs:25:150:25:153 | this access | UseUseExplosion.cs:25:167:25:170 | this access | +| UseUseExplosion.cs:25:150:25:153 | this access | UseUseExplosion.cs:25:3073:25:3078 | this access | +| UseUseExplosion.cs:25:167:25:170 | [post] this access | UseUseExplosion.cs:25:184:25:187 | this access | +| UseUseExplosion.cs:25:167:25:170 | [post] this access | UseUseExplosion.cs:25:3058:25:3063 | this access | +| UseUseExplosion.cs:25:167:25:170 | access to property Prop | UseUseExplosion.cs:25:167:25:175 | ... > ... | +| UseUseExplosion.cs:25:167:25:170 | access to property Prop | UseUseExplosion.cs:25:184:25:187 | access to property Prop | +| UseUseExplosion.cs:25:167:25:170 | this access | UseUseExplosion.cs:25:184:25:187 | this access | +| UseUseExplosion.cs:25:167:25:170 | this access | UseUseExplosion.cs:25:3058:25:3063 | this access | +| UseUseExplosion.cs:25:184:25:187 | [post] this access | UseUseExplosion.cs:25:201:25:204 | this access | +| UseUseExplosion.cs:25:184:25:187 | [post] this access | UseUseExplosion.cs:25:3043:25:3048 | this access | +| UseUseExplosion.cs:25:184:25:187 | access to property Prop | UseUseExplosion.cs:25:184:25:192 | ... > ... | +| UseUseExplosion.cs:25:184:25:187 | access to property Prop | UseUseExplosion.cs:25:201:25:204 | access to property Prop | +| UseUseExplosion.cs:25:184:25:187 | this access | UseUseExplosion.cs:25:201:25:204 | this access | +| UseUseExplosion.cs:25:184:25:187 | this access | UseUseExplosion.cs:25:3043:25:3048 | this access | +| UseUseExplosion.cs:25:201:25:204 | [post] this access | UseUseExplosion.cs:25:218:25:221 | this access | +| UseUseExplosion.cs:25:201:25:204 | [post] this access | UseUseExplosion.cs:25:3028:25:3033 | this access | +| UseUseExplosion.cs:25:201:25:204 | access to property Prop | UseUseExplosion.cs:25:201:25:209 | ... > ... | +| UseUseExplosion.cs:25:201:25:204 | access to property Prop | UseUseExplosion.cs:25:218:25:221 | access to property Prop | +| UseUseExplosion.cs:25:201:25:204 | this access | UseUseExplosion.cs:25:218:25:221 | this access | +| UseUseExplosion.cs:25:201:25:204 | this access | UseUseExplosion.cs:25:3028:25:3033 | this access | +| UseUseExplosion.cs:25:218:25:221 | [post] this access | UseUseExplosion.cs:25:235:25:238 | this access | +| UseUseExplosion.cs:25:218:25:221 | [post] this access | UseUseExplosion.cs:25:3013:25:3018 | this access | +| UseUseExplosion.cs:25:218:25:221 | access to property Prop | UseUseExplosion.cs:25:218:25:226 | ... > ... | +| UseUseExplosion.cs:25:218:25:221 | access to property Prop | UseUseExplosion.cs:25:235:25:238 | access to property Prop | +| UseUseExplosion.cs:25:218:25:221 | this access | UseUseExplosion.cs:25:235:25:238 | this access | +| UseUseExplosion.cs:25:218:25:221 | this access | UseUseExplosion.cs:25:3013:25:3018 | this access | +| UseUseExplosion.cs:25:235:25:238 | [post] this access | UseUseExplosion.cs:25:252:25:255 | this access | +| UseUseExplosion.cs:25:235:25:238 | [post] this access | UseUseExplosion.cs:25:2998:25:3003 | this access | +| UseUseExplosion.cs:25:235:25:238 | access to property Prop | UseUseExplosion.cs:25:235:25:243 | ... > ... | +| UseUseExplosion.cs:25:235:25:238 | access to property Prop | UseUseExplosion.cs:25:252:25:255 | access to property Prop | +| UseUseExplosion.cs:25:235:25:238 | this access | UseUseExplosion.cs:25:252:25:255 | this access | +| UseUseExplosion.cs:25:235:25:238 | this access | UseUseExplosion.cs:25:2998:25:3003 | this access | +| UseUseExplosion.cs:25:252:25:255 | [post] this access | UseUseExplosion.cs:25:269:25:272 | this access | +| UseUseExplosion.cs:25:252:25:255 | [post] this access | UseUseExplosion.cs:25:2983:25:2988 | this access | +| UseUseExplosion.cs:25:252:25:255 | access to property Prop | UseUseExplosion.cs:25:252:25:260 | ... > ... | +| UseUseExplosion.cs:25:252:25:255 | access to property Prop | UseUseExplosion.cs:25:269:25:272 | access to property Prop | +| UseUseExplosion.cs:25:252:25:255 | this access | UseUseExplosion.cs:25:269:25:272 | this access | +| UseUseExplosion.cs:25:252:25:255 | this access | UseUseExplosion.cs:25:2983:25:2988 | this access | +| UseUseExplosion.cs:25:269:25:272 | [post] this access | UseUseExplosion.cs:25:286:25:289 | this access | +| UseUseExplosion.cs:25:269:25:272 | [post] this access | UseUseExplosion.cs:25:2968:25:2973 | this access | +| UseUseExplosion.cs:25:269:25:272 | access to property Prop | UseUseExplosion.cs:25:269:25:277 | ... > ... | +| UseUseExplosion.cs:25:269:25:272 | access to property Prop | UseUseExplosion.cs:25:286:25:289 | access to property Prop | +| UseUseExplosion.cs:25:269:25:272 | this access | UseUseExplosion.cs:25:286:25:289 | this access | +| UseUseExplosion.cs:25:269:25:272 | this access | UseUseExplosion.cs:25:2968:25:2973 | this access | +| UseUseExplosion.cs:25:286:25:289 | [post] this access | UseUseExplosion.cs:25:303:25:306 | this access | +| UseUseExplosion.cs:25:286:25:289 | [post] this access | UseUseExplosion.cs:25:2953:25:2958 | this access | +| UseUseExplosion.cs:25:286:25:289 | access to property Prop | UseUseExplosion.cs:25:286:25:294 | ... > ... | +| UseUseExplosion.cs:25:286:25:289 | access to property Prop | UseUseExplosion.cs:25:303:25:306 | access to property Prop | +| UseUseExplosion.cs:25:286:25:289 | this access | UseUseExplosion.cs:25:303:25:306 | this access | +| UseUseExplosion.cs:25:286:25:289 | this access | UseUseExplosion.cs:25:2953:25:2958 | this access | +| UseUseExplosion.cs:25:303:25:306 | [post] this access | UseUseExplosion.cs:25:320:25:323 | this access | +| UseUseExplosion.cs:25:303:25:306 | [post] this access | UseUseExplosion.cs:25:2938:25:2943 | this access | +| UseUseExplosion.cs:25:303:25:306 | access to property Prop | UseUseExplosion.cs:25:303:25:311 | ... > ... | +| UseUseExplosion.cs:25:303:25:306 | access to property Prop | UseUseExplosion.cs:25:320:25:323 | access to property Prop | +| UseUseExplosion.cs:25:303:25:306 | this access | UseUseExplosion.cs:25:320:25:323 | this access | +| UseUseExplosion.cs:25:303:25:306 | this access | UseUseExplosion.cs:25:2938:25:2943 | this access | +| UseUseExplosion.cs:25:320:25:323 | [post] this access | UseUseExplosion.cs:25:337:25:340 | this access | +| UseUseExplosion.cs:25:320:25:323 | [post] this access | UseUseExplosion.cs:25:2923:25:2928 | this access | +| UseUseExplosion.cs:25:320:25:323 | access to property Prop | UseUseExplosion.cs:25:320:25:328 | ... > ... | +| UseUseExplosion.cs:25:320:25:323 | access to property Prop | UseUseExplosion.cs:25:337:25:340 | access to property Prop | +| UseUseExplosion.cs:25:320:25:323 | this access | UseUseExplosion.cs:25:337:25:340 | this access | +| UseUseExplosion.cs:25:320:25:323 | this access | UseUseExplosion.cs:25:2923:25:2928 | this access | +| UseUseExplosion.cs:25:337:25:340 | [post] this access | UseUseExplosion.cs:25:354:25:357 | this access | +| UseUseExplosion.cs:25:337:25:340 | [post] this access | UseUseExplosion.cs:25:2908:25:2913 | this access | +| UseUseExplosion.cs:25:337:25:340 | access to property Prop | UseUseExplosion.cs:25:337:25:345 | ... > ... | +| UseUseExplosion.cs:25:337:25:340 | access to property Prop | UseUseExplosion.cs:25:354:25:357 | access to property Prop | +| UseUseExplosion.cs:25:337:25:340 | this access | UseUseExplosion.cs:25:354:25:357 | this access | +| UseUseExplosion.cs:25:337:25:340 | this access | UseUseExplosion.cs:25:2908:25:2913 | this access | +| UseUseExplosion.cs:25:354:25:357 | [post] this access | UseUseExplosion.cs:25:371:25:374 | this access | +| UseUseExplosion.cs:25:354:25:357 | [post] this access | UseUseExplosion.cs:25:2893:25:2898 | this access | +| UseUseExplosion.cs:25:354:25:357 | access to property Prop | UseUseExplosion.cs:25:354:25:362 | ... > ... | +| UseUseExplosion.cs:25:354:25:357 | access to property Prop | UseUseExplosion.cs:25:371:25:374 | access to property Prop | +| UseUseExplosion.cs:25:354:25:357 | this access | UseUseExplosion.cs:25:371:25:374 | this access | +| UseUseExplosion.cs:25:354:25:357 | this access | UseUseExplosion.cs:25:2893:25:2898 | this access | +| UseUseExplosion.cs:25:371:25:374 | [post] this access | UseUseExplosion.cs:25:388:25:391 | this access | +| UseUseExplosion.cs:25:371:25:374 | [post] this access | UseUseExplosion.cs:25:2878:25:2883 | this access | +| UseUseExplosion.cs:25:371:25:374 | access to property Prop | UseUseExplosion.cs:25:371:25:379 | ... > ... | +| UseUseExplosion.cs:25:371:25:374 | access to property Prop | UseUseExplosion.cs:25:388:25:391 | access to property Prop | +| UseUseExplosion.cs:25:371:25:374 | this access | UseUseExplosion.cs:25:388:25:391 | this access | +| UseUseExplosion.cs:25:371:25:374 | this access | UseUseExplosion.cs:25:2878:25:2883 | this access | +| UseUseExplosion.cs:25:388:25:391 | [post] this access | UseUseExplosion.cs:25:405:25:408 | this access | +| UseUseExplosion.cs:25:388:25:391 | [post] this access | UseUseExplosion.cs:25:2863:25:2868 | this access | +| UseUseExplosion.cs:25:388:25:391 | access to property Prop | UseUseExplosion.cs:25:388:25:396 | ... > ... | +| UseUseExplosion.cs:25:388:25:391 | access to property Prop | UseUseExplosion.cs:25:405:25:408 | access to property Prop | +| UseUseExplosion.cs:25:388:25:391 | this access | UseUseExplosion.cs:25:405:25:408 | this access | +| UseUseExplosion.cs:25:388:25:391 | this access | UseUseExplosion.cs:25:2863:25:2868 | this access | +| UseUseExplosion.cs:25:405:25:408 | [post] this access | UseUseExplosion.cs:25:422:25:425 | this access | +| UseUseExplosion.cs:25:405:25:408 | [post] this access | UseUseExplosion.cs:25:2848:25:2853 | this access | +| UseUseExplosion.cs:25:405:25:408 | access to property Prop | UseUseExplosion.cs:25:405:25:413 | ... > ... | +| UseUseExplosion.cs:25:405:25:408 | access to property Prop | UseUseExplosion.cs:25:422:25:425 | access to property Prop | +| UseUseExplosion.cs:25:405:25:408 | this access | UseUseExplosion.cs:25:422:25:425 | this access | +| UseUseExplosion.cs:25:405:25:408 | this access | UseUseExplosion.cs:25:2848:25:2853 | this access | +| UseUseExplosion.cs:25:422:25:425 | [post] this access | UseUseExplosion.cs:25:439:25:442 | this access | +| UseUseExplosion.cs:25:422:25:425 | [post] this access | UseUseExplosion.cs:25:2833:25:2838 | this access | +| UseUseExplosion.cs:25:422:25:425 | access to property Prop | UseUseExplosion.cs:25:422:25:430 | ... > ... | +| UseUseExplosion.cs:25:422:25:425 | access to property Prop | UseUseExplosion.cs:25:439:25:442 | access to property Prop | +| UseUseExplosion.cs:25:422:25:425 | this access | UseUseExplosion.cs:25:439:25:442 | this access | +| UseUseExplosion.cs:25:422:25:425 | this access | UseUseExplosion.cs:25:2833:25:2838 | this access | +| UseUseExplosion.cs:25:439:25:442 | [post] this access | UseUseExplosion.cs:25:456:25:459 | this access | +| UseUseExplosion.cs:25:439:25:442 | [post] this access | UseUseExplosion.cs:25:2818:25:2823 | this access | +| UseUseExplosion.cs:25:439:25:442 | access to property Prop | UseUseExplosion.cs:25:439:25:447 | ... > ... | +| UseUseExplosion.cs:25:439:25:442 | access to property Prop | UseUseExplosion.cs:25:456:25:459 | access to property Prop | +| UseUseExplosion.cs:25:439:25:442 | this access | UseUseExplosion.cs:25:456:25:459 | this access | +| UseUseExplosion.cs:25:439:25:442 | this access | UseUseExplosion.cs:25:2818:25:2823 | this access | +| UseUseExplosion.cs:25:456:25:459 | [post] this access | UseUseExplosion.cs:25:473:25:476 | this access | +| UseUseExplosion.cs:25:456:25:459 | [post] this access | UseUseExplosion.cs:25:2803:25:2808 | this access | +| UseUseExplosion.cs:25:456:25:459 | access to property Prop | UseUseExplosion.cs:25:456:25:464 | ... > ... | +| UseUseExplosion.cs:25:456:25:459 | access to property Prop | UseUseExplosion.cs:25:473:25:476 | access to property Prop | +| UseUseExplosion.cs:25:456:25:459 | this access | UseUseExplosion.cs:25:473:25:476 | this access | +| UseUseExplosion.cs:25:456:25:459 | this access | UseUseExplosion.cs:25:2803:25:2808 | this access | +| UseUseExplosion.cs:25:473:25:476 | [post] this access | UseUseExplosion.cs:25:490:25:493 | this access | +| UseUseExplosion.cs:25:473:25:476 | [post] this access | UseUseExplosion.cs:25:2788:25:2793 | this access | +| UseUseExplosion.cs:25:473:25:476 | access to property Prop | UseUseExplosion.cs:25:473:25:481 | ... > ... | +| UseUseExplosion.cs:25:473:25:476 | access to property Prop | UseUseExplosion.cs:25:490:25:493 | access to property Prop | +| UseUseExplosion.cs:25:473:25:476 | this access | UseUseExplosion.cs:25:490:25:493 | this access | +| UseUseExplosion.cs:25:473:25:476 | this access | UseUseExplosion.cs:25:2788:25:2793 | this access | +| UseUseExplosion.cs:25:490:25:493 | [post] this access | UseUseExplosion.cs:25:507:25:510 | this access | +| UseUseExplosion.cs:25:490:25:493 | [post] this access | UseUseExplosion.cs:25:2773:25:2778 | this access | +| UseUseExplosion.cs:25:490:25:493 | access to property Prop | UseUseExplosion.cs:25:490:25:498 | ... > ... | +| UseUseExplosion.cs:25:490:25:493 | access to property Prop | UseUseExplosion.cs:25:507:25:510 | access to property Prop | +| UseUseExplosion.cs:25:490:25:493 | this access | UseUseExplosion.cs:25:507:25:510 | this access | +| UseUseExplosion.cs:25:490:25:493 | this access | UseUseExplosion.cs:25:2773:25:2778 | this access | +| UseUseExplosion.cs:25:507:25:510 | [post] this access | UseUseExplosion.cs:25:524:25:527 | this access | +| UseUseExplosion.cs:25:507:25:510 | [post] this access | UseUseExplosion.cs:25:2758:25:2763 | this access | +| UseUseExplosion.cs:25:507:25:510 | access to property Prop | UseUseExplosion.cs:25:507:25:515 | ... > ... | +| UseUseExplosion.cs:25:507:25:510 | access to property Prop | UseUseExplosion.cs:25:524:25:527 | access to property Prop | +| UseUseExplosion.cs:25:507:25:510 | this access | UseUseExplosion.cs:25:524:25:527 | this access | +| UseUseExplosion.cs:25:507:25:510 | this access | UseUseExplosion.cs:25:2758:25:2763 | this access | +| UseUseExplosion.cs:25:524:25:527 | [post] this access | UseUseExplosion.cs:25:541:25:544 | this access | +| UseUseExplosion.cs:25:524:25:527 | [post] this access | UseUseExplosion.cs:25:2743:25:2748 | this access | +| UseUseExplosion.cs:25:524:25:527 | access to property Prop | UseUseExplosion.cs:25:524:25:532 | ... > ... | +| UseUseExplosion.cs:25:524:25:527 | access to property Prop | UseUseExplosion.cs:25:541:25:544 | access to property Prop | +| UseUseExplosion.cs:25:524:25:527 | this access | UseUseExplosion.cs:25:541:25:544 | this access | +| UseUseExplosion.cs:25:524:25:527 | this access | UseUseExplosion.cs:25:2743:25:2748 | this access | +| UseUseExplosion.cs:25:541:25:544 | [post] this access | UseUseExplosion.cs:25:558:25:561 | this access | +| UseUseExplosion.cs:25:541:25:544 | [post] this access | UseUseExplosion.cs:25:2728:25:2733 | this access | +| UseUseExplosion.cs:25:541:25:544 | access to property Prop | UseUseExplosion.cs:25:541:25:549 | ... > ... | +| UseUseExplosion.cs:25:541:25:544 | access to property Prop | UseUseExplosion.cs:25:558:25:561 | access to property Prop | +| UseUseExplosion.cs:25:541:25:544 | this access | UseUseExplosion.cs:25:558:25:561 | this access | +| UseUseExplosion.cs:25:541:25:544 | this access | UseUseExplosion.cs:25:2728:25:2733 | this access | +| UseUseExplosion.cs:25:558:25:561 | [post] this access | UseUseExplosion.cs:25:575:25:578 | this access | +| UseUseExplosion.cs:25:558:25:561 | [post] this access | UseUseExplosion.cs:25:2713:25:2718 | this access | +| UseUseExplosion.cs:25:558:25:561 | access to property Prop | UseUseExplosion.cs:25:558:25:566 | ... > ... | +| UseUseExplosion.cs:25:558:25:561 | access to property Prop | UseUseExplosion.cs:25:575:25:578 | access to property Prop | +| UseUseExplosion.cs:25:558:25:561 | this access | UseUseExplosion.cs:25:575:25:578 | this access | +| UseUseExplosion.cs:25:558:25:561 | this access | UseUseExplosion.cs:25:2713:25:2718 | this access | +| UseUseExplosion.cs:25:575:25:578 | [post] this access | UseUseExplosion.cs:25:592:25:595 | this access | +| UseUseExplosion.cs:25:575:25:578 | [post] this access | UseUseExplosion.cs:25:2698:25:2703 | this access | +| UseUseExplosion.cs:25:575:25:578 | access to property Prop | UseUseExplosion.cs:25:575:25:583 | ... > ... | +| UseUseExplosion.cs:25:575:25:578 | access to property Prop | UseUseExplosion.cs:25:592:25:595 | access to property Prop | +| UseUseExplosion.cs:25:575:25:578 | this access | UseUseExplosion.cs:25:592:25:595 | this access | +| UseUseExplosion.cs:25:575:25:578 | this access | UseUseExplosion.cs:25:2698:25:2703 | this access | +| UseUseExplosion.cs:25:592:25:595 | [post] this access | UseUseExplosion.cs:25:609:25:612 | this access | +| UseUseExplosion.cs:25:592:25:595 | [post] this access | UseUseExplosion.cs:25:2683:25:2688 | this access | +| UseUseExplosion.cs:25:592:25:595 | access to property Prop | UseUseExplosion.cs:25:592:25:600 | ... > ... | +| UseUseExplosion.cs:25:592:25:595 | access to property Prop | UseUseExplosion.cs:25:609:25:612 | access to property Prop | +| UseUseExplosion.cs:25:592:25:595 | this access | UseUseExplosion.cs:25:609:25:612 | this access | +| UseUseExplosion.cs:25:592:25:595 | this access | UseUseExplosion.cs:25:2683:25:2688 | this access | +| UseUseExplosion.cs:25:609:25:612 | [post] this access | UseUseExplosion.cs:25:626:25:629 | this access | +| UseUseExplosion.cs:25:609:25:612 | [post] this access | UseUseExplosion.cs:25:2668:25:2673 | this access | +| UseUseExplosion.cs:25:609:25:612 | access to property Prop | UseUseExplosion.cs:25:609:25:617 | ... > ... | +| UseUseExplosion.cs:25:609:25:612 | access to property Prop | UseUseExplosion.cs:25:626:25:629 | access to property Prop | +| UseUseExplosion.cs:25:609:25:612 | this access | UseUseExplosion.cs:25:626:25:629 | this access | +| UseUseExplosion.cs:25:609:25:612 | this access | UseUseExplosion.cs:25:2668:25:2673 | this access | +| UseUseExplosion.cs:25:626:25:629 | [post] this access | UseUseExplosion.cs:25:643:25:646 | this access | +| UseUseExplosion.cs:25:626:25:629 | [post] this access | UseUseExplosion.cs:25:2653:25:2658 | this access | +| UseUseExplosion.cs:25:626:25:629 | access to property Prop | UseUseExplosion.cs:25:626:25:634 | ... > ... | +| UseUseExplosion.cs:25:626:25:629 | access to property Prop | UseUseExplosion.cs:25:643:25:646 | access to property Prop | +| UseUseExplosion.cs:25:626:25:629 | this access | UseUseExplosion.cs:25:643:25:646 | this access | +| UseUseExplosion.cs:25:626:25:629 | this access | UseUseExplosion.cs:25:2653:25:2658 | this access | +| UseUseExplosion.cs:25:643:25:646 | [post] this access | UseUseExplosion.cs:25:660:25:663 | this access | +| UseUseExplosion.cs:25:643:25:646 | [post] this access | UseUseExplosion.cs:25:2638:25:2643 | this access | +| UseUseExplosion.cs:25:643:25:646 | access to property Prop | UseUseExplosion.cs:25:643:25:651 | ... > ... | +| UseUseExplosion.cs:25:643:25:646 | access to property Prop | UseUseExplosion.cs:25:660:25:663 | access to property Prop | +| UseUseExplosion.cs:25:643:25:646 | this access | UseUseExplosion.cs:25:660:25:663 | this access | +| UseUseExplosion.cs:25:643:25:646 | this access | UseUseExplosion.cs:25:2638:25:2643 | this access | +| UseUseExplosion.cs:25:660:25:663 | [post] this access | UseUseExplosion.cs:25:677:25:680 | this access | +| UseUseExplosion.cs:25:660:25:663 | [post] this access | UseUseExplosion.cs:25:2623:25:2628 | this access | +| UseUseExplosion.cs:25:660:25:663 | access to property Prop | UseUseExplosion.cs:25:660:25:668 | ... > ... | +| UseUseExplosion.cs:25:660:25:663 | access to property Prop | UseUseExplosion.cs:25:677:25:680 | access to property Prop | +| UseUseExplosion.cs:25:660:25:663 | this access | UseUseExplosion.cs:25:677:25:680 | this access | +| UseUseExplosion.cs:25:660:25:663 | this access | UseUseExplosion.cs:25:2623:25:2628 | this access | +| UseUseExplosion.cs:25:677:25:680 | [post] this access | UseUseExplosion.cs:25:694:25:697 | this access | +| UseUseExplosion.cs:25:677:25:680 | [post] this access | UseUseExplosion.cs:25:2608:25:2613 | this access | +| UseUseExplosion.cs:25:677:25:680 | access to property Prop | UseUseExplosion.cs:25:677:25:685 | ... > ... | +| UseUseExplosion.cs:25:677:25:680 | access to property Prop | UseUseExplosion.cs:25:694:25:697 | access to property Prop | +| UseUseExplosion.cs:25:677:25:680 | this access | UseUseExplosion.cs:25:694:25:697 | this access | +| UseUseExplosion.cs:25:677:25:680 | this access | UseUseExplosion.cs:25:2608:25:2613 | this access | +| UseUseExplosion.cs:25:694:25:697 | [post] this access | UseUseExplosion.cs:25:711:25:714 | this access | +| UseUseExplosion.cs:25:694:25:697 | [post] this access | UseUseExplosion.cs:25:2593:25:2598 | this access | +| UseUseExplosion.cs:25:694:25:697 | access to property Prop | UseUseExplosion.cs:25:694:25:702 | ... > ... | +| UseUseExplosion.cs:25:694:25:697 | access to property Prop | UseUseExplosion.cs:25:711:25:714 | access to property Prop | +| UseUseExplosion.cs:25:694:25:697 | this access | UseUseExplosion.cs:25:711:25:714 | this access | +| UseUseExplosion.cs:25:694:25:697 | this access | UseUseExplosion.cs:25:2593:25:2598 | this access | +| UseUseExplosion.cs:25:711:25:714 | [post] this access | UseUseExplosion.cs:25:728:25:731 | this access | +| UseUseExplosion.cs:25:711:25:714 | [post] this access | UseUseExplosion.cs:25:2578:25:2583 | this access | +| UseUseExplosion.cs:25:711:25:714 | access to property Prop | UseUseExplosion.cs:25:711:25:719 | ... > ... | +| UseUseExplosion.cs:25:711:25:714 | access to property Prop | UseUseExplosion.cs:25:728:25:731 | access to property Prop | +| UseUseExplosion.cs:25:711:25:714 | this access | UseUseExplosion.cs:25:728:25:731 | this access | +| UseUseExplosion.cs:25:711:25:714 | this access | UseUseExplosion.cs:25:2578:25:2583 | this access | +| UseUseExplosion.cs:25:728:25:731 | [post] this access | UseUseExplosion.cs:25:745:25:748 | this access | +| UseUseExplosion.cs:25:728:25:731 | [post] this access | UseUseExplosion.cs:25:2563:25:2568 | this access | +| UseUseExplosion.cs:25:728:25:731 | access to property Prop | UseUseExplosion.cs:25:728:25:736 | ... > ... | +| UseUseExplosion.cs:25:728:25:731 | access to property Prop | UseUseExplosion.cs:25:745:25:748 | access to property Prop | +| UseUseExplosion.cs:25:728:25:731 | this access | UseUseExplosion.cs:25:745:25:748 | this access | +| UseUseExplosion.cs:25:728:25:731 | this access | UseUseExplosion.cs:25:2563:25:2568 | this access | +| UseUseExplosion.cs:25:745:25:748 | [post] this access | UseUseExplosion.cs:25:762:25:765 | this access | +| UseUseExplosion.cs:25:745:25:748 | [post] this access | UseUseExplosion.cs:25:2548:25:2553 | this access | +| UseUseExplosion.cs:25:745:25:748 | access to property Prop | UseUseExplosion.cs:25:745:25:753 | ... > ... | +| UseUseExplosion.cs:25:745:25:748 | access to property Prop | UseUseExplosion.cs:25:762:25:765 | access to property Prop | +| UseUseExplosion.cs:25:745:25:748 | this access | UseUseExplosion.cs:25:762:25:765 | this access | +| UseUseExplosion.cs:25:745:25:748 | this access | UseUseExplosion.cs:25:2548:25:2553 | this access | +| UseUseExplosion.cs:25:762:25:765 | [post] this access | UseUseExplosion.cs:25:779:25:782 | this access | +| UseUseExplosion.cs:25:762:25:765 | [post] this access | UseUseExplosion.cs:25:2533:25:2538 | this access | +| UseUseExplosion.cs:25:762:25:765 | access to property Prop | UseUseExplosion.cs:25:762:25:770 | ... > ... | +| UseUseExplosion.cs:25:762:25:765 | access to property Prop | UseUseExplosion.cs:25:779:25:782 | access to property Prop | +| UseUseExplosion.cs:25:762:25:765 | this access | UseUseExplosion.cs:25:779:25:782 | this access | +| UseUseExplosion.cs:25:762:25:765 | this access | UseUseExplosion.cs:25:2533:25:2538 | this access | +| UseUseExplosion.cs:25:779:25:782 | [post] this access | UseUseExplosion.cs:25:796:25:799 | this access | +| UseUseExplosion.cs:25:779:25:782 | [post] this access | UseUseExplosion.cs:25:2518:25:2523 | this access | +| UseUseExplosion.cs:25:779:25:782 | access to property Prop | UseUseExplosion.cs:25:779:25:787 | ... > ... | +| UseUseExplosion.cs:25:779:25:782 | access to property Prop | UseUseExplosion.cs:25:796:25:799 | access to property Prop | +| UseUseExplosion.cs:25:779:25:782 | this access | UseUseExplosion.cs:25:796:25:799 | this access | +| UseUseExplosion.cs:25:779:25:782 | this access | UseUseExplosion.cs:25:2518:25:2523 | this access | +| UseUseExplosion.cs:25:796:25:799 | [post] this access | UseUseExplosion.cs:25:813:25:816 | this access | +| UseUseExplosion.cs:25:796:25:799 | [post] this access | UseUseExplosion.cs:25:2503:25:2508 | this access | +| UseUseExplosion.cs:25:796:25:799 | access to property Prop | UseUseExplosion.cs:25:796:25:804 | ... > ... | +| UseUseExplosion.cs:25:796:25:799 | access to property Prop | UseUseExplosion.cs:25:813:25:816 | access to property Prop | +| UseUseExplosion.cs:25:796:25:799 | this access | UseUseExplosion.cs:25:813:25:816 | this access | +| UseUseExplosion.cs:25:796:25:799 | this access | UseUseExplosion.cs:25:2503:25:2508 | this access | +| UseUseExplosion.cs:25:813:25:816 | [post] this access | UseUseExplosion.cs:25:830:25:833 | this access | +| UseUseExplosion.cs:25:813:25:816 | [post] this access | UseUseExplosion.cs:25:2488:25:2493 | this access | +| UseUseExplosion.cs:25:813:25:816 | access to property Prop | UseUseExplosion.cs:25:813:25:821 | ... > ... | +| UseUseExplosion.cs:25:813:25:816 | access to property Prop | UseUseExplosion.cs:25:830:25:833 | access to property Prop | +| UseUseExplosion.cs:25:813:25:816 | this access | UseUseExplosion.cs:25:830:25:833 | this access | +| UseUseExplosion.cs:25:813:25:816 | this access | UseUseExplosion.cs:25:2488:25:2493 | this access | +| UseUseExplosion.cs:25:830:25:833 | [post] this access | UseUseExplosion.cs:25:847:25:850 | this access | +| UseUseExplosion.cs:25:830:25:833 | [post] this access | UseUseExplosion.cs:25:2473:25:2478 | this access | +| UseUseExplosion.cs:25:830:25:833 | access to property Prop | UseUseExplosion.cs:25:830:25:838 | ... > ... | +| UseUseExplosion.cs:25:830:25:833 | access to property Prop | UseUseExplosion.cs:25:847:25:850 | access to property Prop | +| UseUseExplosion.cs:25:830:25:833 | this access | UseUseExplosion.cs:25:847:25:850 | this access | +| UseUseExplosion.cs:25:830:25:833 | this access | UseUseExplosion.cs:25:2473:25:2478 | this access | +| UseUseExplosion.cs:25:847:25:850 | [post] this access | UseUseExplosion.cs:25:864:25:867 | this access | +| UseUseExplosion.cs:25:847:25:850 | [post] this access | UseUseExplosion.cs:25:2458:25:2463 | this access | +| UseUseExplosion.cs:25:847:25:850 | access to property Prop | UseUseExplosion.cs:25:847:25:855 | ... > ... | +| UseUseExplosion.cs:25:847:25:850 | access to property Prop | UseUseExplosion.cs:25:864:25:867 | access to property Prop | +| UseUseExplosion.cs:25:847:25:850 | this access | UseUseExplosion.cs:25:864:25:867 | this access | +| UseUseExplosion.cs:25:847:25:850 | this access | UseUseExplosion.cs:25:2458:25:2463 | this access | +| UseUseExplosion.cs:25:864:25:867 | [post] this access | UseUseExplosion.cs:25:881:25:884 | this access | +| UseUseExplosion.cs:25:864:25:867 | [post] this access | UseUseExplosion.cs:25:2443:25:2448 | this access | +| UseUseExplosion.cs:25:864:25:867 | access to property Prop | UseUseExplosion.cs:25:864:25:872 | ... > ... | +| UseUseExplosion.cs:25:864:25:867 | access to property Prop | UseUseExplosion.cs:25:881:25:884 | access to property Prop | +| UseUseExplosion.cs:25:864:25:867 | this access | UseUseExplosion.cs:25:881:25:884 | this access | +| UseUseExplosion.cs:25:864:25:867 | this access | UseUseExplosion.cs:25:2443:25:2448 | this access | +| UseUseExplosion.cs:25:881:25:884 | [post] this access | UseUseExplosion.cs:25:898:25:901 | this access | +| UseUseExplosion.cs:25:881:25:884 | [post] this access | UseUseExplosion.cs:25:2428:25:2433 | this access | +| UseUseExplosion.cs:25:881:25:884 | access to property Prop | UseUseExplosion.cs:25:881:25:889 | ... > ... | +| UseUseExplosion.cs:25:881:25:884 | access to property Prop | UseUseExplosion.cs:25:898:25:901 | access to property Prop | +| UseUseExplosion.cs:25:881:25:884 | this access | UseUseExplosion.cs:25:898:25:901 | this access | +| UseUseExplosion.cs:25:881:25:884 | this access | UseUseExplosion.cs:25:2428:25:2433 | this access | +| UseUseExplosion.cs:25:898:25:901 | [post] this access | UseUseExplosion.cs:25:915:25:918 | this access | +| UseUseExplosion.cs:25:898:25:901 | [post] this access | UseUseExplosion.cs:25:2413:25:2418 | this access | +| UseUseExplosion.cs:25:898:25:901 | access to property Prop | UseUseExplosion.cs:25:898:25:906 | ... > ... | +| UseUseExplosion.cs:25:898:25:901 | access to property Prop | UseUseExplosion.cs:25:915:25:918 | access to property Prop | +| UseUseExplosion.cs:25:898:25:901 | this access | UseUseExplosion.cs:25:915:25:918 | this access | +| UseUseExplosion.cs:25:898:25:901 | this access | UseUseExplosion.cs:25:2413:25:2418 | this access | +| UseUseExplosion.cs:25:915:25:918 | [post] this access | UseUseExplosion.cs:25:932:25:935 | this access | +| UseUseExplosion.cs:25:915:25:918 | [post] this access | UseUseExplosion.cs:25:2398:25:2403 | this access | +| UseUseExplosion.cs:25:915:25:918 | access to property Prop | UseUseExplosion.cs:25:915:25:923 | ... > ... | +| UseUseExplosion.cs:25:915:25:918 | access to property Prop | UseUseExplosion.cs:25:932:25:935 | access to property Prop | +| UseUseExplosion.cs:25:915:25:918 | this access | UseUseExplosion.cs:25:932:25:935 | this access | +| UseUseExplosion.cs:25:915:25:918 | this access | UseUseExplosion.cs:25:2398:25:2403 | this access | +| UseUseExplosion.cs:25:932:25:935 | [post] this access | UseUseExplosion.cs:25:949:25:952 | this access | +| UseUseExplosion.cs:25:932:25:935 | [post] this access | UseUseExplosion.cs:25:2383:25:2388 | this access | +| UseUseExplosion.cs:25:932:25:935 | access to property Prop | UseUseExplosion.cs:25:932:25:940 | ... > ... | +| UseUseExplosion.cs:25:932:25:935 | access to property Prop | UseUseExplosion.cs:25:949:25:952 | access to property Prop | +| UseUseExplosion.cs:25:932:25:935 | this access | UseUseExplosion.cs:25:949:25:952 | this access | +| UseUseExplosion.cs:25:932:25:935 | this access | UseUseExplosion.cs:25:2383:25:2388 | this access | +| UseUseExplosion.cs:25:949:25:952 | [post] this access | UseUseExplosion.cs:25:966:25:969 | this access | +| UseUseExplosion.cs:25:949:25:952 | [post] this access | UseUseExplosion.cs:25:2368:25:2373 | this access | +| UseUseExplosion.cs:25:949:25:952 | access to property Prop | UseUseExplosion.cs:25:949:25:957 | ... > ... | +| UseUseExplosion.cs:25:949:25:952 | access to property Prop | UseUseExplosion.cs:25:966:25:969 | access to property Prop | +| UseUseExplosion.cs:25:949:25:952 | this access | UseUseExplosion.cs:25:966:25:969 | this access | +| UseUseExplosion.cs:25:949:25:952 | this access | UseUseExplosion.cs:25:2368:25:2373 | this access | +| UseUseExplosion.cs:25:966:25:969 | [post] this access | UseUseExplosion.cs:25:983:25:986 | this access | +| UseUseExplosion.cs:25:966:25:969 | [post] this access | UseUseExplosion.cs:25:2353:25:2358 | this access | +| UseUseExplosion.cs:25:966:25:969 | access to property Prop | UseUseExplosion.cs:25:966:25:974 | ... > ... | +| UseUseExplosion.cs:25:966:25:969 | access to property Prop | UseUseExplosion.cs:25:983:25:986 | access to property Prop | +| UseUseExplosion.cs:25:966:25:969 | this access | UseUseExplosion.cs:25:983:25:986 | this access | +| UseUseExplosion.cs:25:966:25:969 | this access | UseUseExplosion.cs:25:2353:25:2358 | this access | +| UseUseExplosion.cs:25:983:25:986 | [post] this access | UseUseExplosion.cs:25:1000:25:1003 | this access | +| UseUseExplosion.cs:25:983:25:986 | [post] this access | UseUseExplosion.cs:25:2338:25:2343 | this access | +| UseUseExplosion.cs:25:983:25:986 | access to property Prop | UseUseExplosion.cs:25:983:25:991 | ... > ... | +| UseUseExplosion.cs:25:983:25:986 | access to property Prop | UseUseExplosion.cs:25:1000:25:1003 | access to property Prop | +| UseUseExplosion.cs:25:983:25:986 | this access | UseUseExplosion.cs:25:1000:25:1003 | this access | +| UseUseExplosion.cs:25:983:25:986 | this access | UseUseExplosion.cs:25:2338:25:2343 | this access | +| UseUseExplosion.cs:25:1000:25:1003 | [post] this access | UseUseExplosion.cs:25:1017:25:1020 | this access | +| UseUseExplosion.cs:25:1000:25:1003 | [post] this access | UseUseExplosion.cs:25:2323:25:2328 | this access | +| UseUseExplosion.cs:25:1000:25:1003 | access to property Prop | UseUseExplosion.cs:25:1000:25:1008 | ... > ... | +| UseUseExplosion.cs:25:1000:25:1003 | access to property Prop | UseUseExplosion.cs:25:1017:25:1020 | access to property Prop | +| UseUseExplosion.cs:25:1000:25:1003 | this access | UseUseExplosion.cs:25:1017:25:1020 | this access | +| UseUseExplosion.cs:25:1000:25:1003 | this access | UseUseExplosion.cs:25:2323:25:2328 | this access | +| UseUseExplosion.cs:25:1017:25:1020 | [post] this access | UseUseExplosion.cs:25:1034:25:1037 | this access | +| UseUseExplosion.cs:25:1017:25:1020 | [post] this access | UseUseExplosion.cs:25:2308:25:2313 | this access | +| UseUseExplosion.cs:25:1017:25:1020 | access to property Prop | UseUseExplosion.cs:25:1017:25:1025 | ... > ... | +| UseUseExplosion.cs:25:1017:25:1020 | access to property Prop | UseUseExplosion.cs:25:1034:25:1037 | access to property Prop | +| UseUseExplosion.cs:25:1017:25:1020 | this access | UseUseExplosion.cs:25:1034:25:1037 | this access | +| UseUseExplosion.cs:25:1017:25:1020 | this access | UseUseExplosion.cs:25:2308:25:2313 | this access | +| UseUseExplosion.cs:25:1034:25:1037 | [post] this access | UseUseExplosion.cs:25:1051:25:1054 | this access | +| UseUseExplosion.cs:25:1034:25:1037 | [post] this access | UseUseExplosion.cs:25:2293:25:2298 | this access | +| UseUseExplosion.cs:25:1034:25:1037 | access to property Prop | UseUseExplosion.cs:25:1034:25:1042 | ... > ... | +| UseUseExplosion.cs:25:1034:25:1037 | access to property Prop | UseUseExplosion.cs:25:1051:25:1054 | access to property Prop | +| UseUseExplosion.cs:25:1034:25:1037 | this access | UseUseExplosion.cs:25:1051:25:1054 | this access | +| UseUseExplosion.cs:25:1034:25:1037 | this access | UseUseExplosion.cs:25:2293:25:2298 | this access | +| UseUseExplosion.cs:25:1051:25:1054 | [post] this access | UseUseExplosion.cs:25:1068:25:1071 | this access | +| UseUseExplosion.cs:25:1051:25:1054 | [post] this access | UseUseExplosion.cs:25:2278:25:2283 | this access | +| UseUseExplosion.cs:25:1051:25:1054 | access to property Prop | UseUseExplosion.cs:25:1051:25:1059 | ... > ... | +| UseUseExplosion.cs:25:1051:25:1054 | access to property Prop | UseUseExplosion.cs:25:1068:25:1071 | access to property Prop | +| UseUseExplosion.cs:25:1051:25:1054 | this access | UseUseExplosion.cs:25:1068:25:1071 | this access | +| UseUseExplosion.cs:25:1051:25:1054 | this access | UseUseExplosion.cs:25:2278:25:2283 | this access | +| UseUseExplosion.cs:25:1068:25:1071 | [post] this access | UseUseExplosion.cs:25:1085:25:1088 | this access | +| UseUseExplosion.cs:25:1068:25:1071 | [post] this access | UseUseExplosion.cs:25:2263:25:2268 | this access | +| UseUseExplosion.cs:25:1068:25:1071 | access to property Prop | UseUseExplosion.cs:25:1068:25:1076 | ... > ... | +| UseUseExplosion.cs:25:1068:25:1071 | access to property Prop | UseUseExplosion.cs:25:1085:25:1088 | access to property Prop | +| UseUseExplosion.cs:25:1068:25:1071 | this access | UseUseExplosion.cs:25:1085:25:1088 | this access | +| UseUseExplosion.cs:25:1068:25:1071 | this access | UseUseExplosion.cs:25:2263:25:2268 | this access | +| UseUseExplosion.cs:25:1085:25:1088 | [post] this access | UseUseExplosion.cs:25:1102:25:1105 | this access | +| UseUseExplosion.cs:25:1085:25:1088 | [post] this access | UseUseExplosion.cs:25:2248:25:2253 | this access | +| UseUseExplosion.cs:25:1085:25:1088 | access to property Prop | UseUseExplosion.cs:25:1085:25:1093 | ... > ... | +| UseUseExplosion.cs:25:1085:25:1088 | access to property Prop | UseUseExplosion.cs:25:1102:25:1105 | access to property Prop | +| UseUseExplosion.cs:25:1085:25:1088 | this access | UseUseExplosion.cs:25:1102:25:1105 | this access | +| UseUseExplosion.cs:25:1085:25:1088 | this access | UseUseExplosion.cs:25:2248:25:2253 | this access | +| UseUseExplosion.cs:25:1102:25:1105 | [post] this access | UseUseExplosion.cs:25:1119:25:1122 | this access | +| UseUseExplosion.cs:25:1102:25:1105 | [post] this access | UseUseExplosion.cs:25:2233:25:2238 | this access | +| UseUseExplosion.cs:25:1102:25:1105 | access to property Prop | UseUseExplosion.cs:25:1102:25:1110 | ... > ... | +| UseUseExplosion.cs:25:1102:25:1105 | access to property Prop | UseUseExplosion.cs:25:1119:25:1122 | access to property Prop | +| UseUseExplosion.cs:25:1102:25:1105 | this access | UseUseExplosion.cs:25:1119:25:1122 | this access | +| UseUseExplosion.cs:25:1102:25:1105 | this access | UseUseExplosion.cs:25:2233:25:2238 | this access | +| UseUseExplosion.cs:25:1119:25:1122 | [post] this access | UseUseExplosion.cs:25:1136:25:1139 | this access | +| UseUseExplosion.cs:25:1119:25:1122 | [post] this access | UseUseExplosion.cs:25:2218:25:2223 | this access | +| UseUseExplosion.cs:25:1119:25:1122 | access to property Prop | UseUseExplosion.cs:25:1119:25:1127 | ... > ... | +| UseUseExplosion.cs:25:1119:25:1122 | access to property Prop | UseUseExplosion.cs:25:1136:25:1139 | access to property Prop | +| UseUseExplosion.cs:25:1119:25:1122 | this access | UseUseExplosion.cs:25:1136:25:1139 | this access | +| UseUseExplosion.cs:25:1119:25:1122 | this access | UseUseExplosion.cs:25:2218:25:2223 | this access | +| UseUseExplosion.cs:25:1136:25:1139 | [post] this access | UseUseExplosion.cs:25:1153:25:1156 | this access | +| UseUseExplosion.cs:25:1136:25:1139 | [post] this access | UseUseExplosion.cs:25:2203:25:2208 | this access | +| UseUseExplosion.cs:25:1136:25:1139 | access to property Prop | UseUseExplosion.cs:25:1136:25:1144 | ... > ... | +| UseUseExplosion.cs:25:1136:25:1139 | access to property Prop | UseUseExplosion.cs:25:1153:25:1156 | access to property Prop | +| UseUseExplosion.cs:25:1136:25:1139 | this access | UseUseExplosion.cs:25:1153:25:1156 | this access | +| UseUseExplosion.cs:25:1136:25:1139 | this access | UseUseExplosion.cs:25:2203:25:2208 | this access | +| UseUseExplosion.cs:25:1153:25:1156 | [post] this access | UseUseExplosion.cs:25:1170:25:1173 | this access | +| UseUseExplosion.cs:25:1153:25:1156 | [post] this access | UseUseExplosion.cs:25:2188:25:2193 | this access | +| UseUseExplosion.cs:25:1153:25:1156 | access to property Prop | UseUseExplosion.cs:25:1153:25:1161 | ... > ... | +| UseUseExplosion.cs:25:1153:25:1156 | access to property Prop | UseUseExplosion.cs:25:1170:25:1173 | access to property Prop | +| UseUseExplosion.cs:25:1153:25:1156 | this access | UseUseExplosion.cs:25:1170:25:1173 | this access | +| UseUseExplosion.cs:25:1153:25:1156 | this access | UseUseExplosion.cs:25:2188:25:2193 | this access | +| UseUseExplosion.cs:25:1170:25:1173 | [post] this access | UseUseExplosion.cs:25:1187:25:1190 | this access | +| UseUseExplosion.cs:25:1170:25:1173 | [post] this access | UseUseExplosion.cs:25:2173:25:2178 | this access | +| UseUseExplosion.cs:25:1170:25:1173 | access to property Prop | UseUseExplosion.cs:25:1170:25:1178 | ... > ... | +| UseUseExplosion.cs:25:1170:25:1173 | access to property Prop | UseUseExplosion.cs:25:1187:25:1190 | access to property Prop | +| UseUseExplosion.cs:25:1170:25:1173 | this access | UseUseExplosion.cs:25:1187:25:1190 | this access | +| UseUseExplosion.cs:25:1170:25:1173 | this access | UseUseExplosion.cs:25:2173:25:2178 | this access | +| UseUseExplosion.cs:25:1187:25:1190 | [post] this access | UseUseExplosion.cs:25:1204:25:1207 | this access | +| UseUseExplosion.cs:25:1187:25:1190 | [post] this access | UseUseExplosion.cs:25:2158:25:2163 | this access | +| UseUseExplosion.cs:25:1187:25:1190 | access to property Prop | UseUseExplosion.cs:25:1187:25:1195 | ... > ... | +| UseUseExplosion.cs:25:1187:25:1190 | access to property Prop | UseUseExplosion.cs:25:1204:25:1207 | access to property Prop | +| UseUseExplosion.cs:25:1187:25:1190 | this access | UseUseExplosion.cs:25:1204:25:1207 | this access | +| UseUseExplosion.cs:25:1187:25:1190 | this access | UseUseExplosion.cs:25:2158:25:2163 | this access | +| UseUseExplosion.cs:25:1204:25:1207 | [post] this access | UseUseExplosion.cs:25:1221:25:1224 | this access | +| UseUseExplosion.cs:25:1204:25:1207 | [post] this access | UseUseExplosion.cs:25:2143:25:2148 | this access | +| UseUseExplosion.cs:25:1204:25:1207 | access to property Prop | UseUseExplosion.cs:25:1204:25:1212 | ... > ... | +| UseUseExplosion.cs:25:1204:25:1207 | access to property Prop | UseUseExplosion.cs:25:1221:25:1224 | access to property Prop | +| UseUseExplosion.cs:25:1204:25:1207 | this access | UseUseExplosion.cs:25:1221:25:1224 | this access | +| UseUseExplosion.cs:25:1204:25:1207 | this access | UseUseExplosion.cs:25:2143:25:2148 | this access | +| UseUseExplosion.cs:25:1221:25:1224 | [post] this access | UseUseExplosion.cs:25:1238:25:1241 | this access | +| UseUseExplosion.cs:25:1221:25:1224 | [post] this access | UseUseExplosion.cs:25:2128:25:2133 | this access | +| UseUseExplosion.cs:25:1221:25:1224 | access to property Prop | UseUseExplosion.cs:25:1221:25:1229 | ... > ... | +| UseUseExplosion.cs:25:1221:25:1224 | access to property Prop | UseUseExplosion.cs:25:1238:25:1241 | access to property Prop | +| UseUseExplosion.cs:25:1221:25:1224 | this access | UseUseExplosion.cs:25:1238:25:1241 | this access | +| UseUseExplosion.cs:25:1221:25:1224 | this access | UseUseExplosion.cs:25:2128:25:2133 | this access | +| UseUseExplosion.cs:25:1238:25:1241 | [post] this access | UseUseExplosion.cs:25:1255:25:1258 | this access | +| UseUseExplosion.cs:25:1238:25:1241 | [post] this access | UseUseExplosion.cs:25:2113:25:2118 | this access | +| UseUseExplosion.cs:25:1238:25:1241 | access to property Prop | UseUseExplosion.cs:25:1238:25:1246 | ... > ... | +| UseUseExplosion.cs:25:1238:25:1241 | access to property Prop | UseUseExplosion.cs:25:1255:25:1258 | access to property Prop | +| UseUseExplosion.cs:25:1238:25:1241 | this access | UseUseExplosion.cs:25:1255:25:1258 | this access | +| UseUseExplosion.cs:25:1238:25:1241 | this access | UseUseExplosion.cs:25:2113:25:2118 | this access | +| UseUseExplosion.cs:25:1255:25:1258 | [post] this access | UseUseExplosion.cs:25:1272:25:1275 | this access | +| UseUseExplosion.cs:25:1255:25:1258 | [post] this access | UseUseExplosion.cs:25:2098:25:2103 | this access | +| UseUseExplosion.cs:25:1255:25:1258 | access to property Prop | UseUseExplosion.cs:25:1255:25:1263 | ... > ... | +| UseUseExplosion.cs:25:1255:25:1258 | access to property Prop | UseUseExplosion.cs:25:1272:25:1275 | access to property Prop | +| UseUseExplosion.cs:25:1255:25:1258 | this access | UseUseExplosion.cs:25:1272:25:1275 | this access | +| UseUseExplosion.cs:25:1255:25:1258 | this access | UseUseExplosion.cs:25:2098:25:2103 | this access | +| UseUseExplosion.cs:25:1272:25:1275 | [post] this access | UseUseExplosion.cs:25:1289:25:1292 | this access | +| UseUseExplosion.cs:25:1272:25:1275 | [post] this access | UseUseExplosion.cs:25:2083:25:2088 | this access | +| UseUseExplosion.cs:25:1272:25:1275 | access to property Prop | UseUseExplosion.cs:25:1272:25:1280 | ... > ... | +| UseUseExplosion.cs:25:1272:25:1275 | access to property Prop | UseUseExplosion.cs:25:1289:25:1292 | access to property Prop | +| UseUseExplosion.cs:25:1272:25:1275 | this access | UseUseExplosion.cs:25:1289:25:1292 | this access | +| UseUseExplosion.cs:25:1272:25:1275 | this access | UseUseExplosion.cs:25:2083:25:2088 | this access | +| UseUseExplosion.cs:25:1289:25:1292 | [post] this access | UseUseExplosion.cs:25:1306:25:1309 | this access | +| UseUseExplosion.cs:25:1289:25:1292 | [post] this access | UseUseExplosion.cs:25:2068:25:2073 | this access | +| UseUseExplosion.cs:25:1289:25:1292 | access to property Prop | UseUseExplosion.cs:25:1289:25:1297 | ... > ... | +| UseUseExplosion.cs:25:1289:25:1292 | access to property Prop | UseUseExplosion.cs:25:1306:25:1309 | access to property Prop | +| UseUseExplosion.cs:25:1289:25:1292 | this access | UseUseExplosion.cs:25:1306:25:1309 | this access | +| UseUseExplosion.cs:25:1289:25:1292 | this access | UseUseExplosion.cs:25:2068:25:2073 | this access | +| UseUseExplosion.cs:25:1306:25:1309 | [post] this access | UseUseExplosion.cs:25:1323:25:1326 | this access | +| UseUseExplosion.cs:25:1306:25:1309 | [post] this access | UseUseExplosion.cs:25:2053:25:2058 | this access | +| UseUseExplosion.cs:25:1306:25:1309 | access to property Prop | UseUseExplosion.cs:25:1306:25:1314 | ... > ... | +| UseUseExplosion.cs:25:1306:25:1309 | access to property Prop | UseUseExplosion.cs:25:1323:25:1326 | access to property Prop | +| UseUseExplosion.cs:25:1306:25:1309 | this access | UseUseExplosion.cs:25:1323:25:1326 | this access | +| UseUseExplosion.cs:25:1306:25:1309 | this access | UseUseExplosion.cs:25:2053:25:2058 | this access | +| UseUseExplosion.cs:25:1323:25:1326 | [post] this access | UseUseExplosion.cs:25:1340:25:1343 | this access | +| UseUseExplosion.cs:25:1323:25:1326 | [post] this access | UseUseExplosion.cs:25:2038:25:2043 | this access | +| UseUseExplosion.cs:25:1323:25:1326 | access to property Prop | UseUseExplosion.cs:25:1323:25:1331 | ... > ... | +| UseUseExplosion.cs:25:1323:25:1326 | access to property Prop | UseUseExplosion.cs:25:1340:25:1343 | access to property Prop | +| UseUseExplosion.cs:25:1323:25:1326 | this access | UseUseExplosion.cs:25:1340:25:1343 | this access | +| UseUseExplosion.cs:25:1323:25:1326 | this access | UseUseExplosion.cs:25:2038:25:2043 | this access | +| UseUseExplosion.cs:25:1340:25:1343 | [post] this access | UseUseExplosion.cs:25:1357:25:1360 | this access | +| UseUseExplosion.cs:25:1340:25:1343 | [post] this access | UseUseExplosion.cs:25:2023:25:2028 | this access | +| UseUseExplosion.cs:25:1340:25:1343 | access to property Prop | UseUseExplosion.cs:25:1340:25:1348 | ... > ... | +| UseUseExplosion.cs:25:1340:25:1343 | access to property Prop | UseUseExplosion.cs:25:1357:25:1360 | access to property Prop | +| UseUseExplosion.cs:25:1340:25:1343 | this access | UseUseExplosion.cs:25:1357:25:1360 | this access | +| UseUseExplosion.cs:25:1340:25:1343 | this access | UseUseExplosion.cs:25:2023:25:2028 | this access | +| UseUseExplosion.cs:25:1357:25:1360 | [post] this access | UseUseExplosion.cs:25:1374:25:1377 | this access | +| UseUseExplosion.cs:25:1357:25:1360 | [post] this access | UseUseExplosion.cs:25:2008:25:2013 | this access | +| UseUseExplosion.cs:25:1357:25:1360 | access to property Prop | UseUseExplosion.cs:25:1357:25:1365 | ... > ... | +| UseUseExplosion.cs:25:1357:25:1360 | access to property Prop | UseUseExplosion.cs:25:1374:25:1377 | access to property Prop | +| UseUseExplosion.cs:25:1357:25:1360 | this access | UseUseExplosion.cs:25:1374:25:1377 | this access | +| UseUseExplosion.cs:25:1357:25:1360 | this access | UseUseExplosion.cs:25:2008:25:2013 | this access | +| UseUseExplosion.cs:25:1374:25:1377 | [post] this access | UseUseExplosion.cs:25:1391:25:1394 | this access | +| UseUseExplosion.cs:25:1374:25:1377 | [post] this access | UseUseExplosion.cs:25:1993:25:1998 | this access | +| UseUseExplosion.cs:25:1374:25:1377 | access to property Prop | UseUseExplosion.cs:25:1374:25:1382 | ... > ... | +| UseUseExplosion.cs:25:1374:25:1377 | access to property Prop | UseUseExplosion.cs:25:1391:25:1394 | access to property Prop | +| UseUseExplosion.cs:25:1374:25:1377 | this access | UseUseExplosion.cs:25:1391:25:1394 | this access | +| UseUseExplosion.cs:25:1374:25:1377 | this access | UseUseExplosion.cs:25:1993:25:1998 | this access | +| UseUseExplosion.cs:25:1391:25:1394 | [post] this access | UseUseExplosion.cs:25:1408:25:1411 | this access | +| UseUseExplosion.cs:25:1391:25:1394 | [post] this access | UseUseExplosion.cs:25:1978:25:1983 | this access | +| UseUseExplosion.cs:25:1391:25:1394 | access to property Prop | UseUseExplosion.cs:25:1391:25:1399 | ... > ... | +| UseUseExplosion.cs:25:1391:25:1394 | access to property Prop | UseUseExplosion.cs:25:1408:25:1411 | access to property Prop | +| UseUseExplosion.cs:25:1391:25:1394 | this access | UseUseExplosion.cs:25:1408:25:1411 | this access | +| UseUseExplosion.cs:25:1391:25:1394 | this access | UseUseExplosion.cs:25:1978:25:1983 | this access | +| UseUseExplosion.cs:25:1408:25:1411 | [post] this access | UseUseExplosion.cs:25:1425:25:1428 | this access | +| UseUseExplosion.cs:25:1408:25:1411 | [post] this access | UseUseExplosion.cs:25:1963:25:1968 | this access | +| UseUseExplosion.cs:25:1408:25:1411 | access to property Prop | UseUseExplosion.cs:25:1408:25:1416 | ... > ... | +| UseUseExplosion.cs:25:1408:25:1411 | access to property Prop | UseUseExplosion.cs:25:1425:25:1428 | access to property Prop | +| UseUseExplosion.cs:25:1408:25:1411 | this access | UseUseExplosion.cs:25:1425:25:1428 | this access | +| UseUseExplosion.cs:25:1408:25:1411 | this access | UseUseExplosion.cs:25:1963:25:1968 | this access | +| UseUseExplosion.cs:25:1425:25:1428 | [post] this access | UseUseExplosion.cs:25:1442:25:1445 | this access | +| UseUseExplosion.cs:25:1425:25:1428 | [post] this access | UseUseExplosion.cs:25:1948:25:1953 | this access | +| UseUseExplosion.cs:25:1425:25:1428 | access to property Prop | UseUseExplosion.cs:25:1425:25:1433 | ... > ... | +| UseUseExplosion.cs:25:1425:25:1428 | access to property Prop | UseUseExplosion.cs:25:1442:25:1445 | access to property Prop | +| UseUseExplosion.cs:25:1425:25:1428 | this access | UseUseExplosion.cs:25:1442:25:1445 | this access | +| UseUseExplosion.cs:25:1425:25:1428 | this access | UseUseExplosion.cs:25:1948:25:1953 | this access | +| UseUseExplosion.cs:25:1442:25:1445 | [post] this access | UseUseExplosion.cs:25:1459:25:1462 | this access | +| UseUseExplosion.cs:25:1442:25:1445 | [post] this access | UseUseExplosion.cs:25:1933:25:1938 | this access | +| UseUseExplosion.cs:25:1442:25:1445 | access to property Prop | UseUseExplosion.cs:25:1442:25:1450 | ... > ... | +| UseUseExplosion.cs:25:1442:25:1445 | access to property Prop | UseUseExplosion.cs:25:1459:25:1462 | access to property Prop | +| UseUseExplosion.cs:25:1442:25:1445 | this access | UseUseExplosion.cs:25:1459:25:1462 | this access | +| UseUseExplosion.cs:25:1442:25:1445 | this access | UseUseExplosion.cs:25:1933:25:1938 | this access | +| UseUseExplosion.cs:25:1459:25:1462 | [post] this access | UseUseExplosion.cs:25:1476:25:1479 | this access | +| UseUseExplosion.cs:25:1459:25:1462 | [post] this access | UseUseExplosion.cs:25:1918:25:1923 | this access | +| UseUseExplosion.cs:25:1459:25:1462 | access to property Prop | UseUseExplosion.cs:25:1459:25:1467 | ... > ... | +| UseUseExplosion.cs:25:1459:25:1462 | access to property Prop | UseUseExplosion.cs:25:1476:25:1479 | access to property Prop | +| UseUseExplosion.cs:25:1459:25:1462 | this access | UseUseExplosion.cs:25:1476:25:1479 | this access | +| UseUseExplosion.cs:25:1459:25:1462 | this access | UseUseExplosion.cs:25:1918:25:1923 | this access | +| UseUseExplosion.cs:25:1476:25:1479 | [post] this access | UseUseExplosion.cs:25:1493:25:1496 | this access | +| UseUseExplosion.cs:25:1476:25:1479 | [post] this access | UseUseExplosion.cs:25:1903:25:1908 | this access | +| UseUseExplosion.cs:25:1476:25:1479 | access to property Prop | UseUseExplosion.cs:25:1476:25:1484 | ... > ... | +| UseUseExplosion.cs:25:1476:25:1479 | access to property Prop | UseUseExplosion.cs:25:1493:25:1496 | access to property Prop | +| UseUseExplosion.cs:25:1476:25:1479 | this access | UseUseExplosion.cs:25:1493:25:1496 | this access | +| UseUseExplosion.cs:25:1476:25:1479 | this access | UseUseExplosion.cs:25:1903:25:1908 | this access | +| UseUseExplosion.cs:25:1493:25:1496 | [post] this access | UseUseExplosion.cs:25:1510:25:1513 | this access | +| UseUseExplosion.cs:25:1493:25:1496 | [post] this access | UseUseExplosion.cs:25:1888:25:1893 | this access | +| UseUseExplosion.cs:25:1493:25:1496 | access to property Prop | UseUseExplosion.cs:25:1493:25:1501 | ... > ... | +| UseUseExplosion.cs:25:1493:25:1496 | access to property Prop | UseUseExplosion.cs:25:1510:25:1513 | access to property Prop | +| UseUseExplosion.cs:25:1493:25:1496 | this access | UseUseExplosion.cs:25:1510:25:1513 | this access | +| UseUseExplosion.cs:25:1493:25:1496 | this access | UseUseExplosion.cs:25:1888:25:1893 | this access | +| UseUseExplosion.cs:25:1510:25:1513 | [post] this access | UseUseExplosion.cs:25:1527:25:1530 | this access | +| UseUseExplosion.cs:25:1510:25:1513 | [post] this access | UseUseExplosion.cs:25:1873:25:1878 | this access | +| UseUseExplosion.cs:25:1510:25:1513 | access to property Prop | UseUseExplosion.cs:25:1510:25:1518 | ... > ... | +| UseUseExplosion.cs:25:1510:25:1513 | access to property Prop | UseUseExplosion.cs:25:1527:25:1530 | access to property Prop | +| UseUseExplosion.cs:25:1510:25:1513 | this access | UseUseExplosion.cs:25:1527:25:1530 | this access | +| UseUseExplosion.cs:25:1510:25:1513 | this access | UseUseExplosion.cs:25:1873:25:1878 | this access | +| UseUseExplosion.cs:25:1527:25:1530 | [post] this access | UseUseExplosion.cs:25:1544:25:1547 | this access | +| UseUseExplosion.cs:25:1527:25:1530 | [post] this access | UseUseExplosion.cs:25:1858:25:1863 | this access | +| UseUseExplosion.cs:25:1527:25:1530 | access to property Prop | UseUseExplosion.cs:25:1527:25:1535 | ... > ... | +| UseUseExplosion.cs:25:1527:25:1530 | access to property Prop | UseUseExplosion.cs:25:1544:25:1547 | access to property Prop | +| UseUseExplosion.cs:25:1527:25:1530 | this access | UseUseExplosion.cs:25:1544:25:1547 | this access | +| UseUseExplosion.cs:25:1527:25:1530 | this access | UseUseExplosion.cs:25:1858:25:1863 | this access | +| UseUseExplosion.cs:25:1544:25:1547 | [post] this access | UseUseExplosion.cs:25:1561:25:1564 | this access | +| UseUseExplosion.cs:25:1544:25:1547 | [post] this access | UseUseExplosion.cs:25:1843:25:1848 | this access | +| UseUseExplosion.cs:25:1544:25:1547 | access to property Prop | UseUseExplosion.cs:25:1544:25:1552 | ... > ... | +| UseUseExplosion.cs:25:1544:25:1547 | access to property Prop | UseUseExplosion.cs:25:1561:25:1564 | access to property Prop | +| UseUseExplosion.cs:25:1544:25:1547 | this access | UseUseExplosion.cs:25:1561:25:1564 | this access | +| UseUseExplosion.cs:25:1544:25:1547 | this access | UseUseExplosion.cs:25:1843:25:1848 | this access | +| UseUseExplosion.cs:25:1561:25:1564 | [post] this access | UseUseExplosion.cs:25:1577:25:1580 | this access | +| UseUseExplosion.cs:25:1561:25:1564 | [post] this access | UseUseExplosion.cs:25:1828:25:1833 | this access | +| UseUseExplosion.cs:25:1561:25:1564 | access to property Prop | UseUseExplosion.cs:25:1561:25:1568 | ... > ... | +| UseUseExplosion.cs:25:1561:25:1564 | access to property Prop | UseUseExplosion.cs:25:1577:25:1580 | access to property Prop | +| UseUseExplosion.cs:25:1561:25:1564 | this access | UseUseExplosion.cs:25:1577:25:1580 | this access | +| UseUseExplosion.cs:25:1561:25:1564 | this access | UseUseExplosion.cs:25:1828:25:1833 | this access | +| UseUseExplosion.cs:25:1577:25:1580 | [post] this access | UseUseExplosion.cs:25:1593:25:1596 | this access | +| UseUseExplosion.cs:25:1577:25:1580 | [post] this access | UseUseExplosion.cs:25:1813:25:1818 | this access | +| UseUseExplosion.cs:25:1577:25:1580 | access to property Prop | UseUseExplosion.cs:25:1577:25:1584 | ... > ... | +| UseUseExplosion.cs:25:1577:25:1580 | access to property Prop | UseUseExplosion.cs:25:1593:25:1596 | access to property Prop | +| UseUseExplosion.cs:25:1577:25:1580 | this access | UseUseExplosion.cs:25:1593:25:1596 | this access | +| UseUseExplosion.cs:25:1577:25:1580 | this access | UseUseExplosion.cs:25:1813:25:1818 | this access | +| UseUseExplosion.cs:25:1593:25:1596 | [post] this access | UseUseExplosion.cs:25:1609:25:1612 | this access | +| UseUseExplosion.cs:25:1593:25:1596 | [post] this access | UseUseExplosion.cs:25:1798:25:1803 | this access | +| UseUseExplosion.cs:25:1593:25:1596 | access to property Prop | UseUseExplosion.cs:25:1593:25:1600 | ... > ... | +| UseUseExplosion.cs:25:1593:25:1596 | access to property Prop | UseUseExplosion.cs:25:1609:25:1612 | access to property Prop | +| UseUseExplosion.cs:25:1593:25:1596 | this access | UseUseExplosion.cs:25:1609:25:1612 | this access | +| UseUseExplosion.cs:25:1593:25:1596 | this access | UseUseExplosion.cs:25:1798:25:1803 | this access | +| UseUseExplosion.cs:25:1609:25:1612 | [post] this access | UseUseExplosion.cs:25:1625:25:1628 | this access | +| UseUseExplosion.cs:25:1609:25:1612 | [post] this access | UseUseExplosion.cs:25:1783:25:1788 | this access | +| UseUseExplosion.cs:25:1609:25:1612 | access to property Prop | UseUseExplosion.cs:25:1609:25:1616 | ... > ... | +| UseUseExplosion.cs:25:1609:25:1612 | access to property Prop | UseUseExplosion.cs:25:1625:25:1628 | access to property Prop | +| UseUseExplosion.cs:25:1609:25:1612 | this access | UseUseExplosion.cs:25:1625:25:1628 | this access | +| UseUseExplosion.cs:25:1609:25:1612 | this access | UseUseExplosion.cs:25:1783:25:1788 | this access | +| UseUseExplosion.cs:25:1625:25:1628 | [post] this access | UseUseExplosion.cs:25:1641:25:1644 | this access | +| UseUseExplosion.cs:25:1625:25:1628 | [post] this access | UseUseExplosion.cs:25:1768:25:1773 | this access | +| UseUseExplosion.cs:25:1625:25:1628 | access to property Prop | UseUseExplosion.cs:25:1625:25:1632 | ... > ... | +| UseUseExplosion.cs:25:1625:25:1628 | access to property Prop | UseUseExplosion.cs:25:1641:25:1644 | access to property Prop | +| UseUseExplosion.cs:25:1625:25:1628 | this access | UseUseExplosion.cs:25:1641:25:1644 | this access | +| UseUseExplosion.cs:25:1625:25:1628 | this access | UseUseExplosion.cs:25:1768:25:1773 | this access | +| UseUseExplosion.cs:25:1641:25:1644 | [post] this access | UseUseExplosion.cs:25:1657:25:1660 | this access | +| UseUseExplosion.cs:25:1641:25:1644 | [post] this access | UseUseExplosion.cs:25:1753:25:1758 | this access | +| UseUseExplosion.cs:25:1641:25:1644 | access to property Prop | UseUseExplosion.cs:25:1641:25:1648 | ... > ... | +| UseUseExplosion.cs:25:1641:25:1644 | access to property Prop | UseUseExplosion.cs:25:1657:25:1660 | access to property Prop | +| UseUseExplosion.cs:25:1641:25:1644 | this access | UseUseExplosion.cs:25:1657:25:1660 | this access | +| UseUseExplosion.cs:25:1641:25:1644 | this access | UseUseExplosion.cs:25:1753:25:1758 | this access | +| UseUseExplosion.cs:25:1657:25:1660 | [post] this access | UseUseExplosion.cs:25:1673:25:1676 | this access | +| UseUseExplosion.cs:25:1657:25:1660 | [post] this access | UseUseExplosion.cs:25:1738:25:1743 | this access | +| UseUseExplosion.cs:25:1657:25:1660 | access to property Prop | UseUseExplosion.cs:25:1657:25:1664 | ... > ... | +| UseUseExplosion.cs:25:1657:25:1660 | access to property Prop | UseUseExplosion.cs:25:1673:25:1676 | access to property Prop | +| UseUseExplosion.cs:25:1657:25:1660 | this access | UseUseExplosion.cs:25:1673:25:1676 | this access | +| UseUseExplosion.cs:25:1657:25:1660 | this access | UseUseExplosion.cs:25:1738:25:1743 | this access | +| UseUseExplosion.cs:25:1673:25:1676 | [post] this access | UseUseExplosion.cs:25:1689:25:1692 | this access | +| UseUseExplosion.cs:25:1673:25:1676 | [post] this access | UseUseExplosion.cs:25:1723:25:1728 | this access | +| UseUseExplosion.cs:25:1673:25:1676 | access to property Prop | UseUseExplosion.cs:25:1673:25:1680 | ... > ... | +| UseUseExplosion.cs:25:1673:25:1676 | access to property Prop | UseUseExplosion.cs:25:1689:25:1692 | access to property Prop | +| UseUseExplosion.cs:25:1673:25:1676 | this access | UseUseExplosion.cs:25:1689:25:1692 | this access | +| UseUseExplosion.cs:25:1673:25:1676 | this access | UseUseExplosion.cs:25:1723:25:1728 | this access | +| UseUseExplosion.cs:25:1689:25:1692 | [post] this access | UseUseExplosion.cs:25:1708:25:1713 | this access | +| UseUseExplosion.cs:25:1689:25:1692 | access to property Prop | UseUseExplosion.cs:25:1689:25:1696 | ... > ... | +| UseUseExplosion.cs:25:1689:25:1692 | this access | UseUseExplosion.cs:25:1708:25:1713 | this access | diff --git a/csharp/ql/test/library-tests/dataflow/local/UseUseExplosion.cs b/csharp/ql/test/library-tests/dataflow/local/UseUseExplosion.cs new file mode 100644 index 00000000000..b062aeba8f5 --- /dev/null +++ b/csharp/ql/test/library-tests/dataflow/local/UseUseExplosion.cs @@ -0,0 +1,29 @@ +class C +{ + int Prop { get; set; } + + // Should generate 100 + 100 local use-use flow steps for `x`, and not 100 * 100 + // + // Generated by quick-evaling `gen/0` below: + // + // ```ql + // string gen(int depth) { + // depth in [0 .. 100] and + // ( + // if depth = 0 + // then result = "" + // else result = "if (Prop > " + depth + ") { " + gen(depth - 1) + " } else Use(x);" + // ) + // } + // + // string gen() { result = "var x = 0;\n" + gen(100) + "\n" + gen(100) } + // ``` + void M() + { + var x = 0; + if (Prop > 100) { if (Prop > 99) { if (Prop > 98) { if (Prop > 97) { if (Prop > 96) { if (Prop > 95) { if (Prop > 94) { if (Prop > 93) { if (Prop > 92) { if (Prop > 91) { if (Prop > 90) { if (Prop > 89) { if (Prop > 88) { if (Prop > 87) { if (Prop > 86) { if (Prop > 85) { if (Prop > 84) { if (Prop > 83) { if (Prop > 82) { if (Prop > 81) { if (Prop > 80) { if (Prop > 79) { if (Prop > 78) { if (Prop > 77) { if (Prop > 76) { if (Prop > 75) { if (Prop > 74) { if (Prop > 73) { if (Prop > 72) { if (Prop > 71) { if (Prop > 70) { if (Prop > 69) { if (Prop > 68) { if (Prop > 67) { if (Prop > 66) { if (Prop > 65) { if (Prop > 64) { if (Prop > 63) { if (Prop > 62) { if (Prop > 61) { if (Prop > 60) { if (Prop > 59) { if (Prop > 58) { if (Prop > 57) { if (Prop > 56) { if (Prop > 55) { if (Prop > 54) { if (Prop > 53) { if (Prop > 52) { if (Prop > 51) { if (Prop > 50) { if (Prop > 49) { if (Prop > 48) { if (Prop > 47) { if (Prop > 46) { if (Prop > 45) { if (Prop > 44) { if (Prop > 43) { if (Prop > 42) { if (Prop > 41) { if (Prop > 40) { if (Prop > 39) { if (Prop > 38) { if (Prop > 37) { if (Prop > 36) { if (Prop > 35) { if (Prop > 34) { if (Prop > 33) { if (Prop > 32) { if (Prop > 31) { if (Prop > 30) { if (Prop > 29) { if (Prop > 28) { if (Prop > 27) { if (Prop > 26) { if (Prop > 25) { if (Prop > 24) { if (Prop > 23) { if (Prop > 22) { if (Prop > 21) { if (Prop > 20) { if (Prop > 19) { if (Prop > 18) { if (Prop > 17) { if (Prop > 16) { if (Prop > 15) { if (Prop > 14) { if (Prop > 13) { if (Prop > 12) { if (Prop > 11) { if (Prop > 10) { if (Prop > 9) { if (Prop > 8) { if (Prop > 7) { if (Prop > 6) { if (Prop > 5) { if (Prop > 4) { if (Prop > 3) { if (Prop > 2) { if (Prop > 1) { } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); + if (Prop > 100) { if (Prop > 99) { if (Prop > 98) { if (Prop > 97) { if (Prop > 96) { if (Prop > 95) { if (Prop > 94) { if (Prop > 93) { if (Prop > 92) { if (Prop > 91) { if (Prop > 90) { if (Prop > 89) { if (Prop > 88) { if (Prop > 87) { if (Prop > 86) { if (Prop > 85) { if (Prop > 84) { if (Prop > 83) { if (Prop > 82) { if (Prop > 81) { if (Prop > 80) { if (Prop > 79) { if (Prop > 78) { if (Prop > 77) { if (Prop > 76) { if (Prop > 75) { if (Prop > 74) { if (Prop > 73) { if (Prop > 72) { if (Prop > 71) { if (Prop > 70) { if (Prop > 69) { if (Prop > 68) { if (Prop > 67) { if (Prop > 66) { if (Prop > 65) { if (Prop > 64) { if (Prop > 63) { if (Prop > 62) { if (Prop > 61) { if (Prop > 60) { if (Prop > 59) { if (Prop > 58) { if (Prop > 57) { if (Prop > 56) { if (Prop > 55) { if (Prop > 54) { if (Prop > 53) { if (Prop > 52) { if (Prop > 51) { if (Prop > 50) { if (Prop > 49) { if (Prop > 48) { if (Prop > 47) { if (Prop > 46) { if (Prop > 45) { if (Prop > 44) { if (Prop > 43) { if (Prop > 42) { if (Prop > 41) { if (Prop > 40) { if (Prop > 39) { if (Prop > 38) { if (Prop > 37) { if (Prop > 36) { if (Prop > 35) { if (Prop > 34) { if (Prop > 33) { if (Prop > 32) { if (Prop > 31) { if (Prop > 30) { if (Prop > 29) { if (Prop > 28) { if (Prop > 27) { if (Prop > 26) { if (Prop > 25) { if (Prop > 24) { if (Prop > 23) { if (Prop > 22) { if (Prop > 21) { if (Prop > 20) { if (Prop > 19) { if (Prop > 18) { if (Prop > 17) { if (Prop > 16) { if (Prop > 15) { if (Prop > 14) { if (Prop > 13) { if (Prop > 12) { if (Prop > 11) { if (Prop > 10) { if (Prop > 9) { if (Prop > 8) { if (Prop > 7) { if (Prop > 6) { if (Prop > 5) { if (Prop > 4) { if (Prop > 3) { if (Prop > 2) { if (Prop > 1) { } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); + } + + void Use(int i) { } +} diff --git a/csharp/ql/test/library-tests/dataflow/ssa-large/Large.cs b/csharp/ql/test/library-tests/dataflow/ssa-large/Large.cs index f6cce7f149a..798f106e9f6 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa-large/Large.cs +++ b/csharp/ql/test/library-tests/dataflow/ssa-large/Large.cs @@ -2886,7 +2886,7 @@ public class Large // ( // if depth = 0 // then result = "" - // else else result = "if (Prop > " + depth + ") { " + gen(depth - 1, var) + " } else Use(" + var + ");" + // else result = "if (Prop > " + depth + ") { " + gen(depth - 1, var) + " } else Use(" + var + ");" // ) // } // From 811426c586ea0d0d9fd8869cce729fbc62a30c37 Mon Sep 17 00:00:00 2001 From: Taus Date: Thu, 17 Nov 2022 14:15:55 +0000 Subject: [PATCH 341/796] Python: Remove manual magic entirely This was causing issues with imports with many "dots" in the name. Previously, the test added in this commit would not have the desired result for the `check` call. --- .../semmle/python/dataflow/new/internal/ImportResolution.qll | 1 - python/ql/test/experimental/import-resolution/main.py | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll index 53f41bd945e..320ec8d998e 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -231,7 +231,6 @@ module ImportResolution { // Reading an attribute on a module may return a submodule (or subpackage). exists(DataFlow::AttrRead ar, Module p, string attr_name | ar.accesses(getModuleReference(p), attr_name) and - attr_name = any(Module m0).getFile().getStem() and result = ar | isPreferredModuleForName(m.getFile(), p.getPackageName() + "." + attr_name + ["", ".__init__"]) diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index 27c6ffff7c1..45c84559fb6 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -69,6 +69,11 @@ check("aliased_subpackage.subpackage_attr", aliased_subpackage.subpackage_attr, import package.subpackage #$ imports=package.__init__ as=package check("package.package_attr", package.package_attr, "package_attr", globals()) #$ prints=package_attr +# Deep imports +import package.subpackage.submodule #$ imports=package.__init__ as=package +check("package.subpackage.submodule.submodule_attr", package.subpackage.submodule.submodule_attr, "submodule_attr", globals()) #$ prints=submodule_attr + + if sys.version_info[0] == 3: # Importing from a namespace module. from namespace_package.namespace_module import namespace_module_attr From dae60c9debae2e9e58813e14d05b4784bb341cf0 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 20 Oct 2022 13:04:39 +0100 Subject: [PATCH 342/796] Update data flow libraries to 55e052af26 --- .../go/dataflow/internal/AccessPathSyntax.qll | 105 +- .../go/dataflow/internal/DataFlowImpl.qll | 2121 +++++++++++------ .../go/dataflow/internal/DataFlowImpl2.qll | 2117 ++++++++++------ .../dataflow/internal/DataFlowImplCommon.qll | 137 +- .../go/dataflow/internal/FlowSummaryImpl.qll | 302 ++- .../tainttracking1/TaintTrackingImpl.qll | 72 +- .../tainttracking2/TaintTrackingImpl.qll | 72 +- 7 files changed, 3351 insertions(+), 1575 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/AccessPathSyntax.qll b/go/ql/lib/semmle/go/dataflow/internal/AccessPathSyntax.qll index ecb6f542955..076e12f2671 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/AccessPathSyntax.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/AccessPathSyntax.qll @@ -6,6 +6,15 @@ * (which does not use the shared data flow libraries). */ +/** + * Convenience-predicate for extracting two capture groups at once. + */ +bindingset[input, regexp] +private predicate regexpCaptureTwo(string input, string regexp, string capture1, string capture2) { + capture1 = input.regexpCapture(regexp, 1) and + capture2 = input.regexpCapture(regexp, 2) +} + /** Companion module to the `AccessPath` class. */ module AccessPath { /** A string that should be parsed as an access path. */ @@ -13,6 +22,93 @@ module AccessPath { bindingset[this] Range() { any() } } + + /** + * Parses an integer constant `n` or interval `n1..n2` (inclusive) and gets the value + * of the constant or any value contained in the interval. + */ + bindingset[arg] + int parseInt(string arg) { + result = arg.toInt() + or + // Match "n1..n2" + exists(string lo, string hi | + regexpCaptureTwo(arg, "(-?\\d+)\\.\\.(-?\\d+)", lo, hi) and + result = [lo.toInt() .. hi.toInt()] + ) + } + + /** + * Parses a lower-bounded interval `n..` and gets the lower bound. + */ + bindingset[arg] + int parseLowerBound(string arg) { result = arg.regexpCapture("(-?\\d+)\\.\\.", 1).toInt() } + + /** + * Parses an integer constant or interval (bounded or unbounded) that explicitly + * references the arity, such as `N-1` or `N-3..N-1`. + * + * Note that expressions of form `N-x` will never resolve to a negative index, + * even if `N` is zero (it will have no result in that case). + */ + bindingset[arg, arity] + private int parseIntWithExplicitArity(string arg, int arity) { + result >= 0 and // do not allow N-1 to resolve to a negative index + exists(string lo | + // N-x + lo = arg.regexpCapture("N-(\\d+)", 1) and + result = arity - lo.toInt() + or + // N-x.. + lo = arg.regexpCapture("N-(\\d+)\\.\\.", 1) and + result = [arity - lo.toInt(), arity - 1] + ) + or + exists(string lo, string hi | + // x..N-y + regexpCaptureTwo(arg, "(-?\\d+)\\.\\.N-(\\d+)", lo, hi) and + result = [lo.toInt() .. arity - hi.toInt()] + or + // N-x..N-y + regexpCaptureTwo(arg, "N-(\\d+)\\.\\.N-(\\d+)", lo, hi) and + result = [arity - lo.toInt() .. arity - hi.toInt()] and + result >= 0 + or + // N-x..y + regexpCaptureTwo(arg, "N-(\\d+)\\.\\.(\\d+)", lo, hi) and + result = [arity - lo.toInt() .. hi.toInt()] and + result >= 0 + ) + } + + /** + * Parses an integer constant or interval (bounded or unbounded) and gets any + * of the integers contained within (of which there may be infinitely many). + * + * Has no result for arguments involving an explicit arity, such as `N-1`. + */ + bindingset[arg, result] + int parseIntUnbounded(string arg) { + result = parseInt(arg) + or + result >= parseLowerBound(arg) + } + + /** + * Parses an integer constant or interval (bounded or unbounded) that + * may reference the arity of a call, such as `N-1` or `N-3..N-1`. + * + * Note that expressions of form `N-x` will never resolve to a negative index, + * even if `N` is zero (it will have no result in that case). + */ + bindingset[arg, arity] + int parseIntWithArity(string arg, int arity) { + result = parseInt(arg) + or + result in [parseLowerBound(arg) .. arity - 1] + or + result = parseIntWithExplicitArity(arg, arity) + } } /** Gets the `n`th token on the access path as a string. */ @@ -53,7 +149,7 @@ class AccessPath extends string instanceof AccessPath::Range { * An access part token such as `Argument[1]` or `ReturnValue`, appearing in one or more access paths. */ class AccessPathToken extends string { - AccessPathToken() { this = getRawToken(any(AccessPath path), _) } + AccessPathToken() { this = getRawToken(_, _) } private string getPart(int part) { result = this.regexpCapture("([^\\[]+)(?:\\[([^\\]]*)\\])?", part) @@ -71,9 +167,16 @@ class AccessPathToken extends string { /** Gets the `n`th argument to this token, such as `x` or `y` from `Member[x,y]`. */ string getArgument(int n) { result = this.getArgumentList().splitAt(",", n).trim() } + /** Gets the `n`th argument to this `name` token, such as `x` or `y` from `Member[x,y]`. */ + pragma[nomagic] + string getArgument(string name, int n) { name = this.getName() and result = this.getArgument(n) } + /** Gets an argument to this token, such as `x` or `y` from `Member[x,y]`. */ string getAnArgument() { result = this.getArgument(_) } + /** Gets an argument to this `name` token, such as `x` or `y` from `Member[x,y]`. */ + string getAnArgument(string name) { result = this.getArgument(name, _) } + /** Gets the number of arguments to this token, such as 2 for `Member[x,y]` or zero for `ReturnValue`. */ int getNumArgument() { result = count(int n | exists(this.getArgument(n))) } } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index bf150f191ed..a076f7a2e45 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -54,12 +54,23 @@ abstract class Configuration extends string { /** * Holds if `source` is a relevant data flow source. */ - abstract predicate isSource(Node source); + predicate isSource(Node source) { none() } + + /** + * Holds if `source` is a relevant data flow source with the given initial + * `state`. + */ + predicate isSource(Node source, FlowState state) { none() } /** * Holds if `sink` is a relevant data flow sink. */ - abstract predicate isSink(Node sink); + predicate isSink(Node sink) { none() } + + /** + * Holds if `sink` is a relevant data flow sink accepting `state`. + */ + predicate isSink(Node source, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -67,6 +78,12 @@ abstract class Configuration extends string { */ predicate isBarrier(Node node) { none() } + /** + * Holds if data flow through `node` is prohibited when the flow state is + * `state`. + */ + predicate isBarrier(Node node, FlowState state) { none() } + /** Holds if data flow into `node` is prohibited. */ predicate isBarrierIn(Node node) { none() } @@ -81,16 +98,31 @@ abstract class Configuration extends string { deprecated predicate isBarrierGuard(BarrierGuard guard) { none() } /** - * Holds if the additional flow step from `node1` to `node2` must be taken - * into account in the analysis. + * DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead. + * + * Holds if data flow through nodes guarded by `guard` is prohibited when + * the flow state is `state` + */ + deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() } + + /** + * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. */ predicate isAdditionalFlowStep(Node node1, Node node2) { none() } + /** + * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. + * This step is only applicable in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + none() + } + /** * Holds if an arbitrary number of implicit read steps of content `c` may be * taken at `node`. */ - predicate allowImplicitRead(Node node, Content c) { none() } + predicate allowImplicitRead(Node node, ContentSet c) { none() } /** * Gets the virtual dispatch branching limit when calculating field flow. @@ -144,6 +176,14 @@ abstract class Configuration extends string { */ int explorationLimit() { none() } + /** + * Holds if hidden nodes should be included in the data flow graph. + * + * This feature should only be used for debugging or when the data flow graph + * is not visualized (for example in a `path-problem` query). + */ + predicate includeHiddenNodes() { none() } + /** * Holds if there is a partial data flow path from `source` to `node`. The * approximate distance between `node` and the closest source is `dist` and @@ -201,10 +241,16 @@ abstract private class ConfigurationRecursionPrevention extends Configuration { override predicate hasFlow(Node source, Node sink) { strictcount(Node n | this.isSource(n)) < 0 or + strictcount(Node n | this.isSource(n, _)) < 0 + or strictcount(Node n | this.isSink(n)) < 0 or + strictcount(Node n | this.isSink(n, _)) < 0 + or strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 or + strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 + or super.hasFlow(source, sink) } } @@ -260,11 +306,11 @@ private class ArgNodeEx extends NodeEx { private class ParamNodeEx extends NodeEx { ParamNodeEx() { this.asNode() instanceof ParamNode } - predicate isParameterOf(DataFlowCallable c, int i) { - this.asNode().(ParamNode).isParameterOf(c, i) + predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { + this.asNode().(ParamNode).isParameterOf(c, pos) } - int getPosition() { this.isParameterOf(_, result) } + ParameterPosition getPosition() { this.isParameterOf(_, result) } predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } @@ -280,22 +326,26 @@ private class RetNodeEx extends NodeEx { private predicate inBarrier(NodeEx node, Configuration config) { exists(Node n | node.asNode() = n and - config.isBarrierIn(n) and - config.isSource(n) + config.isBarrierIn(n) + | + config.isSource(n) or config.isSource(n, _) ) } private predicate outBarrier(NodeEx node, Configuration config) { exists(Node n | node.asNode() = n and - config.isBarrierOut(n) and - config.isSink(n) + config.isBarrierOut(n) + | + config.isSink(n) or config.isSink(n, _) ) } /** A bridge class to access the deprecated `isBarrierGuard`. */ private class BarrierGuardGuardedNodeBridge extends Unit { abstract predicate guardedNode(Node n, Configuration config); + + abstract predicate guardedNode(Node n, FlowState state, Configuration config); } private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge { @@ -305,6 +355,13 @@ private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge { n = g.getAGuardedNode() ) } + + deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) { + exists(BarrierGuard g | + config.isBarrierGuard(g, state) and + n = g.getAGuardedNode() + ) + } } pragma[nomagic] @@ -313,23 +370,47 @@ private predicate fullBarrier(NodeEx node, Configuration config) { config.isBarrier(n) or config.isBarrierIn(n) and - not config.isSource(n) + not config.isSource(n) and + not config.isSource(n, _) or config.isBarrierOut(n) and - not config.isSink(n) + not config.isSink(n) and + not config.isSink(n, _) or any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config) ) } pragma[nomagic] -private predicate sourceNode(NodeEx node, Configuration config) { - config.isSource(node.asNode()) and - not fullBarrier(node, config) +private predicate stateBarrier(NodeEx node, FlowState state, Configuration config) { + exists(Node n | node.asNode() = n | + config.isBarrier(n, state) + or + any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config) + ) } pragma[nomagic] -private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) } +private predicate sourceNode(NodeEx node, FlowState state, Configuration config) { + ( + config.isSource(node.asNode()) and state instanceof FlowStateEmpty + or + config.isSource(node.asNode(), state) + ) and + not fullBarrier(node, config) and + not stateBarrier(node, state, config) +} + +pragma[nomagic] +private predicate sinkNode(NodeEx node, FlowState state, Configuration config) { + ( + config.isSink(node.asNode()) and state instanceof FlowStateEmpty + or + config.isSink(node.asNode(), state) + ) and + not fullBarrier(node, config) and + not stateBarrier(node, state, config) +} /** Provides the relevant barriers for a step from `node1` to `node2`. */ pragma[inline] @@ -366,8 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - pragma[only_bind_into](config) - .isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -380,6 +460,20 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat ) } +private predicate additionalLocalStateStep( + NodeEx node1, FlowState s1, NodeEx node2, FlowState s2, Configuration config +) { + exists(Node n1, Node n2 | + node1.asNode() = n1 and + node2.asNode() = n2 and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and + getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and + stepFilter(node1, node2, config) and + not stateBarrier(node1, s1, config) and + not stateBarrier(node2, s2, config) + ) +} + /** * Holds if data can flow from `node1` to `node2` in a way that discards call contexts. */ @@ -400,21 +494,32 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - pragma[only_bind_into](config) - .isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) } -private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) { +private predicate additionalJumpStateStep( + NodeEx node1, FlowState s1, NodeEx node2, FlowState s2, Configuration config +) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - read(pragma[only_bind_into](n1), c, pragma[only_bind_into](n2)) and - stepFilter(node1, node2, config) + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and + getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and + stepFilter(node1, node2, config) and + not stateBarrier(node1, s1, config) and + not stateBarrier(node2, s2, config) and + not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) +} + +pragma[nomagic] +private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and + stepFilter(node1, node2, config) or exists(Node n | node2.isImplicitReadNode(n, true) and @@ -423,16 +528,44 @@ private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration conf ) } +// inline to reduce fan-out via `getAReadContent` +bindingset[c] +private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) { + exists(ContentSet cs | + readSet(node1, cs, node2, config) and + pragma[only_bind_out](c) = pragma[only_bind_into](cs).getAReadContent() + ) +} + +// inline to reduce fan-out via `getAReadContent` +bindingset[c] +private predicate clearsContentEx(NodeEx n, Content c) { + exists(ContentSet cs | + clearsContentCached(n.asNode(), cs) and + pragma[only_bind_out](c) = pragma[only_bind_into](cs).getAReadContent() + ) +} + +// inline to reduce fan-out via `getAReadContent` +bindingset[c] +private predicate expectsContentEx(NodeEx n, Content c) { + exists(ContentSet cs | + expectsContentCached(n.asNode(), cs) and + pragma[only_bind_out](c) = pragma[only_bind_into](cs).getAReadContent() + ) +} + +pragma[nomagic] +private predicate notExpectsContent(NodeEx n) { not expectsContentCached(n.asNode(), _) } + +pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - exists(Node n1, Node n2 | - node1.asNode() = n1 and - node2.asNode() = n2 and - store(pragma[only_bind_into](n1), tc, pragma[only_bind_into](n2), contentType) and - read(_, tc.getContent(), _, config) and - stepFilter(node1, node2, config) - ) + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and + read(_, tc.getContent(), _, config) and + stepFilter(node1, node2, config) } pragma[nomagic] @@ -481,29 +614,19 @@ private module Stage1 { * argument in a call. */ predicate fwdFlow(NodeEx node, Cc cc, Configuration config) { - sourceNode(node, config) and + sourceNode(node, _, config) and if hasSourceCallCtx(config) then cc = true else cc = false or - exists(NodeEx mid | - fwdFlow(mid, cc, config) and - localFlowStep(mid, node, config) + exists(NodeEx mid | fwdFlow(mid, cc, config) | + localFlowStep(mid, node, config) or + additionalLocalFlowStep(mid, node, config) or + additionalLocalStateStep(mid, _, node, _, config) ) or - exists(NodeEx mid | - fwdFlow(mid, cc, config) and - additionalLocalFlowStep(mid, node, config) - ) - or - exists(NodeEx mid | - fwdFlow(mid, _, config) and - jumpStep(mid, node, config) and - cc = false - ) - or - exists(NodeEx mid | - fwdFlow(mid, _, config) and - additionalJumpStep(mid, node, config) and - cc = false + exists(NodeEx mid | fwdFlow(mid, _, config) and cc = false | + jumpStep(mid, node, config) or + additionalJumpStep(mid, node, config) or + additionalJumpStateStep(mid, _, node, _, config) ) or // store @@ -514,9 +637,9 @@ private module Stage1 { ) or // read - exists(Content c | - fwdFlowRead(c, node, cc, config) and - fwdFlowConsCand(c, config) + exists(ContentSet c | + fwdFlowReadSet(c, node, cc, config) and + fwdFlowConsCandSet(c, _, config) ) or // flow into a callable @@ -540,10 +663,10 @@ private module Stage1 { private predicate fwdFlow(NodeEx node, Configuration config) { fwdFlow(node, _, config) } pragma[nomagic] - private predicate fwdFlowRead(Content c, NodeEx node, Cc cc, Configuration config) { + private predicate fwdFlowReadSet(ContentSet c, NodeEx node, Cc cc, Configuration config) { exists(NodeEx mid | fwdFlow(mid, cc, config) and - read(mid, c, node, config) + readSet(mid, c, node, config) ) } @@ -561,6 +684,16 @@ private module Stage1 { ) } + /** + * Holds if `cs` may be interpreted in a read as the target of some store + * into `c`, in the flow covered by `fwdFlow`. + */ + pragma[nomagic] + private predicate fwdFlowConsCandSet(ContentSet cs, Content c, Configuration config) { + fwdFlowConsCand(c, config) and + c = cs.getAReadContent() + } + pragma[nomagic] private predicate fwdFlowReturnPosition(ReturnPosition pos, Cc cc, Configuration config) { exists(RetNodeEx ret | @@ -594,6 +727,24 @@ private module Stage1 { ) } + private predicate stateStepFwd(FlowState state1, FlowState state2, Configuration config) { + exists(NodeEx node1 | + additionalLocalStateStep(node1, state1, _, state2, config) or + additionalJumpStateStep(node1, state1, _, state2, config) + | + fwdFlow(node1, config) + ) + } + + private predicate fwdFlowState(FlowState state, Configuration config) { + sourceNode(_, state, config) + or + exists(FlowState state0 | + fwdFlowState(state0, config) and + stateStepFwd(state0, state, config) + ) + } + /** * Holds if `node` is part of a path from a source to a sink in the * configuration `config`. @@ -609,30 +760,23 @@ private module Stage1 { pragma[nomagic] private predicate revFlow0(NodeEx node, boolean toReturn, Configuration config) { - fwdFlow(node, config) and - sinkNode(node, config) and - if hasSinkCallCtx(config) then toReturn = true else toReturn = false - or - exists(NodeEx mid | - localFlowStep(node, mid, config) and - revFlow(mid, toReturn, config) + exists(FlowState state | + fwdFlow(node, pragma[only_bind_into](config)) and + sinkNode(node, state, config) and + fwdFlowState(state, pragma[only_bind_into](config)) and + if hasSinkCallCtx(config) then toReturn = true else toReturn = false ) or - exists(NodeEx mid | - additionalLocalFlowStep(node, mid, config) and - revFlow(mid, toReturn, config) + exists(NodeEx mid | revFlow(mid, toReturn, config) | + localFlowStep(node, mid, config) or + additionalLocalFlowStep(node, mid, config) or + additionalLocalStateStep(node, _, mid, _, config) ) or - exists(NodeEx mid | - jumpStep(node, mid, config) and - revFlow(mid, _, config) and - toReturn = false - ) - or - exists(NodeEx mid | - additionalJumpStep(node, mid, config) and - revFlow(mid, _, config) and - toReturn = false + exists(NodeEx mid | revFlow(mid, _, config) and toReturn = false | + jumpStep(node, mid, config) or + additionalJumpStep(node, mid, config) or + additionalJumpStateStep(node, _, mid, _, config) ) or // store @@ -642,9 +786,9 @@ private module Stage1 { ) or // read - exists(NodeEx mid, Content c | - read(node, c, mid, config) and - fwdFlowConsCand(c, pragma[only_bind_into](config)) and + exists(NodeEx mid, ContentSet c | + readSet(node, c, mid, config) and + fwdFlowConsCandSet(c, _, pragma[only_bind_into](config)) and revFlow(mid, toReturn, pragma[only_bind_into](config)) ) or @@ -670,10 +814,10 @@ private module Stage1 { */ pragma[nomagic] private predicate revFlowConsCand(Content c, Configuration config) { - exists(NodeEx mid, NodeEx node | + exists(NodeEx mid, NodeEx node, ContentSet cs | fwdFlow(node, pragma[only_bind_into](config)) and - read(node, c, mid, config) and - fwdFlowConsCand(c, pragma[only_bind_into](config)) and + readSet(node, cs, mid, config) and + fwdFlowConsCandSet(cs, c, pragma[only_bind_into](config)) and revFlow(pragma[only_bind_into](mid), _, pragma[only_bind_into](config)) ) } @@ -692,7 +836,8 @@ private module Stage1 { * Holds if `c` is the target of both a read and a store in the flow covered * by `revFlow`. */ - private predicate revFlowIsReadAndStored(Content c, Configuration conf) { + pragma[nomagic] + predicate revFlowIsReadAndStored(Content c, Configuration conf) { revFlowConsCand(c, conf) and revFlowStore(c, _, _, conf) } @@ -749,6 +894,31 @@ private module Stage1 { ) } + private predicate stateStepRev(FlowState state1, FlowState state2, Configuration config) { + exists(NodeEx node1, NodeEx node2 | + additionalLocalStateStep(node1, state1, node2, state2, config) or + additionalJumpStateStep(node1, state1, node2, state2, config) + | + revFlow(node1, _, pragma[only_bind_into](config)) and + revFlow(node2, _, pragma[only_bind_into](config)) and + fwdFlowState(state1, pragma[only_bind_into](config)) and + fwdFlowState(state2, pragma[only_bind_into](config)) + ) + } + + predicate revFlowState(FlowState state, Configuration config) { + exists(NodeEx node | + sinkNode(node, state, config) and + revFlow(node, _, pragma[only_bind_into](config)) and + fwdFlowState(state, pragma[only_bind_into](config)) + ) + or + exists(FlowState state0 | + revFlowState(state0, config) and + stateStepRev(state, state0, config) + ) + } + pragma[nomagic] predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -766,15 +936,21 @@ private module Stage1 { pragma[nomagic] predicate readStepCand(NodeEx n1, Content c, NodeEx n2, Configuration config) { revFlowIsReadAndStored(c, pragma[only_bind_into](config)) and - revFlow(n2, pragma[only_bind_into](config)) and - read(n1, c, n2, pragma[only_bind_into](config)) + read(n1, c, n2, pragma[only_bind_into](config)) and + revFlow(n2, pragma[only_bind_into](config)) } pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } - predicate revFlow(NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config) { - revFlow(node, toReturn, config) and exists(returnAp) and exists(ap) + bindingset[node, state, config] + predicate revFlow( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + revFlow(node, toReturn, pragma[only_bind_into](config)) and + exists(state) and + exists(returnAp) and + exists(ap) } private predicate throughFlowNodeCand(NodeEx node, Configuration config) { @@ -825,17 +1001,21 @@ private module Stage1 { ) } - predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { + predicate stats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config + ) { fwd = true and nodes = count(NodeEx node | fwdFlow(node, config)) and fields = count(Content f0 | fwdFlowConsCand(f0, config)) and conscand = -1 and + states = count(FlowState state | fwdFlowState(state, config)) and tuples = count(NodeEx n, boolean b | fwdFlow(n, b, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, config)) and fields = count(Content f0 | revFlowConsCand(f0, config)) and conscand = -1 and + states = count(FlowState state | revFlowState(state, config)) and tuples = count(NodeEx n, boolean b | revFlow(n, b, config)) } /* End: Stage 1 logic. */ @@ -1016,18 +1196,26 @@ private module Stage2 { if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() } - bindingset[node, cc, config] - private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } + bindingset[node, cc] + private LocalCc getLocalCc(NodeEx node, Cc cc) { any() } + bindingset[node1, state1, config] + bindingset[node2, state2, config] private predicate localStep( - NodeEx node1, NodeEx node2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApNil ap, Configuration config, LocalCc lcc ) { ( preservesValue = true and - localFlowStepNodeCand1(node1, node2, config) + localFlowStepNodeCand1(node1, node2, config) and + state1 = state2 or preservesValue = false and - additionalLocalFlowStepNodeCand1(node1, node2, config) + additionalLocalFlowStepNodeCand1(node1, node2, config) and + state1 = state2 + or + preservesValue = false and + additionalLocalStateStep(node1, state1, node2, state2, config) ) and exists(ap) and exists(lcc) @@ -1037,22 +1225,40 @@ private module Stage2 { private predicate flowIntoCall = flowIntoCallNodeCand1/5; - bindingset[node, ap] - private predicate filter(NodeEx node, Ap ap) { any() } + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::revFlowIsReadAndStored(c, pragma[only_bind_into](config)) and + expectsContentEx(node, c) + ) + } + + bindingset[node, state, ap, config] + private predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + PrevStage::revFlowState(state, pragma[only_bind_into](config)) and + exists(ap) and + not stateBarrier(node, state, config) and + ( + notExpectsContent(node) + or + ap = true and + expectsContentCand(node, config) + ) + } bindingset[ap, contentType] private predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } /* Begin: Stage 2 logic. */ - private predicate flowCand(NodeEx node, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, _, _, apa, config) + bindingset[node, state, config] + private predicate flowCand(NodeEx node, FlowState state, ApApprox apa, Configuration config) { + PrevStage::revFlow(node, state, _, _, apa, config) } bindingset[result, apa] private ApApprox unbindApa(ApApprox apa) { - exists(ApApprox apa0 | - apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0) - ) + pragma[only_bind_out](apa) = pragma[only_bind_out](result) } pragma[nomagic] @@ -1076,63 +1282,70 @@ private module Stage2 { * argument. */ pragma[nomagic] - predicate fwdFlow(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, cc, argAp, ap, config) and - flowCand(node, unbindApa(getApprox(ap)), config) and - filter(node, ap) + predicate fwdFlow(NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config) { + fwdFlow0(node, state, cc, argAp, ap, config) and + flowCand(node, state, unbindApa(getApprox(ap)), config) and + filter(node, state, ap, config) } pragma[nomagic] - private predicate fwdFlow0(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - flowCand(node, _, config) and - sourceNode(node, config) and + private predicate fwdFlow0( + NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + ) { + sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and ap = getApNil(node) or - exists(NodeEx mid, Ap ap0, LocalCc localCc | - fwdFlow(mid, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc, config) + exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | + fwdFlow(mid, state0, cc, argAp, ap0, config) and + localCc = getLocalCc(mid, cc) | - localStep(mid, node, true, _, config, localCc) and + localStep(mid, state0, node, state, true, _, config, localCc) and ap = ap0 or - localStep(mid, node, false, ap, config, localCc) and + localStep(mid, state0, node, state, false, ap, config, localCc) and ap0 instanceof ApNil ) or exists(NodeEx mid | - fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and argAp = apNone() and ap = getApNil(node) ) or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + additionalJumpStateStep(mid, state0, node, state, config) and + cc = ccNone() and + argAp = apNone() and + ap = getApNil(node) + ) + or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, ap, config) and apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, _, apa, config) then argAp = apSome(ap) @@ -1140,20 +1353,21 @@ private module Stage2 { ) or // flow out of a callable - fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) or exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Cc cc, ApOption argAp, Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1166,7 +1380,7 @@ private module Stage2 { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1174,20 +1388,21 @@ private module Stage2 { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, Cc cc, ApOption argAp, Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + Configuration config ) { - fwdFlow(node1, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, Cc outercc, Cc innercc, ApOption argAp, Ap ap, - Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, + Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1196,13 +1411,13 @@ private module Stage2 { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, innercc, argAp, ap, config) and + fwdFlow(ret, state, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and @@ -1212,10 +1427,10 @@ private module Stage2 { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config ) { exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, ccc, apSome(argAp), ap, config) and + fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1230,7 +1445,7 @@ private module Stage2 { DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config ) { exists(ParamNodeEx p | - fwdFlowIn(call, p, cc, _, argAp, ap, config) and + fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) ) } @@ -1239,24 +1454,24 @@ private module Stage2 { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) @@ -1268,14 +1483,16 @@ private module Stage2 { DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } pragma[nomagic] - private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) { - fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config) + private predicate returnNodeMayFlowThrough( + RetNodeEx ret, FlowState state, Ap ap, Configuration config + ) { + fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) } /** @@ -1287,44 +1504,56 @@ private module Stage2 { * the access path of the returned value. */ pragma[nomagic] - predicate revFlow(NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config) { - revFlow0(node, toReturn, returnAp, ap, config) and - fwdFlow(node, _, _, ap, config) + predicate revFlow( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + revFlow0(node, state, toReturn, returnAp, ap, config) and + fwdFlow(node, state, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { - fwdFlow(node, _, _, ap, config) and - sinkNode(node, config) and + fwdFlow(node, state, _, _, ap, config) and + sinkNode(node, state, config) and (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and returnAp = apNone() and ap instanceof ApNil or - exists(NodeEx mid | - localStep(node, mid, true, _, config, _) and - revFlow(mid, toReturn, returnAp, ap, config) + exists(NodeEx mid, FlowState state0 | + localStep(node, state, mid, state0, true, _, config, _) and + revFlow(mid, state0, toReturn, returnAp, ap, config) ) or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - localStep(node, mid, false, _, config, _) and - revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and + revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and - revFlow(mid, _, _, ap, config) and + revFlow(mid, state, _, _, ap, config) and toReturn = false and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and + revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and + toReturn = false and + returnAp = apNone() and + ap instanceof ApNil + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + additionalJumpStateStep(node, state, mid, state0, config) and + revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, + pragma[only_bind_into](config)) and toReturn = false and returnAp = apNone() and ap instanceof ApNil @@ -1332,39 +1561,39 @@ private module Stage2 { or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, toReturn, returnAp, ap0, config) and + revFlow(mid, state, toReturn, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, returnAp, ap, config) and + revFlowInNotToReturn(node, state, returnAp, ap, config) and toReturn = false or exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowInToReturn(call, node, state, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, _, _, ap, config) and + revFlowOut(_, node, state, _, _, ap, config) and toReturn = true and - if returnNodeMayFlowThrough(node, ap, config) + if returnNodeMayFlowThrough(node, state, ap, config) then returnAp = apSome(ap) else returnAp = apNone() } pragma[nomagic] private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, TypedContent tc, NodeEx mid, boolean toReturn, - ApOption returnAp, Configuration config + Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, + boolean toReturn, ApOption returnAp, Configuration config ) { - revFlow(mid, toReturn, returnAp, ap0, config) and + revFlow(mid, state, toReturn, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1376,7 +1605,7 @@ private module Stage2 { pragma[nomagic] private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, tail, config) and + revFlow(mid, _, _, _, tail, config) and tail = pragma[only_bind_into](tail0) and readStepFwd(_, cons, c, mid, tail0, config) ) @@ -1384,11 +1613,11 @@ private module Stage2 { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, boolean toReturn, ApOption returnAp, Ap ap, + DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, toReturn, returnAp, ap, config) and + revFlow(out, state, toReturn, returnAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1396,10 +1625,10 @@ private module Stage2 { pragma[nomagic] private predicate revFlowInNotToReturn( - ArgNodeEx arg, ApOption returnAp, Ap ap, Configuration config + ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, false, returnAp, ap, config) and + revFlow(p, state, false, returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1407,10 +1636,10 @@ private module Stage2 { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, true, apSome(returnAp), ap, config) and + revFlow(p, state, true, apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1425,9 +1654,9 @@ private module Stage2 { private predicate revFlowIsReturned( DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { - exists(RetNodeEx ret, CcCall ccc | - revFlowOut(call, ret, toReturn, returnAp, ap, config) and - fwdFlow(ret, ccc, apSome(_), ap, config) and + exists(RetNodeEx ret, FlowState state, CcCall ccc | + revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and + fwdFlow(ret, state, ccc, apSome(_), ap, config) and ccc.matchesCall(call) ) } @@ -1438,46 +1667,77 @@ private module Stage2 { Configuration config ) { exists(Ap ap2, Content c | - store(node1, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, tc, node2, _, _, config) and + PrevStage::storeStepCand(node1, _, tc, node2, contentType, config) and + revFlowStore(ap2, c, ap1, node1, _, tc, node2, _, _, config) and revFlowConsCand(ap2, c, ap1, config) ) } predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and + revFlow(node2, _, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, + revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _, pragma[only_bind_into](config)) ) } - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, config) } + predicate revFlow(NodeEx node, FlowState state, Configuration config) { + revFlow(node, state, _, _, _, config) + } + + pragma[nomagic] + predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + predicate revFlowAlias( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + revFlow(node, state, toReturn, returnAp, ap, config) + } private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { storeStepFwd(_, ap, tc, _, _, config) } - predicate consCand(TypedContent tc, Ap ap, Configuration config) { + private predicate revConsCand(TypedContent tc, Ap ap, Configuration config) { storeStepCand(_, ap, tc, _, _, config) } + private predicate validAp(Ap ap, Configuration config) { + revFlow(_, _, _, _, ap, config) and ap instanceof ApNil + or + exists(TypedContent head, Ap tail | + consCand(head, tail, config) and + ap = apCons(head, tail) + ) + } + + predicate consCand(TypedContent tc, Ap ap, Configuration config) { + revConsCand(tc, ap, config) and + validAp(ap, config) + } + pragma[noinline] private predicate parameterFlow( ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config ) { - revFlow(p, true, apSome(ap0), ap, config) and + revFlow(p, _, true, apSome(ap0), ap, config) and c = p.getEnclosingCallable() } predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos | + exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | parameterFlow(p, ap, ap0, c, config) and c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0), - pragma[only_bind_into](config)) and - fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and + revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), + pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and + fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and kind = ret.getKind() and p.getPosition() = pos and // we don't expect a parameter to return stored in itself, unless explicitly allowed @@ -1491,25 +1751,37 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, ArgNodeEx arg, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(arg, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, returnAp0, ap, config) and + exists( + Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + | + revFlow(arg, state, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } - predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { + predicate stats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config + ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - tuples = count(NodeEx n, Cc cc, ApOption argAp, Ap ap | fwdFlow(n, cc, argAp, ap, config)) + states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, argAp, ap, config) + ) or fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, config)) and + nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and fields = count(TypedContent f0 | consCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - tuples = count(NodeEx n, boolean b, ApOption retAp, Ap ap | revFlow(n, b, retAp, ap, config)) + states = count(FlowState state | revFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | + revFlow(n, state, b, retAp, ap, config) + ) } /* End: Stage 2 logic. */ } @@ -1520,7 +1792,7 @@ private predicate flowOutOfCallNodeCand2( ) { flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and - Stage2::revFlow(node1, pragma[only_bind_into](config)) + Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } pragma[nomagic] @@ -1530,7 +1802,7 @@ private predicate flowIntoCallNodeCand2( ) { flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and - Stage2::revFlow(node1, pragma[only_bind_into](config)) + Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } private module LocalFlowBigStep { @@ -1541,7 +1813,8 @@ private module LocalFlowBigStep { private class FlowCheckNode extends NodeEx { FlowCheckNode() { castNode(this.asNode()) or - clearsContentCached(this.asNode(), _) + clearsContentCached(this.asNode(), _) or + expectsContentCached(this.asNode(), _) } } @@ -1549,17 +1822,31 @@ private module LocalFlowBigStep { * Holds if `node` can be the first node in a maximal subsequence of local * flow steps in a dataflow path. */ - predicate localFlowEntry(NodeEx node, Configuration config) { - Stage2::revFlow(node, config) and + private predicate localFlowEntry(NodeEx node, FlowState state, Configuration config) { + Stage2::revFlow(node, state, config) and ( - sourceNode(node, config) or - jumpStep(_, node, config) or - additionalJumpStep(_, node, config) or - node instanceof ParamNodeEx or - node.asNode() instanceof OutNodeExt or - store(_, _, node, _, config) or - read(_, _, node, config) or + sourceNode(node, state, config) + or + jumpStep(_, node, config) + or + additionalJumpStep(_, node, config) + or + additionalJumpStateStep(_, _, node, state, config) + or + node instanceof ParamNodeEx + or + node.asNode() instanceof OutNodeExt + or + Stage2::storeStepCand(_, _, _, node, _, config) + or + Stage2::readStepCand(_, _, node, config) + or node instanceof FlowCheckNode + or + exists(FlowState s | + additionalLocalStateStep(_, s, node, state, config) and + s != state + ) ) } @@ -1567,28 +1854,43 @@ private module LocalFlowBigStep { * Holds if `node` can be the last node in a maximal subsequence of local * flow steps in a dataflow path. */ - private predicate localFlowExit(NodeEx node, Configuration config) { - exists(NodeEx next | Stage2::revFlow(next, config) | + private predicate localFlowExit(NodeEx node, FlowState state, Configuration config) { + exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or flowIntoCallNodeCand1(_, node, next, config) or flowOutOfCallNodeCand1(_, node, next, config) or - store(node, _, next, _, config) or - read(node, _, next, config) + Stage2::storeStepCand(node, _, _, next, _, config) or + Stage2::readStepCand(node, _, next, config) ) or + exists(NodeEx next, FlowState s | Stage2::revFlow(next, s, config) | + additionalJumpStateStep(node, state, next, s, config) + or + additionalLocalStateStep(node, state, next, s, config) and + s != state + ) + or + Stage2::revFlow(node, state, config) and node instanceof FlowCheckNode or - sinkNode(node, config) + sinkNode(node, state, config) } pragma[noinline] private predicate additionalLocalFlowStepNodeCand2( - NodeEx node1, NodeEx node2, Configuration config + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, Configuration config ) { additionalLocalFlowStepNodeCand1(node1, node2, config) and - Stage2::revFlow(node1, _, _, false, pragma[only_bind_into](config)) and - Stage2::revFlow(node2, _, _, false, pragma[only_bind_into](config)) + state1 = state2 and + Stage2::revFlow(node1, pragma[only_bind_into](state1), _, _, false, + pragma[only_bind_into](config)) and + Stage2::revFlowAlias(node2, pragma[only_bind_into](state2), _, _, false, + pragma[only_bind_into](config)) + or + additionalLocalStateStep(node1, state1, node2, state2, config) and + Stage2::revFlow(node1, state1, _, _, false, pragma[only_bind_into](config)) and + Stage2::revFlowAlias(node2, state2, _, _, false, pragma[only_bind_into](config)) } /** @@ -1600,40 +1902,40 @@ private module LocalFlowBigStep { */ pragma[nomagic] private predicate localFlowStepPlus( - NodeEx node1, NodeEx node2, boolean preservesValue, DataFlowType t, Configuration config, - LocalCallContext cc + NodeEx node1, FlowState state, NodeEx node2, boolean preservesValue, DataFlowType t, + Configuration config, LocalCallContext cc ) { not isUnreachableInCallCached(node2.asNode(), cc.(LocalCallContextSpecificCall).getCall()) and ( - localFlowEntry(node1, pragma[only_bind_into](config)) and + localFlowEntry(node1, pragma[only_bind_into](state), pragma[only_bind_into](config)) and ( localFlowStepNodeCand1(node1, node2, config) and preservesValue = true and - t = node1.getDataFlowType() // irrelevant dummy value + t = node1.getDataFlowType() and // irrelevant dummy value + Stage2::revFlow(node2, pragma[only_bind_into](state), pragma[only_bind_into](config)) or - additionalLocalFlowStepNodeCand2(node1, node2, config) and + additionalLocalFlowStepNodeCand2(node1, state, node2, state, config) and preservesValue = false and t = node2.getDataFlowType() ) and node1 != node2 and cc.relevantFor(node1.getEnclosingCallable()) and - not isUnreachableInCallCached(node1.asNode(), cc.(LocalCallContextSpecificCall).getCall()) and - Stage2::revFlow(node2, pragma[only_bind_into](config)) + not isUnreachableInCallCached(node1.asNode(), cc.(LocalCallContextSpecificCall).getCall()) or exists(NodeEx mid | - localFlowStepPlus(node1, mid, preservesValue, t, pragma[only_bind_into](config), cc) and + localFlowStepPlus(node1, pragma[only_bind_into](state), mid, preservesValue, t, + pragma[only_bind_into](config), cc) and localFlowStepNodeCand1(mid, node2, config) and not mid instanceof FlowCheckNode and - Stage2::revFlow(node2, pragma[only_bind_into](config)) + Stage2::revFlow(node2, pragma[only_bind_into](state), pragma[only_bind_into](config)) ) or exists(NodeEx mid | - localFlowStepPlus(node1, mid, _, _, pragma[only_bind_into](config), cc) and - additionalLocalFlowStepNodeCand2(mid, node2, config) and + localFlowStepPlus(node1, state, mid, _, _, pragma[only_bind_into](config), cc) and + additionalLocalFlowStepNodeCand2(mid, state, node2, state, config) and not mid instanceof FlowCheckNode and preservesValue = false and - t = node2.getDataFlowType() and - Stage2::revFlow(node2, pragma[only_bind_into](config)) + t = node2.getDataFlowType() ) ) } @@ -1644,11 +1946,22 @@ private module LocalFlowBigStep { */ pragma[nomagic] predicate localFlowBigStep( - NodeEx node1, NodeEx node2, boolean preservesValue, AccessPathFrontNil apf, - Configuration config, LocalCallContext callContext + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + AccessPathFrontNil apf, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, node2, preservesValue, apf.getType(), config, callContext) and - localFlowExit(node2, config) + localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowExit(node2, state1, config) and + state1 = state2 + or + additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and + state1 != state2 and + preservesValue = false and + apf = TFrontNil(node2.getDataFlowType()) and + callContext.relevantFor(node1.getEnclosingCallable()) and + not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | + isUnreachableInCallCached(node1.asNode(), call) or + isUnreachableInCallCached(node2.asNode(), call) + ) } } @@ -1706,13 +2019,14 @@ private module Stage3 { bindingset[call, c, innercc] private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } - bindingset[node, cc, config] - private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } + bindingset[node, cc] + private LocalCc getLocalCc(NodeEx node, Cc cc) { any() } private predicate localStep( - NodeEx node1, NodeEx node2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, node2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } private predicate flowOutOfCall = flowOutOfCallNodeCand2/5; @@ -1720,15 +2034,49 @@ private module Stage3 { private predicate flowIntoCall = flowIntoCallNodeCand2/5; pragma[nomagic] - private predicate clear(NodeEx node, Ap ap) { ap.isClearedAt(node.asNode()) } + private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { + PrevStage::revFlow(node, config) and + clearsContentCached(node.asNode(), c) + } + + pragma[nomagic] + private predicate clearContent(NodeEx node, Content c, Configuration config) { + exists(ContentSet cs | + PrevStage::readStepCand(_, pragma[only_bind_into](c), _, pragma[only_bind_into](config)) and + c = cs.getAReadContent() and + clearSet(node, cs, pragma[only_bind_into](config)) + ) + } + + pragma[nomagic] + private predicate clear(NodeEx node, Ap ap, Configuration config) { + clearContent(node, ap.getHead().getContent(), config) + } + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getHead().getContent() + ) + } pragma[nomagic] private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } - bindingset[node, ap] - private predicate filter(NodeEx node, Ap ap) { - not clear(node, ap) and - if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any() + bindingset[node, state, ap, config] + private predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + not clear(node, ap, config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) } bindingset[ap, contentType] @@ -1739,15 +2087,14 @@ private module Stage3 { } /* Begin: Stage 3 logic. */ - private predicate flowCand(NodeEx node, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, _, _, apa, config) + bindingset[node, state, config] + private predicate flowCand(NodeEx node, FlowState state, ApApprox apa, Configuration config) { + PrevStage::revFlow(node, state, _, _, apa, config) } bindingset[result, apa] private ApApprox unbindApa(ApApprox apa) { - exists(ApApprox apa0 | - apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0) - ) + pragma[only_bind_out](apa) = pragma[only_bind_out](result) } pragma[nomagic] @@ -1771,63 +2118,70 @@ private module Stage3 { * argument. */ pragma[nomagic] - predicate fwdFlow(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, cc, argAp, ap, config) and - flowCand(node, unbindApa(getApprox(ap)), config) and - filter(node, ap) + predicate fwdFlow(NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config) { + fwdFlow0(node, state, cc, argAp, ap, config) and + flowCand(node, state, unbindApa(getApprox(ap)), config) and + filter(node, state, ap, config) } pragma[nomagic] - private predicate fwdFlow0(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - flowCand(node, _, config) and - sourceNode(node, config) and + private predicate fwdFlow0( + NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + ) { + sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and ap = getApNil(node) or - exists(NodeEx mid, Ap ap0, LocalCc localCc | - fwdFlow(mid, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc, config) + exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | + fwdFlow(mid, state0, cc, argAp, ap0, config) and + localCc = getLocalCc(mid, cc) | - localStep(mid, node, true, _, config, localCc) and + localStep(mid, state0, node, state, true, _, config, localCc) and ap = ap0 or - localStep(mid, node, false, ap, config, localCc) and + localStep(mid, state0, node, state, false, ap, config, localCc) and ap0 instanceof ApNil ) or exists(NodeEx mid | - fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and argAp = apNone() and ap = getApNil(node) ) or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + additionalJumpStateStep(mid, state0, node, state, config) and + cc = ccNone() and + argAp = apNone() and + ap = getApNil(node) + ) + or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, ap, config) and apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, _, apa, config) then argAp = apSome(ap) @@ -1835,20 +2189,21 @@ private module Stage3 { ) or // flow out of a callable - fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) or exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Cc cc, ApOption argAp, Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1861,7 +2216,7 @@ private module Stage3 { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1869,20 +2224,21 @@ private module Stage3 { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, Cc cc, ApOption argAp, Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + Configuration config ) { - fwdFlow(node1, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, Cc outercc, Cc innercc, ApOption argAp, Ap ap, - Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, + Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1891,13 +2247,13 @@ private module Stage3 { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, innercc, argAp, ap, config) and + fwdFlow(ret, state, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and @@ -1907,10 +2263,10 @@ private module Stage3 { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config ) { exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, ccc, apSome(argAp), ap, config) and + fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1925,7 +2281,7 @@ private module Stage3 { DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config ) { exists(ParamNodeEx p | - fwdFlowIn(call, p, cc, _, argAp, ap, config) and + fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) ) } @@ -1934,24 +2290,24 @@ private module Stage3 { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) @@ -1963,14 +2319,16 @@ private module Stage3 { DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } pragma[nomagic] - private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) { - fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config) + private predicate returnNodeMayFlowThrough( + RetNodeEx ret, FlowState state, Ap ap, Configuration config + ) { + fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) } /** @@ -1982,44 +2340,56 @@ private module Stage3 { * the access path of the returned value. */ pragma[nomagic] - predicate revFlow(NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config) { - revFlow0(node, toReturn, returnAp, ap, config) and - fwdFlow(node, _, _, ap, config) + predicate revFlow( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + revFlow0(node, state, toReturn, returnAp, ap, config) and + fwdFlow(node, state, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { - fwdFlow(node, _, _, ap, config) and - sinkNode(node, config) and + fwdFlow(node, state, _, _, ap, config) and + sinkNode(node, state, config) and (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and returnAp = apNone() and ap instanceof ApNil or - exists(NodeEx mid | - localStep(node, mid, true, _, config, _) and - revFlow(mid, toReturn, returnAp, ap, config) + exists(NodeEx mid, FlowState state0 | + localStep(node, state, mid, state0, true, _, config, _) and + revFlow(mid, state0, toReturn, returnAp, ap, config) ) or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - localStep(node, mid, false, _, config, _) and - revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and + revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and - revFlow(mid, _, _, ap, config) and + revFlow(mid, state, _, _, ap, config) and toReturn = false and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and + revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and + toReturn = false and + returnAp = apNone() and + ap instanceof ApNil + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + additionalJumpStateStep(node, state, mid, state0, config) and + revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, + pragma[only_bind_into](config)) and toReturn = false and returnAp = apNone() and ap instanceof ApNil @@ -2027,39 +2397,39 @@ private module Stage3 { or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, toReturn, returnAp, ap0, config) and + revFlow(mid, state, toReturn, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, returnAp, ap, config) and + revFlowInNotToReturn(node, state, returnAp, ap, config) and toReturn = false or exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowInToReturn(call, node, state, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, _, _, ap, config) and + revFlowOut(_, node, state, _, _, ap, config) and toReturn = true and - if returnNodeMayFlowThrough(node, ap, config) + if returnNodeMayFlowThrough(node, state, ap, config) then returnAp = apSome(ap) else returnAp = apNone() } pragma[nomagic] private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, TypedContent tc, NodeEx mid, boolean toReturn, - ApOption returnAp, Configuration config + Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, + boolean toReturn, ApOption returnAp, Configuration config ) { - revFlow(mid, toReturn, returnAp, ap0, config) and + revFlow(mid, state, toReturn, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -2071,7 +2441,7 @@ private module Stage3 { pragma[nomagic] private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, tail, config) and + revFlow(mid, _, _, _, tail, config) and tail = pragma[only_bind_into](tail0) and readStepFwd(_, cons, c, mid, tail0, config) ) @@ -2079,11 +2449,11 @@ private module Stage3 { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, boolean toReturn, ApOption returnAp, Ap ap, + DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, toReturn, returnAp, ap, config) and + revFlow(out, state, toReturn, returnAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -2091,10 +2461,10 @@ private module Stage3 { pragma[nomagic] private predicate revFlowInNotToReturn( - ArgNodeEx arg, ApOption returnAp, Ap ap, Configuration config + ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, false, returnAp, ap, config) and + revFlow(p, state, false, returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -2102,10 +2472,10 @@ private module Stage3 { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, true, apSome(returnAp), ap, config) and + revFlow(p, state, true, apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -2120,9 +2490,9 @@ private module Stage3 { private predicate revFlowIsReturned( DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { - exists(RetNodeEx ret, CcCall ccc | - revFlowOut(call, ret, toReturn, returnAp, ap, config) and - fwdFlow(ret, ccc, apSome(_), ap, config) and + exists(RetNodeEx ret, FlowState state, CcCall ccc | + revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and + fwdFlow(ret, state, ccc, apSome(_), ap, config) and ccc.matchesCall(call) ) } @@ -2133,46 +2503,77 @@ private module Stage3 { Configuration config ) { exists(Ap ap2, Content c | - store(node1, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, tc, node2, _, _, config) and + PrevStage::storeStepCand(node1, _, tc, node2, contentType, config) and + revFlowStore(ap2, c, ap1, node1, _, tc, node2, _, _, config) and revFlowConsCand(ap2, c, ap1, config) ) } predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and + revFlow(node2, _, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, + revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _, pragma[only_bind_into](config)) ) } - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, config) } + predicate revFlow(NodeEx node, FlowState state, Configuration config) { + revFlow(node, state, _, _, _, config) + } + + pragma[nomagic] + predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + predicate revFlowAlias( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + revFlow(node, state, toReturn, returnAp, ap, config) + } private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { storeStepFwd(_, ap, tc, _, _, config) } - predicate consCand(TypedContent tc, Ap ap, Configuration config) { + private predicate revConsCand(TypedContent tc, Ap ap, Configuration config) { storeStepCand(_, ap, tc, _, _, config) } + private predicate validAp(Ap ap, Configuration config) { + revFlow(_, _, _, _, ap, config) and ap instanceof ApNil + or + exists(TypedContent head, Ap tail | + consCand(head, tail, config) and + ap = apCons(head, tail) + ) + } + + predicate consCand(TypedContent tc, Ap ap, Configuration config) { + revConsCand(tc, ap, config) and + validAp(ap, config) + } + pragma[noinline] private predicate parameterFlow( ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config ) { - revFlow(p, true, apSome(ap0), ap, config) and + revFlow(p, _, true, apSome(ap0), ap, config) and c = p.getEnclosingCallable() } predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos | + exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | parameterFlow(p, ap, ap0, c, config) and c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0), - pragma[only_bind_into](config)) and - fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and + revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), + pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and + fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and kind = ret.getKind() and p.getPosition() = pos and // we don't expect a parameter to return stored in itself, unless explicitly allowed @@ -2186,25 +2587,37 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, ArgNodeEx arg, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(arg, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, returnAp0, ap, config) and + exists( + Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + | + revFlow(arg, state, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } - predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { + predicate stats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config + ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - tuples = count(NodeEx n, Cc cc, ApOption argAp, Ap ap | fwdFlow(n, cc, argAp, ap, config)) + states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, argAp, ap, config) + ) or fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, config)) and + nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and fields = count(TypedContent f0 | consCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - tuples = count(NodeEx n, boolean b, ApOption retAp, Ap ap | revFlow(n, b, retAp, ap, config)) + states = count(FlowState state | revFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | + revFlow(n, state, b, retAp, ap, config) + ) } /* End: Stage 3 logic. */ } @@ -2213,10 +2626,12 @@ private module Stage3 { * Holds if `argApf` is recorded as the summary context for flow reaching `node` * and remains relevant for the following pruning stage. */ -private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { +private predicate flowCandSummaryCtx( + NodeEx node, FlowState state, AccessPathFront argApf, Configuration config +) { exists(AccessPathFront apf | - Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, true, _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2228,10 +2643,10 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) exists(int tails, int nodes, int apLimit, int tupleLimit | tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and nodes = - strictcount(NodeEx n | - Stage3::revFlow(n, _, _, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + strictcount(NodeEx n, FlowState state | + Stage3::revFlow(n, state, _, _, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or - flowCandSummaryCtx(n, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and @@ -2464,27 +2879,31 @@ private module Stage4 { if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() } - bindingset[node, cc, config] - private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { - localFlowEntry(node, config) and + bindingset[node, cc] + private LocalCc getLocalCc(NodeEx node, Cc cc) { result = getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), node.getEnclosingCallable()) } private predicate localStep( - NodeEx node1, NodeEx node2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, node2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) } pragma[nomagic] private predicate flowOutOfCall( DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and - PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and - PrevStage::revFlow(node1, _, _, _, pragma[only_bind_into](config)) + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, _, _, + pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, _, _, + pragma[only_bind_into](config)) + ) } pragma[nomagic] @@ -2492,28 +2911,31 @@ private module Stage4 { DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and - PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and - PrevStage::revFlow(node1, _, _, _, pragma[only_bind_into](config)) + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, _, _, + pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, _, _, + pragma[only_bind_into](config)) + ) } - bindingset[node, ap] - private predicate filter(NodeEx node, Ap ap) { any() } + bindingset[node, state, ap, config] + private predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { any() } // Type checking is not necessary here as it has already been done in stage 3. bindingset[ap, contentType] private predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } /* Begin: Stage 4 logic. */ - private predicate flowCand(NodeEx node, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, _, _, apa, config) + bindingset[node, state, config] + private predicate flowCand(NodeEx node, FlowState state, ApApprox apa, Configuration config) { + PrevStage::revFlow(node, state, _, _, apa, config) } bindingset[result, apa] private ApApprox unbindApa(ApApprox apa) { - exists(ApApprox apa0 | - apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0) - ) + pragma[only_bind_out](apa) = pragma[only_bind_out](result) } pragma[nomagic] @@ -2537,63 +2959,70 @@ private module Stage4 { * argument. */ pragma[nomagic] - predicate fwdFlow(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, cc, argAp, ap, config) and - flowCand(node, unbindApa(getApprox(ap)), config) and - filter(node, ap) + predicate fwdFlow(NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config) { + fwdFlow0(node, state, cc, argAp, ap, config) and + flowCand(node, state, unbindApa(getApprox(ap)), config) and + filter(node, state, ap, config) } pragma[nomagic] - private predicate fwdFlow0(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - flowCand(node, _, config) and - sourceNode(node, config) and + private predicate fwdFlow0( + NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + ) { + sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and ap = getApNil(node) or - exists(NodeEx mid, Ap ap0, LocalCc localCc | - fwdFlow(mid, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc, config) + exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | + fwdFlow(mid, state0, cc, argAp, ap0, config) and + localCc = getLocalCc(mid, cc) | - localStep(mid, node, true, _, config, localCc) and + localStep(mid, state0, node, state, true, _, config, localCc) and ap = ap0 or - localStep(mid, node, false, ap, config, localCc) and + localStep(mid, state0, node, state, false, ap, config, localCc) and ap0 instanceof ApNil ) or exists(NodeEx mid | - fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and argAp = apNone() and ap = getApNil(node) ) or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + additionalJumpStateStep(mid, state0, node, state, config) and + cc = ccNone() and + argAp = apNone() and + ap = getApNil(node) + ) + or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, ap, config) and apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, _, apa, config) then argAp = apSome(ap) @@ -2601,20 +3030,21 @@ private module Stage4 { ) or // flow out of a callable - fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) or exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Cc cc, ApOption argAp, Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -2627,7 +3057,7 @@ private module Stage4 { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -2635,20 +3065,21 @@ private module Stage4 { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, Cc cc, ApOption argAp, Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + Configuration config ) { - fwdFlow(node1, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, Cc outercc, Cc innercc, ApOption argAp, Ap ap, - Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, + Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -2657,13 +3088,13 @@ private module Stage4 { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, innercc, argAp, ap, config) and + fwdFlow(ret, state, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and @@ -2673,10 +3104,10 @@ private module Stage4 { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config ) { exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, ccc, apSome(argAp), ap, config) and + fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -2691,7 +3122,7 @@ private module Stage4 { DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config ) { exists(ParamNodeEx p | - fwdFlowIn(call, p, cc, _, argAp, ap, config) and + fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) ) } @@ -2700,24 +3131,24 @@ private module Stage4 { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) @@ -2729,14 +3160,16 @@ private module Stage4 { DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } pragma[nomagic] - private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) { - fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config) + private predicate returnNodeMayFlowThrough( + RetNodeEx ret, FlowState state, Ap ap, Configuration config + ) { + fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) } /** @@ -2748,44 +3181,56 @@ private module Stage4 { * the access path of the returned value. */ pragma[nomagic] - predicate revFlow(NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config) { - revFlow0(node, toReturn, returnAp, ap, config) and - fwdFlow(node, _, _, ap, config) + predicate revFlow( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + revFlow0(node, state, toReturn, returnAp, ap, config) and + fwdFlow(node, state, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { - fwdFlow(node, _, _, ap, config) and - sinkNode(node, config) and + fwdFlow(node, state, _, _, ap, config) and + sinkNode(node, state, config) and (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and returnAp = apNone() and ap instanceof ApNil or - exists(NodeEx mid | - localStep(node, mid, true, _, config, _) and - revFlow(mid, toReturn, returnAp, ap, config) + exists(NodeEx mid, FlowState state0 | + localStep(node, state, mid, state0, true, _, config, _) and + revFlow(mid, state0, toReturn, returnAp, ap, config) ) or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - localStep(node, mid, false, _, config, _) and - revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and + revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and - revFlow(mid, _, _, ap, config) and + revFlow(mid, state, _, _, ap, config) and toReturn = false and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and + revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and + toReturn = false and + returnAp = apNone() and + ap instanceof ApNil + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + additionalJumpStateStep(node, state, mid, state0, config) and + revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, + pragma[only_bind_into](config)) and toReturn = false and returnAp = apNone() and ap instanceof ApNil @@ -2793,39 +3238,39 @@ private module Stage4 { or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, toReturn, returnAp, ap0, config) and + revFlow(mid, state, toReturn, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, returnAp, ap, config) and + revFlowInNotToReturn(node, state, returnAp, ap, config) and toReturn = false or exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowInToReturn(call, node, state, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, _, _, ap, config) and + revFlowOut(_, node, state, _, _, ap, config) and toReturn = true and - if returnNodeMayFlowThrough(node, ap, config) + if returnNodeMayFlowThrough(node, state, ap, config) then returnAp = apSome(ap) else returnAp = apNone() } pragma[nomagic] private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, TypedContent tc, NodeEx mid, boolean toReturn, - ApOption returnAp, Configuration config + Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, + boolean toReturn, ApOption returnAp, Configuration config ) { - revFlow(mid, toReturn, returnAp, ap0, config) and + revFlow(mid, state, toReturn, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -2837,7 +3282,7 @@ private module Stage4 { pragma[nomagic] private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, tail, config) and + revFlow(mid, _, _, _, tail, config) and tail = pragma[only_bind_into](tail0) and readStepFwd(_, cons, c, mid, tail0, config) ) @@ -2845,11 +3290,11 @@ private module Stage4 { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, boolean toReturn, ApOption returnAp, Ap ap, + DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, toReturn, returnAp, ap, config) and + revFlow(out, state, toReturn, returnAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -2857,10 +3302,10 @@ private module Stage4 { pragma[nomagic] private predicate revFlowInNotToReturn( - ArgNodeEx arg, ApOption returnAp, Ap ap, Configuration config + ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, false, returnAp, ap, config) and + revFlow(p, state, false, returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -2868,10 +3313,10 @@ private module Stage4 { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, true, apSome(returnAp), ap, config) and + revFlow(p, state, true, apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -2886,9 +3331,9 @@ private module Stage4 { private predicate revFlowIsReturned( DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { - exists(RetNodeEx ret, CcCall ccc | - revFlowOut(call, ret, toReturn, returnAp, ap, config) and - fwdFlow(ret, ccc, apSome(_), ap, config) and + exists(RetNodeEx ret, FlowState state, CcCall ccc | + revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and + fwdFlow(ret, state, ccc, apSome(_), ap, config) and ccc.matchesCall(call) ) } @@ -2899,46 +3344,77 @@ private module Stage4 { Configuration config ) { exists(Ap ap2, Content c | - store(node1, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, tc, node2, _, _, config) and + PrevStage::storeStepCand(node1, _, tc, node2, contentType, config) and + revFlowStore(ap2, c, ap1, node1, _, tc, node2, _, _, config) and revFlowConsCand(ap2, c, ap1, config) ) } predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and + revFlow(node2, _, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, + revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _, pragma[only_bind_into](config)) ) } - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, config) } + predicate revFlow(NodeEx node, FlowState state, Configuration config) { + revFlow(node, state, _, _, _, config) + } + + pragma[nomagic] + predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + predicate revFlowAlias( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + revFlow(node, state, toReturn, returnAp, ap, config) + } private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { storeStepFwd(_, ap, tc, _, _, config) } - predicate consCand(TypedContent tc, Ap ap, Configuration config) { + private predicate revConsCand(TypedContent tc, Ap ap, Configuration config) { storeStepCand(_, ap, tc, _, _, config) } + private predicate validAp(Ap ap, Configuration config) { + revFlow(_, _, _, _, ap, config) and ap instanceof ApNil + or + exists(TypedContent head, Ap tail | + consCand(head, tail, config) and + ap = apCons(head, tail) + ) + } + + predicate consCand(TypedContent tc, Ap ap, Configuration config) { + revConsCand(tc, ap, config) and + validAp(ap, config) + } + pragma[noinline] private predicate parameterFlow( ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config ) { - revFlow(p, true, apSome(ap0), ap, config) and + revFlow(p, _, true, apSome(ap0), ap, config) and c = p.getEnclosingCallable() } predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos | + exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | parameterFlow(p, ap, ap0, c, config) and c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0), - pragma[only_bind_into](config)) and - fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and + revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), + pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and + fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and kind = ret.getKind() and p.getPosition() = pos and // we don't expect a parameter to return stored in itself, unless explicitly allowed @@ -2952,25 +3428,37 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, ArgNodeEx arg, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(arg, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, returnAp0, ap, config) and + exists( + Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + | + revFlow(arg, state, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } - predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { + predicate stats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config + ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - tuples = count(NodeEx n, Cc cc, ApOption argAp, Ap ap | fwdFlow(n, cc, argAp, ap, config)) + states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, argAp, ap, config) + ) or fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, config)) and + nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and fields = count(TypedContent f0 | consCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - tuples = count(NodeEx n, boolean b, ApOption retAp, Ap ap | revFlow(n, b, retAp, ap, config)) + states = count(FlowState state | revFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | + revFlow(n, state, b, retAp, ap, config) + ) } /* End: Stage 4 logic. */ } @@ -2980,19 +3468,35 @@ private Configuration unbindConf(Configuration conf) { exists(Configuration c | result = pragma[only_bind_into](c) and conf = pragma[only_bind_into](c)) } -private predicate nodeMayUseSummary(NodeEx n, AccessPathApprox apa, Configuration config) { - exists(DataFlowCallable c, AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, apa, _) and - Stage4::revFlow(n, true, _, apa0, config) and - Stage4::fwdFlow(n, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and +pragma[nomagic] +private predicate nodeMayUseSummary0( + NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config +) { + exists(AccessPathApprox apa0 | + Stage4::parameterMayFlowThrough(_, c, _, _) and + Stage4::revFlow(n, state, true, _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and n.getEnclosingCallable() = c ) } +pragma[nomagic] +private predicate nodeMayUseSummary( + NodeEx n, FlowState state, AccessPathApprox apa, Configuration config +) { + exists(DataFlowCallable c | + Stage4::parameterMayFlowThrough(_, c, apa, config) and + nodeMayUseSummary0(n, c, state, apa, config) + ) +} + private newtype TSummaryCtx = TSummaryCtxNone() or - TSummaryCtxSome(ParamNodeEx p, AccessPath ap) { - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), _) + TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { + exists(Configuration config | + Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::revFlow(p, state, _, _, _, config) + ) } /** @@ -3013,11 +3517,12 @@ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone { /** A summary context from which a flow summary can be generated. */ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome { private ParamNodeEx p; + private FlowState s; private AccessPath ap; - SummaryCtxSome() { this = TSummaryCtxSome(p, ap) } + SummaryCtxSome() { this = TSummaryCtxSome(p, s, ap) } - int getParameterPos() { p.isParameterOf(_, result) } + ParameterPosition getParameterPos() { p.isParameterOf(_, result) } ParamNodeEx getParamNode() { result = p } @@ -3047,8 +3552,8 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = - strictcount(NodeEx n | - Stage4::revFlow(n, _, _, apa, config) or nodeMayUseSummary(n, apa, config) + strictcount(NodeEx n, FlowState state | + Stage4::revFlow(n, state, _, _, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -3144,10 +3649,12 @@ private newtype TAccessPath = } private newtype TPathNode = - TPathNodeMid(NodeEx node, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config) { + TPathNodeMid( + NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config + ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, config) and - sourceNode(node, config) and + Stage4::revFlow(node, state, config) and + sourceNode(node, state, config) and ( if hasSourceCallCtx(config) then cc instanceof CallContextSomeCall @@ -3158,15 +3665,16 @@ private newtype TPathNode = or // ... or a step from an existing PathNode to another node. exists(PathNodeMid mid | - pathStep(mid, node, cc, sc, ap) and + pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, _, _, ap.getApprox(), pragma[only_bind_into](config)) + Stage4::revFlow(node, state, _, _, ap.getApprox(), pragma[only_bind_into](config)) ) } or - TPathNodeSink(NodeEx node, Configuration config) { + TPathNodeSink(NodeEx node, FlowState state, Configuration config) { exists(PathNodeMid sink | sink.isAtSink() and node = sink.getNodeEx() and + state = sink.getState() and config = sink.getConfiguration() ) } @@ -3177,7 +3685,7 @@ private newtype TPathNode = * of dereference operations needed to get from the value in the node to the * tracked object. The final type indicates the type of the tracked object. */ -abstract private class AccessPath extends TAccessPath { +private class AccessPath extends TAccessPath { /** Gets the head of this access path, if any. */ abstract TypedContent getHead(); @@ -3364,19 +3872,17 @@ class PathNode extends TPathNode { /** Gets the underlying `Node`. */ final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result } + /** Gets the `FlowState` of this node. */ + FlowState getState() { none() } + /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3384,16 +3890,30 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); predicate isHidden() { - hiddenNode(this.getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.getNodeEx() instanceof TNodeImplicitRead + not this.getConfiguration().includeHiddenNodes() and + ( + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + ) } private string ppAp() { @@ -3424,15 +3944,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } -/** Holds if `n` can reach a sink or is used in a subpath. */ +/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3441,14 +3963,25 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } - query predicate subpaths = Subpaths::subpaths/4; + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) { + Subpaths::subpaths(arg, par, ret, out) and + reach(arg) and + reach(par) and + reach(ret) and + reach(out) + } } /** @@ -3457,15 +3990,18 @@ module PathGraph { */ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { NodeEx node; + FlowState state; CallContext cc; SummaryCtx sc; AccessPath ap; Configuration config; - PathNodeMid() { this = TPathNodeMid(node, cc, sc, ap, config) } + PathNodeMid() { this = TPathNodeMid(node, state, cc, sc, ap, config) } override NodeEx getNodeEx() { result = node } + override FlowState getState() { result = state } + CallContext getCallContext() { result = cc } SummaryCtx getSummaryCtx() { result = sc } @@ -3475,8 +4011,8 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { override Configuration getConfiguration() { result = config } private PathNodeMid getSuccMid() { - pathStep(this, result.getNodeEx(), result.getCallContext(), result.getSummaryCtx(), - result.getAp()) and + pathStep(this, result.getNodeEx(), result.getState(), result.getCallContext(), + result.getSummaryCtx(), result.getAp()) and result.getConfiguration() = unbindConf(this.getConfiguration()) } @@ -3489,7 +4025,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { } override predicate isSource() { - sourceNode(node, config) and + sourceNode(node, state, config) and ( if hasSourceCallCtx(config) then cc instanceof CallContextSomeCall @@ -3500,7 +4036,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { } predicate isAtSink() { - sinkNode(node, config) and + sinkNode(node, state, config) and ap instanceof AccessPathNil and if hasSinkCallCtx(config) then @@ -3522,6 +4058,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { PathNodeSink projectToSink() { this.isAtSink() and result.getNodeEx() = node and + result.getState() = state and result.getConfiguration() = unbindConf(config) } } @@ -3533,91 +4070,117 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { */ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { NodeEx node; + FlowState state; Configuration config; - PathNodeSink() { this = TPathNodeSink(node, config) } + PathNodeSink() { this = TPathNodeSink(node, state, config) } override NodeEx getNodeEx() { result = node } + override FlowState getState() { result = state } + override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } - override predicate isSource() { sourceNode(node, config) } + override predicate isSource() { sourceNode(node, state, config) } +} + +private predicate pathNode( + PathNodeMid mid, NodeEx midnode, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, + Configuration conf, LocalCallContext localCC +) { + midnode = mid.getNodeEx() and + state = mid.getState() and + conf = mid.getConfiguration() and + cc = mid.getCallContext() and + sc = mid.getSummaryCtx() and + localCC = + getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), + midnode.getEnclosingCallable()) and + ap = mid.getAp() } /** * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ +pragma[nomagic] private predicate pathStep( - PathNodeMid mid, NodeEx node, CallContext cc, SummaryCtx sc, AccessPath ap + PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap ) { - exists(AccessPath ap0, NodeEx midnode, Configuration conf, LocalCallContext localCC | - midnode = mid.getNodeEx() and - conf = mid.getConfiguration() and - cc = mid.getCallContext() and - sc = mid.getSummaryCtx() and - localCC = - getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), - midnode.getEnclosingCallable()) and - ap0 = mid.getAp() + exists(NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | + pathNode(mid, midnode, state0, cc, sc, ap, conf, localCC) and + localFlowBigStep(midnode, state0, node, state, true, _, conf, localCC) + ) + or + exists( + AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | - localFlowBigStep(midnode, node, true, _, conf, localCC) and - ap = ap0 - or - localFlowBigStep(midnode, node, false, ap.getFront(), conf, localCC) and + pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and ap0 instanceof AccessPathNil ) or jumpStep(mid.getNodeEx(), node, mid.getConfiguration()) and + state = mid.getState() and cc instanceof CallContextAny and sc instanceof SummaryCtxNone and ap = mid.getAp() or additionalJumpStep(mid.getNodeEx(), node, mid.getConfiguration()) and + state = mid.getState() and cc instanceof CallContextAny and sc instanceof SummaryCtxNone and mid.getAp() instanceof AccessPathNil and ap = TAccessPathNil(node.getDataFlowType()) or - exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and + additionalJumpStateStep(mid.getNodeEx(), mid.getState(), node, state, mid.getConfiguration()) and + cc instanceof CallContextAny and + sc instanceof SummaryCtxNone and + mid.getAp() instanceof AccessPathNil and + ap = TAccessPathNil(node.getDataFlowType()) + or + exists(TypedContent tc | pathStoreStep(mid, node, state, ap.pop(tc), tc, cc)) and sc = mid.getSummaryCtx() or - exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and + exists(TypedContent tc | pathReadStep(mid, node, state, ap.push(tc), tc, cc)) and sc = mid.getSummaryCtx() or - pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp() + pathIntoCallable(mid, node, state, _, cc, sc, _, _) and ap = mid.getAp() or - pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone + pathOutOfCallable(mid, node, state, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone or - pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx() + pathThroughCallable(mid, node, state, cc, ap) and sc = mid.getSummaryCtx() } pragma[nomagic] private predicate pathReadStep( - PathNodeMid mid, NodeEx node, AccessPath ap0, TypedContent tc, CallContext cc + PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and tc = ap0.getHead() and Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + state = mid.getState() and cc = mid.getCallContext() } pragma[nomagic] private predicate pathStoreStep( - PathNodeMid mid, NodeEx node, AccessPath ap0, TypedContent tc, CallContext cc + PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + state = mid.getState() and cc = mid.getCallContext() } private predicate pathOutOfCallable0( - PathNodeMid mid, ReturnPosition pos, CallContext innercc, AccessPathApprox apa, + PathNodeMid mid, ReturnPosition pos, FlowState state, CallContext innercc, AccessPathApprox apa, Configuration config ) { pos = mid.getNodeEx().(RetNodeEx).getReturnPosition() and + state = mid.getState() and innercc = mid.getCallContext() and innercc instanceof CallContextNoCall and apa = mid.getAp().getApprox() and @@ -3626,11 +4189,11 @@ private predicate pathOutOfCallable0( pragma[nomagic] private predicate pathOutOfCallable1( - PathNodeMid mid, DataFlowCall call, ReturnKindExt kind, CallContext cc, AccessPathApprox apa, - Configuration config + PathNodeMid mid, DataFlowCall call, ReturnKindExt kind, FlowState state, CallContext cc, + AccessPathApprox apa, Configuration config ) { exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc | - pathOutOfCallable0(mid, pos, innercc, apa, config) and + pathOutOfCallable0(mid, pos, state, innercc, apa, config) and c = pos.getCallable() and kind = pos.getKind() and resolveReturn(innercc, c, call) @@ -3644,7 +4207,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, _, apa, config) + Stage4::revFlow(result, _, _, _, apa, config) } /** @@ -3652,9 +4215,9 @@ private NodeEx getAnOutNodeFlow( * is a return from a callable and is recorded by `cc`, if needed. */ pragma[noinline] -private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc) { +private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, FlowState state, CallContext cc) { exists(ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config | - pathOutOfCallable1(mid, call, kind, cc, apa, config) and + pathOutOfCallable1(mid, call, kind, state, cc, apa, config) and out = getAnOutNodeFlow(kind, call, apa, config) ) } @@ -3664,39 +4227,37 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc) */ pragma[noinline] private predicate pathIntoArg( - PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa, - Configuration config + PathNodeMid mid, ParameterPosition ppos, FlowState state, CallContext cc, DataFlowCall call, + AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(ArgNode arg | - arg = mid.getNodeEx().asNode() and - cc = mid.getCallContext() and - arg.argumentOf(call, i) and - ap = mid.getAp() and + exists(ArgNodeEx arg, ArgumentPosition apos | + pathNode(mid, arg, state, cc, _, ap, config, _) and + arg.asNode().(ArgNode).argumentOf(call, apos) and apa = ap.getApprox() and - config = mid.getConfiguration() + parameterMatch(ppos, apos) ) } pragma[nomagic] private predicate parameterCand( - DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config + DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, _, apa, config) and - p.isParameterOf(callable, i) + Stage4::revFlow(p, _, _, _, apa, config) and + p.isParameterOf(callable, pos) ) } pragma[nomagic] private predicate pathIntoCallable0( - PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call, - AccessPath ap, Configuration config + PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, FlowState state, + CallContext outercc, DataFlowCall call, AccessPath ap, Configuration config ) { exists(AccessPathApprox apa | - pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa), - pragma[only_bind_into](config)) and + pathIntoArg(mid, pragma[only_bind_into](pos), state, outercc, call, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and callable = resolveCall(call, outercc) and - parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa), + parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa), pragma[only_bind_into](config)) ) } @@ -3708,16 +4269,16 @@ private predicate pathIntoCallable0( */ pragma[nomagic] private predicate pathIntoCallable( - PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc, - DataFlowCall call, Configuration config + PathNodeMid mid, ParamNodeEx p, FlowState state, CallContext outercc, CallContextCall innercc, + SummaryCtx sc, DataFlowCall call, Configuration config ) { - exists(int i, DataFlowCallable callable, AccessPath ap | - pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and - p.isParameterOf(callable, i) and + exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap | + pathIntoCallable0(mid, callable, pos, state, outercc, call, ap, config) and + p.isParameterOf(callable, pos) and ( - sc = TSummaryCtxSome(p, ap) + sc = TSummaryCtxSome(p, state, ap) or - not exists(TSummaryCtxSome(p, ap)) and + not exists(TSummaryCtxSome(p, state, ap)) and sc = TSummaryCtxNone() and // When the call contexts of source and sink needs to match then there's // never any reason to enter a callable except to find a summary. See also @@ -3734,16 +4295,12 @@ private predicate pathIntoCallable( /** Holds if data may flow from a parameter given by `sc` to a return of kind `kind`. */ pragma[nomagic] private predicate paramFlowsThrough( - ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, - Configuration config + ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, + AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, int pos | - mid.getNodeEx() = ret and + exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and - cc = mid.getCallContext() and - sc = mid.getSummaryCtx() and - config = mid.getConfiguration() and - ap = mid.getAp() and apa = ap.getApprox() and pos = sc.getParameterPos() and // we don't expect a parameter to return stored in itself, unless explicitly allowed @@ -3757,12 +4314,12 @@ private predicate paramFlowsThrough( pragma[nomagic] private predicate pathThroughCallable0( - DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap, - AccessPathApprox apa, Configuration config + DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, FlowState state, CallContext cc, + AccessPath ap, AccessPathApprox apa, Configuration config ) { exists(CallContext innercc, SummaryCtx sc | - pathIntoCallable(mid, _, cc, innercc, sc, call, config) and - paramFlowsThrough(kind, innercc, sc, ap, apa, config) + pathIntoCallable(mid, _, _, cc, innercc, sc, call, config) and + paramFlowsThrough(kind, state, innercc, sc, ap, apa, config) ) } @@ -3771,9 +4328,11 @@ private predicate pathThroughCallable0( * The context `cc` is restored to its value prior to entering the callable. */ pragma[noinline] -private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) { +private predicate pathThroughCallable( + PathNodeMid mid, NodeEx out, FlowState state, CallContext cc, AccessPath ap +) { exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config | - pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and + pathThroughCallable0(call, mid, kind, state, cc, ap, apa, config) and out = getAnOutNodeFlow(kind, call, apa, config) ) } @@ -3786,26 +4345,27 @@ private module Subpaths { pragma[nomagic] private predicate subpaths01( PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, - NodeEx out, AccessPath apout + NodeEx out, FlowState sout, AccessPath apout ) { exists(Configuration config | - pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and - pathIntoCallable(arg, par, _, innercc, sc, _, config) and - paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config)) and + pathThroughCallable(arg, out, pragma[only_bind_into](sout), _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, _, innercc, sc, _, config) and + paramFlowsThrough(kind, pragma[only_bind_into](sout), innercc, sc, + pragma[only_bind_into](apout), _, unbindConf(config)) and not arg.isHidden() ) } /** * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by - * `kind`, `sc`, `apout`, and `innercc`. + * `kind`, `sc`, `sout`, `apout`, and `innercc`. */ pragma[nomagic] private predicate subpaths02( PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, - NodeEx out, AccessPath apout + NodeEx out, FlowState sout, AccessPath apout ) { - subpaths01(arg, par, sc, innercc, kind, out, apout) and + subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and out.asNode() = kind.getAnOutNode(_) } @@ -3817,16 +4377,12 @@ private module Subpaths { */ pragma[nomagic] private predicate subpaths03( - PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout ) { exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | - subpaths02(arg, par, sc, innercc, kind, out, apout) and - ret.getNodeEx() = retnode and - kind = retnode.getKind() and - innercc = ret.getCallContext() and - sc = ret.getSummaryCtx() and - ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and - apout = ret.getAp() + subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and + pathNode(ret, retnode, sout, innercc, sc, apout, unbindConf(getPathNodeConf(arg)), _) and + kind = retnode.getKind() ) } @@ -3834,38 +4390,44 @@ private module Subpaths { n.getASuccessorImpl() = result and result.isHidden() and exists(NodeEx n1, NodeEx n2 | n1 = n.getNodeEx() and n2 = result.getNodeEx() | - localFlowBigStep(n1, n2, _, _, _, _) or + localFlowBigStep(n1, _, n2, _, _, _, _, _) or store(n1, _, n2, _, _) or - read(n1, _, n2, _) + readSet(n1, _, n2, _) ) } + pragma[nomagic] + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and + succNode = succ.getNodeEx() + } + /** * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNodeMid out) { - exists(ParamNodeEx p, NodeEx o, AccessPath apout | - pragma[only_bind_into](arg).getASuccessor() = par and - pragma[only_bind_into](arg).getASuccessor() = out and - subpaths03(arg, p, localStepToHidden*(ret), o, apout) and + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and + subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and + hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and - par.getNodeEx() = p and - out.getNodeEx() = o and - out.getAp() = apout + pathNode(out0, o, sout, _, _, apout, _, _) + | + out = out0 or out = out0.projectToSink() ) } /** - * Holds if `n` can reach a return node in a summarized subpath. + * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { - subpaths(_, _, n, _) + predicate retReach(PathNodeImpl n) { + exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } @@ -3897,17 +4459,21 @@ predicate flowsTo(Node source, Node sink, Configuration configuration) { flowsTo(_, _, source, sink, configuration) } -private predicate finalStats(boolean fwd, int nodes, int fields, int conscand, int tuples) { +private predicate finalStats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples +) { fwd = true and nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0)) and fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and + states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and tuples = count(PathNode pn) or fwd = false and nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and + states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and tuples = count(PathNode pn | reach(pn)) } @@ -3917,27 +4483,44 @@ private predicate finalStats(boolean fwd, int nodes, int fields, int conscand, i * Calculates per-stage metrics for data flow. */ predicate stageStats( - int n, string stage, int nodes, int fields, int conscand, int tuples, Configuration config + int n, string stage, int nodes, int fields, int conscand, int states, int tuples, + Configuration config ) { - stage = "1 Fwd" and n = 10 and Stage1::stats(true, nodes, fields, conscand, tuples, config) + stage = "1 Fwd" and + n = 10 and + Stage1::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "1 Rev" and n = 15 and Stage1::stats(false, nodes, fields, conscand, tuples, config) + stage = "1 Rev" and + n = 15 and + Stage1::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "2 Fwd" and n = 20 and Stage2::stats(true, nodes, fields, conscand, tuples, config) + stage = "2 Fwd" and + n = 20 and + Stage2::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "2 Rev" and n = 25 and Stage2::stats(false, nodes, fields, conscand, tuples, config) + stage = "2 Rev" and + n = 25 and + Stage2::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "3 Fwd" and n = 30 and Stage3::stats(true, nodes, fields, conscand, tuples, config) + stage = "3 Fwd" and + n = 30 and + Stage3::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "3 Rev" and n = 35 and Stage3::stats(false, nodes, fields, conscand, tuples, config) + stage = "3 Rev" and + n = 35 and + Stage3::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "4 Fwd" and n = 40 and Stage4::stats(true, nodes, fields, conscand, tuples, config) + stage = "4 Fwd" and + n = 40 and + Stage4::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "4 Rev" and n = 45 and Stage4::stats(false, nodes, fields, conscand, tuples, config) + stage = "4 Rev" and + n = 45 and + Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, tuples) + stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, tuples) + stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { @@ -3947,6 +4530,8 @@ private module FlowExploration { or additionalJumpStep(node1, node2, config) or + additionalJumpStateStep(node1, _, node2, _, config) + or // flow into callable viableParamArgEx(_, node2, node1) or @@ -3960,7 +4545,7 @@ private module FlowExploration { } private predicate interestingCallableSrc(DataFlowCallable c, Configuration config) { - exists(Node n | config.isSource(n) and c = getNodeEnclosingCallable(n)) + exists(Node n | config.isSource(n) or config.isSource(n, _) | c = getNodeEnclosingCallable(n)) or exists(DataFlowCallable mid | interestingCallableSrc(mid, config) and callableStep(mid, c, config) @@ -3968,7 +4553,7 @@ private module FlowExploration { } private predicate interestingCallableSink(DataFlowCallable c, Configuration config) { - exists(Node n | config.isSink(n) and c = getNodeEnclosingCallable(n)) + exists(Node n | config.isSink(n) or config.isSink(n, _) | c = getNodeEnclosingCallable(n)) or exists(DataFlowCallable mid | interestingCallableSink(mid, config) and callableStep(c, mid, config) @@ -3996,13 +4581,13 @@ private module FlowExploration { or exists(Node n, Configuration config | ce1 = TCallableSrc() and - config.isSource(n) and + (config.isSource(n) or config.isSource(n, _)) and ce2 = TCallable(getNodeEnclosingCallable(n), config) ) or exists(Node n, Configuration config | ce2 = TCallableSink() and - config.isSink(n) and + (config.isSink(n) or config.isSink(n, _)) and ce1 = TCallable(getNodeEnclosingCallable(n), config) ) } @@ -4104,13 +4689,26 @@ private module FlowExploration { } } + private predicate relevantState(FlowState state) { + sourceNode(_, state, _) or + sinkNode(_, state, _) or + additionalLocalStateStep(_, state, _, _, _) or + additionalLocalStateStep(_, _, _, state, _) or + additionalJumpStateStep(_, state, _, _, _) or + additionalJumpStateStep(_, _, _, state, _) + } + private newtype TSummaryCtx1 = TSummaryCtx1None() or TSummaryCtx1Param(ParamNodeEx p) private newtype TSummaryCtx2 = TSummaryCtx2None() or - TSummaryCtx2Some(PartialAccessPath ap) + TSummaryCtx2Some(FlowState s) { relevantState(s) } + + private newtype TSummaryCtx3 = + TSummaryCtx3None() or + TSummaryCtx3Some(PartialAccessPath ap) private newtype TRevSummaryCtx1 = TRevSummaryCtx1None() or @@ -4118,52 +4716,66 @@ private module FlowExploration { private newtype TRevSummaryCtx2 = TRevSummaryCtx2None() or - TRevSummaryCtx2Some(RevPartialAccessPath ap) + TRevSummaryCtx2Some(FlowState s) { relevantState(s) } + + private newtype TRevSummaryCtx3 = + TRevSummaryCtx3None() or + TRevSummaryCtx3Some(RevPartialAccessPath ap) private newtype TPartialPathNode = TPartialPathNodeFwd( - NodeEx node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, PartialAccessPath ap, - Configuration config + NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, + TSummaryCtx3 sc3, PartialAccessPath ap, Configuration config ) { - sourceNode(node, config) and + sourceNode(node, state, config) and cc instanceof CallContextAny and sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and ap = TPartialNil(node.getDataFlowType()) and - not fullBarrier(node, config) and exists(config.explorationLimit()) or - partialPathNodeMk0(node, cc, sc1, sc2, ap, config) and + partialPathNodeMk0(node, state, cc, sc1, sc2, sc3, ap, config) and distSrc(node.getEnclosingCallable(), config) <= config.explorationLimit() } or TPartialPathNodeRev( - NodeEx node, TRevSummaryCtx1 sc1, TRevSummaryCtx2 sc2, RevPartialAccessPath ap, - Configuration config + NodeEx node, FlowState state, TRevSummaryCtx1 sc1, TRevSummaryCtx2 sc2, TRevSummaryCtx3 sc3, + RevPartialAccessPath ap, Configuration config ) { - sinkNode(node, config) and + sinkNode(node, state, config) and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and ap = TRevPartialNil() and - not fullBarrier(node, config) and exists(config.explorationLimit()) or exists(PartialPathNodeRev mid | - revPartialPathStep(mid, node, sc1, sc2, ap, config) and - not clearsContentCached(node.asNode(), ap.getHead()) and + revPartialPathStep(mid, node, state, sc1, sc2, sc3, ap, config) and + not clearsContentEx(node, ap.getHead()) and + ( + notExpectsContent(node) or + expectsContentEx(node, ap.getHead()) + ) and not fullBarrier(node, config) and + not stateBarrier(node, state, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) } pragma[nomagic] private predicate partialPathNodeMk0( - NodeEx node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, PartialAccessPath ap, - Configuration config + NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, + TSummaryCtx3 sc3, PartialAccessPath ap, Configuration config ) { exists(PartialPathNodeFwd mid | - partialPathStep(mid, node, cc, sc1, sc2, ap, config) and + partialPathStep(mid, node, state, cc, sc1, sc2, sc3, ap, config) and not fullBarrier(node, config) and - not clearsContentCached(node.asNode(), ap.getHead().getContent()) and + not stateBarrier(node, state, config) and + not clearsContentEx(node, ap.getHead().getContent()) and + ( + notExpectsContent(node) or + expectsContentEx(node, ap.getHead().getContent()) + ) and if node.asNode() instanceof CastingNode then compatibleTypes(node.getDataFlowType(), ap.getType()) else any() @@ -4201,6 +4813,8 @@ private module FlowExploration { /** Gets the underlying `Node`. */ final Node getNode() { this.getNodeEx().projectToNode() = result } + FlowState getState() { none() } + private NodeEx getNodeEx() { result = this.(PartialPathNodeFwd).getNodeEx() or result = this.(PartialPathNodeRev).getNodeEx() @@ -4258,135 +4872,182 @@ private module FlowExploration { private class PartialPathNodeFwd extends PartialPathNode, TPartialPathNodeFwd { NodeEx node; + FlowState state; CallContext cc; TSummaryCtx1 sc1; TSummaryCtx2 sc2; + TSummaryCtx3 sc3; PartialAccessPath ap; Configuration config; - PartialPathNodeFwd() { this = TPartialPathNodeFwd(node, cc, sc1, sc2, ap, config) } + PartialPathNodeFwd() { this = TPartialPathNodeFwd(node, state, cc, sc1, sc2, sc3, ap, config) } NodeEx getNodeEx() { result = node } + override FlowState getState() { result = state } + CallContext getCallContext() { result = cc } TSummaryCtx1 getSummaryCtx1() { result = sc1 } TSummaryCtx2 getSummaryCtx2() { result = sc2 } + TSummaryCtx3 getSummaryCtx3() { result = sc3 } + PartialAccessPath getAp() { result = ap } override Configuration getConfiguration() { result = config } override PartialPathNodeFwd getASuccessor() { - partialPathStep(this, result.getNodeEx(), result.getCallContext(), result.getSummaryCtx1(), - result.getSummaryCtx2(), result.getAp(), result.getConfiguration()) + partialPathStep(this, result.getNodeEx(), result.getState(), result.getCallContext(), + result.getSummaryCtx1(), result.getSummaryCtx2(), result.getSummaryCtx3(), result.getAp(), + result.getConfiguration()) } predicate isSource() { - sourceNode(node, config) and + sourceNode(node, state, config) and cc instanceof CallContextAny and sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and ap instanceof TPartialNil } } private class PartialPathNodeRev extends PartialPathNode, TPartialPathNodeRev { NodeEx node; + FlowState state; TRevSummaryCtx1 sc1; TRevSummaryCtx2 sc2; + TRevSummaryCtx3 sc3; RevPartialAccessPath ap; Configuration config; - PartialPathNodeRev() { this = TPartialPathNodeRev(node, sc1, sc2, ap, config) } + PartialPathNodeRev() { this = TPartialPathNodeRev(node, state, sc1, sc2, sc3, ap, config) } NodeEx getNodeEx() { result = node } + override FlowState getState() { result = state } + TRevSummaryCtx1 getSummaryCtx1() { result = sc1 } TRevSummaryCtx2 getSummaryCtx2() { result = sc2 } + TRevSummaryCtx3 getSummaryCtx3() { result = sc3 } + RevPartialAccessPath getAp() { result = ap } override Configuration getConfiguration() { result = config } override PartialPathNodeRev getASuccessor() { - revPartialPathStep(result, this.getNodeEx(), this.getSummaryCtx1(), this.getSummaryCtx2(), - this.getAp(), this.getConfiguration()) + revPartialPathStep(result, this.getNodeEx(), this.getState(), this.getSummaryCtx1(), + this.getSummaryCtx2(), this.getSummaryCtx3(), this.getAp(), this.getConfiguration()) } predicate isSink() { - sinkNode(node, config) and + sinkNode(node, state, config) and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and ap = TRevPartialNil() } } private predicate partialPathStep( - PartialPathNodeFwd mid, NodeEx node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - PartialAccessPath ap, Configuration config + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, PartialAccessPath ap, Configuration config ) { not isUnreachableInCallCached(node.asNode(), cc.(CallContextSpecificCall).getCall()) and ( localFlowStep(mid.getNodeEx(), node, config) and + state = mid.getState() and cc = mid.getCallContext() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and ap = mid.getAp() and config = mid.getConfiguration() or additionalLocalFlowStep(mid.getNodeEx(), node, config) and + state = mid.getState() and cc = mid.getCallContext() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and + mid.getAp() instanceof PartialAccessPathNil and + ap = TPartialNil(node.getDataFlowType()) and + config = mid.getConfiguration() + or + additionalLocalStateStep(mid.getNodeEx(), mid.getState(), node, state, config) and + cc = mid.getCallContext() and + sc1 = mid.getSummaryCtx1() and + sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and mid.getAp() instanceof PartialAccessPathNil and ap = TPartialNil(node.getDataFlowType()) and config = mid.getConfiguration() ) or jumpStep(mid.getNodeEx(), node, config) and + state = mid.getState() and cc instanceof CallContextAny and sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and ap = mid.getAp() and config = mid.getConfiguration() or additionalJumpStep(mid.getNodeEx(), node, config) and + state = mid.getState() and cc instanceof CallContextAny and sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and + mid.getAp() instanceof PartialAccessPathNil and + ap = TPartialNil(node.getDataFlowType()) and + config = mid.getConfiguration() + or + additionalJumpStateStep(mid.getNodeEx(), mid.getState(), node, state, config) and + cc instanceof CallContextAny and + sc1 = TSummaryCtx1None() and + sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and mid.getAp() instanceof PartialAccessPathNil and ap = TPartialNil(node.getDataFlowType()) and config = mid.getConfiguration() or partialPathStoreStep(mid, _, _, node, ap) and + state = mid.getState() and cc = mid.getCallContext() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and config = mid.getConfiguration() or exists(PartialAccessPath ap0, TypedContent tc | partialPathReadStep(mid, ap0, tc, node, cc, config) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and apConsFwd(ap, tc, ap0, config) ) or - partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config) + partialPathIntoCallable(mid, node, state, _, cc, sc1, sc2, sc3, _, ap, config) or - partialPathOutOfCallable(mid, node, cc, ap, config) and + partialPathOutOfCallable(mid, node, state, cc, ap, config) and sc1 = TSummaryCtx1None() and - sc2 = TSummaryCtx2None() + sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() or - partialPathThroughCallable(mid, node, cc, ap, config) and + partialPathThroughCallable(mid, node, state, cc, ap, config) and sc1 = mid.getSummaryCtx1() and - sc2 = mid.getSummaryCtx2() + sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() } bindingset[result, i] - private int unbindInt(int i) { i <= result and i >= result } + private int unbindInt(int i) { pragma[only_bind_out](i) = pragma[only_bind_out](result) } pragma[inline] private predicate partialPathStoreStep( @@ -4429,10 +5090,11 @@ private module FlowExploration { } private predicate partialPathOutOfCallable0( - PartialPathNodeFwd mid, ReturnPosition pos, CallContext innercc, PartialAccessPath ap, - Configuration config + PartialPathNodeFwd mid, ReturnPosition pos, FlowState state, CallContext innercc, + PartialAccessPath ap, Configuration config ) { pos = mid.getNodeEx().(RetNodeEx).getReturnPosition() and + state = mid.getState() and innercc = mid.getCallContext() and innercc instanceof CallContextNoCall and ap = mid.getAp() and @@ -4441,11 +5103,11 @@ private module FlowExploration { pragma[nomagic] private predicate partialPathOutOfCallable1( - PartialPathNodeFwd mid, DataFlowCall call, ReturnKindExt kind, CallContext cc, + PartialPathNodeFwd mid, DataFlowCall call, ReturnKindExt kind, FlowState state, CallContext cc, PartialAccessPath ap, Configuration config ) { exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc | - partialPathOutOfCallable0(mid, pos, innercc, ap, config) and + partialPathOutOfCallable0(mid, pos, state, innercc, ap, config) and c = pos.getCallable() and kind = pos.getKind() and resolveReturn(innercc, c, call) @@ -4455,10 +5117,11 @@ private module FlowExploration { } private predicate partialPathOutOfCallable( - PartialPathNodeFwd mid, NodeEx out, CallContext cc, PartialAccessPath ap, Configuration config + PartialPathNodeFwd mid, NodeEx out, FlowState state, CallContext cc, PartialAccessPath ap, + Configuration config ) { exists(ReturnKindExt kind, DataFlowCall call | - partialPathOutOfCallable1(mid, call, kind, cc, ap, config) + partialPathOutOfCallable1(mid, call, kind, state, cc, ap, config) | out.asNode() = kind.getAnOutNode(call) ) @@ -4466,37 +5129,40 @@ private module FlowExploration { pragma[noinline] private predicate partialPathIntoArg( - PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap, - Configuration config + PartialPathNodeFwd mid, ParameterPosition ppos, FlowState state, CallContext cc, + DataFlowCall call, PartialAccessPath ap, Configuration config ) { - exists(ArgNode arg | + exists(ArgNode arg, ArgumentPosition apos | arg = mid.getNodeEx().asNode() and + state = mid.getState() and cc = mid.getCallContext() and - arg.argumentOf(call, i) and + arg.argumentOf(call, apos) and ap = mid.getAp() and - config = mid.getConfiguration() + config = mid.getConfiguration() and + parameterMatch(ppos, apos) ) } pragma[nomagic] private predicate partialPathIntoCallable0( - PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc, - DataFlowCall call, PartialAccessPath ap, Configuration config + PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, FlowState state, + CallContext outercc, DataFlowCall call, PartialAccessPath ap, Configuration config ) { - partialPathIntoArg(mid, i, outercc, call, ap, config) and + partialPathIntoArg(mid, pos, state, outercc, call, ap, config) and callable = resolveCall(call, outercc) } private predicate partialPathIntoCallable( - PartialPathNodeFwd mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, - TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap, - Configuration config + PartialPathNodeFwd mid, ParamNodeEx p, FlowState state, CallContext outercc, + CallContextCall innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, + DataFlowCall call, PartialAccessPath ap, Configuration config ) { - exists(int i, DataFlowCallable callable | - partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and - p.isParameterOf(callable, i) and + exists(ParameterPosition pos, DataFlowCallable callable | + partialPathIntoCallable0(mid, callable, pos, state, outercc, call, ap, config) and + p.isParameterOf(callable, pos) and sc1 = TSummaryCtx1Param(p) and - sc2 = TSummaryCtx2Some(ap) + sc2 = TSummaryCtx2Some(state) and + sc3 = TSummaryCtx3Some(ap) | if recordDataFlowCallSite(call, callable) then innercc = TSpecificCall(call) @@ -4506,15 +5172,17 @@ private module FlowExploration { pragma[nomagic] private predicate paramFlowsThroughInPartialPath( - ReturnKindExt kind, CallContextCall cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - PartialAccessPath ap, Configuration config + ReturnKindExt kind, FlowState state, CallContextCall cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, + TSummaryCtx3 sc3, PartialAccessPath ap, Configuration config ) { exists(PartialPathNodeFwd mid, RetNodeEx ret | mid.getNodeEx() = ret and kind = ret.getKind() and + state = mid.getState() and cc = mid.getCallContext() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and config = mid.getConfiguration() and ap = mid.getAp() ) @@ -4522,85 +5190,119 @@ private module FlowExploration { pragma[noinline] private predicate partialPathThroughCallable0( - DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, CallContext cc, + DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, FlowState state, CallContext cc, PartialAccessPath ap, Configuration config ) { - exists(CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 | - partialPathIntoCallable(mid, _, cc, innercc, sc1, sc2, call, _, config) and - paramFlowsThroughInPartialPath(kind, innercc, sc1, sc2, ap, config) + exists(CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3 | + partialPathIntoCallable(mid, _, _, cc, innercc, sc1, sc2, sc3, call, _, config) and + paramFlowsThroughInPartialPath(kind, state, innercc, sc1, sc2, sc3, ap, config) ) } private predicate partialPathThroughCallable( - PartialPathNodeFwd mid, NodeEx out, CallContext cc, PartialAccessPath ap, Configuration config + PartialPathNodeFwd mid, NodeEx out, FlowState state, CallContext cc, PartialAccessPath ap, + Configuration config ) { exists(DataFlowCall call, ReturnKindExt kind | - partialPathThroughCallable0(call, mid, kind, cc, ap, config) and + partialPathThroughCallable0(call, mid, kind, state, cc, ap, config) and out.asNode() = kind.getAnOutNode(call) ) } + pragma[nomagic] private predicate revPartialPathStep( - PartialPathNodeRev mid, NodeEx node, TRevSummaryCtx1 sc1, TRevSummaryCtx2 sc2, - RevPartialAccessPath ap, Configuration config + PartialPathNodeRev mid, NodeEx node, FlowState state, TRevSummaryCtx1 sc1, TRevSummaryCtx2 sc2, + TRevSummaryCtx3 sc3, RevPartialAccessPath ap, Configuration config ) { localFlowStep(node, mid.getNodeEx(), config) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and ap = mid.getAp() and config = mid.getConfiguration() or additionalLocalFlowStep(node, mid.getNodeEx(), config) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and + mid.getAp() instanceof RevPartialAccessPathNil and + ap = TRevPartialNil() and + config = mid.getConfiguration() + or + additionalLocalStateStep(node, state, mid.getNodeEx(), mid.getState(), config) and + sc1 = mid.getSummaryCtx1() and + sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and mid.getAp() instanceof RevPartialAccessPathNil and ap = TRevPartialNil() and config = mid.getConfiguration() or jumpStep(node, mid.getNodeEx(), config) and + state = mid.getState() and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and ap = mid.getAp() and config = mid.getConfiguration() or additionalJumpStep(node, mid.getNodeEx(), config) and + state = mid.getState() and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and + mid.getAp() instanceof RevPartialAccessPathNil and + ap = TRevPartialNil() and + config = mid.getConfiguration() + or + additionalJumpStateStep(node, state, mid.getNodeEx(), mid.getState(), config) and + sc1 = TRevSummaryCtx1None() and + sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and mid.getAp() instanceof RevPartialAccessPathNil and ap = TRevPartialNil() and config = mid.getConfiguration() or revPartialPathReadStep(mid, _, _, node, ap) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and config = mid.getConfiguration() or exists(RevPartialAccessPath ap0, Content c | revPartialPathStoreStep(mid, ap0, c, node, config) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and apConsRev(ap, c, ap0, config) ) or exists(ParamNodeEx p | mid.getNodeEx() = p and viableParamArgEx(_, p, node) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and ap = mid.getAp() and config = mid.getConfiguration() ) or exists(ReturnPosition pos | - revPartialPathIntoReturn(mid, pos, sc1, sc2, _, ap, config) and + revPartialPathIntoReturn(mid, pos, state, sc1, sc2, sc3, _, ap, config) and pos = getReturnPosition(node.asNode()) ) or - revPartialPathThroughCallable(mid, node, ap, config) and + revPartialPathThroughCallable(mid, node, state, ap, config) and sc1 = mid.getSummaryCtx1() and - sc2 = mid.getSummaryCtx2() + sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() } pragma[inline] @@ -4643,14 +5345,17 @@ private module FlowExploration { pragma[nomagic] private predicate revPartialPathIntoReturn( - PartialPathNodeRev mid, ReturnPosition pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, - DataFlowCall call, RevPartialAccessPath ap, Configuration config + PartialPathNodeRev mid, ReturnPosition pos, FlowState state, TRevSummaryCtx1Some sc1, + TRevSummaryCtx2Some sc2, TRevSummaryCtx3Some sc3, DataFlowCall call, RevPartialAccessPath ap, + Configuration config ) { exists(NodeEx out | mid.getNodeEx() = out and + mid.getState() = state and viableReturnPosOutEx(call, pos, out) and sc1 = TRevSummaryCtx1Some(pos) and - sc2 = TRevSummaryCtx2Some(ap) and + sc2 = TRevSummaryCtx2Some(state) and + sc3 = TRevSummaryCtx3Some(ap) and ap = mid.getAp() and config = mid.getConfiguration() ) @@ -4658,36 +5363,40 @@ private module FlowExploration { pragma[nomagic] private predicate revPartialPathFlowsThrough( - int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap, - Configuration config + ArgumentPosition apos, FlowState state, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, + TRevSummaryCtx3Some sc3, RevPartialAccessPath ap, Configuration config ) { - exists(PartialPathNodeRev mid, ParamNodeEx p | + exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos | mid.getNodeEx() = p and - p.getPosition() = pos and + mid.getState() = state and + p.getPosition() = ppos and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and ap = mid.getAp() and - config = mid.getConfiguration() + config = mid.getConfiguration() and + parameterMatch(ppos, apos) ) } pragma[nomagic] private predicate revPartialPathThroughCallable0( - DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap, - Configuration config + DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, FlowState state, + RevPartialAccessPath ap, Configuration config ) { - exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 | - revPartialPathIntoReturn(mid, _, sc1, sc2, call, _, config) and - revPartialPathFlowsThrough(pos, sc1, sc2, ap, config) + exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, TRevSummaryCtx3Some sc3 | + revPartialPathIntoReturn(mid, _, _, sc1, sc2, sc3, call, _, config) and + revPartialPathFlowsThrough(pos, state, sc1, sc2, sc3, ap, config) ) } pragma[nomagic] private predicate revPartialPathThroughCallable( - PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config + PartialPathNodeRev mid, ArgNodeEx node, FlowState state, RevPartialAccessPath ap, + Configuration config ) { - exists(DataFlowCall call, int pos | - revPartialPathThroughCallable0(call, mid, pos, ap, config) and + exists(DataFlowCall call, ArgumentPosition pos | + revPartialPathThroughCallable0(call, mid, pos, state, ap, config) and node.asNode().(ArgNode).argumentOf(call, pos) ) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index 65408c9915a..a076f7a2e45 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -54,12 +54,23 @@ abstract class Configuration extends string { /** * Holds if `source` is a relevant data flow source. */ - abstract predicate isSource(Node source); + predicate isSource(Node source) { none() } + + /** + * Holds if `source` is a relevant data flow source with the given initial + * `state`. + */ + predicate isSource(Node source, FlowState state) { none() } /** * Holds if `sink` is a relevant data flow sink. */ - abstract predicate isSink(Node sink); + predicate isSink(Node sink) { none() } + + /** + * Holds if `sink` is a relevant data flow sink accepting `state`. + */ + predicate isSink(Node source, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -67,6 +78,12 @@ abstract class Configuration extends string { */ predicate isBarrier(Node node) { none() } + /** + * Holds if data flow through `node` is prohibited when the flow state is + * `state`. + */ + predicate isBarrier(Node node, FlowState state) { none() } + /** Holds if data flow into `node` is prohibited. */ predicate isBarrierIn(Node node) { none() } @@ -81,16 +98,31 @@ abstract class Configuration extends string { deprecated predicate isBarrierGuard(BarrierGuard guard) { none() } /** - * Holds if the additional flow step from `node1` to `node2` must be taken - * into account in the analysis. + * DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead. + * + * Holds if data flow through nodes guarded by `guard` is prohibited when + * the flow state is `state` + */ + deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() } + + /** + * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. */ predicate isAdditionalFlowStep(Node node1, Node node2) { none() } + /** + * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. + * This step is only applicable in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + none() + } + /** * Holds if an arbitrary number of implicit read steps of content `c` may be * taken at `node`. */ - predicate allowImplicitRead(Node node, Content c) { none() } + predicate allowImplicitRead(Node node, ContentSet c) { none() } /** * Gets the virtual dispatch branching limit when calculating field flow. @@ -144,6 +176,14 @@ abstract class Configuration extends string { */ int explorationLimit() { none() } + /** + * Holds if hidden nodes should be included in the data flow graph. + * + * This feature should only be used for debugging or when the data flow graph + * is not visualized (for example in a `path-problem` query). + */ + predicate includeHiddenNodes() { none() } + /** * Holds if there is a partial data flow path from `source` to `node`. The * approximate distance between `node` and the closest source is `dist` and @@ -201,10 +241,16 @@ abstract private class ConfigurationRecursionPrevention extends Configuration { override predicate hasFlow(Node source, Node sink) { strictcount(Node n | this.isSource(n)) < 0 or + strictcount(Node n | this.isSource(n, _)) < 0 + or strictcount(Node n | this.isSink(n)) < 0 or + strictcount(Node n | this.isSink(n, _)) < 0 + or strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 or + strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 + or super.hasFlow(source, sink) } } @@ -260,11 +306,11 @@ private class ArgNodeEx extends NodeEx { private class ParamNodeEx extends NodeEx { ParamNodeEx() { this.asNode() instanceof ParamNode } - predicate isParameterOf(DataFlowCallable c, int i) { - this.asNode().(ParamNode).isParameterOf(c, i) + predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { + this.asNode().(ParamNode).isParameterOf(c, pos) } - int getPosition() { this.isParameterOf(_, result) } + ParameterPosition getPosition() { this.isParameterOf(_, result) } predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } @@ -280,22 +326,26 @@ private class RetNodeEx extends NodeEx { private predicate inBarrier(NodeEx node, Configuration config) { exists(Node n | node.asNode() = n and - config.isBarrierIn(n) and - config.isSource(n) + config.isBarrierIn(n) + | + config.isSource(n) or config.isSource(n, _) ) } private predicate outBarrier(NodeEx node, Configuration config) { exists(Node n | node.asNode() = n and - config.isBarrierOut(n) and - config.isSink(n) + config.isBarrierOut(n) + | + config.isSink(n) or config.isSink(n, _) ) } /** A bridge class to access the deprecated `isBarrierGuard`. */ private class BarrierGuardGuardedNodeBridge extends Unit { abstract predicate guardedNode(Node n, Configuration config); + + abstract predicate guardedNode(Node n, FlowState state, Configuration config); } private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge { @@ -305,6 +355,13 @@ private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge { n = g.getAGuardedNode() ) } + + deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) { + exists(BarrierGuard g | + config.isBarrierGuard(g, state) and + n = g.getAGuardedNode() + ) + } } pragma[nomagic] @@ -313,23 +370,47 @@ private predicate fullBarrier(NodeEx node, Configuration config) { config.isBarrier(n) or config.isBarrierIn(n) and - not config.isSource(n) + not config.isSource(n) and + not config.isSource(n, _) or config.isBarrierOut(n) and - not config.isSink(n) + not config.isSink(n) and + not config.isSink(n, _) or any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config) ) } pragma[nomagic] -private predicate sourceNode(NodeEx node, Configuration config) { - config.isSource(node.asNode()) and - not fullBarrier(node, config) +private predicate stateBarrier(NodeEx node, FlowState state, Configuration config) { + exists(Node n | node.asNode() = n | + config.isBarrier(n, state) + or + any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config) + ) } pragma[nomagic] -private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) } +private predicate sourceNode(NodeEx node, FlowState state, Configuration config) { + ( + config.isSource(node.asNode()) and state instanceof FlowStateEmpty + or + config.isSource(node.asNode(), state) + ) and + not fullBarrier(node, config) and + not stateBarrier(node, state, config) +} + +pragma[nomagic] +private predicate sinkNode(NodeEx node, FlowState state, Configuration config) { + ( + config.isSink(node.asNode()) and state instanceof FlowStateEmpty + or + config.isSink(node.asNode(), state) + ) and + not fullBarrier(node, config) and + not stateBarrier(node, state, config) +} /** Provides the relevant barriers for a step from `node1` to `node2`. */ pragma[inline] @@ -347,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -366,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -379,6 +460,20 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat ) } +private predicate additionalLocalStateStep( + NodeEx node1, FlowState s1, NodeEx node2, FlowState s2, Configuration config +) { + exists(Node n1, Node n2 | + node1.asNode() = n1 and + node2.asNode() = n2 and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and + getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and + stepFilter(node1, node2, config) and + not stateBarrier(node1, s1, config) and + not stateBarrier(node2, s2, config) + ) +} + /** * Holds if data can flow from `node1` to `node2` in a way that discards call contexts. */ @@ -386,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -399,15 +494,31 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) } -private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) { - read(node1.asNode(), c, node2.asNode()) and +private predicate additionalJumpStateStep( + NodeEx node1, FlowState s1, NodeEx node2, FlowState s2, Configuration config +) { + exists(Node n1, Node n2 | + node1.asNode() = n1 and + node2.asNode() = n2 and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and + getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and + stepFilter(node1, node2, config) and + not stateBarrier(node1, s1, config) and + not stateBarrier(node2, s2, config) and + not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext + ) +} + +pragma[nomagic] +private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -417,10 +528,42 @@ private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration conf ) } +// inline to reduce fan-out via `getAReadContent` +bindingset[c] +private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) { + exists(ContentSet cs | + readSet(node1, cs, node2, config) and + pragma[only_bind_out](c) = pragma[only_bind_into](cs).getAReadContent() + ) +} + +// inline to reduce fan-out via `getAReadContent` +bindingset[c] +private predicate clearsContentEx(NodeEx n, Content c) { + exists(ContentSet cs | + clearsContentCached(n.asNode(), cs) and + pragma[only_bind_out](c) = pragma[only_bind_into](cs).getAReadContent() + ) +} + +// inline to reduce fan-out via `getAReadContent` +bindingset[c] +private predicate expectsContentEx(NodeEx n, Content c) { + exists(ContentSet cs | + expectsContentCached(n.asNode(), cs) and + pragma[only_bind_out](c) = pragma[only_bind_into](cs).getAReadContent() + ) +} + +pragma[nomagic] +private predicate notExpectsContent(NodeEx n) { not expectsContentCached(n.asNode(), _) } + +pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } @@ -471,29 +614,19 @@ private module Stage1 { * argument in a call. */ predicate fwdFlow(NodeEx node, Cc cc, Configuration config) { - sourceNode(node, config) and + sourceNode(node, _, config) and if hasSourceCallCtx(config) then cc = true else cc = false or - exists(NodeEx mid | - fwdFlow(mid, cc, config) and - localFlowStep(mid, node, config) + exists(NodeEx mid | fwdFlow(mid, cc, config) | + localFlowStep(mid, node, config) or + additionalLocalFlowStep(mid, node, config) or + additionalLocalStateStep(mid, _, node, _, config) ) or - exists(NodeEx mid | - fwdFlow(mid, cc, config) and - additionalLocalFlowStep(mid, node, config) - ) - or - exists(NodeEx mid | - fwdFlow(mid, _, config) and - jumpStep(mid, node, config) and - cc = false - ) - or - exists(NodeEx mid | - fwdFlow(mid, _, config) and - additionalJumpStep(mid, node, config) and - cc = false + exists(NodeEx mid | fwdFlow(mid, _, config) and cc = false | + jumpStep(mid, node, config) or + additionalJumpStep(mid, node, config) or + additionalJumpStateStep(mid, _, node, _, config) ) or // store @@ -504,9 +637,9 @@ private module Stage1 { ) or // read - exists(Content c | - fwdFlowRead(c, node, cc, config) and - fwdFlowConsCand(c, config) + exists(ContentSet c | + fwdFlowReadSet(c, node, cc, config) and + fwdFlowConsCandSet(c, _, config) ) or // flow into a callable @@ -530,10 +663,10 @@ private module Stage1 { private predicate fwdFlow(NodeEx node, Configuration config) { fwdFlow(node, _, config) } pragma[nomagic] - private predicate fwdFlowRead(Content c, NodeEx node, Cc cc, Configuration config) { + private predicate fwdFlowReadSet(ContentSet c, NodeEx node, Cc cc, Configuration config) { exists(NodeEx mid | fwdFlow(mid, cc, config) and - read(mid, c, node, config) + readSet(mid, c, node, config) ) } @@ -551,6 +684,16 @@ private module Stage1 { ) } + /** + * Holds if `cs` may be interpreted in a read as the target of some store + * into `c`, in the flow covered by `fwdFlow`. + */ + pragma[nomagic] + private predicate fwdFlowConsCandSet(ContentSet cs, Content c, Configuration config) { + fwdFlowConsCand(c, config) and + c = cs.getAReadContent() + } + pragma[nomagic] private predicate fwdFlowReturnPosition(ReturnPosition pos, Cc cc, Configuration config) { exists(RetNodeEx ret | @@ -584,6 +727,24 @@ private module Stage1 { ) } + private predicate stateStepFwd(FlowState state1, FlowState state2, Configuration config) { + exists(NodeEx node1 | + additionalLocalStateStep(node1, state1, _, state2, config) or + additionalJumpStateStep(node1, state1, _, state2, config) + | + fwdFlow(node1, config) + ) + } + + private predicate fwdFlowState(FlowState state, Configuration config) { + sourceNode(_, state, config) + or + exists(FlowState state0 | + fwdFlowState(state0, config) and + stateStepFwd(state0, state, config) + ) + } + /** * Holds if `node` is part of a path from a source to a sink in the * configuration `config`. @@ -599,30 +760,23 @@ private module Stage1 { pragma[nomagic] private predicate revFlow0(NodeEx node, boolean toReturn, Configuration config) { - fwdFlow(node, config) and - sinkNode(node, config) and - if hasSinkCallCtx(config) then toReturn = true else toReturn = false - or - exists(NodeEx mid | - localFlowStep(node, mid, config) and - revFlow(mid, toReturn, config) + exists(FlowState state | + fwdFlow(node, pragma[only_bind_into](config)) and + sinkNode(node, state, config) and + fwdFlowState(state, pragma[only_bind_into](config)) and + if hasSinkCallCtx(config) then toReturn = true else toReturn = false ) or - exists(NodeEx mid | - additionalLocalFlowStep(node, mid, config) and - revFlow(mid, toReturn, config) + exists(NodeEx mid | revFlow(mid, toReturn, config) | + localFlowStep(node, mid, config) or + additionalLocalFlowStep(node, mid, config) or + additionalLocalStateStep(node, _, mid, _, config) ) or - exists(NodeEx mid | - jumpStep(node, mid, config) and - revFlow(mid, _, config) and - toReturn = false - ) - or - exists(NodeEx mid | - additionalJumpStep(node, mid, config) and - revFlow(mid, _, config) and - toReturn = false + exists(NodeEx mid | revFlow(mid, _, config) and toReturn = false | + jumpStep(node, mid, config) or + additionalJumpStep(node, mid, config) or + additionalJumpStateStep(node, _, mid, _, config) ) or // store @@ -632,9 +786,9 @@ private module Stage1 { ) or // read - exists(NodeEx mid, Content c | - read(node, c, mid, config) and - fwdFlowConsCand(c, pragma[only_bind_into](config)) and + exists(NodeEx mid, ContentSet c | + readSet(node, c, mid, config) and + fwdFlowConsCandSet(c, _, pragma[only_bind_into](config)) and revFlow(mid, toReturn, pragma[only_bind_into](config)) ) or @@ -660,10 +814,10 @@ private module Stage1 { */ pragma[nomagic] private predicate revFlowConsCand(Content c, Configuration config) { - exists(NodeEx mid, NodeEx node | + exists(NodeEx mid, NodeEx node, ContentSet cs | fwdFlow(node, pragma[only_bind_into](config)) and - read(node, c, mid, config) and - fwdFlowConsCand(c, pragma[only_bind_into](config)) and + readSet(node, cs, mid, config) and + fwdFlowConsCandSet(cs, c, pragma[only_bind_into](config)) and revFlow(pragma[only_bind_into](mid), _, pragma[only_bind_into](config)) ) } @@ -682,7 +836,8 @@ private module Stage1 { * Holds if `c` is the target of both a read and a store in the flow covered * by `revFlow`. */ - private predicate revFlowIsReadAndStored(Content c, Configuration conf) { + pragma[nomagic] + predicate revFlowIsReadAndStored(Content c, Configuration conf) { revFlowConsCand(c, conf) and revFlowStore(c, _, _, conf) } @@ -739,6 +894,31 @@ private module Stage1 { ) } + private predicate stateStepRev(FlowState state1, FlowState state2, Configuration config) { + exists(NodeEx node1, NodeEx node2 | + additionalLocalStateStep(node1, state1, node2, state2, config) or + additionalJumpStateStep(node1, state1, node2, state2, config) + | + revFlow(node1, _, pragma[only_bind_into](config)) and + revFlow(node2, _, pragma[only_bind_into](config)) and + fwdFlowState(state1, pragma[only_bind_into](config)) and + fwdFlowState(state2, pragma[only_bind_into](config)) + ) + } + + predicate revFlowState(FlowState state, Configuration config) { + exists(NodeEx node | + sinkNode(node, state, config) and + revFlow(node, _, pragma[only_bind_into](config)) and + fwdFlowState(state, pragma[only_bind_into](config)) + ) + or + exists(FlowState state0 | + revFlowState(state0, config) and + stateStepRev(state, state0, config) + ) + } + pragma[nomagic] predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -756,15 +936,21 @@ private module Stage1 { pragma[nomagic] predicate readStepCand(NodeEx n1, Content c, NodeEx n2, Configuration config) { revFlowIsReadAndStored(c, pragma[only_bind_into](config)) and - revFlow(n2, pragma[only_bind_into](config)) and - read(n1, c, n2, pragma[only_bind_into](config)) + read(n1, c, n2, pragma[only_bind_into](config)) and + revFlow(n2, pragma[only_bind_into](config)) } pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } - predicate revFlow(NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config) { - revFlow(node, toReturn, config) and exists(returnAp) and exists(ap) + bindingset[node, state, config] + predicate revFlow( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + revFlow(node, toReturn, pragma[only_bind_into](config)) and + exists(state) and + exists(returnAp) and + exists(ap) } private predicate throughFlowNodeCand(NodeEx node, Configuration config) { @@ -815,17 +1001,21 @@ private module Stage1 { ) } - predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { + predicate stats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config + ) { fwd = true and nodes = count(NodeEx node | fwdFlow(node, config)) and fields = count(Content f0 | fwdFlowConsCand(f0, config)) and conscand = -1 and + states = count(FlowState state | fwdFlowState(state, config)) and tuples = count(NodeEx n, boolean b | fwdFlow(n, b, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, config)) and fields = count(Content f0 | revFlowConsCand(f0, config)) and conscand = -1 and + states = count(FlowState state | revFlowState(state, config)) and tuples = count(NodeEx n, boolean b | revFlow(n, b, config)) } /* End: Stage 1 logic. */ @@ -1006,18 +1196,26 @@ private module Stage2 { if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() } - bindingset[node, cc, config] - private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } + bindingset[node, cc] + private LocalCc getLocalCc(NodeEx node, Cc cc) { any() } + bindingset[node1, state1, config] + bindingset[node2, state2, config] private predicate localStep( - NodeEx node1, NodeEx node2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApNil ap, Configuration config, LocalCc lcc ) { ( preservesValue = true and - localFlowStepNodeCand1(node1, node2, config) + localFlowStepNodeCand1(node1, node2, config) and + state1 = state2 or preservesValue = false and - additionalLocalFlowStepNodeCand1(node1, node2, config) + additionalLocalFlowStepNodeCand1(node1, node2, config) and + state1 = state2 + or + preservesValue = false and + additionalLocalStateStep(node1, state1, node2, state2, config) ) and exists(ap) and exists(lcc) @@ -1027,22 +1225,40 @@ private module Stage2 { private predicate flowIntoCall = flowIntoCallNodeCand1/5; - bindingset[node, ap] - private predicate filter(NodeEx node, Ap ap) { any() } + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::revFlowIsReadAndStored(c, pragma[only_bind_into](config)) and + expectsContentEx(node, c) + ) + } + + bindingset[node, state, ap, config] + private predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + PrevStage::revFlowState(state, pragma[only_bind_into](config)) and + exists(ap) and + not stateBarrier(node, state, config) and + ( + notExpectsContent(node) + or + ap = true and + expectsContentCand(node, config) + ) + } bindingset[ap, contentType] private predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } /* Begin: Stage 2 logic. */ - private predicate flowCand(NodeEx node, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, _, _, apa, config) + bindingset[node, state, config] + private predicate flowCand(NodeEx node, FlowState state, ApApprox apa, Configuration config) { + PrevStage::revFlow(node, state, _, _, apa, config) } bindingset[result, apa] private ApApprox unbindApa(ApApprox apa) { - exists(ApApprox apa0 | - apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0) - ) + pragma[only_bind_out](apa) = pragma[only_bind_out](result) } pragma[nomagic] @@ -1066,63 +1282,70 @@ private module Stage2 { * argument. */ pragma[nomagic] - predicate fwdFlow(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, cc, argAp, ap, config) and - flowCand(node, unbindApa(getApprox(ap)), config) and - filter(node, ap) + predicate fwdFlow(NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config) { + fwdFlow0(node, state, cc, argAp, ap, config) and + flowCand(node, state, unbindApa(getApprox(ap)), config) and + filter(node, state, ap, config) } pragma[nomagic] - private predicate fwdFlow0(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - flowCand(node, _, config) and - sourceNode(node, config) and + private predicate fwdFlow0( + NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + ) { + sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and ap = getApNil(node) or - exists(NodeEx mid, Ap ap0, LocalCc localCc | - fwdFlow(mid, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc, config) + exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | + fwdFlow(mid, state0, cc, argAp, ap0, config) and + localCc = getLocalCc(mid, cc) | - localStep(mid, node, true, _, config, localCc) and + localStep(mid, state0, node, state, true, _, config, localCc) and ap = ap0 or - localStep(mid, node, false, ap, config, localCc) and + localStep(mid, state0, node, state, false, ap, config, localCc) and ap0 instanceof ApNil ) or exists(NodeEx mid | - fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and argAp = apNone() and ap = getApNil(node) ) or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + additionalJumpStateStep(mid, state0, node, state, config) and + cc = ccNone() and + argAp = apNone() and + ap = getApNil(node) + ) + or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, ap, config) and apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, _, apa, config) then argAp = apSome(ap) @@ -1130,20 +1353,21 @@ private module Stage2 { ) or // flow out of a callable - fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) or exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Cc cc, ApOption argAp, Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1156,7 +1380,7 @@ private module Stage2 { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1164,20 +1388,21 @@ private module Stage2 { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, Cc cc, ApOption argAp, Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + Configuration config ) { - fwdFlow(node1, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, Cc outercc, Cc innercc, ApOption argAp, Ap ap, - Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, + Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1186,13 +1411,13 @@ private module Stage2 { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, innercc, argAp, ap, config) and + fwdFlow(ret, state, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and @@ -1202,10 +1427,10 @@ private module Stage2 { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config ) { exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, ccc, apSome(argAp), ap, config) and + fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1220,7 +1445,7 @@ private module Stage2 { DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config ) { exists(ParamNodeEx p | - fwdFlowIn(call, p, cc, _, argAp, ap, config) and + fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) ) } @@ -1229,24 +1454,24 @@ private module Stage2 { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) @@ -1258,14 +1483,16 @@ private module Stage2 { DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } pragma[nomagic] - private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) { - fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config) + private predicate returnNodeMayFlowThrough( + RetNodeEx ret, FlowState state, Ap ap, Configuration config + ) { + fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) } /** @@ -1277,44 +1504,56 @@ private module Stage2 { * the access path of the returned value. */ pragma[nomagic] - predicate revFlow(NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config) { - revFlow0(node, toReturn, returnAp, ap, config) and - fwdFlow(node, _, _, ap, config) + predicate revFlow( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + revFlow0(node, state, toReturn, returnAp, ap, config) and + fwdFlow(node, state, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { - fwdFlow(node, _, _, ap, config) and - sinkNode(node, config) and + fwdFlow(node, state, _, _, ap, config) and + sinkNode(node, state, config) and (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and returnAp = apNone() and ap instanceof ApNil or - exists(NodeEx mid | - localStep(node, mid, true, _, config, _) and - revFlow(mid, toReturn, returnAp, ap, config) + exists(NodeEx mid, FlowState state0 | + localStep(node, state, mid, state0, true, _, config, _) and + revFlow(mid, state0, toReturn, returnAp, ap, config) ) or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - localStep(node, mid, false, _, config, _) and - revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and + revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and - revFlow(mid, _, _, ap, config) and + revFlow(mid, state, _, _, ap, config) and toReturn = false and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and + revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and + toReturn = false and + returnAp = apNone() and + ap instanceof ApNil + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + additionalJumpStateStep(node, state, mid, state0, config) and + revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, + pragma[only_bind_into](config)) and toReturn = false and returnAp = apNone() and ap instanceof ApNil @@ -1322,39 +1561,39 @@ private module Stage2 { or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, toReturn, returnAp, ap0, config) and + revFlow(mid, state, toReturn, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, returnAp, ap, config) and + revFlowInNotToReturn(node, state, returnAp, ap, config) and toReturn = false or exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowInToReturn(call, node, state, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, _, _, ap, config) and + revFlowOut(_, node, state, _, _, ap, config) and toReturn = true and - if returnNodeMayFlowThrough(node, ap, config) + if returnNodeMayFlowThrough(node, state, ap, config) then returnAp = apSome(ap) else returnAp = apNone() } pragma[nomagic] private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, TypedContent tc, NodeEx mid, boolean toReturn, - ApOption returnAp, Configuration config + Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, + boolean toReturn, ApOption returnAp, Configuration config ) { - revFlow(mid, toReturn, returnAp, ap0, config) and + revFlow(mid, state, toReturn, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1366,7 +1605,7 @@ private module Stage2 { pragma[nomagic] private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, tail, config) and + revFlow(mid, _, _, _, tail, config) and tail = pragma[only_bind_into](tail0) and readStepFwd(_, cons, c, mid, tail0, config) ) @@ -1374,11 +1613,11 @@ private module Stage2 { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, boolean toReturn, ApOption returnAp, Ap ap, + DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, toReturn, returnAp, ap, config) and + revFlow(out, state, toReturn, returnAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1386,10 +1625,10 @@ private module Stage2 { pragma[nomagic] private predicate revFlowInNotToReturn( - ArgNodeEx arg, ApOption returnAp, Ap ap, Configuration config + ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, false, returnAp, ap, config) and + revFlow(p, state, false, returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1397,10 +1636,10 @@ private module Stage2 { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, true, apSome(returnAp), ap, config) and + revFlow(p, state, true, apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1415,9 +1654,9 @@ private module Stage2 { private predicate revFlowIsReturned( DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { - exists(RetNodeEx ret, CcCall ccc | - revFlowOut(call, ret, toReturn, returnAp, ap, config) and - fwdFlow(ret, ccc, apSome(_), ap, config) and + exists(RetNodeEx ret, FlowState state, CcCall ccc | + revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and + fwdFlow(ret, state, ccc, apSome(_), ap, config) and ccc.matchesCall(call) ) } @@ -1428,46 +1667,77 @@ private module Stage2 { Configuration config ) { exists(Ap ap2, Content c | - store(node1, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, tc, node2, _, _, config) and + PrevStage::storeStepCand(node1, _, tc, node2, contentType, config) and + revFlowStore(ap2, c, ap1, node1, _, tc, node2, _, _, config) and revFlowConsCand(ap2, c, ap1, config) ) } predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and + revFlow(node2, _, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, + revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _, pragma[only_bind_into](config)) ) } - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, config) } + predicate revFlow(NodeEx node, FlowState state, Configuration config) { + revFlow(node, state, _, _, _, config) + } + + pragma[nomagic] + predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + predicate revFlowAlias( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + revFlow(node, state, toReturn, returnAp, ap, config) + } private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { storeStepFwd(_, ap, tc, _, _, config) } - predicate consCand(TypedContent tc, Ap ap, Configuration config) { + private predicate revConsCand(TypedContent tc, Ap ap, Configuration config) { storeStepCand(_, ap, tc, _, _, config) } + private predicate validAp(Ap ap, Configuration config) { + revFlow(_, _, _, _, ap, config) and ap instanceof ApNil + or + exists(TypedContent head, Ap tail | + consCand(head, tail, config) and + ap = apCons(head, tail) + ) + } + + predicate consCand(TypedContent tc, Ap ap, Configuration config) { + revConsCand(tc, ap, config) and + validAp(ap, config) + } + pragma[noinline] private predicate parameterFlow( ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config ) { - revFlow(p, true, apSome(ap0), ap, config) and + revFlow(p, _, true, apSome(ap0), ap, config) and c = p.getEnclosingCallable() } predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos | + exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | parameterFlow(p, ap, ap0, c, config) and c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0), - pragma[only_bind_into](config)) and - fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and + revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), + pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and + fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and kind = ret.getKind() and p.getPosition() = pos and // we don't expect a parameter to return stored in itself, unless explicitly allowed @@ -1481,25 +1751,37 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, ArgNodeEx arg, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(arg, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, returnAp0, ap, config) and + exists( + Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + | + revFlow(arg, state, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } - predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { + predicate stats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config + ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - tuples = count(NodeEx n, Cc cc, ApOption argAp, Ap ap | fwdFlow(n, cc, argAp, ap, config)) + states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, argAp, ap, config) + ) or fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, config)) and + nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and fields = count(TypedContent f0 | consCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - tuples = count(NodeEx n, boolean b, ApOption retAp, Ap ap | revFlow(n, b, retAp, ap, config)) + states = count(FlowState state | revFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | + revFlow(n, state, b, retAp, ap, config) + ) } /* End: Stage 2 logic. */ } @@ -1510,7 +1792,7 @@ private predicate flowOutOfCallNodeCand2( ) { flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and - Stage2::revFlow(node1, pragma[only_bind_into](config)) + Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } pragma[nomagic] @@ -1520,7 +1802,7 @@ private predicate flowIntoCallNodeCand2( ) { flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and - Stage2::revFlow(node1, pragma[only_bind_into](config)) + Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } private module LocalFlowBigStep { @@ -1531,7 +1813,8 @@ private module LocalFlowBigStep { private class FlowCheckNode extends NodeEx { FlowCheckNode() { castNode(this.asNode()) or - clearsContentCached(this.asNode(), _) + clearsContentCached(this.asNode(), _) or + expectsContentCached(this.asNode(), _) } } @@ -1539,17 +1822,31 @@ private module LocalFlowBigStep { * Holds if `node` can be the first node in a maximal subsequence of local * flow steps in a dataflow path. */ - predicate localFlowEntry(NodeEx node, Configuration config) { - Stage2::revFlow(node, config) and + private predicate localFlowEntry(NodeEx node, FlowState state, Configuration config) { + Stage2::revFlow(node, state, config) and ( - sourceNode(node, config) or - jumpStep(_, node, config) or - additionalJumpStep(_, node, config) or - node instanceof ParamNodeEx or - node.asNode() instanceof OutNodeExt or - store(_, _, node, _, config) or - read(_, _, node, config) or + sourceNode(node, state, config) + or + jumpStep(_, node, config) + or + additionalJumpStep(_, node, config) + or + additionalJumpStateStep(_, _, node, state, config) + or + node instanceof ParamNodeEx + or + node.asNode() instanceof OutNodeExt + or + Stage2::storeStepCand(_, _, _, node, _, config) + or + Stage2::readStepCand(_, _, node, config) + or node instanceof FlowCheckNode + or + exists(FlowState s | + additionalLocalStateStep(_, s, node, state, config) and + s != state + ) ) } @@ -1557,28 +1854,43 @@ private module LocalFlowBigStep { * Holds if `node` can be the last node in a maximal subsequence of local * flow steps in a dataflow path. */ - private predicate localFlowExit(NodeEx node, Configuration config) { - exists(NodeEx next | Stage2::revFlow(next, config) | + private predicate localFlowExit(NodeEx node, FlowState state, Configuration config) { + exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or flowIntoCallNodeCand1(_, node, next, config) or flowOutOfCallNodeCand1(_, node, next, config) or - store(node, _, next, _, config) or - read(node, _, next, config) + Stage2::storeStepCand(node, _, _, next, _, config) or + Stage2::readStepCand(node, _, next, config) ) or + exists(NodeEx next, FlowState s | Stage2::revFlow(next, s, config) | + additionalJumpStateStep(node, state, next, s, config) + or + additionalLocalStateStep(node, state, next, s, config) and + s != state + ) + or + Stage2::revFlow(node, state, config) and node instanceof FlowCheckNode or - sinkNode(node, config) + sinkNode(node, state, config) } pragma[noinline] private predicate additionalLocalFlowStepNodeCand2( - NodeEx node1, NodeEx node2, Configuration config + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, Configuration config ) { additionalLocalFlowStepNodeCand1(node1, node2, config) and - Stage2::revFlow(node1, _, _, false, pragma[only_bind_into](config)) and - Stage2::revFlow(node2, _, _, false, pragma[only_bind_into](config)) + state1 = state2 and + Stage2::revFlow(node1, pragma[only_bind_into](state1), _, _, false, + pragma[only_bind_into](config)) and + Stage2::revFlowAlias(node2, pragma[only_bind_into](state2), _, _, false, + pragma[only_bind_into](config)) + or + additionalLocalStateStep(node1, state1, node2, state2, config) and + Stage2::revFlow(node1, state1, _, _, false, pragma[only_bind_into](config)) and + Stage2::revFlowAlias(node2, state2, _, _, false, pragma[only_bind_into](config)) } /** @@ -1590,40 +1902,40 @@ private module LocalFlowBigStep { */ pragma[nomagic] private predicate localFlowStepPlus( - NodeEx node1, NodeEx node2, boolean preservesValue, DataFlowType t, Configuration config, - LocalCallContext cc + NodeEx node1, FlowState state, NodeEx node2, boolean preservesValue, DataFlowType t, + Configuration config, LocalCallContext cc ) { not isUnreachableInCallCached(node2.asNode(), cc.(LocalCallContextSpecificCall).getCall()) and ( - localFlowEntry(node1, pragma[only_bind_into](config)) and + localFlowEntry(node1, pragma[only_bind_into](state), pragma[only_bind_into](config)) and ( localFlowStepNodeCand1(node1, node2, config) and preservesValue = true and - t = node1.getDataFlowType() // irrelevant dummy value + t = node1.getDataFlowType() and // irrelevant dummy value + Stage2::revFlow(node2, pragma[only_bind_into](state), pragma[only_bind_into](config)) or - additionalLocalFlowStepNodeCand2(node1, node2, config) and + additionalLocalFlowStepNodeCand2(node1, state, node2, state, config) and preservesValue = false and t = node2.getDataFlowType() ) and node1 != node2 and cc.relevantFor(node1.getEnclosingCallable()) and - not isUnreachableInCallCached(node1.asNode(), cc.(LocalCallContextSpecificCall).getCall()) and - Stage2::revFlow(node2, pragma[only_bind_into](config)) + not isUnreachableInCallCached(node1.asNode(), cc.(LocalCallContextSpecificCall).getCall()) or exists(NodeEx mid | - localFlowStepPlus(node1, mid, preservesValue, t, pragma[only_bind_into](config), cc) and + localFlowStepPlus(node1, pragma[only_bind_into](state), mid, preservesValue, t, + pragma[only_bind_into](config), cc) and localFlowStepNodeCand1(mid, node2, config) and not mid instanceof FlowCheckNode and - Stage2::revFlow(node2, pragma[only_bind_into](config)) + Stage2::revFlow(node2, pragma[only_bind_into](state), pragma[only_bind_into](config)) ) or exists(NodeEx mid | - localFlowStepPlus(node1, mid, _, _, pragma[only_bind_into](config), cc) and - additionalLocalFlowStepNodeCand2(mid, node2, config) and + localFlowStepPlus(node1, state, mid, _, _, pragma[only_bind_into](config), cc) and + additionalLocalFlowStepNodeCand2(mid, state, node2, state, config) and not mid instanceof FlowCheckNode and preservesValue = false and - t = node2.getDataFlowType() and - Stage2::revFlow(node2, pragma[only_bind_into](config)) + t = node2.getDataFlowType() ) ) } @@ -1634,11 +1946,22 @@ private module LocalFlowBigStep { */ pragma[nomagic] predicate localFlowBigStep( - NodeEx node1, NodeEx node2, boolean preservesValue, AccessPathFrontNil apf, - Configuration config, LocalCallContext callContext + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + AccessPathFrontNil apf, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, node2, preservesValue, apf.getType(), config, callContext) and - localFlowExit(node2, config) + localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowExit(node2, state1, config) and + state1 = state2 + or + additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and + state1 != state2 and + preservesValue = false and + apf = TFrontNil(node2.getDataFlowType()) and + callContext.relevantFor(node1.getEnclosingCallable()) and + not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | + isUnreachableInCallCached(node1.asNode(), call) or + isUnreachableInCallCached(node2.asNode(), call) + ) } } @@ -1696,13 +2019,14 @@ private module Stage3 { bindingset[call, c, innercc] private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } - bindingset[node, cc, config] - private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } + bindingset[node, cc] + private LocalCc getLocalCc(NodeEx node, Cc cc) { any() } private predicate localStep( - NodeEx node1, NodeEx node2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, node2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } private predicate flowOutOfCall = flowOutOfCallNodeCand2/5; @@ -1710,15 +2034,49 @@ private module Stage3 { private predicate flowIntoCall = flowIntoCallNodeCand2/5; pragma[nomagic] - private predicate clear(NodeEx node, Ap ap) { ap.isClearedAt(node.asNode()) } + private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { + PrevStage::revFlow(node, config) and + clearsContentCached(node.asNode(), c) + } + + pragma[nomagic] + private predicate clearContent(NodeEx node, Content c, Configuration config) { + exists(ContentSet cs | + PrevStage::readStepCand(_, pragma[only_bind_into](c), _, pragma[only_bind_into](config)) and + c = cs.getAReadContent() and + clearSet(node, cs, pragma[only_bind_into](config)) + ) + } + + pragma[nomagic] + private predicate clear(NodeEx node, Ap ap, Configuration config) { + clearContent(node, ap.getHead().getContent(), config) + } + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getHead().getContent() + ) + } pragma[nomagic] private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } - bindingset[node, ap] - private predicate filter(NodeEx node, Ap ap) { - not clear(node, ap) and - if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any() + bindingset[node, state, ap, config] + private predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + not clear(node, ap, config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) } bindingset[ap, contentType] @@ -1729,15 +2087,14 @@ private module Stage3 { } /* Begin: Stage 3 logic. */ - private predicate flowCand(NodeEx node, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, _, _, apa, config) + bindingset[node, state, config] + private predicate flowCand(NodeEx node, FlowState state, ApApprox apa, Configuration config) { + PrevStage::revFlow(node, state, _, _, apa, config) } bindingset[result, apa] private ApApprox unbindApa(ApApprox apa) { - exists(ApApprox apa0 | - apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0) - ) + pragma[only_bind_out](apa) = pragma[only_bind_out](result) } pragma[nomagic] @@ -1761,63 +2118,70 @@ private module Stage3 { * argument. */ pragma[nomagic] - predicate fwdFlow(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, cc, argAp, ap, config) and - flowCand(node, unbindApa(getApprox(ap)), config) and - filter(node, ap) + predicate fwdFlow(NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config) { + fwdFlow0(node, state, cc, argAp, ap, config) and + flowCand(node, state, unbindApa(getApprox(ap)), config) and + filter(node, state, ap, config) } pragma[nomagic] - private predicate fwdFlow0(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - flowCand(node, _, config) and - sourceNode(node, config) and + private predicate fwdFlow0( + NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + ) { + sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and ap = getApNil(node) or - exists(NodeEx mid, Ap ap0, LocalCc localCc | - fwdFlow(mid, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc, config) + exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | + fwdFlow(mid, state0, cc, argAp, ap0, config) and + localCc = getLocalCc(mid, cc) | - localStep(mid, node, true, _, config, localCc) and + localStep(mid, state0, node, state, true, _, config, localCc) and ap = ap0 or - localStep(mid, node, false, ap, config, localCc) and + localStep(mid, state0, node, state, false, ap, config, localCc) and ap0 instanceof ApNil ) or exists(NodeEx mid | - fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and argAp = apNone() and ap = getApNil(node) ) or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + additionalJumpStateStep(mid, state0, node, state, config) and + cc = ccNone() and + argAp = apNone() and + ap = getApNil(node) + ) + or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, ap, config) and apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, _, apa, config) then argAp = apSome(ap) @@ -1825,20 +2189,21 @@ private module Stage3 { ) or // flow out of a callable - fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) or exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Cc cc, ApOption argAp, Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1851,7 +2216,7 @@ private module Stage3 { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1859,20 +2224,21 @@ private module Stage3 { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, Cc cc, ApOption argAp, Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + Configuration config ) { - fwdFlow(node1, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, Cc outercc, Cc innercc, ApOption argAp, Ap ap, - Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, + Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1881,13 +2247,13 @@ private module Stage3 { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, innercc, argAp, ap, config) and + fwdFlow(ret, state, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and @@ -1897,10 +2263,10 @@ private module Stage3 { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config ) { exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, ccc, apSome(argAp), ap, config) and + fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1915,7 +2281,7 @@ private module Stage3 { DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config ) { exists(ParamNodeEx p | - fwdFlowIn(call, p, cc, _, argAp, ap, config) and + fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) ) } @@ -1924,24 +2290,24 @@ private module Stage3 { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) @@ -1953,14 +2319,16 @@ private module Stage3 { DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } pragma[nomagic] - private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) { - fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config) + private predicate returnNodeMayFlowThrough( + RetNodeEx ret, FlowState state, Ap ap, Configuration config + ) { + fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) } /** @@ -1972,44 +2340,56 @@ private module Stage3 { * the access path of the returned value. */ pragma[nomagic] - predicate revFlow(NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config) { - revFlow0(node, toReturn, returnAp, ap, config) and - fwdFlow(node, _, _, ap, config) + predicate revFlow( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + revFlow0(node, state, toReturn, returnAp, ap, config) and + fwdFlow(node, state, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { - fwdFlow(node, _, _, ap, config) and - sinkNode(node, config) and + fwdFlow(node, state, _, _, ap, config) and + sinkNode(node, state, config) and (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and returnAp = apNone() and ap instanceof ApNil or - exists(NodeEx mid | - localStep(node, mid, true, _, config, _) and - revFlow(mid, toReturn, returnAp, ap, config) + exists(NodeEx mid, FlowState state0 | + localStep(node, state, mid, state0, true, _, config, _) and + revFlow(mid, state0, toReturn, returnAp, ap, config) ) or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - localStep(node, mid, false, _, config, _) and - revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and + revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and - revFlow(mid, _, _, ap, config) and + revFlow(mid, state, _, _, ap, config) and toReturn = false and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and + revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and + toReturn = false and + returnAp = apNone() and + ap instanceof ApNil + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + additionalJumpStateStep(node, state, mid, state0, config) and + revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, + pragma[only_bind_into](config)) and toReturn = false and returnAp = apNone() and ap instanceof ApNil @@ -2017,39 +2397,39 @@ private module Stage3 { or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, toReturn, returnAp, ap0, config) and + revFlow(mid, state, toReturn, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, returnAp, ap, config) and + revFlowInNotToReturn(node, state, returnAp, ap, config) and toReturn = false or exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowInToReturn(call, node, state, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, _, _, ap, config) and + revFlowOut(_, node, state, _, _, ap, config) and toReturn = true and - if returnNodeMayFlowThrough(node, ap, config) + if returnNodeMayFlowThrough(node, state, ap, config) then returnAp = apSome(ap) else returnAp = apNone() } pragma[nomagic] private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, TypedContent tc, NodeEx mid, boolean toReturn, - ApOption returnAp, Configuration config + Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, + boolean toReturn, ApOption returnAp, Configuration config ) { - revFlow(mid, toReturn, returnAp, ap0, config) and + revFlow(mid, state, toReturn, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -2061,7 +2441,7 @@ private module Stage3 { pragma[nomagic] private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, tail, config) and + revFlow(mid, _, _, _, tail, config) and tail = pragma[only_bind_into](tail0) and readStepFwd(_, cons, c, mid, tail0, config) ) @@ -2069,11 +2449,11 @@ private module Stage3 { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, boolean toReturn, ApOption returnAp, Ap ap, + DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, toReturn, returnAp, ap, config) and + revFlow(out, state, toReturn, returnAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -2081,10 +2461,10 @@ private module Stage3 { pragma[nomagic] private predicate revFlowInNotToReturn( - ArgNodeEx arg, ApOption returnAp, Ap ap, Configuration config + ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, false, returnAp, ap, config) and + revFlow(p, state, false, returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -2092,10 +2472,10 @@ private module Stage3 { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, true, apSome(returnAp), ap, config) and + revFlow(p, state, true, apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -2110,9 +2490,9 @@ private module Stage3 { private predicate revFlowIsReturned( DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { - exists(RetNodeEx ret, CcCall ccc | - revFlowOut(call, ret, toReturn, returnAp, ap, config) and - fwdFlow(ret, ccc, apSome(_), ap, config) and + exists(RetNodeEx ret, FlowState state, CcCall ccc | + revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and + fwdFlow(ret, state, ccc, apSome(_), ap, config) and ccc.matchesCall(call) ) } @@ -2123,46 +2503,77 @@ private module Stage3 { Configuration config ) { exists(Ap ap2, Content c | - store(node1, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, tc, node2, _, _, config) and + PrevStage::storeStepCand(node1, _, tc, node2, contentType, config) and + revFlowStore(ap2, c, ap1, node1, _, tc, node2, _, _, config) and revFlowConsCand(ap2, c, ap1, config) ) } predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and + revFlow(node2, _, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, + revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _, pragma[only_bind_into](config)) ) } - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, config) } + predicate revFlow(NodeEx node, FlowState state, Configuration config) { + revFlow(node, state, _, _, _, config) + } + + pragma[nomagic] + predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + predicate revFlowAlias( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + revFlow(node, state, toReturn, returnAp, ap, config) + } private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { storeStepFwd(_, ap, tc, _, _, config) } - predicate consCand(TypedContent tc, Ap ap, Configuration config) { + private predicate revConsCand(TypedContent tc, Ap ap, Configuration config) { storeStepCand(_, ap, tc, _, _, config) } + private predicate validAp(Ap ap, Configuration config) { + revFlow(_, _, _, _, ap, config) and ap instanceof ApNil + or + exists(TypedContent head, Ap tail | + consCand(head, tail, config) and + ap = apCons(head, tail) + ) + } + + predicate consCand(TypedContent tc, Ap ap, Configuration config) { + revConsCand(tc, ap, config) and + validAp(ap, config) + } + pragma[noinline] private predicate parameterFlow( ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config ) { - revFlow(p, true, apSome(ap0), ap, config) and + revFlow(p, _, true, apSome(ap0), ap, config) and c = p.getEnclosingCallable() } predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos | + exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | parameterFlow(p, ap, ap0, c, config) and c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0), - pragma[only_bind_into](config)) and - fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and + revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), + pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and + fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and kind = ret.getKind() and p.getPosition() = pos and // we don't expect a parameter to return stored in itself, unless explicitly allowed @@ -2176,25 +2587,37 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, ArgNodeEx arg, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(arg, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, returnAp0, ap, config) and + exists( + Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + | + revFlow(arg, state, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } - predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { + predicate stats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config + ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - tuples = count(NodeEx n, Cc cc, ApOption argAp, Ap ap | fwdFlow(n, cc, argAp, ap, config)) + states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, argAp, ap, config) + ) or fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, config)) and + nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and fields = count(TypedContent f0 | consCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - tuples = count(NodeEx n, boolean b, ApOption retAp, Ap ap | revFlow(n, b, retAp, ap, config)) + states = count(FlowState state | revFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | + revFlow(n, state, b, retAp, ap, config) + ) } /* End: Stage 3 logic. */ } @@ -2203,10 +2626,12 @@ private module Stage3 { * Holds if `argApf` is recorded as the summary context for flow reaching `node` * and remains relevant for the following pruning stage. */ -private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { +private predicate flowCandSummaryCtx( + NodeEx node, FlowState state, AccessPathFront argApf, Configuration config +) { exists(AccessPathFront apf | - Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, true, _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2218,10 +2643,10 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) exists(int tails, int nodes, int apLimit, int tupleLimit | tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and nodes = - strictcount(NodeEx n | - Stage3::revFlow(n, _, _, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + strictcount(NodeEx n, FlowState state | + Stage3::revFlow(n, state, _, _, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or - flowCandSummaryCtx(n, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and @@ -2454,27 +2879,31 @@ private module Stage4 { if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() } - bindingset[node, cc, config] - private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { - localFlowEntry(node, config) and + bindingset[node, cc] + private LocalCc getLocalCc(NodeEx node, Cc cc) { result = getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), node.getEnclosingCallable()) } private predicate localStep( - NodeEx node1, NodeEx node2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, node2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) } pragma[nomagic] private predicate flowOutOfCall( DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and - PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and - PrevStage::revFlow(node1, _, _, _, pragma[only_bind_into](config)) + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, _, _, + pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, _, _, + pragma[only_bind_into](config)) + ) } pragma[nomagic] @@ -2482,28 +2911,31 @@ private module Stage4 { DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and - PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and - PrevStage::revFlow(node1, _, _, _, pragma[only_bind_into](config)) + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, _, _, + pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, _, _, + pragma[only_bind_into](config)) + ) } - bindingset[node, ap] - private predicate filter(NodeEx node, Ap ap) { any() } + bindingset[node, state, ap, config] + private predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { any() } // Type checking is not necessary here as it has already been done in stage 3. bindingset[ap, contentType] private predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } /* Begin: Stage 4 logic. */ - private predicate flowCand(NodeEx node, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, _, _, apa, config) + bindingset[node, state, config] + private predicate flowCand(NodeEx node, FlowState state, ApApprox apa, Configuration config) { + PrevStage::revFlow(node, state, _, _, apa, config) } bindingset[result, apa] private ApApprox unbindApa(ApApprox apa) { - exists(ApApprox apa0 | - apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0) - ) + pragma[only_bind_out](apa) = pragma[only_bind_out](result) } pragma[nomagic] @@ -2527,63 +2959,70 @@ private module Stage4 { * argument. */ pragma[nomagic] - predicate fwdFlow(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, cc, argAp, ap, config) and - flowCand(node, unbindApa(getApprox(ap)), config) and - filter(node, ap) + predicate fwdFlow(NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config) { + fwdFlow0(node, state, cc, argAp, ap, config) and + flowCand(node, state, unbindApa(getApprox(ap)), config) and + filter(node, state, ap, config) } pragma[nomagic] - private predicate fwdFlow0(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - flowCand(node, _, config) and - sourceNode(node, config) and + private predicate fwdFlow0( + NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + ) { + sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and ap = getApNil(node) or - exists(NodeEx mid, Ap ap0, LocalCc localCc | - fwdFlow(mid, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc, config) + exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | + fwdFlow(mid, state0, cc, argAp, ap0, config) and + localCc = getLocalCc(mid, cc) | - localStep(mid, node, true, _, config, localCc) and + localStep(mid, state0, node, state, true, _, config, localCc) and ap = ap0 or - localStep(mid, node, false, ap, config, localCc) and + localStep(mid, state0, node, state, false, ap, config, localCc) and ap0 instanceof ApNil ) or exists(NodeEx mid | - fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and argAp = apNone() and ap = getApNil(node) ) or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + additionalJumpStateStep(mid, state0, node, state, config) and + cc = ccNone() and + argAp = apNone() and + ap = getApNil(node) + ) + or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, ap, config) and apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, _, apa, config) then argAp = apSome(ap) @@ -2591,20 +3030,21 @@ private module Stage4 { ) or // flow out of a callable - fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) or exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Cc cc, ApOption argAp, Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -2617,7 +3057,7 @@ private module Stage4 { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -2625,20 +3065,21 @@ private module Stage4 { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, Cc cc, ApOption argAp, Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + Configuration config ) { - fwdFlow(node1, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, Cc outercc, Cc innercc, ApOption argAp, Ap ap, - Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, + Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -2647,13 +3088,13 @@ private module Stage4 { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, innercc, argAp, ap, config) and + fwdFlow(ret, state, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and @@ -2663,10 +3104,10 @@ private module Stage4 { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config ) { exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, ccc, apSome(argAp), ap, config) and + fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -2681,7 +3122,7 @@ private module Stage4 { DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config ) { exists(ParamNodeEx p | - fwdFlowIn(call, p, cc, _, argAp, ap, config) and + fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) ) } @@ -2690,24 +3131,24 @@ private module Stage4 { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) @@ -2719,14 +3160,16 @@ private module Stage4 { DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } pragma[nomagic] - private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) { - fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config) + private predicate returnNodeMayFlowThrough( + RetNodeEx ret, FlowState state, Ap ap, Configuration config + ) { + fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) } /** @@ -2738,44 +3181,56 @@ private module Stage4 { * the access path of the returned value. */ pragma[nomagic] - predicate revFlow(NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config) { - revFlow0(node, toReturn, returnAp, ap, config) and - fwdFlow(node, _, _, ap, config) + predicate revFlow( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + revFlow0(node, state, toReturn, returnAp, ap, config) and + fwdFlow(node, state, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { - fwdFlow(node, _, _, ap, config) and - sinkNode(node, config) and + fwdFlow(node, state, _, _, ap, config) and + sinkNode(node, state, config) and (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and returnAp = apNone() and ap instanceof ApNil or - exists(NodeEx mid | - localStep(node, mid, true, _, config, _) and - revFlow(mid, toReturn, returnAp, ap, config) + exists(NodeEx mid, FlowState state0 | + localStep(node, state, mid, state0, true, _, config, _) and + revFlow(mid, state0, toReturn, returnAp, ap, config) ) or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - localStep(node, mid, false, _, config, _) and - revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and + revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and - revFlow(mid, _, _, ap, config) and + revFlow(mid, state, _, _, ap, config) and toReturn = false and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and + revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and + toReturn = false and + returnAp = apNone() and + ap instanceof ApNil + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + additionalJumpStateStep(node, state, mid, state0, config) and + revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, + pragma[only_bind_into](config)) and toReturn = false and returnAp = apNone() and ap instanceof ApNil @@ -2783,39 +3238,39 @@ private module Stage4 { or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, toReturn, returnAp, ap0, config) and + revFlow(mid, state, toReturn, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, returnAp, ap, config) and + revFlowInNotToReturn(node, state, returnAp, ap, config) and toReturn = false or exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowInToReturn(call, node, state, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, _, _, ap, config) and + revFlowOut(_, node, state, _, _, ap, config) and toReturn = true and - if returnNodeMayFlowThrough(node, ap, config) + if returnNodeMayFlowThrough(node, state, ap, config) then returnAp = apSome(ap) else returnAp = apNone() } pragma[nomagic] private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, TypedContent tc, NodeEx mid, boolean toReturn, - ApOption returnAp, Configuration config + Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, + boolean toReturn, ApOption returnAp, Configuration config ) { - revFlow(mid, toReturn, returnAp, ap0, config) and + revFlow(mid, state, toReturn, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -2827,7 +3282,7 @@ private module Stage4 { pragma[nomagic] private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, tail, config) and + revFlow(mid, _, _, _, tail, config) and tail = pragma[only_bind_into](tail0) and readStepFwd(_, cons, c, mid, tail0, config) ) @@ -2835,11 +3290,11 @@ private module Stage4 { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, boolean toReturn, ApOption returnAp, Ap ap, + DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, toReturn, returnAp, ap, config) and + revFlow(out, state, toReturn, returnAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -2847,10 +3302,10 @@ private module Stage4 { pragma[nomagic] private predicate revFlowInNotToReturn( - ArgNodeEx arg, ApOption returnAp, Ap ap, Configuration config + ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, false, returnAp, ap, config) and + revFlow(p, state, false, returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -2858,10 +3313,10 @@ private module Stage4 { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, true, apSome(returnAp), ap, config) and + revFlow(p, state, true, apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -2876,9 +3331,9 @@ private module Stage4 { private predicate revFlowIsReturned( DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { - exists(RetNodeEx ret, CcCall ccc | - revFlowOut(call, ret, toReturn, returnAp, ap, config) and - fwdFlow(ret, ccc, apSome(_), ap, config) and + exists(RetNodeEx ret, FlowState state, CcCall ccc | + revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and + fwdFlow(ret, state, ccc, apSome(_), ap, config) and ccc.matchesCall(call) ) } @@ -2889,46 +3344,77 @@ private module Stage4 { Configuration config ) { exists(Ap ap2, Content c | - store(node1, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, tc, node2, _, _, config) and + PrevStage::storeStepCand(node1, _, tc, node2, contentType, config) and + revFlowStore(ap2, c, ap1, node1, _, tc, node2, _, _, config) and revFlowConsCand(ap2, c, ap1, config) ) } predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and + revFlow(node2, _, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, + revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _, pragma[only_bind_into](config)) ) } - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, config) } + predicate revFlow(NodeEx node, FlowState state, Configuration config) { + revFlow(node, state, _, _, _, config) + } + + pragma[nomagic] + predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + predicate revFlowAlias( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + revFlow(node, state, toReturn, returnAp, ap, config) + } private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { storeStepFwd(_, ap, tc, _, _, config) } - predicate consCand(TypedContent tc, Ap ap, Configuration config) { + private predicate revConsCand(TypedContent tc, Ap ap, Configuration config) { storeStepCand(_, ap, tc, _, _, config) } + private predicate validAp(Ap ap, Configuration config) { + revFlow(_, _, _, _, ap, config) and ap instanceof ApNil + or + exists(TypedContent head, Ap tail | + consCand(head, tail, config) and + ap = apCons(head, tail) + ) + } + + predicate consCand(TypedContent tc, Ap ap, Configuration config) { + revConsCand(tc, ap, config) and + validAp(ap, config) + } + pragma[noinline] private predicate parameterFlow( ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config ) { - revFlow(p, true, apSome(ap0), ap, config) and + revFlow(p, _, true, apSome(ap0), ap, config) and c = p.getEnclosingCallable() } predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos | + exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | parameterFlow(p, ap, ap0, c, config) and c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0), - pragma[only_bind_into](config)) and - fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and + revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), + pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and + fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and kind = ret.getKind() and p.getPosition() = pos and // we don't expect a parameter to return stored in itself, unless explicitly allowed @@ -2942,25 +3428,37 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, ArgNodeEx arg, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(arg, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, returnAp0, ap, config) and + exists( + Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + | + revFlow(arg, state, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } - predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { + predicate stats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config + ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - tuples = count(NodeEx n, Cc cc, ApOption argAp, Ap ap | fwdFlow(n, cc, argAp, ap, config)) + states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, argAp, ap, config) + ) or fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, config)) and + nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and fields = count(TypedContent f0 | consCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - tuples = count(NodeEx n, boolean b, ApOption retAp, Ap ap | revFlow(n, b, retAp, ap, config)) + states = count(FlowState state | revFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | + revFlow(n, state, b, retAp, ap, config) + ) } /* End: Stage 4 logic. */ } @@ -2970,19 +3468,35 @@ private Configuration unbindConf(Configuration conf) { exists(Configuration c | result = pragma[only_bind_into](c) and conf = pragma[only_bind_into](c)) } -private predicate nodeMayUseSummary(NodeEx n, AccessPathApprox apa, Configuration config) { - exists(DataFlowCallable c, AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, apa, _) and - Stage4::revFlow(n, true, _, apa0, config) and - Stage4::fwdFlow(n, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and +pragma[nomagic] +private predicate nodeMayUseSummary0( + NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config +) { + exists(AccessPathApprox apa0 | + Stage4::parameterMayFlowThrough(_, c, _, _) and + Stage4::revFlow(n, state, true, _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and n.getEnclosingCallable() = c ) } +pragma[nomagic] +private predicate nodeMayUseSummary( + NodeEx n, FlowState state, AccessPathApprox apa, Configuration config +) { + exists(DataFlowCallable c | + Stage4::parameterMayFlowThrough(_, c, apa, config) and + nodeMayUseSummary0(n, c, state, apa, config) + ) +} + private newtype TSummaryCtx = TSummaryCtxNone() or - TSummaryCtxSome(ParamNodeEx p, AccessPath ap) { - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), _) + TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { + exists(Configuration config | + Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::revFlow(p, state, _, _, _, config) + ) } /** @@ -3003,11 +3517,12 @@ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone { /** A summary context from which a flow summary can be generated. */ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome { private ParamNodeEx p; + private FlowState s; private AccessPath ap; - SummaryCtxSome() { this = TSummaryCtxSome(p, ap) } + SummaryCtxSome() { this = TSummaryCtxSome(p, s, ap) } - int getParameterPos() { p.isParameterOf(_, result) } + ParameterPosition getParameterPos() { p.isParameterOf(_, result) } ParamNodeEx getParamNode() { result = p } @@ -3037,8 +3552,8 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = - strictcount(NodeEx n | - Stage4::revFlow(n, _, _, apa, config) or nodeMayUseSummary(n, apa, config) + strictcount(NodeEx n, FlowState state | + Stage4::revFlow(n, state, _, _, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -3134,10 +3649,12 @@ private newtype TAccessPath = } private newtype TPathNode = - TPathNodeMid(NodeEx node, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config) { + TPathNodeMid( + NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config + ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, config) and - sourceNode(node, config) and + Stage4::revFlow(node, state, config) and + sourceNode(node, state, config) and ( if hasSourceCallCtx(config) then cc instanceof CallContextSomeCall @@ -3148,15 +3665,16 @@ private newtype TPathNode = or // ... or a step from an existing PathNode to another node. exists(PathNodeMid mid | - pathStep(mid, node, cc, sc, ap) and + pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, _, _, ap.getApprox(), pragma[only_bind_into](config)) + Stage4::revFlow(node, state, _, _, ap.getApprox(), pragma[only_bind_into](config)) ) } or - TPathNodeSink(NodeEx node, Configuration config) { + TPathNodeSink(NodeEx node, FlowState state, Configuration config) { exists(PathNodeMid sink | sink.isAtSink() and node = sink.getNodeEx() and + state = sink.getState() and config = sink.getConfiguration() ) } @@ -3167,7 +3685,7 @@ private newtype TPathNode = * of dereference operations needed to get from the value in the node to the * tracked object. The final type indicates the type of the tracked object. */ -abstract private class AccessPath extends TAccessPath { +private class AccessPath extends TAccessPath { /** Gets the head of this access path, if any. */ abstract TypedContent getHead(); @@ -3354,19 +3872,17 @@ class PathNode extends TPathNode { /** Gets the underlying `Node`. */ final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result } + /** Gets the `FlowState` of this node. */ + FlowState getState() { none() } + /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3374,16 +3890,30 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); predicate isHidden() { - hiddenNode(this.getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.getNodeEx() instanceof TNodeImplicitRead + not this.getConfiguration().includeHiddenNodes() and + ( + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + ) } private string ppAp() { @@ -3414,15 +3944,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } -/** Holds if `n` can reach a sink or is used in a subpath. */ +/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3431,14 +3963,25 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } - query predicate subpaths = Subpaths::subpaths/4; + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) { + Subpaths::subpaths(arg, par, ret, out) and + reach(arg) and + reach(par) and + reach(ret) and + reach(out) + } } /** @@ -3447,15 +3990,18 @@ module PathGraph { */ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { NodeEx node; + FlowState state; CallContext cc; SummaryCtx sc; AccessPath ap; Configuration config; - PathNodeMid() { this = TPathNodeMid(node, cc, sc, ap, config) } + PathNodeMid() { this = TPathNodeMid(node, state, cc, sc, ap, config) } override NodeEx getNodeEx() { result = node } + override FlowState getState() { result = state } + CallContext getCallContext() { result = cc } SummaryCtx getSummaryCtx() { result = sc } @@ -3465,8 +4011,8 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { override Configuration getConfiguration() { result = config } private PathNodeMid getSuccMid() { - pathStep(this, result.getNodeEx(), result.getCallContext(), result.getSummaryCtx(), - result.getAp()) and + pathStep(this, result.getNodeEx(), result.getState(), result.getCallContext(), + result.getSummaryCtx(), result.getAp()) and result.getConfiguration() = unbindConf(this.getConfiguration()) } @@ -3479,7 +4025,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { } override predicate isSource() { - sourceNode(node, config) and + sourceNode(node, state, config) and ( if hasSourceCallCtx(config) then cc instanceof CallContextSomeCall @@ -3490,7 +4036,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { } predicate isAtSink() { - sinkNode(node, config) and + sinkNode(node, state, config) and ap instanceof AccessPathNil and if hasSinkCallCtx(config) then @@ -3512,6 +4058,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { PathNodeSink projectToSink() { this.isAtSink() and result.getNodeEx() = node and + result.getState() = state and result.getConfiguration() = unbindConf(config) } } @@ -3523,91 +4070,117 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { */ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { NodeEx node; + FlowState state; Configuration config; - PathNodeSink() { this = TPathNodeSink(node, config) } + PathNodeSink() { this = TPathNodeSink(node, state, config) } override NodeEx getNodeEx() { result = node } + override FlowState getState() { result = state } + override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } - override predicate isSource() { sourceNode(node, config) } + override predicate isSource() { sourceNode(node, state, config) } +} + +private predicate pathNode( + PathNodeMid mid, NodeEx midnode, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, + Configuration conf, LocalCallContext localCC +) { + midnode = mid.getNodeEx() and + state = mid.getState() and + conf = mid.getConfiguration() and + cc = mid.getCallContext() and + sc = mid.getSummaryCtx() and + localCC = + getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), + midnode.getEnclosingCallable()) and + ap = mid.getAp() } /** * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ +pragma[nomagic] private predicate pathStep( - PathNodeMid mid, NodeEx node, CallContext cc, SummaryCtx sc, AccessPath ap + PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap ) { - exists(AccessPath ap0, NodeEx midnode, Configuration conf, LocalCallContext localCC | - midnode = mid.getNodeEx() and - conf = mid.getConfiguration() and - cc = mid.getCallContext() and - sc = mid.getSummaryCtx() and - localCC = - getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), - midnode.getEnclosingCallable()) and - ap0 = mid.getAp() + exists(NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | + pathNode(mid, midnode, state0, cc, sc, ap, conf, localCC) and + localFlowBigStep(midnode, state0, node, state, true, _, conf, localCC) + ) + or + exists( + AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | - localFlowBigStep(midnode, node, true, _, conf, localCC) and - ap = ap0 - or - localFlowBigStep(midnode, node, false, ap.getFront(), conf, localCC) and + pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and ap0 instanceof AccessPathNil ) or jumpStep(mid.getNodeEx(), node, mid.getConfiguration()) and + state = mid.getState() and cc instanceof CallContextAny and sc instanceof SummaryCtxNone and ap = mid.getAp() or additionalJumpStep(mid.getNodeEx(), node, mid.getConfiguration()) and + state = mid.getState() and cc instanceof CallContextAny and sc instanceof SummaryCtxNone and mid.getAp() instanceof AccessPathNil and ap = TAccessPathNil(node.getDataFlowType()) or - exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and + additionalJumpStateStep(mid.getNodeEx(), mid.getState(), node, state, mid.getConfiguration()) and + cc instanceof CallContextAny and + sc instanceof SummaryCtxNone and + mid.getAp() instanceof AccessPathNil and + ap = TAccessPathNil(node.getDataFlowType()) + or + exists(TypedContent tc | pathStoreStep(mid, node, state, ap.pop(tc), tc, cc)) and sc = mid.getSummaryCtx() or - exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and + exists(TypedContent tc | pathReadStep(mid, node, state, ap.push(tc), tc, cc)) and sc = mid.getSummaryCtx() or - pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp() + pathIntoCallable(mid, node, state, _, cc, sc, _, _) and ap = mid.getAp() or - pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone + pathOutOfCallable(mid, node, state, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone or - pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx() + pathThroughCallable(mid, node, state, cc, ap) and sc = mid.getSummaryCtx() } pragma[nomagic] private predicate pathReadStep( - PathNodeMid mid, NodeEx node, AccessPath ap0, TypedContent tc, CallContext cc + PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and tc = ap0.getHead() and Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + state = mid.getState() and cc = mid.getCallContext() } pragma[nomagic] private predicate pathStoreStep( - PathNodeMid mid, NodeEx node, AccessPath ap0, TypedContent tc, CallContext cc + PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + state = mid.getState() and cc = mid.getCallContext() } private predicate pathOutOfCallable0( - PathNodeMid mid, ReturnPosition pos, CallContext innercc, AccessPathApprox apa, + PathNodeMid mid, ReturnPosition pos, FlowState state, CallContext innercc, AccessPathApprox apa, Configuration config ) { pos = mid.getNodeEx().(RetNodeEx).getReturnPosition() and + state = mid.getState() and innercc = mid.getCallContext() and innercc instanceof CallContextNoCall and apa = mid.getAp().getApprox() and @@ -3616,11 +4189,11 @@ private predicate pathOutOfCallable0( pragma[nomagic] private predicate pathOutOfCallable1( - PathNodeMid mid, DataFlowCall call, ReturnKindExt kind, CallContext cc, AccessPathApprox apa, - Configuration config + PathNodeMid mid, DataFlowCall call, ReturnKindExt kind, FlowState state, CallContext cc, + AccessPathApprox apa, Configuration config ) { exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc | - pathOutOfCallable0(mid, pos, innercc, apa, config) and + pathOutOfCallable0(mid, pos, state, innercc, apa, config) and c = pos.getCallable() and kind = pos.getKind() and resolveReturn(innercc, c, call) @@ -3634,7 +4207,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, _, apa, config) + Stage4::revFlow(result, _, _, _, apa, config) } /** @@ -3642,9 +4215,9 @@ private NodeEx getAnOutNodeFlow( * is a return from a callable and is recorded by `cc`, if needed. */ pragma[noinline] -private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc) { +private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, FlowState state, CallContext cc) { exists(ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config | - pathOutOfCallable1(mid, call, kind, cc, apa, config) and + pathOutOfCallable1(mid, call, kind, state, cc, apa, config) and out = getAnOutNodeFlow(kind, call, apa, config) ) } @@ -3654,39 +4227,37 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc) */ pragma[noinline] private predicate pathIntoArg( - PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa, - Configuration config + PathNodeMid mid, ParameterPosition ppos, FlowState state, CallContext cc, DataFlowCall call, + AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(ArgNode arg | - arg = mid.getNodeEx().asNode() and - cc = mid.getCallContext() and - arg.argumentOf(call, i) and - ap = mid.getAp() and + exists(ArgNodeEx arg, ArgumentPosition apos | + pathNode(mid, arg, state, cc, _, ap, config, _) and + arg.asNode().(ArgNode).argumentOf(call, apos) and apa = ap.getApprox() and - config = mid.getConfiguration() + parameterMatch(ppos, apos) ) } pragma[nomagic] private predicate parameterCand( - DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config + DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, _, apa, config) and - p.isParameterOf(callable, i) + Stage4::revFlow(p, _, _, _, apa, config) and + p.isParameterOf(callable, pos) ) } pragma[nomagic] private predicate pathIntoCallable0( - PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call, - AccessPath ap, Configuration config + PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, FlowState state, + CallContext outercc, DataFlowCall call, AccessPath ap, Configuration config ) { exists(AccessPathApprox apa | - pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa), - pragma[only_bind_into](config)) and + pathIntoArg(mid, pragma[only_bind_into](pos), state, outercc, call, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and callable = resolveCall(call, outercc) and - parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa), + parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa), pragma[only_bind_into](config)) ) } @@ -3698,16 +4269,16 @@ private predicate pathIntoCallable0( */ pragma[nomagic] private predicate pathIntoCallable( - PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc, - DataFlowCall call, Configuration config + PathNodeMid mid, ParamNodeEx p, FlowState state, CallContext outercc, CallContextCall innercc, + SummaryCtx sc, DataFlowCall call, Configuration config ) { - exists(int i, DataFlowCallable callable, AccessPath ap | - pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and - p.isParameterOf(callable, i) and + exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap | + pathIntoCallable0(mid, callable, pos, state, outercc, call, ap, config) and + p.isParameterOf(callable, pos) and ( - sc = TSummaryCtxSome(p, ap) + sc = TSummaryCtxSome(p, state, ap) or - not exists(TSummaryCtxSome(p, ap)) and + not exists(TSummaryCtxSome(p, state, ap)) and sc = TSummaryCtxNone() and // When the call contexts of source and sink needs to match then there's // never any reason to enter a callable except to find a summary. See also @@ -3724,16 +4295,12 @@ private predicate pathIntoCallable( /** Holds if data may flow from a parameter given by `sc` to a return of kind `kind`. */ pragma[nomagic] private predicate paramFlowsThrough( - ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, - Configuration config + ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, + AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, int pos | - mid.getNodeEx() = ret and + exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and - cc = mid.getCallContext() and - sc = mid.getSummaryCtx() and - config = mid.getConfiguration() and - ap = mid.getAp() and apa = ap.getApprox() and pos = sc.getParameterPos() and // we don't expect a parameter to return stored in itself, unless explicitly allowed @@ -3747,12 +4314,12 @@ private predicate paramFlowsThrough( pragma[nomagic] private predicate pathThroughCallable0( - DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap, - AccessPathApprox apa, Configuration config + DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, FlowState state, CallContext cc, + AccessPath ap, AccessPathApprox apa, Configuration config ) { exists(CallContext innercc, SummaryCtx sc | - pathIntoCallable(mid, _, cc, innercc, sc, call, config) and - paramFlowsThrough(kind, innercc, sc, ap, apa, config) + pathIntoCallable(mid, _, _, cc, innercc, sc, call, config) and + paramFlowsThrough(kind, state, innercc, sc, ap, apa, config) ) } @@ -3761,9 +4328,11 @@ private predicate pathThroughCallable0( * The context `cc` is restored to its value prior to entering the callable. */ pragma[noinline] -private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) { +private predicate pathThroughCallable( + PathNodeMid mid, NodeEx out, FlowState state, CallContext cc, AccessPath ap +) { exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config | - pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and + pathThroughCallable0(call, mid, kind, state, cc, ap, apa, config) and out = getAnOutNodeFlow(kind, call, apa, config) ) } @@ -3776,26 +4345,27 @@ private module Subpaths { pragma[nomagic] private predicate subpaths01( PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, - NodeEx out, AccessPath apout + NodeEx out, FlowState sout, AccessPath apout ) { exists(Configuration config | - pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and - pathIntoCallable(arg, par, _, innercc, sc, _, config) and - paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config)) and + pathThroughCallable(arg, out, pragma[only_bind_into](sout), _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, _, innercc, sc, _, config) and + paramFlowsThrough(kind, pragma[only_bind_into](sout), innercc, sc, + pragma[only_bind_into](apout), _, unbindConf(config)) and not arg.isHidden() ) } /** * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by - * `kind`, `sc`, `apout`, and `innercc`. + * `kind`, `sc`, `sout`, `apout`, and `innercc`. */ pragma[nomagic] private predicate subpaths02( PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, - NodeEx out, AccessPath apout + NodeEx out, FlowState sout, AccessPath apout ) { - subpaths01(arg, par, sc, innercc, kind, out, apout) and + subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and out.asNode() = kind.getAnOutNode(_) } @@ -3807,16 +4377,12 @@ private module Subpaths { */ pragma[nomagic] private predicate subpaths03( - PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout ) { exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | - subpaths02(arg, par, sc, innercc, kind, out, apout) and - ret.getNodeEx() = retnode and - kind = retnode.getKind() and - innercc = ret.getCallContext() and - sc = ret.getSummaryCtx() and - ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and - apout = ret.getAp() + subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and + pathNode(ret, retnode, sout, innercc, sc, apout, unbindConf(getPathNodeConf(arg)), _) and + kind = retnode.getKind() ) } @@ -3824,38 +4390,44 @@ private module Subpaths { n.getASuccessorImpl() = result and result.isHidden() and exists(NodeEx n1, NodeEx n2 | n1 = n.getNodeEx() and n2 = result.getNodeEx() | - localFlowBigStep(n1, n2, _, _, _, _) or + localFlowBigStep(n1, _, n2, _, _, _, _, _) or store(n1, _, n2, _, _) or - read(n1, _, n2, _) + readSet(n1, _, n2, _) ) } + pragma[nomagic] + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and + succNode = succ.getNodeEx() + } + /** * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNodeMid out) { - exists(ParamNodeEx p, NodeEx o, AccessPath apout | - pragma[only_bind_into](arg).getASuccessor() = par and - pragma[only_bind_into](arg).getASuccessor() = out and - subpaths03(arg, p, localStepToHidden*(ret), o, apout) and + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and + subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and + hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and - par.getNodeEx() = p and - out.getNodeEx() = o and - out.getAp() = apout + pathNode(out0, o, sout, _, _, apout, _, _) + | + out = out0 or out = out0.projectToSink() ) } /** - * Holds if `n` can reach a return node in a summarized subpath. + * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { - subpaths(_, _, n, _) + predicate retReach(PathNodeImpl n) { + exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } @@ -3887,17 +4459,21 @@ predicate flowsTo(Node source, Node sink, Configuration configuration) { flowsTo(_, _, source, sink, configuration) } -private predicate finalStats(boolean fwd, int nodes, int fields, int conscand, int tuples) { +private predicate finalStats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples +) { fwd = true and nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0)) and fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and + states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and tuples = count(PathNode pn) or fwd = false and nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and + states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and tuples = count(PathNode pn | reach(pn)) } @@ -3907,27 +4483,44 @@ private predicate finalStats(boolean fwd, int nodes, int fields, int conscand, i * Calculates per-stage metrics for data flow. */ predicate stageStats( - int n, string stage, int nodes, int fields, int conscand, int tuples, Configuration config + int n, string stage, int nodes, int fields, int conscand, int states, int tuples, + Configuration config ) { - stage = "1 Fwd" and n = 10 and Stage1::stats(true, nodes, fields, conscand, tuples, config) + stage = "1 Fwd" and + n = 10 and + Stage1::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "1 Rev" and n = 15 and Stage1::stats(false, nodes, fields, conscand, tuples, config) + stage = "1 Rev" and + n = 15 and + Stage1::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "2 Fwd" and n = 20 and Stage2::stats(true, nodes, fields, conscand, tuples, config) + stage = "2 Fwd" and + n = 20 and + Stage2::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "2 Rev" and n = 25 and Stage2::stats(false, nodes, fields, conscand, tuples, config) + stage = "2 Rev" and + n = 25 and + Stage2::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "3 Fwd" and n = 30 and Stage3::stats(true, nodes, fields, conscand, tuples, config) + stage = "3 Fwd" and + n = 30 and + Stage3::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "3 Rev" and n = 35 and Stage3::stats(false, nodes, fields, conscand, tuples, config) + stage = "3 Rev" and + n = 35 and + Stage3::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "4 Fwd" and n = 40 and Stage4::stats(true, nodes, fields, conscand, tuples, config) + stage = "4 Fwd" and + n = 40 and + Stage4::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "4 Rev" and n = 45 and Stage4::stats(false, nodes, fields, conscand, tuples, config) + stage = "4 Rev" and + n = 45 and + Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, tuples) + stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, tuples) + stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { @@ -3937,6 +4530,8 @@ private module FlowExploration { or additionalJumpStep(node1, node2, config) or + additionalJumpStateStep(node1, _, node2, _, config) + or // flow into callable viableParamArgEx(_, node2, node1) or @@ -3950,7 +4545,7 @@ private module FlowExploration { } private predicate interestingCallableSrc(DataFlowCallable c, Configuration config) { - exists(Node n | config.isSource(n) and c = getNodeEnclosingCallable(n)) + exists(Node n | config.isSource(n) or config.isSource(n, _) | c = getNodeEnclosingCallable(n)) or exists(DataFlowCallable mid | interestingCallableSrc(mid, config) and callableStep(mid, c, config) @@ -3958,7 +4553,7 @@ private module FlowExploration { } private predicate interestingCallableSink(DataFlowCallable c, Configuration config) { - exists(Node n | config.isSink(n) and c = getNodeEnclosingCallable(n)) + exists(Node n | config.isSink(n) or config.isSink(n, _) | c = getNodeEnclosingCallable(n)) or exists(DataFlowCallable mid | interestingCallableSink(mid, config) and callableStep(c, mid, config) @@ -3986,13 +4581,13 @@ private module FlowExploration { or exists(Node n, Configuration config | ce1 = TCallableSrc() and - config.isSource(n) and + (config.isSource(n) or config.isSource(n, _)) and ce2 = TCallable(getNodeEnclosingCallable(n), config) ) or exists(Node n, Configuration config | ce2 = TCallableSink() and - config.isSink(n) and + (config.isSink(n) or config.isSink(n, _)) and ce1 = TCallable(getNodeEnclosingCallable(n), config) ) } @@ -4094,13 +4689,26 @@ private module FlowExploration { } } + private predicate relevantState(FlowState state) { + sourceNode(_, state, _) or + sinkNode(_, state, _) or + additionalLocalStateStep(_, state, _, _, _) or + additionalLocalStateStep(_, _, _, state, _) or + additionalJumpStateStep(_, state, _, _, _) or + additionalJumpStateStep(_, _, _, state, _) + } + private newtype TSummaryCtx1 = TSummaryCtx1None() or TSummaryCtx1Param(ParamNodeEx p) private newtype TSummaryCtx2 = TSummaryCtx2None() or - TSummaryCtx2Some(PartialAccessPath ap) + TSummaryCtx2Some(FlowState s) { relevantState(s) } + + private newtype TSummaryCtx3 = + TSummaryCtx3None() or + TSummaryCtx3Some(PartialAccessPath ap) private newtype TRevSummaryCtx1 = TRevSummaryCtx1None() or @@ -4108,52 +4716,66 @@ private module FlowExploration { private newtype TRevSummaryCtx2 = TRevSummaryCtx2None() or - TRevSummaryCtx2Some(RevPartialAccessPath ap) + TRevSummaryCtx2Some(FlowState s) { relevantState(s) } + + private newtype TRevSummaryCtx3 = + TRevSummaryCtx3None() or + TRevSummaryCtx3Some(RevPartialAccessPath ap) private newtype TPartialPathNode = TPartialPathNodeFwd( - NodeEx node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, PartialAccessPath ap, - Configuration config + NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, + TSummaryCtx3 sc3, PartialAccessPath ap, Configuration config ) { - sourceNode(node, config) and + sourceNode(node, state, config) and cc instanceof CallContextAny and sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and ap = TPartialNil(node.getDataFlowType()) and - not fullBarrier(node, config) and exists(config.explorationLimit()) or - partialPathNodeMk0(node, cc, sc1, sc2, ap, config) and + partialPathNodeMk0(node, state, cc, sc1, sc2, sc3, ap, config) and distSrc(node.getEnclosingCallable(), config) <= config.explorationLimit() } or TPartialPathNodeRev( - NodeEx node, TRevSummaryCtx1 sc1, TRevSummaryCtx2 sc2, RevPartialAccessPath ap, - Configuration config + NodeEx node, FlowState state, TRevSummaryCtx1 sc1, TRevSummaryCtx2 sc2, TRevSummaryCtx3 sc3, + RevPartialAccessPath ap, Configuration config ) { - sinkNode(node, config) and + sinkNode(node, state, config) and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and ap = TRevPartialNil() and - not fullBarrier(node, config) and exists(config.explorationLimit()) or exists(PartialPathNodeRev mid | - revPartialPathStep(mid, node, sc1, sc2, ap, config) and - not clearsContentCached(node.asNode(), ap.getHead()) and + revPartialPathStep(mid, node, state, sc1, sc2, sc3, ap, config) and + not clearsContentEx(node, ap.getHead()) and + ( + notExpectsContent(node) or + expectsContentEx(node, ap.getHead()) + ) and not fullBarrier(node, config) and + not stateBarrier(node, state, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) } pragma[nomagic] private predicate partialPathNodeMk0( - NodeEx node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, PartialAccessPath ap, - Configuration config + NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, + TSummaryCtx3 sc3, PartialAccessPath ap, Configuration config ) { exists(PartialPathNodeFwd mid | - partialPathStep(mid, node, cc, sc1, sc2, ap, config) and + partialPathStep(mid, node, state, cc, sc1, sc2, sc3, ap, config) and not fullBarrier(node, config) and - not clearsContentCached(node.asNode(), ap.getHead().getContent()) and + not stateBarrier(node, state, config) and + not clearsContentEx(node, ap.getHead().getContent()) and + ( + notExpectsContent(node) or + expectsContentEx(node, ap.getHead().getContent()) + ) and if node.asNode() instanceof CastingNode then compatibleTypes(node.getDataFlowType(), ap.getType()) else any() @@ -4191,6 +4813,8 @@ private module FlowExploration { /** Gets the underlying `Node`. */ final Node getNode() { this.getNodeEx().projectToNode() = result } + FlowState getState() { none() } + private NodeEx getNodeEx() { result = this.(PartialPathNodeFwd).getNodeEx() or result = this.(PartialPathNodeRev).getNodeEx() @@ -4248,135 +4872,182 @@ private module FlowExploration { private class PartialPathNodeFwd extends PartialPathNode, TPartialPathNodeFwd { NodeEx node; + FlowState state; CallContext cc; TSummaryCtx1 sc1; TSummaryCtx2 sc2; + TSummaryCtx3 sc3; PartialAccessPath ap; Configuration config; - PartialPathNodeFwd() { this = TPartialPathNodeFwd(node, cc, sc1, sc2, ap, config) } + PartialPathNodeFwd() { this = TPartialPathNodeFwd(node, state, cc, sc1, sc2, sc3, ap, config) } NodeEx getNodeEx() { result = node } + override FlowState getState() { result = state } + CallContext getCallContext() { result = cc } TSummaryCtx1 getSummaryCtx1() { result = sc1 } TSummaryCtx2 getSummaryCtx2() { result = sc2 } + TSummaryCtx3 getSummaryCtx3() { result = sc3 } + PartialAccessPath getAp() { result = ap } override Configuration getConfiguration() { result = config } override PartialPathNodeFwd getASuccessor() { - partialPathStep(this, result.getNodeEx(), result.getCallContext(), result.getSummaryCtx1(), - result.getSummaryCtx2(), result.getAp(), result.getConfiguration()) + partialPathStep(this, result.getNodeEx(), result.getState(), result.getCallContext(), + result.getSummaryCtx1(), result.getSummaryCtx2(), result.getSummaryCtx3(), result.getAp(), + result.getConfiguration()) } predicate isSource() { - sourceNode(node, config) and + sourceNode(node, state, config) and cc instanceof CallContextAny and sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and ap instanceof TPartialNil } } private class PartialPathNodeRev extends PartialPathNode, TPartialPathNodeRev { NodeEx node; + FlowState state; TRevSummaryCtx1 sc1; TRevSummaryCtx2 sc2; + TRevSummaryCtx3 sc3; RevPartialAccessPath ap; Configuration config; - PartialPathNodeRev() { this = TPartialPathNodeRev(node, sc1, sc2, ap, config) } + PartialPathNodeRev() { this = TPartialPathNodeRev(node, state, sc1, sc2, sc3, ap, config) } NodeEx getNodeEx() { result = node } + override FlowState getState() { result = state } + TRevSummaryCtx1 getSummaryCtx1() { result = sc1 } TRevSummaryCtx2 getSummaryCtx2() { result = sc2 } + TRevSummaryCtx3 getSummaryCtx3() { result = sc3 } + RevPartialAccessPath getAp() { result = ap } override Configuration getConfiguration() { result = config } override PartialPathNodeRev getASuccessor() { - revPartialPathStep(result, this.getNodeEx(), this.getSummaryCtx1(), this.getSummaryCtx2(), - this.getAp(), this.getConfiguration()) + revPartialPathStep(result, this.getNodeEx(), this.getState(), this.getSummaryCtx1(), + this.getSummaryCtx2(), this.getSummaryCtx3(), this.getAp(), this.getConfiguration()) } predicate isSink() { - sinkNode(node, config) and + sinkNode(node, state, config) and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and ap = TRevPartialNil() } } private predicate partialPathStep( - PartialPathNodeFwd mid, NodeEx node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - PartialAccessPath ap, Configuration config + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, PartialAccessPath ap, Configuration config ) { not isUnreachableInCallCached(node.asNode(), cc.(CallContextSpecificCall).getCall()) and ( localFlowStep(mid.getNodeEx(), node, config) and + state = mid.getState() and cc = mid.getCallContext() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and ap = mid.getAp() and config = mid.getConfiguration() or additionalLocalFlowStep(mid.getNodeEx(), node, config) and + state = mid.getState() and cc = mid.getCallContext() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and + mid.getAp() instanceof PartialAccessPathNil and + ap = TPartialNil(node.getDataFlowType()) and + config = mid.getConfiguration() + or + additionalLocalStateStep(mid.getNodeEx(), mid.getState(), node, state, config) and + cc = mid.getCallContext() and + sc1 = mid.getSummaryCtx1() and + sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and mid.getAp() instanceof PartialAccessPathNil and ap = TPartialNil(node.getDataFlowType()) and config = mid.getConfiguration() ) or jumpStep(mid.getNodeEx(), node, config) and + state = mid.getState() and cc instanceof CallContextAny and sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and ap = mid.getAp() and config = mid.getConfiguration() or additionalJumpStep(mid.getNodeEx(), node, config) and + state = mid.getState() and cc instanceof CallContextAny and sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and + mid.getAp() instanceof PartialAccessPathNil and + ap = TPartialNil(node.getDataFlowType()) and + config = mid.getConfiguration() + or + additionalJumpStateStep(mid.getNodeEx(), mid.getState(), node, state, config) and + cc instanceof CallContextAny and + sc1 = TSummaryCtx1None() and + sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and mid.getAp() instanceof PartialAccessPathNil and ap = TPartialNil(node.getDataFlowType()) and config = mid.getConfiguration() or partialPathStoreStep(mid, _, _, node, ap) and + state = mid.getState() and cc = mid.getCallContext() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and config = mid.getConfiguration() or exists(PartialAccessPath ap0, TypedContent tc | partialPathReadStep(mid, ap0, tc, node, cc, config) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and apConsFwd(ap, tc, ap0, config) ) or - partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config) + partialPathIntoCallable(mid, node, state, _, cc, sc1, sc2, sc3, _, ap, config) or - partialPathOutOfCallable(mid, node, cc, ap, config) and + partialPathOutOfCallable(mid, node, state, cc, ap, config) and sc1 = TSummaryCtx1None() and - sc2 = TSummaryCtx2None() + sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() or - partialPathThroughCallable(mid, node, cc, ap, config) and + partialPathThroughCallable(mid, node, state, cc, ap, config) and sc1 = mid.getSummaryCtx1() and - sc2 = mid.getSummaryCtx2() + sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() } bindingset[result, i] - private int unbindInt(int i) { i <= result and i >= result } + private int unbindInt(int i) { pragma[only_bind_out](i) = pragma[only_bind_out](result) } pragma[inline] private predicate partialPathStoreStep( @@ -4419,10 +5090,11 @@ private module FlowExploration { } private predicate partialPathOutOfCallable0( - PartialPathNodeFwd mid, ReturnPosition pos, CallContext innercc, PartialAccessPath ap, - Configuration config + PartialPathNodeFwd mid, ReturnPosition pos, FlowState state, CallContext innercc, + PartialAccessPath ap, Configuration config ) { pos = mid.getNodeEx().(RetNodeEx).getReturnPosition() and + state = mid.getState() and innercc = mid.getCallContext() and innercc instanceof CallContextNoCall and ap = mid.getAp() and @@ -4431,11 +5103,11 @@ private module FlowExploration { pragma[nomagic] private predicate partialPathOutOfCallable1( - PartialPathNodeFwd mid, DataFlowCall call, ReturnKindExt kind, CallContext cc, + PartialPathNodeFwd mid, DataFlowCall call, ReturnKindExt kind, FlowState state, CallContext cc, PartialAccessPath ap, Configuration config ) { exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc | - partialPathOutOfCallable0(mid, pos, innercc, ap, config) and + partialPathOutOfCallable0(mid, pos, state, innercc, ap, config) and c = pos.getCallable() and kind = pos.getKind() and resolveReturn(innercc, c, call) @@ -4445,10 +5117,11 @@ private module FlowExploration { } private predicate partialPathOutOfCallable( - PartialPathNodeFwd mid, NodeEx out, CallContext cc, PartialAccessPath ap, Configuration config + PartialPathNodeFwd mid, NodeEx out, FlowState state, CallContext cc, PartialAccessPath ap, + Configuration config ) { exists(ReturnKindExt kind, DataFlowCall call | - partialPathOutOfCallable1(mid, call, kind, cc, ap, config) + partialPathOutOfCallable1(mid, call, kind, state, cc, ap, config) | out.asNode() = kind.getAnOutNode(call) ) @@ -4456,37 +5129,40 @@ private module FlowExploration { pragma[noinline] private predicate partialPathIntoArg( - PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap, - Configuration config + PartialPathNodeFwd mid, ParameterPosition ppos, FlowState state, CallContext cc, + DataFlowCall call, PartialAccessPath ap, Configuration config ) { - exists(ArgNode arg | + exists(ArgNode arg, ArgumentPosition apos | arg = mid.getNodeEx().asNode() and + state = mid.getState() and cc = mid.getCallContext() and - arg.argumentOf(call, i) and + arg.argumentOf(call, apos) and ap = mid.getAp() and - config = mid.getConfiguration() + config = mid.getConfiguration() and + parameterMatch(ppos, apos) ) } pragma[nomagic] private predicate partialPathIntoCallable0( - PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc, - DataFlowCall call, PartialAccessPath ap, Configuration config + PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, FlowState state, + CallContext outercc, DataFlowCall call, PartialAccessPath ap, Configuration config ) { - partialPathIntoArg(mid, i, outercc, call, ap, config) and + partialPathIntoArg(mid, pos, state, outercc, call, ap, config) and callable = resolveCall(call, outercc) } private predicate partialPathIntoCallable( - PartialPathNodeFwd mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, - TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap, - Configuration config + PartialPathNodeFwd mid, ParamNodeEx p, FlowState state, CallContext outercc, + CallContextCall innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, + DataFlowCall call, PartialAccessPath ap, Configuration config ) { - exists(int i, DataFlowCallable callable | - partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and - p.isParameterOf(callable, i) and + exists(ParameterPosition pos, DataFlowCallable callable | + partialPathIntoCallable0(mid, callable, pos, state, outercc, call, ap, config) and + p.isParameterOf(callable, pos) and sc1 = TSummaryCtx1Param(p) and - sc2 = TSummaryCtx2Some(ap) + sc2 = TSummaryCtx2Some(state) and + sc3 = TSummaryCtx3Some(ap) | if recordDataFlowCallSite(call, callable) then innercc = TSpecificCall(call) @@ -4496,15 +5172,17 @@ private module FlowExploration { pragma[nomagic] private predicate paramFlowsThroughInPartialPath( - ReturnKindExt kind, CallContextCall cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - PartialAccessPath ap, Configuration config + ReturnKindExt kind, FlowState state, CallContextCall cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, + TSummaryCtx3 sc3, PartialAccessPath ap, Configuration config ) { exists(PartialPathNodeFwd mid, RetNodeEx ret | mid.getNodeEx() = ret and kind = ret.getKind() and + state = mid.getState() and cc = mid.getCallContext() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and config = mid.getConfiguration() and ap = mid.getAp() ) @@ -4512,85 +5190,119 @@ private module FlowExploration { pragma[noinline] private predicate partialPathThroughCallable0( - DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, CallContext cc, + DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, FlowState state, CallContext cc, PartialAccessPath ap, Configuration config ) { - exists(CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 | - partialPathIntoCallable(mid, _, cc, innercc, sc1, sc2, call, _, config) and - paramFlowsThroughInPartialPath(kind, innercc, sc1, sc2, ap, config) + exists(CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3 | + partialPathIntoCallable(mid, _, _, cc, innercc, sc1, sc2, sc3, call, _, config) and + paramFlowsThroughInPartialPath(kind, state, innercc, sc1, sc2, sc3, ap, config) ) } private predicate partialPathThroughCallable( - PartialPathNodeFwd mid, NodeEx out, CallContext cc, PartialAccessPath ap, Configuration config + PartialPathNodeFwd mid, NodeEx out, FlowState state, CallContext cc, PartialAccessPath ap, + Configuration config ) { exists(DataFlowCall call, ReturnKindExt kind | - partialPathThroughCallable0(call, mid, kind, cc, ap, config) and + partialPathThroughCallable0(call, mid, kind, state, cc, ap, config) and out.asNode() = kind.getAnOutNode(call) ) } + pragma[nomagic] private predicate revPartialPathStep( - PartialPathNodeRev mid, NodeEx node, TRevSummaryCtx1 sc1, TRevSummaryCtx2 sc2, - RevPartialAccessPath ap, Configuration config + PartialPathNodeRev mid, NodeEx node, FlowState state, TRevSummaryCtx1 sc1, TRevSummaryCtx2 sc2, + TRevSummaryCtx3 sc3, RevPartialAccessPath ap, Configuration config ) { localFlowStep(node, mid.getNodeEx(), config) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and ap = mid.getAp() and config = mid.getConfiguration() or additionalLocalFlowStep(node, mid.getNodeEx(), config) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and + mid.getAp() instanceof RevPartialAccessPathNil and + ap = TRevPartialNil() and + config = mid.getConfiguration() + or + additionalLocalStateStep(node, state, mid.getNodeEx(), mid.getState(), config) and + sc1 = mid.getSummaryCtx1() and + sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and mid.getAp() instanceof RevPartialAccessPathNil and ap = TRevPartialNil() and config = mid.getConfiguration() or jumpStep(node, mid.getNodeEx(), config) and + state = mid.getState() and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and ap = mid.getAp() and config = mid.getConfiguration() or additionalJumpStep(node, mid.getNodeEx(), config) and + state = mid.getState() and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and + mid.getAp() instanceof RevPartialAccessPathNil and + ap = TRevPartialNil() and + config = mid.getConfiguration() + or + additionalJumpStateStep(node, state, mid.getNodeEx(), mid.getState(), config) and + sc1 = TRevSummaryCtx1None() and + sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and mid.getAp() instanceof RevPartialAccessPathNil and ap = TRevPartialNil() and config = mid.getConfiguration() or revPartialPathReadStep(mid, _, _, node, ap) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and config = mid.getConfiguration() or exists(RevPartialAccessPath ap0, Content c | revPartialPathStoreStep(mid, ap0, c, node, config) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and apConsRev(ap, c, ap0, config) ) or exists(ParamNodeEx p | mid.getNodeEx() = p and viableParamArgEx(_, p, node) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and ap = mid.getAp() and config = mid.getConfiguration() ) or exists(ReturnPosition pos | - revPartialPathIntoReturn(mid, pos, sc1, sc2, _, ap, config) and + revPartialPathIntoReturn(mid, pos, state, sc1, sc2, sc3, _, ap, config) and pos = getReturnPosition(node.asNode()) ) or - revPartialPathThroughCallable(mid, node, ap, config) and + revPartialPathThroughCallable(mid, node, state, ap, config) and sc1 = mid.getSummaryCtx1() and - sc2 = mid.getSummaryCtx2() + sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() } pragma[inline] @@ -4633,14 +5345,17 @@ private module FlowExploration { pragma[nomagic] private predicate revPartialPathIntoReturn( - PartialPathNodeRev mid, ReturnPosition pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, - DataFlowCall call, RevPartialAccessPath ap, Configuration config + PartialPathNodeRev mid, ReturnPosition pos, FlowState state, TRevSummaryCtx1Some sc1, + TRevSummaryCtx2Some sc2, TRevSummaryCtx3Some sc3, DataFlowCall call, RevPartialAccessPath ap, + Configuration config ) { exists(NodeEx out | mid.getNodeEx() = out and + mid.getState() = state and viableReturnPosOutEx(call, pos, out) and sc1 = TRevSummaryCtx1Some(pos) and - sc2 = TRevSummaryCtx2Some(ap) and + sc2 = TRevSummaryCtx2Some(state) and + sc3 = TRevSummaryCtx3Some(ap) and ap = mid.getAp() and config = mid.getConfiguration() ) @@ -4648,36 +5363,40 @@ private module FlowExploration { pragma[nomagic] private predicate revPartialPathFlowsThrough( - int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap, - Configuration config + ArgumentPosition apos, FlowState state, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, + TRevSummaryCtx3Some sc3, RevPartialAccessPath ap, Configuration config ) { - exists(PartialPathNodeRev mid, ParamNodeEx p | + exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos | mid.getNodeEx() = p and - p.getPosition() = pos and + mid.getState() = state and + p.getPosition() = ppos and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and ap = mid.getAp() and - config = mid.getConfiguration() + config = mid.getConfiguration() and + parameterMatch(ppos, apos) ) } pragma[nomagic] private predicate revPartialPathThroughCallable0( - DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap, - Configuration config + DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, FlowState state, + RevPartialAccessPath ap, Configuration config ) { - exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 | - revPartialPathIntoReturn(mid, _, sc1, sc2, call, _, config) and - revPartialPathFlowsThrough(pos, sc1, sc2, ap, config) + exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, TRevSummaryCtx3Some sc3 | + revPartialPathIntoReturn(mid, _, _, sc1, sc2, sc3, call, _, config) and + revPartialPathFlowsThrough(pos, state, sc1, sc2, sc3, ap, config) ) } pragma[nomagic] private predicate revPartialPathThroughCallable( - PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config + PartialPathNodeRev mid, ArgNodeEx node, FlowState state, RevPartialAccessPath ap, + Configuration config ) { - exists(DataFlowCall call, int pos | - revPartialPathThroughCallable0(call, mid, pos, ap, config) and + exists(DataFlowCall call, ArgumentPosition pos | + revPartialPathThroughCallable0(call, mid, pos, state, ap, config) and node.asNode().(ArgNode).argumentOf(call, pos) ) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll index c139593b1b8..95b34f15dad 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll @@ -3,6 +3,17 @@ private import DataFlowImplSpecific::Public import Cached module DataFlowImplCommonPublic { + /** A state value to track during data flow. */ + class FlowState = string; + + /** + * The default state, which is used when the state is unspecified for a source + * or a sink. + */ + class FlowStateEmpty extends FlowState { + FlowStateEmpty() { this = "" } + } + private newtype TFlowFeature = TFeatureHasSourceCallContext() or TFeatureHasSinkCallContext() or @@ -62,6 +73,18 @@ predicate accessPathCostLimits(int apLimit, int tupleLimit) { tupleLimit = 1000 } +/** + * Holds if `arg` is an argument of `call` with an argument position that matches + * parameter position `ppos`. + */ +pragma[noinline] +predicate argumentPositionMatch(DataFlowCall call, ArgNode arg, ParameterPosition ppos) { + exists(ArgumentPosition apos | + arg.argumentOf(call, apos) and + parameterMatch(ppos, apos) + ) +} + /** * Provides a simple data-flow analysis for resolving lambda calls. The analysis * currently excludes read-steps, store-steps, and flow-through. @@ -71,25 +94,27 @@ predicate accessPathCostLimits(int apLimit, int tupleLimit) { * calls. For this reason, we cannot reuse the code from `DataFlowImpl.qll` directly. */ private module LambdaFlow { - private predicate viableParamNonLambda(DataFlowCall call, int i, ParamNode p) { - p.isParameterOf(viableCallable(call), i) + pragma[noinline] + private predicate viableParamNonLambda(DataFlowCall call, ParameterPosition ppos, ParamNode p) { + p.isParameterOf(viableCallable(call), ppos) } - private predicate viableParamLambda(DataFlowCall call, int i, ParamNode p) { - p.isParameterOf(viableCallableLambda(call, _), i) + pragma[noinline] + private predicate viableParamLambda(DataFlowCall call, ParameterPosition ppos, ParamNode p) { + p.isParameterOf(viableCallableLambda(call, _), ppos) } private predicate viableParamArgNonLambda(DataFlowCall call, ParamNode p, ArgNode arg) { - exists(int i | - viableParamNonLambda(call, i, p) and - arg.argumentOf(call, i) + exists(ParameterPosition ppos | + viableParamNonLambda(call, ppos, p) and + argumentPositionMatch(call, arg, ppos) ) } private predicate viableParamArgLambda(DataFlowCall call, ParamNode p, ArgNode arg) { - exists(int i | - viableParamLambda(call, i, p) and - arg.argumentOf(call, i) + exists(ParameterPosition ppos | + viableParamLambda(call, ppos, p) and + argumentPositionMatch(call, arg, ppos) ) } @@ -191,10 +216,9 @@ private module LambdaFlow { or // jump step exists(Node mid, DataFlowType t0 | - revLambdaFlow(lambdaCall, kind, mid, t0, _, _, _) and + revLambdaFlow(lambdaCall, kind, mid, t0, _, _, lastCall) and toReturn = false and - toJump = true and - lastCall = TDataFlowCallNone() + toJump = true | jumpStepCached(node, mid) and t = t0 @@ -301,7 +325,10 @@ private module Cached { predicate jumpStepCached(Node node1, Node node2) { jumpStep(node1, node2) } cached - predicate clearsContentCached(Node n, Content c) { clearsContent(n, c) } + predicate clearsContentCached(Node n, ContentSet c) { clearsContent(n, c) } + + cached + predicate expectsContentCached(Node n, ContentSet c) { expectsContent(n, c) } cached predicate isUnreachableInCallCached(Node n, DataFlowCall call) { isUnreachableInCall(n, call) } @@ -322,7 +349,7 @@ private module Cached { or exists(ArgNode arg | result.(PostUpdateNode).getPreUpdateNode() = arg and - arg.argumentOf(call, k.(ParamUpdateReturnKind).getPosition()) + arg.argumentOf(call, k.(ParamUpdateReturnKind).getAMatchingArgumentPosition()) ) } @@ -330,7 +357,7 @@ private module Cached { predicate returnNodeExt(Node n, ReturnKindExt k) { k = TValueReturn(n.(ReturnNode).getKind()) or - exists(ParamNode p, int pos | + exists(ParamNode p, ParameterPosition pos | parameterValueFlowsToPreUpdate(p, n) and p.isParameterOf(_, pos) and k = TParamUpdate(pos) @@ -348,15 +375,17 @@ private module Cached { // For reads, `x.f`, we want to check that the tracked type after the read (which // is obtained by popping the head of the access path stack) is compatible with // the type of `x.f`. - read(_, _, n) + readSet(_, _, n) } cached - predicate parameterNode(Node p, DataFlowCallable c, int pos) { isParameterNode(p, c, pos) } + predicate parameterNode(Node p, DataFlowCallable c, ParameterPosition pos) { + isParameterNode(p, c, pos) + } cached - predicate argumentNode(Node n, DataFlowCall call, int pos) { - n.(ArgumentNode).argumentOf(call, pos) + predicate argumentNode(Node n, DataFlowCall call, ArgumentPosition pos) { + isArgumentNode(n, call, pos) } /** @@ -374,12 +403,12 @@ private module Cached { } /** - * Holds if `p` is the `i`th parameter of a viable dispatch target of `call`. - * The instance parameter is considered to have index `-1`. + * Holds if `p` is the parameter of a viable dispatch target of `call`, + * and `p` has position `ppos`. */ pragma[nomagic] - private predicate viableParam(DataFlowCall call, int i, ParamNode p) { - p.isParameterOf(viableCallableExt(call), i) + private predicate viableParam(DataFlowCall call, ParameterPosition ppos, ParamNode p) { + p.isParameterOf(viableCallableExt(call), ppos) } /** @@ -388,9 +417,9 @@ private module Cached { */ cached predicate viableParamArg(DataFlowCall call, ParamNode p, ArgNode arg) { - exists(int i | - viableParam(call, i, p) and - arg.argumentOf(call, i) and + exists(ParameterPosition ppos | + viableParam(call, ppos, p) and + argumentPositionMatch(call, arg, ppos) and compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) ) } @@ -442,7 +471,7 @@ private module Cached { // read exists(Node mid | parameterValueFlowCand(p, mid, false) and - read(mid, _, node) and + readSet(mid, _, node) and read = true ) or @@ -630,8 +659,10 @@ private module Cached { * Holds if `arg` flows to `out` through a call using only * value-preserving steps and a single read step, not taking call * contexts into account, thus representing a getter-step. + * + * This predicate is exposed for testing only. */ - predicate getterStep(ArgNode arg, Content c, Node out) { + predicate getterStep(ArgNode arg, ContentSet c, Node out) { argumentValueFlowsThrough(arg, TReadStepTypesSome(_, c, _), out) } @@ -754,8 +785,12 @@ private module Cached { parameterValueFlow(p, n.getPreUpdateNode(), TReadStepTypesNone()) } - private predicate store( - Node node1, Content c, Node node2, DataFlowType contentType, DataFlowType containerType + cached + predicate readSet(Node node1, ContentSet c, Node node2) { readStep(node1, c, node2) } + + cached + predicate storeSet( + Node node1, ContentSet c, Node node2, DataFlowType contentType, DataFlowType containerType ) { storeStep(node1, c, node2) and contentType = getNodeDataFlowType(node1) and @@ -767,14 +802,19 @@ private module Cached { | argumentValueFlowsThrough(n2, TReadStepTypesSome(containerType, c, contentType), n1) or - read(n2, c, n1) and + readSet(n2, c, n1) and contentType = getNodeDataFlowType(n1) and containerType = getNodeDataFlowType(n2) ) } - cached - predicate read(Node node1, Content c, Node node2) { readStep(node1, c, node2) } + private predicate store( + Node node1, Content c, Node node2, DataFlowType contentType, DataFlowType containerType + ) { + exists(ContentSet cs | + c = cs.getAStoreContent() and storeSet(node1, cs, node2, contentType, containerType) + ) + } /** * Holds if data can flow from `node1` to `node2` via a direct assignment to @@ -862,7 +902,7 @@ private module Cached { cached newtype TReturnKindExt = TValueReturn(ReturnKind kind) or - TParamUpdate(int pos) { exists(ParamNode p | p.isParameterOf(_, pos)) } + TParamUpdate(ParameterPosition pos) { exists(ParamNode p | p.isParameterOf(_, pos)) } cached newtype TBooleanOption = @@ -905,16 +945,16 @@ class CastingNode extends Node { } private predicate readStepWithTypes( - Node n1, DataFlowType container, Content c, Node n2, DataFlowType content + Node n1, DataFlowType container, ContentSet c, Node n2, DataFlowType content ) { - read(n1, c, n2) and + readSet(n1, c, n2) and container = getNodeDataFlowType(n1) and content = getNodeDataFlowType(n2) } private newtype TReadStepTypesOption = TReadStepTypesNone() or - TReadStepTypesSome(DataFlowType container, Content c, DataFlowType content) { + TReadStepTypesSome(DataFlowType container, ContentSet c, DataFlowType content) { readStepWithTypes(_, container, c, _, content) } @@ -923,7 +963,7 @@ private class ReadStepTypesOption extends TReadStepTypesOption { DataFlowType getContainerType() { this = TReadStepTypesSome(result, _, _) } - Content getContent() { this = TReadStepTypesSome(_, result, _) } + ContentSet getContent() { this = TReadStepTypesSome(_, result, _) } DataFlowType getContentType() { this = TReadStepTypesSome(_, _, result) } @@ -1054,9 +1094,9 @@ class ParamNode extends Node { /** * Holds if this node is the parameter of callable `c` at the specified - * (zero-based) position. + * position. */ - predicate isParameterOf(DataFlowCallable c, int i) { parameterNode(this, c, i) } + predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { parameterNode(this, c, pos) } } /** A data-flow node that represents a call argument. */ @@ -1064,7 +1104,9 @@ class ArgNode extends Node { ArgNode() { argumentNode(this, _, _) } /** Holds if this argument occurs at the given position in the given call. */ - final predicate argumentOf(DataFlowCall call, int pos) { argumentNode(this, call, pos) } + final predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { + argumentNode(this, call, pos) + } } /** @@ -1110,11 +1152,14 @@ class ValueReturnKind extends ReturnKindExt, TValueReturn { } class ParamUpdateReturnKind extends ReturnKindExt, TParamUpdate { - private int pos; + private ParameterPosition pos; ParamUpdateReturnKind() { this = TParamUpdate(pos) } - int getPosition() { result = pos } + ParameterPosition getPosition() { result = pos } + + pragma[nomagic] + ArgumentPosition getAMatchingArgumentPosition() { parameterMatch(pos, result) } override string toString() { result = "param update " + pos } } @@ -1258,7 +1303,7 @@ class DataFlowCallOption extends TDataFlowCallOption { } } -/** Content tagged with the type of a containing object. */ +/** A `Content` tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; private DataFlowType t; @@ -1293,8 +1338,6 @@ abstract class AccessPathFront extends TAccessPathFront { abstract boolean toBoolNonEmpty(); TypedContent getHead() { this = TFrontHead(result) } - - predicate isClearedAt(Node n) { clearsContentCached(n, this.getHead().getContent()) } } class AccessPathFrontNil extends AccessPathFront, TFrontNil { diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index e59c96a5c17..7abae2b105b 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -24,7 +24,11 @@ module Public { class SummaryComponent extends TSummaryComponent { /** Gets a textual representation of this summary component. */ string toString() { - exists(Content c | this = TContentSummaryComponent(c) and result = c.toString()) + exists(ContentSet c | this = TContentSummaryComponent(c) and result = c.toString()) + or + exists(ContentSet c | this = TWithoutContentSummaryComponent(c) and result = "without " + c) + or + exists(ContentSet c | this = TWithContentSummaryComponent(c) and result = "with " + c) or exists(ArgumentPosition pos | this = TParameterSummaryComponent(pos) and result = "parameter " + pos @@ -41,7 +45,13 @@ module Public { /** Provides predicates for constructing summary components. */ module SummaryComponent { /** Gets a summary component for content `c`. */ - SummaryComponent content(Content c) { result = TContentSummaryComponent(c) } + SummaryComponent content(ContentSet c) { result = TContentSummaryComponent(c) } + + /** Gets a summary component where data is not allowed to be stored in `c`. */ + SummaryComponent withoutContent(ContentSet c) { result = TWithoutContentSummaryComponent(c) } + + /** Gets a summary component where data must be stored in `c`. */ + SummaryComponent withContent(ContentSet c) { result = TWithContentSummaryComponent(c) } /** Gets a summary component for a parameter at position `pos`. */ SummaryComponent parameter(ArgumentPosition pos) { result = TParameterSummaryComponent(pos) } @@ -185,7 +195,10 @@ module Public { } /** A callable with a flow summary. */ - abstract class SummarizedCallable extends DataFlowCallable { + abstract class SummarizedCallable extends SummarizedCallableBase { + bindingset[this] + SummarizedCallable() { any() } + /** * Holds if data may flow from `input` to `output` through this callable. * @@ -216,9 +229,16 @@ module Public { /** * Holds if values stored inside `content` are cleared on objects passed as * arguments at position `pos` to this callable. + * + * TODO: Remove once all languages support `WithoutContent` tokens. */ pragma[nomagic] - predicate clearsContent(ParameterPosition pos, Content content) { none() } + predicate clearsContent(ParameterPosition pos, ContentSet content) { none() } + + /** + * Holds if the summary is auto generated. + */ + predicate isAutoGenerated() { none() } } } @@ -231,10 +251,12 @@ module Private { import AccessPathSyntax newtype TSummaryComponent = - TContentSummaryComponent(Content c) or + TContentSummaryComponent(ContentSet c) or TParameterSummaryComponent(ArgumentPosition pos) or TArgumentSummaryComponent(ParameterPosition pos) or - TReturnSummaryComponent(ReturnKind rk) + TReturnSummaryComponent(ReturnKind rk) or + TWithoutContentSummaryComponent(ContentSet c) or + TWithContentSummaryComponent(ContentSet c) private TParameterSummaryComponent thisParam() { result = TParameterSummaryComponent(instanceParameterPosition()) @@ -296,6 +318,23 @@ module Private { SummaryComponentStack::singleton(TArgumentSummaryComponent(_))) and preservesValue = preservesValue1.booleanAnd(preservesValue2) ) + or + exists(ParameterPosition ppos, ContentSet cs | + c.clearsContent(ppos, cs) and + input = SummaryComponentStack::push(SummaryComponent::withoutContent(cs), output) and + output = SummaryComponentStack::argument(ppos) and + preservesValue = true + ) + } + + private class MkClearStack extends RequiredSummaryComponentStack { + override predicate required(SummaryComponent head, SummaryComponentStack tail) { + exists(SummarizedCallable sc, ParameterPosition ppos, ContentSet cs | + sc.clearsContent(ppos, cs) and + head = SummaryComponent::withoutContent(cs) and + tail = SummaryComponentStack::argument(ppos) + ) + } } /** @@ -378,10 +417,7 @@ module Private { private newtype TSummaryNodeState = TSummaryNodeInputState(SummaryComponentStack s) { inputState(_, s) } or - TSummaryNodeOutputState(SummaryComponentStack s) { outputState(_, s) } or - TSummaryNodeClearsContentState(ParameterPosition pos, boolean post) { - any(SummarizedCallable sc).clearsContent(pos, _) and post in [false, true] - } + TSummaryNodeOutputState(SummaryComponentStack s) { outputState(_, s) } /** * A state used to break up (complex) flow summaries into atomic flow steps. @@ -428,12 +464,6 @@ module Private { this = TSummaryNodeOutputState(s) and result = "to write: " + s ) - or - exists(ParameterPosition pos, boolean post, string postStr | - this = TSummaryNodeClearsContentState(pos, post) and - (if post = true then postStr = " (post)" else postStr = "") and - result = "clear: " + pos + postStr - ) } } @@ -457,11 +487,6 @@ module Private { not parameterReadState(c, state, _) or state.isOutputState(c, _) - or - exists(ParameterPosition pos | - c.clearsContent(pos, _) and - state = TSummaryNodeClearsContentState(pos, _) - ) } pragma[noinline] @@ -471,7 +496,7 @@ module Private { or exists(ParameterPosition pos | parameterReadState(c, state, pos) and - result.(ParamNode).isParameterOf(c, pos) + result.(ParamNode).isParameterOf(inject(c), pos) ) ) } @@ -497,8 +522,6 @@ module Private { parameterReadState(c, _, pos) or isParameterPostUpdate(_, c, pos) - or - c.clearsContent(pos, _) } private predicate callbackOutput( @@ -506,7 +529,7 @@ module Private { ) { any(SummaryNodeState state).isInputState(c, s) and s.head() = TReturnSummaryComponent(rk) and - receiver = summaryNodeInputState(c, s.drop(1)) + receiver = summaryNodeInputState(c, s.tail()) } private predicate callbackInput( @@ -514,7 +537,7 @@ module Private { ) { any(SummaryNodeState state).isOutputState(c, s) and s.head() = TParameterSummaryComponent(pos) and - receiver = summaryNodeInputState(c, s.drop(1)) + receiver = summaryNodeInputState(c, s.tail()) } /** Holds if a call targeting `receiver` should be synthesized inside `c`. */ @@ -540,21 +563,27 @@ module Private { exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() | n = summaryNodeInputState(c, s) and ( - exists(Content cont | - head = TContentSummaryComponent(cont) and result = getContentType(cont) + exists(ContentSet cont | result = getContentType(cont) | + head = TContentSummaryComponent(cont) or + head = TWithContentSummaryComponent(cont) + ) + or + exists(ContentSet cont | + head = TWithoutContentSummaryComponent(cont) and + result = getNodeType(summaryNodeInputState(c, s.tail())) ) or exists(ReturnKind rk | head = TReturnSummaryComponent(rk) and result = getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), - s.drop(1))), rk) + s.tail())), rk) ) ) or n = summaryNodeOutputState(c, s) and ( - exists(Content cont | + exists(ContentSet cont | head = TContentSummaryComponent(cont) and result = getContentType(cont) ) or @@ -567,16 +596,10 @@ module Private { exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) | result = getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), - s.drop(1))), pos) + s.tail())), pos) ) ) ) - or - exists(SummarizedCallable c, ParameterPosition pos, ParamNode p | - n = summaryNode(c, TSummaryNodeClearsContentState(pos, false)) and - p.isParameterOf(c, pos) and - result = getNodeType(p) - ) } /** Holds if summary node `out` contains output of kind `rk` from call `c`. */ @@ -601,10 +624,7 @@ module Private { predicate summaryPostUpdateNode(Node post, Node pre) { exists(SummarizedCallable c, ParameterPosition pos | isParameterPostUpdate(post, c, pos) and - pre.(ParamNode).isParameterOf(c, pos) - or - pre = summaryNode(c, TSummaryNodeClearsContentState(pos, false)) and - post = summaryNode(c, TSummaryNodeClearsContentState(pos, true)) + pre.(ParamNode).isParameterOf(inject(c), pos) ) or exists(SummarizedCallable callable, SummaryComponentStack s | @@ -627,9 +647,7 @@ module Private { * node, and back out to `p`. */ predicate summaryAllowParameterReturnInSelf(ParamNode p) { - exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(c, ppos) | - c.clearsContent(ppos, _) - or + exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(inject(c), ppos) | exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents | summary(c, inputContents, outputContents, _) and inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and @@ -658,9 +676,10 @@ module Private { preservesValue = false and not summary(c, inputContents, outputContents, true) ) or - exists(SummarizedCallable c, ParameterPosition pos | - pred.(ParamNode).isParameterOf(c, pos) and - succ = summaryNode(c, TSummaryNodeClearsContentState(pos, _)) and + exists(SummarizedCallable c, SummaryComponentStack s | + pred = summaryNodeInputState(c, s.tail()) and + succ = summaryNodeInputState(c, s) and + s.head() = [SummaryComponent::withContent(_), SummaryComponent::withoutContent(_)] and preservesValue = true ) } @@ -669,9 +688,9 @@ module Private { * Holds if there is a read step of content `c` from `pred` to `succ`, which * is synthesized from a flow summary. */ - predicate summaryReadStep(Node pred, Content c, Node succ) { + predicate summaryReadStep(Node pred, ContentSet c, Node succ) { exists(SummarizedCallable sc, SummaryComponentStack s | - pred = summaryNodeInputState(sc, s.drop(1)) and + pred = summaryNodeInputState(sc, s.tail()) and succ = summaryNodeInputState(sc, s) and SummaryComponent::content(c) = s.head() ) @@ -681,10 +700,10 @@ module Private { * Holds if there is a store step of content `c` from `pred` to `succ`, which * is synthesized from a flow summary. */ - predicate summaryStoreStep(Node pred, Content c, Node succ) { + predicate summaryStoreStep(Node pred, ContentSet c, Node succ) { exists(SummarizedCallable sc, SummaryComponentStack s | pred = summaryNodeOutputState(sc, s) and - succ = summaryNodeOutputState(sc, s.drop(1)) and + succ = summaryNodeOutputState(sc, s.tail()) and SummaryComponent::content(c) = s.head() ) } @@ -708,10 +727,23 @@ module Private { * `a` on line 2 to the post-update node for `a` on that line (via an intermediate * node where field `b` is cleared). */ - predicate summaryClearsContent(Node n, Content c) { - exists(SummarizedCallable sc, ParameterPosition pos | - n = summaryNode(sc, TSummaryNodeClearsContentState(pos, true)) and - sc.clearsContent(pos, c) + predicate summaryClearsContent(Node n, ContentSet c) { + exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | + n = summaryNode(sc, state) and + state.isInputState(sc, stack) and + stack.head() = SummaryComponent::withoutContent(c) + ) + } + + /** + * Holds if the value that is being tracked is expected to be stored inside + * content `c` at `n`. + */ + predicate summaryExpectsContent(Node n, ContentSet c) { + exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | + n = summaryNode(sc, state) and + state.isInputState(sc, stack) and + stack.head() = SummaryComponent::withContent(c) ) } @@ -719,55 +751,79 @@ module Private { private predicate viableParam( DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, ParamNode p ) { - p.isParameterOf(sc, ppos) and - sc = viableCallable(call) - } - - /** - * Holds if values stored inside content `c` are cleared inside a - * callable to which `arg` is an argument. - * - * In such cases, it is important to prevent use-use flow out of - * `arg` (see comment for `summaryClearsContent`). - */ - predicate summaryClearsContentArg(ArgNode arg, Content c) { - exists(DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos | - argumentPositionMatch(call, arg, ppos) and - viableParam(call, sc, ppos, _) and - sc.clearsContent(ppos, c) + exists(DataFlowCallable c | + c = inject(sc) and + p.isParameterOf(c, ppos) and + c = viableCallable(call) ) } pragma[nomagic] - private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg) { - exists(ParameterPosition ppos, SummarizedCallable sc | + private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { + exists(ParameterPosition ppos | argumentPositionMatch(call, arg, ppos) and viableParam(call, sc, ppos, result) ) } + /** + * Holds if use-use flow starting from `arg` should be prohibited. + * + * This is the case when `arg` is the argument of a call that targets a + * flow summary where the corresponding parameter either clears contents + * or expects contents. + */ pragma[nomagic] - private ParamNode summaryArgParam(ArgNode arg, ReturnKindExt rk, OutNodeExt out) { - exists(DataFlowCall call | - result = summaryArgParam0(call, arg) and - out = rk.getAnOutNode(call) + predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) { + exists(ParamNode p, Node mid, ParameterPosition ppos, Node ret | + p = summaryArgParam0(_, arg, sc) and + p.isParameterOf(_, pragma[only_bind_into](ppos)) and + summaryLocalStep(p, mid, true) and + summaryLocalStep(mid, ret, true) and + isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos)) + | + summaryClearsContent(mid, _) or + summaryExpectsContent(mid, _) + ) + } + + bindingset[ret] + private ParamNode summaryArgParam( + ArgNode arg, ReturnNodeExt ret, OutNodeExt out, SummarizedCallable sc + ) { + exists(DataFlowCall call, ReturnKindExt rk | + result = summaryArgParam0(call, arg, sc) and + ret.getKind() = pragma[only_bind_into](rk) and + out = pragma[only_bind_into](rk).getAnOutNode(call) ) } /** - * Holds if `arg` flows to `out` using a simple flow summary, that is, a flow - * summary without reads and stores. + * Holds if `arg` flows to `out` using a simple value-preserving flow + * summary, that is, a flow summary without reads and stores. * * NOTE: This step should not be used in global data-flow/taint-tracking, but may * be useful to include in the exposed local data-flow/taint-tracking relations. */ - predicate summaryThroughStep(ArgNode arg, Node out, boolean preservesValue) { - exists(ReturnKindExt rk, ReturnNodeExt ret | - summaryLocalStep(summaryArgParam(arg, rk, out), ret, preservesValue) and - ret.getKind() = rk + predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) { + exists(ReturnKind rk, ReturnNode ret, DataFlowCall call | + summaryLocalStep(summaryArgParam0(call, arg, sc), ret, true) and + ret.getKind() = pragma[only_bind_into](rk) and + out = getAnOutNode(call, pragma[only_bind_into](rk)) ) } + /** + * Holds if `arg` flows to `out` using a simple flow summary involving taint + * step, that is, a flow summary without reads and stores. + * + * NOTE: This step should not be used in global data-flow/taint-tracking, but may + * be useful to include in the exposed local data-flow/taint-tracking relations. + */ + predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) { + exists(ReturnNodeExt ret | summaryLocalStep(summaryArgParam(arg, ret, out, sc), ret, false)) + } + /** * Holds if there is a read(+taint) of `c` from `arg` to `out` using a * flow summary. @@ -775,11 +831,10 @@ module Private { * NOTE: This step should not be used in global data-flow/taint-tracking, but may * be useful to include in the exposed local data-flow/taint-tracking relations. */ - predicate summaryGetterStep(ArgNode arg, Content c, Node out) { - exists(ReturnKindExt rk, Node mid, ReturnNodeExt ret | - summaryReadStep(summaryArgParam(arg, rk, out), c, mid) and - summaryLocalStep(mid, ret, _) and - ret.getKind() = rk + predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { + exists(Node mid, ReturnNodeExt ret | + summaryReadStep(summaryArgParam(arg, ret, out, sc), c, mid) and + summaryLocalStep(mid, ret, _) ) } @@ -790,11 +845,10 @@ module Private { * NOTE: This step should not be used in global data-flow/taint-tracking, but may * be useful to include in the exposed local data-flow/taint-tracking relations. */ - predicate summarySetterStep(ArgNode arg, Content c, Node out) { - exists(ReturnKindExt rk, Node mid, ReturnNodeExt ret | - summaryLocalStep(summaryArgParam(arg, rk, out), mid, _) and - summaryStoreStep(mid, c, ret) and - ret.getKind() = rk + predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { + exists(Node mid, ReturnNodeExt ret | + summaryLocalStep(summaryArgParam(arg, ret, out, sc), mid, _) and + summaryStoreStep(mid, c, ret) ) } } @@ -806,10 +860,10 @@ module Private { module External { /** Holds if `spec` is a relevant external specification. */ private predicate relevantSpec(string spec) { - summaryElement(_, spec, _, _) or - summaryElement(_, _, spec, _) or - sourceElement(_, spec, _) or - sinkElement(_, spec, _) + summaryElement(_, spec, _, _, _) or + summaryElement(_, _, spec, _, _) or + sourceElement(_, spec, _, _) or + sinkElement(_, spec, _, _) } private class AccessPathRange extends AccessPath::Range { @@ -875,13 +929,27 @@ module Private { } private class SummarizedCallableExternal extends SummarizedCallable { - SummarizedCallableExternal() { summaryElement(this, _, _, _) } + SummarizedCallableExternal() { summaryElement(this, _, _, _, _) } + + private predicate relevantSummaryElementGenerated( + AccessPath inSpec, AccessPath outSpec, string kind + ) { + summaryElement(this, inSpec, outSpec, kind, true) and + not summaryElement(this, _, _, _, false) and + not this.clearsContent(_, _) + } + + private predicate relevantSummaryElement(AccessPath inSpec, AccessPath outSpec, string kind) { + summaryElement(this, inSpec, outSpec, kind, false) + or + this.relevantSummaryElementGenerated(inSpec, outSpec, kind) + } override predicate propagatesFlow( SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { exists(AccessPath inSpec, AccessPath outSpec, string kind | - summaryElement(this, inSpec, outSpec, kind) and + this.relevantSummaryElement(inSpec, outSpec, kind) and interpretSpec(inSpec, input) and interpretSpec(outSpec, output) | @@ -890,6 +958,8 @@ module Private { kind = "taint" and preservesValue = false ) } + + override predicate isAutoGenerated() { this.relevantSummaryElementGenerated(_, _, _) } } /** Holds if component `c` of specification `spec` cannot be parsed. */ @@ -910,7 +980,7 @@ module Private { private predicate sourceElementRef(InterpretNode ref, AccessPath output, string kind) { exists(SourceOrSinkElement e | - sourceElement(e, output, kind) and + sourceElement(e, output, kind, _) and if outputNeedsReference(output.getToken(0)) then e = ref.getCallTarget() else e = ref.asElement() @@ -919,7 +989,7 @@ module Private { private predicate sinkElementRef(InterpretNode ref, AccessPath input, string kind) { exists(SourceOrSinkElement e | - sinkElement(e, input, kind) and + sinkElement(e, input, kind, _) and if inputNeedsReference(input.getToken(0)) then e = ref.getCallTarget() else e = ref.asElement() @@ -1025,7 +1095,7 @@ module Private { /** Provides a query predicate for outputting a set of relevant flow summaries. */ module TestOutput { /** A flow summary to include in the `summary/3` query predicate. */ - abstract class RelevantSummarizedCallable extends SummarizedCallable { + abstract class RelevantSummarizedCallable instanceof SummarizedCallable { /** Gets the string representation of this callable used by `summary/1`. */ abstract string getCallableCsv(); @@ -1033,8 +1103,10 @@ module Private { predicate relevantSummary( SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { - this.propagatesFlow(input, output, preservesValue) + super.propagatesFlow(input, output, preservesValue) } + + string toString() { result = super.toString() } } /** Render the kind in the format used in flow summaries. */ @@ -1044,9 +1116,13 @@ module Private { preservesValue = false and result = "taint" } + private string renderProvenance(RelevantSummarizedCallable c) { + if c.(SummarizedCallable).isAutoGenerated() then result = "generated" else result = "manual" + } + /** * A query predicate for outputting flow summaries in semi-colon separated format in QL tests. - * The syntax is: "namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind", + * The syntax is: "namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind;provenance"", * ext is hardcoded to empty. */ query predicate summary(string csv) { @@ -1056,8 +1132,8 @@ module Private { | c.relevantSummary(input, output, preservesValue) and csv = - c.getCallableCsv() + ";;" + getComponentStackCsv(input) + ";" + - getComponentStackCsv(output) + ";" + renderKind(preservesValue) + c.getCallableCsv() + getComponentStackCsv(input) + ";" + getComponentStackCsv(output) + + ";" + renderKind(preservesValue) + ";" + renderProvenance(c) ) } } @@ -1071,19 +1147,21 @@ module Private { */ module RenderSummarizedCallable { /** A summarized callable to include in the graph. */ - abstract class RelevantSummarizedCallable extends SummarizedCallable { } + abstract class RelevantSummarizedCallable instanceof SummarizedCallable { + string toString() { result = super.toString() } + } private newtype TNodeOrCall = MkNode(Node n) { exists(RelevantSummarizedCallable c | n = summaryNode(c, _) or - n.(ParamNode).isParameterOf(c, _) + n.(ParamNode).isParameterOf(inject(c), _) ) } or MkCall(DataFlowCall call) { call = summaryDataFlowCall(_) and - call.getEnclosingCallable() instanceof RelevantSummarizedCallable + call.getEnclosingCallable() = inject(any(RelevantSummarizedCallable c)) } private class NodeOrCall extends TNodeOrCall { @@ -1123,7 +1201,7 @@ module Private { if preservesValue = true then value = "value" else value = "taint" ) or - exists(Content c | + exists(ContentSet c | Private::Steps::summaryReadStep(a.asNode(), c, b.asNode()) and value = "read (" + c + ")" or @@ -1133,6 +1211,10 @@ module Private { Private::Steps::summaryClearsContent(a.asNode(), c) and b = a and value = "clear (" + c + ")" + or + Private::Steps::summaryExpectsContent(a.asNode(), c) and + b = a and + value = "expect (" + c + ")" ) or summaryPostUpdateNode(b.asNode(), a.asNode()) and diff --git a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll index 4e613ba727e..e6ce1ada8d4 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -61,15 +61,32 @@ abstract class Configuration extends DataFlow::Configuration { * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc - abstract override predicate isSource(DataFlow::Node source); + override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc - abstract override predicate isSink(DataFlow::Node sink); + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink) { none() } + + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -101,8 +128,23 @@ abstract class Configuration extends DataFlow::Configuration { } /** - * Holds if the additional taint propagation step from `node1` to `node2` - * must be taken into account in the analysis. + * DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead. + * + * Holds if taint propagation through nodes guarded by `guard` is prohibited + * when the flow state is `state`. + */ + deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { + none() + } + + deprecated final override predicate isBarrierGuard( + DataFlow::BarrierGuard guard, DataFlow::FlowState state + ) { + this.isSanitizerGuard(guard, state) + } + + /** + * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. */ predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } @@ -111,7 +153,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { + /** + * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. + * This step is only applicable in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll index 4e613ba727e..e6ce1ada8d4 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @@ -61,15 +61,32 @@ abstract class Configuration extends DataFlow::Configuration { * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc - abstract override predicate isSource(DataFlow::Node source); + override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc - abstract override predicate isSink(DataFlow::Node sink); + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink) { none() } + + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -101,8 +128,23 @@ abstract class Configuration extends DataFlow::Configuration { } /** - * Holds if the additional taint propagation step from `node1` to `node2` - * must be taken into account in the analysis. + * DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead. + * + * Holds if taint propagation through nodes guarded by `guard` is prohibited + * when the flow state is `state`. + */ + deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { + none() + } + + deprecated final override predicate isBarrierGuard( + DataFlow::BarrierGuard guard, DataFlow::FlowState state + ) { + this.isSanitizerGuard(guard, state) + } + + /** + * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. */ predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } @@ -111,7 +153,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { + /** + * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. + * This step is only applicable in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) } From c768f04e3264f6114741ccf3c8d9c55c70d35165 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 25 Oct 2022 12:58:27 +0100 Subject: [PATCH 343/796] Go: Introduce generated flag as a part of the kind column for flow summaries Equivalent of https://github.com/github/codeql/pull/8628 --- go/ql/lib/semmle/go/dataflow/ExternalFlow.qll | 70 +++++++++++-------- .../internal/FlowSummaryImplSpecific.qll | 21 +++--- 2 files changed, 52 insertions(+), 39 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll index 3f414c8e6af..556c5d3b726 100644 --- a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll @@ -124,10 +124,17 @@ predicate sinkModel(string row) { any(SinkModelCsv s).row(row) } /** Holds if `row` is a summary model. */ predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) } +bindingset[input] +private predicate getKind(string input, string kind, boolean generated) { + input.splitAt(":", 0) = "generated" and kind = input.splitAt(":", 1) and generated = true + or + not input.matches("%:%") and kind = input and generated = false +} + /** Holds if a source model exists for the given parameters. */ predicate sourceModel( string namespace, string type, boolean subtypes, string name, string signature, string ext, - string output, string kind + string output, string kind, boolean generated ) { exists(string row | sourceModel(row) and @@ -139,14 +146,14 @@ predicate sourceModel( row.splitAt(";", 4) = signature and row.splitAt(";", 5) = ext and row.splitAt(";", 6) = output and - row.splitAt(";", 7) = kind + exists(string k | row.splitAt(";", 7) = k and getKind(k, kind, generated)) ) } /** Holds if a sink model exists for the given parameters. */ predicate sinkModel( string namespace, string type, boolean subtypes, string name, string signature, string ext, - string input, string kind + string input, string kind, boolean generated ) { exists(string row | sinkModel(row) and @@ -158,22 +165,22 @@ predicate sinkModel( row.splitAt(";", 4) = signature and row.splitAt(";", 5) = ext and row.splitAt(";", 6) = input and - row.splitAt(";", 7) = kind + exists(string k | row.splitAt(";", 7) = k and getKind(k, kind, generated)) ) } /** Holds if a summary model exists for the given parameters. */ predicate summaryModel( string namespace, string type, boolean subtypes, string name, string signature, string ext, - string input, string output, string kind + string input, string output, string kind, boolean generated ) { - summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, _) + summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, generated, _) } /** Holds if a summary model `row` exists for the given parameters. */ predicate summaryModel( string namespace, string type, boolean subtypes, string name, string signature, string ext, - string input, string output, string kind, string row + string input, string output, string kind, boolean generated, string row ) { summaryModel(row) and row.splitAt(";", 0) = namespace and @@ -185,14 +192,14 @@ predicate summaryModel( row.splitAt(";", 5) = ext and row.splitAt(";", 6) = input and row.splitAt(";", 7) = output and - row.splitAt(";", 8) = kind + exists(string k | row.splitAt(";", 8) = k and getKind(k, kind, generated)) } /** Holds if `package` have CSV framework coverage. */ private predicate packageHasCsvCoverage(string package) { - sourceModel(package, _, _, _, _, _, _, _) or - sinkModel(package, _, _, _, _, _, _, _) or - summaryModel(package, _, _, _, _, _, _, _, _) + sourceModel(package, _, _, _, _, _, _, _, _) or + sinkModel(package, _, _, _, _, _, _, _, _) or + summaryModel(package, _, _, _, _, _, _, _, _, _) } /** @@ -234,25 +241,25 @@ predicate modelCoverage(string package, int pkgs, string kind, string part, int part = "source" and n = strictcount(string subpkg, string type, boolean subtypes, string name, string signature, - string ext, string output | + string ext, string output, boolean generated | canonicalPackageHasASubpackage(package, subpkg) and - sourceModel(subpkg, type, subtypes, name, signature, ext, output, kind) + sourceModel(subpkg, type, subtypes, name, signature, ext, output, kind, generated) ) or part = "sink" and n = strictcount(string subpkg, string type, boolean subtypes, string name, string signature, - string ext, string input | + string ext, string input, boolean generated | canonicalPackageHasASubpackage(package, subpkg) and - sinkModel(subpkg, type, subtypes, name, signature, ext, input, kind) + sinkModel(subpkg, type, subtypes, name, signature, ext, input, kind, generated) ) or part = "summary" and n = strictcount(string subpkg, string type, boolean subtypes, string name, string signature, - string ext, string input, string output | + string ext, string input, string output, boolean generated | canonicalPackageHasASubpackage(package, subpkg) and - summaryModel(subpkg, type, subtypes, name, signature, ext, input, output, kind) + summaryModel(subpkg, type, subtypes, name, signature, ext, input, output, kind, generated) ) ) } @@ -261,9 +268,9 @@ predicate modelCoverage(string package, int pkgs, string kind, string part, int module CsvValidation { private string getInvalidModelInput() { exists(string pred, AccessPath input, string part | - sinkModel(_, _, _, _, _, _, input, _) and pred = "sink" + sinkModel(_, _, _, _, _, _, input, _, _) and pred = "sink" or - summaryModel(_, _, _, _, _, _, input, _, _) and pred = "summary" + summaryModel(_, _, _, _, _, _, input, _, _, _) and pred = "summary" | ( invalidSpecComponent(input, part) and @@ -279,9 +286,9 @@ module CsvValidation { private string getInvalidModelOutput() { exists(string pred, string output, string part | - sourceModel(_, _, _, _, _, _, output, _) and pred = "source" + sourceModel(_, _, _, _, _, _, output, _, _) and pred = "source" or - summaryModel(_, _, _, _, _, _, _, output, _) and pred = "summary" + summaryModel(_, _, _, _, _, _, _, output, _, _) and pred = "summary" | invalidSpecComponent(output, part) and not part = "" and @@ -291,8 +298,9 @@ module CsvValidation { } private string getInvalidModelKind() { - exists(string row, string kind | summaryModel(row) | - kind = row.splitAt(";", 8) and + exists(string row, string k, string kind | summaryModel(row) | + k = row.splitAt(";", 8) and + getKind(k, kind, _) and not kind = ["taint", "value"] and result = "Invalid kind \"" + kind + "\" in summary model." ) @@ -334,11 +342,11 @@ module CsvValidation { private string getInvalidModelSignature() { exists(string pred, string namespace, string type, string name, string signature, string ext | - sourceModel(namespace, type, _, name, signature, ext, _, _) and pred = "source" + sourceModel(namespace, type, _, name, signature, ext, _, _, _) and pred = "source" or - sinkModel(namespace, type, _, name, signature, ext, _, _) and pred = "sink" + sinkModel(namespace, type, _, name, signature, ext, _, _, _) and pred = "sink" or - summaryModel(namespace, type, _, name, signature, ext, _, _, _) and pred = "summary" + summaryModel(namespace, type, _, name, signature, ext, _, _, _, _) and pred = "summary" | not namespace.regexpMatch("[a-zA-Z0-9_\\./]*") and result = "Dubious namespace \"" + namespace + "\" in " + pred + " model." @@ -371,9 +379,9 @@ pragma[nomagic] private predicate elementSpec( string namespace, string type, boolean subtypes, string name, string signature, string ext ) { - sourceModel(namespace, type, subtypes, name, signature, ext, _, _) or - sinkModel(namespace, type, subtypes, name, signature, ext, _, _) or - summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _) + sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _) or + sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _) or + summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) } private string paramsStringPart(Function f, int i) { @@ -421,7 +429,9 @@ SourceOrSinkElement interpretElement( predicate hasExternalSpecification(Function f) { f = any(SummarizedCallable sc).asFunction() or - exists(SourceOrSinkElement e | f = e.asEntity() | sourceElement(e, _, _) or sinkElement(e, _, _)) + exists(SourceOrSinkElement e | f = e.asEntity() | + sourceElement(e, _, _, _) or sinkElement(e, _, _, _) + ) } private predicate parseField(AccessPathToken c, DataFlow::FieldContent f) { diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll index 4d8e19461df..f4e18377a62 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll @@ -84,13 +84,14 @@ DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { none() } /** * Holds if an external flow summary exists for `c` with input specification - * `input`, output specification `output`, and kind `kind`. + * `input`, output specification `output`, kind `kind`, and a flag `generated` + * stating whether the summary is autogenerated. */ -predicate summaryElement(DataFlowCallable c, string input, string output, string kind) { +predicate summaryElement(DataFlowCallable c, string input, string output, string kind, boolean generated) { exists( string namespace, string type, boolean subtypes, string name, string signature, string ext | - summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind) and + summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, generated) and c.asFunction() = interpretElement(namespace, type, subtypes, name, signature, ext).asEntity() ) } @@ -166,26 +167,28 @@ class SourceOrSinkElement extends TSourceOrSinkElement { /** * Holds if an external source specification exists for `e` with output specification - * `output` and kind `kind`. + * `output`, kind `kind`, and a flag `generated` stating whether the source specification is + * autogenerated. */ -predicate sourceElement(SourceOrSinkElement e, string output, string kind) { +predicate sourceElement(SourceOrSinkElement e, string output, string kind, boolean generated) { exists( string namespace, string type, boolean subtypes, string name, string signature, string ext | - sourceModel(namespace, type, subtypes, name, signature, ext, output, kind) and + sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, generated) and e = interpretElement(namespace, type, subtypes, name, signature, ext) ) } /** * Holds if an external sink specification exists for `e` with input specification - * `input` and kind `kind`. + * `input`, kind `kind` and a flag `generated` stating whether the sink specification is + * autogenerated. */ -predicate sinkElement(SourceOrSinkElement e, string input, string kind) { +predicate sinkElement(SourceOrSinkElement e, string input, string kind, boolean generated) { exists( string namespace, string type, boolean subtypes, string name, string signature, string ext | - sinkModel(namespace, type, subtypes, name, signature, ext, input, kind) and + sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, generated) and e = interpretElement(namespace, type, subtypes, name, signature, ext) ) } From 282699e5b5842fb0d938cd3e13d67358a75a61c2 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 20 Oct 2022 14:41:22 +0100 Subject: [PATCH 344/796] Go: Refactor SummarizedCallable. Equivalent of https://github.com/github/codeql/pull/9210 --- go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll | 4 ++-- .../semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll index ea3f757b440..ab3ecf0c64b 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll @@ -12,7 +12,7 @@ private newtype TNode = MkGlobalFunctionNode(Function f) or MkSummarizedParameterNode(DataFlowCallable c, int i) { not exists(c.getFuncDef()) and - c instanceof SummarizedCallable and + c.asCallable() instanceof SummarizedCallable and ( i in [0 .. c.getType().getNumParameter() - 1] or @@ -115,7 +115,7 @@ module Public { exists(DataFlowCallable dfc | result = dfc.asCallable() | this = MkSummarizedParameterNode(dfc, _) or - this = MkSummaryInternalNode(dfc, _) + this = MkSummaryInternalNode(dfc.asCallable(), _) ) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll index f4e18377a62..447b42821cd 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll @@ -14,6 +14,10 @@ private module FlowSummaries { private import semmle.go.dataflow.FlowSummary as F } +class SummarizedCallableBase = Callable; + +DataFlowCallable inject(SummarizedCallable c) { result.asCallable() = c } + /** Holds if `i` is a valid parameter position. */ predicate parameterPosition(int i) { i = [-1 .. any(DataFlowCallable c).getType().getNumParameter()] @@ -87,7 +91,7 @@ DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { none() } * `input`, output specification `output`, kind `kind`, and a flag `generated` * stating whether the summary is autogenerated. */ -predicate summaryElement(DataFlowCallable c, string input, string output, string kind, boolean generated) { +predicate summaryElement(Callable c, string input, string output, string kind, boolean generated) { exists( string namespace, string type, boolean subtypes, string name, string signature, string ext | From e5829201e1bc1e8682632b3cf60f15c8bc86002c Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 25 Oct 2022 13:54:06 +0100 Subject: [PATCH 345/796] Go: Implement ContentSet --- .../go/dataflow/internal/DataFlowUtil.qll | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll index d0a92a322c0..b6a2bfd9123 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll @@ -230,6 +230,34 @@ class SyntheticFieldContent extends Content, TSyntheticFieldContent { override string toString() { result = s.toString() } } +/** + * An entity that represents a set of `Content`s. + * + * The set may be interpreted differently depending on whether it is + * stored into (`getAStoreContent`) or read from (`getAReadContent`). + */ +class ContentSet instanceof Content { + /** Gets a content that may be stored into when storing into this set. */ + Content getAStoreContent() { result = this } + + /** Gets a content that may be read from when reading from this set. */ + Content getAReadContent() { result = this } + + /** Gets a textual representation of this content set. */ + string toString() { result = super.toString() } + + /** + * Holds if this element is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ + predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { + super.hasLocationInfo(path, sl, sc, el, ec) + } +} + /** * Holds if the guard `g` validates the expression `e` upon evaluating to `branch`. * From 1ee5d3e80eedb50b72e7f6b4be0a9bcc1807db81 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 25 Oct 2022 15:59:37 +0100 Subject: [PATCH 346/796] Move ParameterPosition etc to DataflowDispatch.qll --- .../go/dataflow/internal/DataFlowDispatch.qll | 22 ++++++++++++ .../internal/FlowSummaryImplSpecific.qll | 35 +------------------ 2 files changed, 23 insertions(+), 34 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowDispatch.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowDispatch.qll index 019d2831e5d..4cd6e5446bc 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowDispatch.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowDispatch.qll @@ -108,3 +108,25 @@ predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable f) { non * restricted to those `call`s for which a context might make a difference. */ DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) { none() } + +/** Holds if `i` is a valid parameter position. */ +predicate parameterPosition(int i) { + i = [-1 .. any(DataFlowCallable c).getType().getNumParameter()] +} + +/** Gets the parameter position of the instance parameter. */ +int instanceParameterPosition() { result = -1 } + +/** A parameter position represented by an integer. */ +class ParameterPosition extends int { + ParameterPosition() { parameterPosition(this) } +} + +/** An argument position represented by an integer. */ +class ArgumentPosition extends int { + ArgumentPosition() { parameterPosition(this) } +} + +/** Holds if arguments at position `apos` match parameters at position `ppos`. */ +pragma[inline] +predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos } diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll index 447b42821cd..ecf97dd7565 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll @@ -3,6 +3,7 @@ */ private import go +private import DataFlowDispatch private import DataFlowPrivate private import DataFlowUtil private import FlowSummaryImpl::Private @@ -18,40 +19,6 @@ class SummarizedCallableBase = Callable; DataFlowCallable inject(SummarizedCallable c) { result.asCallable() = c } -/** Holds if `i` is a valid parameter position. */ -predicate parameterPosition(int i) { - i = [-1 .. any(DataFlowCallable c).getType().getNumParameter()] -} - -/** Gets the parameter position of the instance parameter. */ -int instanceParameterPosition() { result = -1 } - -/** A parameter position represented by an integer. */ -class ParameterPosition extends int { - ParameterPosition() { parameterPosition(this) } -} - -/** An argument position represented by an integer. */ -class ArgumentPosition extends int { - ArgumentPosition() { parameterPosition(this) } -} - -/** Holds if arguments at position `apos` match parameters at position `ppos`. */ -pragma[inline] -predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos } - -/** - * Holds if `arg` is an argument of `call` with an argument position that matches - * parameter position `ppos`. - */ -pragma[noinline] -predicate argumentPositionMatch(DataFlowCall call, ArgNode arg, ParameterPosition ppos) { - exists(ArgumentPosition apos | - arg.argumentOf(call, apos) and - parameterMatch(ppos, apos) - ) -} - /** Gets the textual representation of a parameter position in the format used for flow summaries. */ string getParameterPositionCsv(ParameterPosition pos) { result = pos.toString() } From 10ed4ad3df8e8cd13b95a621d9be16fe5457bb34 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 26 Oct 2022 11:05:17 +0100 Subject: [PATCH 347/796] Go: Split `summaryThroughStep` into two predicates Cf. https://github.com/github/codeql/pull/9195 --- go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll | 2 +- go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll | 2 +- .../test/library-tests/semmle/go/dataflow/ExternalFlow/steps.ql | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll index b6a2bfd9123..337a368bbea 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll @@ -108,7 +108,7 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) { or // Simple flow through library code is included in the exposed local // step relation, even though flow is technically inter-procedural - FlowSummaryImpl::Private::Steps::summaryThroughStep(nodeFrom, nodeTo, true) + FlowSummaryImpl::Private::Steps::summaryThroughStepValue(nodeFrom, nodeTo) } /** diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index 2a93253c480..422f15d93b3 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -27,7 +27,7 @@ predicate localTaintStep(DataFlow::Node src, DataFlow::Node sink) { localAdditionalTaintStep(src, sink) or // Simple flow through library code is included in the exposed local // step relation, even though flow is technically inter-procedural - FlowSummaryImpl::Private::Steps::summaryThroughStep(src, sink, false) + FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(src, sink) } private Type getElementType(Type containerType) { diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/steps.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/steps.ql index 543aecd5d97..0670657bae0 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/steps.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/steps.ql @@ -22,5 +22,5 @@ class SummaryModelTest extends SummaryModelCsv { } from DataFlow::Node node1, DataFlow::Node node2 -where FlowSummaryImpl::Private::Steps::summaryThroughStep(node1, node2, false) +where FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(node1, node2) select node1, node2 From 83a3af2ffff294a326f0fe97911fa08663db0147 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 26 Oct 2022 11:13:39 +0100 Subject: [PATCH 348/796] Go: Summarized Callable Corresponds to https://github.com/github/codeql/pull/9270 --- go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll | 2 +- go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll | 2 +- .../test/library-tests/semmle/go/dataflow/ExternalFlow/steps.ql | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll index 337a368bbea..9b905087753 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll @@ -108,7 +108,7 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) { or // Simple flow through library code is included in the exposed local // step relation, even though flow is technically inter-procedural - FlowSummaryImpl::Private::Steps::summaryThroughStepValue(nodeFrom, nodeTo) + FlowSummaryImpl::Private::Steps::summaryThroughStepValue(nodeFrom, nodeTo, _) } /** diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index 422f15d93b3..e9173cc605a 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -27,7 +27,7 @@ predicate localTaintStep(DataFlow::Node src, DataFlow::Node sink) { localAdditionalTaintStep(src, sink) or // Simple flow through library code is included in the exposed local // step relation, even though flow is technically inter-procedural - FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(src, sink) + FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(src, sink, _) } private Type getElementType(Type containerType) { diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/steps.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/steps.ql index 0670657bae0..c6603c5df93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/steps.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/steps.ql @@ -22,5 +22,5 @@ class SummaryModelTest extends SummaryModelCsv { } from DataFlow::Node node1, DataFlow::Node node2 -where FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(node1, node2) +where FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(node1, node2, _) select node1, node2 From 50210a9d24c52812a0e46c97fb3fc55fb2c31254 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 26 Oct 2022 11:37:42 +0100 Subject: [PATCH 349/796] Go: ParameterPosition and ArgumentPosition Corresponds to https://github.com/github/codeql/pull/7260, though some of those changes had already been made. --- .../semmle/go/dataflow/internal/DataFlowDispatch.qll | 12 ++++-------- .../semmle/go/dataflow/internal/DataFlowNodes.qll | 9 ++++++++- .../go/dataflow/internal/FlowSummaryImplSpecific.qll | 10 +++++++++- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowDispatch.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowDispatch.qll index 4cd6e5446bc..8f10eee1aab 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowDispatch.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowDispatch.qll @@ -109,22 +109,18 @@ predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable f) { non */ DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) { none() } -/** Holds if `i` is a valid parameter position. */ -predicate parameterPosition(int i) { - i = [-1 .. any(DataFlowCallable c).getType().getNumParameter()] +private int parameterPosition() { + result = [-1 .. any(DataFlowCallable c).getType().getNumParameter()] } -/** Gets the parameter position of the instance parameter. */ -int instanceParameterPosition() { result = -1 } - /** A parameter position represented by an integer. */ class ParameterPosition extends int { - ParameterPosition() { parameterPosition(this) } + ParameterPosition() { this = parameterPosition() } } /** An argument position represented by an integer. */ class ArgumentPosition extends int { - ArgumentPosition() { parameterPosition(this) } + ArgumentPosition() { this = parameterPosition() } } /** Holds if arguments at position `apos` match parameters at position `ppos`. */ diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll index ab3ecf0c64b..715330f87d9 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll @@ -25,6 +25,8 @@ private newtype TNode = /** Nodes intended for only use inside the data-flow libraries. */ module Private { + private import DataFlowDispatch + /** Gets the callable in which this node occurs. */ DataFlowCallable nodeGetEnclosingCallable(Node n) { result.asCallable() = n.getEnclosingCallable() @@ -33,10 +35,15 @@ module Private { } /** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */ - predicate isParameterNode(ParameterNode p, DataFlowCallable c, int pos) { + predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) { p.isParameterOf(c.asCallable(), pos) } + /** Holds if `arg` is an `ArgumentNode` of `c` with position `pos`. */ + predicate isArgumentNode(ArgumentNode arg, DataFlowCall c, ArgumentPosition pos) { + arg.argumentOf(c, pos) + } + /** A data flow node that represents returning a value from a function. */ class ReturnNode extends Node { ReturnKind kind; diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll index ecf97dd7565..5b5382a3cb7 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll @@ -19,6 +19,9 @@ class SummarizedCallableBase = Callable; DataFlowCallable inject(SummarizedCallable c) { result.asCallable() = c } +/** Gets the parameter position of the instance parameter. */ +ArgumentPosition instanceParameterPosition() { result = -1 } + /** Gets the textual representation of a parameter position in the format used for flow summaries. */ string getParameterPositionCsv(ParameterPosition pos) { result = pos.toString() } @@ -245,7 +248,10 @@ predicate interpretInputSpecific(string c, InterpretNode mid, InterpretNode n) { ) } -/** Holds if specification component `c` parses as return value `n`. */ +/** + * Holds if specification component `c` parses as return value `n` or a range + * containing `n`. + */ predicate parseReturn(AccessPathToken c, int n) { ( c = "ReturnValue" and n = 0 @@ -266,8 +272,10 @@ private int parseConstantOrRange(string arg) { ) } +/** Gets the argument position obtained by parsing `X` in `Parameter[X]`. */ bindingset[arg] ArgumentPosition parseParamBody(string arg) { result = parseConstantOrRange(arg) } +/** Gets the parameter position obtained by parsing `X` in `Argument[X]`. */ bindingset[arg] ParameterPosition parseArgBody(string arg) { result = parseConstantOrRange(arg) } From 736435adda41b7e2e04d2d1ab92e2f7b7174443d Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 26 Oct 2022 11:43:09 +0100 Subject: [PATCH 350/796] Go: Add stub `expectsContent` Corresponds to https://github.com/github/codeql/pull/8870 --- go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index d83014b0b93..e34880f7017 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -188,6 +188,12 @@ predicate clearsContent(Node n, Content c) { // FlowSummaryImpl::Private::Steps::summaryClearsContent(n, c) } +/** + * Holds if the value that is being tracked is expected to be stored inside content `c` + * at node `n`. + */ +predicate expectsContent(Node n, ContentSet c) { none() } + /** Gets the type of `n` used for type pruning. */ DataFlowType getNodeType(Node n) { result = n.getType() From 1718ef88be205084a9b56d3820a9670b06e40d59 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 2 Nov 2022 15:51:37 +0000 Subject: [PATCH 351/796] Data flow: Inline local(Expr)?(Flow|Taint) See https://github.com/github/codeql/pull/7791 --- go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll | 1 + go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll | 2 ++ 2 files changed, 3 insertions(+) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll index 9b905087753..69ec6aedd3e 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll @@ -131,6 +131,7 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) { * Holds if data flows from `source` to `sink` in zero or more local * (intra-procedural) steps. */ +pragma[inline] predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) } private newtype TContent = diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index e9173cc605a..77dadd8e3a8 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -9,12 +9,14 @@ private import FlowSummaryImpl as FlowSummaryImpl * Holds if taint can flow from `src` to `sink` in zero or more * local (intra-procedural) steps. */ +pragma[inline] predicate localTaint(DataFlow::Node src, DataFlow::Node sink) { localTaintStep*(src, sink) } /** * Holds if taint can flow from `src` to `sink` in zero or more * local (intra-procedural) steps. */ +pragma[inline] predicate localExprTaint(Expr src, Expr sink) { localTaint(DataFlow::exprNode(src), DataFlow::exprNode(sink)) } From f2e2c02db6d91a5441f2a0887cd35abeb851fb32 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 26 Oct 2022 15:28:48 +0100 Subject: [PATCH 352/796] Rename predicates to avoid clashes --- .../go/security/AllocationSizeOverflow.qll | 4 ++-- .../IncorrectIntegerConversionLib.qll | 6 ++--- .../semmle/go/security/InsecureRandomness.qll | 4 ++-- .../CWE-020/IncompleteHostnameRegexp.ql | 6 ++--- .../Security/CWE-020/MissingRegexpAnchor.ql | 6 ++--- .../CWE-020/SuspiciousCharacterInRegexp.ql | 6 ++--- .../CWE-190/AllocationSizeOverflow.ql | 2 +- .../CWE-322/InsecureHostKeyCallback.ql | 8 +++---- go/ql/src/Security/CWE-327/InsecureTLS.ql | 8 +++---- .../Security/CWE-338/InsecureRandomness.ql | 2 +- .../Security/CWE-352/ConstantOauth2State.ql | 16 +++++++------- .../src/Security/CWE-601/BadRedirectCheck.ql | 6 ++--- .../CWE-942/CorsMisconfiguration.ql | 12 +++++----- .../experimental/Unsafe/WrongUsageOfUnsafe.ql | 22 ++++++++++--------- .../StdlibTaintFlow/StdlibTaintFlow.ql | 14 ++++++------ 15 files changed, 62 insertions(+), 60 deletions(-) diff --git a/go/ql/lib/semmle/go/security/AllocationSizeOverflow.qll b/go/ql/lib/semmle/go/security/AllocationSizeOverflow.qll index 0cd2ff2bc79..294e1048b29 100644 --- a/go/ql/lib/semmle/go/security/AllocationSizeOverflow.qll +++ b/go/ql/lib/semmle/go/security/AllocationSizeOverflow.qll @@ -48,11 +48,11 @@ module AllocationSizeOverflow { * Holds if `nd` is at a position where overflow might occur, and its result is used to compute * allocation size `allocsz`. */ - predicate isSink(DataFlow::Node nd, DataFlow::Node allocsz) { + predicate isSinkWithAllocationSize(DataFlow::Node nd, DataFlow::Node allocsz) { nd.(Sink).getAllocationSize() = allocsz } - override predicate isSink(DataFlow::Node nd) { isSink(nd, _) } + override predicate isSink(DataFlow::Node nd) { isSinkWithAllocationSize(nd, _) } override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { additionalStep(pred, succ) diff --git a/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll b/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll index fbe73ae1128..060832cfffc 100644 --- a/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll +++ b/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll @@ -109,7 +109,7 @@ class ConversionWithoutBoundsCheckConfig extends TaintTracking::Configuration { * not also in a right-shift expression. We allow this case because it is * a common pattern to serialise `byte(v)`, `byte(v >> 8)`, and so on. */ - predicate isSink(DataFlow::TypeCastNode sink, int bitSize) { + predicate isSinkWithBitSize(DataFlow::TypeCastNode sink, int bitSize) { sink.asExpr() instanceof ConversionExpr and exists(IntegerType integerType | sink.getResultType().getUnderlyingType() = integerType | bitSize = integerType.getSize() @@ -125,7 +125,7 @@ class ConversionWithoutBoundsCheckConfig extends TaintTracking::Configuration { ) } - override predicate isSink(DataFlow::Node sink) { this.isSink(sink, sinkBitSize) } + override predicate isSink(DataFlow::Node sink) { this.isSinkWithBitSize(sink, sinkBitSize) } override predicate isSanitizer(DataFlow::Node node) { // To catch flows that only happen on 32-bit architectures we @@ -140,7 +140,7 @@ class ConversionWithoutBoundsCheckConfig extends TaintTracking::Configuration { override predicate isSanitizerOut(DataFlow::Node node) { exists(int bitSize | isIncorrectIntegerConversion(sourceBitSize, bitSize) | - this.isSink(node, bitSize) + this.isSinkWithBitSize(node, bitSize) ) } } diff --git a/go/ql/lib/semmle/go/security/InsecureRandomness.qll b/go/ql/lib/semmle/go/security/InsecureRandomness.qll index 6de3071b598..38916389c9b 100644 --- a/go/ql/lib/semmle/go/security/InsecureRandomness.qll +++ b/go/ql/lib/semmle/go/security/InsecureRandomness.qll @@ -25,10 +25,10 @@ module InsecureRandomness { override predicate isSource(DataFlow::Node source) { source instanceof Source } - override predicate isSink(DataFlow::Node sink) { this.isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { this.isSinkWithKind(sink, _) } /** Holds if `sink` is a sink for this configuration with kind `kind`. */ - predicate isSink(Sink sink, string kind) { kind = sink.getKind() } + predicate isSinkWithKind(Sink sink, string kind) { kind = sink.getKind() } override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } } diff --git a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql index fdd83673b74..29e94f67823 100644 --- a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql +++ b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql @@ -83,7 +83,7 @@ predicate regexpGuardsError(RegexpPattern regexp) { class Config extends DataFlow::Configuration { Config() { this = "IncompleteHostNameRegexp::Config" } - predicate isSource(DataFlow::Node source, string hostPart) { + predicate isSourceString(DataFlow::Node source, string hostPart) { exists(Expr e | e = source.asExpr() and isIncompleteHostNameRegexpPattern(e.getStringValue(), hostPart) @@ -95,7 +95,7 @@ class Config extends DataFlow::Configuration { ) } - override predicate isSource(DataFlow::Node source) { isSource(source, _) } + override predicate isSource(DataFlow::Node source) { isSourceString(source, _) } override predicate isSink(DataFlow::Node sink) { sink instanceof RegexpPattern and @@ -107,7 +107,7 @@ class Config extends DataFlow::Configuration { } from Config c, DataFlow::PathNode source, DataFlow::PathNode sink, string hostPart -where c.hasFlowPath(source, sink) and c.isSource(source.getNode(), hostPart) +where c.hasFlowPath(source, sink) and c.isSourceString(source.getNode(), hostPart) select source, source, sink, "This regular expression has an unescaped dot before '" + hostPart + "', " + "so it might match more hosts than expected when $@.", sink, "the regular expression is used" diff --git a/go/ql/src/Security/CWE-020/MissingRegexpAnchor.ql b/go/ql/src/Security/CWE-020/MissingRegexpAnchor.ql index 8538e435819..f19bee4b179 100644 --- a/go/ql/src/Security/CWE-020/MissingRegexpAnchor.ql +++ b/go/ql/src/Security/CWE-020/MissingRegexpAnchor.ql @@ -63,7 +63,7 @@ predicate isInterestingUnanchoredRegexpString(string re, string msg) { class Config extends DataFlow::Configuration { Config() { this = "MissingRegexpAnchor::Config" } - predicate isSource(DataFlow::Node source, string msg) { + predicate isSourceString(DataFlow::Node source, string msg) { exists(Expr e | e = source.asExpr() | isInterestingUnanchoredRegexpString(e.getStringValue(), msg) or @@ -71,11 +71,11 @@ class Config extends DataFlow::Configuration { ) } - override predicate isSource(DataFlow::Node source) { isSource(source, _) } + override predicate isSource(DataFlow::Node source) { isSourceString(source, _) } override predicate isSink(DataFlow::Node sink) { sink instanceof RegexpPattern } } from Config c, DataFlow::PathNode source, string msg -where c.hasFlowPath(source, _) and c.isSource(source.getNode(), msg) +where c.hasFlowPath(source, _) and c.isSourceString(source.getNode(), msg) select source.getNode(), msg diff --git a/go/ql/src/Security/CWE-020/SuspiciousCharacterInRegexp.ql b/go/ql/src/Security/CWE-020/SuspiciousCharacterInRegexp.ql index 5c1b4528302..667ab999a34 100644 --- a/go/ql/src/Security/CWE-020/SuspiciousCharacterInRegexp.ql +++ b/go/ql/src/Security/CWE-020/SuspiciousCharacterInRegexp.ql @@ -32,7 +32,7 @@ predicate containsEscapedCharacter(DataFlow::Node source, string character) { class Config extends DataFlow::Configuration { Config() { this = "SuspiciousRegexpEscape" } - predicate isSource(DataFlow::Node source, string report) { + predicate isSourceString(DataFlow::Node source, string report) { containsEscapedCharacter(source, "a") and report = "the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text?" @@ -41,12 +41,12 @@ class Config extends DataFlow::Configuration { report = "a literal backspace \\b; did you mean \\\\b, a word boundary?" } - override predicate isSource(DataFlow::Node source) { isSource(source, _) } + override predicate isSource(DataFlow::Node source) { isSourceString(source, _) } override predicate isSink(DataFlow::Node sink) { sink instanceof RegexpPattern } } from Config c, DataFlow::PathNode source, DataFlow::PathNode sink, string report -where c.hasFlowPath(source, sink) and c.isSource(source.getNode(), report) +where c.hasFlowPath(source, sink) and c.isSourceString(source.getNode(), report) select source, source, sink, "This string literal that is $@ contains " + report, sink, "used as a regular expression" diff --git a/go/ql/src/Security/CWE-190/AllocationSizeOverflow.ql b/go/ql/src/Security/CWE-190/AllocationSizeOverflow.ql index c52e9c33305..4962a6626fc 100644 --- a/go/ql/src/Security/CWE-190/AllocationSizeOverflow.ql +++ b/go/ql/src/Security/CWE-190/AllocationSizeOverflow.ql @@ -20,7 +20,7 @@ from DataFlow::Node allocsz where cfg.hasFlowPath(source, sink) and - cfg.isSink(sink.getNode(), allocsz) + cfg.isSinkWithAllocationSize(sink.getNode(), allocsz) select sink, source, sink, "This operation, which is used in an $@, involves a $@ and might overflow.", allocsz, "allocation", source, "potentially large value" diff --git a/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql b/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql index 452e3b94108..486283ddcb4 100644 --- a/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql +++ b/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql @@ -66,14 +66,14 @@ class HostKeyCallbackAssignmentConfig extends DataFlow::Configuration { /** * Holds if `sink` is a value written by `write` to a field `ClientConfig.HostKeyCallback`. */ - predicate isSink(DataFlow::Node sink, Write write) { + predicate writeIsSink(DataFlow::Node sink, Write write) { exists(Field f | f.hasQualifiedName(CryptoSsh::packagePath(), "ClientConfig", "HostKeyCallback") and write.writesField(_, f, sink) ) } - override predicate isSink(DataFlow::Node sink) { this.isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { this.writeIsSink(sink, _) } } /** @@ -92,8 +92,8 @@ predicate hostCheckReachesSink(DataFlow::PathNode sink) { SsaWithFields sinkAccessPath, SsaWithFields otherSinkAccessPath | config.hasFlowPath(source, otherSink) and - config.isSink(sink.getNode(), sinkWrite) and - config.isSink(otherSink.getNode(), otherSinkWrite) and + config.writeIsSink(sink.getNode(), sinkWrite) and + config.writeIsSink(otherSink.getNode(), otherSinkWrite) and sinkWrite.writesField(sinkAccessPath.getAUse(), _, sink.getNode()) and otherSinkWrite.writesField(otherSinkAccessPath.getAUse(), _, otherSink.getNode()) and otherSinkAccessPath = sinkAccessPath.similar() diff --git a/go/ql/src/Security/CWE-327/InsecureTLS.ql b/go/ql/src/Security/CWE-327/InsecureTLS.ql index f8277226144..9163f767382 100644 --- a/go/ql/src/Security/CWE-327/InsecureTLS.ql +++ b/go/ql/src/Security/CWE-327/InsecureTLS.ql @@ -60,7 +60,7 @@ class TlsVersionFlowConfig extends TaintTracking::Configuration { /** * Holds if `source` is a TLS version source yielding value `val`. */ - predicate isSource(DataFlow::Node source, int val) { + predicate intIsSource(DataFlow::Node source, int val) { val = source.getIntValue() and val = getATlsVersion() and not DataFlow::isReturnedWithError(source) @@ -74,7 +74,7 @@ class TlsVersionFlowConfig extends TaintTracking::Configuration { fieldWrite.writesField(base, fld, sink) } - override predicate isSource(DataFlow::Node source) { isSource(source, _) } + override predicate isSource(DataFlow::Node source) { intIsSource(source, _) } override predicate isSink(DataFlow::Node sink) { isSink(sink, _, _, _) } } @@ -87,7 +87,7 @@ predicate secureTlsVersionFlow( ) { exists(int version | config.hasFlowPath(source, sink) and - config.isSource(source.getNode(), version) and + config.intIsSource(source.getNode(), version) and not isInsecureTlsVersion(version, _, fld.getName()) ) } @@ -130,7 +130,7 @@ predicate isInsecureTlsVersionFlow( ) { exists(TlsVersionFlowConfig cfg, int version, Field fld | cfg.hasFlowPath(source, sink) and - cfg.isSource(source.getNode(), version) and + cfg.intIsSource(source.getNode(), version) and cfg.isSink(sink.getNode(), fld, base, _) and isInsecureTlsVersion(version, _, fld.getName()) and // Exclude cases where a secure TLS version can also flow to the same diff --git a/go/ql/src/Security/CWE-338/InsecureRandomness.ql b/go/ql/src/Security/CWE-338/InsecureRandomness.ql index e87bbbae37b..aa26e171e50 100644 --- a/go/ql/src/Security/CWE-338/InsecureRandomness.ql +++ b/go/ql/src/Security/CWE-338/InsecureRandomness.ql @@ -17,7 +17,7 @@ import DataFlow::PathGraph from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, string kind where cfg.hasFlowPath(source, sink) and - cfg.isSink(sink.getNode(), kind) and + cfg.isSinkWithKind(sink.getNode(), kind) and ( kind != "A password-related function" or diff --git a/go/ql/src/Security/CWE-352/ConstantOauth2State.ql b/go/ql/src/Security/CWE-352/ConstantOauth2State.ql index a35fc03b030..92ac3a9b54f 100644 --- a/go/ql/src/Security/CWE-352/ConstantOauth2State.ql +++ b/go/ql/src/Security/CWE-352/ConstantOauth2State.ql @@ -31,7 +31,7 @@ class AuthCodeUrl extends Method { class ConstantStateFlowConf extends DataFlow::Configuration { ConstantStateFlowConf() { this = "ConstantStateFlowConf" } - predicate isSink(DataFlow::Node sink, DataFlow::CallNode call) { + predicate isSinkCall(DataFlow::Node sink, DataFlow::CallNode call) { exists(AuthCodeUrl m | call = m.getACall() | sink = call.getArgument(0)) } @@ -46,7 +46,7 @@ class ConstantStateFlowConf extends DataFlow::Configuration { ) } - override predicate isSink(DataFlow::Node sink) { this.isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { this.isSinkCall(sink, _) } } /** @@ -109,11 +109,11 @@ class PrivateUrlFlowsToAuthCodeUrlCall extends DataFlow::Configuration { any(Fmt::AppenderOrSprinter s).taintStep(pred, succ) } - predicate isSink(DataFlow::Node sink, DataFlow::CallNode call) { + predicate isSinkCall(DataFlow::Node sink, DataFlow::CallNode call) { exists(AuthCodeUrl m | call = m.getACall() | sink = call.getReceiver()) } - override predicate isSink(DataFlow::Node sink) { this.isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { this.isSinkCall(sink, _) } } /** @@ -126,7 +126,7 @@ class PrivateUrlFlowsToAuthCodeUrlCall extends DataFlow::Configuration { predicate privateUrlFlowsToAuthCodeUrlCall(DataFlow::CallNode call) { exists(PrivateUrlFlowsToAuthCodeUrlCall flowConfig, DataFlow::Node receiver | flowConfig.hasFlowTo(receiver) and - flowConfig.isSink(receiver, call) + flowConfig.isSinkCall(receiver, call) ) } @@ -134,7 +134,7 @@ predicate privateUrlFlowsToAuthCodeUrlCall(DataFlow::CallNode call) { class FlowToPrint extends DataFlow::Configuration { FlowToPrint() { this = "FlowToPrint" } - predicate isSink(DataFlow::Node sink, DataFlow::CallNode call) { + predicate isSinkCall(DataFlow::Node sink, DataFlow::CallNode call) { exists(LoggerCall logCall | call = logCall | sink = logCall.getAMessageComponent()) } @@ -142,7 +142,7 @@ class FlowToPrint extends DataFlow::Configuration { source = any(AuthCodeUrl m).getACall().getResult() } - override predicate isSink(DataFlow::Node sink) { this.isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { this.isSinkCall(sink, _) } } /** Holds if the provided `CallNode`'s result flows to an argument of a printer call. */ @@ -198,7 +198,7 @@ from DataFlow::CallNode sinkCall where cfg.hasFlowPath(source, sink) and - cfg.isSink(sink.getNode(), sinkCall) and + cfg.isSinkCall(sink.getNode(), sinkCall) and // Exclude cases that seem to be oauth flows done from within a terminal: not seemsLikeDoneWithinATerminal(sinkCall) and not privateUrlFlowsToAuthCodeUrlCall(sinkCall) diff --git a/go/ql/src/Security/CWE-601/BadRedirectCheck.ql b/go/ql/src/Security/CWE-601/BadRedirectCheck.ql index a35d78519bb..9beb2fe160b 100644 --- a/go/ql/src/Security/CWE-601/BadRedirectCheck.ql +++ b/go/ql/src/Security/CWE-601/BadRedirectCheck.ql @@ -94,13 +94,13 @@ predicate urlPath(DataFlow::Node nd) { class Configuration extends TaintTracking::Configuration { Configuration() { this = "BadRedirectCheck" } - override predicate isSource(DataFlow::Node source) { this.isSource(source, _) } + override predicate isSource(DataFlow::Node source) { this.isCheckedSource(source, _) } /** * Holds if `source` is the first node that flows into a use of a variable that is checked by a * bad redirect check `check`.. */ - predicate isSource(DataFlow::Node source, DataFlow::Node check) { + predicate isCheckedSource(DataFlow::Node source, DataFlow::Node check) { exists(SsaWithFields v | DataFlow::localFlow(source, v.getAUse()) and not exists(source.getAPredecessor()) and @@ -170,7 +170,7 @@ predicate isBadRedirectCheckWrapper(DataFlow::Node check, FuncDef f, FunctionInp from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Node check where - cfg.isSource(source.getNode(), check) and + cfg.isCheckedSource(source.getNode(), check) and cfg.hasFlowPath(source, sink) select check, source, sink, "This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position.", diff --git a/go/ql/src/experimental/CWE-942/CorsMisconfiguration.ql b/go/ql/src/experimental/CWE-942/CorsMisconfiguration.ql index 372b1c21642..9dd62083df4 100644 --- a/go/ql/src/experimental/CWE-942/CorsMisconfiguration.ql +++ b/go/ql/src/experimental/CWE-942/CorsMisconfiguration.ql @@ -61,7 +61,7 @@ class FlowsUntrustedToAllowOriginHeader extends TaintTracking::Configuration { override predicate isSource(DataFlow::Node source) { source instanceof UntrustedFlowSource } - predicate isSink(DataFlow::Node sink, AllowOriginHeaderWrite hw) { sink = hw.getValue() } + predicate isSinkHW(DataFlow::Node sink, AllowOriginHeaderWrite hw) { sink = hw.getValue() } override predicate isSanitizer(DataFlow::Node node) { exists(ControlFlow::ConditionGuardNode cgn | @@ -71,7 +71,7 @@ class FlowsUntrustedToAllowOriginHeader extends TaintTracking::Configuration { ) } - override predicate isSink(DataFlow::Node sink) { this.isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { this.isSinkHW(sink, _) } } /** @@ -95,7 +95,7 @@ predicate allowCredentialsIsSetToTrue(AllowOriginHeaderWrite allowOriginHW) { predicate flowsFromUntrustedToAllowOrigin(AllowOriginHeaderWrite allowOriginHW, string message) { exists(FlowsUntrustedToAllowOriginHeader cfg, DataFlow::Node sink | cfg.hasFlowTo(sink) and - cfg.isSink(sink, allowOriginHW) + cfg.isSinkHW(sink, allowOriginHW) | message = headerAllowOrigin() + " header is set to a user-defined value, and " + @@ -130,9 +130,9 @@ class FlowsFromUntrusted extends TaintTracking::Configuration { override predicate isSource(DataFlow::Node source) { source instanceof UntrustedFlowSource } - override predicate isSink(DataFlow::Node sink) { this.isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { this.isSinkCgn(sink, _) } - predicate isSink(DataFlow::Node sink, ControlFlow::ConditionGuardNode cgn) { + predicate isSinkCgn(DataFlow::Node sink, ControlFlow::ConditionGuardNode cgn) { exists(IfStmt ifs | exists(Expr operand | operand = ifs.getCond().getAChildExpr*() and @@ -171,7 +171,7 @@ class FlowsFromUntrusted extends TaintTracking::Configuration { */ predicate flowsToGuardedByCheckOnUntrusted(AllowOriginHeaderWrite allowOriginHW) { exists(FlowsFromUntrusted cfg, DataFlow::Node sink, ControlFlow::ConditionGuardNode cgn | - cfg.hasFlowTo(sink) and cfg.isSink(sink, cgn) + cfg.hasFlowTo(sink) and cfg.isSinkCgn(sink, cgn) | cgn.dominates(allowOriginHW.getBasicBlock()) ) diff --git a/go/ql/src/experimental/Unsafe/WrongUsageOfUnsafe.ql b/go/ql/src/experimental/Unsafe/WrongUsageOfUnsafe.ql index cafc719dd7a..3dfc90dc40a 100644 --- a/go/ql/src/experimental/Unsafe/WrongUsageOfUnsafe.ql +++ b/go/ql/src/experimental/Unsafe/WrongUsageOfUnsafe.ql @@ -41,16 +41,18 @@ class ConversionToUnsafePointer extends DataFlow::TypeCastNode { class UnsafeTypeCastingConf extends TaintTracking::Configuration { UnsafeTypeCastingConf() { this = "UnsafeTypeCastingConf" } - predicate isSource(DataFlow::Node source, ConversionToUnsafePointer conv) { source = conv } + predicate conversionIsSource(DataFlow::Node source, ConversionToUnsafePointer conv) { + source = conv + } - predicate isSink(DataFlow::Node sink, DataFlow::TypeCastNode ca) { + predicate typeCastNodeIsSink(DataFlow::Node sink, DataFlow::TypeCastNode ca) { ca.getOperand().getType() instanceof UnsafePointerType and sink = ca } - override predicate isSource(DataFlow::Node source) { isSource(source, _) } + override predicate isSource(DataFlow::Node source) { conversionIsSource(source, _) } - override predicate isSink(DataFlow::Node sink) { isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { typeCastNodeIsSink(sink, _) } } /* @@ -66,8 +68,8 @@ predicate castShortArrayToLongerArray( ArrayType arrTo, ArrayType arrFrom, int arrFromSize | cfg.hasFlowPath(source, sink) and - cfg.isSource(source.getNode(), castLittle) and - cfg.isSink(sink.getNode(), castBig) and + cfg.conversionIsSource(source.getNode(), castLittle) and + cfg.typeCastNodeIsSink(sink.getNode(), castBig) and arrTo = getFinalType(castBig.getResultType()) and ( // Array (whole) to array: @@ -111,8 +113,8 @@ predicate castTypeToArray(DataFlow::PathNode source, DataFlow::PathNode sink, st ArrayType arrTo, Type typeFrom | cfg.hasFlowPath(source, sink) and - cfg.isSource(source.getNode(), castLittle) and - cfg.isSink(sink.getNode(), castBig) and + cfg.conversionIsSource(source.getNode(), castLittle) and + cfg.typeCastNodeIsSink(sink.getNode(), castBig) and arrTo = getFinalType(castBig.getResultType()) and not typeFrom.getUnderlyingType() instanceof ArrayType and not typeFrom instanceof PointerType and @@ -141,8 +143,8 @@ predicate castDifferentBitSizeNumbers( NumericType numTo, NumericType numFrom | cfg.hasFlowPath(source, sink) and - cfg.isSource(source.getNode(), castLittle) and - cfg.isSink(sink.getNode(), castBig) and + cfg.conversionIsSource(source.getNode(), castLittle) and + cfg.typeCastNodeIsSink(sink.getNode(), castBig) and numTo = getFinalType(castBig.getResultType()) and numFrom = getFinalType(castLittle.getOperand().getType()) and // TODO: also consider cast from uint to int? diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/StdlibTaintFlow.ql b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/StdlibTaintFlow.ql index bc41ecbd76e..8a3456691a9 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/StdlibTaintFlow.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/StdlibTaintFlow.ql @@ -13,13 +13,13 @@ class Link extends TaintTracking::FunctionModel { } } -predicate isSource(DataFlow::Node source, DataFlow::CallNode call) { +predicate callResultisSource(DataFlow::Node source, DataFlow::CallNode call) { exists(Function fn | fn.hasQualifiedName(_, "newSource") | call = fn.getACall() and source = call.getResult() ) } -predicate isSink(DataFlow::Node sink, DataFlow::CallNode call) { +predicate callArgumentisSink(DataFlow::Node sink, DataFlow::CallNode call) { exists(Function fn | fn.hasQualifiedName(_, "sink") | call = fn.getACall() and sink = call.getArgument(1) ) @@ -28,9 +28,9 @@ predicate isSink(DataFlow::Node sink, DataFlow::CallNode call) { class FlowConf extends TaintTracking::Configuration { FlowConf() { this = "FlowConf" } - override predicate isSource(DataFlow::Node source) { isSource(source, _) } + override predicate isSource(DataFlow::Node source) { callResultisSource(source, _) } - override predicate isSink(DataFlow::Node sink) { isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { callArgumentisSink(sink, _) } } /** @@ -43,8 +43,8 @@ predicate flowsToSink(DataFlow::CallNode sourceCall) { | cfg.hasFlowPath(source, sink) and ( - isSource(source.getNode(), sourceCall) and - isSink(sink.getNode(), sinkCall) and + callResultisSource(source.getNode(), sourceCall) and + callArgumentisSink(sink.getNode(), sinkCall) and sourceCall.getArgument(0).getIntValue() = sinkCall.getArgument(0).getIntValue() ) ) @@ -52,5 +52,5 @@ predicate flowsToSink(DataFlow::CallNode sourceCall) { /* Show only flow sources that DON'T flow to their dedicated sink. */ from DataFlow::CallNode sourceCall -where isSource(_, sourceCall) and not flowsToSink(sourceCall) +where callResultisSource(_, sourceCall) and not flowsToSink(sourceCall) select sourceCall, "No flow to its sink" From 71aeeee7c87b84b728170d221b649ce8704e34c9 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 2 Nov 2022 13:53:44 +0000 Subject: [PATCH 353/796] Accept trivial change to test output In the `subpaths` section, the last node is now printed without its type if it is the sink of the path. This comes from the commit "Dataflow: Bugfix: include subpaths ending at a sink. " in https://github.com/github/codeql/pull/7526 --- .../query-tests/Security/CWE-312/CleartextLogging.expected | 2 +- .../CWE-601/BadRedirectCheck/BadRedirectCheck.expected | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index 8d66b76c863..698779c4ad0 100644 --- a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -99,7 +99,7 @@ nodes | protos/query/query.pb.go:119:10:119:22 | selection of Description : string | semmle.label | selection of Description : string | | util.go:16:9:16:18 | selection of password : string | semmle.label | selection of password : string | subpaths -| protobuf.go:14:14:14:18 | query [pointer, Description] : string | protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] : string | protos/query/query.pb.go:119:10:119:22 | selection of Description : string | protobuf.go:14:14:14:35 | call to GetDescription : string | +| protobuf.go:14:14:14:18 | query [pointer, Description] : string | protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] : string | protos/query/query.pb.go:119:10:119:22 | selection of Description : string | protobuf.go:14:14:14:35 | call to GetDescription | #select | klog.go:22:15:22:20 | header | klog.go:20:30:20:37 | selection of Header : Header | klog.go:22:15:22:20 | header | $@ flows to a logging call. | klog.go:20:30:20:37 | selection of Header | Sensitive data returned by HTTP request headers | | klog.go:28:13:28:41 | call to Get | klog.go:28:13:28:20 | selection of Header : Header | klog.go:28:13:28:41 | call to Get | $@ flows to a logging call. | klog.go:28:13:28:20 | selection of Header | Sensitive data returned by HTTP request headers | diff --git a/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.expected b/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.expected index e140ce0ce96..240c71fb6c1 100644 --- a/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.expected +++ b/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.expected @@ -42,8 +42,8 @@ nodes | main.go:87:9:87:14 | selection of Path : string | semmle.label | selection of Path : string | | main.go:91:25:91:39 | call to getTarget2 | semmle.label | call to getTarget2 | subpaths -| main.go:11:37:11:44 | redirect : string | BadRedirectCheck.go:3:18:3:22 | definition of redir : string | BadRedirectCheck.go:5:10:5:14 | redir : string | main.go:11:25:11:45 | call to sanitizeUrl : string | -| main.go:77:36:77:38 | url : string | main.go:68:17:68:24 | definition of redirect : string | main.go:73:9:73:28 | call to Clean : string | main.go:77:25:77:39 | call to getTarget1 : string | +| main.go:11:37:11:44 | redirect : string | BadRedirectCheck.go:3:18:3:22 | definition of redir : string | BadRedirectCheck.go:5:10:5:14 | redir : string | main.go:11:25:11:45 | call to sanitizeUrl | +| main.go:77:36:77:38 | url : string | main.go:68:17:68:24 | definition of redirect : string | main.go:73:9:73:28 | call to Clean : string | main.go:77:25:77:39 | call to getTarget1 | #select | BadRedirectCheck.go:4:23:4:37 | ...==... | BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir : string | main.go:11:25:11:45 | call to sanitizeUrl | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir | this value | main.go:11:25:11:45 | call to sanitizeUrl | redirect | | BadRedirectCheck.go:4:23:4:37 | ...==... | main.go:10:18:10:25 | argument corresponding to redirect : string | main.go:11:25:11:45 | call to sanitizeUrl | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:10:18:10:25 | argument corresponding to redirect | this value | main.go:11:25:11:45 | call to sanitizeUrl | redirect | From 1a65a27fde35443377ab0e53b6d8c04f4fbd6101 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 9 Nov 2022 14:07:51 +0000 Subject: [PATCH 354/796] Update test expectations In https://github.com/github/codeql/pull/8641, `localFlowExit` was changed to use `Stage2::readStepCand` instead of `read`, which means that the big-step relation is broken up less. This causes test result changes. Nothing is lost from the `select` clause, but some results may have fewer paths, and fewer nodes and edges are output in the test results. --- go/ql/test/experimental/CWE-918/SSRF.expected | 6 - .../go/frameworks/Beego/ReflectedXss.expected | 125 ------------------ .../go/frameworks/BeegoOrm/StoredXss.expected | 17 --- .../go/frameworks/Chi/ReflectedXss.expected | 6 - .../go/frameworks/Echo/OpenRedirect.expected | 2 - .../go/frameworks/Echo/ReflectedXss.expected | 40 ------ .../go/frameworks/Revel/OpenRedirect.expected | 6 - .../go/frameworks/Revel/ReflectedXss.expected | 30 ----- .../go/frameworks/Revel/TaintedPath.expected | 12 -- .../frameworks/XNetHtml/ReflectedXss.expected | 36 ----- .../Security/CWE-022/TaintedPath.expected | 4 - .../Security/CWE-022/ZipSlip.expected | 32 ----- .../Security/CWE-079/ReflectedXss.expected | 4 - .../Security/CWE-327/UnsafeTLS.expected | 18 --- .../OpenUrlRedirect/OpenUrlRedirect.expected | 7 - 15 files changed, 345 deletions(-) diff --git a/go/ql/test/experimental/CWE-918/SSRF.expected b/go/ql/test/experimental/CWE-918/SSRF.expected index 5fdd1775d3d..31b9e81ff89 100644 --- a/go/ql/test/experimental/CWE-918/SSRF.expected +++ b/go/ql/test/experimental/CWE-918/SSRF.expected @@ -13,11 +13,6 @@ edges | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:69:11:69:57 | call to Sprintf | | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:74:12:74:58 | call to Sprintf | | new-tests.go:78:18:78:24 | selection of URL : pointer type | new-tests.go:79:11:79:46 | ...+... | -| new-tests.go:81:37:81:43 | implicit dereference : URL | new-tests.go:81:37:81:43 | implicit dereference : URL | -| new-tests.go:81:37:81:43 | implicit dereference : URL | new-tests.go:81:37:81:43 | selection of URL : pointer type | -| new-tests.go:81:37:81:43 | implicit dereference : URL | new-tests.go:82:11:82:46 | ...+... | -| new-tests.go:81:37:81:43 | selection of URL : pointer type | new-tests.go:81:37:81:43 | implicit dereference : URL | -| new-tests.go:81:37:81:43 | selection of URL : pointer type | new-tests.go:81:37:81:43 | selection of URL : pointer type | | new-tests.go:81:37:81:43 | selection of URL : pointer type | new-tests.go:82:11:82:46 | ...+... | | new-tests.go:86:10:86:20 | call to Vars : map type | new-tests.go:88:11:88:46 | ...+... | | new-tests.go:95:18:95:45 | call to URLParam : string | new-tests.go:96:11:96:46 | ...+... | @@ -46,7 +41,6 @@ nodes | new-tests.go:74:12:74:58 | call to Sprintf | semmle.label | call to Sprintf | | new-tests.go:78:18:78:24 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | | new-tests.go:79:11:79:46 | ...+... | semmle.label | ...+... | -| new-tests.go:81:37:81:43 | implicit dereference : URL | semmle.label | implicit dereference : URL | | new-tests.go:81:37:81:43 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | | new-tests.go:82:11:82:46 | ...+... | semmle.label | ...+... | | new-tests.go:86:10:86:20 | call to Vars : map type | semmle.label | call to Vars : map type | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected index cb39cfdd247..6af1a75cbbd 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected @@ -1,11 +1,7 @@ edges | test.go:27:6:27:10 | definition of bound : bindMe | test.go:29:13:29:30 | type conversion | -| test.go:27:6:27:10 | definition of bound : bindMe | test.go:29:20:29:26 | selection of a : slice type | | test.go:27:6:27:10 | definition of bound : bindMe | test.go:30:13:30:27 | type conversion | | test.go:27:6:27:10 | definition of bound : bindMe | test.go:31:13:31:29 | type conversion | -| test.go:27:6:27:10 | definition of bound : bindMe | test.go:31:20:31:26 | selection of c : subBindMe | -| test.go:29:20:29:26 | selection of a : slice type | test.go:29:13:29:30 | type conversion | -| test.go:31:20:31:26 | selection of c : subBindMe | test.go:31:13:31:29 | type conversion | | test.go:36:20:36:42 | call to Cookie : string | test.go:36:13:36:43 | type conversion | | test.go:41:20:41:31 | call to Data : map type | test.go:41:13:41:52 | type conversion | | test.go:46:20:46:43 | call to GetData : basic interface type | test.go:46:13:46:53 | type conversion | @@ -30,18 +26,7 @@ edges | test.go:202:18:202:33 | selection of Form : Values | test.go:203:14:203:28 | type conversion | | test.go:217:2:217:34 | ... := ...[0] : File | test.go:220:14:220:20 | content | | test.go:217:2:217:34 | ... := ...[1] : pointer type | test.go:218:14:218:32 | type conversion | -| test.go:217:2:217:34 | ... := ...[1] : pointer type | test.go:218:21:218:22 | implicit dereference : FileHeader | -| test.go:218:21:218:22 | implicit dereference : FileHeader | test.go:218:14:218:32 | type conversion | -| test.go:218:21:218:22 | implicit dereference : FileHeader | test.go:218:21:218:22 | implicit dereference : FileHeader | | test.go:222:2:222:40 | ... := ...[0] : slice type | test.go:223:14:223:38 | type conversion | -| test.go:222:2:222:40 | ... := ...[0] : slice type | test.go:223:21:223:28 | implicit dereference : FileHeader | -| test.go:222:2:222:40 | ... := ...[0] : slice type | test.go:223:21:223:28 | index expression : pointer type | -| test.go:223:21:223:28 | implicit dereference : FileHeader | test.go:223:14:223:38 | type conversion | -| test.go:223:21:223:28 | implicit dereference : FileHeader | test.go:223:21:223:28 | implicit dereference : FileHeader | -| test.go:223:21:223:28 | implicit dereference : FileHeader | test.go:223:21:223:28 | index expression : pointer type | -| test.go:223:21:223:28 | index expression : pointer type | test.go:223:14:223:38 | type conversion | -| test.go:223:21:223:28 | index expression : pointer type | test.go:223:21:223:28 | implicit dereference : FileHeader | -| test.go:223:21:223:28 | index expression : pointer type | test.go:223:21:223:28 | index expression : pointer type | | test.go:225:7:225:28 | call to GetString : string | test.go:226:14:226:22 | type conversion | | test.go:228:8:228:35 | call to GetStrings : slice type | test.go:229:14:229:26 | type conversion | | test.go:231:9:231:17 | call to Input : Values | test.go:232:14:232:27 | type conversion | @@ -50,104 +35,26 @@ edges | test.go:253:23:253:44 | call to GetCookie : string | test.go:253:16:253:45 | type conversion | | test.go:264:62:264:83 | call to GetCookie : string | test.go:264:55:264:84 | type conversion | | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:277:21:277:61 | call to GetDisplayString | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:277:44:277:51 | implicit dereference : FileHeader | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:277:44:277:51 | index expression : pointer type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:278:21:278:53 | call to SliceChunk : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:278:21:278:56 | index expression : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:278:21:278:83 | implicit dereference : FileHeader | | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:278:21:278:92 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:279:21:279:60 | call to SliceDiff : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:279:21:279:87 | implicit dereference : FileHeader | | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:279:21:279:96 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:284:3:286:44 | call to SliceFilter : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:284:3:286:71 | implicit dereference : FileHeader | | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:284:3:286:80 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:287:21:287:65 | call to SliceIntersect : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:287:21:287:92 | implicit dereference : FileHeader | | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:287:21:287:101 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:288:21:288:65 | call to SliceIntersect : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:288:21:288:92 | implicit dereference : FileHeader | | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:288:21:288:101 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:289:21:289:61 | call to SliceMerge : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:289:21:289:88 | implicit dereference : FileHeader | | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:289:21:289:97 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:290:21:290:61 | call to SliceMerge : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:290:21:290:88 | implicit dereference : FileHeader | | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:290:21:290:97 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:291:21:291:66 | call to SlicePad : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:291:21:291:93 | implicit dereference : FileHeader | | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:291:21:291:102 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:292:21:292:66 | call to SlicePad : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:292:21:292:93 | implicit dereference : FileHeader | | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:292:21:292:102 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:293:21:293:73 | implicit dereference : FileHeader | | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:293:21:293:82 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:295:21:295:97 | call to SliceReduce : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:295:21:295:124 | implicit dereference : FileHeader | | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:295:21:295:133 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:296:21:296:52 | call to SliceShuffle : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:296:21:296:79 | implicit dereference : FileHeader | | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:296:21:296:88 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:297:21:297:51 | call to SliceUnique : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:297:21:297:78 | implicit dereference : FileHeader | | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:297:21:297:87 | selection of Filename | -| test.go:277:44:277:51 | implicit dereference : FileHeader | test.go:277:21:277:61 | call to GetDisplayString | -| test.go:277:44:277:51 | implicit dereference : FileHeader | test.go:277:44:277:51 | implicit dereference : FileHeader | -| test.go:277:44:277:51 | implicit dereference : FileHeader | test.go:277:44:277:51 | index expression : pointer type | -| test.go:277:44:277:51 | index expression : pointer type | test.go:277:21:277:61 | call to GetDisplayString | -| test.go:277:44:277:51 | index expression : pointer type | test.go:277:44:277:51 | implicit dereference : FileHeader | -| test.go:277:44:277:51 | index expression : pointer type | test.go:277:44:277:51 | index expression : pointer type | -| test.go:278:21:278:53 | call to SliceChunk : slice type | test.go:278:21:278:56 | index expression : slice type | -| test.go:278:21:278:53 | call to SliceChunk : slice type | test.go:278:21:278:83 | implicit dereference : FileHeader | -| test.go:278:21:278:53 | call to SliceChunk : slice type | test.go:278:21:278:92 | selection of Filename | -| test.go:278:21:278:56 | index expression : slice type | test.go:278:21:278:83 | implicit dereference : FileHeader | -| test.go:278:21:278:56 | index expression : slice type | test.go:278:21:278:92 | selection of Filename | -| test.go:278:21:278:83 | implicit dereference : FileHeader | test.go:278:21:278:92 | selection of Filename | -| test.go:279:21:279:60 | call to SliceDiff : slice type | test.go:279:21:279:87 | implicit dereference : FileHeader | -| test.go:279:21:279:60 | call to SliceDiff : slice type | test.go:279:21:279:96 | selection of Filename | -| test.go:279:21:279:87 | implicit dereference : FileHeader | test.go:279:21:279:96 | selection of Filename | -| test.go:284:3:286:44 | call to SliceFilter : slice type | test.go:284:3:286:71 | implicit dereference : FileHeader | -| test.go:284:3:286:44 | call to SliceFilter : slice type | test.go:284:3:286:80 | selection of Filename | -| test.go:284:3:286:71 | implicit dereference : FileHeader | test.go:284:3:286:80 | selection of Filename | -| test.go:287:21:287:65 | call to SliceIntersect : slice type | test.go:287:21:287:92 | implicit dereference : FileHeader | -| test.go:287:21:287:65 | call to SliceIntersect : slice type | test.go:287:21:287:101 | selection of Filename | -| test.go:287:21:287:92 | implicit dereference : FileHeader | test.go:287:21:287:101 | selection of Filename | -| test.go:288:21:288:65 | call to SliceIntersect : slice type | test.go:288:21:288:92 | implicit dereference : FileHeader | -| test.go:288:21:288:65 | call to SliceIntersect : slice type | test.go:288:21:288:101 | selection of Filename | -| test.go:288:21:288:92 | implicit dereference : FileHeader | test.go:288:21:288:101 | selection of Filename | -| test.go:289:21:289:61 | call to SliceMerge : slice type | test.go:289:21:289:88 | implicit dereference : FileHeader | -| test.go:289:21:289:61 | call to SliceMerge : slice type | test.go:289:21:289:97 | selection of Filename | -| test.go:289:21:289:88 | implicit dereference : FileHeader | test.go:289:21:289:97 | selection of Filename | -| test.go:290:21:290:61 | call to SliceMerge : slice type | test.go:290:21:290:88 | implicit dereference : FileHeader | -| test.go:290:21:290:61 | call to SliceMerge : slice type | test.go:290:21:290:97 | selection of Filename | -| test.go:290:21:290:88 | implicit dereference : FileHeader | test.go:290:21:290:97 | selection of Filename | -| test.go:291:21:291:66 | call to SlicePad : slice type | test.go:291:21:291:93 | implicit dereference : FileHeader | -| test.go:291:21:291:66 | call to SlicePad : slice type | test.go:291:21:291:102 | selection of Filename | -| test.go:291:21:291:93 | implicit dereference : FileHeader | test.go:291:21:291:102 | selection of Filename | -| test.go:292:21:292:66 | call to SlicePad : slice type | test.go:292:21:292:93 | implicit dereference : FileHeader | -| test.go:292:21:292:66 | call to SlicePad : slice type | test.go:292:21:292:102 | selection of Filename | -| test.go:292:21:292:93 | implicit dereference : FileHeader | test.go:292:21:292:102 | selection of Filename | -| test.go:293:21:293:73 | implicit dereference : FileHeader | test.go:293:21:293:82 | selection of Filename | -| test.go:295:21:295:97 | call to SliceReduce : slice type | test.go:295:21:295:124 | implicit dereference : FileHeader | -| test.go:295:21:295:97 | call to SliceReduce : slice type | test.go:295:21:295:133 | selection of Filename | -| test.go:295:21:295:124 | implicit dereference : FileHeader | test.go:295:21:295:133 | selection of Filename | -| test.go:296:21:296:52 | call to SliceShuffle : slice type | test.go:296:21:296:79 | implicit dereference : FileHeader | -| test.go:296:21:296:52 | call to SliceShuffle : slice type | test.go:296:21:296:88 | selection of Filename | -| test.go:296:21:296:79 | implicit dereference : FileHeader | test.go:296:21:296:88 | selection of Filename | -| test.go:297:21:297:51 | call to SliceUnique : slice type | test.go:297:21:297:78 | implicit dereference : FileHeader | -| test.go:297:21:297:51 | call to SliceUnique : slice type | test.go:297:21:297:87 | selection of Filename | -| test.go:297:21:297:78 | implicit dereference : FileHeader | test.go:297:21:297:87 | selection of Filename | | test.go:303:15:303:36 | call to GetString : string | test.go:305:21:305:48 | type assertion | -| test.go:303:15:303:36 | call to GetString : string | test.go:306:21:306:32 | call to Items : map type | | test.go:303:15:303:36 | call to GetString : string | test.go:306:21:306:52 | type assertion | -| test.go:306:21:306:32 | call to Items : map type | test.go:306:21:306:52 | type assertion | nodes | test.go:27:6:27:10 | definition of bound : bindMe | semmle.label | definition of bound : bindMe | | test.go:29:13:29:30 | type conversion | semmle.label | type conversion | -| test.go:29:20:29:26 | selection of a : slice type | semmle.label | selection of a : slice type | | test.go:30:13:30:27 | type conversion | semmle.label | type conversion | | test.go:31:13:31:29 | type conversion | semmle.label | type conversion | -| test.go:31:20:31:26 | selection of c : subBindMe | semmle.label | selection of c : subBindMe | | test.go:36:13:36:43 | type conversion | semmle.label | type conversion | | test.go:36:20:36:42 | call to Cookie : string | semmle.label | call to Cookie : string | | test.go:41:13:41:52 | type conversion | semmle.label | type conversion | @@ -191,12 +98,9 @@ nodes | test.go:217:2:217:34 | ... := ...[0] : File | semmle.label | ... := ...[0] : File | | test.go:217:2:217:34 | ... := ...[1] : pointer type | semmle.label | ... := ...[1] : pointer type | | test.go:218:14:218:32 | type conversion | semmle.label | type conversion | -| test.go:218:21:218:22 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:220:14:220:20 | content | semmle.label | content | | test.go:222:2:222:40 | ... := ...[0] : slice type | semmle.label | ... := ...[0] : slice type | | test.go:223:14:223:38 | type conversion | semmle.label | type conversion | -| test.go:223:21:223:28 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | -| test.go:223:21:223:28 | index expression : pointer type | semmle.label | index expression : pointer type | | test.go:225:7:225:28 | call to GetString : string | semmle.label | call to GetString : string | | test.go:226:14:226:22 | type conversion | semmle.label | type conversion | | test.go:228:8:228:35 | call to GetStrings : slice type | semmle.label | call to GetStrings : slice type | @@ -215,50 +119,21 @@ nodes | test.go:264:62:264:83 | call to GetCookie : string | semmle.label | call to GetCookie : string | | test.go:269:2:269:40 | ... := ...[0] : slice type | semmle.label | ... := ...[0] : slice type | | test.go:277:21:277:61 | call to GetDisplayString | semmle.label | call to GetDisplayString | -| test.go:277:44:277:51 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | -| test.go:277:44:277:51 | index expression : pointer type | semmle.label | index expression : pointer type | -| test.go:278:21:278:53 | call to SliceChunk : slice type | semmle.label | call to SliceChunk : slice type | -| test.go:278:21:278:56 | index expression : slice type | semmle.label | index expression : slice type | -| test.go:278:21:278:83 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:278:21:278:92 | selection of Filename | semmle.label | selection of Filename | -| test.go:279:21:279:60 | call to SliceDiff : slice type | semmle.label | call to SliceDiff : slice type | -| test.go:279:21:279:87 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:279:21:279:96 | selection of Filename | semmle.label | selection of Filename | -| test.go:284:3:286:44 | call to SliceFilter : slice type | semmle.label | call to SliceFilter : slice type | -| test.go:284:3:286:71 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:284:3:286:80 | selection of Filename | semmle.label | selection of Filename | -| test.go:287:21:287:65 | call to SliceIntersect : slice type | semmle.label | call to SliceIntersect : slice type | -| test.go:287:21:287:92 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:287:21:287:101 | selection of Filename | semmle.label | selection of Filename | -| test.go:288:21:288:65 | call to SliceIntersect : slice type | semmle.label | call to SliceIntersect : slice type | -| test.go:288:21:288:92 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:288:21:288:101 | selection of Filename | semmle.label | selection of Filename | -| test.go:289:21:289:61 | call to SliceMerge : slice type | semmle.label | call to SliceMerge : slice type | -| test.go:289:21:289:88 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:289:21:289:97 | selection of Filename | semmle.label | selection of Filename | -| test.go:290:21:290:61 | call to SliceMerge : slice type | semmle.label | call to SliceMerge : slice type | -| test.go:290:21:290:88 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:290:21:290:97 | selection of Filename | semmle.label | selection of Filename | -| test.go:291:21:291:66 | call to SlicePad : slice type | semmle.label | call to SlicePad : slice type | -| test.go:291:21:291:93 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:291:21:291:102 | selection of Filename | semmle.label | selection of Filename | -| test.go:292:21:292:66 | call to SlicePad : slice type | semmle.label | call to SlicePad : slice type | -| test.go:292:21:292:93 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:292:21:292:102 | selection of Filename | semmle.label | selection of Filename | -| test.go:293:21:293:73 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:293:21:293:82 | selection of Filename | semmle.label | selection of Filename | -| test.go:295:21:295:97 | call to SliceReduce : slice type | semmle.label | call to SliceReduce : slice type | -| test.go:295:21:295:124 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:295:21:295:133 | selection of Filename | semmle.label | selection of Filename | -| test.go:296:21:296:52 | call to SliceShuffle : slice type | semmle.label | call to SliceShuffle : slice type | -| test.go:296:21:296:79 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:296:21:296:88 | selection of Filename | semmle.label | selection of Filename | -| test.go:297:21:297:51 | call to SliceUnique : slice type | semmle.label | call to SliceUnique : slice type | -| test.go:297:21:297:78 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:297:21:297:87 | selection of Filename | semmle.label | selection of Filename | | test.go:303:15:303:36 | call to GetString : string | semmle.label | call to GetString : string | | test.go:305:21:305:48 | type assertion | semmle.label | type assertion | -| test.go:306:21:306:32 | call to Items : map type | semmle.label | call to Items : map type | | test.go:306:21:306:52 | type assertion | semmle.label | type assertion | subpaths #select diff --git a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.expected index e0d6b678335..502de21a22e 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.expected @@ -1,11 +1,6 @@ edges | test.go:77:13:77:16 | &... : pointer type | test.go:78:13:78:29 | type conversion | | test.go:77:13:77:16 | &... : pointer type | test.go:79:13:79:43 | type conversion | -| test.go:77:13:77:16 | &... : pointer type | test.go:79:20:79:33 | selection of substructs : slice type | -| test.go:77:13:77:16 | &... : pointer type | test.go:79:20:79:36 | index expression : SubStruct | -| test.go:79:20:79:33 | selection of substructs : slice type | test.go:79:13:79:43 | type conversion | -| test.go:79:20:79:33 | selection of substructs : slice type | test.go:79:20:79:36 | index expression : SubStruct | -| test.go:79:20:79:36 | index expression : SubStruct | test.go:79:13:79:43 | type conversion | | test.go:82:22:82:26 | &... : pointer type | test.go:83:13:83:30 | type conversion | | test.go:86:21:86:25 | &... : pointer type | test.go:87:13:87:30 | type conversion | | test.go:92:20:92:36 | call to Value : string | test.go:92:13:92:37 | type conversion | @@ -18,14 +13,6 @@ edges | test.go:99:20:99:40 | call to RawValue : basic interface type | test.go:99:13:99:50 | type conversion | | test.go:100:20:100:38 | call to String : string | test.go:100:13:100:39 | type conversion | | test.go:106:9:106:13 | &... : pointer type | test.go:107:13:107:33 | type conversion | -| test.go:106:9:106:13 | &... : pointer type | test.go:107:20:107:26 | implicit dereference : MyStruct | -| test.go:106:9:106:13 | &... : pointer type | test.go:107:20:107:26 | index expression : pointer type | -| test.go:107:20:107:26 | implicit dereference : MyStruct | test.go:107:13:107:33 | type conversion | -| test.go:107:20:107:26 | implicit dereference : MyStruct | test.go:107:20:107:26 | implicit dereference : MyStruct | -| test.go:107:20:107:26 | implicit dereference : MyStruct | test.go:107:20:107:26 | index expression : pointer type | -| test.go:107:20:107:26 | index expression : pointer type | test.go:107:13:107:33 | type conversion | -| test.go:107:20:107:26 | index expression : pointer type | test.go:107:20:107:26 | implicit dereference : MyStruct | -| test.go:107:20:107:26 | index expression : pointer type | test.go:107:20:107:26 | index expression : pointer type | | test.go:110:9:110:12 | &... : pointer type | test.go:111:13:111:29 | type conversion | | test.go:114:12:114:19 | &... : pointer type | test.go:115:13:115:48 | type conversion | | test.go:118:16:118:24 | &... : pointer type | test.go:119:13:119:43 | type conversion | @@ -43,8 +30,6 @@ nodes | test.go:77:13:77:16 | &... : pointer type | semmle.label | &... : pointer type | | test.go:78:13:78:29 | type conversion | semmle.label | type conversion | | test.go:79:13:79:43 | type conversion | semmle.label | type conversion | -| test.go:79:20:79:33 | selection of substructs : slice type | semmle.label | selection of substructs : slice type | -| test.go:79:20:79:36 | index expression : SubStruct | semmle.label | index expression : SubStruct | | test.go:82:22:82:26 | &... : pointer type | semmle.label | &... : pointer type | | test.go:83:13:83:30 | type conversion | semmle.label | type conversion | | test.go:86:21:86:25 | &... : pointer type | semmle.label | &... : pointer type | @@ -69,8 +54,6 @@ nodes | test.go:100:20:100:38 | call to String : string | semmle.label | call to String : string | | test.go:106:9:106:13 | &... : pointer type | semmle.label | &... : pointer type | | test.go:107:13:107:33 | type conversion | semmle.label | type conversion | -| test.go:107:20:107:26 | implicit dereference : MyStruct | semmle.label | implicit dereference : MyStruct | -| test.go:107:20:107:26 | index expression : pointer type | semmle.label | index expression : pointer type | | test.go:110:9:110:12 | &... : pointer type | semmle.label | &... : pointer type | | test.go:111:13:111:29 | type conversion | semmle.label | type conversion | | test.go:114:12:114:19 | &... : pointer type | semmle.label | &... : pointer type | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Chi/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/Chi/ReflectedXss.expected index d934df79582..3c2812ee51a 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Chi/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Chi/ReflectedXss.expected @@ -1,9 +1,4 @@ edges -| test.go:13:12:13:16 | implicit dereference : URL | test.go:13:12:13:16 | implicit dereference : URL | -| test.go:13:12:13:16 | implicit dereference : URL | test.go:13:12:13:16 | selection of URL : pointer type | -| test.go:13:12:13:16 | implicit dereference : URL | test.go:13:12:13:21 | selection of Path : string | -| test.go:13:12:13:16 | selection of URL : pointer type | test.go:13:12:13:16 | implicit dereference : URL | -| test.go:13:12:13:16 | selection of URL : pointer type | test.go:13:12:13:16 | selection of URL : pointer type | | test.go:13:12:13:16 | selection of URL : pointer type | test.go:13:12:13:21 | selection of Path : string | | test.go:13:12:13:21 | selection of Path : string | test.go:21:18:21:23 | hidden : string | | test.go:21:18:21:23 | hidden : string | test.go:21:11:21:24 | type conversion | @@ -11,7 +6,6 @@ edges | test.go:23:18:23:60 | call to URLParamFromCtx : string | test.go:23:11:23:61 | type conversion | | test.go:24:18:24:71 | call to URLParam : string | test.go:24:11:24:72 | type conversion | nodes -| test.go:13:12:13:16 | implicit dereference : URL | semmle.label | implicit dereference : URL | | test.go:13:12:13:16 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | | test.go:13:12:13:21 | selection of Path : string | semmle.label | selection of Path : string | | test.go:21:11:21:24 | type conversion | semmle.label | type conversion | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected b/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected index e29c066c9b5..a51104dfa47 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected @@ -1,8 +1,6 @@ edges | test.go:170:11:170:32 | call to Param : string | test.go:171:20:171:24 | param | | test.go:176:11:176:32 | call to Param : string | test.go:180:20:180:28 | ...+... | -| test.go:188:10:188:26 | selection of URL : pointer type | test.go:188:10:188:26 | selection of URL : pointer type | -| test.go:188:10:188:26 | selection of URL : pointer type | test.go:188:10:188:26 | selection of URL : pointer type | | test.go:188:10:188:26 | selection of URL : pointer type | test.go:191:21:191:32 | call to String | | test.go:188:10:188:26 | selection of URL : pointer type | test.go:191:21:191:32 | call to String | nodes diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.expected index f6d15897938..1e7a86c70cd 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.expected @@ -7,41 +7,10 @@ edges | test.go:43:9:43:34 | call to FormValue : string | test.go:44:16:44:18 | val | | test.go:49:2:49:30 | ... := ...[0] : Values | test.go:50:16:50:37 | index expression | | test.go:55:2:55:46 | ... := ...[0] : pointer type | test.go:59:20:59:25 | buffer | -| test.go:64:2:64:31 | ... := ...[0] : pointer type | test.go:65:16:65:19 | implicit dereference : Form | -| test.go:64:2:64:31 | ... := ...[0] : pointer type | test.go:65:16:65:25 | selection of Value : map type | -| test.go:64:2:64:31 | ... := ...[0] : pointer type | test.go:65:16:65:38 | index expression : slice type | | test.go:64:2:64:31 | ... := ...[0] : pointer type | test.go:65:16:65:41 | index expression | -| test.go:65:16:65:19 | implicit dereference : Form | test.go:65:16:65:19 | implicit dereference : Form | -| test.go:65:16:65:19 | implicit dereference : Form | test.go:65:16:65:25 | selection of Value : map type | -| test.go:65:16:65:19 | implicit dereference : Form | test.go:65:16:65:38 | index expression : slice type | -| test.go:65:16:65:19 | implicit dereference : Form | test.go:65:16:65:41 | index expression | -| test.go:65:16:65:25 | selection of Value : map type | test.go:65:16:65:38 | index expression : slice type | -| test.go:65:16:65:25 | selection of Value : map type | test.go:65:16:65:41 | index expression | -| test.go:65:16:65:38 | index expression : slice type | test.go:65:16:65:41 | index expression | -| test.go:70:2:70:31 | ... := ...[0] : pointer type | test.go:71:16:71:19 | implicit dereference : Form | -| test.go:70:2:70:31 | ... := ...[0] : pointer type | test.go:71:16:71:24 | selection of File : map type | -| test.go:70:2:70:31 | ... := ...[0] : pointer type | test.go:71:16:71:40 | index expression : slice type | | test.go:70:2:70:31 | ... := ...[0] : pointer type | test.go:75:20:75:25 | buffer | -| test.go:71:16:71:19 | implicit dereference : Form | test.go:71:16:71:19 | implicit dereference : Form | -| test.go:71:16:71:19 | implicit dereference : Form | test.go:71:16:71:24 | selection of File : map type | -| test.go:71:16:71:19 | implicit dereference : Form | test.go:71:16:71:40 | index expression : slice type | -| test.go:71:16:71:19 | implicit dereference : Form | test.go:75:20:75:25 | buffer | -| test.go:71:16:71:24 | selection of File : map type | test.go:71:16:71:40 | index expression : slice type | -| test.go:71:16:71:24 | selection of File : map type | test.go:75:20:75:25 | buffer | -| test.go:71:16:71:40 | index expression : slice type | test.go:75:20:75:25 | buffer | -| test.go:80:2:80:32 | ... := ...[0] : pointer type | test.go:81:16:81:18 | implicit dereference : Cookie | | test.go:80:2:80:32 | ... := ...[0] : pointer type | test.go:81:16:81:24 | selection of Value | -| test.go:81:16:81:18 | implicit dereference : Cookie | test.go:81:16:81:18 | implicit dereference : Cookie | -| test.go:81:16:81:18 | implicit dereference : Cookie | test.go:81:16:81:24 | selection of Value | -| test.go:86:13:86:25 | call to Cookies : slice type | test.go:87:16:87:25 | implicit dereference : Cookie | -| test.go:86:13:86:25 | call to Cookies : slice type | test.go:87:16:87:25 | index expression : pointer type | | test.go:86:13:86:25 | call to Cookies : slice type | test.go:87:16:87:31 | selection of Value | -| test.go:87:16:87:25 | implicit dereference : Cookie | test.go:87:16:87:25 | implicit dereference : Cookie | -| test.go:87:16:87:25 | implicit dereference : Cookie | test.go:87:16:87:25 | index expression : pointer type | -| test.go:87:16:87:25 | implicit dereference : Cookie | test.go:87:16:87:31 | selection of Value | -| test.go:87:16:87:25 | index expression : pointer type | test.go:87:16:87:25 | implicit dereference : Cookie | -| test.go:87:16:87:25 | index expression : pointer type | test.go:87:16:87:25 | index expression : pointer type | -| test.go:87:16:87:25 | index expression : pointer type | test.go:87:16:87:31 | selection of Value | | test.go:97:11:97:15 | &... : pointer type | test.go:98:16:98:21 | selection of s | | test.go:111:21:111:42 | call to Param : string | test.go:112:16:112:42 | type assertion | | test.go:122:11:122:32 | call to Param : string | test.go:123:16:123:20 | param | @@ -67,21 +36,12 @@ nodes | test.go:55:2:55:46 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | | test.go:59:20:59:25 | buffer | semmle.label | buffer | | test.go:64:2:64:31 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | -| test.go:65:16:65:19 | implicit dereference : Form | semmle.label | implicit dereference : Form | -| test.go:65:16:65:25 | selection of Value : map type | semmle.label | selection of Value : map type | -| test.go:65:16:65:38 | index expression : slice type | semmle.label | index expression : slice type | | test.go:65:16:65:41 | index expression | semmle.label | index expression | | test.go:70:2:70:31 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | -| test.go:71:16:71:19 | implicit dereference : Form | semmle.label | implicit dereference : Form | -| test.go:71:16:71:24 | selection of File : map type | semmle.label | selection of File : map type | -| test.go:71:16:71:40 | index expression : slice type | semmle.label | index expression : slice type | | test.go:75:20:75:25 | buffer | semmle.label | buffer | | test.go:80:2:80:32 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | -| test.go:81:16:81:18 | implicit dereference : Cookie | semmle.label | implicit dereference : Cookie | | test.go:81:16:81:24 | selection of Value | semmle.label | selection of Value | | test.go:86:13:86:25 | call to Cookies : slice type | semmle.label | call to Cookies : slice type | -| test.go:87:16:87:25 | implicit dereference : Cookie | semmle.label | implicit dereference : Cookie | -| test.go:87:16:87:25 | index expression : pointer type | semmle.label | index expression : pointer type | | test.go:87:16:87:31 | selection of Value | semmle.label | selection of Value | | test.go:97:11:97:15 | &... : pointer type | semmle.label | &... : pointer type | | test.go:98:16:98:21 | selection of s | semmle.label | selection of s | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected index a1e94fbd058..f0411268af8 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected @@ -1,12 +1,6 @@ edges -| EndToEnd.go:94:20:94:27 | implicit dereference : Params | EndToEnd.go:94:20:94:27 | implicit dereference : Params | -| EndToEnd.go:94:20:94:27 | implicit dereference : Params | EndToEnd.go:94:20:94:27 | selection of Params : pointer type | -| EndToEnd.go:94:20:94:27 | implicit dereference : Params | EndToEnd.go:94:20:94:49 | call to Get | -| EndToEnd.go:94:20:94:27 | selection of Params : pointer type | EndToEnd.go:94:20:94:27 | implicit dereference : Params | -| EndToEnd.go:94:20:94:27 | selection of Params : pointer type | EndToEnd.go:94:20:94:27 | selection of Params : pointer type | | EndToEnd.go:94:20:94:27 | selection of Params : pointer type | EndToEnd.go:94:20:94:49 | call to Get | nodes -| EndToEnd.go:94:20:94:27 | implicit dereference : Params | semmle.label | implicit dereference : Params | | EndToEnd.go:94:20:94:27 | selection of Params : pointer type | semmle.label | selection of Params : pointer type | | EndToEnd.go:94:20:94:49 | call to Get | semmle.label | call to Get | subpaths diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected index 7f1596dbbf8..8d8c3bc3360 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected @@ -1,48 +1,18 @@ edges -| EndToEnd.go:36:18:36:25 | implicit dereference : Params | EndToEnd.go:36:18:36:25 | implicit dereference : Params | -| EndToEnd.go:36:18:36:25 | implicit dereference : Params | EndToEnd.go:36:18:36:25 | selection of Params : pointer type | -| EndToEnd.go:36:18:36:25 | implicit dereference : Params | EndToEnd.go:37:24:37:26 | buf | -| EndToEnd.go:36:18:36:25 | selection of Params : pointer type | EndToEnd.go:36:18:36:25 | implicit dereference : Params | -| EndToEnd.go:36:18:36:25 | selection of Params : pointer type | EndToEnd.go:36:18:36:25 | selection of Params : pointer type | | EndToEnd.go:36:18:36:25 | selection of Params : pointer type | EndToEnd.go:37:24:37:26 | buf | -| EndToEnd.go:69:22:69:29 | implicit dereference : Params | EndToEnd.go:69:22:69:29 | implicit dereference : Params | -| EndToEnd.go:69:22:69:29 | implicit dereference : Params | EndToEnd.go:69:22:69:29 | selection of Params : pointer type | -| EndToEnd.go:69:22:69:29 | implicit dereference : Params | EndToEnd.go:69:22:69:51 | call to Get | -| EndToEnd.go:69:22:69:29 | selection of Params : pointer type | EndToEnd.go:69:22:69:29 | implicit dereference : Params | -| EndToEnd.go:69:22:69:29 | selection of Params : pointer type | EndToEnd.go:69:22:69:29 | selection of Params : pointer type | | EndToEnd.go:69:22:69:29 | selection of Params : pointer type | EndToEnd.go:69:22:69:51 | call to Get | -| Revel.go:70:22:70:29 | implicit dereference : Params | Revel.go:70:22:70:29 | implicit dereference : Params | -| Revel.go:70:22:70:29 | implicit dereference : Params | Revel.go:70:22:70:29 | selection of Params : pointer type | -| Revel.go:70:22:70:29 | implicit dereference : Params | Revel.go:70:22:70:35 | selection of Query | -| Revel.go:70:22:70:29 | selection of Params : pointer type | Revel.go:70:22:70:29 | implicit dereference : Params | -| Revel.go:70:22:70:29 | selection of Params : pointer type | Revel.go:70:22:70:29 | selection of Params : pointer type | | Revel.go:70:22:70:29 | selection of Params : pointer type | Revel.go:70:22:70:35 | selection of Query | -| examples/booking/app/init.go:36:44:36:48 | implicit dereference : URL | examples/booking/app/init.go:36:44:36:48 | implicit dereference : URL | -| examples/booking/app/init.go:36:44:36:48 | implicit dereference : URL | examples/booking/app/init.go:36:44:36:48 | selection of URL : pointer type | -| examples/booking/app/init.go:36:44:36:48 | implicit dereference : URL | examples/booking/app/init.go:36:44:36:53 | selection of Path | -| examples/booking/app/init.go:36:44:36:48 | selection of URL : pointer type | examples/booking/app/init.go:36:44:36:48 | implicit dereference : URL | -| examples/booking/app/init.go:36:44:36:48 | selection of URL : pointer type | examples/booking/app/init.go:36:44:36:48 | selection of URL : pointer type | | examples/booking/app/init.go:36:44:36:48 | selection of URL : pointer type | examples/booking/app/init.go:36:44:36:53 | selection of Path | -| examples/booking/app/init.go:40:49:40:53 | implicit dereference : URL | examples/booking/app/init.go:40:49:40:53 | implicit dereference : URL | -| examples/booking/app/init.go:40:49:40:53 | implicit dereference : URL | examples/booking/app/init.go:40:49:40:53 | selection of URL : pointer type | -| examples/booking/app/init.go:40:49:40:53 | implicit dereference : URL | examples/booking/app/init.go:40:49:40:58 | selection of Path | -| examples/booking/app/init.go:40:49:40:53 | selection of URL : pointer type | examples/booking/app/init.go:40:49:40:53 | implicit dereference : URL | -| examples/booking/app/init.go:40:49:40:53 | selection of URL : pointer type | examples/booking/app/init.go:40:49:40:53 | selection of URL : pointer type | | examples/booking/app/init.go:40:49:40:53 | selection of URL : pointer type | examples/booking/app/init.go:40:49:40:58 | selection of Path | nodes -| EndToEnd.go:36:18:36:25 | implicit dereference : Params | semmle.label | implicit dereference : Params | | EndToEnd.go:36:18:36:25 | selection of Params : pointer type | semmle.label | selection of Params : pointer type | | EndToEnd.go:37:24:37:26 | buf | semmle.label | buf | -| EndToEnd.go:69:22:69:29 | implicit dereference : Params | semmle.label | implicit dereference : Params | | EndToEnd.go:69:22:69:29 | selection of Params : pointer type | semmle.label | selection of Params : pointer type | | EndToEnd.go:69:22:69:51 | call to Get | semmle.label | call to Get | -| Revel.go:70:22:70:29 | implicit dereference : Params | semmle.label | implicit dereference : Params | | Revel.go:70:22:70:29 | selection of Params : pointer type | semmle.label | selection of Params : pointer type | | Revel.go:70:22:70:35 | selection of Query | semmle.label | selection of Query | -| examples/booking/app/init.go:36:44:36:48 | implicit dereference : URL | semmle.label | implicit dereference : URL | | examples/booking/app/init.go:36:44:36:48 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | | examples/booking/app/init.go:36:44:36:53 | selection of Path | semmle.label | selection of Path | -| examples/booking/app/init.go:40:49:40:53 | implicit dereference : URL | semmle.label | implicit dereference : URL | | examples/booking/app/init.go:40:49:40:53 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | | examples/booking/app/init.go:40:49:40:58 | selection of Path | semmle.label | selection of Path | subpaths diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.expected index fc24c4a73ca..97e912afcc9 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.expected @@ -1,21 +1,9 @@ edges -| EndToEnd.go:58:18:58:25 | implicit dereference : Params | EndToEnd.go:58:18:58:25 | implicit dereference : Params | -| EndToEnd.go:58:18:58:25 | implicit dereference : Params | EndToEnd.go:58:18:58:25 | selection of Params : pointer type | -| EndToEnd.go:58:18:58:25 | implicit dereference : Params | EndToEnd.go:58:18:58:47 | call to Get | -| EndToEnd.go:58:18:58:25 | selection of Params : pointer type | EndToEnd.go:58:18:58:25 | implicit dereference : Params | -| EndToEnd.go:58:18:58:25 | selection of Params : pointer type | EndToEnd.go:58:18:58:25 | selection of Params : pointer type | | EndToEnd.go:58:18:58:25 | selection of Params : pointer type | EndToEnd.go:58:18:58:47 | call to Get | -| EndToEnd.go:64:26:64:33 | implicit dereference : Params | EndToEnd.go:64:26:64:33 | implicit dereference : Params | -| EndToEnd.go:64:26:64:33 | implicit dereference : Params | EndToEnd.go:64:26:64:33 | selection of Params : pointer type | -| EndToEnd.go:64:26:64:33 | implicit dereference : Params | EndToEnd.go:64:26:64:55 | call to Get | -| EndToEnd.go:64:26:64:33 | selection of Params : pointer type | EndToEnd.go:64:26:64:33 | implicit dereference : Params | -| EndToEnd.go:64:26:64:33 | selection of Params : pointer type | EndToEnd.go:64:26:64:33 | selection of Params : pointer type | | EndToEnd.go:64:26:64:33 | selection of Params : pointer type | EndToEnd.go:64:26:64:55 | call to Get | nodes -| EndToEnd.go:58:18:58:25 | implicit dereference : Params | semmle.label | implicit dereference : Params | | EndToEnd.go:58:18:58:25 | selection of Params : pointer type | semmle.label | selection of Params : pointer type | | EndToEnd.go:58:18:58:47 | call to Get | semmle.label | call to Get | -| EndToEnd.go:64:26:64:33 | implicit dereference : Params | semmle.label | implicit dereference : Params | | EndToEnd.go:64:26:64:33 | selection of Params : pointer type | semmle.label | selection of Params : pointer type | | EndToEnd.go:64:26:64:55 | call to Get | semmle.label | call to Get | subpaths diff --git a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected index 8a4bf0b48ed..ca8c2655274 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected @@ -1,61 +1,26 @@ edges | test.go:10:2:10:42 | ... := ...[0] : pointer type | test.go:14:15:14:55 | type conversion | -| test.go:10:2:10:42 | ... := ...[0] : pointer type | test.go:14:42:14:47 | implicit dereference : Cookie | -| test.go:14:42:14:47 | implicit dereference : Cookie | test.go:14:15:14:55 | type conversion | -| test.go:14:42:14:47 | implicit dereference : Cookie | test.go:14:42:14:47 | implicit dereference : Cookie | | test.go:16:24:16:35 | selection of Body : ReadCloser | test.go:17:15:17:31 | type conversion | -| test.go:16:24:16:35 | selection of Body : ReadCloser | test.go:17:22:17:25 | implicit dereference : Node | | test.go:16:24:16:35 | selection of Body : ReadCloser | test.go:28:22:28:25 | node | -| test.go:17:22:17:25 | implicit dereference : Node | test.go:17:15:17:31 | type conversion | -| test.go:17:22:17:25 | implicit dereference : Node | test.go:17:22:17:25 | implicit dereference : Node | -| test.go:17:22:17:25 | implicit dereference : Node | test.go:28:22:28:25 | node | | test.go:19:36:19:47 | selection of Body : ReadCloser | test.go:20:15:20:32 | type conversion | -| test.go:19:36:19:47 | selection of Body : ReadCloser | test.go:20:22:20:26 | implicit dereference : Node | -| test.go:20:22:20:26 | implicit dereference : Node | test.go:20:15:20:32 | type conversion | -| test.go:20:22:20:26 | implicit dereference : Node | test.go:20:22:20:26 | implicit dereference : Node | | test.go:22:33:22:44 | selection of Body : ReadCloser | test.go:23:15:23:35 | type conversion | -| test.go:22:33:22:44 | selection of Body : ReadCloser | test.go:23:22:23:29 | implicit dereference : Node | -| test.go:22:33:22:44 | selection of Body : ReadCloser | test.go:23:22:23:29 | index expression : pointer type | -| test.go:23:22:23:29 | implicit dereference : Node | test.go:23:15:23:35 | type conversion | -| test.go:23:22:23:29 | implicit dereference : Node | test.go:23:22:23:29 | implicit dereference : Node | -| test.go:23:22:23:29 | implicit dereference : Node | test.go:23:22:23:29 | index expression : pointer type | -| test.go:23:22:23:29 | index expression : pointer type | test.go:23:15:23:35 | type conversion | -| test.go:23:22:23:29 | index expression : pointer type | test.go:23:22:23:29 | implicit dereference : Node | -| test.go:23:22:23:29 | index expression : pointer type | test.go:23:22:23:29 | index expression : pointer type | | test.go:25:45:25:56 | selection of Body : ReadCloser | test.go:26:15:26:36 | type conversion | -| test.go:25:45:25:56 | selection of Body : ReadCloser | test.go:26:22:26:30 | implicit dereference : Node | -| test.go:25:45:25:56 | selection of Body : ReadCloser | test.go:26:22:26:30 | index expression : pointer type | -| test.go:26:22:26:30 | implicit dereference : Node | test.go:26:15:26:36 | type conversion | -| test.go:26:22:26:30 | implicit dereference : Node | test.go:26:22:26:30 | implicit dereference : Node | -| test.go:26:22:26:30 | implicit dereference : Node | test.go:26:22:26:30 | index expression : pointer type | -| test.go:26:22:26:30 | index expression : pointer type | test.go:26:15:26:36 | type conversion | -| test.go:26:22:26:30 | index expression : pointer type | test.go:26:22:26:30 | implicit dereference : Node | -| test.go:26:22:26:30 | index expression : pointer type | test.go:26:22:26:30 | index expression : pointer type | | test.go:30:33:30:44 | selection of Body : ReadCloser | test.go:31:15:31:34 | call to Buffered | | test.go:30:33:30:44 | selection of Body : ReadCloser | test.go:32:15:32:29 | call to Raw | | test.go:30:33:30:44 | selection of Body : ReadCloser | test.go:34:15:34:19 | value | | test.go:30:33:30:44 | selection of Body : ReadCloser | test.go:35:15:35:30 | call to Text | | test.go:30:33:30:44 | selection of Body : ReadCloser | test.go:36:15:36:44 | type conversion | -| test.go:30:33:30:44 | selection of Body : ReadCloser | test.go:36:22:36:38 | call to Token : Token | -| test.go:36:22:36:38 | call to Token : Token | test.go:36:15:36:44 | type conversion | nodes | test.go:10:2:10:42 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | | test.go:14:15:14:55 | type conversion | semmle.label | type conversion | -| test.go:14:42:14:47 | implicit dereference : Cookie | semmle.label | implicit dereference : Cookie | | test.go:16:24:16:35 | selection of Body : ReadCloser | semmle.label | selection of Body : ReadCloser | | test.go:17:15:17:31 | type conversion | semmle.label | type conversion | -| test.go:17:22:17:25 | implicit dereference : Node | semmle.label | implicit dereference : Node | | test.go:19:36:19:47 | selection of Body : ReadCloser | semmle.label | selection of Body : ReadCloser | | test.go:20:15:20:32 | type conversion | semmle.label | type conversion | -| test.go:20:22:20:26 | implicit dereference : Node | semmle.label | implicit dereference : Node | | test.go:22:33:22:44 | selection of Body : ReadCloser | semmle.label | selection of Body : ReadCloser | | test.go:23:15:23:35 | type conversion | semmle.label | type conversion | -| test.go:23:22:23:29 | implicit dereference : Node | semmle.label | implicit dereference : Node | -| test.go:23:22:23:29 | index expression : pointer type | semmle.label | index expression : pointer type | | test.go:25:45:25:56 | selection of Body : ReadCloser | semmle.label | selection of Body : ReadCloser | | test.go:26:15:26:36 | type conversion | semmle.label | type conversion | -| test.go:26:22:26:30 | implicit dereference : Node | semmle.label | implicit dereference : Node | -| test.go:26:22:26:30 | index expression : pointer type | semmle.label | index expression : pointer type | | test.go:28:22:28:25 | node | semmle.label | node | | test.go:30:33:30:44 | selection of Body : ReadCloser | semmle.label | selection of Body : ReadCloser | | test.go:31:15:31:34 | call to Buffered | semmle.label | call to Buffered | @@ -63,7 +28,6 @@ nodes | test.go:34:15:34:19 | value | semmle.label | value | | test.go:35:15:35:30 | call to Text | semmle.label | call to Text | | test.go:36:15:36:44 | type conversion | semmle.label | type conversion | -| test.go:36:22:36:38 | call to Token : Token | semmle.label | call to Token : Token | subpaths #select | test.go:14:15:14:55 | type conversion | test.go:10:2:10:42 | ... := ...[0] : pointer type | test.go:14:15:14:55 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:10:2:10:42 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | diff --git a/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected b/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected index acbcbcdeb31..568ba70ff81 100644 --- a/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected +++ b/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected @@ -1,16 +1,12 @@ edges | TaintedPath.go:13:18:13:22 | selection of URL : pointer type | TaintedPath.go:16:29:16:40 | tainted_path | | TaintedPath.go:13:18:13:22 | selection of URL : pointer type | TaintedPath.go:20:28:20:69 | call to Join | -| tst.go:14:2:14:39 | ... := ...[1] : pointer type | tst.go:17:41:17:47 | implicit dereference : FileHeader | | tst.go:14:2:14:39 | ... := ...[1] : pointer type | tst.go:17:41:17:56 | selection of Filename | -| tst.go:17:41:17:47 | implicit dereference : FileHeader | tst.go:17:41:17:47 | implicit dereference : FileHeader | -| tst.go:17:41:17:47 | implicit dereference : FileHeader | tst.go:17:41:17:56 | selection of Filename | nodes | TaintedPath.go:13:18:13:22 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | | TaintedPath.go:16:29:16:40 | tainted_path | semmle.label | tainted_path | | TaintedPath.go:20:28:20:69 | call to Join | semmle.label | call to Join | | tst.go:14:2:14:39 | ... := ...[1] : pointer type | semmle.label | ... := ...[1] : pointer type | -| tst.go:17:41:17:47 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | tst.go:17:41:17:56 | selection of Filename | semmle.label | selection of Filename | subpaths #select diff --git a/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected b/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected index 35714558cc5..2a58d80fe26 100644 --- a/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected +++ b/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected @@ -1,55 +1,23 @@ edges | UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate : string | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | -| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] : pointer type | UnsafeUnzipSymlinkGood.go:76:24:76:29 | implicit dereference : Header | | UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] : pointer type | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname : string | -| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] : pointer type | UnsafeUnzipSymlinkGood.go:76:70:76:75 | implicit dereference : Header | | UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] : pointer type | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name : string | -| UnsafeUnzipSymlinkGood.go:76:24:76:29 | implicit dereference : Header | UnsafeUnzipSymlinkGood.go:76:24:76:29 | implicit dereference : Header | -| UnsafeUnzipSymlinkGood.go:76:24:76:29 | implicit dereference : Header | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname : string | -| UnsafeUnzipSymlinkGood.go:76:24:76:29 | implicit dereference : Header | UnsafeUnzipSymlinkGood.go:76:70:76:75 | implicit dereference : Header | -| UnsafeUnzipSymlinkGood.go:76:24:76:29 | implicit dereference : Header | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name : string | | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname : string | UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate : string | -| UnsafeUnzipSymlinkGood.go:76:70:76:75 | implicit dereference : Header | UnsafeUnzipSymlinkGood.go:76:24:76:29 | implicit dereference : Header | -| UnsafeUnzipSymlinkGood.go:76:70:76:75 | implicit dereference : Header | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname : string | -| UnsafeUnzipSymlinkGood.go:76:70:76:75 | implicit dereference : Header | UnsafeUnzipSymlinkGood.go:76:70:76:75 | implicit dereference : Header | -| UnsafeUnzipSymlinkGood.go:76:70:76:75 | implicit dereference : Header | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name : string | | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name : string | UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate : string | -| ZipSlip.go:11:2:15:2 | range statement[1] : pointer type | ZipSlip.go:12:24:12:24 | implicit dereference : File | -| ZipSlip.go:11:2:15:2 | range statement[1] : pointer type | ZipSlip.go:12:24:12:24 | implicit read of field FileHeader : FileHeader | | ZipSlip.go:11:2:15:2 | range statement[1] : pointer type | ZipSlip.go:14:20:14:20 | p | -| ZipSlip.go:12:24:12:24 | implicit dereference : File | ZipSlip.go:12:24:12:24 | implicit dereference : File | -| ZipSlip.go:12:24:12:24 | implicit dereference : File | ZipSlip.go:12:24:12:24 | implicit read of field FileHeader : FileHeader | -| ZipSlip.go:12:24:12:24 | implicit dereference : File | ZipSlip.go:14:20:14:20 | p | -| ZipSlip.go:12:24:12:24 | implicit read of field FileHeader : FileHeader | ZipSlip.go:14:20:14:20 | p | | tarslip.go:15:2:15:30 | ... := ...[0] : pointer type | tarslip.go:16:14:16:34 | call to Dir | -| tarslip.go:15:2:15:30 | ... := ...[0] : pointer type | tarslip.go:16:23:16:28 | implicit dereference : Header | -| tarslip.go:16:23:16:28 | implicit dereference : Header | tarslip.go:16:14:16:34 | call to Dir | -| tarslip.go:16:23:16:28 | implicit dereference : Header | tarslip.go:16:23:16:28 | implicit dereference : Header | -| tst.go:23:2:43:2 | range statement[1] : pointer type | tst.go:24:11:24:11 | implicit dereference : File | -| tst.go:23:2:43:2 | range statement[1] : pointer type | tst.go:24:11:24:11 | implicit read of field FileHeader : FileHeader | | tst.go:23:2:43:2 | range statement[1] : pointer type | tst.go:29:20:29:23 | path | -| tst.go:24:11:24:11 | implicit dereference : File | tst.go:24:11:24:11 | implicit dereference : File | -| tst.go:24:11:24:11 | implicit dereference : File | tst.go:24:11:24:11 | implicit read of field FileHeader : FileHeader | -| tst.go:24:11:24:11 | implicit dereference : File | tst.go:29:20:29:23 | path | -| tst.go:24:11:24:11 | implicit read of field FileHeader : FileHeader | tst.go:29:20:29:23 | path | nodes | UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate : string | semmle.label | definition of candidate : string | | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | semmle.label | call to Join | | UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | -| UnsafeUnzipSymlinkGood.go:76:24:76:29 | implicit dereference : Header | semmle.label | implicit dereference : Header | | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname : string | semmle.label | selection of Linkname : string | -| UnsafeUnzipSymlinkGood.go:76:70:76:75 | implicit dereference : Header | semmle.label | implicit dereference : Header | | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name : string | semmle.label | selection of Name : string | | ZipSlip.go:11:2:15:2 | range statement[1] : pointer type | semmle.label | range statement[1] : pointer type | -| ZipSlip.go:12:24:12:24 | implicit dereference : File | semmle.label | implicit dereference : File | -| ZipSlip.go:12:24:12:24 | implicit read of field FileHeader : FileHeader | semmle.label | implicit read of field FileHeader : FileHeader | | ZipSlip.go:14:20:14:20 | p | semmle.label | p | | tarslip.go:15:2:15:30 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | | tarslip.go:16:14:16:34 | call to Dir | semmle.label | call to Dir | -| tarslip.go:16:23:16:28 | implicit dereference : Header | semmle.label | implicit dereference : Header | | tst.go:23:2:43:2 | range statement[1] : pointer type | semmle.label | range statement[1] : pointer type | -| tst.go:24:11:24:11 | implicit dereference : File | semmle.label | implicit dereference : File | -| tst.go:24:11:24:11 | implicit read of field FileHeader : FileHeader | semmle.label | implicit read of field FileHeader : FileHeader | | tst.go:29:20:29:23 | path | semmle.label | path | subpaths #select diff --git a/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected b/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected index a71e27e63ac..a5a5028447a 100644 --- a/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected +++ b/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected @@ -9,9 +9,6 @@ edges | reflectedxsstest.go:27:2:27:38 | ... := ...[0] : pointer type | reflectedxsstest.go:28:10:28:57 | type conversion | | reflectedxsstest.go:31:2:31:44 | ... := ...[0] : File | reflectedxsstest.go:33:10:33:57 | type conversion | | reflectedxsstest.go:31:2:31:44 | ... := ...[1] : pointer type | reflectedxsstest.go:34:10:34:62 | type conversion | -| reflectedxsstest.go:31:2:31:44 | ... := ...[1] : pointer type | reflectedxsstest.go:34:46:34:51 | implicit dereference : FileHeader | -| reflectedxsstest.go:34:46:34:51 | implicit dereference : FileHeader | reflectedxsstest.go:34:10:34:62 | type conversion | -| reflectedxsstest.go:34:46:34:51 | implicit dereference : FileHeader | reflectedxsstest.go:34:46:34:51 | implicit dereference : FileHeader | | reflectedxsstest.go:38:2:38:35 | ... := ...[0] : pointer type | reflectedxsstest.go:44:10:44:55 | type conversion | | reflectedxsstest.go:38:2:38:35 | ... := ...[0] : pointer type | reflectedxsstest.go:45:10:45:18 | byteSlice | | reflectedxsstest.go:51:14:51:18 | selection of URL : pointer type | reflectedxsstest.go:54:11:54:21 | type conversion | @@ -44,7 +41,6 @@ nodes | reflectedxsstest.go:31:2:31:44 | ... := ...[1] : pointer type | semmle.label | ... := ...[1] : pointer type | | reflectedxsstest.go:33:10:33:57 | type conversion | semmle.label | type conversion | | reflectedxsstest.go:34:10:34:62 | type conversion | semmle.label | type conversion | -| reflectedxsstest.go:34:46:34:51 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | reflectedxsstest.go:38:2:38:35 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | | reflectedxsstest.go:44:10:44:55 | type conversion | semmle.label | type conversion | | reflectedxsstest.go:45:10:45:18 | byteSlice | semmle.label | byteSlice | diff --git a/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected b/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected index 6ae0010ec99..78bb9148a09 100644 --- a/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected +++ b/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected @@ -15,22 +15,8 @@ edges | UnsafeTLS.go:313:5:313:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:312:18:314:4 | slice literal | | UnsafeTLS.go:329:53:329:93 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:329:25:329:94 | call to append | | UnsafeTLS.go:334:13:334:38 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:336:26:336:58 | call to append | -| UnsafeTLS.go:334:13:334:38 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:336:54:336:54 | implicit dereference : CipherSuite | -| UnsafeTLS.go:336:54:336:54 | implicit dereference : CipherSuite | UnsafeTLS.go:336:26:336:58 | call to append | -| UnsafeTLS.go:336:54:336:54 | implicit dereference : CipherSuite | UnsafeTLS.go:336:54:336:54 | implicit dereference : CipherSuite | -| UnsafeTLS.go:342:13:342:38 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:344:40:344:40 | implicit dereference : CipherSuite | | UnsafeTLS.go:342:13:342:38 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:346:25:346:36 | cipherSuites | -| UnsafeTLS.go:344:40:344:40 | implicit dereference : CipherSuite | UnsafeTLS.go:344:40:344:40 | implicit dereference : CipherSuite | -| UnsafeTLS.go:344:40:344:40 | implicit dereference : CipherSuite | UnsafeTLS.go:346:25:346:36 | cipherSuites | -| UnsafeTLS.go:351:13:351:38 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:353:40:353:48 | implicit dereference : CipherSuite | -| UnsafeTLS.go:351:13:351:38 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:353:40:353:48 | index expression : pointer type | | UnsafeTLS.go:351:13:351:38 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:355:25:355:36 | cipherSuites | -| UnsafeTLS.go:353:40:353:48 | implicit dereference : CipherSuite | UnsafeTLS.go:353:40:353:48 | implicit dereference : CipherSuite | -| UnsafeTLS.go:353:40:353:48 | implicit dereference : CipherSuite | UnsafeTLS.go:353:40:353:48 | index expression : pointer type | -| UnsafeTLS.go:353:40:353:48 | implicit dereference : CipherSuite | UnsafeTLS.go:355:25:355:36 | cipherSuites | -| UnsafeTLS.go:353:40:353:48 | index expression : pointer type | UnsafeTLS.go:353:40:353:48 | implicit dereference : CipherSuite | -| UnsafeTLS.go:353:40:353:48 | index expression : pointer type | UnsafeTLS.go:353:40:353:48 | index expression : pointer type | -| UnsafeTLS.go:353:40:353:48 | index expression : pointer type | UnsafeTLS.go:355:25:355:36 | cipherSuites | | UnsafeTLS.go:363:5:363:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:362:18:364:4 | slice literal | | UnsafeTLS.go:371:5:371:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:370:18:372:4 | slice literal | | UnsafeTLS.go:379:5:379:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:378:18:380:4 | slice literal | @@ -108,13 +94,9 @@ nodes | UnsafeTLS.go:329:53:329:93 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | | UnsafeTLS.go:334:13:334:38 | call to InsecureCipherSuites : slice type | semmle.label | call to InsecureCipherSuites : slice type | | UnsafeTLS.go:336:26:336:58 | call to append | semmle.label | call to append | -| UnsafeTLS.go:336:54:336:54 | implicit dereference : CipherSuite | semmle.label | implicit dereference : CipherSuite | | UnsafeTLS.go:342:13:342:38 | call to InsecureCipherSuites : slice type | semmle.label | call to InsecureCipherSuites : slice type | -| UnsafeTLS.go:344:40:344:40 | implicit dereference : CipherSuite | semmle.label | implicit dereference : CipherSuite | | UnsafeTLS.go:346:25:346:36 | cipherSuites | semmle.label | cipherSuites | | UnsafeTLS.go:351:13:351:38 | call to InsecureCipherSuites : slice type | semmle.label | call to InsecureCipherSuites : slice type | -| UnsafeTLS.go:353:40:353:48 | implicit dereference : CipherSuite | semmle.label | implicit dereference : CipherSuite | -| UnsafeTLS.go:353:40:353:48 | index expression : pointer type | semmle.label | index expression : pointer type | | UnsafeTLS.go:355:25:355:36 | cipherSuites | semmle.label | cipherSuites | | UnsafeTLS.go:362:18:364:4 | slice literal | semmle.label | slice literal | | UnsafeTLS.go:363:5:363:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | diff --git a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected index c27f575acc3..7cf22603fb1 100644 --- a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected +++ b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected @@ -47,19 +47,13 @@ edges | stdlib.go:113:24:113:28 | selection of URL : pointer type | stdlib.go:113:24:113:37 | call to String | | stdlib.go:113:24:113:28 | selection of URL : pointer type | stdlib.go:113:24:113:37 | call to String | | stdlib.go:146:13:146:18 | selection of Form : Values | stdlib.go:152:23:152:28 | target | -| stdlib.go:159:11:159:15 | selection of URL : pointer type | stdlib.go:159:11:159:15 | selection of URL : pointer type | -| stdlib.go:159:11:159:15 | selection of URL : pointer type | stdlib.go:159:11:159:15 | selection of URL : pointer type | | stdlib.go:159:11:159:15 | selection of URL : pointer type | stdlib.go:162:24:162:35 | call to String | | stdlib.go:159:11:159:15 | selection of URL : pointer type | stdlib.go:162:24:162:35 | call to String | | stdlib.go:173:35:173:39 | selection of URL : pointer type | stdlib.go:173:24:173:52 | ...+... | | stdlib.go:173:35:173:39 | selection of URL : pointer type | stdlib.go:173:24:173:52 | ...+... | | stdlib.go:182:13:182:33 | call to FormValue : string | stdlib.go:184:23:184:28 | target | -| stdlib.go:190:36:190:56 | call to FormValue : string | stdlib.go:192:23:192:28 | implicit dereference : URL | | stdlib.go:190:36:190:56 | call to FormValue : string | stdlib.go:192:23:192:33 | selection of Path | | stdlib.go:190:36:190:56 | call to FormValue : string | stdlib.go:194:23:194:42 | call to EscapedPath | -| stdlib.go:192:23:192:28 | implicit dereference : URL | stdlib.go:192:23:192:28 | implicit dereference : URL | -| stdlib.go:192:23:192:28 | implicit dereference : URL | stdlib.go:192:23:192:33 | selection of Path | -| stdlib.go:192:23:192:28 | implicit dereference : URL | stdlib.go:194:23:194:42 | call to EscapedPath | nodes | OpenUrlRedirect.go:10:23:10:28 | selection of Form : Values | semmle.label | selection of Form : Values | | OpenUrlRedirect.go:10:23:10:42 | call to Get | semmle.label | call to Get | @@ -114,7 +108,6 @@ nodes | stdlib.go:182:13:182:33 | call to FormValue : string | semmle.label | call to FormValue : string | | stdlib.go:184:23:184:28 | target | semmle.label | target | | stdlib.go:190:36:190:56 | call to FormValue : string | semmle.label | call to FormValue : string | -| stdlib.go:192:23:192:28 | implicit dereference : URL | semmle.label | implicit dereference : URL | | stdlib.go:192:23:192:33 | selection of Path | semmle.label | selection of Path | | stdlib.go:194:23:194:42 | call to EscapedPath | semmle.label | call to EscapedPath | subpaths From 166a3688f8ee13933fa636f76c33d813cfb23020 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 9 Nov 2022 20:49:03 +0000 Subject: [PATCH 355/796] Use standard variable names for `hasLocationInfo` This makes them match the QLDoc and also other implementations of `hasLocationInfo`. --- .../lib/semmle/go/dataflow/internal/DataFlowUtil.qll | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll index 69ec6aedd3e..b38c3c291bd 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll @@ -161,8 +161,10 @@ class Content extends TContent { * For more information, see * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ - predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { - path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0 + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 } } @@ -254,8 +256,10 @@ class ContentSet instanceof Content { * For more information, see * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ - predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { - super.hasLocationInfo(path, sl, sc, el, ec) + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) } } From ab15a190280faa483219c8f730be200a55b8c863 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 15 Nov 2022 13:36:48 +0000 Subject: [PATCH 356/796] Address review comments --- go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll | 4 +++- .../semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index e34880f7017..dfc01b6c574 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -192,7 +192,9 @@ predicate clearsContent(Node n, Content c) { * Holds if the value that is being tracked is expected to be stored inside content `c` * at node `n`. */ -predicate expectsContent(Node n, ContentSet c) { none() } +predicate expectsContent(Node n, ContentSet c) { + FlowSummaryImpl::Private::Steps::summaryExpectsContent(n, c) +} /** Gets the type of `n` used for type pruning. */ DataFlowType getNodeType(Node n) { diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll index 5b5382a3cb7..2af6cde0d63 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll @@ -61,7 +61,9 @@ DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { none() } * `input`, output specification `output`, kind `kind`, and a flag `generated` * stating whether the summary is autogenerated. */ -predicate summaryElement(Callable c, string input, string output, string kind, boolean generated) { +predicate summaryElement( + SummarizedCallableBase c, string input, string output, string kind, boolean generated +) { exists( string namespace, string type, boolean subtypes, string name, string signature, string ext | From 4073d776358d86ab40986b136cd347c6205cad3e Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 17 Nov 2022 14:25:23 +0000 Subject: [PATCH 357/796] Add change notes --- .../change-notes/2022-11-17-allow-implicit-read-signature.md | 4 ++++ go/ql/lib/change-notes/2022-11-17-barrierguard-deprecation.md | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 go/ql/lib/change-notes/2022-11-17-allow-implicit-read-signature.md create mode 100644 go/ql/lib/change-notes/2022-11-17-barrierguard-deprecation.md diff --git a/go/ql/lib/change-notes/2022-11-17-allow-implicit-read-signature.md b/go/ql/lib/change-notes/2022-11-17-allow-implicit-read-signature.md new file mode 100644 index 00000000000..a796e953583 --- /dev/null +++ b/go/ql/lib/change-notes/2022-11-17-allow-implicit-read-signature.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +The signature of `allowImplicitRead` on `DataFlow::Configuration` and `TaintTracking::Configuration` has changed from `allowImplicitRead(DataFlow::Node node, DataFlow::Content c)` to `allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c)`. diff --git a/go/ql/lib/change-notes/2022-11-17-barrierguard-deprecation.md b/go/ql/lib/change-notes/2022-11-17-barrierguard-deprecation.md new file mode 100644 index 00000000000..2bd95798f89 --- /dev/null +++ b/go/ql/lib/change-notes/2022-11-17-barrierguard-deprecation.md @@ -0,0 +1,4 @@ +--- +category: deprecated +--- +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. From 4e88b8453abd2ffd04c7a6d61fe3e86271590367 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Wed, 16 Nov 2022 13:41:21 +0100 Subject: [PATCH 358/796] Ruby: add flow summary for Enumerable#index_with --- .../codeql/ruby/frameworks/ActiveSupport.qll | 16 +++- .../ActiveSupportDataFlow.expected | 81 +++++++++++++++++++ .../active_support/hash_extensions.rb | 18 +++++ 3 files changed, 114 insertions(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll index 7d3286a0a74..48bd1193aaa 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll @@ -294,7 +294,21 @@ module ActiveSupport { preservesValue = true } } - // TODO: index_with, pick, pluck (they require Hash dataflow) + + private class IndexWithSummary extends SimpleSummarizedCallable { + IndexWithSummary() { this = "index_with" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[self].Element[any]" and + output = "Argument[block].Parameter[0]" and + preservesValue = true + or + input = ["Argument[0]", "Argument[block].ReturnValue"] and + output = "ReturnValue.Element[?]" and + preservesValue = true + } + } + // TODO: pick, pluck (they require Hash dataflow) } } diff --git a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected index 11b6b46ee3e..c2d169d1bb9 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected +++ b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected @@ -286,6 +286,40 @@ edges | hash_extensions.rb:73:10:73:10 | h [element] : | hash_extensions.rb:73:10:73:16 | ...[...] | | hash_extensions.rb:74:10:74:10 | h [element] : | hash_extensions.rb:74:10:74:16 | ...[...] | | hash_extensions.rb:74:10:74:10 | h [element] : | hash_extensions.rb:74:10:74:16 | ...[...] | +| hash_extensions.rb:80:15:80:25 | call to source : | hash_extensions.rb:81:9:81:14 | values [element 0] : | +| hash_extensions.rb:80:15:80:25 | call to source : | hash_extensions.rb:81:9:81:14 | values [element 0] : | +| hash_extensions.rb:80:28:80:38 | call to source : | hash_extensions.rb:81:9:81:14 | values [element 1] : | +| hash_extensions.rb:80:28:80:38 | call to source : | hash_extensions.rb:81:9:81:14 | values [element 1] : | +| hash_extensions.rb:80:41:80:51 | call to source : | hash_extensions.rb:81:9:81:14 | values [element 2] : | +| hash_extensions.rb:80:41:80:51 | call to source : | hash_extensions.rb:81:9:81:14 | values [element 2] : | +| hash_extensions.rb:81:9:81:14 | values [element 0] : | hash_extensions.rb:81:31:81:33 | key : | +| hash_extensions.rb:81:9:81:14 | values [element 0] : | hash_extensions.rb:81:31:81:33 | key : | +| hash_extensions.rb:81:9:81:14 | values [element 1] : | hash_extensions.rb:81:31:81:33 | key : | +| hash_extensions.rb:81:9:81:14 | values [element 1] : | hash_extensions.rb:81:31:81:33 | key : | +| hash_extensions.rb:81:9:81:14 | values [element 2] : | hash_extensions.rb:81:31:81:33 | key : | +| hash_extensions.rb:81:9:81:14 | values [element 2] : | hash_extensions.rb:81:31:81:33 | key : | +| hash_extensions.rb:81:9:84:7 | call to index_with [element] : | hash_extensions.rb:86:10:86:10 | h [element] : | +| hash_extensions.rb:81:9:84:7 | call to index_with [element] : | hash_extensions.rb:86:10:86:10 | h [element] : | +| hash_extensions.rb:81:9:84:7 | call to index_with [element] : | hash_extensions.rb:87:10:87:10 | h [element] : | +| hash_extensions.rb:81:9:84:7 | call to index_with [element] : | hash_extensions.rb:87:10:87:10 | h [element] : | +| hash_extensions.rb:81:31:81:33 | key : | hash_extensions.rb:82:14:82:16 | key | +| hash_extensions.rb:81:31:81:33 | key : | hash_extensions.rb:82:14:82:16 | key | +| hash_extensions.rb:83:9:83:19 | call to source : | hash_extensions.rb:81:9:84:7 | call to index_with [element] : | +| hash_extensions.rb:83:9:83:19 | call to source : | hash_extensions.rb:81:9:84:7 | call to index_with [element] : | +| hash_extensions.rb:86:10:86:10 | h [element] : | hash_extensions.rb:86:10:86:16 | ...[...] | +| hash_extensions.rb:86:10:86:10 | h [element] : | hash_extensions.rb:86:10:86:16 | ...[...] | +| hash_extensions.rb:87:10:87:10 | h [element] : | hash_extensions.rb:87:10:87:16 | ...[...] | +| hash_extensions.rb:87:10:87:10 | h [element] : | hash_extensions.rb:87:10:87:16 | ...[...] | +| hash_extensions.rb:89:9:89:38 | call to index_with [element] : | hash_extensions.rb:91:10:91:10 | j [element] : | +| hash_extensions.rb:89:9:89:38 | call to index_with [element] : | hash_extensions.rb:91:10:91:10 | j [element] : | +| hash_extensions.rb:89:9:89:38 | call to index_with [element] : | hash_extensions.rb:92:10:92:10 | j [element] : | +| hash_extensions.rb:89:9:89:38 | call to index_with [element] : | hash_extensions.rb:92:10:92:10 | j [element] : | +| hash_extensions.rb:89:27:89:37 | call to source : | hash_extensions.rb:89:9:89:38 | call to index_with [element] : | +| hash_extensions.rb:89:27:89:37 | call to source : | hash_extensions.rb:89:9:89:38 | call to index_with [element] : | +| hash_extensions.rb:91:10:91:10 | j [element] : | hash_extensions.rb:91:10:91:16 | ...[...] | +| hash_extensions.rb:91:10:91:10 | j [element] : | hash_extensions.rb:91:10:91:16 | ...[...] | +| hash_extensions.rb:92:10:92:10 | j [element] : | hash_extensions.rb:92:10:92:16 | ...[...] | +| hash_extensions.rb:92:10:92:10 | j [element] : | hash_extensions.rb:92:10:92:16 | ...[...] | nodes | active_support.rb:10:9:10:18 | call to source : | semmle.label | call to source : | | active_support.rb:11:10:11:10 | x : | semmle.label | x : | @@ -648,6 +682,46 @@ nodes | hash_extensions.rb:74:10:74:10 | h [element] : | semmle.label | h [element] : | | hash_extensions.rb:74:10:74:16 | ...[...] | semmle.label | ...[...] | | hash_extensions.rb:74:10:74:16 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:80:15:80:25 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:80:15:80:25 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:80:28:80:38 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:80:28:80:38 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:80:41:80:51 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:80:41:80:51 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:81:9:81:14 | values [element 0] : | semmle.label | values [element 0] : | +| hash_extensions.rb:81:9:81:14 | values [element 0] : | semmle.label | values [element 0] : | +| hash_extensions.rb:81:9:81:14 | values [element 1] : | semmle.label | values [element 1] : | +| hash_extensions.rb:81:9:81:14 | values [element 1] : | semmle.label | values [element 1] : | +| hash_extensions.rb:81:9:81:14 | values [element 2] : | semmle.label | values [element 2] : | +| hash_extensions.rb:81:9:81:14 | values [element 2] : | semmle.label | values [element 2] : | +| hash_extensions.rb:81:9:84:7 | call to index_with [element] : | semmle.label | call to index_with [element] : | +| hash_extensions.rb:81:9:84:7 | call to index_with [element] : | semmle.label | call to index_with [element] : | +| hash_extensions.rb:81:31:81:33 | key : | semmle.label | key : | +| hash_extensions.rb:81:31:81:33 | key : | semmle.label | key : | +| hash_extensions.rb:82:14:82:16 | key | semmle.label | key | +| hash_extensions.rb:82:14:82:16 | key | semmle.label | key | +| hash_extensions.rb:83:9:83:19 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:83:9:83:19 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:86:10:86:10 | h [element] : | semmle.label | h [element] : | +| hash_extensions.rb:86:10:86:10 | h [element] : | semmle.label | h [element] : | +| hash_extensions.rb:86:10:86:16 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:86:10:86:16 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:87:10:87:10 | h [element] : | semmle.label | h [element] : | +| hash_extensions.rb:87:10:87:10 | h [element] : | semmle.label | h [element] : | +| hash_extensions.rb:87:10:87:16 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:87:10:87:16 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:89:9:89:38 | call to index_with [element] : | semmle.label | call to index_with [element] : | +| hash_extensions.rb:89:9:89:38 | call to index_with [element] : | semmle.label | call to index_with [element] : | +| hash_extensions.rb:89:27:89:37 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:89:27:89:37 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:91:10:91:10 | j [element] : | semmle.label | j [element] : | +| hash_extensions.rb:91:10:91:10 | j [element] : | semmle.label | j [element] : | +| hash_extensions.rb:91:10:91:16 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:91:10:91:16 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:92:10:92:10 | j [element] : | semmle.label | j [element] : | +| hash_extensions.rb:92:10:92:10 | j [element] : | semmle.label | j [element] : | +| hash_extensions.rb:92:10:92:16 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:92:10:92:16 | ...[...] | semmle.label | ...[...] | subpaths #select | active_support.rb:182:10:182:13 | ...[...] | active_support.rb:180:10:180:17 | call to source : | active_support.rb:182:10:182:13 | ...[...] | $@ | active_support.rb:180:10:180:17 | call to source : | call to source : | @@ -685,3 +759,10 @@ subpaths | hash_extensions.rb:74:10:74:16 | ...[...] | hash_extensions.rb:67:15:67:25 | call to source : | hash_extensions.rb:74:10:74:16 | ...[...] | $@ | hash_extensions.rb:67:15:67:25 | call to source : | call to source : | | hash_extensions.rb:74:10:74:16 | ...[...] | hash_extensions.rb:67:28:67:38 | call to source : | hash_extensions.rb:74:10:74:16 | ...[...] | $@ | hash_extensions.rb:67:28:67:38 | call to source : | call to source : | | hash_extensions.rb:74:10:74:16 | ...[...] | hash_extensions.rb:67:41:67:51 | call to source : | hash_extensions.rb:74:10:74:16 | ...[...] | $@ | hash_extensions.rb:67:41:67:51 | call to source : | call to source : | +| hash_extensions.rb:82:14:82:16 | key | hash_extensions.rb:80:15:80:25 | call to source : | hash_extensions.rb:82:14:82:16 | key | $@ | hash_extensions.rb:80:15:80:25 | call to source : | call to source : | +| hash_extensions.rb:82:14:82:16 | key | hash_extensions.rb:80:28:80:38 | call to source : | hash_extensions.rb:82:14:82:16 | key | $@ | hash_extensions.rb:80:28:80:38 | call to source : | call to source : | +| hash_extensions.rb:82:14:82:16 | key | hash_extensions.rb:80:41:80:51 | call to source : | hash_extensions.rb:82:14:82:16 | key | $@ | hash_extensions.rb:80:41:80:51 | call to source : | call to source : | +| hash_extensions.rb:86:10:86:16 | ...[...] | hash_extensions.rb:83:9:83:19 | call to source : | hash_extensions.rb:86:10:86:16 | ...[...] | $@ | hash_extensions.rb:83:9:83:19 | call to source : | call to source : | +| hash_extensions.rb:87:10:87:16 | ...[...] | hash_extensions.rb:83:9:83:19 | call to source : | hash_extensions.rb:87:10:87:16 | ...[...] | $@ | hash_extensions.rb:83:9:83:19 | call to source : | call to source : | +| hash_extensions.rb:91:10:91:16 | ...[...] | hash_extensions.rb:89:27:89:37 | call to source : | hash_extensions.rb:91:10:91:16 | ...[...] | $@ | hash_extensions.rb:89:27:89:37 | call to source : | call to source : | +| hash_extensions.rb:92:10:92:16 | ...[...] | hash_extensions.rb:89:27:89:37 | call to source : | hash_extensions.rb:92:10:92:16 | ...[...] | $@ | hash_extensions.rb:89:27:89:37 | call to source : | call to source : | diff --git a/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb b/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb index 6669cd83c37..4675e6ea72e 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb +++ b/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb @@ -75,3 +75,21 @@ def m_index_by end m_index_by() + +def m_index_with + values = [source("a"), source("b"), source("c")] + h = values.index_with do |key| + sink key # $ hasValueFlow=a $ hasValueFlow=b $ hasValueFlow=c + source("x") + end + + sink h[:foo] # $ hasValueFlow=x + sink h[:bar] # $ hasValueFlow=x + + j = values.index_with(source("y")) + + sink j[:foo] # $ hasValueFlow=y + sink j[:bar] # $ hasValueFlow=y +end + +m_index_with() From e105c13e777d5a251a0e232224d34101cbda195e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 17 Nov 2022 16:40:45 +0000 Subject: [PATCH 359/796] Release preparation for version 2.11.4 --- cpp/ql/lib/CHANGELOG.md | 4 ++++ cpp/ql/lib/change-notes/released/0.4.4.md | 3 +++ cpp/ql/lib/codeql-pack.release.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/CHANGELOG.md | 4 ++++ cpp/ql/src/change-notes/released/0.4.4.md | 3 +++ cpp/ql/src/codeql-pack.release.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md | 4 ++++ .../Solorigate/lib/change-notes/released/1.3.4.md | 3 +++ .../Solorigate/lib/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/CHANGELOG.md | 4 ++++ .../Solorigate/src/change-notes/released/1.3.4.md | 3 +++ .../Solorigate/src/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/CHANGELOG.md | 6 ++++++ .../0.4.4.md} | 9 +++++---- csharp/ql/lib/codeql-pack.release.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/CHANGELOG.md | 4 ++++ csharp/ql/src/change-notes/released/0.4.4.md | 3 +++ csharp/ql/src/codeql-pack.release.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/lib/CHANGELOG.md | 4 ++++ go/ql/lib/change-notes/released/0.3.4.md | 3 +++ go/ql/lib/codeql-pack.release.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/CHANGELOG.md | 4 ++++ go/ql/src/change-notes/released/0.3.4.md | 3 +++ go/ql/src/codeql-pack.release.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/CHANGELOG.md | 12 ++++++++++++ ...2022-10-19-android-startactivities-summaries.md | 4 ---- .../change-notes/2022-10-31-shared-redos-pack.md | 4 ---- java/ql/lib/change-notes/2022-11-10-getInfo.md | 4 ---- .../lib/change-notes/2022-11-10-kotlin-default.md | 4 ---- java/ql/lib/change-notes/released/0.4.4.md | 11 +++++++++++ java/ql/lib/codeql-pack.release.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/CHANGELOG.md | 7 +++++++ .../2022-10-07-sensitive-keyboard-cache.md | 4 ---- .../0.4.4.md} | 8 +++++--- java/ql/src/codeql-pack.release.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/CHANGELOG.md | 6 ++++++ .../lib/change-notes/2022-11-15-typescript-4-9.md | 4 ---- javascript/ql/lib/change-notes/released/0.3.4.md | 5 +++++ javascript/ql/lib/codeql-pack.release.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/CHANGELOG.md | 13 +++++++++++++ .../ql/src/change-notes/2022-11-08-hapi-glue.md | 4 ---- .../src/change-notes/2022-11-08-yaml-locations.md | 5 ----- .../2022-11-14-dynamic-import-type-expr.md | 5 ----- javascript/ql/src/change-notes/released/0.4.4.md | 12 ++++++++++++ javascript/ql/src/codeql-pack.release.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/CHANGELOG.md | 4 ++++ misc/suite-helpers/change-notes/released/0.3.4.md | 3 +++ misc/suite-helpers/codeql-pack.release.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/CHANGELOG.md | 6 ++++++ .../0.6.4.md} | 9 +++++---- python/ql/lib/codeql-pack.release.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/CHANGELOG.md | 4 ++++ python/ql/src/change-notes/released/0.5.4.md | 3 +++ python/ql/src/codeql-pack.release.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/CHANGELOG.md | 14 ++++++++++++++ .../change-notes/2022-10-28-try-code-execution.md | 4 ---- .../2022-11-01-actioncontroller-logger.md | 6 ------ .../2022-11-08-activesupport-hash-extensions.md | 4 ---- .../2022-11-09-actioncable-channels.md | 4 ---- ruby/ql/lib/change-notes/2022-11-10-arel-sql.md | 5 ----- ...2022-11-14-activesupport-enumerable-index-by.md | 4 ---- ruby/ql/lib/change-notes/released/0.4.4.md | 13 +++++++++++++ ruby/ql/lib/codeql-pack.release.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/CHANGELOG.md | 10 ++++++++++ ...2022-10-10-unsafe-shell-command-construction.md | 4 ---- ruby/ql/src/change-notes/2022-11-10-arel-sql.md | 4 ---- ruby/ql/src/change-notes/released/0.4.4.md | 9 +++++++++ ruby/ql/src/codeql-pack.release.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- .../2022-09-26-initial-version.md => CHANGELOG.md} | 7 ++++--- shared/regex/change-notes/released/0.0.1.md | 5 +++++ shared/regex/codeql-pack.release.yml | 2 ++ shared/regex/qlpack.yml | 2 +- shared/ssa/CHANGELOG.md | 4 ++++ shared/ssa/change-notes/released/0.0.5.md | 3 +++ shared/ssa/codeql-pack.release.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/typos/CHANGELOG.md | 4 ++++ shared/typos/change-notes/released/0.0.5.md | 3 +++ shared/typos/codeql-pack.release.yml | 2 +- shared/typos/qlpack.yml | 2 +- 97 files changed, 266 insertions(+), 126 deletions(-) create mode 100644 cpp/ql/lib/change-notes/released/0.4.4.md create mode 100644 cpp/ql/src/change-notes/released/0.4.4.md create mode 100644 csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.4.md create mode 100644 csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.4.md rename csharp/ql/lib/change-notes/{2022-11-09-modelsasdataextensions.md => released/0.4.4.md} (72%) create mode 100644 csharp/ql/src/change-notes/released/0.4.4.md create mode 100644 go/ql/lib/change-notes/released/0.3.4.md create mode 100644 go/ql/src/change-notes/released/0.3.4.md delete mode 100644 java/ql/lib/change-notes/2022-10-19-android-startactivities-summaries.md delete mode 100644 java/ql/lib/change-notes/2022-10-31-shared-redos-pack.md delete mode 100644 java/ql/lib/change-notes/2022-11-10-getInfo.md delete mode 100644 java/ql/lib/change-notes/2022-11-10-kotlin-default.md create mode 100644 java/ql/lib/change-notes/released/0.4.4.md delete mode 100644 java/ql/src/change-notes/2022-10-07-sensitive-keyboard-cache.md rename java/ql/src/change-notes/{2022-10-19-insufficient-key-size.md => released/0.4.4.md} (59%) delete mode 100644 javascript/ql/lib/change-notes/2022-11-15-typescript-4-9.md create mode 100644 javascript/ql/lib/change-notes/released/0.3.4.md delete mode 100644 javascript/ql/src/change-notes/2022-11-08-hapi-glue.md delete mode 100644 javascript/ql/src/change-notes/2022-11-08-yaml-locations.md delete mode 100644 javascript/ql/src/change-notes/2022-11-14-dynamic-import-type-expr.md create mode 100644 javascript/ql/src/change-notes/released/0.4.4.md create mode 100644 misc/suite-helpers/change-notes/released/0.3.4.md rename python/ql/lib/change-notes/{2022-10-31-shared-redos-pack.md => released/0.6.4.md} (59%) create mode 100644 python/ql/src/change-notes/released/0.5.4.md delete mode 100644 ruby/ql/lib/change-notes/2022-10-28-try-code-execution.md delete mode 100644 ruby/ql/lib/change-notes/2022-11-01-actioncontroller-logger.md delete mode 100644 ruby/ql/lib/change-notes/2022-11-08-activesupport-hash-extensions.md delete mode 100644 ruby/ql/lib/change-notes/2022-11-09-actioncable-channels.md delete mode 100644 ruby/ql/lib/change-notes/2022-11-10-arel-sql.md delete mode 100644 ruby/ql/lib/change-notes/2022-11-14-activesupport-enumerable-index-by.md create mode 100644 ruby/ql/lib/change-notes/released/0.4.4.md delete mode 100644 ruby/ql/src/change-notes/2022-10-10-unsafe-shell-command-construction.md delete mode 100644 ruby/ql/src/change-notes/2022-11-10-arel-sql.md create mode 100644 ruby/ql/src/change-notes/released/0.4.4.md rename shared/regex/{change-notes/2022-09-26-initial-version.md => CHANGELOG.md} (76%) create mode 100644 shared/regex/change-notes/released/0.0.1.md create mode 100644 shared/regex/codeql-pack.release.yml create mode 100644 shared/ssa/change-notes/released/0.0.5.md create mode 100644 shared/typos/change-notes/released/0.0.5.md diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index 0a7a31b8db9..30a996fdba6 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.4 + +No user-facing changes. + ## 0.4.3 ### Minor Analysis Improvements diff --git a/cpp/ql/lib/change-notes/released/0.4.4.md b/cpp/ql/lib/change-notes/released/0.4.4.md new file mode 100644 index 00000000000..33e1c91255d --- /dev/null +++ b/cpp/ql/lib/change-notes/released/0.4.4.md @@ -0,0 +1,3 @@ +## 0.4.4 + +No user-facing changes. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index 1ec9c4ea5d9..e9b57993a01 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.3 +lastReleaseVersion: 0.4.4 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index ef1fd2099a3..e8c0a17068e 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.4.4-dev +version: 0.4.4 groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index f32f416b540..5546105176e 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.4 + +No user-facing changes. + ## 0.4.3 ### Minor Analysis Improvements diff --git a/cpp/ql/src/change-notes/released/0.4.4.md b/cpp/ql/src/change-notes/released/0.4.4.md new file mode 100644 index 00000000000..33e1c91255d --- /dev/null +++ b/cpp/ql/src/change-notes/released/0.4.4.md @@ -0,0 +1,3 @@ +## 0.4.4 + +No user-facing changes. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index 1ec9c4ea5d9..e9b57993a01 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.3 +lastReleaseVersion: 0.4.4 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 3a44ef8b743..4ee5b28070c 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.4.4-dev +version: 0.4.4 groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index 98c13dfaa77..4aa822f9369 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.4 + +No user-facing changes. + ## 1.3.3 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.4.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.4.md new file mode 100644 index 00000000000..5073aca7222 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.4.md @@ -0,0 +1,3 @@ +## 1.3.4 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index eb1f7dabc84..8263ddf2c8b 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.3.3 +lastReleaseVersion: 1.3.4 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index ccab1b3a8b8..41c454bb5c0 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.3.4-dev +version: 1.3.4 groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index 98c13dfaa77..4aa822f9369 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.4 + +No user-facing changes. + ## 1.3.3 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.4.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.4.md new file mode 100644 index 00000000000..5073aca7222 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.4.md @@ -0,0 +1,3 @@ +## 1.3.4 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index eb1f7dabc84..8263ddf2c8b 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.3.3 +lastReleaseVersion: 1.3.4 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 209538a2014..7ba0669ba7b 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.3.4-dev +version: 1.3.4 groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 2fff5e72443..265b1a3183d 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.4.4 + +### Minor Analysis Improvements + +* The `[Summary|Sink|Source]ModelCsv` classes have been deprecated and Models as Data models are defined as data extensions instead. + ## 0.4.3 No user-facing changes. diff --git a/csharp/ql/lib/change-notes/2022-11-09-modelsasdataextensions.md b/csharp/ql/lib/change-notes/released/0.4.4.md similarity index 72% rename from csharp/ql/lib/change-notes/2022-11-09-modelsasdataextensions.md rename to csharp/ql/lib/change-notes/released/0.4.4.md index 1c9bb14754d..b3d7e2c3be1 100644 --- a/csharp/ql/lib/change-notes/2022-11-09-modelsasdataextensions.md +++ b/csharp/ql/lib/change-notes/released/0.4.4.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- -* The `[Summary|Sink|Source]ModelCsv` classes have been deprecated and Models as Data models are defined as data extensions instead. \ No newline at end of file +## 0.4.4 + +### Minor Analysis Improvements + +* The `[Summary|Sink|Source]ModelCsv` classes have been deprecated and Models as Data models are defined as data extensions instead. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index 1ec9c4ea5d9..e9b57993a01 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.3 +lastReleaseVersion: 0.4.4 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index a43762f9433..bd5cd1b7e16 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.4.4-dev +version: 0.4.4 groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index 46be24580ef..486c21a1125 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.4 + +No user-facing changes. + ## 0.4.3 No user-facing changes. diff --git a/csharp/ql/src/change-notes/released/0.4.4.md b/csharp/ql/src/change-notes/released/0.4.4.md new file mode 100644 index 00000000000..33e1c91255d --- /dev/null +++ b/csharp/ql/src/change-notes/released/0.4.4.md @@ -0,0 +1,3 @@ +## 0.4.4 + +No user-facing changes. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index 1ec9c4ea5d9..e9b57993a01 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.3 +lastReleaseVersion: 0.4.4 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 7f537bcae49..6964f93b085 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.4.4-dev +version: 0.4.4 groups: - csharp - queries diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index 681412ed46f..a5f5d96020a 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.4 + +No user-facing changes. + ## 0.3.3 No user-facing changes. diff --git a/go/ql/lib/change-notes/released/0.3.4.md b/go/ql/lib/change-notes/released/0.3.4.md new file mode 100644 index 00000000000..5fae94b07c9 --- /dev/null +++ b/go/ql/lib/change-notes/released/0.3.4.md @@ -0,0 +1,3 @@ +## 0.3.4 + +No user-facing changes. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index 9da182d3394..5ed15c24b9c 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.3 +lastReleaseVersion: 0.3.4 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 9daccdd80b6..0d453d90f88 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.3.4-dev +version: 0.3.4 groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index 65aa3c40d99..f74e3c23d7c 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.4 + +No user-facing changes. + ## 0.3.3 ### Minor Analysis Improvements diff --git a/go/ql/src/change-notes/released/0.3.4.md b/go/ql/src/change-notes/released/0.3.4.md new file mode 100644 index 00000000000..5fae94b07c9 --- /dev/null +++ b/go/ql/src/change-notes/released/0.3.4.md @@ -0,0 +1,3 @@ +## 0.3.4 + +No user-facing changes. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index 9da182d3394..5ed15c24b9c 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.3 +lastReleaseVersion: 0.3.4 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index e44f8ef80d9..297b6ce7ff9 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.3.4-dev +version: 0.3.4 groups: - go - queries diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 696c3097fac..47c2cc4289d 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.4.4 + +### New Features + +* The new `string Compilation.getInfo(string)` provides access to some information about compilations. +* Kotlin support is now in beta. This means that Java analyses will also include Kotlin code by default. Kotlin support can be disabled by setting `CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN` to `true` in the environment. + +### Minor Analysis Improvements + + * The ReDoS libraries in `semmle.code.java.security.regexp` has been moved to a shared pack inside the `shared/` folder, and the previous location has been deprecated. +* Added data flow summaries for tainted Android intents sent to activities via `Activity.startActivities`. + ## 0.4.3 No user-facing changes. diff --git a/java/ql/lib/change-notes/2022-10-19-android-startactivities-summaries.md b/java/ql/lib/change-notes/2022-10-19-android-startactivities-summaries.md deleted file mode 100644 index 4716fb2ac41..00000000000 --- a/java/ql/lib/change-notes/2022-10-19-android-startactivities-summaries.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added data flow summaries for tainted Android intents sent to activities via `Activity.startActivities`. \ No newline at end of file diff --git a/java/ql/lib/change-notes/2022-10-31-shared-redos-pack.md b/java/ql/lib/change-notes/2022-10-31-shared-redos-pack.md deleted file mode 100644 index 405ddd1108c..00000000000 --- a/java/ql/lib/change-notes/2022-10-31-shared-redos-pack.md +++ /dev/null @@ -1,4 +0,0 @@ ---- - category: minorAnalysis ---- - * The ReDoS libraries in `semmle.code.java.security.regexp` has been moved to a shared pack inside the `shared/` folder, and the previous location has been deprecated. \ No newline at end of file diff --git a/java/ql/lib/change-notes/2022-11-10-getInfo.md b/java/ql/lib/change-notes/2022-11-10-getInfo.md deleted file mode 100644 index 7a113ca3459..00000000000 --- a/java/ql/lib/change-notes/2022-11-10-getInfo.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* The new `string Compilation.getInfo(string)` provides access to some information about compilations. diff --git a/java/ql/lib/change-notes/2022-11-10-kotlin-default.md b/java/ql/lib/change-notes/2022-11-10-kotlin-default.md deleted file mode 100644 index d411c58173c..00000000000 --- a/java/ql/lib/change-notes/2022-11-10-kotlin-default.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Kotlin support is now in beta. This means that Java analyses will also include Kotlin code by default. Kotlin support can be disabled by setting `CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN` to `true` in the environment. diff --git a/java/ql/lib/change-notes/released/0.4.4.md b/java/ql/lib/change-notes/released/0.4.4.md new file mode 100644 index 00000000000..09858b4465d --- /dev/null +++ b/java/ql/lib/change-notes/released/0.4.4.md @@ -0,0 +1,11 @@ +## 0.4.4 + +### New Features + +* The new `string Compilation.getInfo(string)` provides access to some information about compilations. +* Kotlin support is now in beta. This means that Java analyses will also include Kotlin code by default. Kotlin support can be disabled by setting `CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN` to `true` in the environment. + +### Minor Analysis Improvements + + * The ReDoS libraries in `semmle.code.java.security.regexp` has been moved to a shared pack inside the `shared/` folder, and the previous location has been deprecated. +* Added data flow summaries for tainted Android intents sent to activities via `Activity.startActivities`. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 1ec9c4ea5d9..e9b57993a01 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.3 +lastReleaseVersion: 0.4.4 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 4b103c629a2..65e160f8720 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.4.4-dev +version: 0.4.4 groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 61b4170ca74..78c032e50b4 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.4.4 + +### New Queries + +* The query `java/insufficient-key-size` has been promoted from experimental to the main query pack. Its results will now appear by default. This query was originally [submitted as an experimental query by @luchua-bc](https://github.com/github/codeql/pull/4926). +* Added a new query, `java/android/sensitive-keyboard-cache`, to detect instances of sensitive information possibly being saved to the keyboard cache. + ## 0.4.3 No user-facing changes. diff --git a/java/ql/src/change-notes/2022-10-07-sensitive-keyboard-cache.md b/java/ql/src/change-notes/2022-10-07-sensitive-keyboard-cache.md deleted file mode 100644 index 21a1652cc93..00000000000 --- a/java/ql/src/change-notes/2022-10-07-sensitive-keyboard-cache.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: newQuery ---- -* Added a new query, `java/android/sensitive-keyboard-cache`, to detect instances of sensitive information possibly being saved to the keyboard cache. \ No newline at end of file diff --git a/java/ql/src/change-notes/2022-10-19-insufficient-key-size.md b/java/ql/src/change-notes/released/0.4.4.md similarity index 59% rename from java/ql/src/change-notes/2022-10-19-insufficient-key-size.md rename to java/ql/src/change-notes/released/0.4.4.md index e117b5b5941..6cf1320bbd1 100644 --- a/java/ql/src/change-notes/2022-10-19-insufficient-key-size.md +++ b/java/ql/src/change-notes/released/0.4.4.md @@ -1,4 +1,6 @@ ---- -category: newQuery ---- +## 0.4.4 + +### New Queries + * The query `java/insufficient-key-size` has been promoted from experimental to the main query pack. Its results will now appear by default. This query was originally [submitted as an experimental query by @luchua-bc](https://github.com/github/codeql/pull/4926). +* Added a new query, `java/android/sensitive-keyboard-cache`, to detect instances of sensitive information possibly being saved to the keyboard cache. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index 1ec9c4ea5d9..e9b57993a01 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.3 +lastReleaseVersion: 0.4.4 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 87267893413..b15d45f78f9 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.4.4-dev +version: 0.4.4 groups: - java - queries diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index ac17e9e9f27..7bf9f7f1db0 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.3.4 + +### Major Analysis Improvements + +* Added support for TypeScript 4.9. + ## 0.3.3 No user-facing changes. diff --git a/javascript/ql/lib/change-notes/2022-11-15-typescript-4-9.md b/javascript/ql/lib/change-notes/2022-11-15-typescript-4-9.md deleted file mode 100644 index 723f0a5c65f..00000000000 --- a/javascript/ql/lib/change-notes/2022-11-15-typescript-4-9.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: majorAnalysis ---- -* Added support for TypeScript 4.9. diff --git a/javascript/ql/lib/change-notes/released/0.3.4.md b/javascript/ql/lib/change-notes/released/0.3.4.md new file mode 100644 index 00000000000..04b51176020 --- /dev/null +++ b/javascript/ql/lib/change-notes/released/0.3.4.md @@ -0,0 +1,5 @@ +## 0.3.4 + +### Major Analysis Improvements + +* Added support for TypeScript 4.9. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index 9da182d3394..5ed15c24b9c 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.3 +lastReleaseVersion: 0.3.4 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 0a3a773e368..8e1f29f47e0 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.3.4-dev +version: 0.3.4 groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index bdd74c9a701..0783d222cb8 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,16 @@ +## 0.4.4 + +### Minor Analysis Improvements + +* Added support for @hapi/glue and Hapi plugins to the frameworks/Hapi.qll library. + +### Bug Fixes + +* Fixed a bug that would cause the extractor to crash when an `import` type is used in + the `extends` clause of an `interface`. +* Fixed an issue with multi-line strings in YAML files being associated with an invalid location, + causing alerts related to such strings to appear at the top of the YAML file. + ## 0.4.3 ### New Queries diff --git a/javascript/ql/src/change-notes/2022-11-08-hapi-glue.md b/javascript/ql/src/change-notes/2022-11-08-hapi-glue.md deleted file mode 100644 index 18816a2af13..00000000000 --- a/javascript/ql/src/change-notes/2022-11-08-hapi-glue.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added support for @hapi/glue and Hapi plugins to the frameworks/Hapi.qll library. diff --git a/javascript/ql/src/change-notes/2022-11-08-yaml-locations.md b/javascript/ql/src/change-notes/2022-11-08-yaml-locations.md deleted file mode 100644 index 68664780beb..00000000000 --- a/javascript/ql/src/change-notes/2022-11-08-yaml-locations.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: fix ---- -* Fixed an issue with multi-line strings in YAML files being associated with an invalid location, - causing alerts related to such strings to appear at the top of the YAML file. diff --git a/javascript/ql/src/change-notes/2022-11-14-dynamic-import-type-expr.md b/javascript/ql/src/change-notes/2022-11-14-dynamic-import-type-expr.md deleted file mode 100644 index 5f975516620..00000000000 --- a/javascript/ql/src/change-notes/2022-11-14-dynamic-import-type-expr.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: fix ---- -* Fixed a bug that would cause the extractor to crash when an `import` type is used in - the `extends` clause of an `interface`. diff --git a/javascript/ql/src/change-notes/released/0.4.4.md b/javascript/ql/src/change-notes/released/0.4.4.md new file mode 100644 index 00000000000..e423d671d22 --- /dev/null +++ b/javascript/ql/src/change-notes/released/0.4.4.md @@ -0,0 +1,12 @@ +## 0.4.4 + +### Minor Analysis Improvements + +* Added support for @hapi/glue and Hapi plugins to the frameworks/Hapi.qll library. + +### Bug Fixes + +* Fixed a bug that would cause the extractor to crash when an `import` type is used in + the `extends` clause of an `interface`. +* Fixed an issue with multi-line strings in YAML files being associated with an invalid location, + causing alerts related to such strings to appear at the top of the YAML file. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index 1ec9c4ea5d9..e9b57993a01 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.3 +lastReleaseVersion: 0.4.4 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 0d9eb306ee9..ba9e83a24cd 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.4.4-dev +version: 0.4.4 groups: - javascript - queries diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md index e3d9cec6f66..9ee41acc1ec 100644 --- a/misc/suite-helpers/CHANGELOG.md +++ b/misc/suite-helpers/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.4 + +No user-facing changes. + ## 0.3.3 No user-facing changes. diff --git a/misc/suite-helpers/change-notes/released/0.3.4.md b/misc/suite-helpers/change-notes/released/0.3.4.md new file mode 100644 index 00000000000..5fae94b07c9 --- /dev/null +++ b/misc/suite-helpers/change-notes/released/0.3.4.md @@ -0,0 +1,3 @@ +## 0.3.4 + +No user-facing changes. diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml index 9da182d3394..5ed15c24b9c 100644 --- a/misc/suite-helpers/codeql-pack.release.yml +++ b/misc/suite-helpers/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.3 +lastReleaseVersion: 0.3.4 diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index 6a377895b2a..24d2ef3172f 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,3 +1,3 @@ name: codeql/suite-helpers -version: 0.3.4-dev +version: 0.3.4 groups: shared diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index ee84607f683..88107c85b2e 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.6.4 + +### Minor Analysis Improvements + + * The ReDoS libraries in `semmle.code.python.security.regexp` has been moved to a shared pack inside the `shared/` folder, and the previous location has been deprecated. + ## 0.6.3 No user-facing changes. diff --git a/python/ql/lib/change-notes/2022-10-31-shared-redos-pack.md b/python/ql/lib/change-notes/released/0.6.4.md similarity index 59% rename from python/ql/lib/change-notes/2022-10-31-shared-redos-pack.md rename to python/ql/lib/change-notes/released/0.6.4.md index 44212066527..75f233118a7 100644 --- a/python/ql/lib/change-notes/2022-10-31-shared-redos-pack.md +++ b/python/ql/lib/change-notes/released/0.6.4.md @@ -1,4 +1,5 @@ ---- - category: minorAnalysis ---- - * The ReDoS libraries in `semmle.code.python.security.regexp` has been moved to a shared pack inside the `shared/` folder, and the previous location has been deprecated. \ No newline at end of file +## 0.6.4 + +### Minor Analysis Improvements + + * The ReDoS libraries in `semmle.code.python.security.regexp` has been moved to a shared pack inside the `shared/` folder, and the previous location has been deprecated. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index b7dafe32c5d..ced8cf94614 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.3 +lastReleaseVersion: 0.6.4 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index cf9d72aa9d2..ad7d4faa837 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.6.4-dev +version: 0.6.4 groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index 9e30f0aba2f..8c5b1bbc2ed 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.4 + +No user-facing changes. + ## 0.5.3 No user-facing changes. diff --git a/python/ql/src/change-notes/released/0.5.4.md b/python/ql/src/change-notes/released/0.5.4.md new file mode 100644 index 00000000000..1686ab4354d --- /dev/null +++ b/python/ql/src/change-notes/released/0.5.4.md @@ -0,0 +1,3 @@ +## 0.5.4 + +No user-facing changes. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index 2164e038a5d..cd3f72e2513 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.5.3 +lastReleaseVersion: 0.5.4 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index c5f06d5b464..6e3ab19be4b 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.5.4-dev +version: 0.5.4 groups: - python - queries diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index c92874cdbb7..7d0ff13d907 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,3 +1,17 @@ +## 0.4.4 + +### Minor Analysis Improvements + +* Data flow through the `ActiveSupport` extension `Enumerable#index_by` is now modeled. +* The `codeql.ruby.Concepts` library now has a `SqlConstruction` class, in addition to the existing `SqlExecution` class. +* Calls to `Arel.sql` are now modeled as instances of the new `SqlConstruction` concept. +* Arguments to RPC endpoints (public methods) on subclasses of `ActionCable::Channel::Base` are now recognized as sources of remote user input. +* Taint flow through the `ActiveSupport` extensions `Hash#reverse_merge` and `Hash:reverse_merge!`, and their aliases, is now modeled more generally, where previously it was only modeled in the context of `ActionController` parameters. +* Calls to `logger` in `ActiveSupport` actions are now recognised as logger instances. +* Calls to `send_data` in `ActiveSupport` actions are recognised as HTTP responses. +* Calls to `body_stream` in `ActiveSupport` actions are recognised as HTTP request accesses. +* The `ActiveSupport` extensions `Object#try` and `Object#try!` are now recognised as code executions. + ## 0.4.3 ### Minor Analysis Improvements diff --git a/ruby/ql/lib/change-notes/2022-10-28-try-code-execution.md b/ruby/ql/lib/change-notes/2022-10-28-try-code-execution.md deleted file mode 100644 index af5b1cb59e4..00000000000 --- a/ruby/ql/lib/change-notes/2022-10-28-try-code-execution.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The `ActiveSupport` extensions `Object#try` and `Object#try!` are now recognised as code executions. diff --git a/ruby/ql/lib/change-notes/2022-11-01-actioncontroller-logger.md b/ruby/ql/lib/change-notes/2022-11-01-actioncontroller-logger.md deleted file mode 100644 index 367665ac61a..00000000000 --- a/ruby/ql/lib/change-notes/2022-11-01-actioncontroller-logger.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: minorAnalysis ---- -* Calls to `logger` in `ActiveSupport` actions are now recognised as logger instances. -* Calls to `send_data` in `ActiveSupport` actions are recognised as HTTP responses. -* Calls to `body_stream` in `ActiveSupport` actions are recognised as HTTP request accesses. diff --git a/ruby/ql/lib/change-notes/2022-11-08-activesupport-hash-extensions.md b/ruby/ql/lib/change-notes/2022-11-08-activesupport-hash-extensions.md deleted file mode 100644 index e979c49ce0a..00000000000 --- a/ruby/ql/lib/change-notes/2022-11-08-activesupport-hash-extensions.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Taint flow through the `ActiveSupport` extensions `Hash#reverse_merge` and `Hash:reverse_merge!`, and their aliases, is now modeled more generally, where previously it was only modeled in the context of `ActionController` parameters. diff --git a/ruby/ql/lib/change-notes/2022-11-09-actioncable-channels.md b/ruby/ql/lib/change-notes/2022-11-09-actioncable-channels.md deleted file mode 100644 index 3248fc194e0..00000000000 --- a/ruby/ql/lib/change-notes/2022-11-09-actioncable-channels.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Arguments to RPC endpoints (public methods) on subclasses of `ActionCable::Channel::Base` are now recognized as sources of remote user input. diff --git a/ruby/ql/lib/change-notes/2022-11-10-arel-sql.md b/ruby/ql/lib/change-notes/2022-11-10-arel-sql.md deleted file mode 100644 index e803d0e0895..00000000000 --- a/ruby/ql/lib/change-notes/2022-11-10-arel-sql.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- -* The `codeql.ruby.Concepts` library now has a `SqlConstruction` class, in addition to the existing `SqlExecution` class. -* Calls to `Arel.sql` are now modeled as instances of the new `SqlConstruction` concept. diff --git a/ruby/ql/lib/change-notes/2022-11-14-activesupport-enumerable-index-by.md b/ruby/ql/lib/change-notes/2022-11-14-activesupport-enumerable-index-by.md deleted file mode 100644 index 812c292dd94..00000000000 --- a/ruby/ql/lib/change-notes/2022-11-14-activesupport-enumerable-index-by.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Data flow through the `ActiveSupport` extension `Enumerable#index_by` is now modeled. diff --git a/ruby/ql/lib/change-notes/released/0.4.4.md b/ruby/ql/lib/change-notes/released/0.4.4.md new file mode 100644 index 00000000000..6147687886b --- /dev/null +++ b/ruby/ql/lib/change-notes/released/0.4.4.md @@ -0,0 +1,13 @@ +## 0.4.4 + +### Minor Analysis Improvements + +* Data flow through the `ActiveSupport` extension `Enumerable#index_by` is now modeled. +* The `codeql.ruby.Concepts` library now has a `SqlConstruction` class, in addition to the existing `SqlExecution` class. +* Calls to `Arel.sql` are now modeled as instances of the new `SqlConstruction` concept. +* Arguments to RPC endpoints (public methods) on subclasses of `ActionCable::Channel::Base` are now recognized as sources of remote user input. +* Taint flow through the `ActiveSupport` extensions `Hash#reverse_merge` and `Hash:reverse_merge!`, and their aliases, is now modeled more generally, where previously it was only modeled in the context of `ActionController` parameters. +* Calls to `logger` in `ActiveSupport` actions are now recognised as logger instances. +* Calls to `send_data` in `ActiveSupport` actions are recognised as HTTP responses. +* Calls to `body_stream` in `ActiveSupport` actions are recognised as HTTP request accesses. +* The `ActiveSupport` extensions `Object#try` and `Object#try!` are now recognised as code executions. diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index 1ec9c4ea5d9..e9b57993a01 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.3 +lastReleaseVersion: 0.4.4 diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 016f75260eb..cf26086c71c 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.4.4-dev +version: 0.4.4 groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index 1e45bb15389..ea095374247 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,13 @@ +## 0.4.4 + +### New Queries + +* Added a new query, `rb/shell-command-constructed-from-input`, to detect libraries that unsafely construct shell commands from their inputs. + +### Minor Analysis Improvements + +* The `rb/sql-injection` query now considers consider SQL constructions, such as calls to `Arel.sql`, as sinks. + ## 0.4.3 ### Minor Analysis Improvements diff --git a/ruby/ql/src/change-notes/2022-10-10-unsafe-shell-command-construction.md b/ruby/ql/src/change-notes/2022-10-10-unsafe-shell-command-construction.md deleted file mode 100644 index fba6a9304cf..00000000000 --- a/ruby/ql/src/change-notes/2022-10-10-unsafe-shell-command-construction.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: newQuery ---- -* Added a new query, `rb/shell-command-constructed-from-input`, to detect libraries that unsafely construct shell commands from their inputs. diff --git a/ruby/ql/src/change-notes/2022-11-10-arel-sql.md b/ruby/ql/src/change-notes/2022-11-10-arel-sql.md deleted file mode 100644 index 918e46a9d9b..00000000000 --- a/ruby/ql/src/change-notes/2022-11-10-arel-sql.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The `rb/sql-injection` query now considers consider SQL constructions, such as calls to `Arel.sql`, as sinks. diff --git a/ruby/ql/src/change-notes/released/0.4.4.md b/ruby/ql/src/change-notes/released/0.4.4.md new file mode 100644 index 00000000000..59be09518f7 --- /dev/null +++ b/ruby/ql/src/change-notes/released/0.4.4.md @@ -0,0 +1,9 @@ +## 0.4.4 + +### New Queries + +* Added a new query, `rb/shell-command-constructed-from-input`, to detect libraries that unsafely construct shell commands from their inputs. + +### Minor Analysis Improvements + +* The `rb/sql-injection` query now considers consider SQL constructions, such as calls to `Arel.sql`, as sinks. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index 1ec9c4ea5d9..e9b57993a01 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.3 +lastReleaseVersion: 0.4.4 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 93c261cc264..5d1a123e58a 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.4.4-dev +version: 0.4.4 groups: - ruby - queries diff --git a/shared/regex/change-notes/2022-09-26-initial-version.md b/shared/regex/CHANGELOG.md similarity index 76% rename from shared/regex/change-notes/2022-09-26-initial-version.md rename to shared/regex/CHANGELOG.md index e4d6e0490c2..68156d29a72 100644 --- a/shared/regex/change-notes/2022-09-26-initial-version.md +++ b/shared/regex/CHANGELOG.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 0.0.1 + +### Minor Analysis Improvements + * Initial release. Extracted common regex related code, including the ReDoS analysis, into a library pack to share code between languages. diff --git a/shared/regex/change-notes/released/0.0.1.md b/shared/regex/change-notes/released/0.0.1.md new file mode 100644 index 00000000000..68156d29a72 --- /dev/null +++ b/shared/regex/change-notes/released/0.0.1.md @@ -0,0 +1,5 @@ +## 0.0.1 + +### Minor Analysis Improvements + +* Initial release. Extracted common regex related code, including the ReDoS analysis, into a library pack to share code between languages. diff --git a/shared/regex/codeql-pack.release.yml b/shared/regex/codeql-pack.release.yml new file mode 100644 index 00000000000..c6933410b71 --- /dev/null +++ b/shared/regex/codeql-pack.release.yml @@ -0,0 +1,2 @@ +--- +lastReleaseVersion: 0.0.1 diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 4b25672b6c5..c82cff186d0 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 0.0.1-dev +version: 0.0.1 groups: shared library: true dependencies: diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md index d26b43c4358..76932ab7a0f 100644 --- a/shared/ssa/CHANGELOG.md +++ b/shared/ssa/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.5 + +No user-facing changes. + ## 0.0.4 No user-facing changes. diff --git a/shared/ssa/change-notes/released/0.0.5.md b/shared/ssa/change-notes/released/0.0.5.md new file mode 100644 index 00000000000..766ec2723b5 --- /dev/null +++ b/shared/ssa/change-notes/released/0.0.5.md @@ -0,0 +1,3 @@ +## 0.0.5 + +No user-facing changes. diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml index ec411a674bc..bb45a1ab018 100644 --- a/shared/ssa/codeql-pack.release.yml +++ b/shared/ssa/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.4 +lastReleaseVersion: 0.0.5 diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 80e454bf99f..7fb2ed664cb 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/ssa -version: 0.0.5-dev +version: 0.0.5 groups: shared library: true diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md index 6741585b960..89e542713a7 100644 --- a/shared/typos/CHANGELOG.md +++ b/shared/typos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.5 + +No user-facing changes. + ## 0.0.4 No user-facing changes. diff --git a/shared/typos/change-notes/released/0.0.5.md b/shared/typos/change-notes/released/0.0.5.md new file mode 100644 index 00000000000..766ec2723b5 --- /dev/null +++ b/shared/typos/change-notes/released/0.0.5.md @@ -0,0 +1,3 @@ +## 0.0.5 + +No user-facing changes. diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml index ec411a674bc..bb45a1ab018 100644 --- a/shared/typos/codeql-pack.release.yml +++ b/shared/typos/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.4 +lastReleaseVersion: 0.0.5 diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index 1bada6ef1ff..39df1ba73d5 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/typos -version: 0.0.5-dev +version: 0.0.5 groups: shared library: true From 7c74350d5e50696f1fcb4e05ada34125e04d1ead Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 17 Nov 2022 16:51:21 +0000 Subject: [PATCH 360/796] Copyedit Java changelog --- java/ql/lib/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 47c2cc4289d..f199a1a7589 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -2,8 +2,8 @@ ### New Features -* The new `string Compilation.getInfo(string)` provides access to some information about compilations. * Kotlin support is now in beta. This means that Java analyses will also include Kotlin code by default. Kotlin support can be disabled by setting `CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN` to `true` in the environment. +* The new `string Compilation.getInfo(string)` predicate provides access to some information about compilations. ### Minor Analysis Improvements From 2bd151ba9c3ed594d77e5dfc631094a2a1c9c12a Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 17 Nov 2022 16:54:33 +0000 Subject: [PATCH 361/796] Copyedit Java changelog --- java/ql/lib/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index f199a1a7589..32632d9ea68 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -7,7 +7,7 @@ ### Minor Analysis Improvements - * The ReDoS libraries in `semmle.code.java.security.regexp` has been moved to a shared pack inside the `shared/` folder, and the previous location has been deprecated. +* The ReDoS libraries in `semmle.code.java.security.regexp` has been moved to a shared pack inside the `shared/` folder, and the previous location has been deprecated. * Added data flow summaries for tainted Android intents sent to activities via `Activity.startActivities`. ## 0.4.3 From e13eb79f5b95f326f11d112cec34fc7a4bc0d7ca Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 17 Nov 2022 16:55:26 +0000 Subject: [PATCH 362/796] Java: edit 0.4.4 release notes to match the changelog --- java/ql/lib/change-notes/released/0.4.4.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/change-notes/released/0.4.4.md b/java/ql/lib/change-notes/released/0.4.4.md index 09858b4465d..ca76975d283 100644 --- a/java/ql/lib/change-notes/released/0.4.4.md +++ b/java/ql/lib/change-notes/released/0.4.4.md @@ -2,10 +2,10 @@ ### New Features -* The new `string Compilation.getInfo(string)` provides access to some information about compilations. * Kotlin support is now in beta. This means that Java analyses will also include Kotlin code by default. Kotlin support can be disabled by setting `CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN` to `true` in the environment. +* The new `string Compilation.getInfo(string)` predicate provides access to some information about compilations. ### Minor Analysis Improvements - * The ReDoS libraries in `semmle.code.java.security.regexp` has been moved to a shared pack inside the `shared/` folder, and the previous location has been deprecated. +* The ReDoS libraries in `semmle.code.java.security.regexp` has been moved to a shared pack inside the `shared/` folder, and the previous location has been deprecated. * Added data flow summaries for tainted Android intents sent to activities via `Activity.startActivities`. From 47f07d83b8f1efbcc281bcbd63d063231bb3d024 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 17 Nov 2022 16:56:39 +0000 Subject: [PATCH 363/796] Copyedit Java src qlpack changelog --- java/ql/src/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 78c032e50b4..8bbe06cf3fe 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -3,7 +3,7 @@ ### New Queries * The query `java/insufficient-key-size` has been promoted from experimental to the main query pack. Its results will now appear by default. This query was originally [submitted as an experimental query by @luchua-bc](https://github.com/github/codeql/pull/4926). -* Added a new query, `java/android/sensitive-keyboard-cache`, to detect instances of sensitive information possibly being saved to the keyboard cache. +* Added a new query, `java/android/sensitive-keyboard-cache`, to detect instances of sensitive information possibly being saved to the Android keyboard cache. ## 0.4.3 From d45c35a02e54213fdf92e175e20112e4e515b406 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 17 Nov 2022 16:57:08 +0000 Subject: [PATCH 364/796] Copyedit the Java src qlpack 0.4.4 release nnotes --- java/ql/src/change-notes/released/0.4.4.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/change-notes/released/0.4.4.md b/java/ql/src/change-notes/released/0.4.4.md index 6cf1320bbd1..849452aa9c0 100644 --- a/java/ql/src/change-notes/released/0.4.4.md +++ b/java/ql/src/change-notes/released/0.4.4.md @@ -3,4 +3,4 @@ ### New Queries * The query `java/insufficient-key-size` has been promoted from experimental to the main query pack. Its results will now appear by default. This query was originally [submitted as an experimental query by @luchua-bc](https://github.com/github/codeql/pull/4926). -* Added a new query, `java/android/sensitive-keyboard-cache`, to detect instances of sensitive information possibly being saved to the keyboard cache. +* Added a new query, `java/android/sensitive-keyboard-cache`, to detect instances of sensitive information possibly being saved to the Android keyboard cache. From 80b2f0d3cd65b74fcfce6057ed44b185ff9c949a Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 17 Nov 2022 17:01:43 +0000 Subject: [PATCH 365/796] Coopyedit Javascript changelog --- javascript/ql/src/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index 0783d222cb8..fe221bce7d3 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -2,7 +2,7 @@ ### Minor Analysis Improvements -* Added support for @hapi/glue and Hapi plugins to the frameworks/Hapi.qll library. +* Added support for `@hapi/glue` and Hapi plugins to the `frameworks/Hapi.qll` library. ### Bug Fixes From 0219c2b02b65cef13d829da295c868156037bc6b Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 17 Nov 2022 17:02:01 +0000 Subject: [PATCH 366/796] Copyedit Javascript changelog --- javascript/ql/src/change-notes/released/0.4.4.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/src/change-notes/released/0.4.4.md b/javascript/ql/src/change-notes/released/0.4.4.md index e423d671d22..90a5df9d9df 100644 --- a/javascript/ql/src/change-notes/released/0.4.4.md +++ b/javascript/ql/src/change-notes/released/0.4.4.md @@ -2,7 +2,7 @@ ### Minor Analysis Improvements -* Added support for @hapi/glue and Hapi plugins to the frameworks/Hapi.qll library. +* Added support for `@hapi/glue` and Hapi plugins to the `frameworks/Hapi.qll` library. ### Bug Fixes From 63fcbb5969c311d31b442014a695d4ef95f51f95 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 17 Nov 2022 17:02:55 +0000 Subject: [PATCH 367/796] Copyedit Python release notes --- python/ql/lib/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index 88107c85b2e..fe35f8daf38 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -2,7 +2,7 @@ ### Minor Analysis Improvements - * The ReDoS libraries in `semmle.code.python.security.regexp` has been moved to a shared pack inside the `shared/` folder, and the previous location has been deprecated. + * The ReDoS libraries in `semmle.code.python.security.regexp` have been moved to a shared pack inside the `shared/` folder, and the previous location has been deprecated. ## 0.6.3 From 0deb2d4c5f4242c9b41f6ea239bfc1cd10175348 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 17 Nov 2022 17:03:09 +0000 Subject: [PATCH 368/796] Copyedit Python release notes --- python/ql/lib/change-notes/released/0.6.4.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/change-notes/released/0.6.4.md b/python/ql/lib/change-notes/released/0.6.4.md index 75f233118a7..9f12960721c 100644 --- a/python/ql/lib/change-notes/released/0.6.4.md +++ b/python/ql/lib/change-notes/released/0.6.4.md @@ -2,4 +2,4 @@ ### Minor Analysis Improvements - * The ReDoS libraries in `semmle.code.python.security.regexp` has been moved to a shared pack inside the `shared/` folder, and the previous location has been deprecated. + * The ReDoS libraries in `semmle.code.python.security.regexp` have been moved to a shared pack inside the `shared/` folder, and the previous location has been deprecated. From 8b332778e3e75ac182dfe99adb1734b771a1cacf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Thu, 17 Nov 2022 18:08:06 +0100 Subject: [PATCH 369/796] Swift: update `@security-severity` --- swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql index 41065a9d47d..cd96709b6f6 100644 --- a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql +++ b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql @@ -3,7 +3,7 @@ * @description Evaluating JavaScript code containing a substring from a remote source may lead to remote code execution. * @kind path-problem * @problem.severity warning - * @security-severity 6.1 + * @security-severity 9.3 * @precision high * @id swift/unsafe-js-eval * @tags security From cf34dbd27632070958f9abb9b7f167886b5c7c9b Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 16 Nov 2022 12:33:32 +0000 Subject: [PATCH 370/796] Kotlin: format string literals like the Java annotaton extractor Java's regular strings are formatted as they appear in source, but we don't easily have this information available in Kotlin. During annotation extraction however it guesses a source rendering because the source is not necessarily available. By formatting to match the annotation extractor, we prepare to ensure consistency with a Java database when extracting annotations as seen by Kotlin. --- .../src/main/kotlin/KotlinFileExtractor.kt | 19 +- .../PrintAst.expected | 26 +- .../kotlin_java_static_fields/test.expected | 18 +- .../kotlin/nested_generic_types/test.expected | 18 +- .../kotlin/custom_plugin/PrintAst.expected | 2 +- .../kotlin/custom_plugin/staticinit.expected | 2 +- .../library-tests/classes/PrintAst.expected | 6 +- .../collection-literals/PrintAst.expected | 4 +- .../controlflow/basic/bbStmts.expected | 4 +- .../controlflow/basic/getASuccessor.expected | 8 +- .../data-classes/PrintAst.expected | 10 +- .../dataflow/foreach/test.expected | 8 +- .../library-tests/exprs/PrintAst.expected | 40 +-- .../kotlin/library-tests/exprs/binop.expected | 2 +- .../kotlin/library-tests/exprs/exprs.expected | 40 +-- .../exprs_typeaccess/PrintAst.expected | 2 +- .../extensions/methodaccesses.expected | 22 +- .../extensions/parameters.expected | 22 +- .../generic-inner-classes/test.expected | 8 +- .../library-tests/generics/PrintAst.expected | 8 +- .../java-map-methods/PrintAst.expected | 4 +- .../jvmoverloads-annotation/PrintAst.expected | 10 +- .../jvmstatic-annotation/PrintAst.expected | 16 +- .../library-tests/lateinit/PrintAst.expected | 2 +- .../library-tests/literals/literals.expected | 6 +- .../library-tests/methods/exprs.expected | 16 +- .../operator-overloads/PrintAst.expected | 8 +- .../parameter-defaults/PrintAst.expected | 238 +++++++++--------- .../reflection/PrintAst.expected | 14 +- .../library-tests/stmts/PrintAst.expected | 2 +- .../kotlin/library-tests/stmts/exprs.expected | 2 +- .../kotlin/library-tests/trap/diags.expected | 14 +- .../kotlin/library-tests/trap/literals.ql | 2 +- .../library-tests/trap/long_comments.kt | 4 +- .../kotlin/library-tests/vararg/args.expected | 12 +- 35 files changed, 320 insertions(+), 299 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 511b97fd4d0..489d1b85743 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -3395,6 +3395,23 @@ open class KotlinFileExtractor( extractExprContext(it, locId, callable, enclosingStmt) } + private fun escapeCharForQuotedLiteral(c: Char) = + when (c) { + '\r' -> "\\r" + '\n' -> "\\n" + '\t' -> "\\t" + '\\' -> "\\\\" + '"' -> "\\\"" + else -> c.toString() + } + + // Render a string literal as it might occur in Kotlin source. Note this is a reasonable guess; the real source + // could use other escape sequences to describe the same String. Importantly, this is the same guess the Java + // extractor makes regarding string literals occurring within annotations, which we need to coincide with to ensure + // database consistency. + private fun toQuotedLiteral(s: String) = + s.toCharArray().joinToString(separator = "", prefix = "\"", postfix = "\"") { c -> escapeCharForQuotedLiteral(c) } + private fun extractExpression(e: IrExpression, callable: Label, parent: StmtExprParent) { with("expression", e) { when(e) { @@ -3602,7 +3619,7 @@ open class KotlinFileExtractor( tw.writeExprs_stringliteral(id, type.javaResult.id, exprParent.parent, exprParent.idx) tw.writeExprsKotlinType(id, type.kotlinResult.id) extractExprContext(id, locId, callable, exprParent.enclosingStmt) - tw.writeNamestrings(v.toString(), v.toString(), id) + tw.writeNamestrings(toQuotedLiteral(v.toString()), v.toString(), id) } v == null -> { extractNull(e.type, tw.getLocation(e), exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt) diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/PrintAst.expected b/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/PrintAst.expected index ae23298c033..4f056c3c4fb 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/PrintAst.expected +++ b/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/PrintAst.expected @@ -180,15 +180,15 @@ app/src/main/kotlin/testProject/App.kt: # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... # 0| 0: [StringTemplateExpr] "..." -# 0| 0: [StringLiteral] Project( -# 0| 1: [StringLiteral] name= +# 0| 0: [StringLiteral] "Project(" +# 0| 1: [StringLiteral] "name=" # 0| 2: [VarAccess] this.name # 0| -1: [ThisAccess] this -# 0| 3: [StringLiteral] , -# 0| 4: [StringLiteral] language= +# 0| 3: [StringLiteral] ", " +# 0| 4: [StringLiteral] "language=" # 0| 5: [VarAccess] this.language # 0| -1: [ThisAccess] this -# 0| 6: [StringLiteral] ) +# 0| 6: [StringLiteral] ")" # 0| 9: [Method] write$Self # 0| 3: [TypeAccess] Unit #-----| 4: (Parameters) @@ -405,19 +405,19 @@ app/src/main/kotlin/testProject/App.kt: # 7| 1: [LocalVariableDeclExpr] tmp0_serialDesc # 7| 0: [ClassInstanceExpr] new PluginGeneratedSerialDescriptor(...) # 7| -3: [TypeAccess] PluginGeneratedSerialDescriptor -# 7| 0: [StringLiteral] testProject.Project +# 7| 0: [StringLiteral] "testProject.Project" # 7| 1: [ThisAccess] $serializer.this # 7| 0: [TypeAccess] $serializer # 7| 2: [IntegerLiteral] 2 # 7| 1: [ExprStmt] ; # 7| 0: [MethodAccess] addElement(...) # 7| -1: [VarAccess] tmp0_serialDesc -# 7| 0: [StringLiteral] name +# 7| 0: [StringLiteral] "name" # 7| 1: [BooleanLiteral] false # 7| 2: [ExprStmt] ; # 7| 0: [MethodAccess] addElement(...) # 7| -1: [VarAccess] tmp0_serialDesc -# 7| 0: [StringLiteral] language +# 7| 0: [StringLiteral] "language" # 7| 1: [BooleanLiteral] false # 7| 3: [ExprStmt] ; # 7| 0: [AssignExpr] ...=... @@ -520,7 +520,7 @@ app/src/main/kotlin/testProject/App.kt: # 14| 0: [VarAccess] X.this.id # 14| -1: [ThisAccess] X.this # 14| 0: [TypeAccess] X -# 16| 1: [StringLiteral] X +# 16| 1: [StringLiteral] "X" # 14| 1: [WhenBranch] ... -> ... # 14| 0: [BooleanLiteral] true # 14| 1: [ExprStmt] ; @@ -556,7 +556,7 @@ app/src/main/kotlin/testProject/App.kt: # 14| 0: [ValueNEExpr] ... (value not-equals) ... # 14| 0: [MethodAccess] getId(...) # 14| -1: [VarAccess] self -# 16| 1: [StringLiteral] X +# 16| 1: [StringLiteral] "X" # 14| 1: [ExprStmt] ; # 14| 0: [MethodAccess] encodeStringElement(...) # 14| -1: [VarAccess] output @@ -720,14 +720,14 @@ app/src/main/kotlin/testProject/App.kt: # 14| 1: [LocalVariableDeclExpr] tmp0_serialDesc # 14| 0: [ClassInstanceExpr] new PluginGeneratedSerialDescriptor(...) # 14| -3: [TypeAccess] PluginGeneratedSerialDescriptor -# 14| 0: [StringLiteral] testProject.X +# 14| 0: [StringLiteral] "testProject.X" # 14| 1: [ThisAccess] $serializer.this # 14| 0: [TypeAccess] $serializer # 14| 2: [IntegerLiteral] 1 # 14| 1: [ExprStmt] ; # 14| 0: [MethodAccess] addElement(...) # 14| -1: [VarAccess] tmp0_serialDesc -# 14| 0: [StringLiteral] id +# 14| 0: [StringLiteral] "id" # 14| 1: [BooleanLiteral] true # 14| 2: [ExprStmt] ; # 14| 0: [AssignExpr] ...=... @@ -764,7 +764,7 @@ app/src/main/kotlin/testProject/App.kt: # 16| 0: [VarAccess] id # 16| 6: [FieldDeclaration] String id; # 16| -1: [TypeAccess] String -# 16| 0: [StringLiteral] X +# 16| 0: [StringLiteral] "X" # 16| 7: [Method] getId # 16| 3: [TypeAccess] String # 16| 5: [BlockStmt] { ... } diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/test.expected b/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/test.expected index 3581a178422..9f16308bdfc 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/test.expected +++ b/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/test.expected @@ -1,26 +1,26 @@ edges | hasFields.kt:5:5:5:34 | constField : String | ReadsFields.java:5:10:5:29 | HasFields.constField | -| hasFields.kt:5:28:5:34 | taint : String | hasFields.kt:5:5:5:34 | constField : String | +| hasFields.kt:5:28:5:34 | "taint" : String | hasFields.kt:5:5:5:34 | constField : String | | hasFields.kt:7:5:7:38 | lateinitField : String | ReadsFields.java:6:10:6:32 | HasFields.lateinitField | | hasFields.kt:7:14:7:38 | : String | hasFields.kt:7:5:7:38 | lateinitField : String | | hasFields.kt:7:14:7:38 | : String | hasFields.kt:7:14:7:38 | : String | | hasFields.kt:9:5:9:50 | jvmFieldAnnotatedField : String | ReadsFields.java:7:10:7:41 | HasFields.jvmFieldAnnotatedField | -| hasFields.kt:9:44:9:50 | taint : String | hasFields.kt:9:5:9:50 | jvmFieldAnnotatedField : String | -| hasFields.kt:14:22:14:26 | taint : String | hasFields.kt:7:14:7:38 | : String | +| hasFields.kt:9:44:9:50 | "taint" : String | hasFields.kt:9:5:9:50 | jvmFieldAnnotatedField : String | +| hasFields.kt:14:22:14:26 | "taint" : String | hasFields.kt:7:14:7:38 | : String | nodes | ReadsFields.java:5:10:5:29 | HasFields.constField | semmle.label | HasFields.constField | | ReadsFields.java:6:10:6:32 | HasFields.lateinitField | semmle.label | HasFields.lateinitField | | ReadsFields.java:7:10:7:41 | HasFields.jvmFieldAnnotatedField | semmle.label | HasFields.jvmFieldAnnotatedField | | hasFields.kt:5:5:5:34 | constField : String | semmle.label | constField : String | -| hasFields.kt:5:28:5:34 | taint : String | semmle.label | taint : String | +| hasFields.kt:5:28:5:34 | "taint" : String | semmle.label | "taint" : String | | hasFields.kt:7:5:7:38 | lateinitField : String | semmle.label | lateinitField : String | | hasFields.kt:7:14:7:38 | : String | semmle.label | : String | | hasFields.kt:7:14:7:38 | : String | semmle.label | : String | | hasFields.kt:9:5:9:50 | jvmFieldAnnotatedField : String | semmle.label | jvmFieldAnnotatedField : String | -| hasFields.kt:9:44:9:50 | taint : String | semmle.label | taint : String | -| hasFields.kt:14:22:14:26 | taint : String | semmle.label | taint : String | +| hasFields.kt:9:44:9:50 | "taint" : String | semmle.label | "taint" : String | +| hasFields.kt:14:22:14:26 | "taint" : String | semmle.label | "taint" : String | subpaths #select -| hasFields.kt:5:28:5:34 | taint : String | hasFields.kt:5:28:5:34 | taint : String | ReadsFields.java:5:10:5:29 | HasFields.constField | flow path | -| hasFields.kt:9:44:9:50 | taint : String | hasFields.kt:9:44:9:50 | taint : String | ReadsFields.java:7:10:7:41 | HasFields.jvmFieldAnnotatedField | flow path | -| hasFields.kt:14:22:14:26 | taint : String | hasFields.kt:14:22:14:26 | taint : String | ReadsFields.java:6:10:6:32 | HasFields.lateinitField | flow path | +| hasFields.kt:5:28:5:34 | "taint" : String | hasFields.kt:5:28:5:34 | "taint" : String | ReadsFields.java:5:10:5:29 | HasFields.constField | flow path | +| hasFields.kt:9:44:9:50 | "taint" : String | hasFields.kt:9:44:9:50 | "taint" : String | ReadsFields.java:7:10:7:41 | HasFields.jvmFieldAnnotatedField | flow path | +| hasFields.kt:14:22:14:26 | "taint" : String | hasFields.kt:14:22:14:26 | "taint" : String | ReadsFields.java:6:10:6:32 | HasFields.lateinitField | flow path | diff --git a/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.expected b/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.expected index 27db355f838..94ec21eca1a 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.expected +++ b/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.expected @@ -76,7 +76,7 @@ callArgs | KotlinUser.kt:10:34:10:65 | new InnerGeneric(...) | KotlinUser.kt:10:14:10:32 | new OuterGeneric(...) | -2 | | KotlinUser.kt:10:34:10:65 | new InnerGeneric(...) | KotlinUser.kt:10:34:10:65 | InnerGeneric | -3 | | KotlinUser.kt:10:34:10:65 | new InnerGeneric(...) | KotlinUser.kt:10:47:10:49 | a | 0 | -| KotlinUser.kt:10:34:10:65 | new InnerGeneric(...) | KotlinUser.kt:10:53:10:63 | hello world | 1 | +| KotlinUser.kt:10:34:10:65 | new InnerGeneric(...) | KotlinUser.kt:10:53:10:63 | "hello world" | 1 | | KotlinUser.kt:11:13:11:31 | new OuterGeneric(...) | KotlinUser.kt:11:13:11:31 | OuterGeneric | -3 | | KotlinUser.kt:11:33:11:49 | new InnerNotGeneric<>(...) | KotlinUser.kt:11:13:11:31 | new OuterGeneric(...) | -2 | | KotlinUser.kt:11:33:11:49 | new InnerNotGeneric<>(...) | KotlinUser.kt:11:33:11:49 | InnerNotGeneric<> | -3 | @@ -88,10 +88,10 @@ callArgs | KotlinUser.kt:13:31:13:52 | new InnerGeneric(...) | KotlinUser.kt:13:31:13:52 | InnerGeneric | -3 | | KotlinUser.kt:14:26:14:63 | new InnerStaticGeneric(...) | KotlinUser.kt:14:26:14:63 | InnerStaticGeneric | -3 | | KotlinUser.kt:14:26:14:63 | new InnerStaticGeneric(...) | KotlinUser.kt:14:45:14:47 | a | 0 | -| KotlinUser.kt:14:26:14:63 | new InnerStaticGeneric(...) | KotlinUser.kt:14:51:14:61 | hello world | 1 | +| KotlinUser.kt:14:26:14:63 | new InnerStaticGeneric(...) | KotlinUser.kt:14:51:14:61 | "hello world" | 1 | | KotlinUser.kt:15:13:15:39 | new OuterManyParams(...) | KotlinUser.kt:15:13:15:39 | OuterManyParams | -3 | | KotlinUser.kt:15:13:15:39 | new OuterManyParams(...) | KotlinUser.kt:15:29:15:29 | 1 | 0 | -| KotlinUser.kt:15:13:15:39 | new OuterManyParams(...) | KotlinUser.kt:15:33:15:37 | hello | 1 | +| KotlinUser.kt:15:13:15:39 | new OuterManyParams(...) | KotlinUser.kt:15:33:15:37 | "hello" | 1 | | KotlinUser.kt:15:41:15:67 | new MiddleManyParams(...) | KotlinUser.kt:15:13:15:39 | new OuterManyParams(...) | -2 | | KotlinUser.kt:15:41:15:67 | new MiddleManyParams(...) | KotlinUser.kt:15:41:15:67 | MiddleManyParams | -3 | | KotlinUser.kt:15:41:15:67 | new MiddleManyParams(...) | KotlinUser.kt:15:58:15:61 | 1.0 | 0 | @@ -103,23 +103,23 @@ callArgs | KotlinUser.kt:15:89:15:99 | shortValue(...) | KotlinUser.kt:15:89:15:89 | 1 | -1 | | KotlinUser.kt:17:19:17:44 | returnsecond(...) | KotlinUser.kt:17:19:17:19 | a | -1 | | KotlinUser.kt:17:19:17:44 | returnsecond(...) | KotlinUser.kt:17:34:17:34 | 0 | 0 | -| KotlinUser.kt:17:19:17:44 | returnsecond(...) | KotlinUser.kt:17:38:17:42 | hello | 1 | +| KotlinUser.kt:17:19:17:44 | returnsecond(...) | KotlinUser.kt:17:38:17:42 | "hello" | 1 | | KotlinUser.kt:18:20:18:50 | returnsecond(...) | KotlinUser.kt:18:20:18:20 | a | -1 | | KotlinUser.kt:18:20:18:50 | returnsecond(...) | KotlinUser.kt:18:20:18:50 | Character | -2 | | KotlinUser.kt:18:20:18:50 | returnsecond(...) | KotlinUser.kt:18:35:18:35 | 0 | 0 | -| KotlinUser.kt:18:20:18:50 | returnsecond(...) | KotlinUser.kt:18:39:18:43 | hello | 1 | +| KotlinUser.kt:18:20:18:50 | returnsecond(...) | KotlinUser.kt:18:39:18:43 | "hello" | 1 | | KotlinUser.kt:18:20:18:50 | returnsecond(...) | KotlinUser.kt:18:47:18:49 | a | 2 | | KotlinUser.kt:19:19:19:31 | identity(...) | KotlinUser.kt:19:19:19:19 | b | -1 | | KotlinUser.kt:19:19:19:31 | identity(...) | KotlinUser.kt:19:30:19:30 | 5 | 0 | | KotlinUser.kt:20:20:20:39 | identity(...) | KotlinUser.kt:20:20:20:21 | b2 | -1 | -| KotlinUser.kt:20:20:20:39 | identity(...) | KotlinUser.kt:20:33:20:37 | hello | 0 | +| KotlinUser.kt:20:20:20:39 | identity(...) | KotlinUser.kt:20:33:20:37 | "hello" | 0 | | KotlinUser.kt:21:19:21:37 | identity(...) | KotlinUser.kt:21:19:21:19 | c | -1 | -| KotlinUser.kt:21:19:21:37 | identity(...) | KotlinUser.kt:21:31:21:35 | world | 0 | +| KotlinUser.kt:21:19:21:37 | identity(...) | KotlinUser.kt:21:31:21:35 | "world" | 0 | | KotlinUser.kt:22:19:22:39 | identity(...) | KotlinUser.kt:22:19:22:19 | d | -1 | -| KotlinUser.kt:22:19:22:39 | identity(...) | KotlinUser.kt:22:31:22:37 | goodbye | 0 | +| KotlinUser.kt:22:19:22:39 | identity(...) | KotlinUser.kt:22:31:22:37 | "goodbye" | 0 | | KotlinUser.kt:23:19:23:71 | returnSixth(...) | KotlinUser.kt:23:19:23:19 | e | -1 | | KotlinUser.kt:23:19:23:71 | returnSixth(...) | KotlinUser.kt:23:33:23:33 | 1 | 0 | -| KotlinUser.kt:23:19:23:71 | returnSixth(...) | KotlinUser.kt:23:37:23:41 | hello | 1 | +| KotlinUser.kt:23:19:23:71 | returnSixth(...) | KotlinUser.kt:23:37:23:41 | "hello" | 1 | | KotlinUser.kt:23:19:23:71 | returnSixth(...) | KotlinUser.kt:23:45:23:48 | 1.0 | 2 | | KotlinUser.kt:23:19:23:71 | returnSixth(...) | KotlinUser.kt:23:51:23:53 | 1.0 | 3 | | KotlinUser.kt:23:19:23:71 | returnSixth(...) | KotlinUser.kt:23:56:23:57 | 1 | 4 | diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected index 51186ef7b15..6921b7541ad 100644 --- a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected +++ b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected @@ -50,7 +50,7 @@ d.kt: # 1| 1: [Class] D # 0| 2: [FieldDeclaration] String bar; # 0| -1: [TypeAccess] String -# 0| 0: [StringLiteral] Foobar +# 0| 0: [StringLiteral] "Foobar" # 1| 3: [Constructor] D # 1| 5: [BlockStmt] { ... } # 1| 0: [SuperConstructorInvocationStmt] super(...) diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/staticinit.expected b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/staticinit.expected index 606bbd3f338..092e8241a3d 100644 --- a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/staticinit.expected +++ b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/staticinit.expected @@ -1 +1 @@ -| d.kt:0:0:0:0 | bar | d.kt:0:0:0:0 | Foobar | +| d.kt:0:0:0:0 | bar | d.kt:0:0:0:0 | "Foobar" | diff --git a/java/ql/test/kotlin/library-tests/classes/PrintAst.expected b/java/ql/test/kotlin/library-tests/classes/PrintAst.expected index 698a4f874c9..6f19fb37fee 100644 --- a/java/ql/test/kotlin/library-tests/classes/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/classes/PrintAst.expected @@ -138,14 +138,14 @@ classes.kt: # 39| 0: [ExprStmt] ; # 39| 0: [MethodAccess] f(...) # 39| -1: [TypeAccess] ClassesKt -# 39| 0: [StringLiteral] init1 +# 39| 0: [StringLiteral] "init1" # 42| 1: [ExprStmt] ; # 42| 0: [KtInitializerAssignExpr] ...=... # 42| 0: [VarAccess] x # 45| 2: [ExprStmt] ; # 45| 0: [MethodAccess] f(...) # 45| -1: [TypeAccess] ClassesKt -# 45| 0: [StringLiteral] init2 +# 45| 0: [StringLiteral] "init2" # 36| 2: [ExprStmt] ; # 36| 0: [MethodAccess] f(...) # 36| -1: [TypeAccess] ClassesKt @@ -1119,7 +1119,7 @@ local_anonymous.kt: # 40| 1: [BlockStmt] { ... } # 42| 0: [LocalVariableDeclStmt] var ...; # 42| 1: [LocalVariableDeclExpr] answer -# 42| 0: [StringLiteral] 42 +# 42| 0: [StringLiteral] "42" # 40| 1: [ExprStmt] ; # 40| 0: [ClassInstanceExpr] new (...) # 40| -3: [TypeAccess] Interface2 diff --git a/java/ql/test/kotlin/library-tests/collection-literals/PrintAst.expected b/java/ql/test/kotlin/library-tests/collection-literals/PrintAst.expected index 99312685a0e..5a81043964b 100644 --- a/java/ql/test/kotlin/library-tests/collection-literals/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/collection-literals/PrintAst.expected @@ -39,8 +39,8 @@ test.kt: # 1| 0: [VarAccess] p0 # 0| 1: [ArrayCreationExpr] new String[] # 0| -2: [ArrayInit] {...} -# 0| 0: [StringLiteral] hello -# 0| 1: [StringLiteral] world +# 0| 0: [StringLiteral] "hello" +# 0| 1: [StringLiteral] "world" # 0| -1: [TypeAccess] String # 0| 0: [IntegerLiteral] 2 # 1| 1: [IfStmt] if (...) diff --git a/java/ql/test/kotlin/library-tests/controlflow/basic/bbStmts.expected b/java/ql/test/kotlin/library-tests/controlflow/basic/bbStmts.expected index 4e0724fca1f..b3f3c19341f 100644 --- a/java/ql/test/kotlin/library-tests/controlflow/basic/bbStmts.expected +++ b/java/ql/test/kotlin/library-tests/controlflow/basic/bbStmts.expected @@ -155,7 +155,7 @@ | Test.kt:105:5:109:5 | ; | 5 | Test.kt:105:9:105:17 | ... (value not-equals) ... | | Test.kt:105:20:107:5 | { ... } | 0 | Test.kt:105:20:107:5 | { ... } | | Test.kt:105:20:107:5 | { ... } | 1 | Test.kt:106:9:106:29 | ; | -| Test.kt:105:20:107:5 | { ... } | 2 | Test.kt:106:18:106:27 | x not null | +| Test.kt:105:20:107:5 | { ... } | 2 | Test.kt:106:18:106:27 | "x not null" | | Test.kt:105:20:107:5 | { ... } | 3 | Test.kt:106:9:106:29 | println(...) | | Test.kt:107:16:109:5 | ... -> ... | 0 | Test.kt:107:16:109:5 | ... -> ... | | Test.kt:107:16:109:5 | ... -> ... | 1 | Test.kt:107:16:107:16 | y | @@ -163,7 +163,7 @@ | Test.kt:107:16:109:5 | ... -> ... | 3 | Test.kt:107:16:107:24 | ... (value not-equals) ... | | Test.kt:107:27:109:5 | { ... } | 0 | Test.kt:107:27:109:5 | { ... } | | Test.kt:107:27:109:5 | { ... } | 1 | Test.kt:108:9:108:29 | ; | -| Test.kt:107:27:109:5 | { ... } | 2 | Test.kt:108:18:108:27 | y not null | +| Test.kt:107:27:109:5 | { ... } | 2 | Test.kt:108:18:108:27 | "y not null" | | Test.kt:107:27:109:5 | { ... } | 3 | Test.kt:108:9:108:29 | println(...) | | Test.kt:112:1:116:1 | fn | 0 | Test.kt:112:1:116:1 | fn | | Test.kt:112:32:116:1 | { ... } | 0 | Test.kt:112:32:116:1 | { ... } | diff --git a/java/ql/test/kotlin/library-tests/controlflow/basic/getASuccessor.expected b/java/ql/test/kotlin/library-tests/controlflow/basic/getASuccessor.expected index bba6e9cbae7..ddd54d10b7b 100644 --- a/java/ql/test/kotlin/library-tests/controlflow/basic/getASuccessor.expected +++ b/java/ql/test/kotlin/library-tests/controlflow/basic/getASuccessor.expected @@ -207,20 +207,20 @@ missingSuccessor | Test.kt:105:9:107:5 | ... -> ... | WhenBranch | Test.kt:105:9:105:9 | x | VarAccess | | Test.kt:105:14:105:17 | null | NullLiteral | Test.kt:105:9:105:17 | ... (value not-equals) ... | ValueNEExpr | | Test.kt:105:20:107:5 | { ... } | BlockStmt | Test.kt:106:9:106:29 | ; | ExprStmt | -| Test.kt:106:9:106:29 | ; | ExprStmt | Test.kt:106:18:106:27 | x not null | StringLiteral | +| Test.kt:106:9:106:29 | ; | ExprStmt | Test.kt:106:18:106:27 | "x not null" | StringLiteral | | Test.kt:106:9:106:29 | ConsoleKt | TypeAccess | file://:0:0:0:0 | | | | Test.kt:106:9:106:29 | println(...) | MethodAccess | Test.kt:100:1:110:1 | fn | Method | -| Test.kt:106:18:106:27 | x not null | StringLiteral | Test.kt:106:9:106:29 | println(...) | MethodAccess | +| Test.kt:106:18:106:27 | "x not null" | StringLiteral | Test.kt:106:9:106:29 | println(...) | MethodAccess | | Test.kt:107:16:107:16 | y | VarAccess | Test.kt:107:21:107:24 | null | NullLiteral | | Test.kt:107:16:107:24 | ... (value not-equals) ... | ValueNEExpr | Test.kt:100:1:110:1 | fn | Method | | Test.kt:107:16:107:24 | ... (value not-equals) ... | ValueNEExpr | Test.kt:107:27:109:5 | { ... } | BlockStmt | | Test.kt:107:16:109:5 | ... -> ... | WhenBranch | Test.kt:107:16:107:16 | y | VarAccess | | Test.kt:107:21:107:24 | null | NullLiteral | Test.kt:107:16:107:24 | ... (value not-equals) ... | ValueNEExpr | | Test.kt:107:27:109:5 | { ... } | BlockStmt | Test.kt:108:9:108:29 | ; | ExprStmt | -| Test.kt:108:9:108:29 | ; | ExprStmt | Test.kt:108:18:108:27 | y not null | StringLiteral | +| Test.kt:108:9:108:29 | ; | ExprStmt | Test.kt:108:18:108:27 | "y not null" | StringLiteral | | Test.kt:108:9:108:29 | ConsoleKt | TypeAccess | file://:0:0:0:0 | | | | Test.kt:108:9:108:29 | println(...) | MethodAccess | Test.kt:100:1:110:1 | fn | Method | -| Test.kt:108:18:108:27 | y not null | StringLiteral | Test.kt:108:9:108:29 | println(...) | MethodAccess | +| Test.kt:108:18:108:27 | "y not null" | StringLiteral | Test.kt:108:9:108:29 | println(...) | MethodAccess | | Test.kt:112:1:116:1 | Unit | TypeAccess | file://:0:0:0:0 | | | | Test.kt:112:1:116:1 | fn | Method | file://:0:0:0:0 | | | | Test.kt:112:8:112:17 | boolean | TypeAccess | file://:0:0:0:0 | | | diff --git a/java/ql/test/kotlin/library-tests/data-classes/PrintAst.expected b/java/ql/test/kotlin/library-tests/data-classes/PrintAst.expected index d52888544dc..7ea9b169c7c 100644 --- a/java/ql/test/kotlin/library-tests/data-classes/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/data-classes/PrintAst.expected @@ -145,19 +145,19 @@ dc.kt: # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... # 0| 0: [StringTemplateExpr] "..." -# 0| 0: [StringLiteral] ProtoMapValue( -# 0| 1: [StringLiteral] bytes= +# 0| 0: [StringLiteral] "ProtoMapValue(" +# 0| 1: [StringLiteral] "bytes=" # 0| 2: [MethodAccess] toString(...) # 0| -1: [TypeAccess] Arrays # 0| 0: [VarAccess] this.bytes # 0| -1: [ThisAccess] this -# 0| 3: [StringLiteral] , -# 0| 4: [StringLiteral] strs= +# 0| 3: [StringLiteral] ", " +# 0| 4: [StringLiteral] "strs=" # 0| 5: [MethodAccess] toString(...) # 0| -1: [TypeAccess] Arrays # 0| 0: [VarAccess] this.strs # 0| -1: [ThisAccess] this -# 0| 6: [StringLiteral] ) +# 0| 6: [StringLiteral] ")" # 1| 8: [Constructor] ProtoMapValue #-----| 4: (Parameters) # 1| 0: [Parameter] bytes diff --git a/java/ql/test/kotlin/library-tests/dataflow/foreach/test.expected b/java/ql/test/kotlin/library-tests/dataflow/foreach/test.expected index f204c12ebe2..7c7b382a9ad 100644 --- a/java/ql/test/kotlin/library-tests/dataflow/foreach/test.expected +++ b/java/ql/test/kotlin/library-tests/dataflow/foreach/test.expected @@ -2,7 +2,7 @@ | C1.java:10:44:10:46 | "a" | C1.java:12:17:12:20 | ...[...] | | C1.java:10:44:10:46 | "a" | C1.java:15:20:15:23 | ...[...] | | C1.java:10:44:10:46 | "a" | C1.java:19:20:19:20 | s | -| C2.kt:8:32:8:32 | a | C2.kt:9:14:9:14 | l | -| C2.kt:8:32:8:32 | a | C2.kt:10:14:10:17 | ...[...] | -| C2.kt:8:32:8:32 | a | C2.kt:12:18:12:21 | ...[...] | -| C2.kt:8:32:8:32 | a | C2.kt:15:18:15:18 | s | +| C2.kt:8:32:8:32 | "a" | C2.kt:9:14:9:14 | l | +| C2.kt:8:32:8:32 | "a" | C2.kt:10:14:10:17 | ...[...] | +| C2.kt:8:32:8:32 | "a" | C2.kt:12:18:12:21 | ...[...] | +| C2.kt:8:32:8:32 | "a" | C2.kt:15:18:15:18 | s | diff --git a/java/ql/test/kotlin/library-tests/exprs/PrintAst.expected b/java/ql/test/kotlin/library-tests/exprs/PrintAst.expected index f821bdadd5b..78bf583ec0d 100644 --- a/java/ql/test/kotlin/library-tests/exprs/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/exprs/PrintAst.expected @@ -171,7 +171,7 @@ delegatedProperties.kt: # 7| 0: [ExprStmt] ; # 7| 0: [MethodAccess] println(...) # 7| -1: [TypeAccess] ConsoleKt -# 7| 0: [StringLiteral] init +# 7| 0: [StringLiteral] "init" # 8| 1: [ReturnStmt] return ... # 8| 0: [IntegerLiteral] 5 # 6| -3: [TypeAccess] Function0 @@ -2459,10 +2459,10 @@ exprs.kt: # 123| 0: [CharacterLiteral] x # 124| 106: [LocalVariableDeclStmt] var ...; # 124| 1: [LocalVariableDeclExpr] str -# 124| 0: [StringLiteral] string lit +# 124| 0: [StringLiteral] "string lit" # 125| 107: [LocalVariableDeclStmt] var ...; # 125| 1: [LocalVariableDeclExpr] strWithQuote -# 125| 0: [StringLiteral] string " lit +# 125| 0: [StringLiteral] "string \" lit" # 126| 108: [LocalVariableDeclStmt] var ...; # 126| 1: [LocalVariableDeclExpr] b6 # 126| 0: [InstanceOfExpr] ...instanceof... @@ -2480,34 +2480,34 @@ exprs.kt: # 128| 1: [VarAccess] b7 # 129| 111: [LocalVariableDeclStmt] var ...; # 129| 1: [LocalVariableDeclExpr] str1 -# 129| 0: [StringLiteral] string lit +# 129| 0: [StringLiteral] "string lit" # 130| 112: [LocalVariableDeclStmt] var ...; # 130| 1: [LocalVariableDeclExpr] str2 -# 130| 0: [StringLiteral] string lit +# 130| 0: [StringLiteral] "string lit" # 131| 113: [LocalVariableDeclStmt] var ...; # 131| 1: [LocalVariableDeclExpr] str3 # 131| 0: [NullLiteral] null # 132| 114: [LocalVariableDeclStmt] var ...; # 132| 1: [LocalVariableDeclExpr] str4 # 132| 0: [StringTemplateExpr] "..." -# 132| 0: [StringLiteral] foo +# 132| 0: [StringLiteral] "foo " # 132| 1: [VarAccess] str1 -# 132| 2: [StringLiteral] bar +# 132| 2: [StringLiteral] " bar " # 132| 3: [VarAccess] str2 -# 132| 4: [StringLiteral] baz +# 132| 4: [StringLiteral] " baz" # 133| 115: [LocalVariableDeclStmt] var ...; # 133| 1: [LocalVariableDeclExpr] str5 # 133| 0: [StringTemplateExpr] "..." -# 133| 0: [StringLiteral] foo +# 133| 0: [StringLiteral] "foo " # 133| 1: [AddExpr] ... + ... # 133| 0: [VarAccess] str1 # 133| 1: [VarAccess] str2 -# 133| 2: [StringLiteral] bar +# 133| 2: [StringLiteral] " bar " # 133| 3: [MethodAccess] stringPlus(...) # 133| -1: [TypeAccess] Intrinsics # 133| 0: [VarAccess] str2 # 133| 1: [VarAccess] str1 -# 133| 4: [StringLiteral] baz +# 133| 4: [StringLiteral] " baz" # 134| 116: [LocalVariableDeclStmt] var ...; # 134| 1: [LocalVariableDeclExpr] str6 # 134| 0: [AddExpr] ... + ... @@ -3531,12 +3531,12 @@ exprs.kt: # 215| 1: [LocalVariableDeclExpr] d0 # 215| 0: [MethodAccess] valueOf(...) # 215| -1: [TypeAccess] Color -# 215| 0: [StringLiteral] GREEN +# 215| 0: [StringLiteral] "GREEN" # 216| 8: [LocalVariableDeclStmt] var ...; # 216| 1: [LocalVariableDeclExpr] d1 # 216| 0: [MethodAccess] valueOf(...) # 216| -1: [TypeAccess] Color -# 216| 0: [StringLiteral] GREEN +# 216| 0: [StringLiteral] "GREEN" # 224| 11: [Class] SomeClass1 # 224| 1: [Constructor] SomeClass1 # 224| 5: [BlockStmt] { ... } @@ -4468,7 +4468,7 @@ funcExprs.kt: # 36| 0: [TypeAccess] int # 36| 5: [BlockStmt] { ... } # 36| 0: [ReturnStmt] return ... -# 36| 0: [StringLiteral] +# 36| 0: [StringLiteral] "" # 36| -3: [TypeAccess] FunctionN # 36| 0: [TypeAccess] String # 38| 14: [ExprStmt] ; @@ -5316,7 +5316,7 @@ funcExprs.kt: # 90| 0: [TypeAccess] int # 90| 5: [BlockStmt] { ... } # 90| 0: [ReturnStmt] return ... -# 90| 0: [StringLiteral] +# 90| 0: [StringLiteral] "" # 90| -3: [TypeAccess] FunctionN # 90| 0: [TypeAccess] String # 91| 5: [ExprStmt] ; @@ -5407,7 +5407,7 @@ funcExprs.kt: # 94| 0: [TypeAccess] int # 94| 5: [BlockStmt] { ... } # 94| 0: [ReturnStmt] return ... -# 94| 0: [StringLiteral] +# 94| 0: [StringLiteral] "" # 94| -3: [TypeAccess] Function22 # 94| 0: [TypeAccess] Integer # 94| 1: [TypeAccess] Integer @@ -5599,7 +5599,7 @@ funcExprs.kt: # 70| 0: [TypeAccess] int # 70| 5: [BlockStmt] { ... } # 70| 0: [ReturnStmt] return ... -# 70| 0: [StringLiteral] +# 70| 0: [StringLiteral] "" # 73| 4: [Class] Class3 # 73| 3: [Constructor] Class3 # 73| 5: [BlockStmt] { ... } @@ -5625,7 +5625,7 @@ funcExprs.kt: # 75| 0: [TypeAccess] Integer # 75| 5: [BlockStmt] { ... } # 75| 0: [ReturnStmt] return ... -# 75| 0: [StringLiteral] a +# 75| 0: [StringLiteral] "a" # 75| -3: [TypeAccess] Function1>,String> # 75| 0: [TypeAccess] Generic> # 75| 0: [TypeAccess] Generic @@ -6014,7 +6014,7 @@ samConversion.kt: # 7| 0: [ReturnStmt] return ... # 7| 0: [ValueEQExpr] ... (value equals) ... # 7| 0: [ExtensionReceiverAccess] this -# 7| 1: [StringLiteral] +# 7| 1: [StringLiteral] "" # 7| -3: [TypeAccess] Function2 # 7| 0: [TypeAccess] String # 7| 1: [TypeAccess] Integer @@ -7058,7 +7058,7 @@ whenExpr.kt: # 6| 1: [ThrowStmt] throw ... # 6| 0: [ClassInstanceExpr] new Exception(...) # 6| -3: [TypeAccess] Exception -# 6| 0: [StringLiteral] No threes please +# 6| 0: [StringLiteral] "No threes please" # 7| 4: [WhenBranch] ... -> ... # 7| 0: [BooleanLiteral] true # 7| 1: [ExprStmt] ; diff --git a/java/ql/test/kotlin/library-tests/exprs/binop.expected b/java/ql/test/kotlin/library-tests/exprs/binop.expected index 4c08b123a68..f69701028d5 100644 --- a/java/ql/test/kotlin/library-tests/exprs/binop.expected +++ b/java/ql/test/kotlin/library-tests/exprs/binop.expected @@ -127,7 +127,7 @@ | localFunctionCalls.kt:5:25:5:29 | ... + ... | localFunctionCalls.kt:5:25:5:25 | i | localFunctionCalls.kt:5:29:5:29 | x | | samConversion.kt:2:33:2:38 | ... % ... | samConversion.kt:2:33:2:34 | it | samConversion.kt:2:38:2:38 | 2 | | samConversion.kt:2:33:2:43 | ... (value equals) ... | samConversion.kt:2:33:2:38 | ... % ... | samConversion.kt:2:43:2:43 | 0 | -| samConversion.kt:7:36:7:45 | ... (value equals) ... | samConversion.kt:7:36:7:39 | this | samConversion.kt:7:44:7:45 | | +| samConversion.kt:7:36:7:45 | ... (value equals) ... | samConversion.kt:7:36:7:39 | this | samConversion.kt:7:44:7:45 | "" | | samConversion.kt:10:18:10:22 | ... % ... | samConversion.kt:10:18:10:18 | j | samConversion.kt:10:22:10:22 | 2 | | samConversion.kt:10:18:10:27 | ... (value equals) ... | samConversion.kt:10:18:10:22 | ... % ... | samConversion.kt:10:27:10:27 | 0 | | samConversion.kt:12:18:12:22 | ... % ... | samConversion.kt:12:18:12:18 | j | samConversion.kt:12:22:12:22 | 2 | diff --git a/java/ql/test/kotlin/library-tests/exprs/exprs.expected b/java/ql/test/kotlin/library-tests/exprs/exprs.expected index 08a9891f64b..4b8d200a1d7 100644 --- a/java/ql/test/kotlin/library-tests/exprs/exprs.expected +++ b/java/ql/test/kotlin/library-tests/exprs/exprs.expected @@ -51,7 +51,7 @@ | delegatedProperties.kt:6:32:9:9 | int | file://:0:0:0:0 | | TypeAccess | | delegatedProperties.kt:7:13:7:27 | ConsoleKt | delegatedProperties.kt:6:32:9:9 | invoke | TypeAccess | | delegatedProperties.kt:7:13:7:27 | println(...) | delegatedProperties.kt:6:32:9:9 | invoke | MethodAccess | -| delegatedProperties.kt:7:22:7:25 | init | delegatedProperties.kt:6:32:9:9 | invoke | StringLiteral | +| delegatedProperties.kt:7:22:7:25 | "init" | delegatedProperties.kt:6:32:9:9 | invoke | StringLiteral | | delegatedProperties.kt:8:13:8:13 | 5 | delegatedProperties.kt:6:32:9:9 | invoke | IntegerLiteral | | delegatedProperties.kt:10:9:10:22 | ConsoleKt | delegatedProperties.kt:5:5:12:5 | fn | TypeAccess | | delegatedProperties.kt:10:9:10:22 | println(...) | delegatedProperties.kt:5:5:12:5 | fn | MethodAccess | @@ -1337,9 +1337,9 @@ | exprs.kt:123:5:123:15 | c | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:123:13:123:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | CharacterLiteral | | exprs.kt:124:5:124:26 | str | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | -| exprs.kt:124:16:124:25 | string lit | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:124:16:124:25 | "string lit" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | | exprs.kt:125:5:125:38 | strWithQuote | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | -| exprs.kt:125:25:125:37 | string " lit | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:125:25:125:37 | "string \\" lit" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | | exprs.kt:126:5:126:22 | b6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:126:14:126:15 | i1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:126:14:126:22 | ...instanceof... | exprs.kt:4:1:142:1 | topLevelMethod | InstanceOfExpr | @@ -1353,30 +1353,30 @@ | exprs.kt:128:14:128:26 | (...)... | exprs.kt:4:1:142:1 | topLevelMethod | CastExpr | | exprs.kt:128:14:128:26 | boolean | exprs.kt:4:1:142:1 | topLevelMethod | TypeAccess | | exprs.kt:129:5:129:35 | str1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | -| exprs.kt:129:25:129:34 | string lit | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:129:25:129:34 | "string lit" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | | exprs.kt:130:5:130:36 | str2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | -| exprs.kt:130:26:130:35 | string lit | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:130:26:130:35 | "string lit" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | | exprs.kt:131:5:131:28 | str3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:131:25:131:28 | null | exprs.kt:4:1:142:1 | topLevelMethod | NullLiteral | | exprs.kt:132:5:132:48 | str4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:132:24:132:48 | "..." | exprs.kt:4:1:142:1 | topLevelMethod | StringTemplateExpr | -| exprs.kt:132:25:132:28 | foo | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:132:25:132:28 | "foo " | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | | exprs.kt:132:30:132:33 | str1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:132:34:132:38 | bar | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:132:34:132:38 | " bar " | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | | exprs.kt:132:40:132:43 | str2 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:132:44:132:47 | baz | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:132:44:132:47 | " baz" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | | exprs.kt:133:5:133:66 | str5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:133:24:133:66 | "..." | exprs.kt:4:1:142:1 | topLevelMethod | StringTemplateExpr | -| exprs.kt:133:25:133:28 | foo | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:133:25:133:28 | "foo " | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | | exprs.kt:133:31:133:34 | str1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:133:31:133:41 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:133:38:133:41 | str2 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:133:43:133:47 | bar | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:133:43:133:47 | " bar " | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | | exprs.kt:133:50:133:53 | str2 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:133:50:133:60 | Intrinsics | exprs.kt:4:1:142:1 | topLevelMethod | TypeAccess | | exprs.kt:133:50:133:60 | stringPlus(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:133:57:133:60 | str1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:133:62:133:65 | baz | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:133:62:133:65 | " baz" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | | exprs.kt:134:5:134:26 | str6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:134:16:134:19 | str1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:134:16:134:26 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | @@ -1605,11 +1605,11 @@ | exprs.kt:215:9:215:44 | d0 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:215:18:215:44 | Color | exprs.kt:206:5:217:5 | x | TypeAccess | | exprs.kt:215:18:215:44 | valueOf(...) | exprs.kt:206:5:217:5 | x | MethodAccess | -| exprs.kt:215:38:215:42 | GREEN | exprs.kt:206:5:217:5 | x | StringLiteral | +| exprs.kt:215:38:215:42 | "GREEN" | exprs.kt:206:5:217:5 | x | StringLiteral | | exprs.kt:216:9:216:39 | d1 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:216:24:216:39 | Color | exprs.kt:206:5:217:5 | x | TypeAccess | | exprs.kt:216:24:216:39 | valueOf(...) | exprs.kt:206:5:217:5 | x | MethodAccess | -| exprs.kt:216:33:216:37 | GREEN | exprs.kt:206:5:217:5 | x | StringLiteral | +| exprs.kt:216:33:216:37 | "GREEN" | exprs.kt:206:5:217:5 | x | StringLiteral | | exprs.kt:220:1:222:1 | Unit | file://:0:0:0:0 | | TypeAccess | | exprs.kt:221:5:221:10 | StandardKt | exprs.kt:220:1:222:1 | todo | TypeAccess | | exprs.kt:221:5:221:10 | TODO(...) | exprs.kt:220:1:222:1 | todo | MethodAccess | @@ -2730,7 +2730,7 @@ | funcExprs.kt:36:100:36:102 | int | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:36:104:36:106 | int | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:36:108:36:110 | int | file://:0:0:0:0 | | TypeAccess | -| funcExprs.kt:36:115:36:116 | | funcExprs.kt:36:29:36:117 | invoke | StringLiteral | +| funcExprs.kt:36:115:36:116 | "" | funcExprs.kt:36:29:36:117 | invoke | StringLiteral | | funcExprs.kt:38:5:38:39 | FuncExprsKt | funcExprs.kt:21:1:52:1 | call | TypeAccess | | funcExprs.kt:38:5:38:39 | functionExpression0a(...) | funcExprs.kt:21:1:52:1 | call | MethodAccess | | funcExprs.kt:38:26:38:34 | FuncRef | funcExprs.kt:21:1:52:1 | call | TypeAccess | @@ -3231,7 +3231,7 @@ | funcExprs.kt:70:102:70:109 | int | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:70:112:70:119 | int | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:70:122:70:129 | int | file://:0:0:0:0 | | TypeAccess | -| funcExprs.kt:70:134:70:135 | | funcExprs.kt:69:5:70:135 | f23 | StringLiteral | +| funcExprs.kt:70:134:70:135 | "" | funcExprs.kt:69:5:70:135 | f23 | StringLiteral | | funcExprs.kt:74:5:76:5 | Unit | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:75:9:75:22 | fn(...) | funcExprs.kt:74:5:76:5 | call | MethodAccess | | funcExprs.kt:75:9:75:22 | this | funcExprs.kt:74:5:76:5 | call | ThisAccess | @@ -3245,7 +3245,7 @@ | funcExprs.kt:75:14:75:14 | Generic> | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:75:14:75:14 | Generic | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:75:14:75:14 | Integer | file://:0:0:0:0 | | TypeAccess | -| funcExprs.kt:75:20:75:20 | a | funcExprs.kt:75:12:75:22 | invoke | StringLiteral | +| funcExprs.kt:75:20:75:20 | "a" | funcExprs.kt:75:12:75:22 | invoke | StringLiteral | | funcExprs.kt:77:13:77:60 | Unit | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:77:20:77:55 | ? ... | file://:0:0:0:0 | | WildcardTypeAccess | | funcExprs.kt:77:20:77:55 | Function1>,String> | file://:0:0:0:0 | | TypeAccess | @@ -3427,7 +3427,7 @@ | funcExprs.kt:90:57:90:57 | int | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:90:59:90:59 | int | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:90:61:90:61 | int | file://:0:0:0:0 | | TypeAccess | -| funcExprs.kt:90:67:90:68 | | funcExprs.kt:90:15:90:69 | invoke | StringLiteral | +| funcExprs.kt:90:67:90:68 | "" | funcExprs.kt:90:15:90:69 | invoke | StringLiteral | | funcExprs.kt:91:5:91:6 | l3 | funcExprs.kt:82:9:96:1 | fn | VarAccess | | funcExprs.kt:91:5:91:60 | 23 | funcExprs.kt:82:9:96:1 | fn | IntegerLiteral | | funcExprs.kt:91:5:91:60 | Object | funcExprs.kt:82:9:96:1 | fn | TypeAccess | @@ -3508,7 +3508,7 @@ | funcExprs.kt:94:55:94:55 | int | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:94:57:94:57 | int | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:94:59:94:59 | int | file://:0:0:0:0 | | TypeAccess | -| funcExprs.kt:94:65:94:66 | | funcExprs.kt:94:15:94:67 | invoke | StringLiteral | +| funcExprs.kt:94:65:94:66 | "" | funcExprs.kt:94:15:94:67 | invoke | StringLiteral | | funcExprs.kt:95:5:95:6 | l4 | funcExprs.kt:82:9:96:1 | fn | VarAccess | | funcExprs.kt:95:5:95:58 | invoke(...) | funcExprs.kt:82:9:96:1 | fn | MethodAccess | | funcExprs.kt:95:8:95:58 | | funcExprs.kt:82:9:96:1 | fn | ImplicitCoercionToUnitExpr | @@ -3724,7 +3724,7 @@ | samConversion.kt:7:31:7:31 | int | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:7:36:7:39 | this | samConversion.kt:7:29:7:46 | invoke | ExtensionReceiverAccess | | samConversion.kt:7:36:7:45 | ... (value equals) ... | samConversion.kt:7:29:7:46 | invoke | ValueEQExpr | -| samConversion.kt:7:44:7:45 | | samConversion.kt:7:29:7:46 | invoke | StringLiteral | +| samConversion.kt:7:44:7:45 | "" | samConversion.kt:7:29:7:46 | invoke | StringLiteral | | samConversion.kt:9:5:13:6 | x | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | | samConversion.kt:9:13:13:6 | (...)... | samConversion.kt:1:1:14:1 | main | CastExpr | | samConversion.kt:9:13:13:6 | ...=... | samConversion.kt:9:13:13:6 | | AssignExpr | @@ -4379,6 +4379,6 @@ | whenExpr.kt:6:5:6:5 | tmp0_subject | whenExpr.kt:1:1:9:1 | testWhen | VarAccess | | whenExpr.kt:6:16:6:44 | Exception | whenExpr.kt:1:1:9:1 | testWhen | TypeAccess | | whenExpr.kt:6:16:6:44 | new Exception(...) | whenExpr.kt:1:1:9:1 | testWhen | ClassInstanceExpr | -| whenExpr.kt:6:27:6:42 | No threes please | whenExpr.kt:1:1:9:1 | testWhen | StringLiteral | +| whenExpr.kt:6:27:6:42 | "No threes please" | whenExpr.kt:1:1:9:1 | testWhen | StringLiteral | | whenExpr.kt:7:13:7:15 | 999 | whenExpr.kt:1:1:9:1 | testWhen | IntegerLiteral | | whenExpr.kt:7:13:7:15 | true | whenExpr.kt:1:1:9:1 | testWhen | BooleanLiteral | diff --git a/java/ql/test/kotlin/library-tests/exprs_typeaccess/PrintAst.expected b/java/ql/test/kotlin/library-tests/exprs_typeaccess/PrintAst.expected index 77b2fbb794e..5af83a46a01 100644 --- a/java/ql/test/kotlin/library-tests/exprs_typeaccess/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/exprs_typeaccess/PrintAst.expected @@ -27,7 +27,7 @@ A.kt: # 10| 2: [ExprStmt] ; # 10| 0: [MethodAccess] println(...) # 10| -1: [TypeAccess] ConsoleKt -# 10| 0: [StringLiteral] +# 10| 0: [StringLiteral] "" # 13| 6: [Method] getProp # 13| 3: [TypeAccess] int # 13| 5: [BlockStmt] { ... } diff --git a/java/ql/test/kotlin/library-tests/extensions/methodaccesses.expected b/java/ql/test/kotlin/library-tests/extensions/methodaccesses.expected index 03322ec3313..4aa35cde90b 100644 --- a/java/ql/test/kotlin/library-tests/extensions/methodaccesses.expected +++ b/java/ql/test/kotlin/library-tests/extensions/methodaccesses.expected @@ -1,20 +1,20 @@ | A.java:3:9:3:49 | someFun(...) | A.java:3:9:3:20 | ExtensionsKt | A.java:3:30:3:44 | new SomeClass(...) | | A.java:3:9:3:49 | someFun(...) | A.java:3:9:3:20 | ExtensionsKt | A.java:3:47:3:48 | "" | -| extensions.kt:21:5:21:38 | someClassMethod(...) | extensions.kt:21:5:21:15 | new SomeClass(...) | extensions.kt:21:34:21:36 | foo | +| extensions.kt:21:5:21:38 | someClassMethod(...) | extensions.kt:21:5:21:15 | new SomeClass(...) | extensions.kt:21:34:21:36 | "foo" | | extensions.kt:22:5:22:30 | someFun(...) | extensions.kt:22:5:22:30 | ExtensionsKt | extensions.kt:22:5:22:15 | new SomeClass(...) | -| extensions.kt:22:5:22:30 | someFun(...) | extensions.kt:22:5:22:30 | ExtensionsKt | extensions.kt:22:26:22:28 | foo | +| extensions.kt:22:5:22:30 | someFun(...) | extensions.kt:22:5:22:30 | ExtensionsKt | extensions.kt:22:26:22:28 | "foo" | | extensions.kt:23:5:23:30 | bothFun(...) | extensions.kt:23:5:23:30 | ExtensionsKt | extensions.kt:23:5:23:15 | new SomeClass(...) | -| extensions.kt:23:5:23:30 | bothFun(...) | extensions.kt:23:5:23:30 | ExtensionsKt | extensions.kt:23:26:23:28 | foo | +| extensions.kt:23:5:23:30 | bothFun(...) | extensions.kt:23:5:23:30 | ExtensionsKt | extensions.kt:23:26:23:28 | "foo" | | extensions.kt:24:5:24:35 | bothFunDiffTypes(...) | extensions.kt:24:5:24:35 | ExtensionsKt | extensions.kt:24:5:24:15 | new SomeClass(...) | | extensions.kt:24:5:24:35 | bothFunDiffTypes(...) | extensions.kt:24:5:24:35 | ExtensionsKt | extensions.kt:24:34:24:34 | 1 | -| extensions.kt:25:5:25:44 | anotherClassMethod(...) | extensions.kt:25:5:25:18 | new AnotherClass(...) | extensions.kt:25:40:25:42 | foo | +| extensions.kt:25:5:25:44 | anotherClassMethod(...) | extensions.kt:25:5:25:18 | new AnotherClass(...) | extensions.kt:25:40:25:42 | "foo" | | extensions.kt:26:5:26:36 | anotherFun(...) | extensions.kt:26:5:26:36 | ExtensionsKt | extensions.kt:26:5:26:18 | new AnotherClass(...) | -| extensions.kt:26:5:26:36 | anotherFun(...) | extensions.kt:26:5:26:36 | ExtensionsKt | extensions.kt:26:32:26:34 | foo | +| extensions.kt:26:5:26:36 | anotherFun(...) | extensions.kt:26:5:26:36 | ExtensionsKt | extensions.kt:26:32:26:34 | "foo" | | extensions.kt:27:5:27:33 | bothFun(...) | extensions.kt:27:5:27:33 | ExtensionsKt | extensions.kt:27:5:27:18 | new AnotherClass(...) | -| extensions.kt:27:5:27:33 | bothFun(...) | extensions.kt:27:5:27:33 | ExtensionsKt | extensions.kt:27:29:27:31 | foo | +| extensions.kt:27:5:27:33 | bothFun(...) | extensions.kt:27:5:27:33 | ExtensionsKt | extensions.kt:27:29:27:31 | "foo" | | extensions.kt:28:5:28:42 | bothFunDiffTypes(...) | extensions.kt:28:5:28:42 | ExtensionsKt | extensions.kt:28:5:28:18 | new AnotherClass(...) | -| extensions.kt:28:5:28:42 | bothFunDiffTypes(...) | extensions.kt:28:5:28:42 | ExtensionsKt | extensions.kt:28:38:28:40 | foo | -| extensions.kt:29:6:29:27 | bar(...) | extensions.kt:29:6:29:27 | ExtensionsKt | extensions.kt:29:6:29:15 | someString | -| extensions.kt:29:6:29:27 | bar(...) | extensions.kt:29:6:29:27 | ExtensionsKt | extensions.kt:29:23:29:25 | foo | -| extensions.kt:31:6:31:32 | baz(...) | extensions.kt:31:6:31:32 | new (...) | extensions.kt:31:6:31:15 | someString | -| extensions.kt:31:6:31:32 | baz(...) | extensions.kt:31:6:31:32 | new (...) | extensions.kt:31:23:31:30 | bazParam | +| extensions.kt:28:5:28:42 | bothFunDiffTypes(...) | extensions.kt:28:5:28:42 | ExtensionsKt | extensions.kt:28:38:28:40 | "foo" | +| extensions.kt:29:6:29:27 | bar(...) | extensions.kt:29:6:29:27 | ExtensionsKt | extensions.kt:29:6:29:15 | "someString" | +| extensions.kt:29:6:29:27 | bar(...) | extensions.kt:29:6:29:27 | ExtensionsKt | extensions.kt:29:23:29:25 | "foo" | +| extensions.kt:31:6:31:32 | baz(...) | extensions.kt:31:6:31:32 | new (...) | extensions.kt:31:6:31:15 | "someString" | +| extensions.kt:31:6:31:32 | baz(...) | extensions.kt:31:6:31:32 | new (...) | extensions.kt:31:23:31:30 | "bazParam" | diff --git a/java/ql/test/kotlin/library-tests/extensions/parameters.expected b/java/ql/test/kotlin/library-tests/extensions/parameters.expected index 5cb7e0986d3..65906e57dd2 100644 --- a/java/ql/test/kotlin/library-tests/extensions/parameters.expected +++ b/java/ql/test/kotlin/library-tests/extensions/parameters.expected @@ -1,24 +1,24 @@ parametersWithArgs -| extensions.kt:3:25:3:34 | p1 | 0 | extensions.kt:21:34:21:36 | foo | -| extensions.kt:6:28:6:37 | p1 | 0 | extensions.kt:25:40:25:42 | foo | +| extensions.kt:3:25:3:34 | p1 | 0 | extensions.kt:21:34:21:36 | "foo" | +| extensions.kt:6:28:6:37 | p1 | 0 | extensions.kt:25:40:25:42 | "foo" | | extensions.kt:9:5:9:13 | | 0 | A.java:3:30:3:44 | new SomeClass(...) | | extensions.kt:9:5:9:13 | | 0 | extensions.kt:22:5:22:15 | new SomeClass(...) | | extensions.kt:9:23:9:32 | p1 | 1 | A.java:3:47:3:48 | "" | -| extensions.kt:9:23:9:32 | p1 | 1 | extensions.kt:22:26:22:28 | foo | +| extensions.kt:9:23:9:32 | p1 | 1 | extensions.kt:22:26:22:28 | "foo" | | extensions.kt:10:5:10:16 | | 0 | extensions.kt:26:5:26:18 | new AnotherClass(...) | -| extensions.kt:10:29:10:38 | p1 | 1 | extensions.kt:26:32:26:34 | foo | +| extensions.kt:10:29:10:38 | p1 | 1 | extensions.kt:26:32:26:34 | "foo" | | extensions.kt:12:5:12:13 | | 0 | extensions.kt:23:5:23:15 | new SomeClass(...) | -| extensions.kt:12:23:12:32 | p1 | 1 | extensions.kt:23:26:23:28 | foo | +| extensions.kt:12:23:12:32 | p1 | 1 | extensions.kt:23:26:23:28 | "foo" | | extensions.kt:13:5:13:16 | | 0 | extensions.kt:27:5:27:18 | new AnotherClass(...) | -| extensions.kt:13:26:13:35 | p1 | 1 | extensions.kt:27:29:27:31 | foo | +| extensions.kt:13:26:13:35 | p1 | 1 | extensions.kt:27:29:27:31 | "foo" | | extensions.kt:15:5:15:13 | | 0 | extensions.kt:24:5:24:15 | new SomeClass(...) | | extensions.kt:15:32:15:38 | p1 | 1 | extensions.kt:24:34:24:34 | 1 | | extensions.kt:16:5:16:16 | | 0 | extensions.kt:28:5:28:18 | new AnotherClass(...) | -| extensions.kt:16:35:16:44 | p1 | 1 | extensions.kt:28:38:28:40 | foo | -| extensions.kt:18:5:18:10 | | 0 | extensions.kt:29:6:29:15 | someString | -| extensions.kt:18:16:18:25 | p1 | 1 | extensions.kt:29:23:29:25 | foo | -| extensions.kt:30:9:30:14 | | 0 | extensions.kt:31:6:31:15 | someString | -| extensions.kt:30:20:30:29 | p1 | 1 | extensions.kt:31:23:31:30 | bazParam | +| extensions.kt:16:35:16:44 | p1 | 1 | extensions.kt:28:38:28:40 | "foo" | +| extensions.kt:18:5:18:10 | | 0 | extensions.kt:29:6:29:15 | "someString" | +| extensions.kt:18:16:18:25 | p1 | 1 | extensions.kt:29:23:29:25 | "foo" | +| extensions.kt:30:9:30:14 | | 0 | extensions.kt:31:6:31:15 | "someString" | +| extensions.kt:30:20:30:29 | p1 | 1 | extensions.kt:31:23:31:30 | "bazParam" | extensionParameter | extensions.kt:9:5:9:13 | | | extensions.kt:10:5:10:16 | | diff --git a/java/ql/test/kotlin/library-tests/generic-inner-classes/test.expected b/java/ql/test/kotlin/library-tests/generic-inner-classes/test.expected index deed53a7269..8b6a502898e 100644 --- a/java/ql/test/kotlin/library-tests/generic-inner-classes/test.expected +++ b/java/ql/test/kotlin/library-tests/generic-inner-classes/test.expected @@ -2,11 +2,11 @@ callArgs | KotlinUser.kt:7:13:7:31 | new OuterGeneric(...) | KotlinUser.kt:7:13:7:31 | OuterGeneric | -3 | | KotlinUser.kt:7:33:7:61 | new InnerGeneric(...) | KotlinUser.kt:7:13:7:31 | new OuterGeneric(...) | -2 | | KotlinUser.kt:7:33:7:61 | new InnerGeneric(...) | KotlinUser.kt:7:33:7:61 | InnerGeneric | -3 | -| KotlinUser.kt:7:33:7:61 | new InnerGeneric(...) | KotlinUser.kt:7:55:7:59 | hello | 0 | +| KotlinUser.kt:7:33:7:61 | new InnerGeneric(...) | KotlinUser.kt:7:55:7:59 | "hello" | 0 | | KotlinUser.kt:8:14:8:32 | new OuterGeneric(...) | KotlinUser.kt:8:14:8:32 | OuterGeneric | -3 | | KotlinUser.kt:8:34:8:54 | new InnerGeneric(...) | KotlinUser.kt:8:14:8:32 | new OuterGeneric(...) | -2 | | KotlinUser.kt:8:34:8:54 | new InnerGeneric(...) | KotlinUser.kt:8:34:8:54 | InnerGeneric | -3 | -| KotlinUser.kt:8:34:8:54 | new InnerGeneric(...) | KotlinUser.kt:8:48:8:52 | hello | 0 | +| KotlinUser.kt:8:34:8:54 | new InnerGeneric(...) | KotlinUser.kt:8:48:8:52 | "hello" | 0 | | KotlinUser.kt:9:13:9:31 | new OuterGeneric(...) | KotlinUser.kt:9:13:9:31 | OuterGeneric | -3 | | KotlinUser.kt:9:33:9:49 | new InnerNotGeneric<>(...) | KotlinUser.kt:9:13:9:31 | new OuterGeneric(...) | -2 | | KotlinUser.kt:9:33:9:49 | new InnerNotGeneric<>(...) | KotlinUser.kt:9:33:9:49 | InnerNotGeneric<> | -3 | @@ -15,11 +15,11 @@ callArgs | KotlinUser.kt:10:31:10:52 | new InnerGeneric(...) | KotlinUser.kt:10:31:10:52 | InnerGeneric | -3 | | KotlinUser.kt:12:19:12:44 | returnsecond(...) | KotlinUser.kt:12:19:12:19 | a | -1 | | KotlinUser.kt:12:19:12:44 | returnsecond(...) | KotlinUser.kt:12:34:12:34 | 0 | 0 | -| KotlinUser.kt:12:19:12:44 | returnsecond(...) | KotlinUser.kt:12:38:12:42 | hello | 1 | +| KotlinUser.kt:12:19:12:44 | returnsecond(...) | KotlinUser.kt:12:38:12:42 | "hello" | 1 | | KotlinUser.kt:13:19:13:31 | identity(...) | KotlinUser.kt:13:19:13:19 | b | -1 | | KotlinUser.kt:13:19:13:31 | identity(...) | KotlinUser.kt:13:30:13:30 | 5 | 0 | | KotlinUser.kt:14:19:14:37 | identity(...) | KotlinUser.kt:14:19:14:19 | c | -1 | -| KotlinUser.kt:14:19:14:37 | identity(...) | KotlinUser.kt:14:31:14:35 | world | 0 | +| KotlinUser.kt:14:19:14:37 | identity(...) | KotlinUser.kt:14:31:14:35 | "world" | 0 | genericTypes | OuterGeneric.kt:3:1:21:1 | OuterGeneric | OuterGeneric.kt:3:27:3:27 | T | | OuterGeneric.kt:11:3:19:3 | InnerGeneric | OuterGeneric.kt:11:35:11:35 | S | diff --git a/java/ql/test/kotlin/library-tests/generics/PrintAst.expected b/java/ql/test/kotlin/library-tests/generics/PrintAst.expected index 619ba5f3bcc..2c3b395f4f1 100644 --- a/java/ql/test/kotlin/library-tests/generics/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/generics/PrintAst.expected @@ -45,18 +45,18 @@ generics.kt: # 27| 0: [MethodAccess] f2(...) # 27| -2: [TypeAccess] String # 27| -1: [VarAccess] c1 -# 27| 0: [StringLiteral] +# 27| 0: [StringLiteral] "" # 28| 3: [LocalVariableDeclStmt] var ...; # 28| 1: [LocalVariableDeclExpr] c2 # 28| 0: [ClassInstanceExpr] new C1(...) # 28| -3: [TypeAccess] C1 # 28| 0: [TypeAccess] String # 28| 1: [TypeAccess] Integer -# 28| 0: [StringLiteral] +# 28| 0: [StringLiteral] "" # 29| 4: [ExprStmt] ; # 29| 0: [MethodAccess] f1(...) # 29| -1: [VarAccess] c2 -# 29| 0: [StringLiteral] a +# 29| 0: [StringLiteral] "a" # 30| 5: [LocalVariableDeclStmt] var ...; # 30| 1: [LocalVariableDeclExpr] x2 # 30| 0: [MethodAccess] f2(...) @@ -256,4 +256,4 @@ generics.kt: # 61| -3: [TypeAccess] Local # 61| 0: [TypeAccess] Integer # 61| 0: [VarAccess] t -# 61| 1: [StringLiteral] +# 61| 1: [StringLiteral] "" diff --git a/java/ql/test/kotlin/library-tests/java-map-methods/PrintAst.expected b/java/ql/test/kotlin/library-tests/java-map-methods/PrintAst.expected index 978c4777b09..e356679e208 100644 --- a/java/ql/test/kotlin/library-tests/java-map-methods/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/java-map-methods/PrintAst.expected @@ -45,7 +45,7 @@ test.kt: # 9| 0: [ReturnStmt] return ... # 9| 0: [AddExpr] ... + ... # 9| 0: [VarAccess] s -# 9| 1: [StringLiteral] +# 9| 1: [StringLiteral] "" # 10| 5: [Method] fn2 # 10| 3: [TypeAccess] String #-----| 4: (Parameters) @@ -55,7 +55,7 @@ test.kt: # 10| 0: [ReturnStmt] return ... # 10| 0: [AddExpr] ... + ... # 10| 0: [VarAccess] s -# 10| 1: [StringLiteral] +# 10| 1: [StringLiteral] "" # 12| 6: [Method] fn1 # 12| 3: [TypeAccess] int #-----| 4: (Parameters) diff --git a/java/ql/test/kotlin/library-tests/jvmoverloads-annotation/PrintAst.expected b/java/ql/test/kotlin/library-tests/jvmoverloads-annotation/PrintAst.expected index 6dfd45e83f4..a1d0808d7a9 100644 --- a/java/ql/test/kotlin/library-tests/jvmoverloads-annotation/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/jvmoverloads-annotation/PrintAst.expected @@ -5,7 +5,7 @@ test.kt: # 1| 3: [TypeAccess] String # 1| 5: [BlockStmt] { ... } # 1| 0: [ReturnStmt] return ... -# 1| 0: [StringLiteral] Hello world +# 1| 0: [StringLiteral] "Hello world" # 45| 2: [ExtensionMethod] testExtensionFunction # 45| 3: [TypeAccess] int #-----| 4: (Parameters) @@ -929,7 +929,7 @@ test.kt: # 30| 1: [ExprStmt] ; # 30| 0: [AssignExpr] ...=... # 30| 0: [VarAccess] p2 -# 30| 1: [StringLiteral] Hello world +# 30| 1: [StringLiteral] "Hello world" # 30| 2: [ThisConstructorInvocationStmt] this(...) # 30| 0: [VarAccess] p0 # 30| 1: [VarAccess] p1 @@ -1024,7 +1024,7 @@ test.kt: # 33| 1: [ExprStmt] ; # 33| 0: [AssignExpr] ...=... # 33| 0: [VarAccess] p3 -# 33| 1: [StringLiteral] Hello world +# 33| 1: [StringLiteral] "Hello world" # 33| 2: [ReturnStmt] return ... # 33| 0: [MethodAccess] testMemberFunction(...) # 33| -1: [VarAccess] p0 @@ -1049,7 +1049,7 @@ test.kt: # 37| -1: [VarAccess] spec1 # 37| 0: [IntegerLiteral] 1 # 37| 1: [FloatLiteral] 1.0 -# 37| 2: [StringLiteral] Hello world +# 37| 2: [StringLiteral] "Hello world" # 37| 3: [FloatLiteral] 2.0 # 38| 1: [ExprStmt] ; # 38| 0: [ImplicitCoercionToUnitExpr] @@ -1058,5 +1058,5 @@ test.kt: # 38| -1: [VarAccess] spec2 # 38| 0: [IntegerLiteral] 1 # 38| 1: [DoubleLiteral] 1.0 -# 38| 2: [StringLiteral] Hello world +# 38| 2: [StringLiteral] "Hello world" # 38| 3: [DoubleLiteral] 2.0 diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected index 6386ec036fb..1db0b09adc0 100644 --- a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected @@ -81,13 +81,13 @@ test.kt: # 52| 0: [TypeAccess] Unit # 52| 1: [MethodAccess] staticMethod(...) # 52| -1: [VarAccess] Companion -# 52| 0: [StringLiteral] 1 +# 52| 0: [StringLiteral] "1" # 53| 1: [ExprStmt] ; # 53| 0: [ImplicitCoercionToUnitExpr] # 53| 0: [TypeAccess] Unit # 53| 1: [MethodAccess] nonStaticMethod(...) # 53| -1: [VarAccess] Companion -# 53| 0: [StringLiteral] 2 +# 53| 0: [StringLiteral] "2" # 54| 2: [ExprStmt] ; # 54| 0: [MethodAccess] setStaticProp(...) # 54| -1: [VarAccess] Companion @@ -113,13 +113,13 @@ test.kt: # 60| 0: [TypeAccess] Unit # 60| 1: [MethodAccess] staticMethod(...) # 60| -1: [TypeAccess] NonCompanion -# 60| 0: [StringLiteral] 1 +# 60| 0: [StringLiteral] "1" # 61| 7: [ExprStmt] ; # 61| 0: [ImplicitCoercionToUnitExpr] # 61| 0: [TypeAccess] Unit # 61| 1: [MethodAccess] nonStaticMethod(...) # 61| -1: [VarAccess] INSTANCE -# 61| 0: [StringLiteral] 2 +# 61| 0: [StringLiteral] "2" # 62| 8: [ExprStmt] ; # 62| 0: [MethodAccess] setStaticProp(...) # 62| -1: [TypeAccess] NonCompanion @@ -182,7 +182,7 @@ test.kt: # 14| 0: [VarAccess] s # 16| 4: [FieldDeclaration] String staticProp; # 16| -1: [TypeAccess] String -# 16| 0: [StringLiteral] a +# 16| 0: [StringLiteral] "a" # 16| 5: [Method] getStaticProp #-----| 1: (Annotations) # 16| 3: [TypeAccess] String @@ -204,7 +204,7 @@ test.kt: # 16| 1: [VarAccess] # 17| 7: [FieldDeclaration] String nonStaticProp; # 17| -1: [TypeAccess] String -# 17| 0: [StringLiteral] b +# 17| 0: [StringLiteral] "b" # 17| 8: [Method] getNonStaticProp #-----| 1: (Annotations) # 17| 3: [TypeAccess] String @@ -353,7 +353,7 @@ test.kt: # 34| 0: [VarAccess] s # 36| 5: [FieldDeclaration] String staticProp; # 36| -1: [TypeAccess] String -# 36| 0: [StringLiteral] a +# 36| 0: [StringLiteral] "a" # 36| 6: [Method] getStaticProp #-----| 1: (Annotations) # 36| 3: [TypeAccess] String @@ -377,7 +377,7 @@ test.kt: # 36| 1: [VarAccess] # 37| 8: [FieldDeclaration] String nonStaticProp; # 37| -1: [TypeAccess] String -# 37| 0: [StringLiteral] b +# 37| 0: [StringLiteral] "b" # 37| 9: [Method] getNonStaticProp #-----| 1: (Annotations) # 37| 3: [TypeAccess] String diff --git a/java/ql/test/kotlin/library-tests/lateinit/PrintAst.expected b/java/ql/test/kotlin/library-tests/lateinit/PrintAst.expected index c2119ec6123..9f482ab3b71 100644 --- a/java/ql/test/kotlin/library-tests/lateinit/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/lateinit/PrintAst.expected @@ -30,7 +30,7 @@ test.kt: # 4| 0: [ReturnStmt] return ... # 4| 0: [MethodAccess] println(...) # 4| -1: [TypeAccess] ConsoleKt -# 4| 0: [StringLiteral] a +# 4| 0: [StringLiteral] "a" # 6| 6: [Method] init # 6| 3: [TypeAccess] LateInit # 6| 5: [BlockStmt] { ... } diff --git a/java/ql/test/kotlin/library-tests/literals/literals.expected b/java/ql/test/kotlin/library-tests/literals/literals.expected index 86d23aa0d05..a22709ce194 100644 --- a/java/ql/test/kotlin/library-tests/literals/literals.expected +++ b/java/ql/test/kotlin/library-tests/literals/literals.expected @@ -23,7 +23,7 @@ | literals.kt:25:34:25:39 | -123.4 | DoubleLiteral | | literals.kt:26:30:26:32 | c | CharacterLiteral | | literals.kt:27:30:27:33 | \n | CharacterLiteral | -| literals.kt:28:34:28:35 | | StringLiteral | -| literals.kt:29:35:29:45 | Some string | StringLiteral | -| literals.kt:30:35:30:46 | Some\nstring | StringLiteral | +| literals.kt:28:34:28:35 | "" | StringLiteral | +| literals.kt:29:35:29:45 | "Some string" | StringLiteral | +| literals.kt:30:35:30:46 | "Some\\nstring" | StringLiteral | | literals.kt:31:30:31:33 | null | NullLiteral | diff --git a/java/ql/test/kotlin/library-tests/methods/exprs.expected b/java/ql/test/kotlin/library-tests/methods/exprs.expected index 76a48c189c4..6d2221b5bae 100644 --- a/java/ql/test/kotlin/library-tests/methods/exprs.expected +++ b/java/ql/test/kotlin/library-tests/methods/exprs.expected @@ -17,10 +17,13 @@ | dataClass.kt:0:0:0:0 | 1 | IntegerLiteral | | dataClass.kt:0:0:0:0 | 2 | IntegerLiteral | | dataClass.kt:0:0:0:0 | 31 | IntegerLiteral | +| dataClass.kt:0:0:0:0 | ")" | StringLiteral | +| dataClass.kt:0:0:0:0 | ", " | StringLiteral | | dataClass.kt:0:0:0:0 | "..." | StringTemplateExpr | +| dataClass.kt:0:0:0:0 | "DataClass(" | StringLiteral | +| dataClass.kt:0:0:0:0 | "x=" | StringLiteral | +| dataClass.kt:0:0:0:0 | "y=" | StringLiteral | | dataClass.kt:0:0:0:0 | (...)... | CastExpr | -| dataClass.kt:0:0:0:0 | ) | StringLiteral | -| dataClass.kt:0:0:0:0 | , | StringLiteral | | dataClass.kt:0:0:0:0 | ... !is ... | NotInstanceOfExpr | | dataClass.kt:0:0:0:0 | ... & ... | AndBitwiseExpr | | dataClass.kt:0:0:0:0 | ... & ... | AndBitwiseExpr | @@ -40,7 +43,6 @@ | dataClass.kt:0:0:0:0 | DataClass | TypeAccess | | dataClass.kt:0:0:0:0 | DataClass | TypeAccess | | dataClass.kt:0:0:0:0 | DataClass | TypeAccess | -| dataClass.kt:0:0:0:0 | DataClass( | StringLiteral | | dataClass.kt:0:0:0:0 | Object | TypeAccess | | dataClass.kt:0:0:0:0 | Object | TypeAccess | | dataClass.kt:0:0:0:0 | String | TypeAccess | @@ -105,9 +107,7 @@ | dataClass.kt:0:0:0:0 | when ... | WhenExpr | | dataClass.kt:0:0:0:0 | when ... | WhenExpr | | dataClass.kt:0:0:0:0 | x | VarAccess | -| dataClass.kt:0:0:0:0 | x= | StringLiteral | | dataClass.kt:0:0:0:0 | y | VarAccess | -| dataClass.kt:0:0:0:0 | y= | StringLiteral | | dataClass.kt:1:22:1:31 | ...=... | KtInitializerAssignExpr | | dataClass.kt:1:22:1:31 | int | TypeAccess | | dataClass.kt:1:22:1:31 | int | TypeAccess | @@ -204,7 +204,7 @@ | delegates.kt:8:35:11:5 | | VarAccess | | delegates.kt:8:35:11:5 | String | TypeAccess | | delegates.kt:8:35:11:5 | observable(...) | MethodAccess | -| delegates.kt:8:57:8:62 | | StringLiteral | +| delegates.kt:8:57:8:62 | "" | StringLiteral | | delegates.kt:8:66:11:5 | ...->... | LambdaExpr | | delegates.kt:8:66:11:5 | Function3,String,String,Unit> | TypeAccess | | delegates.kt:8:66:11:5 | KProperty | TypeAccess | @@ -219,9 +219,9 @@ | delegates.kt:10:9:10:37 | ConsoleKt | TypeAccess | | delegates.kt:10:9:10:37 | println(...) | MethodAccess | | delegates.kt:10:17:10:36 | "..." | StringTemplateExpr | -| delegates.kt:10:18:10:21 | Was | StringLiteral | +| delegates.kt:10:18:10:21 | "Was " | StringLiteral | | delegates.kt:10:23:10:25 | old | VarAccess | -| delegates.kt:10:26:10:31 | , now | StringLiteral | +| delegates.kt:10:26:10:31 | ", now " | StringLiteral | | delegates.kt:10:33:10:35 | new | VarAccess | | enumClass.kt:0:0:0:0 | EnumClass | TypeAccess | | enumClass.kt:0:0:0:0 | EnumClass | TypeAccess | diff --git a/java/ql/test/kotlin/library-tests/operator-overloads/PrintAst.expected b/java/ql/test/kotlin/library-tests/operator-overloads/PrintAst.expected index af62c3e412e..46fd70318ad 100644 --- a/java/ql/test/kotlin/library-tests/operator-overloads/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/operator-overloads/PrintAst.expected @@ -59,7 +59,7 @@ test.kt: # 10| 0: [TypeAccess] int # 10| 5: [BlockStmt] { ... } # 10| 0: [ReturnStmt] return ... -# 10| 0: [StringLiteral] +# 10| 0: [StringLiteral] "" # 11| 3: [ExtensionMethod] set # 11| 3: [TypeAccess] String #-----| 4: (Parameters) @@ -73,7 +73,7 @@ test.kt: # 11| 0: [TypeAccess] int # 11| 5: [BlockStmt] { ... } # 11| 0: [ReturnStmt] return ... -# 11| 0: [StringLiteral] +# 11| 0: [StringLiteral] "" # 12| 4: [ExtensionMethod] set # 12| 3: [TypeAccess] String #-----| 4: (Parameters) @@ -85,7 +85,7 @@ test.kt: # 12| 0: [TypeAccess] C # 12| 5: [BlockStmt] { ... } # 12| 0: [ReturnStmt] return ... -# 12| 0: [StringLiteral] +# 12| 0: [StringLiteral] "" # 15| 2: [Class] C # 15| 1: [Constructor] C # 15| 5: [BlockStmt] { ... } @@ -100,4 +100,4 @@ test.kt: # 16| 0: [TypeAccess] int # 16| 5: [BlockStmt] { ... } # 16| 0: [ReturnStmt] return ... -# 16| 0: [StringLiteral] +# 16| 0: [StringLiteral] "" diff --git a/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected b/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected index a769bc397ee..972e826cdca 100644 --- a/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected @@ -56,7 +56,7 @@ test.kt: # 184| 1: [ExprStmt] ; # 184| 0: [AssignExpr] ...=... # 184| 0: [VarAccess] p0 -# 184| 1: [StringLiteral] before-vararg-default sunk +# 184| 1: [StringLiteral] "before-vararg-default sunk" # 184| 1: [IfStmt] if (...) # 184| 0: [EQExpr] ... == ... # 184| 0: [AndBitwiseExpr] ... & ... @@ -68,8 +68,8 @@ test.kt: # 184| 0: [VarAccess] p1 # 184| 1: [ArrayCreationExpr] new String[] # 184| -2: [ArrayInit] {...} -# 184| 0: [StringLiteral] first-vararg-default sunk -# 184| 1: [StringLiteral] second-vararg-default sunk +# 184| 0: [StringLiteral] "first-vararg-default sunk" +# 184| 1: [StringLiteral] "second-vararg-default sunk" # 184| -1: [TypeAccess] String # 184| 0: [IntegerLiteral] 2 # 184| 2: [IfStmt] if (...) @@ -81,7 +81,7 @@ test.kt: # 184| 1: [ExprStmt] ; # 184| 0: [AssignExpr] ...=... # 184| 0: [VarAccess] p2 -# 184| 1: [StringLiteral] after-vararg-default sunk +# 184| 1: [StringLiteral] "after-vararg-default sunk" # 184| 3: [ReturnStmt] return ... # 184| 0: [MethodAccess] varargsTest(...) # 184| -1: [TypeAccess] TestKt @@ -102,7 +102,7 @@ test.kt: # 192| 1: [ExprStmt] ; # 192| 0: [MethodAccess] varargsTest$default(...) # 192| -1: [TypeAccess] TestKt -# 192| 0: [StringLiteral] no-varargs-before, no-z-parameter sunk +# 192| 0: [StringLiteral] "no-varargs-before, no-z-parameter sunk" # 1| 1: [NullLiteral] null # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 1 @@ -110,32 +110,32 @@ test.kt: # 193| 2: [ExprStmt] ; # 193| 0: [MethodAccess] varargsTest$default(...) # 193| -1: [TypeAccess] TestKt -# 193| 0: [StringLiteral] no-varargs-before sunk +# 193| 0: [StringLiteral] "no-varargs-before sunk" # 1| 1: [NullLiteral] null -# 193| 2: [StringLiteral] no-varargs-after sunk +# 193| 2: [StringLiteral] "no-varargs-after sunk" # 1| 3: [IntegerLiteral] 5 # 1| 4: [NullLiteral] null # 194| 3: [ExprStmt] ; # 194| 0: [MethodAccess] varargsTest(...) # 194| -1: [TypeAccess] TestKt -# 194| 0: [StringLiteral] one-vararg-before sunk -# 194| 1: [StringLiteral] one-vararg sunk -# 194| 2: [StringLiteral] one-vararg-after sunk +# 194| 0: [StringLiteral] "one-vararg-before sunk" +# 194| 1: [StringLiteral] "one-vararg sunk" +# 194| 2: [StringLiteral] "one-vararg-after sunk" # 195| 4: [ExprStmt] ; # 195| 0: [MethodAccess] varargsTest(...) # 195| -1: [TypeAccess] TestKt -# 195| 0: [StringLiteral] two-varargs-before sunk -# 195| 1: [StringLiteral] two-vararg-first sunk -# 195| 2: [StringLiteral] two-vararg-second sunk -# 195| 3: [StringLiteral] two-varargs-after sunk +# 195| 0: [StringLiteral] "two-varargs-before sunk" +# 195| 1: [StringLiteral] "two-vararg-first sunk" +# 195| 2: [StringLiteral] "two-vararg-second sunk" +# 195| 3: [StringLiteral] "two-varargs-after sunk" # 196| 5: [ExprStmt] ; # 196| 0: [MethodAccess] varargsTest$default(...) # 196| -1: [TypeAccess] TestKt -# 196| 0: [StringLiteral] no-z-parmeter sunk +# 196| 0: [StringLiteral] "no-z-parmeter sunk" # 196| 1: [ArrayCreationExpr] new String[] # 196| -2: [ArrayInit] {...} -# 196| 0: [StringLiteral] no-z-parameter first vararg sunk -# 196| 1: [StringLiteral] no-z-parameter second vararg sunk +# 196| 0: [StringLiteral] "no-z-parameter first vararg sunk" +# 196| 1: [StringLiteral] "no-z-parameter second vararg sunk" # 196| -1: [TypeAccess] String # 196| 0: [IntegerLiteral] 2 # 1| 2: [NullLiteral] null @@ -182,7 +182,7 @@ test.kt: # 199| 1: [ExprStmt] ; # 199| 0: [AssignExpr] ...=... # 199| 0: [VarAccess] p0 -# 199| 1: [StringLiteral] before-vararg-default not sunk 2 +# 199| 1: [StringLiteral] "before-vararg-default not sunk 2" # 199| 1: [IfStmt] if (...) # 199| 0: [EQExpr] ... == ... # 199| 0: [AndBitwiseExpr] ... & ... @@ -194,8 +194,8 @@ test.kt: # 199| 0: [VarAccess] p1 # 199| 1: [ArrayCreationExpr] new String[] # 199| -2: [ArrayInit] {...} -# 199| 0: [StringLiteral] first-vararg-default sunk 2 -# 199| 1: [StringLiteral] second-vararg-default sunk 2 +# 199| 0: [StringLiteral] "first-vararg-default sunk 2" +# 199| 1: [StringLiteral] "second-vararg-default sunk 2" # 199| -1: [TypeAccess] String # 199| 0: [IntegerLiteral] 2 # 199| 2: [IfStmt] if (...) @@ -207,7 +207,7 @@ test.kt: # 199| 1: [ExprStmt] ; # 199| 0: [AssignExpr] ...=... # 199| 0: [VarAccess] p2 -# 199| 1: [StringLiteral] after-vararg-default not sunk 2 +# 199| 1: [StringLiteral] "after-vararg-default not sunk 2" # 199| 3: [ReturnStmt] return ... # 199| 0: [MethodAccess] varargsTestOnlySinkVarargs(...) # 199| -1: [TypeAccess] TestKt @@ -228,7 +228,7 @@ test.kt: # 205| 1: [ExprStmt] ; # 205| 0: [MethodAccess] varargsTestOnlySinkVarargs$default(...) # 205| -1: [TypeAccess] TestKt -# 205| 0: [StringLiteral] no-varargs-before, no-z-parameter not sunk 2 +# 205| 0: [StringLiteral] "no-varargs-before, no-z-parameter not sunk 2" # 1| 1: [NullLiteral] null # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 1 @@ -236,32 +236,32 @@ test.kt: # 206| 2: [ExprStmt] ; # 206| 0: [MethodAccess] varargsTestOnlySinkVarargs$default(...) # 206| -1: [TypeAccess] TestKt -# 206| 0: [StringLiteral] no-varargs-before not sunk 2 +# 206| 0: [StringLiteral] "no-varargs-before not sunk 2" # 1| 1: [NullLiteral] null -# 206| 2: [StringLiteral] no-varargs-after not sunk 2 +# 206| 2: [StringLiteral] "no-varargs-after not sunk 2" # 1| 3: [IntegerLiteral] 5 # 1| 4: [NullLiteral] null # 207| 3: [ExprStmt] ; # 207| 0: [MethodAccess] varargsTestOnlySinkVarargs(...) # 207| -1: [TypeAccess] TestKt -# 207| 0: [StringLiteral] one-vararg-before not sunk 2 -# 207| 1: [StringLiteral] one-vararg sunk 2 -# 207| 2: [StringLiteral] one-vararg-after not sunk 2 +# 207| 0: [StringLiteral] "one-vararg-before not sunk 2" +# 207| 1: [StringLiteral] "one-vararg sunk 2" +# 207| 2: [StringLiteral] "one-vararg-after not sunk 2" # 208| 4: [ExprStmt] ; # 208| 0: [MethodAccess] varargsTestOnlySinkVarargs(...) # 208| -1: [TypeAccess] TestKt -# 208| 0: [StringLiteral] two-varargs-before not sunk 2 -# 208| 1: [StringLiteral] two-vararg-first sunk 2 -# 208| 2: [StringLiteral] two-vararg-second sunk 2 -# 208| 3: [StringLiteral] two-varargs-after not sunk 2 +# 208| 0: [StringLiteral] "two-varargs-before not sunk 2" +# 208| 1: [StringLiteral] "two-vararg-first sunk 2" +# 208| 2: [StringLiteral] "two-vararg-second sunk 2" +# 208| 3: [StringLiteral] "two-varargs-after not sunk 2" # 209| 5: [ExprStmt] ; # 209| 0: [MethodAccess] varargsTestOnlySinkVarargs$default(...) # 209| -1: [TypeAccess] TestKt -# 209| 0: [StringLiteral] no-z-parmeter not sunk 2 +# 209| 0: [StringLiteral] "no-z-parmeter not sunk 2" # 209| 1: [ArrayCreationExpr] new String[] # 209| -2: [ArrayInit] {...} -# 209| 0: [StringLiteral] no-z-parameter first vararg sunk 2 -# 209| 1: [StringLiteral] no-z-parameter second vararg sunk 2 +# 209| 0: [StringLiteral] "no-z-parameter first vararg sunk 2" +# 209| 1: [StringLiteral] "no-z-parameter second vararg sunk 2" # 209| -1: [TypeAccess] String # 209| 0: [IntegerLiteral] 2 # 1| 2: [NullLiteral] null @@ -310,7 +310,7 @@ test.kt: # 212| 1: [ExprStmt] ; # 212| 0: [AssignExpr] ...=... # 212| 0: [VarAccess] p0 -# 212| 1: [StringLiteral] before-vararg-default sunk 3 +# 212| 1: [StringLiteral] "before-vararg-default sunk 3" # 212| 1: [IfStmt] if (...) # 212| 0: [EQExpr] ... == ... # 212| 0: [AndBitwiseExpr] ... & ... @@ -322,8 +322,8 @@ test.kt: # 212| 0: [VarAccess] p1 # 212| 1: [ArrayCreationExpr] new String[] # 212| -2: [ArrayInit] {...} -# 212| 0: [StringLiteral] first-vararg-default not sunk 3 -# 212| 1: [StringLiteral] second-vararg-default not sunk 3 +# 212| 0: [StringLiteral] "first-vararg-default not sunk 3" +# 212| 1: [StringLiteral] "second-vararg-default not sunk 3" # 212| -1: [TypeAccess] String # 212| 0: [IntegerLiteral] 2 # 212| 2: [IfStmt] if (...) @@ -335,7 +335,7 @@ test.kt: # 212| 1: [ExprStmt] ; # 212| 0: [AssignExpr] ...=... # 212| 0: [VarAccess] p2 -# 212| 1: [StringLiteral] after-vararg-default sunk 3 +# 212| 1: [StringLiteral] "after-vararg-default sunk 3" # 212| 3: [ReturnStmt] return ... # 212| 0: [MethodAccess] varargsTestOnlySinkRegularArgs(...) # 212| -1: [TypeAccess] TestKt @@ -356,7 +356,7 @@ test.kt: # 219| 1: [ExprStmt] ; # 219| 0: [MethodAccess] varargsTestOnlySinkRegularArgs$default(...) # 219| -1: [TypeAccess] TestKt -# 219| 0: [StringLiteral] no-varargs-before, no-z-parameter sunk 3 +# 219| 0: [StringLiteral] "no-varargs-before, no-z-parameter sunk 3" # 1| 1: [NullLiteral] null # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 1 @@ -364,32 +364,32 @@ test.kt: # 220| 2: [ExprStmt] ; # 220| 0: [MethodAccess] varargsTestOnlySinkRegularArgs$default(...) # 220| -1: [TypeAccess] TestKt -# 220| 0: [StringLiteral] no-varargs-before sunk 3 +# 220| 0: [StringLiteral] "no-varargs-before sunk 3" # 1| 1: [NullLiteral] null -# 220| 2: [StringLiteral] no-varargs-after sunk 3 +# 220| 2: [StringLiteral] "no-varargs-after sunk 3" # 1| 3: [IntegerLiteral] 5 # 1| 4: [NullLiteral] null # 221| 3: [ExprStmt] ; # 221| 0: [MethodAccess] varargsTestOnlySinkRegularArgs(...) # 221| -1: [TypeAccess] TestKt -# 221| 0: [StringLiteral] one-vararg-before sunk 3 -# 221| 1: [StringLiteral] one-vararg not sunk 3 -# 221| 2: [StringLiteral] one-vararg-after sunk 3 +# 221| 0: [StringLiteral] "one-vararg-before sunk 3" +# 221| 1: [StringLiteral] "one-vararg not sunk 3" +# 221| 2: [StringLiteral] "one-vararg-after sunk 3" # 222| 4: [ExprStmt] ; # 222| 0: [MethodAccess] varargsTestOnlySinkRegularArgs(...) # 222| -1: [TypeAccess] TestKt -# 222| 0: [StringLiteral] two-varargs-before sunk 3 -# 222| 1: [StringLiteral] two-vararg-first not sunk 3 -# 222| 2: [StringLiteral] two-vararg-second not sunk 3 -# 222| 3: [StringLiteral] two-varargs-after sunk 3 +# 222| 0: [StringLiteral] "two-varargs-before sunk 3" +# 222| 1: [StringLiteral] "two-vararg-first not sunk 3" +# 222| 2: [StringLiteral] "two-vararg-second not sunk 3" +# 222| 3: [StringLiteral] "two-varargs-after sunk 3" # 223| 5: [ExprStmt] ; # 223| 0: [MethodAccess] varargsTestOnlySinkRegularArgs$default(...) # 223| -1: [TypeAccess] TestKt -# 223| 0: [StringLiteral] no-z-parmeter sunk 3 +# 223| 0: [StringLiteral] "no-z-parmeter sunk 3" # 223| 1: [ArrayCreationExpr] new String[] # 223| -2: [ArrayInit] {...} -# 223| 0: [StringLiteral] no-z-parameter first vararg not sunk 3 -# 223| 1: [StringLiteral] no-z-parameter second vararg not sunk 3 +# 223| 0: [StringLiteral] "no-z-parameter first vararg not sunk 3" +# 223| 1: [StringLiteral] "no-z-parameter second vararg not sunk 3" # 223| -1: [TypeAccess] String # 223| 0: [IntegerLiteral] 2 # 1| 2: [NullLiteral] null @@ -403,15 +403,15 @@ test.kt: # 233| 0: [TypeAccess] Unit # 233| 1: [ClassInstanceExpr] new VarargsConstructorTest(...) # 233| -3: [TypeAccess] VarargsConstructorTest -# 233| 0: [StringLiteral] varargs constructor test sunk +# 233| 0: [StringLiteral] "varargs constructor test sunk" # 234| 1: [ExprStmt] ; # 234| 0: [ImplicitCoercionToUnitExpr] # 234| 0: [TypeAccess] Unit # 234| 1: [ClassInstanceExpr] new VarargsConstructorTest(...) # 234| -3: [TypeAccess] VarargsConstructorTest -# 234| 0: [StringLiteral] varargs constructor test sunk 2 -# 234| 1: [StringLiteral] varargs constructor test not sunk 1 -# 234| 2: [StringLiteral] varargs constructor test not sunk 2 +# 234| 0: [StringLiteral] "varargs constructor test sunk 2" +# 234| 1: [StringLiteral] "varargs constructor test not sunk 1" +# 234| 2: [StringLiteral] "varargs constructor test not sunk 2" # 3| 2: [Class] TestMember # 3| 1: [Constructor] TestMember # 3| 5: [BlockStmt] { ... } @@ -466,7 +466,7 @@ test.kt: # 5| 1: [ExprStmt] ; # 5| 0: [AssignExpr] ...=... # 5| 0: [VarAccess] p3 -# 5| 1: [StringLiteral] hello world +# 5| 1: [StringLiteral] "hello world" # 5| 2: [ReturnStmt] return ... # 5| 0: [MethodAccess] f(...) # 5| -1: [VarAccess] p0 @@ -480,7 +480,7 @@ test.kt: # 10| 0: [MethodAccess] f$default(...) # 10| -1: [TypeAccess] TestMember # 10| 0: [ThisAccess] this -# 10| 1: [StringLiteral] member sunk +# 10| 1: [StringLiteral] "member sunk" # 1| 2: [NullLiteral] null # 1| 3: [NullLiteral] null # 1| 4: [IntegerLiteral] 1 @@ -489,17 +489,17 @@ test.kt: # 11| 0: [MethodAccess] f$default(...) # 11| -1: [TypeAccess] TestMember # 11| 0: [ThisAccess] this -# 11| 1: [StringLiteral] member sunk fp -# 11| 2: [StringLiteral] member sunk 2 +# 11| 1: [StringLiteral] "member sunk fp" +# 11| 2: [StringLiteral] "member sunk 2" # 1| 3: [NullLiteral] null # 1| 4: [IntegerLiteral] 3 # 1| 5: [NullLiteral] null # 12| 2: [ExprStmt] ; # 12| 0: [MethodAccess] f(...) # 12| -1: [ThisAccess] this -# 12| 0: [StringLiteral] not sunk -# 12| 1: [StringLiteral] member sunk 3 -# 12| 2: [StringLiteral] not sunk +# 12| 0: [StringLiteral] "not sunk" +# 12| 1: [StringLiteral] "member sunk 3" +# 12| 2: [StringLiteral] "not sunk" # 17| 3: [Class] TestExtensionMember # 17| 1: [Constructor] TestExtensionMember # 17| 5: [BlockStmt] { ... } @@ -562,7 +562,7 @@ test.kt: # 19| 1: [ExprStmt] ; # 19| 0: [AssignExpr] ...=... # 19| 0: [VarAccess] p4 -# 19| 1: [StringLiteral] hello world +# 19| 1: [StringLiteral] "hello world" # 19| 2: [ReturnStmt] return ... # 19| 0: [MethodAccess] f(...) # 19| -1: [VarAccess] p1 @@ -581,7 +581,7 @@ test.kt: # 25| -1: [TypeAccess] TestExtensionMember # 25| 0: [VarAccess] sunk # 25| 1: [ThisAccess] this -# 25| 2: [StringLiteral] extension sunk +# 25| 2: [StringLiteral] "extension sunk" # 1| 3: [NullLiteral] null # 1| 4: [NullLiteral] null # 1| 5: [IntegerLiteral] 1 @@ -591,8 +591,8 @@ test.kt: # 26| -1: [TypeAccess] TestExtensionMember # 26| 0: [VarAccess] sunk # 26| 1: [ThisAccess] this -# 26| 2: [StringLiteral] extension sunk fp -# 26| 3: [StringLiteral] extension sunk 2 +# 26| 2: [StringLiteral] "extension sunk fp" +# 26| 3: [StringLiteral] "extension sunk 2" # 1| 4: [NullLiteral] null # 1| 5: [IntegerLiteral] 3 # 1| 6: [NullLiteral] null @@ -600,9 +600,9 @@ test.kt: # 27| 0: [MethodAccess] f(...) # 27| -1: [ThisAccess] this # 27| 0: [VarAccess] sunk -# 27| 1: [StringLiteral] not sunk -# 27| 2: [StringLiteral] extension sunk 3 -# 27| 3: [StringLiteral] not sunk +# 27| 1: [StringLiteral] "not sunk" +# 27| 2: [StringLiteral] "extension sunk 3" +# 27| 3: [StringLiteral] "not sunk" # 32| 4: [Class] TestStaticMember # 32| 1: [Constructor] TestStaticMember # 32| 5: [BlockStmt] { ... } @@ -655,7 +655,7 @@ test.kt: # 34| 1: [ExprStmt] ; # 34| 0: [AssignExpr] ...=... # 34| 0: [VarAccess] p2 -# 34| 1: [StringLiteral] hello world +# 34| 1: [StringLiteral] "hello world" # 34| 2: [ReturnStmt] return ... # 34| 0: [MethodAccess] f(...) # 34| -1: [TypeAccess] TestStaticMember @@ -668,7 +668,7 @@ test.kt: # 39| 0: [ExprStmt] ; # 39| 0: [MethodAccess] f$default(...) # 39| -1: [TypeAccess] TestStaticMember -# 39| 0: [StringLiteral] static sunk +# 39| 0: [StringLiteral] "static sunk" # 1| 1: [NullLiteral] null # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 1 @@ -676,17 +676,17 @@ test.kt: # 40| 1: [ExprStmt] ; # 40| 0: [MethodAccess] f$default(...) # 40| -1: [TypeAccess] TestStaticMember -# 40| 0: [StringLiteral] static sunk fp -# 40| 1: [StringLiteral] static sunk 2 +# 40| 0: [StringLiteral] "static sunk fp" +# 40| 1: [StringLiteral] "static sunk 2" # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 3 # 1| 4: [NullLiteral] null # 41| 2: [ExprStmt] ; # 41| 0: [MethodAccess] f(...) # 41| -1: [TypeAccess] TestStaticMember -# 41| 0: [StringLiteral] not sunk -# 41| 1: [StringLiteral] static sunk 3 -# 41| 2: [StringLiteral] not sunk +# 41| 0: [StringLiteral] "not sunk" +# 41| 1: [StringLiteral] "static sunk 3" +# 41| 2: [StringLiteral] "not sunk" # 46| 5: [Class] ExtendMe # 46| 1: [Constructor] ExtendMe # 46| 5: [BlockStmt] { ... } @@ -770,7 +770,7 @@ test.kt: # 56| 1: [ExprStmt] ; # 56| 0: [AssignExpr] ...=... # 56| 0: [VarAccess] p4 -# 56| 1: [StringLiteral] hello world +# 56| 1: [StringLiteral] "hello world" # 56| 2: [ReturnStmt] return ... # 56| 0: [MethodAccess] test(...) # 56| -1: [VarAccess] p1 @@ -789,7 +789,7 @@ test.kt: # 61| -1: [TypeAccess] TestReceiverReferences # 61| 0: [VarAccess] t # 61| 1: [ThisAccess] this -# 61| 2: [StringLiteral] receiver refs sunk +# 61| 2: [StringLiteral] "receiver refs sunk" # 1| 3: [NullLiteral] null # 1| 4: [NullLiteral] null # 1| 5: [IntegerLiteral] 1 @@ -799,8 +799,8 @@ test.kt: # 62| -1: [TypeAccess] TestReceiverReferences # 62| 0: [VarAccess] t # 62| 1: [ThisAccess] this -# 62| 2: [StringLiteral] receiver refs sunk fp -# 62| 3: [StringLiteral] receiver refs sunk 2 +# 62| 2: [StringLiteral] "receiver refs sunk fp" +# 62| 3: [StringLiteral] "receiver refs sunk 2" # 1| 4: [NullLiteral] null # 1| 5: [IntegerLiteral] 3 # 1| 6: [NullLiteral] null @@ -808,9 +808,9 @@ test.kt: # 63| 0: [MethodAccess] test(...) # 63| -1: [ThisAccess] this # 63| 0: [VarAccess] t -# 63| 1: [StringLiteral] not sunk -# 63| 2: [StringLiteral] receiver refs sunk 3 -# 63| 3: [StringLiteral] not sunk +# 63| 1: [StringLiteral] "not sunk" +# 63| 2: [StringLiteral] "receiver refs sunk 3" +# 63| 3: [StringLiteral] "not sunk" # 68| 7: [Class] TestConstructor # 68| 1: [Constructor] TestConstructor #-----| 4: (Parameters) @@ -859,7 +859,7 @@ test.kt: # 68| 1: [ExprStmt] ; # 68| 0: [AssignExpr] ...=... # 68| 0: [VarAccess] p2 -# 68| 1: [StringLiteral] hello world +# 68| 1: [StringLiteral] "hello world" # 68| 2: [ThisConstructorInvocationStmt] this(...) # 68| 0: [VarAccess] p0 # 68| 1: [VarAccess] p1 @@ -872,7 +872,7 @@ test.kt: # 75| 0: [TypeAccess] Unit # 75| 1: [ClassInstanceExpr] new TestConstructor(...) # 75| -3: [TypeAccess] TestConstructor -# 75| 0: [StringLiteral] constructor sunk +# 75| 0: [StringLiteral] "constructor sunk" # 1| 1: [NullLiteral] null # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 1 @@ -882,8 +882,8 @@ test.kt: # 76| 0: [TypeAccess] Unit # 76| 1: [ClassInstanceExpr] new TestConstructor(...) # 76| -3: [TypeAccess] TestConstructor -# 76| 0: [StringLiteral] constructor sunk fp -# 76| 1: [StringLiteral] constructor sunk 2 +# 76| 0: [StringLiteral] "constructor sunk fp" +# 76| 1: [StringLiteral] "constructor sunk 2" # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 3 # 1| 4: [NullLiteral] null @@ -892,9 +892,9 @@ test.kt: # 77| 0: [TypeAccess] Unit # 77| 1: [ClassInstanceExpr] new TestConstructor(...) # 77| -3: [TypeAccess] TestConstructor -# 77| 0: [StringLiteral] not sunk -# 77| 1: [StringLiteral] constructor sunk 3 -# 77| 2: [StringLiteral] not sunk +# 77| 0: [StringLiteral] "not sunk" +# 77| 1: [StringLiteral] "constructor sunk 3" +# 77| 2: [StringLiteral] "not sunk" # 82| 8: [Class] TestLocal # 82| 1: [Constructor] TestLocal # 82| 5: [BlockStmt] { ... } @@ -955,7 +955,7 @@ test.kt: # 86| 1: [ExprStmt] ; # 86| 0: [AssignExpr] ...=... # 86| 0: [VarAccess] p2 -# 86| 1: [StringLiteral] hello world +# 86| 1: [StringLiteral] "hello world" # 86| 2: [ReturnStmt] return ... # 86| 0: [MethodAccess] f(...) # 86| -1: [ClassInstanceExpr] new (...) @@ -974,7 +974,7 @@ test.kt: # 91| 0: [ExprStmt] ; # 91| 0: [MethodAccess] f$default(...) # 91| -1: [TypeAccess] -# 91| 0: [StringLiteral] local sunk +# 91| 0: [StringLiteral] "local sunk" # 1| 1: [NullLiteral] null # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 1 @@ -982,8 +982,8 @@ test.kt: # 92| 1: [ExprStmt] ; # 92| 0: [MethodAccess] f$default(...) # 92| -1: [TypeAccess] -# 92| 0: [StringLiteral] local sunk fp -# 92| 1: [StringLiteral] local sunk 2 +# 92| 0: [StringLiteral] "local sunk fp" +# 92| 1: [StringLiteral] "local sunk 2" # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 3 # 1| 4: [NullLiteral] null @@ -991,9 +991,9 @@ test.kt: # 93| 0: [MethodAccess] f(...) # 93| -1: [ClassInstanceExpr] new (...) # 93| -3: [TypeAccess] Object -# 93| 0: [StringLiteral] not sunk -# 93| 1: [StringLiteral] local sunk 3 -# 93| 2: [StringLiteral] not sunk +# 93| 0: [StringLiteral] "not sunk" +# 93| 1: [StringLiteral] "local sunk 3" +# 93| 2: [StringLiteral] "not sunk" # 100| 9: [Class] TestLocalClass # 100| 1: [Constructor] TestLocalClass # 100| 5: [BlockStmt] { ... } @@ -1057,7 +1057,7 @@ test.kt: # 106| 1: [ExprStmt] ; # 106| 0: [AssignExpr] ...=... # 106| 0: [VarAccess] p3 -# 106| 1: [StringLiteral] hello world +# 106| 1: [StringLiteral] "hello world" # 106| 2: [ReturnStmt] return ... # 106| 0: [MethodAccess] f(...) # 106| -1: [VarAccess] p0 @@ -1071,7 +1071,7 @@ test.kt: # 111| 0: [MethodAccess] f$default(...) # 111| -1: [TypeAccess] EnclosingLocalClass # 111| 0: [ThisAccess] this -# 111| 1: [StringLiteral] local sunk +# 111| 1: [StringLiteral] "local sunk" # 1| 2: [NullLiteral] null # 1| 3: [NullLiteral] null # 1| 4: [IntegerLiteral] 1 @@ -1080,17 +1080,17 @@ test.kt: # 112| 0: [MethodAccess] f$default(...) # 112| -1: [TypeAccess] EnclosingLocalClass # 112| 0: [ThisAccess] this -# 112| 1: [StringLiteral] local sunk fp -# 112| 2: [StringLiteral] local sunk 2 +# 112| 1: [StringLiteral] "local sunk fp" +# 112| 2: [StringLiteral] "local sunk 2" # 1| 3: [NullLiteral] null # 1| 4: [IntegerLiteral] 3 # 1| 5: [NullLiteral] null # 113| 2: [ExprStmt] ; # 113| 0: [MethodAccess] f(...) # 113| -1: [ThisAccess] this -# 113| 0: [StringLiteral] not sunk -# 113| 1: [StringLiteral] local sunk 3 -# 113| 2: [StringLiteral] not sunk +# 113| 0: [StringLiteral] "not sunk" +# 113| 1: [StringLiteral] "local sunk 3" +# 113| 2: [StringLiteral] "not sunk" # 122| 10: [Class,GenericType,ParameterizedType] TestGeneric #-----| -2: (Generic Parameters) # 122| 0: [TypeVariable] T @@ -1168,7 +1168,7 @@ test.kt: # 129| 0: [MethodAccess] f$default(...) # 129| -1: [TypeAccess] TestGeneric<> # 129| 0: [VarAccess] tgs -# 129| 1: [StringLiteral] generic sunk +# 129| 1: [StringLiteral] "generic sunk" # 1| 2: [NullLiteral] null # 1| 3: [NullLiteral] null # 1| 4: [IntegerLiteral] 1 @@ -1177,23 +1177,23 @@ test.kt: # 130| 0: [MethodAccess] f$default(...) # 130| -1: [TypeAccess] TestGeneric<> # 130| 0: [VarAccess] tcs -# 130| 1: [StringLiteral] generic sunk fp -# 130| 2: [StringLiteral] generic sunk 2 +# 130| 1: [StringLiteral] "generic sunk fp" +# 130| 2: [StringLiteral] "generic sunk 2" # 1| 3: [NullLiteral] null # 1| 4: [IntegerLiteral] 3 # 1| 5: [NullLiteral] null # 131| 2: [ExprStmt] ; # 131| 0: [MethodAccess] f(...) # 131| -1: [VarAccess] tgs -# 131| 0: [StringLiteral] not sunk -# 131| 1: [StringLiteral] generic sunk 3 -# 131| 2: [StringLiteral] not sunk +# 131| 0: [StringLiteral] "not sunk" +# 131| 1: [StringLiteral] "generic sunk 3" +# 131| 2: [StringLiteral] "not sunk" # 132| 3: [ExprStmt] ; # 132| 0: [MethodAccess] f(...) # 132| -1: [VarAccess] tcs -# 132| 0: [StringLiteral] not sunk -# 132| 1: [StringLiteral] generic sunk 3 -# 132| 2: [StringLiteral] not sunk +# 132| 0: [StringLiteral] "not sunk" +# 132| 1: [StringLiteral] "generic sunk 3" +# 132| 2: [StringLiteral] "not sunk" # 135| 5: [Method] testReturn # 135| 3: [TypeAccess] T #-----| 4: (Parameters) @@ -1246,7 +1246,7 @@ test.kt: # 138| 0: [MethodAccess] testReturn$default(...) # 138| -1: [TypeAccess] TestGeneric<> # 138| 0: [VarAccess] tgs -# 138| 1: [StringLiteral] sunk return value +# 138| 1: [StringLiteral] "sunk return value" # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 1 # 1| 4: [NullLiteral] null @@ -1381,7 +1381,7 @@ test.kt: # 150| 0: [MethodAccess] f$default(...) # 150| -1: [TypeAccess] TestGenericFunction<> # 150| 0: [VarAccess] inst -# 150| 1: [StringLiteral] generic function sunk +# 150| 1: [StringLiteral] "generic function sunk" # 1| 2: [NullLiteral] null # 1| 3: [NullLiteral] null # 1| 4: [NullLiteral] null @@ -1393,8 +1393,8 @@ test.kt: # 151| 0: [MethodAccess] f$default(...) # 151| -1: [TypeAccess] TestGenericFunction<> # 151| 0: [VarAccess] inst -# 151| 1: [StringLiteral] generic function sunk fp -# 151| 2: [StringLiteral] generic function sunk 2 +# 151| 1: [StringLiteral] "generic function sunk fp" +# 151| 2: [StringLiteral] "generic function sunk 2" # 1| 3: [NullLiteral] null # 1| 4: [NullLiteral] null # 1| 5: [NullLiteral] null @@ -1612,7 +1612,7 @@ test.kt: # 171| -1: [ClassInstanceExpr] new TestGenericUsedWithinDefaultValue(...) # 171| -3: [TypeAccess] TestGenericUsedWithinDefaultValue # 171| 0: [TypeAccess] String -# 171| 0: [StringLiteral] Hello world +# 171| 0: [StringLiteral] "Hello world" # 171| 1: [ReturnStmt] return ... # 171| 0: [MethodAccess] f(...) # 171| -1: [VarAccess] p0 @@ -1662,7 +1662,7 @@ test.kt: # 179| 1: [ExprStmt] ; # 179| 0: [AssignExpr] ...=... # 179| 0: [VarAccess] p2 -# 179| 1: [StringLiteral] Hello world +# 179| 1: [StringLiteral] "Hello world" # 179| 1: [ReturnStmt] return ... # 179| 0: [MethodAccess] f(...) # 179| -1: [VarAccess] p0 diff --git a/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected b/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected index 64fffd47586..c46be5c7900 100644 --- a/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected @@ -45,7 +45,7 @@ reflection.kt: # 50| -3: [TypeAccess] KProperty1 # 50| 0: [TypeAccess] String # 50| 1: [TypeAccess] Character -# 50| 0: [StringLiteral] abc +# 50| 0: [StringLiteral] "abc" # 51| 1: [ExprStmt] ; # 51| 0: [MethodAccess] println(...) # 51| -1: [TypeAccess] ConsoleKt @@ -78,7 +78,7 @@ reflection.kt: # 51| -1: [ThisAccess] this # 51| -3: [TypeAccess] KProperty0 # 51| 0: [TypeAccess] Character -# 51| 0: [StringLiteral] abcd +# 51| 0: [StringLiteral] "abcd" # 54| 3: [ExtensionMethod] ext1 #-----| 2: (Generic Parameters) # 54| 0: [TypeVariable] T2 @@ -118,7 +118,7 @@ reflection.kt: # 97| 0: [TypeAccess] String # 97| -2: [TypeAccess] String # 97| -1: [TypeAccess] ReflectionKt -# 97| 0: [StringLiteral] +# 97| 0: [StringLiteral] "" # 97| 1: [MemberRefExpr] ...::... # 97| -4: [AnonymousClass] new Function1>(...) { ... } # 97| 1: [Constructor] @@ -143,7 +143,7 @@ reflection.kt: # 98| -3: [TypeAccess] Unit # 98| -2: [TypeAccess] String # 98| -1: [TypeAccess] ReflectionKt -# 98| 0: [StringLiteral] +# 98| 0: [StringLiteral] "" # 98| 1: [MemberRefExpr] ...::... # 98| -4: [AnonymousClass] new Function1(...) { ... } # 98| 1: [Constructor] @@ -169,7 +169,7 @@ reflection.kt: # 99| 1: [TypeAccess] Integer # 99| -2: [TypeAccess] String # 99| -1: [TypeAccess] ReflectionKt -# 99| 0: [StringLiteral] +# 99| 0: [StringLiteral] "" # 99| 1: [MemberRefExpr] ...::... # 99| -4: [AnonymousClass] new Function1>(...) { ... } # 99| 1: [Constructor] @@ -1026,7 +1026,7 @@ reflection.kt: # 24| 0: [ValueEQExpr] ... (value equals) ... # 24| 0: [MethodAccess] getName(...) # 24| -1: [VarAccess] it -# 24| 1: [StringLiteral] p3 +# 24| 1: [StringLiteral] "p3" # 24| -3: [TypeAccess] Function1,Boolean> # 24| 0: [TypeAccess] KCallable # 24| 1: [TypeAccess] Boolean @@ -1534,7 +1534,7 @@ reflection.kt: # 90| 1: [TypeAccess] T # 90| -2: [TypeAccess] String # 90| -1: [TypeAccess] ReflectionKt -# 90| 0: [StringLiteral] +# 90| 0: [StringLiteral] "" # 90| 1: [MemberRefExpr] ...::... # 90| -4: [AnonymousClass] new Function1>(...) { ... } # 90| 1: [Constructor] diff --git a/java/ql/test/kotlin/library-tests/stmts/PrintAst.expected b/java/ql/test/kotlin/library-tests/stmts/PrintAst.expected index 2edcd3755b6..7ab29615bd3 100644 --- a/java/ql/test/kotlin/library-tests/stmts/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/stmts/PrintAst.expected @@ -188,7 +188,7 @@ stmts.kt: # 48| 0: [ThrowStmt] throw ... # 48| 0: [ClassInstanceExpr] new Exception(...) # 48| -3: [TypeAccess] Exception -# 48| 0: [StringLiteral] Foo +# 48| 0: [StringLiteral] "Foo" # 50| 0: [CatchClause] catch (...) #-----| 0: (Single Local Variable Declaration) # 50| 0: [TypeAccess] Exception diff --git a/java/ql/test/kotlin/library-tests/stmts/exprs.expected b/java/ql/test/kotlin/library-tests/stmts/exprs.expected index 01631139da3..9193248487f 100644 --- a/java/ql/test/kotlin/library-tests/stmts/exprs.expected +++ b/java/ql/test/kotlin/library-tests/stmts/exprs.expected @@ -101,7 +101,7 @@ | stmts.kt:46:1:56:1 | int | TypeAccess | | stmts.kt:48:15:48:30 | Exception | TypeAccess | | stmts.kt:48:15:48:30 | new Exception(...) | ClassInstanceExpr | -| stmts.kt:48:26:48:28 | Foo | StringLiteral | +| stmts.kt:48:26:48:28 | "Foo" | StringLiteral | | stmts.kt:50:12:50:23 | Exception | TypeAccess | | stmts.kt:50:12:50:23 | e | LocalVariableDeclExpr | | stmts.kt:51:16:51:16 | 1 | IntegerLiteral | diff --git a/java/ql/test/kotlin/library-tests/trap/diags.expected b/java/ql/test/kotlin/library-tests/trap/diags.expected index 377b7fd0a99..6e145a5e4e0 100644 --- a/java/ql/test/kotlin/library-tests/trap/diags.expected +++ b/java/ql/test/kotlin/library-tests/trap/diags.expected @@ -1,9 +1,11 @@ -| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting '//A03BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:22:0\n | +| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting '"ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBC"' ...while extracting a expression () at long_string.kt:14:31:14:1048605\n ...while extracting a variable expr (longStringLiteral1) at long_string.kt:14:5:14:1048606\n ...while extracting a variable (longStringLiteral1) at long_string.kt:14:5:14:1048606\n ...while extracting a statement (longStringLiteral1) at long_string.kt:14:5:14:1048606\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting '//A03BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:24:0\n | | file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE' ...while extracting a expression () at long_string.kt:16:31:16:1048607\n ...while extracting a variable expr (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a variable (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a statement (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | -| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE' ...while extracting a expression () at long_string.kt:16:31:16:1048607\n ...while extracting a variable expr (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a variable (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a statement (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | -| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting '//A04BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:22:0\n | -| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting '//A05"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:22:0\n | -| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'A"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF' ...while extracting a expression () at long_string.kt:18:31:18:2097181\n ...while extracting a variable expr (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a variable (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a statement (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting '"ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCD"' ...while extracting a expression () at long_string.kt:15:31:15:1048606\n ...while extracting a variable expr (longStringLiteral2) at long_string.kt:15:5:15:1048607\n ...while extracting a variable (longStringLiteral2) at long_string.kt:15:5:15:1048607\n ...while extracting a statement (longStringLiteral2) at long_string.kt:15:5:15:1048607\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting '//A04BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:24:0\n | +| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting '//A05"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:24:0\n | | file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'A"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF' ...while extracting a expression () at long_string.kt:18:31:18:2097181\n ...while extracting a variable expr (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a variable (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a statement (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | | file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF' ...while extracting a expression () at long_string.kt:17:31:17:1048608\n ...while extracting a variable expr (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a variable (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a statement (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | -| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF' ...while extracting a expression () at long_string.kt:17:31:17:1048608\n ...while extracting a variable expr (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a variable (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a statement (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048579 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048579 | DATE TIME Truncated string of length 1048579\nTruncated string of length 1048579, starting '"ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE"' ...while extracting a expression () at long_string.kt:16:31:16:1048607\n ...while extracting a variable expr (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a variable (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a statement (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048580 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048580 | DATE TIME Truncated string of length 1048580\nTruncated string of length 1048580, starting '"ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF"' ...while extracting a expression () at long_string.kt:17:31:17:1048608\n ...while extracting a variable expr (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a variable (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a statement (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 2097153 | CodeQL Kotlin extractor | 2 | | Truncated string of length 2097153 | DATE TIME Truncated string of length 2097153\nTruncated string of length 2097153, starting '"A\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"', ending '"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"CDEF"' ...while extracting a expression () at long_string.kt:18:31:18:2097181\n ...while extracting a variable expr (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a variable (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a statement (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | diff --git a/java/ql/test/kotlin/library-tests/trap/literals.ql b/java/ql/test/kotlin/library-tests/trap/literals.ql index 1490a21b458..b6dc1dcff6f 100644 --- a/java/ql/test/kotlin/library-tests/trap/literals.ql +++ b/java/ql/test/kotlin/library-tests/trap/literals.ql @@ -1,6 +1,6 @@ import java from Literal l, int len -where len = l.getValue().length() +where len = l.getValue().length() and l.getFile().isSourceFile() select l.getLocation(), len, l.getValue().prefix(5) + "..." + l.getValue().suffix(len - 5), l.getPrimaryQlClasses() diff --git a/java/ql/test/kotlin/library-tests/trap/long_comments.kt b/java/ql/test/kotlin/library-tests/trap/long_comments.kt index 3c5cb1d3764..55db7520f21 100644 --- a/java/ql/test/kotlin/library-tests/trap/long_comments.kt +++ b/java/ql/test/kotlin/library-tests/trap/long_comments.kt @@ -18,4 +18,6 @@ // Diagnostic Matches: %Truncated string of length 1048577% // Diagnostic Matches: %Truncated string of length 1048578% - +// Diagnostic Matches: %Truncated string of length 1048579% +// Diagnostic Matches: %Truncated string of length 1048580% +// Diagnostic Matches: %Truncated string of length 2097153% diff --git a/java/ql/test/kotlin/library-tests/vararg/args.expected b/java/ql/test/kotlin/library-tests/vararg/args.expected index 1e5a60a3545..6f5e0fbc035 100644 --- a/java/ql/test/kotlin/library-tests/vararg/args.expected +++ b/java/ql/test/kotlin/library-tests/vararg/args.expected @@ -53,33 +53,33 @@ implicitVarargsArguments | test.kt:35:5:35:34 | funWithOnlyVarArgs(...) | 0 | test.kt:35:24:35:25 | 20 | | test.kt:35:5:35:34 | funWithOnlyVarArgs(...) | 1 | test.kt:35:28:35:29 | 21 | | test.kt:35:5:35:34 | funWithOnlyVarArgs(...) | 2 | test.kt:35:32:35:33 | 22 | -| test.kt:36:5:36:50 | funWithArgsAndVarArgs(...) | 0 | test.kt:36:28:36:30 | foo | +| test.kt:36:5:36:50 | funWithArgsAndVarArgs(...) | 0 | test.kt:36:28:36:30 | "foo" | | test.kt:36:5:36:50 | funWithArgsAndVarArgs(...) | 1 | test.kt:36:34:36:37 | true | | test.kt:36:5:36:50 | funWithArgsAndVarArgs(...) | 2 | test.kt:36:40:36:41 | 30 | | test.kt:36:5:36:50 | funWithArgsAndVarArgs(...) | 3 | test.kt:36:44:36:45 | 31 | | test.kt:36:5:36:50 | funWithArgsAndVarArgs(...) | 4 | test.kt:36:48:36:49 | 32 | -| test.kt:37:5:37:53 | funWithMiddleVarArgs(...) | 0 | test.kt:37:27:37:29 | foo | +| test.kt:37:5:37:53 | funWithMiddleVarArgs(...) | 0 | test.kt:37:27:37:29 | "foo" | | test.kt:37:5:37:53 | funWithMiddleVarArgs(...) | 1 | test.kt:37:33:37:34 | 41 | | test.kt:37:5:37:53 | funWithMiddleVarArgs(...) | 2 | test.kt:37:37:37:38 | 42 | | test.kt:37:5:37:53 | funWithMiddleVarArgs(...) | 3 | test.kt:37:41:37:42 | 43 | | test.kt:37:5:37:53 | funWithMiddleVarArgs(...) | 4 | test.kt:37:49:37:52 | true | | test.kt:38:5:38:30 | funWithOnlyVarArgs(...) | 0 | test.kt:38:25:38:29 | array | -| test.kt:39:5:39:46 | funWithArgsAndVarArgs(...) | 0 | test.kt:39:28:39:30 | foo | +| test.kt:39:5:39:46 | funWithArgsAndVarArgs(...) | 0 | test.kt:39:28:39:30 | "foo" | | test.kt:39:5:39:46 | funWithArgsAndVarArgs(...) | 1 | test.kt:39:34:39:37 | true | | test.kt:39:5:39:46 | funWithArgsAndVarArgs(...) | 2 | test.kt:39:41:39:45 | array | -| test.kt:40:5:40:49 | funWithMiddleVarArgs(...) | 0 | test.kt:40:27:40:29 | foo | +| test.kt:40:5:40:49 | funWithMiddleVarArgs(...) | 0 | test.kt:40:27:40:29 | "foo" | | test.kt:40:5:40:49 | funWithMiddleVarArgs(...) | 1 | test.kt:40:34:40:38 | array | | test.kt:40:5:40:49 | funWithMiddleVarArgs(...) | 2 | test.kt:40:45:40:48 | true | | test.kt:41:5:41:36 | new HasVarargConstructor(...) | 0 | test.kt:41:26:41:27 | 51 | | test.kt:41:5:41:36 | new HasVarargConstructor(...) | 1 | test.kt:41:30:41:31 | 52 | | test.kt:41:5:41:36 | new HasVarargConstructor(...) | 2 | test.kt:41:34:41:35 | 53 | -| test.kt:42:5:42:43 | new HasVarargConstructor(...) | 0 | test.kt:42:27:42:29 | foo | +| test.kt:42:5:42:43 | new HasVarargConstructor(...) | 0 | test.kt:42:27:42:29 | "foo" | | test.kt:42:5:42:43 | new HasVarargConstructor(...) | 1 | test.kt:42:33:42:34 | 61 | | test.kt:42:5:42:43 | new HasVarargConstructor(...) | 2 | test.kt:42:37:42:38 | 62 | | test.kt:42:5:42:43 | new HasVarargConstructor(...) | 3 | test.kt:42:41:42:42 | 63 | | test.kt:43:5:43:38 | new SuperclassHasVarargConstructor(...) | 0 | test.kt:43:36:43:37 | 91 | | test.kt:44:5:44:32 | new HasVarargConstructor(...) | 0 | test.kt:44:27:44:31 | array | -| test.kt:45:5:45:39 | new HasVarargConstructor(...) | 0 | test.kt:45:27:45:29 | foo | +| test.kt:45:5:45:39 | new HasVarargConstructor(...) | 0 | test.kt:45:27:45:29 | "foo" | | test.kt:45:5:45:39 | new HasVarargConstructor(...) | 1 | test.kt:45:34:45:38 | array | | test.kt:55:13:55:43 | new X(...) | 0 | test.kt:55:42:55:42 | 1 | | test.kt:55:13:55:43 | new X(...) | 1 | test.kt:55:15:55:35 | tmp0_s | From a5a244fc5303080d1c5931eceba35425275efe70 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 17 Nov 2022 12:33:06 +0100 Subject: [PATCH 371/796] CPP: delete old deprecations --- cpp/ql/lib/change-notes/2022-11-17-deleted-deps.md | 4 ++++ cpp/ql/lib/semmle/code/cpp/File.qll | 12 ------------ 2 files changed, 4 insertions(+), 12 deletions(-) create mode 100644 cpp/ql/lib/change-notes/2022-11-17-deleted-deps.md diff --git a/cpp/ql/lib/change-notes/2022-11-17-deleted-deps.md b/cpp/ql/lib/change-notes/2022-11-17-deleted-deps.md new file mode 100644 index 00000000000..bf2d5a07de6 --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-11-17-deleted-deps.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `getName` and `getShortName` predicates from the `Folder` class. \ No newline at end of file diff --git a/cpp/ql/lib/semmle/code/cpp/File.qll b/cpp/ql/lib/semmle/code/cpp/File.qll index e58467fac20..b2e4e0a41a5 100644 --- a/cpp/ql/lib/semmle/code/cpp/File.qll +++ b/cpp/ql/lib/semmle/code/cpp/File.qll @@ -189,18 +189,6 @@ class Folder extends Container, @folder { * Gets the URL of this folder. */ deprecated override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" } - - /** - * DEPRECATED: use `getAbsolutePath` instead. - * Gets the name of this folder. - */ - deprecated string getName() { folders(underlyingElement(this), result) } - - /** - * DEPRECATED: use `getBaseName` instead. - * Gets the last part of the folder name. - */ - deprecated string getShortName() { result = this.getBaseName() } } /** From d5ec781d4c2a95a6af74ff1b655e27810012db97 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 17 Nov 2022 12:34:52 +0100 Subject: [PATCH 372/796] C#: delete old deprecations --- csharp/ql/lib/change-notes/2022-11-17-deleted-deps.md | 4 ++++ csharp/ql/lib/semmle/code/csharp/Type.qll | 7 ------- 2 files changed, 4 insertions(+), 7 deletions(-) create mode 100644 csharp/ql/lib/change-notes/2022-11-17-deleted-deps.md diff --git a/csharp/ql/lib/change-notes/2022-11-17-deleted-deps.md b/csharp/ql/lib/change-notes/2022-11-17-deleted-deps.md new file mode 100644 index 00000000000..da5a8d8cd9b --- /dev/null +++ b/csharp/ql/lib/change-notes/2022-11-17-deleted-deps.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `getNameWithoutBrackets` predicate from the `ValueOrRefType` class in `Type.qll`. \ No newline at end of file diff --git a/csharp/ql/lib/semmle/code/csharp/Type.qll b/csharp/ql/lib/semmle/code/csharp/Type.qll index dfabea580a4..d475442f886 100644 --- a/csharp/ql/lib/semmle/code/csharp/Type.qll +++ b/csharp/ql/lib/semmle/code/csharp/Type.qll @@ -56,13 +56,6 @@ private predicate isObjectClass(Class c) { c instanceof ObjectType } * Either a value type (`ValueType`) or a reference type (`RefType`). */ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_or_ref_type { - /** - * DEPRECATED: use `getUndecoratedName()` instead. - * - * Gets the name of this type without `<...>` brackets, in case it is a generic type. - */ - deprecated string getNameWithoutBrackets() { types(this, _, result) } - /** * Holds if this type has the qualified name `qualifier`.`name`. * From a4e5d752e127ca2cf1e707bdb3bed412fe82514e Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 17 Nov 2022 12:37:31 +0100 Subject: [PATCH 373/796] Java: delete old deprecations --- java/ql/lib/change-notes/2022-11-17-deleted-deps.md | 5 +++++ java/ql/lib/semmle/code/java/PrintAst.qll | 6 ------ java/ql/lib/semmle/code/java/Statement.qll | 12 ------------ java/ql/lib/semmle/code/java/Type.qll | 6 ------ 4 files changed, 5 insertions(+), 24 deletions(-) create mode 100644 java/ql/lib/change-notes/2022-11-17-deleted-deps.md diff --git a/java/ql/lib/change-notes/2022-11-17-deleted-deps.md b/java/ql/lib/change-notes/2022-11-17-deleted-deps.md new file mode 100644 index 00000000000..014b4ff23eb --- /dev/null +++ b/java/ql/lib/change-notes/2022-11-17-deleted-deps.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `LocalClassDeclStmtNode` and `LocalClassDeclStmt` classes from `PrintAst.qll` and `Statement.qll` respectively. +* Deleted the deprecated `getLocalClass` predicate from `LocalTypeDeclStmt`, and the deprecated `getLocalClassDeclStmt` predicate from `LocalClassOrInterface`. \ No newline at end of file diff --git a/java/ql/lib/semmle/code/java/PrintAst.qll b/java/ql/lib/semmle/code/java/PrintAst.qll index 4df23f4ec14..d6420f2e4ca 100644 --- a/java/ql/lib/semmle/code/java/PrintAst.qll +++ b/java/ql/lib/semmle/code/java/PrintAst.qll @@ -393,12 +393,6 @@ final class LocalTypeDeclStmtNode extends ExprStmtNode { } } -/** - * DEPRECATED: Renamed `LocalTypeDeclStmtNode` to reflect the fact that - * as of Java 16 interfaces can also be declared locally, not just classes. - */ -deprecated class LocalClassDeclStmtNode = LocalTypeDeclStmtNode; - /** * A node representing a `ForStmt`. */ diff --git a/java/ql/lib/semmle/code/java/Statement.qll b/java/ql/lib/semmle/code/java/Statement.qll index 2c8cff3c217..fe0ba23093a 100644 --- a/java/ql/lib/semmle/code/java/Statement.qll +++ b/java/ql/lib/semmle/code/java/Statement.qll @@ -781,12 +781,6 @@ class LocalTypeDeclStmt extends Stmt, @localtypedeclstmt { /** Gets the local type declared by this statement. */ LocalClassOrInterface getLocalType() { isLocalClassOrInterface(result, this) } - /** - * DEPRECATED: Renamed `getLocalType` to reflect the fact that - * as of Java 16 interfaces can also be declared locally, not just classes. - */ - deprecated LocalClassOrInterface getLocalClass() { result = this.getLocalType() } - private string getDeclKeyword() { result = "class" and this.getLocalType() instanceof Class or @@ -802,12 +796,6 @@ class LocalTypeDeclStmt extends Stmt, @localtypedeclstmt { override string getAPrimaryQlClass() { result = "LocalTypeDeclStmt" } } -/** - * DEPRECATED: Renamed `LocalTypeDeclStmt` to reflect the fact that - * as of Java 16 interfaces can also be declared locally, not just classes. - */ -deprecated class LocalClassDeclStmt = LocalTypeDeclStmt; - /** An explicit `this(...)` constructor invocation. */ class ThisConstructorInvocationStmt extends Stmt, ConstructorCall, @constructorinvocationstmt { /** Gets an argument of this constructor invocation. */ diff --git a/java/ql/lib/semmle/code/java/Type.qll b/java/ql/lib/semmle/code/java/Type.qll index 63df6feef42..eff61ed0fde 100644 --- a/java/ql/lib/semmle/code/java/Type.qll +++ b/java/ql/lib/semmle/code/java/Type.qll @@ -828,12 +828,6 @@ class LocalClassOrInterface extends NestedType, ClassOrInterface { /** Gets the statement that declares this local class. */ LocalTypeDeclStmt getLocalTypeDeclStmt() { isLocalClassOrInterface(this, result) } - /** - * DEPRECATED: renamed `getLocalTypeDeclStmt` to reflect the fact that - * as of Java 16 interfaces can also be declared locally. - */ - deprecated LocalTypeDeclStmt getLocalClassDeclStmt() { result = this.getLocalTypeDeclStmt() } - override string getAPrimaryQlClass() { result = "LocalClassOrInterface" } } From a7ba693ccbd050d9d5d9a04dc5fc7b4bebf7b338 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 17 Nov 2022 12:44:56 +0100 Subject: [PATCH 374/796] Python: delete old deprecations --- .../change-notes/2022-11-17-deleted-deps.md | 7 ++ .../dataflow/new/internal/DataFlowUtil.qll | 64 ---------- .../lib/semmle/python/frameworks/PEP249.qll | 25 ---- .../lib/semmle/python/frameworks/Werkzeug.qll | 115 ------------------ .../python/frameworks/internal/PEP249Impl.qll | 9 -- 5 files changed, 7 insertions(+), 213 deletions(-) create mode 100644 python/ql/lib/change-notes/2022-11-17-deleted-deps.md diff --git a/python/ql/lib/change-notes/2022-11-17-deleted-deps.md b/python/ql/lib/change-notes/2022-11-17-deleted-deps.md new file mode 100644 index 00000000000..6d366b9c114 --- /dev/null +++ b/python/ql/lib/change-notes/2022-11-17-deleted-deps.md @@ -0,0 +1,7 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `importNode` predicate from the `DataFlowUtil.qll` file. +* Deleted the deprecated features from `PEP249.qll` that were not inside the `PEP249` module. +* Deleted the deprecated `werkzeug` from the `Werkzeug` module in `Werkzeug.qll`. +* Deleted the deprecated `methodResult` predicate from `PEP249::Cursor`. \ No newline at end of file diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowUtil.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowUtil.qll index fc697d45524..7f1a6464adf 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowUtil.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowUtil.qll @@ -26,67 +26,3 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) { */ pragma[inline] predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) } - -/** - * DEPRECATED. Use the API graphs library (`semmle.python.ApiGraphs`) instead. - * - * For a drop-in replacement, use `API::moduleImport(name).getAUse()`. - * - * Gets a `Node` that refers to the module referenced by `name`. - * Note that for the statement `import pkg.mod`, the new variable introduced is `pkg` that is a - * reference to the module `pkg`. - * - * This predicate handles (with optional `... as `): - * 1. `import ` - * 2. `from import ` when ` = + "." + ` - * 3. `from import ` when ` = + "." + ` - * - * Finally, in `from import ` we consider the `ImportExpr` corresponding to - * `` to be a reference to that module. - * - * Note: - * While it is technically possible that `import mypkg.foo` and `from mypkg import foo` can give different values, - * it's highly unlikely that this will be a problem in production level code. - * Example: If `mypkg/__init__.py` contains `foo = 42`, then `from mypkg import foo` will not import the module - * `mypkg/foo.py` but the variable `foo` containing `42` -- however, `import mypkg.foo` will always cause `mypkg.foo` - * to refer to the module. - */ -deprecated Node importNode(string name) { - exists(Variable var, Import imp, Alias alias | - alias = imp.getAName() and - alias.getAsname() = var.getAStore() and - ( - name = alias.getValue().(ImportMember).getImportedModuleName() - or - name = alias.getValue().(ImportExpr).getImportedModuleName() - ) and - result.asExpr() = alias.getValue() - ) - or - // Although it may seem superfluous to consider the `foo` part of `from foo import bar as baz` to - // be a reference to a module (since that reference only makes sense locally within the `import` - // statement), it's important for our use of type trackers to consider this local reference to - // also refer to the `foo` module. That way, if one wants to track references to the `bar` - // attribute using a type tracker, one can simply write - // - // ```ql - // DataFlow::Node bar_attr_tracker(TypeTracker t) { - // t.startInAttr("bar") and - // result = foo_module_tracker() - // or - // exists(TypeTracker t2 | result = bar_attr_tracker(t2).track(t2, t)) - // } - // ``` - // - // Where `foo_module_tracker` is a type tracker that tracks references to the `foo` module. - // Because named imports are modeled as `AttrRead`s, the statement `from foo import bar as baz` - // is interpreted as if it was an assignment `baz = foo.bar`, which means `baz` gets tracked as a - // reference to `foo.bar`, as desired. - exists(ImportExpr imp_expr | - imp_expr.getName() = name and - result.asCfgNode().getNode() = imp_expr and - // in `import foo.bar` we DON'T want to give a result for `importNode("foo.bar")`, - // only for `importNode("foo")`. We exclude those cases with the following clause. - not exists(Import imp | imp.getAName().getValue() = imp_expr) - ) -} diff --git a/python/ql/lib/semmle/python/frameworks/PEP249.qll b/python/ql/lib/semmle/python/frameworks/PEP249.qll index 6c4e07cd801..9d09fc4078b 100644 --- a/python/ql/lib/semmle/python/frameworks/PEP249.qll +++ b/python/ql/lib/semmle/python/frameworks/PEP249.qll @@ -9,28 +9,3 @@ private import semmle.python.dataflow.new.RemoteFlowSources private import semmle.python.Concepts private import semmle.python.ApiGraphs import semmle.python.frameworks.internal.PEP249Impl - -/** - * DEPRECATED: Use `PEP249::PEP249ModuleApiNode` instead. - */ -deprecated class PEP249ModuleApiNode = PEP249::PEP249ModuleApiNode; - -/** - * DEPRECATED: Use `PEP249::Connection` instead. - */ -deprecated module Connection = PEP249::Connection; - -/** - * DEPRECATED: Use `PEP249::Cursor` instead. - */ -deprecated module cursor = PEP249::Cursor; - -/** - * DEPRECATED: Use `PEP249::execute` instead. - */ -deprecated predicate execute = PEP249::execute/0; - -/** - * DEPRECATED: Use `PEP249::connect` instead. - */ -deprecated predicate connect = PEP249::connect/0; diff --git a/python/ql/lib/semmle/python/frameworks/Werkzeug.qll b/python/ql/lib/semmle/python/frameworks/Werkzeug.qll index 2867516dcd8..66cea37020e 100644 --- a/python/ql/lib/semmle/python/frameworks/Werkzeug.qll +++ b/python/ql/lib/semmle/python/frameworks/Werkzeug.qll @@ -231,119 +231,4 @@ module Werkzeug { override string getAsyncMethodName() { none() } } } - - import WerkzeugOld -} - -/** - * Old version that contains the deprecated modules. - */ -private module WerkzeugOld { - /** - * DEPRECATED: Use the modeling available directly in the `Werkzeug` module instead. - * - * Provides models for the `werkzeug` module. - */ - deprecated module werkzeug { - /** - * DEPRECATED: Use the modeling available directly in the `Werkzeug` module instead. - * - * Provides models for the `werkzeug.datastructures` module. - */ - deprecated module datastructures { - /** - * DEPRECATED: Use `Werkzeug::MultiDict` instead. - * - * Provides models for the `werkzeug.datastructures.MultiDict` class - * - * See https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.MultiDict. - */ - deprecated module MultiDict { - /** - * DEPRECATED. Use `Werkzeug::MultiDict::InstanceSource` instead. - * - * A source of instances of `werkzeug.datastructures.MultiDict`, extend this class to model new instances. - * - * This can include instantiations of the class, return values from function - * calls, or a special parameter that will be set when functions are called by an external - * library. - * - * Use the predicate `MultiDict::instance()` to get references to instances of `werkzeug.datastructures.MultiDict`. - */ - abstract deprecated class InstanceSourceApiNode extends API::Node { } - - /** - * DEPRECATED - * - * Gets a reference to the `getlist` method on an instance of `werkzeug.datastructures.MultiDict`. - * - * See https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.Headers.getlist - */ - deprecated DataFlow::Node getlist() { - result = any(InstanceSourceApiNode a).getMember("getlist").getAValueReachableFromSource() - } - - private class MultiDictAdditionalTaintStep extends TaintTracking::AdditionalTaintStep { - override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - // obj -> obj.getlist - exists(DataFlow::AttrRead read | - read.getObject() = nodeFrom and - nodeTo = read and - nodeTo = getlist() - ) - or - // getlist -> getlist() - nodeFrom = getlist() and - nodeTo.(DataFlow::CallCfgNode).getFunction() = nodeFrom - } - } - } - - /** - * DEPRECATED: Use `Werkzeug::FileStorage` instead. - * - * Provides models for the `werkzeug.datastructures.FileStorage` class - * - * See https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.FileStorage. - */ - deprecated module FileStorage { - /** - * DEPRECATED. Use `Werkzeug::FileStorage::InstanceSource` instead. - * - * A source of instances of `werkzeug.datastructures.FileStorage`, extend this class to model new instances. - * - * This can include instantiations of the class, return values from function - * calls, or a special parameter that will be set when functions are called by an external - * library. - * - * Use the predicate `FileStorage::instance()` to get references to instances of `werkzeug.datastructures.FileStorage`. - */ - abstract deprecated class InstanceSourceApiNode extends API::Node { } - - /** Gets a reference to an instance of `werkzeug.datastructures.FileStorage`. */ - deprecated DataFlow::Node instance() { - result = any(InstanceSourceApiNode a).getAValueReachableFromSource() - } - - private class FileStorageAdditionalTaintStep extends TaintTracking::AdditionalTaintStep { - override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - nodeFrom = instance() and - exists(DataFlow::AttrRead read | nodeTo = read | - read.getAttributeName() in [ - // str - "filename", "name", "content_type", "mimetype", - // file-like - "stream", - // TODO: werkzeug.datastructures.Headers - "headers", - // dict[str, str] - "mimetype_params" - ] and - read.getObject() = nodeFrom - ) - } - } - } - } - } } diff --git a/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll b/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll index bf63bbb3731..538929bd646 100644 --- a/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll +++ b/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll @@ -129,15 +129,6 @@ module PEP249 { or exists(DataFlow::TypeTracker t2 | result = methodResult(t2).track(t2, t)) } - - /** - * DEPRECATED: Use `Cursor::instance()` to get references to database cursors instead. - * - * Gets a reference to a result of calling the `cursor` method on a database connection. - */ - deprecated DataFlow::Node methodResult() { - methodResult(DataFlow::TypeTracker::end()).flowsTo(result) - } } /** From e491b61e09daace19adf25b9b4737978b9b6ecbd Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 17 Nov 2022 12:46:21 +0100 Subject: [PATCH 375/796] Python: move the contents of `PEP249Impl` to `PEP249`, which is possible now that the deprecations have been deleted --- .../lib/semmle/python/frameworks/PEP249.qll | 176 +++++++++++++++- .../python/frameworks/internal/PEP249Impl.qll | 195 ------------------ 2 files changed, 175 insertions(+), 196 deletions(-) delete mode 100644 python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll diff --git a/python/ql/lib/semmle/python/frameworks/PEP249.qll b/python/ql/lib/semmle/python/frameworks/PEP249.qll index 9d09fc4078b..6dee86b5346 100644 --- a/python/ql/lib/semmle/python/frameworks/PEP249.qll +++ b/python/ql/lib/semmle/python/frameworks/PEP249.qll @@ -8,4 +8,178 @@ private import semmle.python.dataflow.new.DataFlow private import semmle.python.dataflow.new.RemoteFlowSources private import semmle.python.Concepts private import semmle.python.ApiGraphs -import semmle.python.frameworks.internal.PEP249Impl + +/** + * Provides classes modeling database interfaces following PEP 249. + * See https://www.python.org/dev/peps/pep-0249/. + */ +module PEP249 { + /** + * An API graph node representing a module that implements PEP 249. + */ + abstract class PEP249ModuleApiNode extends API::Node { + /** Gets a string representation of this element. */ + override string toString() { result = this.(API::Node).toString() } + } + + /** Gets a reference to the `connect` function of a module that implements PEP 249. */ + DataFlow::Node connect() { + result = any(PEP249ModuleApiNode a).getMember("connect").getAValueReachableFromSource() + } + + /** + * Provides models for database connections (following PEP 249). + * + * See https://www.python.org/dev/peps/pep-0249/#connection-objects. + */ + module Connection { + /** + * A source of database connections (following PEP 249), extend this class to model new instances. + * + * This can include instantiations of the class, return values from function + * calls, or a special parameter that will be set when functions are called by external + * libraries. + * + * Use the predicate `Connection::instance()` to get references to database connections (following PEP 249). + * + * Extend this class if the module implementing PEP 249 offers more direct ways to obtain + * a connection than going through `connect`. + */ + abstract class InstanceSource extends DataFlow::Node { } + + /** A call to the `connect` function of a module that implements PEP 249. */ + private class ConnectCall extends InstanceSource, DataFlow::CallCfgNode { + ConnectCall() { this.getFunction() = connect() } + } + + /** Gets a reference to a database connection (following PEP 249). */ + private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) { + t.start() and + result instanceof InstanceSource + or + exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t)) + } + + /** Gets a reference to a database connection (following PEP 249). */ + DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } + } + + /** + * Provides models for database cursors (following PEP 249). + * + * These are returned by the `cursor` method on a database connection. + * See https://www.python.org/dev/peps/pep-0249/#cursor. + */ + module Cursor { + /** + * A source of database cursors (following PEP 249), extend this class to model new instances. + * + * This can include instantiations of the class, return values from function + * calls, or a special parameter that will be set when functions are called by external + * libraries. + * + * Use the predicate `Cursor::instance()` to get references to database cursors (following PEP 249). + * + * Extend this class if the module implementing PEP 249 offers more direct ways to obtain + * a connection than going through `connect`. + */ + abstract class InstanceSource extends DataFlow::LocalSourceNode { } + + /** Gets a reference to a database cursor. */ + private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) { + t.start() and + result instanceof InstanceSource + or + exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t)) + } + + /** Gets a reference to a database cursor. */ + DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } + + /** Gets a reference to the `cursor` method on a database connection. */ + private DataFlow::TypeTrackingNode methodRef(DataFlow::TypeTracker t) { + t.startInAttr("cursor") and + result = Connection::instance() + or + exists(DataFlow::TypeTracker t2 | result = methodRef(t2).track(t2, t)) + } + + /** Gets a reference to the `cursor` method on a database connection. */ + DataFlow::Node methodRef() { methodRef(DataFlow::TypeTracker::end()).flowsTo(result) } + + /** A call to the `cursor` method on a database connection */ + private class CursorCall extends InstanceSource, DataFlow::CallCfgNode { + CursorCall() { this.getFunction() = methodRef() } + } + + /** Gets a reference to a result of calling the `cursor` method on a database connection. */ + private DataFlow::TypeTrackingNode methodResult(DataFlow::TypeTracker t) { + t.start() and + result.asCfgNode().(CallNode).getFunction() = methodRef().asCfgNode() + or + exists(DataFlow::TypeTracker t2 | result = methodResult(t2).track(t2, t)) + } + } + + /** + * Gets a reference to the `execute` method on a cursor (or on a connection). + * + * Note: while `execute` method on a connection is not part of PEP249, if it is used, we + * recognize it as an alias for constructing a cursor and calling `execute` on it. + * + * See https://peps.python.org/pep-0249/#execute. + */ + private DataFlow::TypeTrackingNode execute(DataFlow::TypeTracker t) { + t.startInAttr("execute") and + result in [Cursor::instance(), Connection::instance()] + or + exists(DataFlow::TypeTracker t2 | result = execute(t2).track(t2, t)) + } + + /** + * Gets a reference to the `execute` method on a cursor (or on a connection). + * + * Note: while `execute` method on a connection is not part of PEP249, if it is used, we + * recognize it as an alias for constructing a cursor and calling `execute` on it. + * + * See https://peps.python.org/pep-0249/#execute. + */ + DataFlow::Node execute() { execute(DataFlow::TypeTracker::end()).flowsTo(result) } + + /** + * A call to the `execute` method on a cursor or a connection. + * + * See https://peps.python.org/pep-0249/#execute + * + * Note: While `execute` method on a connection is not part of PEP249, if it is used, we + * recognize it as an alias for constructing a cursor and calling `execute` on it. + */ + private class ExecuteCall extends SqlExecution::Range, DataFlow::CallCfgNode { + ExecuteCall() { this.getFunction() = execute() } + + override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("sql")] } + } + + private DataFlow::TypeTrackingNode executemany(DataFlow::TypeTracker t) { + t.startInAttr("executemany") and + result in [Cursor::instance(), Connection::instance()] + or + exists(DataFlow::TypeTracker t2 | result = executemany(t2).track(t2, t)) + } + + private DataFlow::Node executemany() { executemany(DataFlow::TypeTracker::end()).flowsTo(result) } + + /** + * A call to the `executemany` method on a cursor or a connection. + * + * See https://peps.python.org/pep-0249/#executemany + * + * Note: While `executemany` method on a connection is not part of PEP249, if it is used, we + * recognize it as an alias for constructing a cursor and calling `executemany` on it. + */ + private class ExecutemanyCall extends SqlExecution::Range, DataFlow::CallCfgNode { + ExecutemanyCall() { this.getFunction() = executemany() } + + override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("sql")] } + } +} diff --git a/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll b/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll deleted file mode 100644 index 538929bd646..00000000000 --- a/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll +++ /dev/null @@ -1,195 +0,0 @@ -/** - * INTERNAL: Do not use. - * - * Provides internal implementation of PEP249. This currently resides in a different - * file than `python/ql/src/semmle/python/frameworks/PEP249.qll`, since we used to - * export everything without being encapsulated in a module, and shadowing rules means - * that we can't just add the module directly to that file :( - * - * So once we can remove those deprecated things (Start of July 2022), we can also move - * the core implementation into its' proper place. - * - * Provides classes modeling PEP 249. - * See https://www.python.org/dev/peps/pep-0249/. - */ - -private import python -private import semmle.python.dataflow.new.DataFlow -private import semmle.python.dataflow.new.RemoteFlowSources -private import semmle.python.Concepts -private import semmle.python.ApiGraphs - -/** - * Provides classes modeling database interfaces following PEP 249. - * See https://www.python.org/dev/peps/pep-0249/. - */ -module PEP249 { - /** - * An API graph node representing a module that implements PEP 249. - */ - abstract class PEP249ModuleApiNode extends API::Node { - /** Gets a string representation of this element. */ - override string toString() { result = this.(API::Node).toString() } - } - - /** Gets a reference to the `connect` function of a module that implements PEP 249. */ - DataFlow::Node connect() { - result = any(PEP249ModuleApiNode a).getMember("connect").getAValueReachableFromSource() - } - - /** - * Provides models for database connections (following PEP 249). - * - * See https://www.python.org/dev/peps/pep-0249/#connection-objects. - */ - module Connection { - /** - * A source of database connections (following PEP 249), extend this class to model new instances. - * - * This can include instantiations of the class, return values from function - * calls, or a special parameter that will be set when functions are called by external - * libraries. - * - * Use the predicate `Connection::instance()` to get references to database connections (following PEP 249). - * - * Extend this class if the module implementing PEP 249 offers more direct ways to obtain - * a connection than going through `connect`. - */ - abstract class InstanceSource extends DataFlow::Node { } - - /** A call to the `connect` function of a module that implements PEP 249. */ - private class ConnectCall extends InstanceSource, DataFlow::CallCfgNode { - ConnectCall() { this.getFunction() = connect() } - } - - /** Gets a reference to a database connection (following PEP 249). */ - private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) { - t.start() and - result instanceof InstanceSource - or - exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t)) - } - - /** Gets a reference to a database connection (following PEP 249). */ - DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } - } - - /** - * Provides models for database cursors (following PEP 249). - * - * These are returned by the `cursor` method on a database connection. - * See https://www.python.org/dev/peps/pep-0249/#cursor. - */ - module Cursor { - /** - * A source of database cursors (following PEP 249), extend this class to model new instances. - * - * This can include instantiations of the class, return values from function - * calls, or a special parameter that will be set when functions are called by external - * libraries. - * - * Use the predicate `Cursor::instance()` to get references to database cursors (following PEP 249). - * - * Extend this class if the module implementing PEP 249 offers more direct ways to obtain - * a connection than going through `connect`. - */ - abstract class InstanceSource extends DataFlow::LocalSourceNode { } - - /** Gets a reference to a database cursor. */ - private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) { - t.start() and - result instanceof InstanceSource - or - exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t)) - } - - /** Gets a reference to a database cursor. */ - DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } - - /** Gets a reference to the `cursor` method on a database connection. */ - private DataFlow::TypeTrackingNode methodRef(DataFlow::TypeTracker t) { - t.startInAttr("cursor") and - result = Connection::instance() - or - exists(DataFlow::TypeTracker t2 | result = methodRef(t2).track(t2, t)) - } - - /** Gets a reference to the `cursor` method on a database connection. */ - DataFlow::Node methodRef() { methodRef(DataFlow::TypeTracker::end()).flowsTo(result) } - - /** A call to the `cursor` method on a database connection */ - private class CursorCall extends InstanceSource, DataFlow::CallCfgNode { - CursorCall() { this.getFunction() = methodRef() } - } - - /** Gets a reference to a result of calling the `cursor` method on a database connection. */ - private DataFlow::TypeTrackingNode methodResult(DataFlow::TypeTracker t) { - t.start() and - result.asCfgNode().(CallNode).getFunction() = methodRef().asCfgNode() - or - exists(DataFlow::TypeTracker t2 | result = methodResult(t2).track(t2, t)) - } - } - - /** - * Gets a reference to the `execute` method on a cursor (or on a connection). - * - * Note: while `execute` method on a connection is not part of PEP249, if it is used, we - * recognize it as an alias for constructing a cursor and calling `execute` on it. - * - * See https://peps.python.org/pep-0249/#execute. - */ - private DataFlow::TypeTrackingNode execute(DataFlow::TypeTracker t) { - t.startInAttr("execute") and - result in [Cursor::instance(), Connection::instance()] - or - exists(DataFlow::TypeTracker t2 | result = execute(t2).track(t2, t)) - } - - /** - * Gets a reference to the `execute` method on a cursor (or on a connection). - * - * Note: while `execute` method on a connection is not part of PEP249, if it is used, we - * recognize it as an alias for constructing a cursor and calling `execute` on it. - * - * See https://peps.python.org/pep-0249/#execute. - */ - DataFlow::Node execute() { execute(DataFlow::TypeTracker::end()).flowsTo(result) } - - /** - * A call to the `execute` method on a cursor or a connection. - * - * See https://peps.python.org/pep-0249/#execute - * - * Note: While `execute` method on a connection is not part of PEP249, if it is used, we - * recognize it as an alias for constructing a cursor and calling `execute` on it. - */ - private class ExecuteCall extends SqlExecution::Range, DataFlow::CallCfgNode { - ExecuteCall() { this.getFunction() = execute() } - - override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("sql")] } - } - - private DataFlow::TypeTrackingNode executemany(DataFlow::TypeTracker t) { - t.startInAttr("executemany") and - result in [Cursor::instance(), Connection::instance()] - or - exists(DataFlow::TypeTracker t2 | result = executemany(t2).track(t2, t)) - } - - private DataFlow::Node executemany() { executemany(DataFlow::TypeTracker::end()).flowsTo(result) } - - /** - * A call to the `executemany` method on a cursor or a connection. - * - * See https://peps.python.org/pep-0249/#executemany - * - * Note: While `executemany` method on a connection is not part of PEP249, if it is used, we - * recognize it as an alias for constructing a cursor and calling `executemany` on it. - */ - private class ExecutemanyCall extends SqlExecution::Range, DataFlow::CallCfgNode { - ExecutemanyCall() { this.getFunction() = executemany() } - - override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("sql")] } - } -} From 635b8772d72999d964df7dde9cd202bcc7f2bda4 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 17 Nov 2022 12:50:50 +0100 Subject: [PATCH 376/796] JS: delete old deprecations --- .../change-notes/2022-11-17-deleted-deps.md | 5 +++ .../lib/semmle/javascript/frameworks/Vue.qll | 43 ------------------- .../security/dataflow/DomBasedXssQuery.qll | 5 --- 3 files changed, 5 insertions(+), 48 deletions(-) create mode 100644 javascript/ql/lib/change-notes/2022-11-17-deleted-deps.md diff --git a/javascript/ql/lib/change-notes/2022-11-17-deleted-deps.md b/javascript/ql/lib/change-notes/2022-11-17-deleted-deps.md new file mode 100644 index 00000000000..e5f1a1c6f56 --- /dev/null +++ b/javascript/ql/lib/change-notes/2022-11-17-deleted-deps.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `Instance` class from the `Vue` module. +* Deleted the deprecated `VHtmlSourceWrite` class from `DomBasedXssQuery.qll`. diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Vue.qll b/javascript/ql/lib/semmle/javascript/frameworks/Vue.qll index 95a372025e2..f3eb2e5bb0d 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Vue.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Vue.qll @@ -115,11 +115,6 @@ module Vue { kind = DataFlow::MemberKind::setter() and result = "set" } - /** - * DEPRECATED. This class has been renamed to `Vue::Component`. - */ - deprecated class Instance = Component; - /** * A Vue component, such as a `new Vue({ ... })` call or a `.vue` file. * @@ -383,23 +378,6 @@ module Vue { } } - /** - * DEPRECATED. Use `Vue::Component` instead. - * - * A Vue component from `new Vue({...})`. - */ - deprecated class VueInstance extends Component { - VueInstance() { - // restrict charpred to match original behavior - this = MkComponentInstantiation(vueLibrary().getAnInstantiation()) - } - } - - /** - * DEPRECATED. Use `Vue::ComponentExtension` or `Vue::Component` instead. - */ - deprecated class ExtendedVue = ComponentExtension; - /** * A component created via an explicit call to `Vue.extend({...})` or `CustomComponent.extend({...})`. */ @@ -429,19 +407,6 @@ module Vue { } } - /** - * DEPRECATED. Use `Vue::Component` instead. - * - * An instance of an extended Vue, for example `instance` of `var Ext = Vue.extend({...}); var instance = new Ext({...})`. - */ - deprecated class ExtendedInstance extends Component { - ExtendedInstance() { - // restrict charpred to match original behavior - this = - MkComponentInstantiation(vueLibrary().getMember("extend").getReturn().getAnInstantiation()) - } - } - /** * A Vue component from `Vue.component("my-component", { ... })`. */ @@ -568,9 +533,6 @@ module Vue { } } - /** DEPRECATED. Do not use. */ - deprecated class InstanceHeapStep = PropStep; - /** * A Vue `v-html` attribute. */ @@ -609,11 +571,6 @@ module Vue { } } - /** - * DEPRECATED. Do not use. - */ - deprecated class VHtmlSourceWrite = VHtmlAttributeStep; - /* * Provides classes for working with Vue templates. */ diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll index e8c1a144920..2f920f59604 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll @@ -8,11 +8,6 @@ private import semmle.javascript.security.TaintedUrlSuffix import DomBasedXssCustomizations::DomBasedXss private import Xss::Shared as Shared -/** - * DEPRECATED. Use `Vue::VHtmlSourceWrite` instead. - */ -deprecated class VHtmlSourceWrite = Vue::VHtmlSourceWrite; - /** DEPRECATED. Use `Configuration`. */ deprecated class HtmlInjectionConfiguration = Configuration; From 3635db82441b3677c12cdc4e0be43872732c3cea Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 17 Nov 2022 12:54:35 +0100 Subject: [PATCH 377/796] JS: delete the deprecated [queryName].qll files --- .../ql/lib/change-notes/2022-11-17-deleted-deps.md | 1 + .../security/dataflow/BrokenCryptoAlgorithm.qll | 7 ------- .../javascript/security/dataflow/BuildArtifactLeak.qll | 7 ------- .../javascript/security/dataflow/CleartextLogging.qll | 7 ------- .../javascript/security/dataflow/CleartextStorage.qll | 7 ------- .../security/dataflow/ClientSideUrlRedirect.qll | 8 -------- .../javascript/security/dataflow/CodeInjection.qll | 7 ------- .../javascript/security/dataflow/CommandInjection.qll | 7 ------- .../javascript/security/dataflow/ConditionalBypass.qll | 7 ------- .../dataflow/CorsMisconfigurationForCredentials.qll | 7 ------- .../security/dataflow/DeepObjectResourceExhaustion.qll | 8 -------- .../dataflow/DifferentKindsComparisonBypass.qll | 7 ------- .../javascript/security/dataflow/DomBasedXss.qll | 7 ------- .../javascript/security/dataflow/ExceptionXss.qll | 7 ------- .../javascript/security/dataflow/FileAccessToHttp.qll | 7 ------- .../security/dataflow/HardcodedCredentials.qll | 7 ------- .../dataflow/HardcodedDataInterpretedAsCode.qll | 7 ------- .../dataflow/HostHeaderPoisoningInEmailGeneration.qll | 7 ------- .../javascript/security/dataflow/HttpToFileAccess.qll | 7 ------- .../security/dataflow/ImproperCodeSanitization.qll | 7 ------- .../dataflow/IncompleteHtmlAttributeSanitization.qll | 7 ------- .../security/dataflow/IndirectCommandInjection.qll | 7 ------- .../javascript/security/dataflow/InsecureDownload.qll | 7 ------- .../security/dataflow/InsecureRandomness.qll | 7 ------- .../security/dataflow/InsufficientPasswordHash.qll | 7 ------- .../javascript/security/dataflow/LogInjection.qll | 7 ------- .../security/dataflow/LoopBoundInjection.qll | 8 -------- .../javascript/security/dataflow/NosqlInjection.qll | 8 -------- .../javascript/security/dataflow/PostMessageStar.qll | 7 ------- .../security/dataflow/PrototypePollutingAssignment.qll | 6 ------ .../security/dataflow/PrototypePollution.qll | 10 ---------- .../javascript/security/dataflow/ReflectedXss.qll | 7 ------- .../javascript/security/dataflow/RegExpInjection.qll | 7 ------- .../security/dataflow/RemotePropertyInjection.qll | 7 ------- .../javascript/security/dataflow/RequestForgery.qll | 8 -------- .../security/dataflow/ServerSideUrlRedirect.qll | 9 --------- .../dataflow/ShellCommandInjectionFromEnvironment.qll | 7 ------- .../javascript/security/dataflow/SqlInjection.qll | 7 ------- .../security/dataflow/StackTraceExposure.qll | 7 ------- .../semmle/javascript/security/dataflow/StoredXss.qll | 7 ------- .../security/dataflow/TaintedFormatString.qll | 8 -------- .../javascript/security/dataflow/TaintedPath.qll | 7 ------- .../security/dataflow/TemplateObjectInjection.qll | 7 ------- .../TypeConfusionThroughParameterTampering.qll | 8 -------- .../security/dataflow/UnsafeDeserialization.qll | 7 ------- .../security/dataflow/UnsafeDynamicMethodAccess.qll | 8 -------- .../security/dataflow/UnsafeHtmlConstruction.qll | 7 ------- .../security/dataflow/UnsafeJQueryPlugin.qll | 8 -------- .../dataflow/UnsafeShellCommandConstruction.qll | 7 ------- .../security/dataflow/UnvalidatedDynamicMethodCall.qll | 9 --------- .../semmle/javascript/security/dataflow/XmlBomb.qll | 7 ------- .../javascript/security/dataflow/XpathInjection.qll | 8 -------- .../javascript/security/dataflow/XssThroughDom.qll | 7 ------- .../ql/lib/semmle/javascript/security/dataflow/Xxe.qll | 7 ------- .../semmle/javascript/security/dataflow/ZipSlip.qll | 7 ------- 55 files changed, 1 insertion(+), 394 deletions(-) delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/BrokenCryptoAlgorithm.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/BuildArtifactLeak.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLogging.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/CleartextStorage.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirect.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjection.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/CommandInjection.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/ConditionalBypass.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/CorsMisconfigurationForCredentials.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/DeepObjectResourceExhaustion.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/DifferentKindsComparisonBypass.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXss.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/ExceptionXss.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/FileAccessToHttp.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedCredentials.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedDataInterpretedAsCode.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGeneration.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/HttpToFileAccess.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/ImproperCodeSanitization.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/IncompleteHtmlAttributeSanitization.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/IndirectCommandInjection.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/InsecureDownload.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/InsecureRandomness.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/InsufficientPasswordHash.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/LogInjection.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjection.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/NosqlInjection.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/PostMessageStar.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignment.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollution.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/ReflectedXss.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/RegExpInjection.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/RemotePropertyInjection.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/RequestForgery.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirect.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/ShellCommandInjectionFromEnvironment.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/SqlInjection.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/StackTraceExposure.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/StoredXss.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatString.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPath.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/TemplateObjectInjection.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTampering.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDeserialization.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDynamicMethodAccess.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstruction.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstruction.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCall.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/XmlBomb.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/XpathInjection.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDom.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/Xxe.qll delete mode 100644 javascript/ql/lib/semmle/javascript/security/dataflow/ZipSlip.qll diff --git a/javascript/ql/lib/change-notes/2022-11-17-deleted-deps.md b/javascript/ql/lib/change-notes/2022-11-17-deleted-deps.md index e5f1a1c6f56..eade7244ce1 100644 --- a/javascript/ql/lib/change-notes/2022-11-17-deleted-deps.md +++ b/javascript/ql/lib/change-notes/2022-11-17-deleted-deps.md @@ -3,3 +3,4 @@ category: minorAnalysis --- * Deleted the deprecated `Instance` class from the `Vue` module. * Deleted the deprecated `VHtmlSourceWrite` class from `DomBasedXssQuery.qll`. +* Deleted all the deprecated `[QueryName].qll` files from the `javascript/ql/lib/semmle/javascript/security/dataflow` folder, use the corresponding `[QueryName]Query.qll` files instead. \ No newline at end of file diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/BrokenCryptoAlgorithm.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/BrokenCryptoAlgorithm.qll deleted file mode 100644 index 43a56b14dbc..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/BrokenCryptoAlgorithm.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `BrokenCryptoAlgorithmQuery` instead. */ - -import javascript -private import BrokenCryptoAlgorithmQuery as BrokenCryptoAlgorithmQuery // ignore-query-import - -/** DEPRECATED. Import `BrokenCryptoAlgorithmQuery` instead. */ -deprecated module BrokenCryptoAlgorithm = BrokenCryptoAlgorithmQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/BuildArtifactLeak.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/BuildArtifactLeak.qll deleted file mode 100644 index f4853263d63..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/BuildArtifactLeak.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `BuildArtifactLeakQuery` instead. */ - -import javascript -private import BuildArtifactLeakQuery as BuildArtifactLeakQuery // ignore-query-import - -/** DEPRECATED. Import `BuildArtifactLeakQuery` instead. */ -deprecated module BuildArtifactLeak = BuildArtifactLeakQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLogging.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLogging.qll deleted file mode 100644 index 40f18772fb3..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLogging.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `CleartextLoggingQuery` instead. */ - -import javascript -private import CleartextLoggingQuery as CleartextLoggingQuery // ignore-query-import - -/** DEPRECATED. Import `CleartextLoggingQuery` instead. */ -deprecated module CleartextLogging = CleartextLoggingQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextStorage.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextStorage.qll deleted file mode 100644 index ac6bc090d66..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextStorage.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `CleartextStorageQuery` instead. */ - -import javascript -private import CleartextStorageQuery as CleartextStorageQuery // ignore-query-import - -/** DEPRECATED. Import `CleartextStorageQuery` instead. */ -deprecated module CleartextStorage = CleartextStorageQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirect.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirect.qll deleted file mode 100644 index 744646e168c..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirect.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** DEPRECATED. Import `ClientSideUrlRedirectQuery` instead. */ - -import javascript -import UrlConcatenation -private import ClientSideUrlRedirectQuery as ClientSideUrlRedirectQuery // ignore-query-import - -/** DEPRECATED. Import `ClientSideUrlRedirectQuery` instead. */ -deprecated module ClientSideUrlRedirect = ClientSideUrlRedirectQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjection.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjection.qll deleted file mode 100644 index 6c03cef6cd3..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjection.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `CodeInjectionQuery` instead. */ - -import javascript -private import CodeInjectionQuery as CodeInjectionQuery // ignore-query-import - -/** DEPRECATED. Import `CodeInjectionQuery` instead. */ -deprecated module CodeInjection = CodeInjectionQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CommandInjection.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CommandInjection.qll deleted file mode 100644 index b424c3695e1..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CommandInjection.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `CommandInjectionQuery` instead. */ - -import javascript -private import CommandInjectionQuery as CommandInjectionQuery // ignore-query-import - -/** DEPRECATED. Import `CommandInjectionQuery` instead. */ -deprecated module CommandInjection = CommandInjectionQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ConditionalBypass.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ConditionalBypass.qll deleted file mode 100644 index 54f1e9418fc..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ConditionalBypass.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `ConditionalBypassQuery` instead. */ - -import javascript -private import ConditionalBypassQuery as ConditionalBypassQuery // ignore-query-import - -/** DEPRECATED. Import `ConditionalBypassQuery` instead. */ -deprecated module ConditionalBypass = ConditionalBypassQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CorsMisconfigurationForCredentials.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CorsMisconfigurationForCredentials.qll deleted file mode 100644 index 06a6378e8ef..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CorsMisconfigurationForCredentials.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `CorsMisconfigurationForCredentialsQuery` instead. */ - -import javascript -private import CorsMisconfigurationForCredentialsQuery as CorsMisconfigurationForCredentialsQuery // ignore-query-import - -/** DEPRECATED. Import `CorsMisconfigurationForCredentialsQuery` instead. */ -deprecated module CorsMisconfigurationForCredentials = CorsMisconfigurationForCredentialsQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DeepObjectResourceExhaustion.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DeepObjectResourceExhaustion.qll deleted file mode 100644 index 82d9f4156a5..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DeepObjectResourceExhaustion.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** DEPRECATED. Import `DeepObjectResourceExhaustionQuery` instead. */ - -import javascript -import semmle.javascript.security.TaintedObject -private import DeepObjectResourceExhaustionQuery as DeepObjectResourceExhaustionQuery // ignore-query-import - -/** DEPRECATED. Import `DeepObjectResourceExhaustionQuery` instead. */ -deprecated module DeepObjectResourceExhaustion = DeepObjectResourceExhaustionQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DifferentKindsComparisonBypass.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DifferentKindsComparisonBypass.qll deleted file mode 100644 index e28dc5e34f1..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DifferentKindsComparisonBypass.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `DifferentKindsComparisonBypassQuery` instead. */ - -import javascript -private import DifferentKindsComparisonBypassQuery as DifferentKindsComparisonBypassQuery // ignore-query-import - -/** DEPRECATED. Import `DifferentKindsComparisonBypassQuery` instead. */ -deprecated module DifferentKindsComparisonBypass = DifferentKindsComparisonBypassQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXss.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXss.qll deleted file mode 100644 index 9a687eb06a0..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXss.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `DomBasedXssQuery` instead. */ - -import javascript -private import DomBasedXssQuery as DomBasedXssQuery // ignore-query-import - -/** DEPRECATED. Import `DomBasedXssQuery` instead. */ -deprecated module DomBasedXss = DomBasedXssQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ExceptionXss.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ExceptionXss.qll deleted file mode 100644 index 7f133319438..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ExceptionXss.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `ExceptionXssQuery` instead. */ - -import javascript -private import ExceptionXssQuery as ExceptionXssQuery // ignore-query-import - -/** DEPRECATED. Import `ExceptionXssQuery` instead. */ -deprecated module ExceptionXss = ExceptionXssQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/FileAccessToHttp.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/FileAccessToHttp.qll deleted file mode 100644 index 7b6e88d0669..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/FileAccessToHttp.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `FileAccessToHttpQuery` instead. */ - -import javascript -private import FileAccessToHttpQuery as FileAccessToHttpQuery // ignore-query-import - -/** DEPRECATED. Import `FileAccessToHttpQuery` instead. */ -deprecated module FileAccessToHttp = FileAccessToHttpQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedCredentials.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedCredentials.qll deleted file mode 100644 index 9fabc93d9ac..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedCredentials.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `HardcodedCredentialsQuery` instead. */ - -import javascript -private import HardcodedCredentialsQuery as HardcodedCredentialsQuery // ignore-query-import - -/** DEPRECATED. Import `HardcodedCredentialsQuery` instead. */ -deprecated module HardcodedCredentials = HardcodedCredentialsQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedDataInterpretedAsCode.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedDataInterpretedAsCode.qll deleted file mode 100644 index e1ca461183a..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedDataInterpretedAsCode.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `HardcodedDataInterpretedAsCodeQuery` instead. */ - -import javascript -private import HardcodedDataInterpretedAsCodeQuery as HardcodedDataInterpretedAsCodeQuery // ignore-query-import - -/** DEPRECATED. Import `HardcodedDataInterpretedAsCodeQuery` instead. */ -deprecated module HardcodedDataInterpretedAsCode = HardcodedDataInterpretedAsCodeQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGeneration.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGeneration.qll deleted file mode 100644 index 18f90400e3d..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGeneration.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `HostHeaderPoisoningInEmailGenerationQuery` instead. */ - -import javascript -private import HostHeaderPoisoningInEmailGenerationQuery as HostHeaderPoisoningInEmailGenerationQuery // ignore-query-import - -/** DEPRECATED. Import `HostHeaderPoisoningInEmailGenerationQuery` instead. */ -deprecated module HostHeaderPoisoningInEmailGeneration = HostHeaderPoisoningInEmailGenerationQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/HttpToFileAccess.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/HttpToFileAccess.qll deleted file mode 100644 index 0569ba0e692..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/HttpToFileAccess.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `HttpToFileAccessQuery` instead. */ - -import javascript -private import HttpToFileAccessQuery as HttpToFileAccessQuery // ignore-query-import - -/** DEPRECATED. Import `HttpToFileAccessQuery` instead. */ -deprecated module HttpToFileAccess = HttpToFileAccessQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ImproperCodeSanitization.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ImproperCodeSanitization.qll deleted file mode 100644 index 7b221c4edb5..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ImproperCodeSanitization.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `ImproperCodeSanitizationQuery` instead. */ - -import javascript -private import ImproperCodeSanitizationQuery as ImproperCodeSanitizationQuery // ignore-query-import - -/** DEPRECATED. Import `ImproperCodeSanitizationQuery` instead. */ -deprecated module ImproperCodeSanitization = ImproperCodeSanitizationQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/IncompleteHtmlAttributeSanitization.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/IncompleteHtmlAttributeSanitization.qll deleted file mode 100644 index f036a3388df..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/IncompleteHtmlAttributeSanitization.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `IncompleteHtmlAttributeSanitizationQuery` instead. */ - -import javascript -private import IncompleteHtmlAttributeSanitizationQuery as IncompleteHtmlAttributeSanitizationQuery // ignore-query-import - -/** DEPRECATED. Import `IncompleteHtmlAttributeSanitizationQuery` instead. */ -deprecated module IncompleteHtmlAttributeSanitization = IncompleteHtmlAttributeSanitizationQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/IndirectCommandInjection.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/IndirectCommandInjection.qll deleted file mode 100644 index 64e24b9ceba..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/IndirectCommandInjection.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `IndirectCommandInjectionQuery` instead. */ - -import javascript -private import IndirectCommandInjectionQuery as IndirectCommandInjectionQuery // ignore-query-import - -/** DEPRECATED. Import `IndirectCommandInjectionQuery` instead. */ -deprecated module IndirectCommandInjection = IndirectCommandInjectionQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureDownload.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureDownload.qll deleted file mode 100644 index 83c1d179243..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureDownload.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `InsecureDownloadQuery` instead. */ - -import javascript -private import InsecureDownloadQuery as InsecureDownloadQuery // ignore-query-import - -/** DEPRECATED. Import `InsecureDownloadQuery` instead. */ -deprecated module InsecureDownload = InsecureDownloadQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureRandomness.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureRandomness.qll deleted file mode 100644 index 2672d48bee7..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureRandomness.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `InsecureRandomnessQuery` instead. */ - -import javascript -private import InsecureRandomnessQuery as InsecureRandomnessQuery // ignore-query-import - -/** DEPRECATED. Import `InsecureRandomnessQuery` instead. */ -deprecated module InsecureRandomness = InsecureRandomnessQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/InsufficientPasswordHash.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/InsufficientPasswordHash.qll deleted file mode 100644 index f3d814e3601..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/InsufficientPasswordHash.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `InsufficientPasswordHashQuery` instead. */ - -import javascript -private import InsufficientPasswordHashQuery as InsufficientPasswordHashQuery // ignore-query-import - -/** DEPRECATED. Import `InsufficientPasswordHashQuery` instead. */ -deprecated module InsufficientPasswordHash = InsufficientPasswordHashQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/LogInjection.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/LogInjection.qll deleted file mode 100644 index 95dec6e87fd..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/LogInjection.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `LogInjectionQuery` instead. */ - -import javascript -private import LogInjectionQuery as LogInjectionQuery // ignore-query-import - -/** DEPRECATED. Import `LogInjectionQuery` instead. */ -deprecated module LogInjection = LogInjectionQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjection.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjection.qll deleted file mode 100644 index ab65fb9705e..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjection.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** DEPRECATED. Import `LoopBoundInjectionQuery` instead. */ - -import javascript -import semmle.javascript.security.TaintedObject -private import LoopBoundInjectionQuery as LoopBoundInjectionQuery // ignore-query-import - -/** DEPRECATED. Import `LoopBoundInjectionQuery` instead. */ -deprecated module LoopBoundInjection = LoopBoundInjectionQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/NosqlInjection.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/NosqlInjection.qll deleted file mode 100644 index 8534cad9a7e..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/NosqlInjection.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** DEPRECATED. Import `NosqlInjectionQuery` instead. */ - -import javascript -import semmle.javascript.security.TaintedObject -private import NosqlInjectionQuery as NosqlInjectionQuery // ignore-query-import - -/** DEPRECATED. Import `NosqlInjectionQuery` instead. */ -deprecated module NosqlInjection = NosqlInjectionQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/PostMessageStar.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/PostMessageStar.qll deleted file mode 100644 index 392466f32ab..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/PostMessageStar.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `PostMessageStarQuery` instead. */ - -import javascript -private import PostMessageStarQuery as PostMessageStarQuery // ignore-query-import - -/** DEPRECATED. Import `PostMessageStarQuery` instead. */ -deprecated module PostMessageStar = PostMessageStarQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignment.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignment.qll deleted file mode 100644 index 6663d74e91a..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignment.qll +++ /dev/null @@ -1,6 +0,0 @@ -/** DEPRECATED. Import `PrototypePollutingAssignmentQuery` instead. */ - -private import PrototypePollutingAssignmentQuery as PrototypePollutingAssignmentQuery // ignore-query-import - -/** DEPRECATED. Import `PrototypePollutingAssignmentQuery` instead. */ -deprecated module PrototypePollutingAssignment = PrototypePollutingAssignmentQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollution.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollution.qll deleted file mode 100644 index 7783a551775..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollution.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** DEPRECATED. Import `PrototypePollutionQuery` instead. */ - -import javascript -import semmle.javascript.security.TaintedObject -import semmle.javascript.dependencies.Dependencies -import semmle.javascript.dependencies.SemVer -private import PrototypePollutionQuery as PrototypePollutionQuery // ignore-query-import - -/** DEPRECATED. Import `PrototypePollutionQuery` instead. */ -deprecated module PrototypePollution = PrototypePollutionQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ReflectedXss.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ReflectedXss.qll deleted file mode 100644 index 92ffd84fdda..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ReflectedXss.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `ReflectedXssQuery` instead. */ - -import javascript -private import ReflectedXssQuery as ReflectedXssQuery // ignore-query-import - -/** DEPRECATED. Import `ReflectedXssQuery` instead. */ -deprecated module ReflectedXss = ReflectedXssQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/RegExpInjection.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/RegExpInjection.qll deleted file mode 100644 index c1a27c66354..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/RegExpInjection.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `RegExpInjectionQuery` instead. */ - -import javascript -private import RegExpInjectionQuery as RegExpInjectionQuery // ignore-query-import - -/** DEPRECATED. Import `RegExpInjectionQuery` instead. */ -deprecated module RegExpInjection = RegExpInjectionQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/RemotePropertyInjection.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/RemotePropertyInjection.qll deleted file mode 100644 index f19b02fdcb3..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/RemotePropertyInjection.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `RemotePropertyInjectionQuery` instead. */ - -import javascript -private import RemotePropertyInjectionQuery as RemotePropertyInjectionQuery // ignore-query-import - -/** DEPRECATED. Import `RemotePropertyInjectionQuery` instead. */ -deprecated module RemotePropertyInjection = RemotePropertyInjectionQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/RequestForgery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/RequestForgery.qll deleted file mode 100644 index a4612bf360d..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/RequestForgery.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** DEPRECATED. Import `RequestForgeryQuery` instead. */ - -import javascript -import UrlConcatenation -private import RequestForgeryQuery as RequestForgeryQuery // ignore-query-import - -/** DEPRECATED. Import `RequestForgeryQuery` instead. */ -deprecated module RequestForgery = RequestForgeryQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirect.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirect.qll deleted file mode 100644 index 25d27e77f2f..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirect.qll +++ /dev/null @@ -1,9 +0,0 @@ -/** DEPRECATED. Import `ServerSideUrlRedirectQuery` instead. */ - -import javascript -import RemoteFlowSources -import UrlConcatenation -private import ServerSideUrlRedirectQuery as ServerSideUrlRedirectQuery // ignore-query-import - -/** DEPRECATED. Import `ServerSideUrlRedirectQuery` instead. */ -deprecated module ServerSideUrlRedirect = ServerSideUrlRedirectQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ShellCommandInjectionFromEnvironment.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ShellCommandInjectionFromEnvironment.qll deleted file mode 100644 index af1c0e7a574..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ShellCommandInjectionFromEnvironment.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `ShellCommandInjectionFromEnvironmentQuery` instead. */ - -import javascript -private import ShellCommandInjectionFromEnvironmentQuery as ShellCommandInjectionFromEnvironmentQuery // ignore-query-import - -/** DEPRECATED. Import `ShellCommandInjectionFromEnvironmentQuery` instead. */ -deprecated module ShellCommandInjectionFromEnvironment = ShellCommandInjectionFromEnvironmentQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/SqlInjection.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/SqlInjection.qll deleted file mode 100644 index 32b0d80669b..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/SqlInjection.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `SqlInjectionQuery` instead. */ - -import javascript -private import SqlInjectionQuery as SqlInjectionQuery // ignore-query-import - -/** DEPRECATED. Import `SqlInjectionQuery` instead. */ -deprecated module SqlInjection = SqlInjectionQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/StackTraceExposure.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/StackTraceExposure.qll deleted file mode 100644 index 4211c6fd633..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/StackTraceExposure.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `StackTraceExposureQuery` instead. */ - -import javascript -private import StackTraceExposureQuery as StackTraceExposureQuery // ignore-query-import - -/** DEPRECATED. Import `StackTraceExposureQuery` instead. */ -deprecated module StackTraceExposure = StackTraceExposureQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXss.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXss.qll deleted file mode 100644 index 65536440bcb..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/StoredXss.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `StoredXssQuery` instead. */ - -import javascript -private import StoredXssQuery as StoredXssQuery // ignore-query-import - -/** DEPRECATED. Import `StoredXssQuery` instead. */ -deprecated module StoredXss = StoredXssQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatString.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatString.qll deleted file mode 100644 index a0660580206..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatString.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** DEPRECATED. Import `TaintedFormatStringQuery` instead. */ - -import javascript -import semmle.javascript.security.dataflow.DOM -private import TaintedFormatStringQuery as TaintedFormatStringQuery // ignore-query-import - -/** DEPRECATED. Import `TaintedFormatStringQuery` instead. */ -deprecated module TaintedFormatString = TaintedFormatStringQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPath.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPath.qll deleted file mode 100644 index ffd7d320684..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPath.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `TaintedPathQuery` instead. */ - -import javascript -private import TaintedPathQuery as TaintedPathQuery // ignore-query-import - -/** DEPRECATED. Import `TaintedPathQuery` instead. */ -deprecated module TaintedPath = TaintedPathQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TemplateObjectInjection.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TemplateObjectInjection.qll deleted file mode 100644 index 37f3721d600..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TemplateObjectInjection.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `TemplateObjectInjectionQuery` instead. */ - -import javascript -private import TemplateObjectInjectionQuery as TemplateObjectInjectionQuery // ignore-query-import - -/** DEPRECATED. Import `TemplateObjectInjectionQuery` instead. */ -deprecated module TemplateObjectInjection = TemplateObjectInjectionQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTampering.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTampering.qll deleted file mode 100644 index 44744e0efa3..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTampering.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** DEPRECATED. Import `TypeConfusionThroughParameterTamperingQuery` instead. */ - -import javascript -private import TypeConfusionThroughParameterTamperingQuery as TypeConfusionThroughParameterTamperingQuery // ignore-query-import - -/** DEPRECATED. Import `TypeConfusionThroughParameterTamperingQuery` instead. */ -deprecated module TypeConfusionThroughParameterTampering = - TypeConfusionThroughParameterTamperingQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDeserialization.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDeserialization.qll deleted file mode 100644 index 4b1fd4b58ea..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDeserialization.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `UnsafeDeserializationQuery` instead. */ - -import javascript -private import UnsafeDeserializationQuery as UnsafeDeserializationQuery // ignore-query-import - -/** DEPRECATED. Import `UnsafeDeserializationQuery` instead. */ -deprecated module UnsafeDeserialization = UnsafeDeserializationQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDynamicMethodAccess.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDynamicMethodAccess.qll deleted file mode 100644 index c38bb4cdeb8..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDynamicMethodAccess.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** DEPRECATED. Import `UnsafeDynamicMethodAccessQuery` instead. */ - -import javascript -import PropertyInjectionShared -private import UnsafeDynamicMethodAccessQuery as UnsafeDynamicMethodAccessQuery // ignore-query-import - -/** DEPRECATED. Import `UnsafeDynamicMethodAccessQuery` instead. */ -deprecated module UnsafeDynamicMethodAccess = UnsafeDynamicMethodAccessQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstruction.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstruction.qll deleted file mode 100644 index 8617d3e8724..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstruction.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `UnsafeHtmlConstructionQuery` instead. */ - -import javascript -private import UnsafeHtmlConstructionQuery as UnsafeHtmlConstructionQuery // ignore-query-import - -/** DEPRECATED. Import `UnsafeHtmlConstructionQuery` instead. */ -deprecated module UnsafeHtmlConstruction = UnsafeHtmlConstructionQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll deleted file mode 100644 index 634b7d917aa..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** DEPRECATED. Import `UnsafeJQueryPluginQuery` instead. */ - -import javascript -import semmle.javascript.security.dataflow.Xss -private import UnsafeJQueryPluginQuery as UnsafeJQueryPluginQuery // ignore-query-import - -/** DEPRECATED. Import `UnsafeJQueryPluginQuery` instead. */ -deprecated module UnsafeJQueryPlugin = UnsafeJQueryPluginQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstruction.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstruction.qll deleted file mode 100644 index 7e9470a7334..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstruction.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `UnsafeShellCommandConstructionQuery` instead. */ - -import javascript -private import UnsafeShellCommandConstructionQuery as UnsafeShellCommandConstructionQuery // ignore-query-import - -/** DEPRECATED. Import `UnsafeShellCommandConstructionQuery` instead. */ -deprecated module UnsafeShellCommandConstruction = UnsafeShellCommandConstructionQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCall.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCall.qll deleted file mode 100644 index f5af520e0d7..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCall.qll +++ /dev/null @@ -1,9 +0,0 @@ -/** DEPRECATED. Import `UnvalidatedDynamicMethodCallQuery` instead. */ - -import javascript -import semmle.javascript.frameworks.Express -import PropertyInjectionShared -private import UnvalidatedDynamicMethodCallQuery as UnvalidatedDynamicMethodCallQuery // ignore-query-import - -/** DEPRECATED. Import `UnvalidatedDynamicMethodCallQuery` instead. */ -deprecated module UnvalidatedDynamicMethodCall = UnvalidatedDynamicMethodCallQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XmlBomb.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XmlBomb.qll deleted file mode 100644 index 45615a92000..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XmlBomb.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `XmlBombQuery` instead. */ - -import javascript -private import XmlBombQuery as XmlBombQuery // ignore-query-import - -/** DEPRECATED. Import `XmlBombQuery` instead. */ -deprecated module XmlBomb = XmlBombQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XpathInjection.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XpathInjection.qll deleted file mode 100644 index 15f5413a620..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XpathInjection.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** DEPRECATED. Import `XpathInjectionQuery` instead. */ - -import javascript -import semmle.javascript.security.dataflow.DOM -private import XpathInjectionQuery as XpathInjectionQuery // ignore-query-import - -/** DEPRECATED. Import `XpathInjectionQuery` instead. */ -deprecated module XpathInjection = XpathInjectionQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDom.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDom.qll deleted file mode 100644 index 0d3096d5c1b..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDom.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `XssThroughDomQuery` instead. */ - -import javascript -private import XssThroughDomQuery as XssThroughDomQuery // ignore-query-import - -/** DEPRECATED. Import `XssThroughDomQuery` instead. */ -deprecated module XssThroughDom = XssThroughDomQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/Xxe.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/Xxe.qll deleted file mode 100644 index 5275c96bada..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/Xxe.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `XxeQuery` instead. */ - -import javascript -private import XxeQuery as XxeQuery // ignore-query-import - -/** DEPRECATED. Import `XxeQuery` instead. */ -deprecated module Xxe = XxeQuery; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ZipSlip.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ZipSlip.qll deleted file mode 100644 index cc3fd8a2f27..00000000000 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ZipSlip.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** DEPRECATED. Import `ZipSlipQuery` instead. */ - -import javascript -private import ZipSlipQuery as ZipSlipQuery // ignore-query-import - -/** DEPRECATED. Import `ZipSlipQuery` instead. */ -deprecated module ZipSlip = ZipSlipQuery; From ba2734909f58a07be155cf71068f61283191e79f Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 17 Nov 2022 15:22:14 +0100 Subject: [PATCH 378/796] JS: don't use deprecated files in tests --- .../PoI/CommandInjectionPoIConfiguration.ql | 6 +++--- .../experimental/PoI/TaintedPathPoIConfiguration.ql | 2 +- .../ql/test/experimental/PoI/XssPoIConfiguration.ql | 8 ++++---- .../test/library-tests/frameworks/Nest/Consistency.ql | 4 ++-- .../test/query-tests/Security/CWE-078/Consistency.ql | 10 +++++----- .../CWE-079/ExceptionXss/ConsistencyExceptionXss.ql | 2 +- .../CWE-079/ReflectedXss/ConsistencyReflectedXss.ql | 2 +- .../Security/CWE-079/StoredXss/ConsistencyStoredXss.ql | 2 +- .../ConsistencyUnsafeHtmlConstruction.ql | 2 +- .../ConsistencyUnsafeJQueryPlugin.ql | 2 +- .../CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql | 2 +- .../Security/CWE-089/untyped/Consistency.ql | 4 ++-- 12 files changed, 23 insertions(+), 23 deletions(-) diff --git a/javascript/ql/test/experimental/PoI/CommandInjectionPoIConfiguration.ql b/javascript/ql/test/experimental/PoI/CommandInjectionPoIConfiguration.ql index 4b7e798b226..5ea8c17fc28 100644 --- a/javascript/ql/test/experimental/PoI/CommandInjectionPoIConfiguration.ql +++ b/javascript/ql/test/experimental/PoI/CommandInjectionPoIConfiguration.ql @@ -4,9 +4,9 @@ import javascript import experimental.poi.PoI -import semmle.javascript.security.dataflow.CommandInjection -import semmle.javascript.security.dataflow.IndirectCommandInjection -import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironment +import semmle.javascript.security.dataflow.CommandInjectionQuery as CommandInjection +import semmle.javascript.security.dataflow.IndirectCommandInjectionQuery as IndirectCommandInjection +import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironmentQuery as ShellCommandInjectionFromEnvironment class MyDataFlowConfigurationPoIs extends DataFlowConfigurationPoI, ActivePoI { } diff --git a/javascript/ql/test/experimental/PoI/TaintedPathPoIConfiguration.ql b/javascript/ql/test/experimental/PoI/TaintedPathPoIConfiguration.ql index e21bc68f68c..784abb7e85b 100644 --- a/javascript/ql/test/experimental/PoI/TaintedPathPoIConfiguration.ql +++ b/javascript/ql/test/experimental/PoI/TaintedPathPoIConfiguration.ql @@ -4,7 +4,7 @@ import javascript import experimental.poi.PoI -import semmle.javascript.security.dataflow.TaintedPath +import semmle.javascript.security.dataflow.TaintedPathQuery as TaintedPath class MyDataflowRelatedPoIs extends DataFlowConfigurationPoI, ActivePoI { } diff --git a/javascript/ql/test/experimental/PoI/XssPoIConfiguration.ql b/javascript/ql/test/experimental/PoI/XssPoIConfiguration.ql index e18b2e96913..05b43a06cd1 100644 --- a/javascript/ql/test/experimental/PoI/XssPoIConfiguration.ql +++ b/javascript/ql/test/experimental/PoI/XssPoIConfiguration.ql @@ -4,10 +4,10 @@ import javascript import experimental.poi.PoI -import semmle.javascript.security.dataflow.ReflectedXss -import semmle.javascript.security.dataflow.StoredXss -import semmle.javascript.security.dataflow.DomBasedXss -import semmle.javascript.security.dataflow.ExceptionXss +import semmle.javascript.security.dataflow.ReflectedXssQuery as ReflectedXss +import semmle.javascript.security.dataflow.StoredXssQuery as StoredXss +import semmle.javascript.security.dataflow.DomBasedXssQuery as DomBasedXss +import semmle.javascript.security.dataflow.ExceptionXssQuery as ExceptionXss class MyDataFlowConfigurationPoIs extends DataFlowConfigurationPoI, ActivePoI { } diff --git a/javascript/ql/test/library-tests/frameworks/Nest/Consistency.ql b/javascript/ql/test/library-tests/frameworks/Nest/Consistency.ql index 787d0a5fdc4..e96cbc4b70f 100644 --- a/javascript/ql/test/library-tests/frameworks/Nest/Consistency.ql +++ b/javascript/ql/test/library-tests/frameworks/Nest/Consistency.ql @@ -1,3 +1,3 @@ import testUtilities.ConsistencyChecking -import semmle.javascript.security.dataflow.ReflectedXss -import semmle.javascript.security.dataflow.ServerSideUrlRedirect +import semmle.javascript.security.dataflow.ReflectedXssQuery as ReflectedXss +import semmle.javascript.security.dataflow.ServerSideUrlRedirectQuery as ServerSideUrlRedirect diff --git a/javascript/ql/test/query-tests/Security/CWE-078/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-078/Consistency.ql index 6ae7fd0a970..c48af1a7971 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/Consistency.ql +++ b/javascript/ql/test/query-tests/Security/CWE-078/Consistency.ql @@ -1,10 +1,10 @@ import javascript import testUtilities.ConsistencyChecking -import semmle.javascript.security.dataflow.CommandInjection -import semmle.javascript.security.dataflow.IndirectCommandInjection -import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironment -import semmle.javascript.security.dataflow.UnsafeShellCommandConstruction -import semmle.javascript.security.dataflow.SecondOrderCommandInjectionQuery +import semmle.javascript.security.dataflow.CommandInjectionQuery as CommandInjection +import semmle.javascript.security.dataflow.IndirectCommandInjectionQuery as IndirectCommandInjection +import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironmentQuery as ShellCommandInjectionFromEnvironment +import semmle.javascript.security.dataflow.UnsafeShellCommandConstructionQuery as UnsafeShellCommandConstruction +import semmle.javascript.security.dataflow.SecondOrderCommandInjectionQuery as SecondOrderCommandInjectionQuery class CommandInjectionConsistency extends ConsistencyConfiguration { CommandInjectionConsistency() { this = "ComandInjection" } diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ConsistencyExceptionXss.ql b/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ConsistencyExceptionXss.ql index 584faa27c11..5b40a626e4a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ConsistencyExceptionXss.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/ExceptionXss/ConsistencyExceptionXss.ql @@ -1,3 +1,3 @@ import javascript import testUtilities.ConsistencyChecking -import semmle.javascript.security.dataflow.ExceptionXss as ExceptionXss +import semmle.javascript.security.dataflow.ExceptionXssQuery as ExceptionXss diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ConsistencyReflectedXss.ql b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ConsistencyReflectedXss.ql index 76785917fb5..3200271daa6 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ConsistencyReflectedXss.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ConsistencyReflectedXss.ql @@ -1,3 +1,3 @@ import javascript import testUtilities.ConsistencyChecking -import semmle.javascript.security.dataflow.ReflectedXss as ReflectedXss +import semmle.javascript.security.dataflow.ReflectedXssQuery as ReflectedXss diff --git a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/ConsistencyStoredXss.ql b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/ConsistencyStoredXss.ql index 63794389bab..c75dbb17b71 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/ConsistencyStoredXss.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss/ConsistencyStoredXss.ql @@ -1,3 +1,3 @@ import javascript import testUtilities.ConsistencyChecking -import semmle.javascript.security.dataflow.StoredXss as StoredXss +import semmle.javascript.security.dataflow.StoredXssQuery as StoredXss diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/ConsistencyUnsafeHtmlConstruction.ql b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/ConsistencyUnsafeHtmlConstruction.ql index 823644730b2..f09744a4d6c 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/ConsistencyUnsafeHtmlConstruction.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/ConsistencyUnsafeHtmlConstruction.ql @@ -1,3 +1,3 @@ import javascript import testUtilities.ConsistencyChecking -import semmle.javascript.security.dataflow.UnsafeHtmlConstruction as UnsafeHtmlConstruction +import semmle.javascript.security.dataflow.UnsafeHtmlConstructionQuery as UnsafeHtmlConstruction diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/ConsistencyUnsafeJQueryPlugin.ql b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/ConsistencyUnsafeJQueryPlugin.ql index 6a16badb37f..b77df2a8d67 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/ConsistencyUnsafeJQueryPlugin.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/ConsistencyUnsafeJQueryPlugin.ql @@ -1,3 +1,3 @@ import javascript import testUtilities.ConsistencyChecking -import semmle.javascript.security.dataflow.UnsafeJQueryPlugin as UnsafeJqueryPlugin +import semmle.javascript.security.dataflow.UnsafeJQueryPluginQuery as UnsafeJqueryPlugin diff --git a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql index 118a875f15d..75416d5a0dc 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql +++ b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/ConsistencyXssThroughDom.ql @@ -1,3 +1,3 @@ import javascript import testUtilities.ConsistencyChecking -import semmle.javascript.security.dataflow.XssThroughDom as ThroughDomXss +import semmle.javascript.security.dataflow.XssThroughDomQuery as ThroughDomXss diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-089/untyped/Consistency.ql index 0ab292b7b82..bd24059f31c 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/Consistency.ql +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/Consistency.ql @@ -1,4 +1,4 @@ import javascript import testUtilities.ConsistencyChecking -import semmle.javascript.security.dataflow.SqlInjection -import semmle.javascript.security.dataflow.NosqlInjection +import semmle.javascript.security.dataflow.SqlInjectionQuery as SqlInjection +import semmle.javascript.security.dataflow.NosqlInjectionQuery as NosqlInjection From 468a879c1f5e96af8c4b13d13ed8b96283f6472b Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 17 Nov 2022 15:27:39 +0100 Subject: [PATCH 379/796] Python: delete dead code. thanks QL-for-QL --- python/ql/lib/semmle/python/frameworks/PEP249.qll | 8 -------- 1 file changed, 8 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/PEP249.qll b/python/ql/lib/semmle/python/frameworks/PEP249.qll index 6dee86b5346..594c3e938e2 100644 --- a/python/ql/lib/semmle/python/frameworks/PEP249.qll +++ b/python/ql/lib/semmle/python/frameworks/PEP249.qll @@ -111,14 +111,6 @@ module PEP249 { private class CursorCall extends InstanceSource, DataFlow::CallCfgNode { CursorCall() { this.getFunction() = methodRef() } } - - /** Gets a reference to a result of calling the `cursor` method on a database connection. */ - private DataFlow::TypeTrackingNode methodResult(DataFlow::TypeTracker t) { - t.start() and - result.asCfgNode().(CallNode).getFunction() = methodRef().asCfgNode() - or - exists(DataFlow::TypeTracker t2 | result = methodResult(t2).track(t2, t)) - } } /** From 5deb16e58cd40f7f181a1caaaeef3772d7c88e8a Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Fri, 18 Nov 2022 18:14:53 +1300 Subject: [PATCH 380/796] Ruby: Remove redundant predicate The existing barrier guard machinery recognises guards such as `if x and y`, so there's no need to explicitly model them. --- .../codeql/ruby/dataflow/BarrierGuards.qll | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll index 16e965f6657..92fb759c468 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll @@ -35,8 +35,6 @@ private predicate stringConstCompare(CfgNodes::AstCfgNode guard, CfgNode testedN stringConstCompareOr(guard, def, branch) and stringConstCompare(g.getLeftOperand(), testedNode, _) ) - or - stringConstCompareAnd(guard, testedNode, branch) } /** @@ -57,23 +55,6 @@ private predicate stringConstCompareOr( ) } -/** - * Holds if `guard` is an `and` expression containing a string comparison guard in either operand. - * For example: - * - * ```rb - * x == "foo" and other_condition() - * other_condition() and x == "foo" - * ``` - */ -private predicate stringConstCompareAnd( - CfgNodes::ExprNodes::BinaryOperationCfgNode guard, CfgNode testedNode, boolean branch -) { - guard.getExpr() instanceof LogicalAndExpr and - branch = true and - stringConstCompare(guard.getAnOperand(), testedNode, branch) -} - /** * A validation of value by comparing with a constant string value, for example * in: From 376d4e03a144178d7ed2744201c449e808c0a7db Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Fri, 18 Nov 2022 18:17:02 +1300 Subject: [PATCH 381/796] Ruby: Cache some barrier guard predicates --- ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll index 92fb759c468..f1f8d2c5b46 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll @@ -9,6 +9,7 @@ private import codeql.ruby.ast.internal.Constant private import codeql.ruby.InclusionTests private import codeql.ruby.ast.internal.Literal +cached private predicate stringConstCompare(CfgNodes::AstCfgNode guard, CfgNode testedNode, boolean branch) { exists(CfgNodes::ExprNodes::ComparisonOperationCfgNode c | c = guard and @@ -102,6 +103,7 @@ deprecated class StringConstCompare extends DataFlow::BarrierGuard, } } +cached private predicate stringConstArrayInclusionCall( CfgNodes::AstCfgNode guard, CfgNode testedNode, boolean branch ) { From 23dc977d48190f5411022504c09bdcab3d953649 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 18 Nov 2022 10:29:42 +0100 Subject: [PATCH 382/796] add a severity to incompleteswitchoverenum.ql to fix a compiler warning --- go/ql/examples/snippets/incompleteswitchoverenum.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/go/ql/examples/snippets/incompleteswitchoverenum.ql b/go/ql/examples/snippets/incompleteswitchoverenum.ql index b201e55089e..1ded8d0a1ab 100644 --- a/go/ql/examples/snippets/incompleteswitchoverenum.ql +++ b/go/ql/examples/snippets/incompleteswitchoverenum.ql @@ -2,6 +2,7 @@ * @name Incomplete switch over enum * @description A switch statement of enum type should explicitly reference each * of the members of that enum. + * @severity warning * @kind problem * @id go/examples/incomplete-switch */ From 7c091fa6cd2ed857c03894f9c1881719dc84b817 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 18 Nov 2022 10:31:42 +0100 Subject: [PATCH 383/796] also compile the examples folders as part of the compilation check --- .github/workflows/compile-queries.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/compile-queries.yml b/.github/workflows/compile-queries.yml index 94378250c85..d053b1cb7c1 100644 --- a/.github/workflows/compile-queries.yml +++ b/.github/workflows/compile-queries.yml @@ -26,7 +26,7 @@ jobs: if: ${{ github.event_name == 'pull_request' }} uses: actions/cache@v3 with: - path: '*/ql/src/.cache' + path: '**/.cache' key: codeql-compile-pr-${{ github.sha }} # deliberately not using the `compile-compile-main` keys here. restore-keys: | codeql-compile-${{ github.base_ref }}-${{ env.merge-base }} @@ -36,7 +36,7 @@ jobs: if: ${{ github.event_name != 'pull_request' }} uses: actions/cache@v3 with: - path: '*/ql/src/.cache' + path: '**/.cache' key: codeql-compile-${{ github.ref_name }}-${{ github.sha }} # just fill on main restore-keys: | # restore from another random commit, to speed up compilation. codeql-compile-${{ github.ref_name }}- @@ -51,7 +51,7 @@ jobs: # run with --check-only if running in a PR (github.sha != main) if : ${{ github.event_name == 'pull_request' }} shell: bash - run: codeql query compile -j0 */ql/src --keep-going --warnings=error --check-only + run: codeql query compile -j0 */ql/{src,examples} --keep-going --warnings=error --check-only - name: compile queries - full # do full compile if running on main - this populates the cache if : ${{ github.event_name != 'pull_request' }} @@ -59,13 +59,13 @@ jobs: run: | # Move all the existing cache into another folder, so we only preserve the cache for the current queries. mkdir -p ${COMBINED_CACHE_DIR} - rm */ql/src/.cache/{lock,size} + rm -f */ql/{src,examples}/.cache/{lock,size} # -f to avoid errors if the cache is empty. # copy the contents of the .cache folders into the combined cache folder. - cp -r */ql/src/.cache/* ${COMBINED_CACHE_DIR}/ + cp -r */ql/{src,examples}/.cache/* ${COMBINED_CACHE_DIR}/ || : # ignore missing files # clean up the .cache folders - rm -rf */ql/src/.cache/* + rm -rf */ql/{src,examples}/.cache/* # compile the queries - codeql query compile -j0 */ql/src --keep-going --warnings=error --compilation-cache ${COMBINED_CACHE_DIR} + codeql query compile -j0 */ql/{src,examples} --keep-going --warnings=error --compilation-cache ${COMBINED_CACHE_DIR} env: COMBINED_CACHE_DIR: ${{ github.workspace }}/compilation-dir \ No newline at end of file From 5b14ebf22abd25e88786cce9f8a21875ee5780d1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 18 Nov 2022 11:26:00 +0000 Subject: [PATCH 384/796] Post-release preparation for codeql-cli-2.11.4 --- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/typos/qlpack.yml | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index e8c0a17068e..4e0b86be561 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.4.4 +version: 0.4.5-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 4ee5b28070c..75602332e29 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.4.4 +version: 0.4.5-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 41c454bb5c0..3b918b3442d 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.3.4 +version: 1.3.5-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 7ba0669ba7b..18101db5518 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.3.4 +version: 1.3.5-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index bd5cd1b7e16..5103c8f0ab7 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.4.4 +version: 0.4.5-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 6964f93b085..e455b240f04 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.4.4 +version: 0.4.5-dev groups: - csharp - queries diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 0d453d90f88..823bb20f97b 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.3.4 +version: 0.3.5-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 297b6ce7ff9..258d6809c80 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.3.4 +version: 0.3.5-dev groups: - go - queries diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 65e160f8720..dfab979e9bd 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.4.4 +version: 0.4.5-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index b15d45f78f9..50d76873114 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.4.4 +version: 0.4.5-dev groups: - java - queries diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 8e1f29f47e0..fed1085652e 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.3.4 +version: 0.3.5-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index ba9e83a24cd..48d1f2353cf 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.4.4 +version: 0.4.5-dev groups: - javascript - queries diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index 24d2ef3172f..77c5496ea53 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,3 +1,3 @@ name: codeql/suite-helpers -version: 0.3.4 +version: 0.3.5-dev groups: shared diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index ad7d4faa837..2cc69948b1d 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.6.4 +version: 0.6.5-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 6e3ab19be4b..c907e7ee1d0 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.5.4 +version: 0.5.5-dev groups: - python - queries diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index cf26086c71c..d36fc9c53ea 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.4.4 +version: 0.4.5-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 5d1a123e58a..c31d52e4fe7 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.4.4 +version: 0.4.5-dev groups: - ruby - queries diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index c82cff186d0..af31de79697 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 0.0.1 +version: 0.0.2-dev groups: shared library: true dependencies: diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 7fb2ed664cb..bf307418089 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/ssa -version: 0.0.5 +version: 0.0.6-dev groups: shared library: true diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index 39df1ba73d5..4d0a7ddae81 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/typos -version: 0.0.5 +version: 0.0.6-dev groups: shared library: true From 3cdfed94830f34cc5c4ab852a7e1ec97aba61d7d Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 18 Nov 2022 14:41:29 +0100 Subject: [PATCH 385/796] CI: delete language specific codeql query compile checks --- .github/workflows/ql-for-ql-tests.yml | 5 ----- .github/workflows/ruby-qltest.yml | 5 ----- 2 files changed, 10 deletions(-) diff --git a/.github/workflows/ql-for-ql-tests.yml b/.github/workflows/ql-for-ql-tests.yml index b820d00a3e4..ce7963e8f79 100644 --- a/.github/workflows/ql-for-ql-tests.yml +++ b/.github/workflows/ql-for-ql-tests.yml @@ -47,8 +47,3 @@ jobs: find ql/ql/src "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 "${CODEQL}" query format --check-only env: CODEQL: ${{ steps.find-codeql.outputs.codeql-path }} - - name: Check QL compilation - run: | - "${CODEQL}" query compile --check-only --threads=4 --warnings=error --search-path "${{ github.workspace }}/ql/extractor-pack" "ql/ql/src" "ql/ql/examples" - env: - CODEQL: ${{ steps.find-codeql.outputs.codeql-path }} diff --git a/.github/workflows/ruby-qltest.yml b/.github/workflows/ruby-qltest.yml index 125e2694fb0..056543a237b 100644 --- a/.github/workflows/ruby-qltest.yml +++ b/.github/workflows/ruby-qltest.yml @@ -33,11 +33,6 @@ jobs: steps: - uses: actions/checkout@v3 - uses: ./.github/actions/fetch-codeql - - name: Check QL compilation - run: | - codeql query compile --check-only --threads=0 --ram 5000 --warnings=error "ql/src" "ql/examples" - env: - GITHUB_TOKEN: ${{ github.token }} qlupgrade: runs-on: ubuntu-latest steps: From d79eed533b83cbe8bfd8b1a4feb1d8cc06a4daa0 Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 18 Nov 2022 13:50:50 +0000 Subject: [PATCH 386/796] Python: Remove unwanted recursion Depending on `localFlowStep` meant that this predicate ended up being recursive with itself (by way of flow summaries which depend on API graphs, which in turn depend on import resolution). Changing this to use the simple local flow step predicate that we use for type tracking should fix this issue. --- .../semmle/python/dataflow/new/internal/ImportResolution.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll index 320ec8d998e..e4af21caacc 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -8,6 +8,7 @@ private import python private import semmle.python.dataflow.new.DataFlow private import semmle.python.dataflow.new.internal.ImportStar private import semmle.python.dataflow.new.TypeTracker +private import semmle.python.dataflow.new.internal.DataFlowPrivate /** * Python modules and the way imports are resolved are... complicated. Here's a crash course in how @@ -279,7 +280,7 @@ module ImportResolution { or // Flow (local or global) forward to a later reference to the module. exists(DataFlow::Node ref | ref = getModuleReference(m) | - DataFlow::localFlow(ref, result) + simpleLocalFlowStepForTypetracking(ref, result) or exists(DataFlow::ModuleVariableNode mv | mv.getAWrite() = ref and From 2cd58817d74ad2d9e47fec40de937467d8c0db14 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 18 Nov 2022 16:29:19 +0100 Subject: [PATCH 387/796] Swift: skip QL code generation on untouched files This is a developer QoL improvement, where running codegen will skip writing (and especially formatting) any files that were not changed. **Why?** While code generation in itself was pretty much instant, QL formatting of generated code was starting to take a long time. This made unconditionally running codegen quite annoying, for example before each test run as part of an IDE workflow or as part of the pre-commit hook. **How?** This was not completely straightforward as we could not work with the contents of the file prior to code generation as that was already post-processed by the QL formatting, so we had no chance of comparing the output of template rendering with that. We therefore store the hashes of the files _prior_ to QL formatting in a checked-in file (`swift/ql/.generated.list`). We can therefore load those hashes at the beginning of code generation, use them to compare the template rendering output and update them in this special registry file. **What else?** We also extend this mechanism to detect accidental modification of generated files in a more robust way. Before this patch, we were doing it with a rough regexp based heuristic. Now, we just store the hashes of the files _after_ QL formatting in the same checked file, so we can check that and stop generation if a generated file was modified, or a stub was modified without removing the `// generated` header. --- .github/workflows/swift.yml | 1 + .pre-commit-config.yaml | 2 +- swift/codegen/codegen.py | 9 +- swift/codegen/generators/qlgen.py | 170 +++--- swift/codegen/lib/render.py | 145 ++++- swift/codegen/test/test_qlgen.py | 53 +- swift/codegen/test/test_render.py | 218 ++++++-- swift/codegen/test/utils.py | 26 +- swift/ql/.generated.list | 890 ++++++++++++++++++++++++++++++ 9 files changed, 1314 insertions(+), 200 deletions(-) create mode 100644 swift/ql/.generated.list diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index 797d950ee57..99579421adf 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -39,6 +39,7 @@ jobs: - 'swift/ql/lib/codeql/swift/elements/**' - 'swift/ql/lib/codeql/swift/generated/**' - 'swift/ql/test/extractor-tests/generated/**' + - 'swift/ql/.generated.list' ql: - 'github/workflows/swift.yml' - 'swift/**/*.ql' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 14845337b36..5f35c2c183b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -44,7 +44,7 @@ repos: - id: swift-codegen name: Run Swift checked in code generation - files: ^swift/(schema.py$|codegen/|.*/generated/|ql/lib/(swift\.dbscheme$|codeql/swift/elements)) + files: ^swift/(schema.py$|codegen/|.*/generated/|ql/lib/(swift\.dbscheme$|codeql/swift/elements)|ql/\.generated.list) language: system entry: bazel run //swift/codegen -- --quiet pass_filenames: false diff --git a/swift/codegen/codegen.py b/swift/codegen/codegen.py index aa09ab805c8..b2da3678b1c 100755 --- a/swift/codegen/codegen.py +++ b/swift/codegen/codegen.py @@ -40,11 +40,13 @@ def _parse_args() -> argparse.Namespace: p.add_argument("--codeql-binary", default="codeql", help="command to use for QL formatting (default %(default)s)") p.add_argument("--cpp-output", type=_abspath, help="output directory for generated C++ files, required if trap or cpp is provided to --generate") + p.add_argument("--generated-registry", type=_abspath, default=paths.swift_dir / "ql/.generated.list", + help="registry file containing information about checked-in generated code") return p.parse_args() -def _abspath(x: str) -> pathlib.Path: - return pathlib.Path(x).resolve() +def _abspath(x: str) -> typing.Optional[pathlib.Path]: + return pathlib.Path(x).resolve() if x else None def run(): @@ -56,9 +58,8 @@ def run(): else: log_level = logging.INFO logging.basicConfig(format="{levelname} {message}", style='{', level=log_level) - exe_path = paths.exe_file.relative_to(opts.swift_dir) for target in opts.generate: - generate(target, opts, render.Renderer(exe_path)) + generate(target, opts, render.Renderer(opts.swift_dir)) if __name__ == "__main__": diff --git a/swift/codegen/generators/qlgen.py b/swift/codegen/generators/qlgen.py index 662a782dbd7..4a7d8435a1e 100755 --- a/swift/codegen/generators/qlgen.py +++ b/swift/codegen/generators/qlgen.py @@ -216,32 +216,11 @@ def get_classes_used_by(cls: ql.Class) -> typing.List[str]: return sorted(set(t for t in get_types_used_by(cls) if t[0].isupper() and t != cls.name)) -_generated_stub_re = re.compile(r"\n*private import .*\n+class \w+ extends Generated::\w+ \{[ \n]?\}", re.MULTILINE) - - -def _is_generated_stub(file: pathlib.Path) -> bool: - with open(file) as contents: - for line in contents: - if not line.startswith("// generated"): - return False - break - else: - # no lines - return False - # we still do not detect modified synth constructors - if not file.name.endswith("Constructor.qll"): - # one line already read, if we can read 5 other we are past the normal stub generation - line_threshold = 5 - first_lines = list(itertools.islice(contents, line_threshold)) - if len(first_lines) == line_threshold or not _generated_stub_re.match("".join(first_lines)): - raise ModifiedStubMarkedAsGeneratedError( - f"{file.name} stub was modified but is still marked as generated") - return True - - def format(codeql, files): - format_cmd = [codeql, "query", "format", "--in-place", "--"] - format_cmd.extend(str(f) for f in files if f.suffix in (".qll", ".ql")) + ql_files = [str(f) for f in files if f.suffix in (".qll", ".ql")] + if not ql_files: + return + format_cmd = [codeql, "query", "format", "--in-place", "--"] + ql_files res = subprocess.run(format_cmd, stderr=subprocess.PIPE, text=True) if res.returncode: for line in res.stderr.splitlines(): @@ -307,11 +286,14 @@ def generate(opts, renderer): stub_out = opts.ql_stub_output test_out = opts.ql_test_output missing_test_source_filename = "MISSING_SOURCE.txt" + include_file = stub_out.with_suffix(".qll") - existing = {q for q in out.rglob("*.qll")} - existing |= {q for q in stub_out.rglob("*.qll") if _is_generated_stub(q)} - existing |= {q for q in test_out.rglob("*.ql")} - existing |= {q for q in test_out.rglob(missing_test_source_filename)} + generated = {q for q in out.rglob("*.qll")} + generated.add(include_file) + generated.update(q for q in test_out.rglob("*.ql")) + generated.update(q for q in test_out.rglob(missing_test_source_filename)) + + stubs = {q for q in stub_out.rglob("*.qll")} data = schema.load_file(input) @@ -324,77 +306,75 @@ def generate(opts, renderer): imports = {} - db_classes = [cls for cls in classes.values() if not cls.ipa] - renderer.render(ql.DbClasses(db_classes), out / "Raw.qll") + with renderer.manage(generated=generated, stubs=stubs, registry=opts.generated_registry) as renderer: - classes_by_dir_and_name = sorted(classes.values(), key=lambda cls: (cls.dir, cls.name)) - for c in classes_by_dir_and_name: - imports[c.name] = get_import(stub_out / c.path, opts.swift_dir) + db_classes = [cls for cls in classes.values() if not cls.ipa] + renderer.render(ql.DbClasses(db_classes), out / "Raw.qll") - for c in classes.values(): - qll = out / c.path.with_suffix(".qll") - c.imports = [imports[t] for t in get_classes_used_by(c)] - renderer.render(c, qll) - stub_file = stub_out / c.path.with_suffix(".qll") - if not stub_file.is_file() or _is_generated_stub(stub_file): - stub = ql.Stub( - name=c.name, base_import=get_import(qll, opts.swift_dir)) - renderer.render(stub, stub_file) + classes_by_dir_and_name = sorted(classes.values(), key=lambda cls: (cls.dir, cls.name)) + for c in classes_by_dir_and_name: + imports[c.name] = get_import(stub_out / c.path, opts.swift_dir) - # for example path/to/elements -> path/to/elements.qll - include_file = stub_out.with_suffix(".qll") - renderer.render(ql.ImportList(list(imports.values())), include_file) + for c in classes.values(): + qll = out / c.path.with_suffix(".qll") + c.imports = [imports[t] for t in get_classes_used_by(c)] + renderer.render(c, qll) + stub_file = stub_out / c.path.with_suffix(".qll") + if not renderer.is_customized_stub(stub_file): + stub = ql.Stub(name=c.name, base_import=get_import(qll, opts.swift_dir)) + renderer.render(stub, stub_file) - renderer.render(ql.GetParentImplementation(list(classes.values())), out / 'ParentChild.qll') + # for example path/to/elements -> path/to/elements.qll + renderer.render(ql.ImportList(list(imports.values())), include_file) - for c in data.classes.values(): - if _should_skip_qltest(c, data.classes): - continue - test_dir = test_out / c.group / c.name - test_dir.mkdir(parents=True, exist_ok=True) - if not any(test_dir.glob("*.swift")): - log.warning(f"no test source in {test_dir.relative_to(test_out)}") - renderer.render(ql.MissingTestInstructions(), - test_dir / missing_test_source_filename) - continue - total_props, partial_props = _partition(_get_all_properties_to_be_tested(c, data.classes), - lambda p: p.is_single or p.is_predicate) - renderer.render(ql.ClassTester(class_name=c.name, - properties=total_props, - # in case of collapsed hierarchies we want to see the actual QL class in results - show_ql_class="qltest_collapse_hierarchy" in c.pragmas), - test_dir / f"{c.name}.ql") - for p in partial_props: - renderer.render(ql.PropertyTester(class_name=c.name, - property=p), test_dir / f"{c.name}_{p.getter}.ql") + renderer.render(ql.GetParentImplementation(list(classes.values())), out / 'ParentChild.qll') - final_ipa_types = [] - non_final_ipa_types = [] - constructor_imports = [] - ipa_constructor_imports = [] - stubs = {} - for cls in sorted(data.classes.values(), key=lambda cls: (cls.group, cls.name)): - ipa_type = get_ql_ipa_class(cls) - if ipa_type.is_final: - final_ipa_types.append(ipa_type) - if ipa_type.has_params: - stub_file = stub_out / cls.group / f"{cls.name}Constructor.qll" - if not stub_file.is_file() or _is_generated_stub(stub_file): - # stub rendering must be postponed as we might not have yet all subtracted ipa types in `ipa_type` - stubs[stub_file] = ql.Synth.ConstructorStub(ipa_type) - constructor_import = get_import(stub_file, opts.swift_dir) - constructor_imports.append(constructor_import) - if ipa_type.is_ipa: - ipa_constructor_imports.append(constructor_import) - else: - non_final_ipa_types.append(ipa_type) + for c in data.classes.values(): + if _should_skip_qltest(c, data.classes): + continue + test_dir = test_out / c.group / c.name + test_dir.mkdir(parents=True, exist_ok=True) + if not any(test_dir.glob("*.swift")): + log.warning(f"no test source in {test_dir.relative_to(test_out)}") + renderer.render(ql.MissingTestInstructions(), + test_dir / missing_test_source_filename) + continue + total_props, partial_props = _partition(_get_all_properties_to_be_tested(c, data.classes), + lambda p: p.is_single or p.is_predicate) + renderer.render(ql.ClassTester(class_name=c.name, + properties=total_props, + # in case of collapsed hierarchies we want to see the actual QL class in results + show_ql_class="qltest_collapse_hierarchy" in c.pragmas), + test_dir / f"{c.name}.ql") + for p in partial_props: + renderer.render(ql.PropertyTester(class_name=c.name, + property=p), test_dir / f"{c.name}_{p.getter}.ql") - for stub_file, data in stubs.items(): - renderer.render(data, stub_file) - renderer.render(ql.Synth.Types(root.name, final_ipa_types, non_final_ipa_types), out / "Synth.qll") - renderer.render(ql.ImportList(constructor_imports), out / "SynthConstructors.qll") - renderer.render(ql.ImportList(ipa_constructor_imports), out / "PureSynthConstructors.qll") + final_ipa_types = [] + non_final_ipa_types = [] + constructor_imports = [] + ipa_constructor_imports = [] + stubs = {} + for cls in sorted(data.classes.values(), key=lambda cls: (cls.group, cls.name)): + ipa_type = get_ql_ipa_class(cls) + if ipa_type.is_final: + final_ipa_types.append(ipa_type) + if ipa_type.has_params: + stub_file = stub_out / cls.group / f"{cls.name}Constructor.qll" + if not renderer.is_customized_stub(stub_file): + # stub rendering must be postponed as we might not have yet all subtracted ipa types in `ipa_type` + stubs[stub_file] = ql.Synth.ConstructorStub(ipa_type) + constructor_import = get_import(stub_file, opts.swift_dir) + constructor_imports.append(constructor_import) + if ipa_type.is_ipa: + ipa_constructor_imports.append(constructor_import) + else: + non_final_ipa_types.append(ipa_type) - renderer.cleanup(existing) - if opts.ql_format: - format(opts.codeql_binary, renderer.written) + for stub_file, data in stubs.items(): + renderer.render(data, stub_file) + renderer.render(ql.Synth.Types(root.name, final_ipa_types, non_final_ipa_types), out / "Synth.qll") + renderer.render(ql.ImportList(constructor_imports), out / "SynthConstructors.qll") + renderer.render(ql.ImportList(ipa_constructor_imports), out / "PureSynthConstructors.qll") + if opts.ql_format: + format(opts.codeql_binary, renderer.written) diff --git a/swift/codegen/lib/render.py b/swift/codegen/lib/render.py index d077161bce0..9564f5eb4ab 100644 --- a/swift/codegen/lib/render.py +++ b/swift/codegen/lib/render.py @@ -7,6 +7,9 @@ https://mustache.github.io/ import logging import pathlib +import typing +import hashlib +from dataclasses import dataclass import pystache @@ -15,15 +18,22 @@ from . import paths log = logging.getLogger(__name__) +class Error(Exception): + pass + + class Renderer: """ Template renderer using mustache templates in the `templates` directory """ - def __init__(self, generator): + def __init__(self, swift_dir: pathlib.Path): self._r = pystache.Renderer(search_dirs=str(paths.templates_dir), escape=lambda u: u) - self.written = set() - self._generator = generator + self._swift_dir = swift_dir + self._generator = self._get_path(paths.exe_file) - def render(self, data, output: pathlib.Path): + def _get_path(self, file: pathlib.Path): + return file.relative_to(self._swift_dir) + + def render(self, data: object, output: pathlib.Path): """ Render `data` to `output`. `data` must have a `template` attribute denoting which template to use from the template directory. @@ -41,13 +51,126 @@ class Renderer: output_filename = output_filename.with_suffix(f".{ext}") template += f"_{ext}" contents = self._r.render_name(template, data, generator=self._generator) - with open(output_filename, "w") as out: - out.write(contents) - log.debug(f"{mnemonic}: generated {output.name}") - self.written.add(output_filename) + self._do_write(mnemonic, contents, output_filename) - def cleanup(self, existing): - """ Remove files in `existing` for which no `render` has been called """ - for f in existing - self.written: + def _do_write(self, mnemonic: str, contents: str, output: pathlib.Path): + with open(output, "w") as out: + out.write(contents) + log.debug(f"{mnemonic}: generated {output.name}") + + def manage(self, generated: typing.Iterable[pathlib.Path], stubs: typing.Iterable[pathlib.Path], + registry: pathlib.Path) -> "RenderManager": + return RenderManager(self._swift_dir, generated, stubs, registry) + + +class RenderManager(Renderer): + """ A context manager allowing to manage checked in generated files and their cleanup, able + to skip unneeded writes. + + This is done by using and updating a checked in list of generated files that assigns two + hashes to each file: + * one is the hash of the mustache rendered contents, that can be used to quickly check whether a + write is needed + * the other is the hash of the actual file after code generation has finished. This will be + different from the above because of post-processing like QL formatting. This hash is used + to detect invalid modification of generated files""" + written: typing.Set[pathlib.Path] + + @dataclass + class Hashes: + """ + pre contains the hash of a file as rendered, post is the hash after + postprocessing (for example QL formatting) + """ + pre: str + post: typing.Optional[str] = None + + def __init__(self, swift_dir: pathlib.Path, generated: typing.Iterable[pathlib.Path], + stubs: typing.Iterable[pathlib.Path], + registry: pathlib.Path): + super().__init__(swift_dir) + self._registry_path = registry + self._hashes = {} + self.written = set() + self._existing = set() + self._skipped = set() + + self._load_registry() + self._process_generated(generated) + self._process_stubs(stubs) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + for f in self._existing - self._skipped - self.written: + self._hashes.pop(self._get_path(f), None) f.unlink(missing_ok=True) log.info(f"removed {f.name}") + for f in self.written: + self._hashes[self._get_path(f)].post = self._hash_file(f) + self._dump_registry() + + def _do_write(self, mnemonic: str, contents: str, output: pathlib.Path): + hash = self._hash_string(contents) + rel_output = self._get_path(output) + if rel_output in self._hashes and self._hashes[rel_output].pre == hash: + self._skipped.add(output) + log.debug(f"{mnemonic}: skipped {output.name}") + else: + self.written.add(output) + super()._do_write(mnemonic, contents, output) + self._hashes[rel_output] = self.Hashes(pre=hash) + + def _process_generated(self, generated: typing.Iterable[pathlib.Path]): + for f in generated: + self._existing.add(f) + rel_path = self._get_path(f) + if rel_path not in self._hashes: + log.warning(f"{rel_path} marked as generated but absent from the registry") + elif self._hashes[rel_path].post != self._hash_file(f): + raise Error(f"{rel_path} is generated but was modified, please revert the file") + + def _process_stubs(self, stubs: typing.Iterable[pathlib.Path]): + for f in stubs: + rel_path = self._get_path(f) + if self.is_customized_stub(f): + self._hashes.pop(rel_path, None) + continue + self._existing.add(f) + if rel_path not in self._hashes: + log.warning(f"{rel_path} marked as stub but absent from the registry") + elif self._hashes[rel_path].post != self._hash_file(f): + raise Error(f"{rel_path} is a stub marked as generated, but it was modified") + + @staticmethod + def is_customized_stub(file: pathlib.Path) -> bool: + if not file.is_file(): + return False + with open(file) as contents: + for line in contents: + return not line.startswith("// generated") + # no lines + return True + + @staticmethod + def _hash_file(filename: pathlib.Path) -> str: + with open(filename) as inp: + return RenderManager._hash_string(inp.read()) + + @staticmethod + def _hash_string(data: str) -> str: + h = hashlib.sha256() + h.update(data.encode()) + return h.hexdigest() + + def _load_registry(self): + with open(self._registry_path) as reg: + for line in reg: + filename, prehash, posthash = line.split() + self._hashes[pathlib.Path(filename)] = self.Hashes(prehash, posthash) + + def _dump_registry(self): + with open(self._registry_path, 'w') as out: + for f, hashes in sorted(self._hashes.items()): + print(f, hashes.pre, hashes.post, file=out) diff --git a/swift/codegen/test/test_qlgen.py b/swift/codegen/test/test_qlgen.py index 0e27f2b7516..0db445f07b9 100644 --- a/swift/codegen/test/test_qlgen.py +++ b/swift/codegen/test/test_qlgen.py @@ -26,6 +26,9 @@ def ql_output_path(): return paths.swift_dir / "ql/lib/other/path" def ql_test_output_path(): return paths.swift_dir / "ql/test/path" +def generated_registry_path(): return paths.swift_dir / "registry.list" + + def import_file(): return stub_path().with_suffix(".qll") @@ -42,18 +45,19 @@ def qlgen_opts(opts): opts.ql_stub_output = stub_path() opts.ql_output = ql_output_path() opts.ql_test_output = ql_test_output_path() + opts.generated_registry = generated_registry_path() opts.ql_format = True opts.swift_dir = paths.swift_dir return opts @pytest.fixture -def generate(input, qlgen_opts, renderer): - renderer.written = [] +def generate(input, qlgen_opts, renderer, render_manager): + render_manager.written = [] def func(classes): input.classes = {cls.name: cls for cls in classes} - return run_generation(qlgen.generate, qlgen_opts, renderer) + return run_managed_generation(qlgen.generate, qlgen_opts, renderer, render_manager) return func @@ -80,6 +84,7 @@ def generate_children_implementations(generate): def _filter_generated_classes(ret, output_test_files=False): files = {x for x in ret} + print(files) files.remove(import_file()) files.remove(children_file()) stub_files = set() @@ -88,6 +93,7 @@ def _filter_generated_classes(ret, output_test_files=False): for f in files: try: stub_files.add(f.relative_to(stub_path())) + print(f) except ValueError: try: base_files.add(f.relative_to(ql_output_path())) @@ -396,10 +402,10 @@ def test_class_dir_imports(generate_import_list): ]) -def test_format(opts, generate, renderer, run_mock): +def test_format(opts, generate, render_manager, run_mock): opts.codeql_binary = "my_fake_codeql" run_mock.return_value.stderr = "some\nlines\n" - renderer.written = [ + render_manager.written = [ pathlib.Path("x", "foo.ql"), pathlib.Path("bar.qll"), pathlib.Path("y", "baz.txt"), @@ -411,11 +417,11 @@ def test_format(opts, generate, renderer, run_mock): ] -def test_format_error(opts, generate, renderer, run_mock): +def test_format_error(opts, generate, render_manager, run_mock): opts.codeql_binary = "my_fake_codeql" run_mock.return_value.stderr = "some\nlines\n" run_mock.return_value.returncode = 1 - renderer.written = [ + render_manager.written = [ pathlib.Path("x", "foo.ql"), pathlib.Path("bar.qll"), pathlib.Path("y", "baz.txt"), @@ -424,12 +430,7 @@ def test_format_error(opts, generate, renderer, run_mock): generate([schema.Class('A')]) -def test_empty_cleanup(generate, renderer): - generate([schema.Class('A')]) - assert renderer.mock_calls[-1] == mock.call.cleanup(set()) - - -def test_non_empty_cleanup(opts, generate, renderer): +def test_manage_parameters(opts, generate, renderer): ql_a = opts.ql_output / "A.qll" ql_b = opts.ql_output / "B.qll" stub_a = opts.ql_stub_output / "A.qll" @@ -439,30 +440,22 @@ def test_non_empty_cleanup(opts, generate, renderer): test_c = opts.ql_test_output / "B.txt" write(ql_a) write(ql_b) - write(stub_a, "// generated\nprivate import bla\n\nclass foo extends Generated::bar {\n}\n") - write(stub_b, "bar\n") + write(stub_a) + write(stub_b) write(test_a) write(test_b) write(test_c) generate([schema.Class('A')]) - assert renderer.mock_calls[-1] == mock.call.cleanup( - {ql_a, ql_b, stub_a, test_a, test_b}) + assert renderer.mock_calls == [ + mock.call.manage(generated={ql_a, ql_b, test_a, test_b, import_file()}, stubs={stub_a, stub_b}, + registry=opts.generated_registry) + ] -def test_modified_stub_still_generated(qlgen_opts, renderer): +def test_modified_stub_skipped(qlgen_opts, generate, render_manager): stub = qlgen_opts.ql_stub_output / "A.qll" - write(stub, "// generated\nprivate import bla\n\nclass foo extends Generated::bar, baz {\n}\n") - with pytest.raises(qlgen.ModifiedStubMarkedAsGeneratedError): - run_generation(qlgen.generate, qlgen_opts, renderer) - - -def test_extended_stub_still_generated(qlgen_opts, renderer): - stub = qlgen_opts.ql_stub_output / "A.qll" - write(stub, - "// generated\nprivate import bla\n\nclass foo extends Generated::bar {\n}\n\n" - "class other {\n other() { none() }\n}") - with pytest.raises(qlgen.ModifiedStubMarkedAsGeneratedError): - run_generation(qlgen.generate, qlgen_opts, renderer) + render_manager.is_customized_stub.side_effect = lambda f: f == stub + assert stub not in generate([schema.Class('A')]) def test_test_missing_source(generate_tests): diff --git a/swift/codegen/test/test_render.py b/swift/codegen/test/test_render.py index 7055930dd6b..64cc745046f 100644 --- a/swift/codegen/test/test_render.py +++ b/swift/codegen/test/test_render.py @@ -1,14 +1,10 @@ import sys -from unittest import mock -import pathlib import pytest -from swift.codegen.lib import paths -from swift.codegen.lib import render +from swift.codegen.test.utils import * - -generator = "test/foogen" +import hashlib @pytest.fixture @@ -20,13 +16,24 @@ def pystache_renderer_cls(): @pytest.fixture def pystache_renderer(pystache_renderer_cls): ret = mock.Mock() - pystache_renderer_cls.side_effect = (ret,) + pystache_renderer_cls.return_value = ret return ret @pytest.fixture def sut(pystache_renderer): - return render.Renderer(generator) + return render.Renderer(paths.swift_dir) + + +def assert_file(file, text): + with open(file) as inp: + assert inp.read() == text + + +def hash(text): + h = hashlib.sha256() + h.update(text.encode()) + return h.hexdigest() def test_constructor(pystache_renderer_cls, sut): @@ -35,24 +42,154 @@ def test_constructor(pystache_renderer_cls, sut): assert pystache_init.kwargs['search_dirs'] == str(paths.templates_dir) an_object = object() assert pystache_init.kwargs['escape'](an_object) is an_object - assert sut.written == set() def test_render(pystache_renderer, sut): data = mock.Mock(spec=("template",)) - output = mock.Mock() - with mock.patch("builtins.open", mock.mock_open()) as output_stream: - sut.render(data, output) + text = "some text" + pystache_renderer.render_name.side_effect = (text,) + output = paths.swift_dir / "some/output.txt" + sut.render(data, output) + + assert_file(output, text) assert pystache_renderer.mock_calls == [ - mock.call.render_name(data.template, data, generator=generator), + mock.call.render_name(data.template, data, generator=paths.exe_file.relative_to(paths.swift_dir)), ] - assert output_stream.mock_calls == [ - mock.call(output, 'w'), - mock.call().__enter__(), - mock.call().write(pystache_renderer.render_name.return_value), - mock.call().__exit__(None, None, None), + + +def test_managed_render(pystache_renderer, sut): + data = mock.Mock(spec=("template",)) + text = "some text" + pystache_renderer.render_name.side_effect = (text,) + output = paths.swift_dir / "some/output.txt" + registry = paths.swift_dir / "a/registry.list" + write(registry) + + with sut.manage(generated=(), stubs=(), registry=registry) as renderer: + renderer.render(data, output) + assert renderer.written == {output} + assert_file(output, text) + + assert_file(registry, f"some/output.txt {hash(text)} {hash(text)}\n") + assert pystache_renderer.mock_calls == [ + mock.call.render_name(data.template, data, generator=paths.exe_file.relative_to(paths.swift_dir)), ] - assert sut.written == {output} + + +def test_managed_render_with_post_processing(pystache_renderer, sut): + data = mock.Mock(spec=("template",)) + text = "some text" + postprocessed_text = "some other text" + pystache_renderer.render_name.side_effect = (text,) + output = paths.swift_dir / "some/output.txt" + registry = paths.swift_dir / "a/registry.list" + write(registry) + + with sut.manage(generated=(), stubs=(), registry=registry) as renderer: + renderer.render(data, output) + assert renderer.written == {output} + assert_file(output, text) + write(output, postprocessed_text) + + assert_file(registry, f"some/output.txt {hash(text)} {hash(postprocessed_text)}\n") + assert pystache_renderer.mock_calls == [ + mock.call.render_name(data.template, data, generator=paths.exe_file.relative_to(paths.swift_dir)), + ] + + +def test_managed_render_with_erasing(pystache_renderer, sut): + output = paths.swift_dir / "some/output.txt" + stub = paths.swift_dir / "some/stub.txt" + registry = paths.swift_dir / "a/registry.list" + write(output) + write(stub, "// generated bla bla") + write(registry) + + with sut.manage(generated=(output,), stubs=(stub,), registry=registry) as renderer: + pass + + assert not output.is_file() + assert not stub.is_file() + assert_file(registry, "") + assert pystache_renderer.mock_calls == [] + + +def test_managed_render_with_skipping_of_generated_file(pystache_renderer, sut): + data = mock.Mock(spec=("template",)) + output = paths.swift_dir / "some/output.txt" + some_output = "some output" + registry = paths.swift_dir / "a/registry.list" + write(output, some_output) + write(registry, f"some/output.txt {hash(some_output)} {hash(some_output)}\n") + + pystache_renderer.render_name.side_effect = (some_output,) + + with sut.manage(generated=(output,), stubs=(), registry=registry) as renderer: + renderer.render(data, output) + assert renderer.written == set() + assert_file(output, some_output) + + assert_file(registry, f"some/output.txt {hash(some_output)} {hash(some_output)}\n") + assert pystache_renderer.mock_calls == [ + mock.call.render_name(data.template, data, generator=paths.exe_file.relative_to(paths.swift_dir)), + ] + + +def test_managed_render_with_skipping_of_stub_file(pystache_renderer, sut): + data = mock.Mock(spec=("template",)) + stub = paths.swift_dir / "some/stub.txt" + some_output = "// generated some output" + some_processed_output = "// generated some processed output" + registry = paths.swift_dir / "a/registry.list" + write(stub, some_processed_output) + write(registry, f"some/stub.txt {hash(some_output)} {hash(some_processed_output)}\n") + + pystache_renderer.render_name.side_effect = (some_output,) + + with sut.manage(generated=(), stubs=(stub,), registry=registry) as renderer: + renderer.render(data, stub) + assert renderer.written == set() + assert_file(stub, some_processed_output) + + assert_file(registry, f"some/stub.txt {hash(some_output)} {hash(some_processed_output)}\n") + assert pystache_renderer.mock_calls == [ + mock.call.render_name(data.template, data, generator=paths.exe_file.relative_to(paths.swift_dir)), + ] + + +def test_managed_render_with_modified_generated_file(pystache_renderer, sut): + output = paths.swift_dir / "some/output.txt" + some_processed_output = "// some processed output" + registry = paths.swift_dir / "a/registry.list" + write(output, "// something else") + write(registry, f"some/output.txt whatever {hash(some_processed_output)}\n") + + with pytest.raises(render.Error): + sut.manage(generated=(output,), stubs=(), registry=registry) + + +def test_managed_render_with_modified_stub_file_still_marked_as_generated(pystache_renderer, sut): + stub = paths.swift_dir / "some/stub.txt" + some_processed_output = "// generated some processed output" + registry = paths.swift_dir / "a/registry.list" + write(stub, "// generated something else") + write(registry, f"some/stub.txt whatever {hash(some_processed_output)}\n") + + with pytest.raises(render.Error): + sut.manage(generated=(), stubs=(stub,), registry=registry) + + +def test_managed_render_with_modified_stub_file_not_marked_as_generated(pystache_renderer, sut): + stub = paths.swift_dir / "some/stub.txt" + some_processed_output = "// generated some processed output" + registry = paths.swift_dir / "a/registry.list" + write(stub, "// no more generated") + write(registry, f"some/stub.txt whatever {hash(some_processed_output)}\n") + + with sut.manage(generated=(), stubs=(stub,), registry=registry) as renderer: + pass + + assert_file(registry, "") def test_render_with_extensions(pystache_renderer, sut): @@ -61,47 +198,16 @@ def test_render_with_extensions(pystache_renderer, sut): data.extensions = ["foo", "bar", "baz"] output = pathlib.Path("my", "test", "file") expected_outputs = [pathlib.Path("my", "test", p) for p in ("file.foo", "file.bar", "file.baz")] - rendered = [object() for _ in expected_outputs] + rendered = [f"text{i}" for i in range(len(expected_outputs))] pystache_renderer.render_name.side_effect = rendered - with mock.patch("builtins.open", mock.mock_open()) as output_stream: - sut.render(data, output) + sut.render(data, output) expected_templates = ["test_template_foo", "test_template_bar", "test_template_baz"] assert pystache_renderer.mock_calls == [ - mock.call.render_name(t, data, generator=generator) for t in expected_templates + mock.call.render_name(t, data, generator=paths.exe_file.relative_to(paths.swift_dir)) + for t in expected_templates ] - expected_calls = [] - for contents, out in zip(rendered, expected_outputs): - expected_calls.extend(( - mock.call(out, 'w'), - mock.call().__enter__(), - mock.call().write(contents), - mock.call().__exit__(None, None, None), - )) - assert sut.written == set(expected_outputs) - - -def test_written(sut): - data = [mock.Mock(spec=("template",)) for _ in range(4)] - output = [mock.Mock() for _ in data] - with mock.patch("builtins.open", mock.mock_open()) as output_stream: - for d, o in zip(data, output): - sut.render(d, o) - assert sut.written == set(output) - - -def test_cleanup(sut): - data = [mock.Mock(spec=("template",)) for _ in range(4)] - output = [mock.Mock() for _ in data] - with mock.patch("builtins.open", mock.mock_open()) as output_stream: - for d, o in zip(data, output): - sut.render(d, o) - expected_erased = [mock.Mock() for _ in range(3)] - existing = set(expected_erased + output[2:]) - sut.cleanup(existing) - for f in expected_erased: - assert f.mock_calls == [mock.call.unlink(missing_ok=True)] - for f in output: - assert f.unlink.mock_calls == [] + for expected_output, expected_contents in zip(expected_outputs, rendered): + assert_file(expected_output, expected_contents) if __name__ == '__main__': diff --git a/swift/codegen/test/utils.py b/swift/codegen/test/utils.py index af033aaa75a..2678190c9f8 100644 --- a/swift/codegen/test/utils.py +++ b/swift/codegen/test/utils.py @@ -6,7 +6,7 @@ import pytest from swift.codegen.lib import render, schema, paths schema_dir = pathlib.Path("a", "dir") -schema_file = schema_dir / "schema.yml" +schema_file = schema_dir / "schema.py" dbscheme_file = pathlib.Path("another", "dir", "test.dbscheme") @@ -18,7 +18,16 @@ def write(out, contents=""): @pytest.fixture def renderer(): - return mock.Mock(spec=render.Renderer("")) + return mock.Mock(spec=render.Renderer) + + +@pytest.fixture +def render_manager(renderer): + ret = mock.Mock(spec=render.RenderManager) + ret.__enter__ = mock.Mock(return_value=ret) + ret.__exit__ = mock.Mock(return_value=None) + ret.is_customized_stub.return_value = False + return ret @pytest.fixture @@ -30,7 +39,9 @@ def opts(): @pytest.fixture(autouse=True) def override_paths(tmp_path): - with mock.patch("swift.codegen.lib.paths.swift_dir", tmp_path): + with (mock.patch("swift.codegen.lib.paths.swift_dir", tmp_path), + mock.patch("swift.codegen.lib.paths.exe_file", tmp_path / "exe"), + ): yield @@ -63,3 +74,12 @@ def run_generation(generate, opts, renderer): renderer.render.side_effect = lambda data, out: output.__setitem__(out, data) generate(opts, renderer) return output + + +def run_managed_generation(generate, opts, renderer, render_manager): + output = {} + + renderer.manage.side_effect = (render_manager,) + render_manager.render.side_effect = lambda data, out: output.__setitem__(out, data) + generate(opts, renderer) + return output diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list new file mode 100644 index 00000000000..fd75bc1ade4 --- /dev/null +++ b/swift/ql/.generated.list @@ -0,0 +1,890 @@ +ql/lib/codeql/swift/elements/CommentConstructor.qll c5a4c55fb26e57a9b4efcff329b428f7de22406b35198d99290b6e646794777a 326365475f2fda857ffa00e1c7841089660eca02d739400b6d62ed6f39ea4d03 +ql/lib/codeql/swift/elements/DbFile.qll 9e0f3c54075f75af82a9c917777755f47cb04a5777b064f5cba4a951414ac004 a3b08dd6ccd18d1a5f6f29b829da473c28a921e8d626b264b4b73515a49164f9 +ql/lib/codeql/swift/elements/DbFileConstructor.qll 2913b16780f4369b405a088bb70f3b0f941b2978e8827ed30745f2ab7ba0cd8e c21b21b100d0b245bb1d498b4c3696db73dd710a5be211c6b825ebf733681da7 +ql/lib/codeql/swift/elements/DbLocation.qll e3e7bf56c7857329e250a44e9df1ccb31f6c2ada47d5199d549b4b92b44bc2f8 aa46535db08966b8045ceb2820b9fd580637272ae4e487192ee57b6215c16e49 +ql/lib/codeql/swift/elements/DbLocationConstructor.qll 88366e22ba40eaaee097f413130117925dda488f1bcbd3989e301e86dd394df3 c61b32994d403a8c4f85c26251e24ffb8c6ea34dbbe935872d868ccbfb6c1ff6 +ql/lib/codeql/swift/elements/DiagnosticsConstructor.qll 6a3e312f3ed57465747c672cbb6d615eca89f42586519221d2973ac3e2ab052c a010ef546f9ed2a75b812ee47db00110056b3076b1f939efa2addb000c327427 +ql/lib/codeql/swift/elements/ErrorElement.qll 6b6be3731a2fd178e5093ddebb7cd519ecc5fbbd549bd4dbd5f69687791c3630 ab0028bab8a9ed14c6b4bfe0f8a10e4768ea1e21f86b495258021ab9b8e65aeb +ql/lib/codeql/swift/elements/UnspecifiedElementConstructor.qll 0d179f8189f6268916f88c78a2665f8d4e78dc71e71b6229354677e915ac505d e8f5c313b7d8b0e93cee84151a5f080013d2ca502f3facbbde4cdb0889bc7f8e +ql/lib/codeql/swift/elements/decl/AbstractStorageDecl.qll 6196ecc35d358e6fe1c34b0478c0479acd0f0de67a64daac4d814af90a87d514 74a74330a953d16ce1cc19b2dbabdf8c8ff0fc3d250d101b8108a6597844e179 +ql/lib/codeql/swift/elements/decl/AbstractTypeParamDecl.qll 83950437007703c0f35ef154f46577d8754fb191c93772ff718b29107ce8852e 737ad9c857c079605e84dc7ebaecbafa86fe129283756b98e6e574ac9e24c22c +ql/lib/codeql/swift/elements/decl/AccessorDeclConstructor.qll 08376434fd14a2b07280e931d3e22d3eafd2063d745f7c78cad0f9fd7e6156ba 6f74d15a88433953998a07eb2131841679a88cb13efb0569ed9b5502c4a2e362 +ql/lib/codeql/swift/elements/decl/AssociatedTypeDecl.qll ae6107c8d9ee9affa7e8430a4d8cd58879578eafcfba668275af4d20f8ea9c53 e81dc740623b4e2c75f83104acaa3d2b6cc6d001dd36a8520c381e0de10e15c4 +ql/lib/codeql/swift/elements/decl/AssociatedTypeDeclConstructor.qll ec9007ea072ff22c367f40da69db2f0a8463bb411bbfd33e2d6c8b489a496027 631f688a8410ddcfbaa575fa2f8ffcdbc1b51ee37639b337c804ca1d5af56e0c +ql/lib/codeql/swift/elements/decl/ClassDecl.qll 225405ad04e5e959319fbc1ea086ec4eab0b66f5671ebc58290cce45e4103c51 ac681bdc1770a823ea529456f32b1da7b389621254ccd9102e6a49136c53854b +ql/lib/codeql/swift/elements/decl/ClassDeclConstructor.qll 0092ab4b76cd858489d76be94a43442c0e5f395b1d5684309674957e107979b7 9bc496e483feb88552ca0d48e32039aa4566f4612fc27073fea48ad954985d46 +ql/lib/codeql/swift/elements/decl/ConcreteFuncDecl.qll 7dd23b6145977ec6ca60dd39cf9db09673e0340cdb8de2080279c83599ccd831 3a07a73dc11ef06ddaeb3d401748ef14a1ee66447c86d2e8c8f187dda92b34a2 +ql/lib/codeql/swift/elements/decl/ConcreteFuncDeclConstructor.qll 4eb2e9dc8b4c93e457bb594085d8f50862dc07a712ce7a0f2dee7f108467ce3e 1f994d6ae1ca2e4fd5da075b70ea22322181bdaf43034face1e82ef353fe34bf +ql/lib/codeql/swift/elements/decl/ConcreteVarDecl.qll be33f40e8870a10aec413f35d8f62a502d7d5dd8a52665730740e880566206d7 d821efa43c6d83aedfb959500de42c5ecabbf856f8556f739bc6cec30a88dfab +ql/lib/codeql/swift/elements/decl/ConcreteVarDeclConstructor.qll 4b6a9f458db5437f9351b14464b3809a78194029554ea818b3e18272c17afba3 a60d695b0d0ffa917ad01908bec2beaa663e644eddb00fb370fbc906623775d4 +ql/lib/codeql/swift/elements/decl/ConstructorDecl.qll df6725dfa6670b1ff9a5135126b38cb93d813f852ffd1290bb60b541e28b92d9 fb3ed454cdc97bedc5577c9823f6385eb9616d156085fc8796cc09732ae48121 +ql/lib/codeql/swift/elements/decl/ConstructorDeclConstructor.qll ba5cc6f440cba3d47b364a37febd64f85941cdc0237db52a2b8844d1dc75d483 9fc039ca7a0f33f03b3f573186f02efecbac0c2e0dc5abba5d47876ca26390fe +ql/lib/codeql/swift/elements/decl/Decl.qll 7a7ea5727a238684e783adf04ce8f721bf4451e1324ffc966ad671d60a43d64b 662e53ffc8226ae351032d0389784e6b70d517794e83a4c698ac84996361608f +ql/lib/codeql/swift/elements/decl/DestructorDecl.qll a2ba5e8861661ebc4cf875d540bf1edf0970920304aeeaef34592ea2739afc21 10001d21ec5aecc398e4c0e9bf05ee905c3edc4f89dd0afc7b2e5aca6b767dec +ql/lib/codeql/swift/elements/decl/DestructorDeclConstructor.qll c33b113a3ccb0b1bfd9aad8b909940776da5fdb8a24e1b998c5ebde3903be981 155ad928fbebf9688eec30a2cf61d9a2d4cd15d1161dc3f6202e6331bdb3a56a +ql/lib/codeql/swift/elements/decl/EnumCaseDeclConstructor.qll 8c907544170671f713a8665d294eeefdbe78a607c2f16e2c630ea9c33f484baf eec83efc930683628185dbdad8f73311aad510074d168a53d85ea09d13f1f7e1 +ql/lib/codeql/swift/elements/decl/EnumDecl.qll 04271e164379af3a33eb060d230b768878e06acc37c3d132cad089a2c663c6c4 779940ebdbd510eb651972c57eb84b04af39c44ef59a8c307a44549ab730febb +ql/lib/codeql/swift/elements/decl/EnumDeclConstructor.qll 642bbfb71e917d84695622f3b2c7b36bf5be4e185358609810267ab1fc4e221b f6e06d79e7ff65fbabf72c553508b67406fb59c577215d28cc47971d34b6af05 +ql/lib/codeql/swift/elements/decl/EnumElementDeclConstructor.qll 736074246a795c14a30a8ec7bb8da595a729983187887294e485487309919dc6 4614fb380fad7af1b5fb8afce920f3e7350378254ece60d19722046046672fbb +ql/lib/codeql/swift/elements/decl/ExtensionDeclConstructor.qll 4f811e3332720327d2b9019edbb2fa70fb24322e72881afc040e7927452409d6 554f9832311dfc30762507e0bd4b25c5b6fdb9d0c4e8252cc5a1ef1033fafacb +ql/lib/codeql/swift/elements/decl/FuncDecl.qll 47ff5eaccc79944bb01ad819a4a9e373475d7511d477e76226538fc4efc9c88d ba8e48682e93af0804e66f5bf0207049e291a0c1430a872252dc67af17ea700a +ql/lib/codeql/swift/elements/decl/GenericContext.qll b8f21d625cfdccc201201e0d84aab7b5c1e7ccaec21ee788ac425916be8f8ac9 4747af5faf0a93d7508e0ec58021a842ca5ec41831b5d71cbc7fce2a2389a820 +ql/lib/codeql/swift/elements/decl/GenericTypeDecl.qll 774e087cc7208a4fe5df753a848191f4b986265b2b74856a52049aeb018c937a 42e1e3e055f3e5fa70c8624910d635ab10fe4015d378be9e1e6e1adb39f0dc40 +ql/lib/codeql/swift/elements/decl/GenericTypeParamDecl.qll bbcf2844cb26435e3af6d58c2b37ffeee3295a5f3330fbee34881fada7bde85b 569a380917adf4e26b286343c654954d472eabf3fe91e0d1b5f26549d9c6d24e +ql/lib/codeql/swift/elements/decl/GenericTypeParamDeclConstructor.qll 63db91dc8d42746bfdd9a6bcf1f8df5b723b4ee752bd80cc61d512f2813ef959 096972e3f7f5775e60af189345bece7c0e8baec9e218709a49ed9511a3089424 +ql/lib/codeql/swift/elements/decl/IfConfigDeclConstructor.qll ebd945f0a081421bd720235d0aefde800a8ad8a1db4cbd37b44447c417ff7114 1448bfdd290ad41e038a1a1ffd5ea60a75b5ec06f3a8d4d138bd56b8b960332e +ql/lib/codeql/swift/elements/decl/ImportDeclConstructor.qll f2f09df91784d7a6d348d67eaf3429780ac820d2d3a08f66e1922ea1d4c8c60d 4496865a26be2857a335cbc00b112beb78a319ff891d0c5d2ad41a4d299f0457 +ql/lib/codeql/swift/elements/decl/InfixOperatorDecl.qll ca3af3b403b9d456029cb4f4b94b610a93d2d70ea71a3d6c4532088ebc83bd0b 5dec87f0c43948f38e942b204583043eb4f7386caa80cec8bf2857a2fd933ed4 +ql/lib/codeql/swift/elements/decl/InfixOperatorDeclConstructor.qll ca6c5c477e35e2d6c45f8e7a08577c43e151d3e16085f1eae5c0a69081714b04 73543543dff1f9847f3299091979fdf3d105a84e2bcdb890ce5d72ea18bba6c8 +ql/lib/codeql/swift/elements/decl/IterableDeclContext.qll 7b27fe02dca453d5bdb5f10be07978d98308e466bad5585b3040ed9c1a817737 fed59974e47c3011d4bddefb959f5cacaa3b770ad5a6db15558334ef02ad04e9 +ql/lib/codeql/swift/elements/decl/MissingMemberDeclConstructor.qll 82738836fa49447262e184d781df955429c5e3697d39bf3689397d828f04ce65 8ef82ed7c4f641dc8b4d71cd83944582da539c34fb3d946c2377883abada8578 +ql/lib/codeql/swift/elements/decl/ModuleDecl.qll 0d39d88c926d5633f467ab7a1db0101e8d61250ee5e4847de862232f997de783 410311bf3ae1efac53d8fd6515c2fe69d9ab79902c1048780e87d478cd200e26 +ql/lib/codeql/swift/elements/decl/ModuleDeclConstructor.qll 9b18b6d3517fd0c524ac051fd5dea288e8f923ada00fe4cc809cbebce036f890 0efc90492417089b0982a9a6d60310faba7a1fce5c1749396e3a29b3aac75dc5 +ql/lib/codeql/swift/elements/decl/NominalTypeDecl.qll 0b101f879e48e000074971d6412183f6be98fe99512037967ee650ffd82ec7a3 9faf5bd4e51b47a75edb67e9115281ca5b20ab6c0d8f6882f043734495bb399f +ql/lib/codeql/swift/elements/decl/OpaqueTypeDecl.qll 7c4a5fda798c9b44e481905f28e6c105ab3f8ab5567c2c336b24d27102fd7d66 e84e0dd1a3175ad29123def00e71efbd6f4526a12601fc027b0892930602046b +ql/lib/codeql/swift/elements/decl/OpaqueTypeDeclConstructor.qll f707aab3627801e94c63aedcded21eab14d3617c35da5cf317692eeb39c84710 20888ae6e386ae31e3cb9ff78155cb408e781ef1e7b6d687c2705843bcac0340 +ql/lib/codeql/swift/elements/decl/ParamDeclConstructor.qll cfa0ba73a9727b8222efbf65845d6df0d01800646feaf7b407b8ffe21a6691d8 916ff2d3e96546eac6828e1b151d4b045ce5f7bcd5d7dbb074f82ecf126b0e09 +ql/lib/codeql/swift/elements/decl/PatternBindingDeclConstructor.qll bcefa54011001b2559f90eb6ddcd286d8c47f2707103226abe3f2701ec1f45ef d58ca16ab91943a2fd97e4c7b71881b097e927156f56f3bd9dfaababccfda8f7 +ql/lib/codeql/swift/elements/decl/PostfixOperatorDecl.qll af46544addbb5bf5241e71c1846b40f33f73d64ae0932f0d057058a32ad63bee 3befb6218e934681e874c7655677eb4618edc817111ed18ef4ebcf16e06f4027 +ql/lib/codeql/swift/elements/decl/PostfixOperatorDeclConstructor.qll 27356cfe1d1c45a1999a200a3f1268bf09cfb019fbb7f9fb48cd32aa38b67880 6638c1acc9b0b642c106b1a14f98dfad7a9ebcc78a1b8212037d32a147e40086 +ql/lib/codeql/swift/elements/decl/PoundDiagnosticDeclConstructor.qll 1b85ec959c92d1e8b218ae99d0dcd0acaa1b96e741cf7d0cf1137f2dca25d765 b8f164d00d4c5db4356933de5c3b6833b54ae8d3e9fcb908e324fcdc91a5f6ec +ql/lib/codeql/swift/elements/decl/PrecedenceGroupDeclConstructor.qll 4f7548c613ee98f561a104f46ae61335d51be1b4598ae420397ae63d3ae619ca 87c11e093fb0bc5ed498f7fd36bfb844099f0e93e55de731c3e8c5fdeded35f1 +ql/lib/codeql/swift/elements/decl/PrefixOperatorDecl.qll d314c804e5ab476920a6e970b1c33cb09bf1ad076bc1f889b5068053d9de8ab5 19558ab5d027f580463ea096eb7882066d0ff95123493b8e23be79613bfdd28d +ql/lib/codeql/swift/elements/decl/PrefixOperatorDeclConstructor.qll eee048d4c2314234df17966deefeee08e769a831fa500e6e494f64fca9e9dda1 01d9b09f809645c91f92b981a46c9ed6e332f5734d768ab369b7a328a9a391d4 +ql/lib/codeql/swift/elements/decl/ProtocolDecl.qll 17e89e410275aa2fbc1687a5380e23354a1b64e1b9581d52875210921b0eed8f 0bb0dca7980934cfb98dab5b83fd253153740ac8054cdf85bdce8b5ed6db9398 +ql/lib/codeql/swift/elements/decl/ProtocolDeclConstructor.qll 2bbc92ddcec810cefb6cfa85320f873f1c542b1c62a197a8fbafa12e0e949c00 b2060fb804a16619e235afcd76856cdc377c4e47cfb43c5a6f9d32ff5b852e74 +ql/lib/codeql/swift/elements/decl/StructDecl.qll 1cb599afb1c574a64c2033a2c20bddbf2142b593f0775abc3d5b1cfafccca6b6 ebc04601ac1cd736151783073ef4ad1a42311731aab36b38dc02760ecb22bd4a +ql/lib/codeql/swift/elements/decl/StructDeclConstructor.qll 653fef1ce7a5924f9db110dfab4ebc191b6688fa14ebeb6cf2a09fe338f00646 c7ed15002c41b7dd11a5dd768e0f6f1fe241c680d155364404c64d6251adee5c +ql/lib/codeql/swift/elements/decl/SubscriptDeclConstructor.qll 3a88617b41f96827cb6edd596d6d95ebcf5baf99ba113bdd298276666c6aeadf 166e04fc72507cb27e2c16ad2d5217074f8678d286cb6d0980e5b84125648abe +ql/lib/codeql/swift/elements/decl/TopLevelCodeDeclConstructor.qll 6920a4e7aec45ae2a561cef95b9082b861f81c16c259698541f317481645e194 4bd65820b93a5ec7332dd1bbf59326fc19b77e94c122ad65d41393c84e6ac581 +ql/lib/codeql/swift/elements/decl/TypeAliasDecl.qll ecb457a9a81c6b13a1068f471c0b87e59227838f54c5d4effe7d4c2f6e7f5800 630dc9cbf20603855c599a9f86037ba0d889ad3d2c2b6f9ac17508d398bff9e3 +ql/lib/codeql/swift/elements/decl/TypeAliasDeclConstructor.qll ba70bb69b3a14283def254cc1859c29963838f624b3f1062a200a8df38f1edd5 96ac51d1b3156d4139e583f7f803e9eb95fe25cc61c12986e1b2972a781f9c8b +ql/lib/codeql/swift/elements/decl/ValueDecl.qll b344768498e0d1794d92bc5b7c0417e75079aa8a82e27d7b3449f1e52f78d1e9 e3056cf6a883da2737cb220a89499a9e3977eb1c56b9e1d2f41a56b71a0c29f9 +ql/lib/codeql/swift/elements/expr/AbstractClosureExpr.qll 125f8bd8f21c95c439616744539577afcfa9fd63c65683132a2c971abcec3523 400790fe643585ad39f40c433eff8934bbe542d140b81341bca3b6dfc5b22861 +ql/lib/codeql/swift/elements/expr/AnyHashableErasureExpr.qll 20dd848a35a47af94d0fb8cf1a33a2bd6582c751440708c365cf338e522f6de5 bf80cab3e9ff5366a6223153409f4852acdb9e4a5d464fb73b2a8cffc664ca29 +ql/lib/codeql/swift/elements/expr/AnyHashableErasureExprConstructor.qll 12816f18d079477176519a20b0f1262fc84da98f60bce3d3dd6476098c6542e7 4cc5c8492a97f4639e7d857f2fca9065293dfa953d6af451206ce911cda9f323 +ql/lib/codeql/swift/elements/expr/AnyTryExpr.qll 51aa09941b366d147a685452b3b89be4f0cc35f8cf9ff5ebcd53622ddd7df727 988b5df28972e877486704a43698ada91e68fe875efc331f0d7139c78b36f7dd +ql/lib/codeql/swift/elements/expr/AppliedPropertyWrapperExpr.qll b1a6c026b0167c7299d1f2de30935a8f805382edd8d91c1f7f18e9278ccd564c 9508f93ca59561455e1eb194eaddd9f071960a752f985844c65b3b498f057461 +ql/lib/codeql/swift/elements/expr/AppliedPropertyWrapperExprConstructor.qll d9baf27c0d64e08466952b584ef08e4f40f7dfb861582aef2e7ebb16bb3da13b 2f19e7dbc02f9450c5521728ff1c5f178b14f50de4ff345fcd9bc834070a21d6 +ql/lib/codeql/swift/elements/expr/ArchetypeToSuperExpr.qll ea81d53ed038e29d0454b2411feb069e3396e6f7a0aa93bcfd05793772fe1d52 64e21e6f3307cd39d817ea66be2935e717168187bbeaedd4247bb77cec9d95ea +ql/lib/codeql/swift/elements/expr/ArchetypeToSuperExprConstructor.qll df9f0db27fd2420e9d9cc4e1c6796b5513f6781940b5f571e8b8b9850a6e163f b4b15aa01de7ce91f74bd47a2e654c3ea360b90687c92ef9e19257289696f97e +ql/lib/codeql/swift/elements/expr/ArrayExprConstructor.qll 57d37bb5a745f504c1bf06e51ffa0c757e224c158034c34e2bbb805b4efdc9f4 808753dccddfc0a02ef871af8f3d6487289ca48e7b4e4ea6356e0a87e3692583 +ql/lib/codeql/swift/elements/expr/ArrayToPointerExpr.qll 202b724bcf20f8083028d9d683d748ffceab3d0becf02c29c57228fe8aca30a5 035b15b1ecb700c4e6961b9a99e3c33476cedaa1a96310601b558e7ede9de39f +ql/lib/codeql/swift/elements/expr/ArrayToPointerExprConstructor.qll ad4346298ff16512f06f9841bf8171b163f59fde949e24e257db7379eb524c4f b2d038e1e13340b0616044fc28005904562035bc8c9871bd6c9b117f15adffe6 +ql/lib/codeql/swift/elements/expr/AssignExprConstructor.qll 14cb0d217bc9ca982d29cdbf39c79399b39faa7e031469bc47884f413507e743 646658cb2f664ba0675f48cb51591c64cf2107a0c756038bfc66243b4c092b45 +ql/lib/codeql/swift/elements/expr/AutoClosureExprConstructor.qll 928391f52b914e42625fafadbdfa703e6fb246a09a7d8e39bf7700bc2fc8c22c 2d698cceed54a230890f5f2ad9f019ebe82fdd15831b8a5b6aaabf1ea855063f +ql/lib/codeql/swift/elements/expr/AwaitExprConstructor.qll 5c73999bf54f43c845e3a8ec9dcd9898f35c9b5160aadb1837a266d3413a76e4 74830d06f6fbd443393dbba61a48480f7632ce2c38fcb15febfeaf88ec8fd868 +ql/lib/codeql/swift/elements/expr/BinaryExprConstructor.qll 99baa77331e4e5b2d0fe0ca31e839c901ba677e4337bed3aa4d580c3258fb610 7f42ac4bfc73c18743f73a3e961b529f1d302e70a634ab91fcf3676b959ddb22 +ql/lib/codeql/swift/elements/expr/BindOptionalExprConstructor.qll 1dd7074d6513977eb50f857de87aea35686ddda8f1ee442569fcfac16fc02fd6 1c23977e1f5ad4fd1a9d43a01765dda2fe72496a0361701f92212f7eef3f13c2 +ql/lib/codeql/swift/elements/expr/BooleanLiteralExprConstructor.qll 561ac38c94fdc3eb7baab09d0f2f2d7f64424dbfe879c395470ee6d5cd6a9354 2b76d00a58cd7d051d422f050d187c36e97614de6d99f52068aff3c20a45c7af +ql/lib/codeql/swift/elements/expr/BridgeFromObjCExpr.qll 129251956d27cd32ce806c4b11cd2ea1774723d53c4dc1d8112cab7401a2db0b 91385232931b55817e53e4caebf7a2dd9c0a520ec055012de82e7b1da923f0ec +ql/lib/codeql/swift/elements/expr/BridgeFromObjCExprConstructor.qll f91e80dad19b7177c6ea1b127c7622d145cb250575acba9bf34d99b933849b94 c3133e6ad25d86bcec697999c16d0c18db1abf894068f5b8d14c90ffae35ca09 +ql/lib/codeql/swift/elements/expr/BridgeToObjCExpr.qll 436b10412525fb6fca966416f2fb563efd569ee2826b003c9cee594a4887658f 8fc781a59f6009fa64fbbf28f302b2e83b0f7fcbe0cf13d5236637248dcb6579 +ql/lib/codeql/swift/elements/expr/BridgeToObjCExprConstructor.qll 7e51fef328ad149170f83664efd57de2b7058511934f3cf1a9d6cb4033562bed 34ab05bbdddc5477ba681cc89f03283057867116c83b3e57766c3b24f38ca7bf +ql/lib/codeql/swift/elements/expr/BuiltinLiteralExpr.qll 5455879c4f3aef960881da579007544e8f20a973d2fba0c58aa21705800a0c9d 9d9de530709c80cfe710a9e3d62a1b7cede61ba22da46365b1ba7766dbc48b44 +ql/lib/codeql/swift/elements/expr/CallExpr.qll 625c0e0866c1e6384591c5022952391d256b2366d1b83174c2d299ccca086d23 8040ab28b4e1630ff343ab77d10b2449e792908b55e683316f442d853eee6c0a +ql/lib/codeql/swift/elements/expr/CallExprConstructor.qll 478caaaee61b5d83126da6de16ff21d11dc452428f15a879e1401d595b7bed75 7014f17d347b781e4c8211568954c2858ab2dcf37ef5dfd5ed36678415000009 +ql/lib/codeql/swift/elements/expr/CaptureListExprConstructor.qll 03af12d1b10bdc2cc4ac2b0322c4cd7f68a77699f37315ddca97f1e99a770c93 0fc709cdca8935a3142f7718d660c932af65952db8603bd909087aa68eab9236 +ql/lib/codeql/swift/elements/expr/CheckedCastExpr.qll 766f2fc44952f34ac0609aa346a5fedf7eb9c1d7bf1393890a05cb5bda45725e e7c90a92829472335199fd7a8e4ba7b781fbbf7d18cf12d6c421ddb22c719a4b +ql/lib/codeql/swift/elements/expr/ClassMetatypeToObjectExpr.qll 36fd3daf20130882e26e0f301b02380219e67ed3fe8a1caaac3854789eb6bcad 4b5aca9fa4524dc25dc6d12eb32eeda179a7e7ec20f4504493cf7eb828a8e7be +ql/lib/codeql/swift/elements/expr/ClassMetatypeToObjectExprConstructor.qll 369cecb4859164413d997ee4afba444853b77fb857fa2d82589603d88d01e1dc 3b4ebd1fb2e426cba21edd91b36e14dc3963a1ede8c482cdf04ef5003a290b28 +ql/lib/codeql/swift/elements/expr/ClosureExprConstructor.qll cf2fa2dab328f6b98aeffcdc833de4d74f69d23779ac897f5ada9c2dca9ef093 13f85b735ebb56c361458baba45eb854e70b7987d5e1863e564084c1a6165cc5 +ql/lib/codeql/swift/elements/expr/CoerceExpr.qll efc1e3852212089d81b5c3d06ae74b0a36abf2dd8843689d50dcc22d3bed12ba eb13ef05c7436d039c1f8a4164b039bdbf12323310c249d7702291058f244d38 +ql/lib/codeql/swift/elements/expr/CoerceExprConstructor.qll aa80ea0e6c904fab461c463137ce1e755089c3990f789fae6a0b29dea7013f6d 455f5184a3d2e2a6b9720a191f1f568699f598984779d923c2b28e8a3718fa9d +ql/lib/codeql/swift/elements/expr/CollectionExpr.qll 80fedf0757cd8024ebcadd0b82507cfd5cec57b4d7c53ff0f97357384f9d89c4 87977b7661bcd8212b07b36f45ff94f5e98513c6dddb4cca697d1d6b853dff72 +ql/lib/codeql/swift/elements/expr/CollectionUpcastConversionExpr.qll 37aa0e9e829a480a5db855a2d2617ace57ac8d89fe01ec11251aa9183ccbd0a1 ab8370b77f27ed658f58571638f96187746cbafdfdf86583caf807bf3910f8c2 +ql/lib/codeql/swift/elements/expr/CollectionUpcastConversionExprConstructor.qll 4896b2ac56def7a428945c97cd5d5e44ca6378be96707baf1cb3a47c81ef9ca3 c8f1efdfcc67b5d631447ab2b87a0a70722bd52ef3282ad74d8de929c361f626 +ql/lib/codeql/swift/elements/expr/ConditionalBridgeFromObjCExpr.qll f9b1da899020c8dd9c0633376410f5b8b8d00f4df43d5da164e5e5696c813499 4013b1dcebbc873f337ee433042ad1e5d178b0afe2d62434fe235a234e9b8aa6 +ql/lib/codeql/swift/elements/expr/ConditionalBridgeFromObjCExprConstructor.qll 7350d9e279995181f08dcc931723d21a36aac17b3ea5b633c82bac5c7aeb733a dc6767f621bddcc22be8594b46b7d3170e5d7bfcee6f1e0279c26492fd88c81d +ql/lib/codeql/swift/elements/expr/ConditionalCheckedCastExpr.qll 527f8f1dd071e2647f6f86a6b204a082c7e9929f9a37f35b8dcd40e99e1064b2 a66a1e07b210a1e8d999380db04a8b3210b66049a876bd92c8f56eae66c5a062 +ql/lib/codeql/swift/elements/expr/ConditionalCheckedCastExprConstructor.qll 13a1032bfa1199245746d4aac2c54d3ba336d3580c2713a66a91ad47eb8648ca 2a7c66669551aaa3528d77a8525985b850acbc983fea6f076561709a076dadb7 +ql/lib/codeql/swift/elements/expr/ConstructorRefCallExpr.qll e8830d2c73a10d394495b8aa5bc68290f9524b0f09dba932d7cd7b533f149a1b fc4b855b27f7afefab8132bd2adc3567cceec6b2fd762bf1dc7463ce76421326 +ql/lib/codeql/swift/elements/expr/ConstructorRefCallExprConstructor.qll 7f22cf621c69a4cd11f40332d8f0bce9381f87830d600f5fa5aae6df9a0bcace 7005c9c220532188b338b99c87f6fd8c9975f7af0fee16812a2faf69a9660ac0 +ql/lib/codeql/swift/elements/expr/CovariantFunctionConversionExpr.qll 687065e8625a249d51e8e92136afacfd3c48f85f689d5aff077a5a9dac56272e 4510d77d211f4b6db9dd4c941706d7eb7579fe7311714758c9d1d24513bfbdc4 +ql/lib/codeql/swift/elements/expr/CovariantFunctionConversionExprConstructor.qll eac12524819e9fe29074f90ea89fea866023b5ed4a5494345f2b9d8eec531620 71a6eb320630f42403e1e67bb37c39a1bae1c9f6cc38c0f1688a31f3f206d83f +ql/lib/codeql/swift/elements/expr/CovariantReturnConversionExpr.qll e6a7a3ce538c068bd7ab0974b4615acbf00038d3b01dc594372152114559fa44 720fb172ebcb800c70810539c7a80dbdf61acb970277f2b6a54b9159ab4e016e +ql/lib/codeql/swift/elements/expr/CovariantReturnConversionExprConstructor.qll b32a9b3c067d09bd6350efe57215e3b3b9ae598631756878da4a1e474876fc3f bcc963ee556fdd5e1563c305d1bfc6a89e8953243f5dfa1b92144d280ccb3b1a +ql/lib/codeql/swift/elements/expr/DefaultArgumentExprConstructor.qll 013827d95e2a9d65830b748093fd8a02da6b6cae78729875f624bf71cc28a4fe 900879fd1c26cfbcea0cd0c3b8f95425644458a8a1dd6628a8bd4bc61bc45809 +ql/lib/codeql/swift/elements/expr/DerivedToBaseExpr.qll 782d47d73634aea8ee4ea991acde27180b77535d8e5112d40df77262d9e9a19e e12acd24f48b7b59009615af6a43e061ffc595f1edc55bfe01c1524f30d7be7c +ql/lib/codeql/swift/elements/expr/DerivedToBaseExprConstructor.qll ca74471f6ac2500145de98bb75880450c9185f697f5ce25905271358182a29b3 797b9eaa9d3d56a963d584ba560a67ec94e1a1b10916f0d03f4ad4777e4984f9 +ql/lib/codeql/swift/elements/expr/DestructureTupleExpr.qll 618298ec50ac464268472bba7925695ba3d37bd3ae07b310a69724b396265554 8bc4a6238bec6dbdc2f91e2777cb00d86c63642bf3d2d9758a192d170cf6fcde +ql/lib/codeql/swift/elements/expr/DestructureTupleExprConstructor.qll 7d844c6c4a0f9008e2fdf9a194621f09595e328a5f5c6f2f993b1a3cd2a74a03 e75d47955ae9a91c75fcb8e0bb12b6ed792c361645ee29bbcc37fa2ac27c4517 +ql/lib/codeql/swift/elements/expr/DictionaryExprConstructor.qll 6bd61507158b62fd8d2f3a68c61cceff5926915bf71730c898cf6be402d1e426 37cfce5600dd047a65f1321709350eabae5846429a1940c6f8b27f601420a687 +ql/lib/codeql/swift/elements/expr/DifferentiableFunctionExpr.qll 32d59a601c7ee95715e09478561018788e8f10eca34c5637c94d7700a868636c 520f79dd2fd9b500c32fb31d578fffaec67d232690638746792417a0b80b98e6 +ql/lib/codeql/swift/elements/expr/DifferentiableFunctionExprConstructor.qll 4ee532a020a6e75ba2971cee5724fcccc7e6b60530ec26385cbbda0b2626f9be 6c35cd2b0142b2c74e7d8a46cf3aebfcf92e5809e5c0c480a666d8a7dacdcfa2 +ql/lib/codeql/swift/elements/expr/DifferentiableFunctionExtractOriginalExprConstructor.qll ce008cb7ce392277dd0678203f845f94a9933b9530c265a58a66c16542423495 4b4522c39929d062662b5e321371e76df5f2c9c8e5eebdf5c62e88b8eb84960b +ql/lib/codeql/swift/elements/expr/DiscardAssignmentExprConstructor.qll cd814e77f82fac48949382335655f22b0d1d99ece04612f026aebc2bc60f0dc9 d1faa9e2d863175feb00cd2b503ac839e09744cbbfbe4c18b670416f9d50483c +ql/lib/codeql/swift/elements/expr/DotSelfExprConstructor.qll 4b6956818dac5b460dfbe9878c2c5b6761fcf1c65556b38555f68de9cc6f2562 2ae26f5e7bde2f972cc5a63e4a3dca1698e3a7c75b06419bb7bb080cb8ce78d9 +ql/lib/codeql/swift/elements/expr/DotSyntaxBaseIgnoredExprConstructor.qll 8ca889cc506cac0eeb35c246a3f317c9da8fe4dbfaf736a2056108b00b1c8521 9a20b12ad44f1dbf58d205a58cdfc1d63d2540353d8c8df48d87393d3b50d8b6 +ql/lib/codeql/swift/elements/expr/DotSyntaxCallExpr.qll f5048cff6fcdd298c8822ece1cd2042a61b40521dfc230f0f0e1798527010e58 5220861621d01b15ea0182bbb8358d700f842b94ec07745f77c5285d0e84a509 +ql/lib/codeql/swift/elements/expr/DotSyntaxCallExprConstructor.qll d32660cba3474b84e060eb33bbf57d77722ce7bf2a320aec15ccd980e0a0d0bb 0a6f46f887750221f01e7f5d834b7c811009e4351c1afc0b4ef61ac6c0af421b +ql/lib/codeql/swift/elements/expr/DynamicLookupExpr.qll cd5670379df14b7a765037378221e541dd93567c97729d6be24bbbbb9aacc054 89f564a793d1f09a8aeb2dd61c475df3e55a49f4f0b6094ceb9f0ebe6d42fa76 +ql/lib/codeql/swift/elements/expr/DynamicMemberRefExprConstructor.qll 6bd769bdbb83999bfd94bf4d5a1b8a32cc045460183f5f2fcf7055257f6c3787 e2b72550a71f2f39bde171ada6e04c6bdbd797caa74813ea3c8070b93cefa25e +ql/lib/codeql/swift/elements/expr/DynamicSubscriptExprConstructor.qll d40d88069371807c72445453f26e0777ac857e200c9c3e8a88cd55628ccb9230 6ff580bbc1b7f99c95145168f7099ab19b5d150e7d7e83747595ff2eb2c289c4 +ql/lib/codeql/swift/elements/expr/DynamicTypeExprConstructor.qll 37066c57e8a9b7044b8b4ecf42a7bf079e3400dd02bf28a1d51abd5406391ba0 62cc0405ecfe4c8d5477957d8789a6b03a4e9eecabbb0f94e1bde5ce2adabb8c +ql/lib/codeql/swift/elements/expr/EnumIsCaseExprConstructor.qll a02f992035c7ef7692c381377b1e594f0021025df6bcab23f149efeacd61c8e6 687df32678e1b3bcc4241270962593f7838e461970621f6e5b829321718ed257 +ql/lib/codeql/swift/elements/expr/ErasureExpr.qll 3549ee36cbca32207ec7a339de87e81126b0ca0e087e74a6f525c817b4dd15be 91a60971ff01d158f6358a6cb2e028234b66b3a75c851a3f5289af0aa8c16613 +ql/lib/codeql/swift/elements/expr/ErasureExprConstructor.qll 29e0ab9f363b6009f59a24b2b293d12b12c3cdea0f771952d1a57c693f4db4a3 c4bc12f016b792dff79e38b296ef58dba3370357d088fd63931a8af09c8444a9 +ql/lib/codeql/swift/elements/expr/ErrorExpr.qll 89468d8ed9c1cc69575cb9c890b8e424ec0c8495894f691a657774e9146a896d bc3e4a566bc37590929e90a72e383f9fbc446e4f955e07e83c1c59a86cee8215 +ql/lib/codeql/swift/elements/expr/ErrorExprConstructor.qll dd2bec0e35121e0a65d47600100834963a7695c268e3832aad513e70b1b92a75 e85dcf686403511c5f72b25ae9cf62f77703575137c39610e61562efc988bbac +ql/lib/codeql/swift/elements/expr/ExistentialMetatypeToObjectExpr.qll cd5d01e8410ed65165bb4a1a570a63864b0a75c742ac9224cef8c2683d72f62d c0b5811c8665f3324b04d40f5952a62e631ec4b3f00db8e9cc13cb5d60028178 +ql/lib/codeql/swift/elements/expr/ExistentialMetatypeToObjectExprConstructor.qll 1a735425a59f8a2bd208a845e3b4fc961632c82db3b69d0b71a1bc2875090f3b 769b6a80a451c64cbf9ce09729b34493a59330d4ef54ab0d51d8ff81305b680f +ql/lib/codeql/swift/elements/expr/FloatLiteralExprConstructor.qll 4dfb34d32e4022b55caadcfbe147e94ebe771395c59f137228213a51a744ba10 1eb78fcda9e0b70d1993e02408fb6032035991bf937c4267149ab9c7c6a99d3a +ql/lib/codeql/swift/elements/expr/ForceTryExprConstructor.qll 48cbc408bb34a50558d25aa092188e1ad0f68d83e98836e05072037f3d8b49af 62ce7b92410bf712ecd49d3eb7dd9b195b9157415713aaf59712542339f37e4c +ql/lib/codeql/swift/elements/expr/ForceValueExprConstructor.qll 3b201ee2d70ab13ad7e3c52aad6f210385466ec4a60d03867808b4d3d97511a8 d5d9f0e7e7b4cae52f97e4681960fa36a0c59b47164868a4a099754f133e25af +ql/lib/codeql/swift/elements/expr/ForcedCheckedCastExpr.qll 27612d688194618da2403d9c913cb7fe0f423e099f0abdb9b54f4eb58b2767be a3bae0709caac887bec37c502f191ea51608006e719bb17550c3215f65b16f7f +ql/lib/codeql/swift/elements/expr/ForcedCheckedCastExprConstructor.qll 3fdd87183e72c4b0ee927c5865c8cbadf4f133bd09441bf77324941c4057cbc8 a6e7dc34de8d1767512c2595121524bd8369bd21879857e13590cec87a4b0eeb +ql/lib/codeql/swift/elements/expr/ForeignObjectConversionExpr.qll fbffcd3bde46cd3e443ce583bf7bfb2d73b86e3d061465c7ddb4468be7447b72 7ea9aa492b2d37ad05d92421a92bb9b1786175b2f3b02867c1d39f1c67934f3d +ql/lib/codeql/swift/elements/expr/ForeignObjectConversionExprConstructor.qll d90fdb1b4125299e45be4dead6831835e8d3cd7137c82143e687e1d0b0a0a3bc a2f38e36823a18d275e199c35a246a6bc5ec4a37bf8547a09a59fe5dd39a0b4e +ql/lib/codeql/swift/elements/expr/FunctionConversionExpr.qll e6dcf7fb3966d2ee5e4434221ec615b066da0e17ddc442692ca7936fcebec70b 87c1f5a44d9cc7dd10d05f17f5d4c718ecc5b673c7b7f4c1662b5d97e0177803 +ql/lib/codeql/swift/elements/expr/FunctionConversionExprConstructor.qll ff88509ae6754c622d5d020c0e92e0ea1efe2f7c54e59482366640b2100d187b fd640286e765dc00c4a6c87d766750cad0acd2544566ec9a21bc49c44cf09dba +ql/lib/codeql/swift/elements/expr/IfExprConstructor.qll 19450ccaa41321db4114c2751e9083fbd6ceb9f6a68905e6dca5993f90dd567a 42605d9af0376e3e23b982716266f776d998d3073d228e2bf3b90705c7cb6c58 +ql/lib/codeql/swift/elements/expr/InOutExprConstructor.qll c8c230f9a396acadca6df83aed6751ec1710a51575f85546c2664e5244b6c395 2e354aca8430185889e091ddaecd7d7df54da10706fe7fe11b4fa0ee04d892e0 +ql/lib/codeql/swift/elements/expr/InOutToPointerExpr.qll 60e70359ea6a433cac1b4d7afe27d739979176d2f881a8108e61fe7c1dea1a9a e9c7db3671cce65c775760c52d1e58e91903ad7be656457f096bfe2abab63d29 +ql/lib/codeql/swift/elements/expr/InOutToPointerExprConstructor.qll 06b1377d3d7399ef308ba3c7787192446452a4c2e80e4bb9e235267b765ae05d 969680fddeb48d9e97c05061ae9cbc56263e4c5ad7f4fad5ff34fdaa6c0010b4 +ql/lib/codeql/swift/elements/expr/InjectIntoOptionalExpr.qll d44e2ccede83bc55fb5fcd135d176a53be55783904be700e4b7bc6ca54f23499 6ec93a725c92a9abf62c39451eaf6435942b61b56bd06db0d494da0b5f407441 +ql/lib/codeql/swift/elements/expr/InjectIntoOptionalExprConstructor.qll e25cee8b12b0640bfcc652973bbe677c93b4cb252feba46f9ffe3d822f9d97e0 4211336657fce1789dcdc97d9fe75e6bc5ab3e79ec9999733488e0be0ae52ca2 +ql/lib/codeql/swift/elements/expr/IntegerLiteralExprConstructor.qll 779c97ef157265fa4e02dacc6ece40834d78e061a273d30773ac2a444cf099d0 d57c9e8bbb04d8c852906a099dc319473ae126b55145735b0c2dc2b671e1bcbd +ql/lib/codeql/swift/elements/expr/InterpolatedStringLiteralExprConstructor.qll 2d288a4cbaa3d7e412543fe851bb8764c56f8ccd88dc9d3a22734e7aa8da3c1a dfa6bea9f18f17d548d8af0bb4cd15e9a327a8100349d2ecfce51908062b45c8 +ql/lib/codeql/swift/elements/expr/IsExprConstructor.qll 0dc758a178c448c453fb390257f1a7a98d105efd8d8b2b592b290ef733d0fc80 e93e77865988bf522b9f48e105f913a7e33f98764e3edf910f9203ec44a785b1 +ql/lib/codeql/swift/elements/expr/KeyPathApplicationExprConstructor.qll c58c6812821d81dfb724fd37f17b2d80512c0584cf79e58ebb3a9657199e8f91 a4b9d8369f0224f9878bf20fcad4047756e26592fb7848988bdb96e463236440 +ql/lib/codeql/swift/elements/expr/KeyPathDotExprConstructor.qll d112a3a1c1b421fc6901933685179232ac37134270482a5b18d96ba6f78a1fd1 abce0b957bdf2c4b7316f4041491d31735b6c893a38fbf8d96e700a377617b51 +ql/lib/codeql/swift/elements/expr/KeyPathExprConstructor.qll 96f7bc80a1364b95f5a02526b3da4f937abe6d8672e2a324d57c1b036389e102 2f65b63e8eac280b338db29875f620751c8eb14fbdcf6864d852f332c9951dd7 +ql/lib/codeql/swift/elements/expr/LazyInitializerExprConstructor.qll deba52e51f31504564adc33da079b70f1f2da1e3e6f9538cba8bf97be0c27c64 4499c688d86c08cb33a754ad86f6adbe47754aa0fc58a4d77dd7cbfa1ca1fa50 +ql/lib/codeql/swift/elements/expr/LinearFunctionExpr.qll bcdc3b7c9f854f622e087a16a892af677439fee023d29341be534d297596bd3e b3253571f09a743a235c0d27384e72cf66b26ba8aa5e34061956c63be4940f15 +ql/lib/codeql/swift/elements/expr/LinearFunctionExprConstructor.qll 18998356c31c95a9a706a62dd2db24b3751015878c354dc36aa4655e386f53c3 7e02b4801e624c50d880c2826ef7149ad609aa896d194d64f715c16cfbd11a7d +ql/lib/codeql/swift/elements/expr/LinearFunctionExtractOriginalExpr.qll fb5d879aa0dd3191dfc587926618b59f977914780c607c6c62c293ecc654b6fe bd9f3c1a5114cec5c360a1bb94fe2ffaa8559dfdd69d78bd1a1c039b9d0cab10 +ql/lib/codeql/swift/elements/expr/LinearFunctionExtractOriginalExprConstructor.qll 4cdacae7a04da12cd19a51ff6b8fa5d0a5fb40b915073a261c1b71a1a0586c90 b4f338fa97ff256a53932901cf209473af8c78c8da0ec7caa66335bfb2aabe1f +ql/lib/codeql/swift/elements/expr/LinearToDifferentiableFunctionExpr.qll c841a3a0d5deb1d0f8c26122270c10793f8d49d8a484ac0fb838ad0733619fb6 a002c9d1cfc933b45eecf317654c90727a2986fb6d3403fc541be431d7c6b901 +ql/lib/codeql/swift/elements/expr/LinearToDifferentiableFunctionExprConstructor.qll 8a66e39915b4945bef0b1d5b31f4cbbf8149e1392ae42a29d661cfea9c0e3476 954242936f413271a64da2b8862168712ee7b3e0a31653344268f1d615e20fdf +ql/lib/codeql/swift/elements/expr/LiteralExpr.qll 8e39746df049b3598013901e5b5f9e5d328c22fb7893c273f1a8ab96ec8305fa a599db9010b51379172c400cbd28ab3ea0e893a2dd049e2af3ed1a5eb9329f73 +ql/lib/codeql/swift/elements/expr/LoadExpr.qll 74643292340ccd9ac1c6449faa65bb02ba86749ec6a4f64e7ff04572822a1acd 44b0d1213be692586ac2a2af025ed2c4c2c2f707d2d3e6abab11ee7a28083510 +ql/lib/codeql/swift/elements/expr/LoadExprConstructor.qll 47e2766b4019cec454177db59429f66ff4cc5e6c2ba811b9afd6b651fb390c8d a37517b63ad9e83b18a6e03cad5a4b31bc58d471a078603e7346c2f52dbb5ef9 +ql/lib/codeql/swift/elements/expr/LookupExpr.qll 46ed9daef8b3fe31ad93bb7450b11d35dfae639a7803c24c999603f49517e1ef cf76a591d96ccd9f64f404332b1be1e0587a124e3de0f9ea978d819549f51582 +ql/lib/codeql/swift/elements/expr/MagicIdentifierLiteralExprConstructor.qll 9ac0c8296b8a0920782210520b1d55b780f037cd080bbd1332daddddc23dac97 d87f853e1a761f3986236c44937cbe21d233e821a9ad4739d98ec8255829eb32 +ql/lib/codeql/swift/elements/expr/MakeTemporarilyEscapableExprConstructor.qll b291d55ccbdef0d783ba05c68f496c0a015a211c9e5067dc6e4e65b50292a358 1c2ee4068da4b6fc5f3671af5319a784c0d3e1aa715392f8416918738f3d3633 +ql/lib/codeql/swift/elements/expr/MemberRefExprConstructor.qll 484391d318c767336ae0b1625e28adcc656cbfa6075a38732d92848aaf8fb25e 2907badc97b8aa8df10912fd116758ce4762940753d6fa66d61a557e9d76cde6 +ql/lib/codeql/swift/elements/expr/MetatypeConversionExpr.qll 50ee8a089204600476f1a629bdfc8efe7718a62806abcd81901df9c8b257797c f4debff6b8aab8ddf041f3d2a9a3d9e1432e77178b3d6128ebd9861c4fa73ac1 +ql/lib/codeql/swift/elements/expr/MetatypeConversionExprConstructor.qll 925f2a5c20517f60d6464f52fe1f2940ea1c46b418571d9050f387be51b36705 60063f936b7180aea9eba42a029202a362473c0bb620e880001f0b76d326b54a +ql/lib/codeql/swift/elements/expr/NilLiteralExprConstructor.qll 483911d82316ea9c4fd29a46aa9e587e91ce51e78e6f55959aa6edafd5ae4c88 12ec784670587f43e793dd50e2bc47555897203dfa9bf3d8fc591ddeb39d3bb5 +ql/lib/codeql/swift/elements/expr/NumberLiteralExpr.qll 14e4dd1acbd947ccb86c1700ac0f0dd0830aee733da356b857d0efe612498fe3 abbe1abbabb1d0511429e2c25b7cbcfba524b9f8391f4d8a5aca079b2c1085e6 +ql/lib/codeql/swift/elements/expr/ObjCSelectorExprConstructor.qll f61b72989d2729e279b0e70343cf020e72de8daa530ef8f1e996816431720a50 37c5f7695da3a7db0f7281e06cc34328a5ae158a5c7a15e0ac64100e06beb7f9 +ql/lib/codeql/swift/elements/expr/ObjectLiteralExprConstructor.qll a18863eb82d0615e631a3fd04343646a2d45f21c14e666d4425a139d333ec035 b41bed928509bd792ec619a08560f1b5c80fb75cec485648601d55b9d7c53d1c +ql/lib/codeql/swift/elements/expr/OneWayExprConstructor.qll 1f6b634d0c211d4b2fb13b5ac3f9cf6af93c535f9b0d9b764feb36dbc11a252e a2f0660ac48420cfd73111b1100f7f4f6523140c5860e1e5489c105707106275 +ql/lib/codeql/swift/elements/expr/OpaqueValueExpr.qll 15e24ab58aa38242dcc01cce60fb006da3e1a1fd98d7d3a715af3c96d28f1efc 3bf654dc10e2057a92f5f6b727237ec0b0ec7f564a6cc6ef2027c20e8e23a1e9 +ql/lib/codeql/swift/elements/expr/OpaqueValueExprConstructor.qll 35e8475fd6a83e3ef7678529465852de9fb60d129bb5db13a26380c1376ada8b c9c999cb816b948be266aaa83bc22fb9af11b104137b4da1d99f453759784a62 +ql/lib/codeql/swift/elements/expr/OpenExistentialExpr.qll d6187b0ccca6e84c502a4528dcaa0ada8ade1c96ba0a85c5fcd2d052ad291558 cfd96b626180ef3c63c2dbc17b13cd6f585515427f5c3beac48896cf98234a67 +ql/lib/codeql/swift/elements/expr/OpenExistentialExprConstructor.qll c56e5e6f7ae59a089316cd66a9b03d2584024625c2c662e7f74526c0b15dbd60 ea3cc78dd1b1f8fb744258e1c2bf6a3ec09eb9c1181e1a502c6a9bc2cf449337 +ql/lib/codeql/swift/elements/expr/OptionalEvaluationExpr.qll 2f46c15d17a50b14e91552be8ac5b72dbdc9f39b8fac9fa068e519ae5c8aa99b 559902efedbf4c5ef24697267c7b48162129b4ab463b41d89bdfb8b94742fa9f +ql/lib/codeql/swift/elements/expr/OptionalEvaluationExprConstructor.qll 4ba0af8f8b4b7920bc1106d069455eb754b7404d9a4bfc361d2ea22e8763f4fe 6d07e7838339290d1a2aec88addd511f01224d7e1d485b08ef4793e01f4b4421 +ql/lib/codeql/swift/elements/expr/OptionalTryExprConstructor.qll 60d2f88e2c6fc843353cc52ce1e1c9f7b80978750d0e780361f817b1b2fea895 4eabd9f03dc5c1f956e50e2a7af0535292484acc69692d7c7f771e213609fd04 +ql/lib/codeql/swift/elements/expr/OtherConstructorDeclRefExprConstructor.qll cf726ed7ed830e17aaedf1acddf1edc4efc7d72ab9f9580bc89cc8eefbd54d8a 4ef3010dc5500bd503db8aa531d5455a9c80bc30172fb005abc6459b6f66ea00 +ql/lib/codeql/swift/elements/expr/OverloadedDeclRefExpr.qll adb49e25cdd87d2e6259399a7ce3a1fbe6eb345f9b8f4e34eb23cb39eb3555da 47b1c6df5397de490f62e96edc0656b1f97c0be73c6b99ecd78b62d46106ce61 +ql/lib/codeql/swift/elements/expr/OverloadedDeclRefExprConstructor.qll 2cf79b483f942fbf8aaf9956429b92bf9536e212bb7f7940c2bc1d30e8e8dfd5 f4c16a90e3ab944dded491887779f960e3077f0a8823f17f50f82cf5b9803737 +ql/lib/codeql/swift/elements/expr/ParenExprConstructor.qll 6baaa592db57870f5ecd9be632bd3f653c44d72581efd41e8a837916e1590f9e 6f28988d04b2cb69ddcb63fba9ae3166b527803a61c250f97e48ff39a28379f6 +ql/lib/codeql/swift/elements/expr/PointerToPointerExpr.qll 921645a373443d050dbc29b9f6bc4a734163c75aeffce453a4f8334b34077d30 54089de77845f6b0e623c537bc25a010ecf1b5c7630b1b4060d2b378abc07f4e +ql/lib/codeql/swift/elements/expr/PointerToPointerExprConstructor.qll 95cc8003b9a3b2101afb8f110ec4cbd29e380fc048ee080f5047bcf0e14a06c7 114d487a1bb2cd33b27a9c3a47ad1d7254766e169512642f8b09b9c32cf3dc86 +ql/lib/codeql/swift/elements/expr/PostfixUnaryExpr.qll a67abdf379f04f1aeee0795cd3ebeb28ed8dfe0efad15b128d44cc9e30b32cbd cbb2b2d54c8e316dc71388ea4ff6bb5d0a6204b4e9d9ce2888e1877a54e85e8f +ql/lib/codeql/swift/elements/expr/PostfixUnaryExprConstructor.qll c26326e2703b9a8b077ea9f132ae86a76b4010a108b8dcde29864f4206096231 70e45fbe365b63226d0132158cdd453e2e00d740a31c1fb0f7bfb3b2dedfd928 +ql/lib/codeql/swift/elements/expr/PrefixUnaryExprConstructor.qll 6d4c915baf460691cc22681154b1129852c26f1bd9fe3e27b4e162f819d934f5 7971698433bc03dbff2fec34426a96a969fab1a5a575aaf91f10044819e16f6d +ql/lib/codeql/swift/elements/expr/PropertyWrapperValuePlaceholderExpr.qll 35a61a7f68e71165690127b445fff39780028cb6be5e7b5eadaafa8aeb6b2321 f9e32f65e6d453d3fa857a4d3ca19700be1f8ea2f3d13534656bc21a2fc5f0b0 +ql/lib/codeql/swift/elements/expr/PropertyWrapperValuePlaceholderExprConstructor.qll 874da84b8ac2fbf6f44e5343e09629225f9196f0f1f3584e6bc314e5d01d8593 e01fc8f9a1d1cddab7c249437c13f63e8dc93e7892409791728f82f1111ac924 +ql/lib/codeql/swift/elements/expr/ProtocolMetatypeToObjectExpr.qll db0a35204b99aa6665d95461db0c5592739172d3def43d38461612622d39fea7 1f342dead634daf2cd77dd32a1e59546e8c2c073e997108e17eb2c3c832b3070 +ql/lib/codeql/swift/elements/expr/ProtocolMetatypeToObjectExprConstructor.qll aaaf5fd2496e24b341345933a5c730bbfd4de31c5737e22269c3f6927f8ae733 bece45f59dc21e9deffc1632aae52c17cf41924f953afc31a1aa94149ecc1512 +ql/lib/codeql/swift/elements/expr/RebindSelfInConstructorExprConstructor.qll 434e00b6e5d3ccf356dabb4a7d6574966676c32d4c257ad3606d5b9e2b715524 637a16d0f5f504bad4a04bb85d6491a94738781d3282bc27363cceafb3023408 +ql/lib/codeql/swift/elements/expr/RegexLiteralExprConstructor.qll 7bf1bdba26d38e8397a9a489d05042ea2057f06e35f2a664876dc0225e45892d dcc697170a9fc03b708f4a13391395e3986d60eb482639e3f5a3ba0984b72349 +ql/lib/codeql/swift/elements/expr/SelfApplyExpr.qll 75a7f14daedd69803bbb2650e503c7db5589044347c3b783f8cd13130c7c508e f0349628f9ead822783e09e56e0721f939bfb7f59c8661e6155b5a7d113c26f3 +ql/lib/codeql/swift/elements/expr/SequenceExpr.qll b1269230db9782dacba9a61e60fb2b962b05d47048b205a5bcf89157fe475b82 3b2d06ac54746033a90319463243f2d0f17265c7f1573cbfedbdca3fb7063fd2 +ql/lib/codeql/swift/elements/expr/SequenceExprConstructor.qll 5a15ede013bb017a85092aff35dd2f4f1fb025e0e4e9002ac6e65b8e27c27a0b 05d6c0e2fa80bbd088b67c039520fe74ef4aa7c946f75c86207af125e7e2e6b4 +ql/lib/codeql/swift/elements/expr/StringLiteralExprConstructor.qll 49de92f9566459609f4a05b7bf9b776e3a420a7316151e1d3d4ec4c5471dcffb 4a7474d3782b74a098afe48599faee2c35c88c1c7a47d4b94f79d39921cd4a1f +ql/lib/codeql/swift/elements/expr/StringToPointerExpr.qll 8fcb58665cac6f01df36fbd4f3cd78f515ee57bc1a2bdf5f414174615442cf49 6f6710f7ac709102b0f3240dcd779baf5da00d2e7a547d19291600bc405c5a54 +ql/lib/codeql/swift/elements/expr/StringToPointerExprConstructor.qll 138dd290fff168d00af79f78d9d39a1940c2a1654afd0ec02e36be86cebef970 66f7385721789915b6d5311665b89feff9469707fab630a6dcbf742980857fd9 +ql/lib/codeql/swift/elements/expr/SubscriptExprConstructor.qll dd2a249c6fb3a2ce2641929206df147167682c6294c9e5815dab7dddbac0d3bd ad382cbd793461f4b4b1979b93144b5e545ba91773f06957c8e1b4808113cd80 +ql/lib/codeql/swift/elements/expr/SuperRefExprConstructor.qll 7d503393bddf5c32fb4af9b47e6d748d523fc4f3deb58b36a43d3c8c176c7233 86d2312a61ccb3661d899b90ac1f37a1079b5599782d52adaf48f773b7e7dd72 +ql/lib/codeql/swift/elements/expr/TapExprConstructor.qll aa35459a9f1d6a6201ce1629bc64d5902f3e163fcef42e62b1828fa8fde724f8 88d92995026d2c2cbd25fab9e467d91572174d3459584729723a5fe3c41f75b9 +ql/lib/codeql/swift/elements/expr/TryExprConstructor.qll 786f2e720922c6d485a3e02fe39ef53271399be4a86fdea7226a7edb1e01b111 e9f527562c45e75276cbe2b899c52677268dffd08c3f6c260cd1a9abbc04bd25 +ql/lib/codeql/swift/elements/expr/TupleElementExprConstructor.qll d5677df4f573dd79af7636bf632f854e5fd1cbe05a42a5d141892be83550e655 5248a81d39ed60c663987463f1ce35f0d48b300cd8e9c1bcd2fdbf5a32db48dc +ql/lib/codeql/swift/elements/expr/TupleExprConstructor.qll 0eec270bb267006b7cdb0579efe4c420e0b01d901254a4034c3d16f98dc18fc0 4dab110e17ff808e01e46fc33436ffd22ebf5644abcb92158b5b09a93c0b1c19 +ql/lib/codeql/swift/elements/expr/TypeExprConstructor.qll d4cbe4ddbd7a43a67f9a9ca55081ae11c4a85aa1cc598bc31edd3ff975255c62 1ca407571c456237f3f4f212bbcfa821d96aac44c9e569c6e5a4929c144c4569 +ql/lib/codeql/swift/elements/expr/UnderlyingToOpaqueExpr.qll f8238439d553627d5b82f21fd906f602e2d1fc884d593209be00deb2fb85b8c7 f947161c8956113ff052743fea50645176959f2b04041cb30f4111c2569400be +ql/lib/codeql/swift/elements/expr/UnderlyingToOpaqueExprConstructor.qll 6b580c0c36a8c5497b3ec7c2b704c230de4529cfdeb44399184503048dc547d7 b896b2635319b2b2498eac7d22c98f1190ff7ba23a1e2e285c97a773860d9884 +ql/lib/codeql/swift/elements/expr/UnevaluatedInstanceExpr.qll 7d390adafff48b7365e4abe80e98a9367030ad62992b0ee8b17e16d140c0e673 a094972b3b30a8a5ead53e12ede960f637190f9fa7dd061f76b4a4ab1ff5282e +ql/lib/codeql/swift/elements/expr/UnevaluatedInstanceExprConstructor.qll 9453bb0ae5e6b9f92c3c9ded75a6bbaff7a68f8770b160b3dd1e4c133b421a80 51ac38be089bbc98950e8175f8a2b0ab2a6b8e6dbb736c754b46bf3c21b7551e +ql/lib/codeql/swift/elements/expr/UnresolvedDeclRefExprConstructor.qll 6f7498cf4edc48fa4c0184bb4068be63a88a0a5ab349bd54228f23d23df292cb b9e16dc1bd56535494a65f8faa780fca70a7eae1e04da132d99638ca2ee5e62c +ql/lib/codeql/swift/elements/expr/UnresolvedDotExprConstructor.qll 11d54c61f34291a77e4de8d1d763de06da5933ab784f0ae6b4bf6798ab6e2297 78b01e12cd7f49dc71456419922cf972b322bd76554090bedeb4263a8701f1af +ql/lib/codeql/swift/elements/expr/UnresolvedMemberChainResultExpr.qll 0eaae416c14e9e6cb7319344509012a321587f96fcbd4f9c45002908450ff3d9 97362882ce004dce33e97a76f2857527925696f21ac5f1f1b285d57fea7e1d57 +ql/lib/codeql/swift/elements/expr/UnresolvedMemberChainResultExprConstructor.qll 3e76d7a004acd986c8d58ff399d6fb0510577b9a67e01a85294f89319038e895 e02f88167623ad78bc44f4682b87312bd3c44ddb1f0f85970e19fdbf4df3a4a8 +ql/lib/codeql/swift/elements/expr/UnresolvedMemberExpr.qll 4afc9da4eeb97f89adf31d3e04610d7df3437b66fe1c601507421fad7d3d3996 6591d38ddf3aa0e4db0fa7fdb28b8f70d8278ff96e8117c560ecb1bdf770bb2a +ql/lib/codeql/swift/elements/expr/UnresolvedMemberExprConstructor.qll db3c55863184bd02e003bf159cab3d7f713a29749d35485473f727f3ccf801a8 ea74f8904d67ac3552d85c12a2b8a19d3e2edf216efccb4263a546501fd4eba2 +ql/lib/codeql/swift/elements/expr/UnresolvedPatternExpr.qll cb316e3bd39f7d558466f91428c5c8da7b3b07ea12e138c72fda33f3b4e3398a f3624cdd8025f1bb525cd0e9a85dc098ca8fa7876f1754849bade0d4e3840589 +ql/lib/codeql/swift/elements/expr/UnresolvedPatternExprConstructor.qll 7b7f834d2793c7e3d60fbd69cb989a170b0e62c2777d817d33a83110ca337e94 f4f8ee260274e547514f3a46ced487abe074409b209adb84f41dc9ebb3d67691 +ql/lib/codeql/swift/elements/expr/UnresolvedSpecializeExpr.qll 8b6975b0759e4a694d2b715f48b22af0b58b390c85ca1299e5a3aa5a687a61db c6fa963f07ed372dca97ea217a836f603c276ed309576b6a13e7cc75d13038c4 +ql/lib/codeql/swift/elements/expr/UnresolvedSpecializeExprConstructor.qll 1cbb484b72efa96b510103bea12247adfe31ec17f9d62b982868d4a5ca3e19b9 af57548a00010dc5e8a51342e85e0c7fc15a30068d7d68b082236cfc53b8c60b +ql/lib/codeql/swift/elements/expr/UnresolvedTypeConversionExpr.qll d7e889aa4c45ea8a7f171b0de7229cae8872f2f37dc2d5cdb458ffba66ef27b9 0270bc88ba7c53e443e35d04309fcff756f0afac0b3cd601779358b54f81e4a1 +ql/lib/codeql/swift/elements/expr/UnresolvedTypeConversionExprConstructor.qll 191cc2641ea735a72cedd50a1b4fcc66e0e42e3bdc5d1368003790d1621478f4 07384657c12f97d9cac284154a2bcff9c7bc4a745e705cbd7c1e2f0bc857ad48 +ql/lib/codeql/swift/elements/expr/VarargExpansionExprConstructor.qll b3d9bb66747c3495a47f8d7ea27162a216124e94ceb4a0c403faf7c1ca0c1ea1 84cfb1600f461ddfe088b0028ca26b1e2708bd5b59e634eed2d8766817fa6906 +ql/lib/codeql/swift/elements/pattern/AnyPatternConstructor.qll 9ce05c2c4c015a072f7ab5b0d1a15fa7c2666f252ae361164c59e90150338b2a 4a0d79d90e5392187cf631397b94a0e23bc6d661d381e880b129e4964e6468f2 +ql/lib/codeql/swift/elements/pattern/BindingPatternConstructor.qll efbf0b1979430d4a285f683a1a8869366e14948499e015beca8f4d6b80fe9c9b 5e9e5339cda4e6864078883421ee5bc5c5300efc48dc8a0fcf0c9fbdd508a10e +ql/lib/codeql/swift/elements/pattern/BoolPatternConstructor.qll 6f06125093da5b555990c1636bedc95e5664551bc3bc429a3428dba2ebe2e0dd 4d775af563074088dcd6b91adf133a0a03201e21b32669ea3c0f47043e4800c6 +ql/lib/codeql/swift/elements/pattern/EnumElementPatternConstructor.qll 3d4fd658bbece603aba093d524c60db5e3da912aa6f730bd99de1bb23c829fe3 b63c250501f5d778a9fbece1661c8f48b65f0a5c6791f89ce38a073591496d41 +ql/lib/codeql/swift/elements/pattern/ExprPatternConstructor.qll 477db1715b13660d1fecab766d65ef719be2d700e1f43767c6853f77506534d9 8fe20342b9da54f4aae05b7f925afa39cbbb4b0d26f1c4f294fcd5f83a5b536b +ql/lib/codeql/swift/elements/pattern/IsPatternConstructor.qll 209ad40227f49dfe1b82e6c9c318d0a8adc808c99fb46034512bcff96324ee91 2776b04bca8fbaadd5d2cc4017f3760f2294d5793ecf70135920036cff3d6275 +ql/lib/codeql/swift/elements/pattern/NamedPatternConstructor.qll 437ccf0a28c204a83861babc91e0e422846630f001554a3d7764b323c8632a26 91c52727ccf6b035cc1f0c2ca1eb91482ef28fa874bca382fb34f9226c31c84e +ql/lib/codeql/swift/elements/pattern/OptionalSomePatternConstructor.qll bc33a81415edfa4294ad9dfb57f5aa929ea4d7f21a013f145949352009a93975 9fb2afa86dc9cedd28af9f27543ea8babf431a4ba48e9941bcd484b9aa0aeab5 +ql/lib/codeql/swift/elements/pattern/ParenPatternConstructor.qll 7229439aac7010dbb82f2aaa48aedf47b189e21cc70cb926072e00faa8358369 341cfacd838185178e95a2a7bb29f198e46954098f6d13890351a82943969809 +ql/lib/codeql/swift/elements/pattern/Pattern.qll e2f802e788d00a9da18dd6b5d3536666972d9a6a87969b93f95174a922afbbac cbecbc4b2d9bea7b571b9d184a0bb8cf472f66106e96d4f70e0e98d627f269a5 +ql/lib/codeql/swift/elements/pattern/TuplePatternConstructor.qll 208fe1f6af1eb569ea4cd5f76e8fbe4dfab9a6264f6c12b762f074a237934bdc 174c55ad1bf3058059ed6c3c3502d6099cda95fbfce925cfd261705accbddbcd +ql/lib/codeql/swift/elements/pattern/TypedPatternConstructor.qll 1befdd0455e94d4daa0332b644b74eae43f98bab6aab7491a37176a431c36c34 e574ecf38aac7d9381133bfb894da8cb96aec1c933093f4f7cc951dba8152570 +ql/lib/codeql/swift/elements/stmt/BraceStmtConstructor.qll eb2b4817d84da4063eaa0b95fe22131cc980c761dcf41f1336566e95bc28aae4 c8e5f7fecd01a7724d8f58c2cd8c845264be91252281f37e3eb20f4a6f421c72 +ql/lib/codeql/swift/elements/stmt/BreakStmtConstructor.qll 700a23b837fa95fc5bce58d4dd7d08f86cb7e75d8de828fee6eb9c7b9d1df085 4282838548f870a1488efb851edb96ec9d143bf6f714efe72d033ee51f67a2c5 +ql/lib/codeql/swift/elements/stmt/CaseLabelItemConstructor.qll ff8649d218f874dddb712fbeb71d1060bd74d857420abbd60afa5f233e865d65 438526ef34e6ff3f70c4861e7824fdb4cf3651d7fbeea013c13455b05b2b5b97 +ql/lib/codeql/swift/elements/stmt/CaseStmtConstructor.qll f80665bfea9bf5f33a0195d9fb273fe425383c6612a85b02166279466d814f03 5b45dbf87b2c660c7f0cc9c10c4bc9fefd8d3d7f8a0a7c95dabe257169ea14db +ql/lib/codeql/swift/elements/stmt/ConditionElementConstructor.qll 05e98b9c9ecaf343aff209c6b509ae03a774d522b5b4a1e90a071ac724a3100f 620e57a7082160e810cb4bcf129736c7510a75d437c3c1e5a2becc5ca4d013ce +ql/lib/codeql/swift/elements/stmt/ContinueStmtConstructor.qll 64932cdf9e5a6908547a195568e0b3d3da615699cf44d8e03c3a2b146f8addf4 32d5aad9b594b4d0349d79c0b200936864eafc998ab82b2e5a1c6165d3b88cbd +ql/lib/codeql/swift/elements/stmt/DeferStmtConstructor.qll 1d541efcd414a5c0db07afebd34556181b5339cb2d2df3dc9a97c8b518b21581 598096568e26177d0fc602b4a00092372771f9ba840296e30e8c3b280f7c630d +ql/lib/codeql/swift/elements/stmt/DoCatchStmtConstructor.qll c23512debcea7db48ca0b66560a752301de8ec148de31bda0ba7614d6f6f2c51 f1165f2854a7e0699da0c11f65dbf199baf93fc0855f5a6c06c73adf0ded6bab +ql/lib/codeql/swift/elements/stmt/DoStmtConstructor.qll 6555b197019d88e59e4676251fe65e5a72db52b284644c942091851cc96acac4 9d0c764391405c8cacfdf423ba20c6aa06823e30e8eee15fba255938ad3c6bd9 +ql/lib/codeql/swift/elements/stmt/FailStmtConstructor.qll a44f0fc51bcf51215256e2ead3f32ff41cd61cc6af2a73f952e046ab5cca60ed 1634392524d9c70421f9b0fbe03121858b43cfd740e25f271a1fce2022d2cc2b +ql/lib/codeql/swift/elements/stmt/FallthroughStmtConstructor.qll 657f6a565884949e0d99429a75b3b46d6da2b6fe2ecacfdc2be71d95ad03decb 282b99f61fc51d6acb82256d4f816497add99bf84a0022f5757ca9911fb62a20 +ql/lib/codeql/swift/elements/stmt/ForEachStmtConstructor.qll e21b78d279a072736b9e5ce14a1c5c68c6d4536f64093bf21f8c4e2103586105 02a28c4ef39f8e7efffb2e6d8dcfeccb6f0a0fc2889cbcda5dd971711ac0ff07 +ql/lib/codeql/swift/elements/stmt/GuardStmtConstructor.qll 77ddea5f97777902854eec271811cd13f86d944bcc4df80a40ed19ad0ee9411e 1602e1209b64530ee0399536bff3c13dcecbccbc92cc1f46bc5bbb5edb4e7350 +ql/lib/codeql/swift/elements/stmt/IfStmtConstructor.qll c65681a3e20e383173877720e1a8a5db141215158fffad87db0a5b9e4e76e394 104d1a33a5afb61543f7f76e60a51420599625e857151c02ac874c50c6985ee9 +ql/lib/codeql/swift/elements/stmt/LabeledConditionalStmt.qll 77c2dc7bfa551dd96109ee64ca9bbd5774a36762dd00cfad89a21eaf237e1f18 2b082cc547b431391f143d317c74fe7a3533f21cd422a6bd3c9ef617cacecc0f +ql/lib/codeql/swift/elements/stmt/PoundAssertStmtConstructor.qll 70a0d22f81d7d7ce4b67cc22442beee681a64ac9d0b74108dfa2e8b109d7670e 08fee916772704f02c560b06b926cb4a56154d01d87166763b3179c5d4c85542 +ql/lib/codeql/swift/elements/stmt/RepeatWhileStmtConstructor.qll e19d34dbf98501b60978db21c69abe2b77896b4b6379c6ff02b15c9f5c37270e a72db7c5cb0eb5be7b07cbddb17247d4d69d2bb8cbc957dc648c25fa6c0636ce +ql/lib/codeql/swift/elements/stmt/ReturnStmtConstructor.qll ade838b3c154898f24a8e1d4ef547d460eac1cd6df81148ffb0f904d38855138 c00befd9ac0962172369319d7a791c44268413f760f2ac5e377fdee09c163101 +ql/lib/codeql/swift/elements/stmt/Stmt.qll 18aaec168417ad00fcb7fa120f9b4251b6a260ab7e31799687ac57b31c4a4819 014e29f6cc639359708f4416b1719823218efa0e92dc33630ecfc051144c7ac0 +ql/lib/codeql/swift/elements/stmt/StmtConditionConstructor.qll 599663e986ff31d0174500788d42a66180efb299769fc0f72a5c751621ddb9e2 8da4524319980f8039289165d01b53d588180cc1139b16ea7a6714b857086795 +ql/lib/codeql/swift/elements/stmt/SwitchStmtConstructor.qll e55c4bda4e8c1b02e8bb00b546eca91b8797c9efb315d17aa9d7044bef0568b9 a8315347d620671ec752e7ff150faa6e6cbb2353773bc16f1d0162aa53f2c8ed +ql/lib/codeql/swift/elements/stmt/ThrowStmtConstructor.qll 5a0905f1385b41e184c41d474a5d5fa031ed43e11c0f05b0411de097302cf81c 658daa8e97de69ed0c6bb79bc1e945c39bac9ff8d7530bd4aca5a5d3e3606a3a +ql/lib/codeql/swift/elements/stmt/WhileStmtConstructor.qll 9b5711a82db7c4f2c01f124a1c787baa26fd038433979fd01e778b3326c2c357 4e89d6b2dfefd88b67ec7335376ea0cdccab047319a7ec23113728f937ff1c26 +ql/lib/codeql/swift/elements/stmt/YieldStmtConstructor.qll c0aa7145a96c7ba46b904e39989f6ebf81b53239f84e5b96023ea84aef4b0195 50908d5ee60b7bc811ca1350eff5294e8426dbbab862e0866ef2df6e90c4859c +ql/lib/codeql/swift/elements/type/AnyBuiltinIntegerType.qll f89e8ede8fc455a74ad643521d3910dc27b29359f7e15b0333d823831b7cd20c bbd9611e593c95c7ddff9d648b06b236f1973759f5cd3783d359ddb7d2c7d29e +ql/lib/codeql/swift/elements/type/AnyFunctionType.qll 9a2f25f7f72aa80a2dcd936886dfda32f2b48ae44b79da58dbad5201ef4d7375 c7154b0018d161a6dcf461f351f37b2b4f6813968d2c2d0b1e357ea8c6f50710 +ql/lib/codeql/swift/elements/type/AnyGenericType.qll 9020d36bc6899c7f305cd99403d007c6d63fadfa080b4ec57372e7a76ca60975 4474fb21ac3f092f6c1e551cd9cf397abaa721ac2e30019b1d1a3974224d907d +ql/lib/codeql/swift/elements/type/AnyMetatypeType.qll d71d790b77c2d83f3637a1fbf2bae77ac5e95d8dc81a7fd662c22db586eea71c c73a76b03eee2faee33bb7e80ab057dbc6c302d9c8d5bfa452a7e919f86d942a +ql/lib/codeql/swift/elements/type/ArchetypeType.qll 5dba765115cc421e84c56e196d2a2d70310f3d8048aa78bd3b2042785aa5e880 28190086005e4e14b0556162d18aafe4d59eef0cb69e1a02bc440b27db012197 +ql/lib/codeql/swift/elements/type/ArraySliceType.qll 57184bc51fb02bc966d1ae143750a2a82e704dc52d20e314965420a83ebd9164 21d15a7dab938ce81de00b646b897e7348476da01096168430a4a19261b74f6d +ql/lib/codeql/swift/elements/type/ArraySliceTypeConstructor.qll a1f1eb78e59c6ddf2c95a43908b11c25e2113c870a5b0b58e00b1ef5e89974c0 f0b4681e070343a13ee91b25aa20c0c6a474b701d1f7ea587ad72543a32dab72 +ql/lib/codeql/swift/elements/type/BoundGenericClassType.qll 7d02a471484de918f1395638f6e8017a3301f8953016c9ed62300308c6e2b6ac 284da181c967e57023009eb9e91ed4d26ae93925fea07e71d3af0d1b0c50f90a +ql/lib/codeql/swift/elements/type/BoundGenericClassTypeConstructor.qll 1174753a0421f88abdca9f124768946d790f488554e9af3136bb0c08c5a6027f c6565c9f112f1297e12f025865d6b26c6622d25a8718de92222dd4fb64ede53e +ql/lib/codeql/swift/elements/type/BoundGenericEnumType.qll 685670068892a04cd20b718118c46c768488807a57cc75102b3d6be5b07e3c94 c394d8e963e2edec82b27368dc7832c033dbf56a8acd8990ff6cf825c29cc7d9 +ql/lib/codeql/swift/elements/type/BoundGenericEnumTypeConstructor.qll 4faf2e4f76d446940d2801b457e8b24f5087494b145bae1e1e0a05ba2e8d4eee eda2bdd1b9f2176d8a6c78de68ae86148e35f5d75d96d78a84995ae99816f80e +ql/lib/codeql/swift/elements/type/BoundGenericStructType.qll 8e87dbeb3bad4c3b37a5260aadfac5b6c15c067a84be376ba8b5c3cf0794bd21 a3f7a3549ff7ab0bdbfda7da4c84b125c5b96073744ae62d719e9d3278e127cf +ql/lib/codeql/swift/elements/type/BoundGenericStructTypeConstructor.qll 9bc4dd0ffc865f0d2668e160fb0ce526bb4aa7e400ad20a10707aad839330d31 a0f28828125726f1e5d18ed7a2145ad133c3a2200523928b69abbdc1204e3349 +ql/lib/codeql/swift/elements/type/BoundGenericType.qll 1854ab70126e449cb64e9ac00b2eb465d1fac342e172a4eff6e7417a5d663d0e 86a3a2c73a837a4c58d104af5d473fe3171bd12b03d7a2862cc0ec6d2e85667f +ql/lib/codeql/swift/elements/type/BuiltinBridgeObjectType.qll 86971ec94ed0b5db7b33484d310c01e3b7d835e7845e7ec6f5f7a3e3df3bfe3d d5f2623c2742b9c123bd6789215f32dcb8035475c98b792e53c6ef583e245f65 +ql/lib/codeql/swift/elements/type/BuiltinBridgeObjectTypeConstructor.qll e309fbf1bb61cc755fd0844697f8d587c63477fe11947f4af7d39b07fc731e8f 41acdb0acf0f2eb6b1b38fb57cbbf4dfcec46afc089798b829c1ffc0539cd0fc +ql/lib/codeql/swift/elements/type/BuiltinDefaultActorStorageType.qll 3f2a38da5222ebddcd9c0ef7ddccf84e26616a56e19978a2caa725ee6743e594 96777d099fe5e06a17e5770ce73fa4f50eefbe27703218871dc7dec4c2e8e11f +ql/lib/codeql/swift/elements/type/BuiltinDefaultActorStorageTypeConstructor.qll 645d8dd261fffb8b7f8d326bcdd0b153085c7cf45fe1cc50c8cb06dbe43a9d8d 0424cf62f6f0efb86a78ba55b2ef799caf04e63fdf15f3f8458108a93ee174b1 +ql/lib/codeql/swift/elements/type/BuiltinExecutorType.qll 226a09b42840529bd31c4e9795d570466462a8e5e1833edbcb36fc96458a33b3 bb2f7e62295b20fa07cc905ef0329293c932ab8ad115f8d37aa021e421b425c0 +ql/lib/codeql/swift/elements/type/BuiltinExecutorTypeConstructor.qll 72545245dbf61a3ab298ece1de108950c063b146a585126753684218ad40ea10 b926c1688325022c98611b5e7c9747faf0faf8f9d301d976aa208a5aace46e0d +ql/lib/codeql/swift/elements/type/BuiltinFloatType.qll 7b307414ec4175d87ef715abe950830214785eca4728bfe32542f89f061cc3a6 3dfa2ed2e1f469e1f03dcc88b29cb2318a285051aa2941dcc29c7c925dad0d29 +ql/lib/codeql/swift/elements/type/BuiltinFloatTypeConstructor.qll 4254aa8c61c82fbea44d3ca1a94876546024600a56ac88d0e622c6126dfe6b9f 953f0fcb52668e1a435f6cabf01f9c96c5fc1645bf90b8257907218a4ce51e02 +ql/lib/codeql/swift/elements/type/BuiltinIntegerLiteralType.qll 5ca7d5b579924cd37d67703ce032fd626f6f2e53aecbd8246284471a7c766237 462bfc80eb0cfe478562fc5dcade8e6a1ecdd958b26481e4df19ecf632e72a7f +ql/lib/codeql/swift/elements/type/BuiltinIntegerLiteralTypeConstructor.qll 21c0ba7a316accd4197d57dafbeb7ce356ccef0a376e9188ec78b3e9a7d046bd 165f4a30ffb1fa34ee94c69975cbea57d940aea2e46558af7eff3a1941a269c2 +ql/lib/codeql/swift/elements/type/BuiltinIntegerType.qll ba9c4722bc8adcd3b81a516f228a2d1d6c6900a0a74c1586e6fda11fdc57cde9 2807cb11ca75f8d8cc3bc87159786528f7f28e6c594ee79bf0984d0dd960d524 +ql/lib/codeql/swift/elements/type/BuiltinIntegerTypeConstructor.qll 8e738b8996c0b1612900dd40d6dd9ea395e7463a501feb04cc3c27e7fe73ee02 c517e29002513b5ae6d05d52bc3f7e8a85f33f6e9be0f56cdd53eb25de0c9cb9 +ql/lib/codeql/swift/elements/type/BuiltinJobType.qll 77ae06df788a1d6bdf060525f842408fb5ff773397862d30dfd46f80fe889c64 7c381ec2a6be2991518cfeef57be62238f50c27845cad8b72434c404ecc5c298 +ql/lib/codeql/swift/elements/type/BuiltinJobTypeConstructor.qll a63724058d426fc38c092235adec6348aa9ea302aca408d4e9721d924ec28539 abf1263e6fad8f3de7692340399f013010f39c01f5fe93b92a491b7301be998c +ql/lib/codeql/swift/elements/type/BuiltinNativeObjectType.qll 5fddd40563fdff908bd357c5b34086b927f9e615554a8c0942a3bc24ee5936fc 3225e0b8e70f488b84d02b84ef02bf1a3ac879d8f442de2b6d2c3ae53445e8e8 +ql/lib/codeql/swift/elements/type/BuiltinNativeObjectTypeConstructor.qll 9ec77aa1da74d7fe83a7c22e60a6b370d04c6859e59eed11b8dbc06a1ac8e68b bd9dcd8c5317d13a07695c51ff15f7d9cbf59ad7549301d42950caf5c6cc878f +ql/lib/codeql/swift/elements/type/BuiltinRawPointerType.qll 06ebac74cfcdc7195de3159d528288afb32786a071e42c2ede932666d89ea4d3 d2f6b327e6c5d4ff9382041bcebad2b9312eb86116c42b24b88c558b10a7561a +ql/lib/codeql/swift/elements/type/BuiltinRawPointerTypeConstructor.qll 7f77e1c768cb46b0eb8b08bb36e721417b95f1411bd200636ffdfc4e80c3c5c3 ce0916e95044ad74f5d7e762f3cc22065cc37e804f094e6067908bd635da6d97 +ql/lib/codeql/swift/elements/type/BuiltinRawUnsafeContinuationType.qll c91a28c12be5694004e02680d5d32bc3b67208ef6a7e0f9ab04cd4a7bb3a83ed 81682a768dcbcd72b2f13b5257e1f05b642e762de92bb3f0e275f863bad261c7 +ql/lib/codeql/swift/elements/type/BuiltinRawUnsafeContinuationTypeConstructor.qll f5a6c5ea5dd91c892f242b2a05837b2a4dd440365a33749994df8df30f393701 2eab1e5815c5f4854f310a2706482f1e7b401502291d0328d37184e50c0136b9 +ql/lib/codeql/swift/elements/type/BuiltinType.qll 6031ef4546c562d127d7c7120d12b9183021f2d9ff171ebf41ffa8491ce1a628 8e02dc1d67222a969ba563365897d93be105a64ec405fd0db367370624796db2 +ql/lib/codeql/swift/elements/type/BuiltinUnsafeValueBufferType.qll 2feff34c6e0c3cb22ff287b4b0fd7bac97ce796289175524a63c0a16258ef966 27a98fe13786b8d59d587ac042e440dec6699c76eb65288bbff6d374c28bfc53 +ql/lib/codeql/swift/elements/type/BuiltinUnsafeValueBufferTypeConstructor.qll 08a3a0f1ab53739a0db79a185a0e05538c1b7c7318b25bea93e0044ad98a3c6b fb8bb4ca4b20c6581d4419ac48581bf6e75b20e1612a953e31a7207c7dd0a0d8 +ql/lib/codeql/swift/elements/type/BuiltinVectorType.qll cfe1887a0f626704881622fb63287bc408fcf72022c8ba7f3bd14974068f36a5 df375c900db766f3f66dc022cb6302f2000bda90b5f2f023be992519948151f1 +ql/lib/codeql/swift/elements/type/BuiltinVectorTypeConstructor.qll 81d10e15693a33c51df659d4d8e8fa5dedea310415f580c6861e0043d36e83d3 3f60d067b860f3331edb5c0e67b2e9e469b78a9bcdb39a2f3a8724c6a6638f5e +ql/lib/codeql/swift/elements/type/ClassType.qll a69b0552206ca564124dfc9befd6288c0b84dcbadfd758baa85a33e0d8b820e8 a50d11cff50d948fcbbe3d27332f7e5842291844eaee9750d72063b7d2c0d7c2 +ql/lib/codeql/swift/elements/type/ClassTypeConstructor.qll 0c462e43cc8139d666fe1d77b394f29f4141064c9295ec3581fe20f920cbbbe7 43cce957ebb274ff34f14ca8bdcf93ab9c81a27a204fa56e37d7d17c4a469600 +ql/lib/codeql/swift/elements/type/DependentMemberType.qll 5d57942f02b68fce9970176a15365cd5a4e7c8092f886781388098d53cdc8615 46b2e84f7731e2cc32b98c25b1c8794f0919fbd3c653ba9b2e82822ab351e164 +ql/lib/codeql/swift/elements/type/DependentMemberTypeConstructor.qll 8580f6bbd73045908f33920cbd5a4406522dc57b5719e6034656eec0812d3754 fdeba4bfc25eecff972235d4d19305747eaa58963024735fd839b06b434ae9f2 +ql/lib/codeql/swift/elements/type/DictionaryType.qll b5b815ec4518781ccc600caaea81371e95fbee8a97803e5dce8e0bfc8789bae6 6b6901e8331ae2bd814a3011f057b12431f37b1ad57d3ecdaf7c2b599809060f +ql/lib/codeql/swift/elements/type/DictionaryTypeConstructor.qll 663bd10225565fab7ecd272b29356a89750e9fc57668b83bdb40bfb95b7b1fcb 5bfe2900eceee331765b15889357d3b45fc5b9ccaf034f13c76f51ad073c247f +ql/lib/codeql/swift/elements/type/DynamicSelfType.qll 7ba19e4fa1a8bbbc41fb08c16abbd1949feebe8ddadad7d3dfcb525f2abf5746 f9544f83ee11ae2317c7f67372a98eca904ea25667eeef4d0d21c5ef66fe6b28 +ql/lib/codeql/swift/elements/type/DynamicSelfTypeConstructor.qll f81ea2287fade045d164e6f14bf3f8a43d2bb7124e0ad6b7adf26e581acd58ff 73889ef1ac9a114a76a95708929185240fb1762c1fff8db9a77d3949d827599a +ql/lib/codeql/swift/elements/type/EnumType.qll d5428bcca8398cfbf706689b32390460d8c93cc2c733ceb10432ed496d11579d 7eb0dad9ffc7fad2a22e68710deac11d5e4dfa18698001f121c50850a758078f +ql/lib/codeql/swift/elements/type/EnumTypeConstructor.qll aa9dbd67637aae078e3975328b383824a6ad0f0446d17b9c24939a95a0caf8df 1d697f400a5401c7962c09da430b8ce23be063aa1d83985d81bcdc947fd00b81 +ql/lib/codeql/swift/elements/type/ErrorType.qll ac897e297783736a984eb6168be9b300b7a2a536ae3988b6ec29426a38bc11f0 c02282abefeb4c93938cc398d4c06ccd2be2c64e45612f20eafc73783fa84486 +ql/lib/codeql/swift/elements/type/ErrorTypeConstructor.qll b62dcd329e8bba82bd70aa439ed4d0ddb070da6fcd3ce5ce235e9c660ce5b5a8 43e3c4b7174bc17ca98c40554c2dbae281f1b66617d8ae59e8f970308fd24573 +ql/lib/codeql/swift/elements/type/ExistentialMetatypeType.qll 2b37fa25e3a06b42b3ecb211c1d4ca72f85a99474714811ef5e89d5c2e5e4592 e22e904092b9c5784aa2890968a27265df277c60f88d968e2546f39ab6454536 +ql/lib/codeql/swift/elements/type/ExistentialMetatypeTypeConstructor.qll a6b088425c0b0993b3ba3649a49c72c15c7bb3b369f610a7971d5cef858ed9b8 56e8663f9c50f5437b6f8269e41675e8832cfae7aa3b204fa03b86d4f35ce9ff +ql/lib/codeql/swift/elements/type/ExistentialType.qll 8cc0eb534ea2152dcd83e986103616c4f7aa31f0c0e23c73c1addcb39e3758b2 0d5ef028a6bd998fa2de2f4456bf7519202a2f0e66f2bc98bcb43c8af686cade +ql/lib/codeql/swift/elements/type/ExistentialTypeConstructor.qll bc9bd26dc789fe389c5f9781a0d5465189c4b685ef29cd9ca3488c64b5423e45 d9977de27830d154e2afa34c3c69a7a02b750eda00a21a70554ca31c086cfe2e +ql/lib/codeql/swift/elements/type/FunctionType.qll e2d289fcb9e2fabfaef2a1265b29fa1595e3e188eec7d8d5847ad7d2862d4a6e 1bfc06f2ca2abf5861602fc45ab4531f69bf40646ac39a12f3b6dba8e43b0b21 +ql/lib/codeql/swift/elements/type/FunctionTypeConstructor.qll 1fa2829f1ee961a1ce1cfd8259a6cc88bedcbee0aad7aece207839b4066e73f4 8537e7e2f61998e5cf1920fb872089e68b81d67d5e9939611117e7e5a6d62eb5 +ql/lib/codeql/swift/elements/type/GenericFunctionType.qll 06446c074997ba2b99aa0f4f5d1928e01117e431326578e2ead6294abd90daf0 6d52f6ee2f3b6e9976d473d0d33ab1b9b3274f1e6b352f2d1e33215a27d68ad4 +ql/lib/codeql/swift/elements/type/GenericFunctionTypeConstructor.qll cd3099dfa77dc5186c98e6323a0e02f6496e5b2ab131aab7b3dac403365607d0 cf6c83cef81a52c336e10f83f3eff265df34d97fbe5accdebaccfa24baefe07b +ql/lib/codeql/swift/elements/type/GenericTypeParamType.qll 6881305d3599d5a511561e4eae0664a5681d8cbb2aa6718dfffcde943474cef0 e1288015ff8a0261edc1876320ea475180d0e6e75f4b5565b1ccd1498949740f +ql/lib/codeql/swift/elements/type/GenericTypeParamTypeConstructor.qll 4265701fad1ad336be3e08e820946dcd1f119b4fa29132ae913318c784236172 d4bf5127edc0dfa4fb8758081a557b768c6e4854c9489184c7955f66b68d3148 +ql/lib/codeql/swift/elements/type/InOutType.qll d2f6be1da40e93a6d6745b467824b1e974bb64ec56378dc328cc3e864c54e433 942f46afd617151783c79c69d96234aa4ca5741084b12b3d8349338cebb99cc2 +ql/lib/codeql/swift/elements/type/InOutTypeConstructor.qll c4889f1009018a55d0ac18c5f2a006572ac6de1f57633adc904e8a2046c09e83 8a2496df02e9f5fcb07331165cee64f97dd40dc4b4f8f32eacaf395c7c014a99 +ql/lib/codeql/swift/elements/type/LValueType.qll 60a55935763564f2fa7a5ca71af5ac59914289435d2385aee9a01e5d161b1600 daa1eacb13397c20fe3c092e4b7f7f5798da43005bad61c0fef2b18357770b01 +ql/lib/codeql/swift/elements/type/LValueTypeConstructor.qll e426dac8fce60f9bbd6aa12b8e33230c405c9c773046226c948bc9791e03c911 4d495938b0eb604033cea8ff105854c0c9917dbad59bb47a8751fc12d7554bdd +ql/lib/codeql/swift/elements/type/MetatypeType.qll 5d2995b2269ec118daf81268cca62beaa4189e65cae32ef7ec83b9129858cef8 34c021dc051d5d80410cd7aa25b45ccd2d7b267b2bbcb92f4249f528f524c5d8 +ql/lib/codeql/swift/elements/type/MetatypeTypeConstructor.qll 5dfa528a0c849afa46ad08c4c92e47c3bc3418abb7674e94a0d36bc0e45d5686 6b95579b99e4cdd53cc95d9288ecbdb07ef268e5344e467336d89adddb7cc853 +ql/lib/codeql/swift/elements/type/ModuleType.qll 5f7540f8520ee7e3c7c15c1f7da269e4acd4b02b57912902e3d334fc53a9ac76 2b6cec36c543c6319178415b9ccb29e4f840b1f6e8b760a83d0f9399722995da +ql/lib/codeql/swift/elements/type/ModuleTypeConstructor.qll da4d1836c7e453d67221f59d007b5aff113ee31b4c9ad9445c2a7726851acf9b c902ed1ffbde644498c987708b8a4ea06ab891ffd4656ab7eb5008420bd89273 +ql/lib/codeql/swift/elements/type/NominalOrBoundGenericNominalType.qll 76248640645cf2f6ad096a73189447b3b42565e91d8f85ee1a0e3922a231c1a5 bf7e4ff426288481e9b6b5c48be7ff10a69ace0f2d2a848462c21ad9ec3167b7 +ql/lib/codeql/swift/elements/type/OpaqueTypeArchetypeType.qll fe987d7f715f118695b43ceebd4ab6c7fc9eab1530fbb54f3b79b8edfb5666a2 73bf49c826d791678af964d51836c0e1693e994465af9531aa4d1a542455c93f +ql/lib/codeql/swift/elements/type/OpaqueTypeArchetypeTypeConstructor.qll 20c8aa032f25f2e9759d69849e943e7049a22f8b452c055591be982f8c1aee2b 17341a9c4ec4bbad59c82d217501c771df2a58cb6adb8f1d50cf4ec31e65f803 +ql/lib/codeql/swift/elements/type/OpenedArchetypeType.qll a69b4dc52f6e25014a0db401ca90a7f827c1c906cc91ab9dd18be6b3296acefe 49fd53e2f449da6b2f40bf16f3e8c394bf0f46e5d1e019b54b5a29a3ad964e2b +ql/lib/codeql/swift/elements/type/OpenedArchetypeTypeConstructor.qll cc114bee717de27c63efed38ddb9d8101e6ba96e91c358541625dc24eb0c6dd5 92c1f22b4c9e0486a2fd6eca7d43c7353ac265026de482235d2045f32473aeb7 +ql/lib/codeql/swift/elements/type/OptionalType.qll 27e81ae79cbfa22c8cda3839ebaac95d11abf68615caedc2bd8c0c3362cbc7c6 37be60f19fd806fa4e1c66d6bee4091e1fb605861d1f79aa428a1e7b6b991280 +ql/lib/codeql/swift/elements/type/OptionalTypeConstructor.qll 61219c8fa7226e782b36e1f5a2719272e532146004da9358e1b369e669760b7e 74621440a712a77f85678bc408e0f1dc3da4d0971e18ef70c4de112800fc48ac +ql/lib/codeql/swift/elements/type/ParameterizedProtocolType.qll 342a6a5bc7709d9de4819041e1b9b85caf8d716e4b817020d4eff12d8790006c 78b09022b0f9448d347c9faf7b8373ebae40c889428e342e0cefbd228ceff053 +ql/lib/codeql/swift/elements/type/ParameterizedProtocolTypeConstructor.qll 549649fd93b455bb6220677733a26539565240bc8b49163e934e9a42ebebd115 3886762d26172facf53a0baab2fe7b310a2f356cf9c30d325217ba2c51c136f4 +ql/lib/codeql/swift/elements/type/ParenType.qll 8a1aaf7c3e4c354a3848b3285d0261d1dc14324d65dfa64986cc9240f3869eed cde8c9488dfefbbdb177c6d37f7aa3f9c2f327e0d92383b294fbd2172bba2dff +ql/lib/codeql/swift/elements/type/ParenTypeConstructor.qll a8dc27a9de0d1492ba3bab4bf87aa45e557eccf142cee12ffde224cd670d41df a08ce80fcd6255bc2492e2447c26210631ca09a30c4cc3874eb747ae1153bf66 +ql/lib/codeql/swift/elements/type/PrimaryArchetypeType.qll f9807812ae3827e0f195935b44528537ff91e769df131ac4755b0547c113834d c950a30ba14eaad1b72d944b5a65ba04dd064726cf65061b472fefdfa8828dbb +ql/lib/codeql/swift/elements/type/PrimaryArchetypeTypeConstructor.qll a0d24202332449b15a1e804959896f045c123e2153291a7a2805473b8efbb347 1be1fbfbff1bb63f18402e4e082878b81d57708cfc20d1499f5fd91e8332b90b +ql/lib/codeql/swift/elements/type/ProtocolCompositionType.qll 97bdcfde6955bef578f121f803ce5cea42ebca80568ae6eb8d3451f079b8fd3d 3048be59e02ee821e8bf2d470b8901f61b18075696d598babda1964b2b00cbde +ql/lib/codeql/swift/elements/type/ProtocolCompositionTypeConstructor.qll b5f4d7e73ea9281874521acf0d91a1deb2f3744854531ee2026913e695d5090d be55225d2fd21e40d9cacb0ad52f5721fed47c36a559d859fba9c9f0cb3b73c3 +ql/lib/codeql/swift/elements/type/ProtocolType.qll 7f6806952e1fe87648516cdc310370ccd886a53f4a2014e9d62cd6ce14dbd7c3 527b2acdc24eca89847fa80deb84b9584d9c92fab333724f5994dfb5e475269d +ql/lib/codeql/swift/elements/type/ProtocolTypeConstructor.qll c0252a9975f1a21e46969d03e608d2bd11f4d1f249406f263c34232d31c9574d 145e536a0836ed5047408f0f4cf79ab8855938e99927e458d3a893cd796fda74 +ql/lib/codeql/swift/elements/type/ReferenceStorageType.qll 12966c9aeaec22d3991ba970a314d8618971f7f6a579f249c88c47333fc518a2 5635deaf09199afe8fff909f34f989c864c65447c43edf8d8e2afdf0e89a7351 +ql/lib/codeql/swift/elements/type/StructType.qll 1b92a9a6107abd816d00193b910ab236de700299793b90fa50bfbea6e0055f45 07d5b0a29e946a7e5bf6dc131b6373745f75dbdbca6fe6a3843d4b0ba7ab0309 +ql/lib/codeql/swift/elements/type/StructTypeConstructor.qll a784445a9bb98bb59b866aff23bbe4763e02a2dc4a268b84a72e6cd60da5b17d 8718e384a94fd23910f5d04e18f2a6f14b2148047244e485214b55ae7d28e877 +ql/lib/codeql/swift/elements/type/SubstitutableType.qll 2dc4774a5b6c941376e37785b34891e9311075715af840273322fd422e93e671 cdc27e531f61fb50aaa9a20f5bf05c081759ac27df35e16afcdd2d1ecdac5da0 +ql/lib/codeql/swift/elements/type/SugarType.qll d13faf1eb71d9fa1d6fd378455cbbcfea49029e94303e33f1d08bb03d115d654 cbcbd68098b76d99c09e7ee43c9e7d04e1b2e860df943a520bf793e835c4db81 +ql/lib/codeql/swift/elements/type/SyntaxSugarType.qll 0843801d8abcb3090a6dc8c41cce5d60bba47761aa68f3c89ce21cf659696af5 a7a002cf597c3e3d0fda67111116c61a80f1e66ab8db8ddb3e189c6f15cadda6 +ql/lib/codeql/swift/elements/type/TupleType.qll ef49280a8d01acf3ecba2d3c12b512d3d3480048c412d922a1997cb1ac76fc6b 0b34c17ce9db336d0be9a869da988f31f10f754d6ffab6fa88791e508044edd2 +ql/lib/codeql/swift/elements/type/TupleTypeConstructor.qll 060633b22ee9884cb98103b380963fac62a02799461d342372cfb9cc6303d693 c9a89f695c85e7e22947287bcc32909b1f701168fd89c3598a45c97909e879f4 +ql/lib/codeql/swift/elements/type/TypeAliasType.qll 615273f833d588940a32e16adacdfa56b6ac480e1aca6ebd11adfaa878b6d19e 760c79b9b581cc645f1002ca892656d406d3d339267fd58e765738257dbb45ce +ql/lib/codeql/swift/elements/type/TypeAliasTypeConstructor.qll f63ada921beb95d5f3484ab072aa4412e93adfc8e7c0b1637273f99356f5cb13 f90d2789f7c922bc8254a0d131e36b40db1e00f9b32518633520d5c3341cd70a +ql/lib/codeql/swift/elements/type/TypeReprConstructor.qll 2bb9c5ece40c6caed9c3a614affc0efd47ad2309c09392800ad346bf369969bf 30429adc135eb8fc476bc9bc185cff0a4119ddc0e618368c44f4a43246b5287f +ql/lib/codeql/swift/elements/type/UnarySyntaxSugarType.qll 072fbc064fb059a49befab907dd6049b4bf1a28e4ba3fcddf3e73d7913bc3906 0b113b1a7834779fabfa046a64c6d256cde0f510edb84da253e89d36f41f8241 +ql/lib/codeql/swift/elements/type/UnboundGenericType.qll 21878a4bf3ad77085812ad55c85e3ed0257cad10e6d7c72e513aae81616ef405 cca58789f97e51acb9d873d826eb77eda793fc514db6656ee44d33180578680c +ql/lib/codeql/swift/elements/type/UnboundGenericTypeConstructor.qll 63462b24e0acceea0546ec04c808fb6cf33659c44ea26df1f407205e70b0243d d591e96f9831cce1ca6f776e2c324c8e0e1c4e37077f25f3457c885e29afbf3e +ql/lib/codeql/swift/elements/type/UnmanagedStorageType.qll 3e8276cc1bae19f448027d2a0629c95c0b58b3e096b898ef006cb5eaea613908 d32206af9bf319b4b0b826d91705dbd920073d6aaa002a21ec60175996ab9d1a +ql/lib/codeql/swift/elements/type/UnmanagedStorageTypeConstructor.qll c5927ab988beb973785a840840647e47cc0fb6d51712bed796cb23de67b9d7d6 b9f0f451c58f70f54c47ad98d9421a187cf8bd52972e898c66988a9f49e4eda0 +ql/lib/codeql/swift/elements/type/UnownedStorageType.qll 18923326a76bcfa31697551fb001a06b2a38ea074fa312c47953dd9a7ac16604 3b5d90688070be5dc0b84ab29aed2439b734e65d57c7556c6d763f5714a466ba +ql/lib/codeql/swift/elements/type/UnownedStorageTypeConstructor.qll 211c9f3a9d41d1c9e768aa8ece5c48cca37f7811c5daab8bf80fdc2bd663dd86 c4fb8b39d319e1c27175f96ceec9712f473e0df1597e801d5b475b4c5c9c6389 +ql/lib/codeql/swift/elements/type/UnresolvedType.qll d573017fef5394a11d43cdcbaad91060e0b1e4c9ba6f2a9e358f818176ca8f45 680dd2fc64eeec5f81d2c2a05221c56a1ef7004bdcb1a8517640caa5fba0890d +ql/lib/codeql/swift/elements/type/UnresolvedTypeConstructor.qll 76c34ca055a017a0fa7cfff93843392d0698657fbf864ac798e1ae98325b3556 d0770637ec9674f9e2a47ad5c59423b91d12bb22a9d35dcfa8afa65da9e6ed93 +ql/lib/codeql/swift/elements/type/VariadicSequenceType.qll 5bca77dd661d3b2653d31005c2341b408c86661e89ae0cab9539999ecac60eea 3ac870a1d6df1642fae26ccda6274a288524a5cf242fab6fac8705d70e3fca88 +ql/lib/codeql/swift/elements/type/VariadicSequenceTypeConstructor.qll 0d1d2328a3b5e503a883e7e6d7efd0ca5e7f2633abead9e4c94a9f98ed3cb223 69bff81c1b9413949eacb9298d2efb718ea808e68364569a1090c9878c4af856 +ql/lib/codeql/swift/elements/type/WeakStorageType.qll 87a28616eea3600fb0156fffcd65eeddc1ea74ce9c0ba5886c6365b9359e00ce 9c968414d7cc8d672f3754bced5d4f83f43a6d7872d0d263d79ff60483e1f996 +ql/lib/codeql/swift/elements/type/WeakStorageTypeConstructor.qll d88b031ef44d6de14b3ddcff2eb47b53dbd11550c37250ff2edb42e5d21ec3e9 26d855c33492cf7a118e439f7baeed0e5425cfaf058b1dcc007eca7ed765c897 +ql/lib/codeql/swift/elements.qll af0ce7fc361a5cffdbdfbe1c7ff2a5addf6b8a79e3fc062f266776bc97886c33 af0ce7fc361a5cffdbdfbe1c7ff2a5addf6b8a79e3fc062f266776bc97886c33 +ql/lib/codeql/swift/generated/AstNode.qll 02ca56d82801f942ae6265c6079d92ccafdf6b532f6bcebd98a04029ddf696e4 6216fda240e45bd4302fa0cf0f08f5f945418b144659264cdda84622b0420aa2 +ql/lib/codeql/swift/generated/Callable.qll f4050fac68d745fe0fc4d7bd6cff7c326d6c19a5820a780e1d7e589328b1e550 b6540534acc0b583481a18918264b95a129f13ad26256abe667bf4f72c4432d2 +ql/lib/codeql/swift/generated/Comment.qll f58b49f6e68c21f87c51e2ff84c8a64b09286d733e86f70d67d3a98fe6260bd6 975bbb599a2a7adc35179f6ae06d9cbc56ea8a03b972ef2ee87604834bc6deb1 +ql/lib/codeql/swift/generated/DbFile.qll a49b2a2cb2788cb49c861ebcd458b8daead7b15adb19c3a9f4db3bf39a0051fc a49b2a2cb2788cb49c861ebcd458b8daead7b15adb19c3a9f4db3bf39a0051fc +ql/lib/codeql/swift/generated/DbLocation.qll b9baea963d9fa82068986512c0649d1050897654eee3df51dba17cf6b1170873 b9baea963d9fa82068986512c0649d1050897654eee3df51dba17cf6b1170873 +ql/lib/codeql/swift/generated/Diagnostics.qll d2ee2db55e932dcaee95fcc1164a51ffbe1a78d86ee0f50aabb299b458462afe 566d554d579cadde26dc4d1d6b1750ca800511201b737b629f15b6f873af3733 +ql/lib/codeql/swift/generated/Element.qll 9caf84a1da2509f5b01a22d6597126c573ae63ec3e8c6af6fd6fcc7ead0b4e82 70deb2238509d5ed660369bf763c796065d92efd732469088cdf67f68bacd796 +ql/lib/codeql/swift/generated/ErrorElement.qll 4b032abe8ffb71376a29c63e470a52943ace2527bf7b433c97a8bf716f9ad102 4f2b1be162a5c275e3264dbc51bf98bce8846d251be8490a0d4b16cbc85f630f +ql/lib/codeql/swift/generated/File.qll 61454459f5f1ae378bd4970ad1da4f39f3e696bac8a5eebdd162f131995c5316 3e6805f8858cd55dd0e0d0e5aeab923d6a55292dbf98b0029db1ae0208efe684 +ql/lib/codeql/swift/generated/Locatable.qll bdc98b9fb7788f44a4bf7e487ee5bd329473409950a8e9f116d61995615ad849 0b36b4fe45e2aa195e4bb70c50ea95f32f141b8e01e5f23466c6427dd9ab88fb +ql/lib/codeql/swift/generated/Location.qll 851766e474cdfdfa67da42e0031fc42dd60196ff5edd39d82f08d3e32deb84c1 b29b2c37672f5acff15f1d3c5727d902f193e51122327b31bd27ec5f877bca3b +ql/lib/codeql/swift/generated/ParentChild.qll 9d6fe5dd7ab99fa9afdc1bd846e21ce951613bbe6a89d4e34c29e36466a8293f e0e59a05018e4b59ebda3a9fdc3435b1c82207b915630d55edbe6d3f92488356 +ql/lib/codeql/swift/generated/PureSynthConstructors.qll 1cd47d61fec37e019ce2e476603eb2273775bea81062d6bf3d6bbc49796f7b77 1cd47d61fec37e019ce2e476603eb2273775bea81062d6bf3d6bbc49796f7b77 +ql/lib/codeql/swift/generated/Raw.qll 34ce12e57d0cfffb8ca127e44041fece4ac6079cb2a80d14e0a05c0a8d344fdd dd7b6f54f2cc4ba1d8ed31168f97e3f6f8197ebb4d759e0bed0ed68d55a43c25 +ql/lib/codeql/swift/generated/Synth.qll 90df85be365c89c3c2e22041ee7dc9dd2ad9194b66f82e8f9d8fefb8afd900ec 1632984f7a55f6bc55adb9f647baf634b002c299655cbf641dfb110525291689 +ql/lib/codeql/swift/generated/SynthConstructors.qll 5c91f09bd82728651ed61f498704e0f62847788fa986dec5e674d81f294076c7 5c91f09bd82728651ed61f498704e0f62847788fa986dec5e674d81f294076c7 +ql/lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 +ql/lib/codeql/swift/generated/UnknownLocation.qll e50efefa02a0ec1ff635a00951b5924602fc8cab57e5756e4a039382c69d3882 e50efefa02a0ec1ff635a00951b5924602fc8cab57e5756e4a039382c69d3882 +ql/lib/codeql/swift/generated/UnspecifiedElement.qll dbc6ca4018012977b26ca184a88044c55b0661e3998cd14d46295b62a8d69625 184c9a0ce18c2ac881943b0fb400613d1401ed1d5564f90716b6c310ba5afe71 +ql/lib/codeql/swift/generated/decl/AbstractFunctionDecl.qll 8255b24dddda83e8a7dee9d69a4cf9883b5a7ae43676d7242b5aab5169f68982 407c7d63681fb03ad6cb4ea3c2b04be7ccb5ddbe655a8aec4219eb3799bc36e8 +ql/lib/codeql/swift/generated/decl/AbstractStorageDecl.qll 66147ad36cefce974b4ae0f3e84569bd6742ea2f3e842c3c04e6e5cbd17e7928 ce7c2347e2dfe0b141db103ccb8e56a61d286476c201aebe6a275edd7fca2c0f +ql/lib/codeql/swift/generated/decl/AbstractTypeParamDecl.qll 1e268b00d0f2dbbd85aa70ac206c5e4a4612f06ba0091e5253483635f486ccf9 5479e13e99f68f1f347283535f8098964f7fd4a34326ff36ad5711b2de1ab0d0 +ql/lib/codeql/swift/generated/decl/AccessorDecl.qll 97773751c95475efd78ee5cb0c71e3094b13bba121b564c99934659d1908dca2 25c97d7586379558ff8f7cea4d4fcf7633256029fe3e560964353c3b90497076 +ql/lib/codeql/swift/generated/decl/AssociatedTypeDecl.qll 4169d083104f9c089223ed3c5968f757b8cd6c726887bbb6fbaf21f5ed7ee144 4169d083104f9c089223ed3c5968f757b8cd6c726887bbb6fbaf21f5ed7ee144 +ql/lib/codeql/swift/generated/decl/ClassDecl.qll a60e8af2fdbcd20cfa2049660c8bcbbc00508fbd3dde72b4778317dfc23c5ae4 a60e8af2fdbcd20cfa2049660c8bcbbc00508fbd3dde72b4778317dfc23c5ae4 +ql/lib/codeql/swift/generated/decl/ConcreteFuncDecl.qll c7192e79ce67f77df36575cceb942f11b182c26c93899469654316de2d543cf9 c7192e79ce67f77df36575cceb942f11b182c26c93899469654316de2d543cf9 +ql/lib/codeql/swift/generated/decl/ConcreteVarDecl.qll 4801ccc477480c4bc4fc117976fbab152e081064e064c97fbb0f37199cb1d0a8 4d7cfbf5b39b307dd673781adc220fdef04213f2e3d080004fa658ba6d3acb8d +ql/lib/codeql/swift/generated/decl/ConstructorDecl.qll 20e3a37809eacfc43828fa61248ad19b0ff610faad3a12b82b3cf5ed2bcce13c 20e3a37809eacfc43828fa61248ad19b0ff610faad3a12b82b3cf5ed2bcce13c +ql/lib/codeql/swift/generated/decl/Decl.qll b850ab1b909c1b555f3847ce9dca0e2f075db87e7b40f460b8774220bf87a1e6 a3496437246cb10eafaa9d6d45f57f830b6a1c88f15bbcffa3c5dae476004140 +ql/lib/codeql/swift/generated/decl/DestructorDecl.qll 8767e3ddabdf05ea5ee99867e9b77e67f7926c305b2fba1ca3abf94e31d836b9 8767e3ddabdf05ea5ee99867e9b77e67f7926c305b2fba1ca3abf94e31d836b9 +ql/lib/codeql/swift/generated/decl/EnumCaseDecl.qll b25413c29fa814f5cd594004e5abdeeb420f75fd86d3ab483dc04fd5d4ec8135 9ef8a30873476ace498d78b91a902e3bb600e9e3a9defc4bea42ea9d3ac7b2f7 +ql/lib/codeql/swift/generated/decl/EnumDecl.qll fa4490d511ee537751a4fab2478e65250ff3deba43c74db5341184c9ba25b534 fa4490d511ee537751a4fab2478e65250ff3deba43c74db5341184c9ba25b534 +ql/lib/codeql/swift/generated/decl/EnumElementDecl.qll d56a4d26ed209de4836fe324415a3a1e545af52ab47af607827a6f0ef7d309fd c0672aad1c9b688bb9367850005bf5f595ce628041a02d666aa0a2403338df61 +ql/lib/codeql/swift/generated/decl/ExtensionDecl.qll c6c057adadf3682d5d9e58154eaf2a28f769f7df3c2e48f9d2f5bae017917e5f 8aa2d7f20f7452ec25d2a8e1e00a7d3f4465c9c3c21326bfb3fe416c6fe83057 +ql/lib/codeql/swift/generated/decl/FuncDecl.qll 11ebe386dd06937c84fdb283a73be806763d939c163d3c0fd0c4c3eb1caeda41 6a5b6854818cb3d2bc76f0abdee4933ca839c182abd07fb4d271400f5267f6e2 +ql/lib/codeql/swift/generated/decl/GenericContext.qll 948ed5af71b3247a8e252b3691864d6a6b769c68088c60f00521d87de3a5349b 51f3f1a2b2c8b4e1f5bf549ac5864bf6f87e7c6e480c673210eccda4daca9846 +ql/lib/codeql/swift/generated/decl/GenericTypeDecl.qll 71f5c9c6078567dda0a3ac17e2d2d590454776b2459267e31fed975724f84aec 669c5dbd8fad8daf007598e719ac0b2dbcb4f9fad698bffb6f1d0bcd2cee9102 +ql/lib/codeql/swift/generated/decl/GenericTypeParamDecl.qll bc41a9d854e65b1e0da86350870a8fe050eb1dc031cd17ded11c15b5ad8ad183 bc41a9d854e65b1e0da86350870a8fe050eb1dc031cd17ded11c15b5ad8ad183 +ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll 4923f062fe485d2e10a628df6d34fdb019eaf35431aea2a314f76534b28156ff 8fc67cde1a0b061bfc0532375088a12681ebf64ff5ebfd8368ba86875795514c +ql/lib/codeql/swift/generated/decl/ImportDecl.qll 46c927960d563dd229cb4305babc95f14c9fb08fbf3ffb5a145ea1d902bdfdcb c6a04e12c3be1af134d321d01337dd114bacc1afe615ed8053a90a5fed1d0a0f +ql/lib/codeql/swift/generated/decl/InfixOperatorDecl.qll d98168fdf180f28582bae8ec0242c1220559235230a9c94e9f479708c561ea21 aad805aa74d63116b19f435983d6df6df31cef6a5bbd30d7c2944280b470dee6 +ql/lib/codeql/swift/generated/decl/IterableDeclContext.qll 1594024f03130e8b1b86376131abdfa7612915cd1ed6fff19a2879613a2df400 029134916cf708839263b28e3cd0e822c9455a65cbb272d015f7ea1d05062780 +ql/lib/codeql/swift/generated/decl/MissingMemberDecl.qll eaf8989eda461ec886a2e25c1e5e80fc4a409f079c8d28671e6e2127e3167479 d74b31b5dfa54ca5411cd5d41c58f1f76cfccc1e12b4f1fdeed398b4faae5355 +ql/lib/codeql/swift/generated/decl/ModuleDecl.qll 2d99174fe4e0684a1b184e8fb5b78974a0c5b49bf50b944710ba497278dceb5d 56c28abf63bd691add7d4768652989b03722b2fd3b8a027521fd7af30505b2e9 +ql/lib/codeql/swift/generated/decl/NominalTypeDecl.qll 1ff6cc5226206b6ce08c7206ef574ac36110403e97bd9a7ab3aef49c3966f2c5 50d25a5356b3b0863ef175afefed1d8159ee1b1a354f374b99de9c04f2146bde +ql/lib/codeql/swift/generated/decl/OpaqueTypeDecl.qll b07f9bc85897e420016f681731fcb54a6ef737c1146053e8904e4114a21817e7 c02b02f619dfa381db8c1beb96d1392c274db7115e34af34d6419caeaddb23c4 +ql/lib/codeql/swift/generated/decl/OperatorDecl.qll 3ffdc7ab780ee94a975f0ce3ae4252b52762ca8dbea6f0eb95f951e404c36a5b 25e39ccd868fa2d1fbce0eb7cbf8e9c2aca67d6fd42f76e247fb0fa74a51b230 +ql/lib/codeql/swift/generated/decl/ParamDecl.qll f182ebac3c54a57a291d695b87ff3dbc1499ea699747b800dc4a8c1a5a4524b1 979e27a6ce2bc932a45b968ee2f556afe1071888f1de8dd8ead60fb11acf300c +ql/lib/codeql/swift/generated/decl/PatternBindingDecl.qll 914c711b4dcf3bd386571215fae55262e095911a65b26571e635d84064baf62d 0fccb9434f9c3c99b1707835b9a5fc247d6700e864f2c02cb2253fcf2818e851 +ql/lib/codeql/swift/generated/decl/PostfixOperatorDecl.qll 5aa85fa325020b39769fdb18ef97ef63bd28e0d46f26c1383138221a63065083 5aa85fa325020b39769fdb18ef97ef63bd28e0d46f26c1383138221a63065083 +ql/lib/codeql/swift/generated/decl/PoundDiagnosticDecl.qll c5a646d7b82c97b97d8c79855fc68d36ca494d81dfc83582131d0551187a9b77 a2c567589a89bda3de916d9c5111b123136f03239bb40ac71ac5e949f9b527ce +ql/lib/codeql/swift/generated/decl/PrecedenceGroupDecl.qll d0918f238484052a0af902624b671c04eb8d018ee71ef4931c2fdbb74fa5c5d4 d0918f238484052a0af902624b671c04eb8d018ee71ef4931c2fdbb74fa5c5d4 +ql/lib/codeql/swift/generated/decl/PrefixOperatorDecl.qll 18f2a1f83ea880775344fbc57ed332e17edba97a56594da64580baeb45e95a5d 18f2a1f83ea880775344fbc57ed332e17edba97a56594da64580baeb45e95a5d +ql/lib/codeql/swift/generated/decl/ProtocolDecl.qll 4b03e3c2a7af66e66e8abc40bd2ea35e71959f471669e551f4c42af7f0fd4566 4b03e3c2a7af66e66e8abc40bd2ea35e71959f471669e551f4c42af7f0fd4566 +ql/lib/codeql/swift/generated/decl/StructDecl.qll 9343b001dfeec83a6b41e88dc1ec75744d39c397e8e48441aa4d01493f10026a 9343b001dfeec83a6b41e88dc1ec75744d39c397e8e48441aa4d01493f10026a +ql/lib/codeql/swift/generated/decl/SubscriptDecl.qll d08bc4dbeecafe0d758234e0e3487c2d67b3453aa6b9671b4947518276348a2f 89eaf1b579d41eb66069a75352f385e12e15e15e17583e05349c573586c10e8d +ql/lib/codeql/swift/generated/decl/TopLevelCodeDecl.qll aececf62fda517bd90b1c56bb112bb3ee2eecac3bb2358a889dc8c4de898346e d8c69935ac88f0343a03f17ea155653b97e9b9feff40586cfa8452ac5232700d +ql/lib/codeql/swift/generated/decl/TypeAliasDecl.qll 15cb5bdbe9d722c403874f744bfb3da85f532e33638a64a593acbbdee2f6095e 15cb5bdbe9d722c403874f744bfb3da85f532e33638a64a593acbbdee2f6095e +ql/lib/codeql/swift/generated/decl/TypeDecl.qll 3fb055ab433ec40186f822c5711e3d47f9084fb12a1faee550e1e3e2507cfb45 1f46f7ae90c414c5d00bc2e33c86aa80f5ffddfd6be1853d8d6d4222b8e3f584 +ql/lib/codeql/swift/generated/decl/ValueDecl.qll 7b4e4c9334be676f242857c77099306d8a0a4357b253f8bc68f71328cedf1f58 f18938c47f670f2e0c27ffd7e31e55f291f88fb50d8e576fcea116d5f9e5c66d +ql/lib/codeql/swift/generated/decl/VarDecl.qll 2fca00ba8b535d7cefc2fa863246a0821437ca29b885c4c30362e8a63f284479 5ba623001e071c16267e94d050bfd973addf2436152c7726945b5d87aa521af8 +ql/lib/codeql/swift/generated/expr/AbstractClosureExpr.qll f0060c2972d2e1f9818d8deea3ceebbbe0b19d2ce11adc9b670beb672c4564d3 5f2500c5f3728f81599bd4e1fb9c97ac5a44a6dce8c1ab84a850c62aae3741ff +ql/lib/codeql/swift/generated/expr/AnyHashableErasureExpr.qll f450ac8e316def1cd64dcb61411bae191144079df7f313a5973e59dc89fe367f f450ac8e316def1cd64dcb61411bae191144079df7f313a5973e59dc89fe367f +ql/lib/codeql/swift/generated/expr/AnyTryExpr.qll f2929f39407e1717b91fc41f593bd52f1ae14c619d61598bd0668a478a04a91e 62693c2c18678af1ff9ce5393f0dd87c5381e567b340f1a8a9ecf91a92e2e666 +ql/lib/codeql/swift/generated/expr/AppliedPropertyWrapperExpr.qll 191612ec26b3f0d5a61301789a34d9e349b4c9754618760d1c0614f71712e828 cc212df0068ec318c997a83dc6e95bdda5135bccc12d1076b0aebf245da78a4b +ql/lib/codeql/swift/generated/expr/ApplyExpr.qll 478467da16196b55805b5a1746352384b998c211f29d4423ffeacbb95da20080 daf7a0579663245ff32c3813f00dd65d8e5c93e1ae9fdce35067f44f32f96ca8 +ql/lib/codeql/swift/generated/expr/ArchetypeToSuperExpr.qll e0b665b7389e5d0cb736426b9fd56abfec3b52f57178a12d55073f0776d8e5b7 e0b665b7389e5d0cb736426b9fd56abfec3b52f57178a12d55073f0776d8e5b7 +ql/lib/codeql/swift/generated/expr/Argument.qll fe3cf5660e46df1447eac88c97da79b2d9e3530210978831f6e915d4930534ba 814e107498892203bac688198792eefa83afc3472f3c321ba2592579d3093310 +ql/lib/codeql/swift/generated/expr/ArrayExpr.qll d4239a0260189cdfa7b841bcaa4134a035900e511b22b6552cfd61f4d47ab535 dc490a2b3c94c69dbd6340d7bf71e0aaccd5ed4d1050b5149b6e4f9cf496d428 +ql/lib/codeql/swift/generated/expr/ArrayToPointerExpr.qll afa9d62eb0f2044d8b2f5768c728558fe7d8f7be26de48261086752f57c70539 afa9d62eb0f2044d8b2f5768c728558fe7d8f7be26de48261086752f57c70539 +ql/lib/codeql/swift/generated/expr/AssignExpr.qll b9cbe998daccc6b8646b754e903667de171fefe6845d73a952ae9b4e84f0ae13 14f1972f704f0b31e88cca317157e6e185692f871ba3e4548c9384bcf1387163 +ql/lib/codeql/swift/generated/expr/AutoClosureExpr.qll 26f2ef81e6e66541da75316f894498e74525c0703076cf67398c73a7cbd9736e 26f2ef81e6e66541da75316f894498e74525c0703076cf67398c73a7cbd9736e +ql/lib/codeql/swift/generated/expr/AwaitExpr.qll e17b87b23bd71308ba957b6fe320047b76c261e65d8f9377430e392f831ce2f1 e17b87b23bd71308ba957b6fe320047b76c261e65d8f9377430e392f831ce2f1 +ql/lib/codeql/swift/generated/expr/BinaryExpr.qll 5ace1961cd6d6cf67960e1db97db177240acb6c6c4eba0a99e4a4e0cc2dae2e3 5ace1961cd6d6cf67960e1db97db177240acb6c6c4eba0a99e4a4e0cc2dae2e3 +ql/lib/codeql/swift/generated/expr/BindOptionalExpr.qll 79b8ade1f9c10f4d5095011a651e04ea33b9280cacac6e964b50581f32278825 38197be5874ac9d1221e2d2868696aceedf4d10247021ca043feb21d0a741839 +ql/lib/codeql/swift/generated/expr/BooleanLiteralExpr.qll 8e13cdeb8bc2da9ef5d0c19e3904ac891dc126f4aa695bfe14a55f6e3b567ccb 4960b899c265547f7e9a935880cb3e12a25de2bc980aa128fbd90042dab63aff +ql/lib/codeql/swift/generated/expr/BridgeFromObjCExpr.qll b9a6520d01613dfb8c7606177e2d23759e2d8ce54bd255a4b76a817971061a6b b9a6520d01613dfb8c7606177e2d23759e2d8ce54bd255a4b76a817971061a6b +ql/lib/codeql/swift/generated/expr/BridgeToObjCExpr.qll 31ca13762aee9a6a17746f40ec4e1e929811c81fdadb27c48e0e7ce6a3a6222d 31ca13762aee9a6a17746f40ec4e1e929811c81fdadb27c48e0e7ce6a3a6222d +ql/lib/codeql/swift/generated/expr/BuiltinLiteralExpr.qll 052f8d0e9109a0d4496da1ae2b461417951614c88dbc9d80220908734b3f70c6 536fa290bb75deae0517d53528237eab74664958bf7fdbf8041283415dda2142 +ql/lib/codeql/swift/generated/expr/CallExpr.qll c7dc105fcb6c0956e20d40f736db35bd7f38f41c3d872858972c2ca120110d36 c7dc105fcb6c0956e20d40f736db35bd7f38f41c3d872858972c2ca120110d36 +ql/lib/codeql/swift/generated/expr/CaptureListExpr.qll d6eacfd06c99be3fbe563854856d8b6838f5e63230e1db80824685c8c627aec6 e6116de199aa7ddd549f205476e6ebe7edddb1f53f43ea4efcfa41d0a31586cd +ql/lib/codeql/swift/generated/expr/CheckedCastExpr.qll 146c24e72cda519676321d3bdb89d1953dfe1810d2710f04cfdc4210ace24c40 91093e0ba88ec3621b538d98454573b5eea6d43075a2ab0a08f80f9b9be336d3 +ql/lib/codeql/swift/generated/expr/ClassMetatypeToObjectExpr.qll 076c0f7369af3fffc8860429bd8e290962bf7fc8cf53bbba061de534e99cc8bf 076c0f7369af3fffc8860429bd8e290962bf7fc8cf53bbba061de534e99cc8bf +ql/lib/codeql/swift/generated/expr/ClosureExpr.qll 4c20a922fc4c1f2a0f77026436282d056d0d188cc038443cca0d033dc57cf5a9 4c20a922fc4c1f2a0f77026436282d056d0d188cc038443cca0d033dc57cf5a9 +ql/lib/codeql/swift/generated/expr/CoerceExpr.qll a2656e30dff4adc693589cab20e0419886959c821e542d7f996ab38613fa8456 a2656e30dff4adc693589cab20e0419886959c821e542d7f996ab38613fa8456 +ql/lib/codeql/swift/generated/expr/CollectionExpr.qll 8782f55c91dc77310d9282303ba623cb852a4b5e7a8f6426e7df07a08efb8819 b2ce17bf217fe3df3da54ac2a9896ab052c1daaf5559a5c73cc866ca255a6b74 +ql/lib/codeql/swift/generated/expr/CollectionUpcastConversionExpr.qll 2d007ed079803843a4413466988d659f78af8e6d06089ed9e22a0a8dedf78dbe 38a49c14fc0f47d5a6c86fa1176bf7ae69d88a13f008c8adac9b3dc509b1917d +ql/lib/codeql/swift/generated/expr/ConditionalBridgeFromObjCExpr.qll 4a21e63cc547021b70ca1b8080903997574ab5a2508a14f780ce08aa4de050de 5bc488e29f5bb1fae6830285c3206ac133e5bde5c3e5e3a7c882abf827a725c3 +ql/lib/codeql/swift/generated/expr/ConditionalCheckedCastExpr.qll 92a999dd1dcc1f498ed2e28b4d65ac697788960a66452a66b5281c287596d42b 92a999dd1dcc1f498ed2e28b4d65ac697788960a66452a66b5281c287596d42b +ql/lib/codeql/swift/generated/expr/ConstructorRefCallExpr.qll d0662d960b78c3cf7e81cf5b619aa9e2a906d35c094ae32702da96720354fe4f d0662d960b78c3cf7e81cf5b619aa9e2a906d35c094ae32702da96720354fe4f +ql/lib/codeql/swift/generated/expr/CovariantFunctionConversionExpr.qll b749118590163eafbd538e71e4c903668451f52ae0dabbb13e504e7b1fefa9e1 d3af8e3beb6e395f537348d875978dfae119243dc3495c48a7c83b056aff2f6c +ql/lib/codeql/swift/generated/expr/CovariantReturnConversionExpr.qll f1b409f0bf54b149deb1a40fbe337579a0f6eb2498ef176ef5f64bc53e94e2fe a32992597057657c7bbf13c809db67844b834668e8d2804adabcf6187d81c244 +ql/lib/codeql/swift/generated/expr/DeclRefExpr.qll c68a39ef4445d6c865976fe9f6013bbe77dca68a23d188f1fac3a8492eac70a6 92ae3f39d0e9e1d5017bd660c940225ad2cb07ef9076608dc1bca844adb5d6f0 +ql/lib/codeql/swift/generated/expr/DefaultArgumentExpr.qll b38015d25ef840298a284b3f4e20cd444987474545544dc451dd5e12c3783f20 afc581e2127983faae125fd58b24d346bfee34d9a474e6d499e4606b672fe5f0 +ql/lib/codeql/swift/generated/expr/DerivedToBaseExpr.qll 5f371b5b82262efb416af1a54073079dcf857f7a744010294f79a631c76c0e68 5f371b5b82262efb416af1a54073079dcf857f7a744010294f79a631c76c0e68 +ql/lib/codeql/swift/generated/expr/DestructureTupleExpr.qll 1214d25d0fa6a7c2f183d9b12c97c679e9b92420ca1970d802ea1fe84b42ccc8 1214d25d0fa6a7c2f183d9b12c97c679e9b92420ca1970d802ea1fe84b42ccc8 +ql/lib/codeql/swift/generated/expr/DictionaryExpr.qll 72a103889a7dfe9c2e25ef3336aabddad168d5573f3b19670f198e79e20f3bca aac250a0b831d632adaaa4484f85e55e04f9e95fe5ae152bd68758d9a3116f21 +ql/lib/codeql/swift/generated/expr/DifferentiableFunctionExpr.qll 9143e12dfe0b3b4cc2d1fe27d893498f5bd6725c31bee217ab9fa1ca5efeca7b 8af001026d4b1a08d787af5146affb2df57c0432b1dfcdb557cd4de2cebe51a5 +ql/lib/codeql/swift/generated/expr/DifferentiableFunctionExtractOriginalExpr.qll d90266387d6eecf2bacb2d0f5f05a2132a018f1ccf723664e314dcfd8972772d 878ea62a077e8cda87490bbf770ca0df68d94cbafd2576ff7b725311d73ffef7 +ql/lib/codeql/swift/generated/expr/DiscardAssignmentExpr.qll f2cb4a5295855bcfe47a223e0ab9b915c22081fe7dddda801b360aa365604efd f2cb4a5295855bcfe47a223e0ab9b915c22081fe7dddda801b360aa365604efd +ql/lib/codeql/swift/generated/expr/DotSelfExpr.qll af32541b2a03d91c4b4184b8ebca50e2fe61307c2b438f50f46cd90592147425 af32541b2a03d91c4b4184b8ebca50e2fe61307c2b438f50f46cd90592147425 +ql/lib/codeql/swift/generated/expr/DotSyntaxBaseIgnoredExpr.qll 12c9cf8d2fd3c5245e12f43520de8b7558d65407fa935da7014ac12de8d6887e 49f5f12aeb7430fa15430efd1193f56c7e236e87786e57fd49629bd61daa7981 +ql/lib/codeql/swift/generated/expr/DotSyntaxCallExpr.qll 3768ef558b4fe8c2f0fb4db9b61f84999577a9a4ce5f97fa773a98bf367202ff 3768ef558b4fe8c2f0fb4db9b61f84999577a9a4ce5f97fa773a98bf367202ff +ql/lib/codeql/swift/generated/expr/DynamicLookupExpr.qll 0f0d745085364bca3b67f67e3445d530cbd3733d857c76acab2bccedabb5446e f252dd4b1ba1580fc9a32f42ab1b5be49b85120ec10c278083761494d1ee4c5d +ql/lib/codeql/swift/generated/expr/DynamicMemberRefExpr.qll 2eab0e58a191624a9bf81a25f5ddad841f04001b7e9412a91e49b9d015259bbe 2eab0e58a191624a9bf81a25f5ddad841f04001b7e9412a91e49b9d015259bbe +ql/lib/codeql/swift/generated/expr/DynamicSubscriptExpr.qll f9d7d2fc89f1b724cab837be23188604cefa2c368fa07e942c7a408c9e824f3d f9d7d2fc89f1b724cab837be23188604cefa2c368fa07e942c7a408c9e824f3d +ql/lib/codeql/swift/generated/expr/DynamicTypeExpr.qll 8fc5dcb619161af4c54ff219d13312690dbe9b03657c62ec456656e3c0d5d21b e230d2b148bb95ebd4c504f3473539a45ef08092e0e5650dc35b6f25c1b9e7ed +ql/lib/codeql/swift/generated/expr/EnumIsCaseExpr.qll f49fcf0f610095b49dcabe0189f6f3966407eddb6914c2f0aa629dc5ebe901d2 a9dbc91391643f35cd9285e4ecfeaae5921566dd058250f947153569fd3b36eb +ql/lib/codeql/swift/generated/expr/ErasureExpr.qll c232bc7b612429b97dbd4bb2383c2601c7d12f63312f2c49e695c7a8a87fa72a c232bc7b612429b97dbd4bb2383c2601c7d12f63312f2c49e695c7a8a87fa72a +ql/lib/codeql/swift/generated/expr/ErrorExpr.qll 8e354eed5655e7261d939f3831eb6fa2961cdd2cebe41e3e3e7f54475e8a6083 8e354eed5655e7261d939f3831eb6fa2961cdd2cebe41e3e3e7f54475e8a6083 +ql/lib/codeql/swift/generated/expr/ExistentialMetatypeToObjectExpr.qll eb0d42aac3f6331011a0e26cf5581c5e0a1b5523d2da94672abdebe70000d65b 0ce8b72c817161bc5c1ffc40cb778643b3694512df0502e5295afdf2987b37df +ql/lib/codeql/swift/generated/expr/ExplicitCastExpr.qll d98c1ad02175cfaad739870cf041fcd58143dd4b2675b632b68cda63855a4ceb 2aded243b54c1428ba16c0f131ab5e4480c2004002b1089d9186a435eb3a6ab5 +ql/lib/codeql/swift/generated/expr/Expr.qll 68beba5a460429be58ba2dcad990932b791209405345fae35b975fe64444f07e a0a25a6870f8c9f129289cec7929aa3d6ec67e434919f3fb39dc060656bd1529 +ql/lib/codeql/swift/generated/expr/FloatLiteralExpr.qll ae851773886b3d33ab5535572a4d6f771d4b11d6c93e802f01348edb2d80c454 35f103436fc2d1b2cec67b5fbae07b28c054c9687d57cbd3245c38c55d8bde0b +ql/lib/codeql/swift/generated/expr/ForceTryExpr.qll 062997b5e9a9e993de703856ae6af60fe1950951cf77cdab11b972fb0a5a4ed3 062997b5e9a9e993de703856ae6af60fe1950951cf77cdab11b972fb0a5a4ed3 +ql/lib/codeql/swift/generated/expr/ForceValueExpr.qll 97a8860edae2ea0754b31f63fc53be1739cd32f8eb56c812709f38e6554edef7 359b9c4708f0c28465661690e8c3b1ed60247ca24460749993fe34cf4f2f22f9 +ql/lib/codeql/swift/generated/expr/ForcedCheckedCastExpr.qll cf4792bd4a2c5ce264de141bdbc2ec10f59f1a79a5def8c052737f67807bb8c1 cf4792bd4a2c5ce264de141bdbc2ec10f59f1a79a5def8c052737f67807bb8c1 +ql/lib/codeql/swift/generated/expr/ForeignObjectConversionExpr.qll 243a4e14037546fcbb0afc1c3ba9e93d386780e83518b0f03383a721c68998d6 468fa46af1209c089c003a84acec449412947a6e8a3c9c31f40b4316df3877d9 +ql/lib/codeql/swift/generated/expr/FunctionConversionExpr.qll 8f6c927adaf036358b276ad1d9069620f932fa9e0e15f77e46e5ed19318349ab 8f6c927adaf036358b276ad1d9069620f932fa9e0e15f77e46e5ed19318349ab +ql/lib/codeql/swift/generated/expr/IdentityExpr.qll 1b9f8d1db63b90150dae48b81b4b3e55c28f0b712e567109f451dcc7a42b9f21 6e64db232f3069cf03df98a83033cd139e7215d4585de7a55a0e20ee7a79b1c8 +ql/lib/codeql/swift/generated/expr/IfExpr.qll d9ef7f9ee06f718fd7f244ca0d892e4b11ada18b6579029d229906460f9d4d7e e9ef16296b66f2a35af1dad4c3abcf33071766748bcab99a02a0e489a5614c88 +ql/lib/codeql/swift/generated/expr/ImplicitConversionExpr.qll 52dc57e4413ab523d2c2254ce6527d2d9adaaa4e7faba49b02a88df292aa911d 39883081b5feacf1c55ed99499a135c1da53cd175ab6a05a6969625c6247efd7 +ql/lib/codeql/swift/generated/expr/InOutExpr.qll 26d2019105c38695bace614aa9552b901fa5580f463822688ee556b0e0832859 665333c422f6f34f134254cf2a48d3f5f441786517d0916ade5bec717a28d59d +ql/lib/codeql/swift/generated/expr/InOutToPointerExpr.qll 4b9ceffe43f192fac0c428d66e6d91c3a6e2136b6d4e3c98cdab83b2e6a77719 4b9ceffe43f192fac0c428d66e6d91c3a6e2136b6d4e3c98cdab83b2e6a77719 +ql/lib/codeql/swift/generated/expr/InjectIntoOptionalExpr.qll b6fafb589901d73e94eb9bb0f5e87b54378d06ccc04c51a9f4c8003d1f23ead6 b6fafb589901d73e94eb9bb0f5e87b54378d06ccc04c51a9f4c8003d1f23ead6 +ql/lib/codeql/swift/generated/expr/IntegerLiteralExpr.qll aa54660c47169a35e396ea44430c3c4ec4353e33df1a00bd82aff7119f5af71b 7ba90cf17dd34080a9923253986b0f2680b44c4a4ba6e0fbad8b39d3b20c44b9 +ql/lib/codeql/swift/generated/expr/InterpolatedStringLiteralExpr.qll 35f79ec9d443165229a2aa4744551e9e288d5cd051ace48a24af96dc99e7184a 28e8a3dc8491bcb91827a6316f16540518b2f85a875c4a03501986730a468935 +ql/lib/codeql/swift/generated/expr/IsExpr.qll b5ca50490cae8ac590b68a1a51b7039a54280d606b42c444808a04fa26c7e1b6 b5ca50490cae8ac590b68a1a51b7039a54280d606b42c444808a04fa26c7e1b6 +ql/lib/codeql/swift/generated/expr/KeyPathApplicationExpr.qll 232e204a06b8fad3247040d47a1aa34c6736b764ab1ebca6c5dc74c3d4fc0c9b 6b823c483ee33cd6419f0a61a543cfce0cecfd0c90df72e60d01f5df8b3da3c0 +ql/lib/codeql/swift/generated/expr/KeyPathDotExpr.qll ea73a462801fbe5e27b2f47bca4b39f6936d326d15d6de3f18b7afa6ace35878 ea73a462801fbe5e27b2f47bca4b39f6936d326d15d6de3f18b7afa6ace35878 +ql/lib/codeql/swift/generated/expr/KeyPathExpr.qll e44b9d2a7a6c046d2e61b40192c878e37bd9391c03c8277d92dfba05d9040228 e32c4f6fc35f4e7ada95e82b8dd2cd3eb1912406d3604066f2d183f1311f8c0d +ql/lib/codeql/swift/generated/expr/LazyInitializerExpr.qll d8e93dcfa7fa8a00005f30b4aaa426f50d5040db11bef0c3b56558419b6cc110 3ca7d7ca9e52a025c38d7605c509d6758a4d5ceb0543192074c901f5935d4453 +ql/lib/codeql/swift/generated/expr/LinearFunctionExpr.qll cd4c31bed9d0beb09fdfc57069d28adb3a661c064d9c6f52bb250011d8e212a7 cd4c31bed9d0beb09fdfc57069d28adb3a661c064d9c6f52bb250011d8e212a7 +ql/lib/codeql/swift/generated/expr/LinearFunctionExtractOriginalExpr.qll ee7d3e025815b5af392ffc006ec91e3150130f2bd708ab92dbe80f2efa9e6792 e1646e4b50f6c4af5ed179786e4cbba33910dd642ca47959fec938770e6c7a0e +ql/lib/codeql/swift/generated/expr/LinearToDifferentiableFunctionExpr.qll f7aa178bff083d8e2822fda63de201d9d7f56f7f59f797ec92826001fca98143 e8da45d1f1c61936f8d2d52058ea029af13647bbb40a15e3688ece27918da365 +ql/lib/codeql/swift/generated/expr/LiteralExpr.qll b501f426fa4e638b24d772c2ce4a4e0d40fce25b083a3eee361a66983683ee9d 068208879c86fbd5bed8290ce5962868af6c294a53ad1548cf89cf5a7f8e1781 +ql/lib/codeql/swift/generated/expr/LoadExpr.qll 90b9ba4c96c26c476c3692b1200c31071aa10199d3e21ef386ff48b9f0b6d33a 90b9ba4c96c26c476c3692b1200c31071aa10199d3e21ef386ff48b9f0b6d33a +ql/lib/codeql/swift/generated/expr/LookupExpr.qll 4b8c4f710e3cbdeb684a07c105f48915782e5de002da87f693ae1e07f3b67031 eceb13729282b77a44317c39f9206d9c1467bc93633b7bac5ada97ea13a773fe +ql/lib/codeql/swift/generated/expr/MagicIdentifierLiteralExpr.qll 16f0050128caf916506b1f7372dc225a12809a60b5b00f108705fcdfce3344a8 c064778526a5854bdf8cdbf4b64ad680b60df9fe71ec7a2d9aa6c36a7c4e5b31 +ql/lib/codeql/swift/generated/expr/MakeTemporarilyEscapableExpr.qll d23bd9ea3b13869d7a7f7eef3c3d1c3c156d384b72c65867a0b955bc517da775 f2fd167ac40f01c092b2b443af1557c92dac32074506f2195d32f60b0e0547d8 +ql/lib/codeql/swift/generated/expr/MemberRefExpr.qll 07000a05bec2e6d18e89ec4bbdba41a149691c50527da9073630d4193c0248d8 1bd43b79231aa31e0d60f9f7104f2b889fc3d9f042ecba8fe09d2cd289f4381d +ql/lib/codeql/swift/generated/expr/MetatypeConversionExpr.qll 714ecbc8ac51fdaaa4075388f20fe5063ead9264ca20c4ab8864c48364ef4b42 714ecbc8ac51fdaaa4075388f20fe5063ead9264ca20c4ab8864c48364ef4b42 +ql/lib/codeql/swift/generated/expr/MethodRefExpr.qll 014f976ce55cfc07a18a86c379fcf12c68f3c300c2d5e730731e61bfa50c6419 014f976ce55cfc07a18a86c379fcf12c68f3c300c2d5e730731e61bfa50c6419 +ql/lib/codeql/swift/generated/expr/NilLiteralExpr.qll 6f44106bc5396c87681676fc3e1239fe052d1a481d0a854afa8b66369668b058 6f44106bc5396c87681676fc3e1239fe052d1a481d0a854afa8b66369668b058 +ql/lib/codeql/swift/generated/expr/NumberLiteralExpr.qll 8acc7df8fe83b7d36d66b2feed0b8859bfde873c6a88dd676c9ebed32f39bd04 4bbafc8996b2e95522d8167417668b536b2651817f732554de3083c4857af96a +ql/lib/codeql/swift/generated/expr/ObjCSelectorExpr.qll 8b4f7a9668d1cae4058ba460673b3e0b79f05f2fe871fd992ca1b7ea85f7c09d 629a3057c0ff3ede3a18ea8ea1aa29b24bc780d0dc60b51f99793a6001432a4e +ql/lib/codeql/swift/generated/expr/ObjectLiteralExpr.qll 1eb11648e4ffc2d49b8bdfc332092787972c60394df1827b4c3317e1a4985323 80e767bd0f02a23c32af061e37c5847cb76406be1d848a3411ac78b05ac07aab +ql/lib/codeql/swift/generated/expr/OneWayExpr.qll bf6dbe9429634a59e831624dde3fe6d32842a543d25a8a5e5026899b7a608a54 dd2d844f3e4b190dfba123cf470a2c2fcfdcc0e02944468742abe816db13f6ba +ql/lib/codeql/swift/generated/expr/OpaqueValueExpr.qll 354f23d00d5ea2e734fd192130620d26c76c14d5bb7b0a1aa69f17ffb5289793 354f23d00d5ea2e734fd192130620d26c76c14d5bb7b0a1aa69f17ffb5289793 +ql/lib/codeql/swift/generated/expr/OpenExistentialExpr.qll 55cfe105f217a4bdb15d1392705030f1d7dec8c082cafa875301f81440ec0b7b 168389014cddb8fd738e2e84ddd22983e5c620c3c843de51976171038d95adc0 +ql/lib/codeql/swift/generated/expr/OptionalEvaluationExpr.qll 000b00afe1dcdec43f756f699fd3e38212884eab14bf90e3c276d4ca9cb444a6 177bd4bfbb44e9f5aeaaf283b6537f3146900c1376854607827d224a81456f59 +ql/lib/codeql/swift/generated/expr/OptionalTryExpr.qll f0c8dff90faee4fbf07772efda53afe1acc1fd148c16ee4d85a1502a36178e71 f0c8dff90faee4fbf07772efda53afe1acc1fd148c16ee4d85a1502a36178e71 +ql/lib/codeql/swift/generated/expr/OtherConstructorDeclRefExpr.qll b40c18df25bdb08f159eb34d685d2e27fbba2c5e518b7d8b236f9913d76029cb 30f743385b8a47c36ec54c2c13b42fc6937568aa3cace5f075b51c02a64ca506 +ql/lib/codeql/swift/generated/expr/OverloadedDeclRefExpr.qll 364d63e962d8a741e1fde33e743217cdda176cc58d7da365d4af1ad5401575d8 ac798b3bd5e7f166b6647dbf5fcee04e3bb38d4cd214c6b0141c6b91af1c277f +ql/lib/codeql/swift/generated/expr/ParenExpr.qll f3fb35017423ee7360cab737249c01623cafc5affe8845f3898697d3bd2ef9d7 f3fb35017423ee7360cab737249c01623cafc5affe8845f3898697d3bd2ef9d7 +ql/lib/codeql/swift/generated/expr/PointerToPointerExpr.qll 7d6fa806bba09804705f9cef5be66e09cbbbbda9a4c5eae75d4380f1527bb1bd 7d6fa806bba09804705f9cef5be66e09cbbbbda9a4c5eae75d4380f1527bb1bd +ql/lib/codeql/swift/generated/expr/PostfixUnaryExpr.qll d1094c42aa03158bf89bace09b0a92b3056d560ebf69ddbf286accce7940d3ab d1094c42aa03158bf89bace09b0a92b3056d560ebf69ddbf286accce7940d3ab +ql/lib/codeql/swift/generated/expr/PrefixUnaryExpr.qll f66dee3c70ed257914de4dd4e8501bb49c9fe6c156ddad86cdcc636cf49b5f62 f66dee3c70ed257914de4dd4e8501bb49c9fe6c156ddad86cdcc636cf49b5f62 +ql/lib/codeql/swift/generated/expr/PropertyWrapperValuePlaceholderExpr.qll 011897278a75050f1c55bd3f2378b73b447d5882404fd410c9707cd06d226a0e e04b210ab15ffcada94a70d4a1333c348d6d9111697129938c7591364ac88c9f +ql/lib/codeql/swift/generated/expr/ProtocolMetatypeToObjectExpr.qll b692be6e5b249c095b77f4adcad5760f48bc07f6f53767ee3d236025ee4a2a51 cc69abe3cde83a4cd398ce666509326b21e7ee0b4b766c8dc0e0fea0c7d1ca91 +ql/lib/codeql/swift/generated/expr/RebindSelfInConstructorExpr.qll 7796a88c1635b3bd2492563880c995f1a7a0c68f69bad33b8bd77086eb1ce404 aee11e030ba21115931cbc1e34ac001eaafe4460fb3724a078aa4cbda84e4642 +ql/lib/codeql/swift/generated/expr/RegexLiteralExpr.qll ed7eccdf051b18a6388c47986b68e755edfae5d81d83e58772effb72c0e9d75e ed7eccdf051b18a6388c47986b68e755edfae5d81d83e58772effb72c0e9d75e +ql/lib/codeql/swift/generated/expr/SelfApplyExpr.qll c676c551bcb528512dad6422cce39be8391d03f517df2d5dc4d6ac7ab4f23897 64b3ddb7e2b093acca289d5e81d4662560d8aef20d4dd07fcd41771d54fb3f5c +ql/lib/codeql/swift/generated/expr/SequenceExpr.qll 044581c933d44ecf153a22724985d0c9d3b1bb0ca2614ba60db962ee126a293a 3ae93804ece0fa386099be2344dc7cb8b5d8091ce53980a265973c0faacad1c7 +ql/lib/codeql/swift/generated/expr/StringLiteralExpr.qll f420c5cd51a223b6f98177147967266e0094a5718ba2d57ae2d3acbb64bbb4b6 30d6dab2a93fd95e652a700902c4d106fecfce13880c2ece565de29f2504bedf +ql/lib/codeql/swift/generated/expr/StringToPointerExpr.qll ef69b570aa90697d438f5787a86797955b4b2f985960b5859a7bd13b9ecb9cd3 ef69b570aa90697d438f5787a86797955b4b2f985960b5859a7bd13b9ecb9cd3 +ql/lib/codeql/swift/generated/expr/SubscriptExpr.qll f207679b6a8387fe71eb7ce13061bc4ca8af62ccec92d062b8d67fb2ea0f0d10 ba7ed5c7105f2297ff15e0b07dce96b731da1249c9319bddb723d6898254c5f7 +ql/lib/codeql/swift/generated/expr/SuperRefExpr.qll 3cc44a550ecab7d11b591082a3ad1ac88207d55cd694942ce44a90c576517482 d1712eed916f83d3e1b21c6af944ef56df2b82d163b9b3cb8dc793d48305fa6c +ql/lib/codeql/swift/generated/expr/TapExpr.qll 0a2cbaaec596fa5aabb7acc3cab23bbf1bb1173ea4f240634698d5a89686d014 2267243198f67bb879d639f566e9729cfa9e3a3e205ffe6ff3782b7017a8bf7f +ql/lib/codeql/swift/generated/expr/TryExpr.qll e6619905d9b2e06708c3bf41dace8c4e6332903f7111b3a59609d2bb7a6483ee e6619905d9b2e06708c3bf41dace8c4e6332903f7111b3a59609d2bb7a6483ee +ql/lib/codeql/swift/generated/expr/TupleElementExpr.qll 764371c3b6189f21dcdc8d87f9e6f6ba24e3f2ef0b8c35b8ce8c3b7d4feb7370 25f4f2b747b3887edd82d5eb3fa9ba1b45e7921d2745bfee06300db22a35c291 +ql/lib/codeql/swift/generated/expr/TupleExpr.qll e01ce2dea15839076f32a0b6ebbb4f76a1d1428d4c93cf275ac271140edea91b b3a062055a45cac48e0ae0b0b57b58471827ea47675379f6411ba1cec2a24eab +ql/lib/codeql/swift/generated/expr/TypeExpr.qll 132096079d0da05ac0e06616e4165c32c5f7e3bc338e37930bb81f4d26d7caea edd58d31ce921a8f7d09c49de3683d5170dfed636184bafc862bbfd78c474ca6 +ql/lib/codeql/swift/generated/expr/UnderlyingToOpaqueExpr.qll 13d6c7a16ec0c4c92d12e052437dfa84274394ee8a4ca9b2c9e59514564dc683 13d6c7a16ec0c4c92d12e052437dfa84274394ee8a4ca9b2c9e59514564dc683 +ql/lib/codeql/swift/generated/expr/UnevaluatedInstanceExpr.qll 21dedc617838eed25a8d3a011296fda78f99aee0e8ae2c06789484da6886cfea 21dedc617838eed25a8d3a011296fda78f99aee0e8ae2c06789484da6886cfea +ql/lib/codeql/swift/generated/expr/UnresolvedDeclRefExpr.qll 3469931227ad5ea0c09226e866f2820bfed3636caa2250a1241c2d396e39e7cb b6a7934e17ac4799409724d1438582a372c6e8395cb142aaf101c66b04cc8cf7 +ql/lib/codeql/swift/generated/expr/UnresolvedDotExpr.qll d6bf4bf1a3c4732f2ca3feef34e8482fc6707ac387a2d6f75cb5dde2e742cc38 d58048081b4c2ed582749b03ae8158d9aa0786f1f0bf2988f2339fee2d42e13b +ql/lib/codeql/swift/generated/expr/UnresolvedMemberChainResultExpr.qll ce900badb9484eb2202c4df5ab11de7a3765e8e5eefaa9639779500942790ef1 8ac96bb5d41e4808300838c0f6b8cd23b6bb9bb1ca777994d11840dc7a343ba3 +ql/lib/codeql/swift/generated/expr/UnresolvedMemberExpr.qll 6604f7eea32c151322c446c58e91ff68f3cfbf0fc040ccee046669bcc59fb42d c7738e6b909cb621ac109235ba13ede67a10b32894fd1a5114b16d48d6e9b606 +ql/lib/codeql/swift/generated/expr/UnresolvedPatternExpr.qll 6f4494d73d3f286daef9b0c6edef9e2b39454db3f1f54fcb5a74f3df955e659d 39fbd35d8755353b3aad89fbf49344b2280561f2c271d9cee6011c9ea9c7bf03 +ql/lib/codeql/swift/generated/expr/UnresolvedSpecializeExpr.qll 17387e6e516254bfda7836974771ec1cf9afe6d255f6d28768f6033ac9feced8 e6ec877eb07aa4b83857214675f4d0bc0c89f8c2041daeccaa1285c4a77642f7 +ql/lib/codeql/swift/generated/expr/UnresolvedTypeConversionExpr.qll a38b74b695b9a21b2f1202d4d39017c3ac401e468079477b6d4901c118ae26b6 f8ec529a812c61e85247c4c59f240472a238f87b2001f03ad1b161392795cb9f +ql/lib/codeql/swift/generated/expr/VarargExpansionExpr.qll de72227f75493de4bbb75b80fd072c994ef0e6c096bcaf81fd7dd0b274df5ea9 5400811b30f9673f387a26cfb1ab9fc7ef0055fafb1b96985211b4dde8b1b8f9 +ql/lib/codeql/swift/generated/pattern/AnyPattern.qll ce091e368da281381539d17e3bac59497ad51bb9c167d8991b661db11c482775 ce091e368da281381539d17e3bac59497ad51bb9c167d8991b661db11c482775 +ql/lib/codeql/swift/generated/pattern/BindingPattern.qll 0687ec9761718aed5a13b23fe394f478844c25d6e1feec44d877d82deccd7a70 01bcb096073747e10fc3d2de0c3cc0971ab34626e2b4b2f2bfd670680aff3d5e +ql/lib/codeql/swift/generated/pattern/BoolPattern.qll 118300aa665defa688a7c28f82deb73fa76adce1429d19aa082c71cfcbeb0903 0cd6db87e925e89f8ad6d464762d01d63ddfd34b05a31d5e80eb41aec37480b4 +ql/lib/codeql/swift/generated/pattern/EnumElementPattern.qll 397ae58175ff54d35388b86524172009904cb784040ef06b8421f1dcdf064e3e 1485105498b397d7ee5cb1b3dd99e76597018dc357983b3e463bf689ddda865d +ql/lib/codeql/swift/generated/pattern/ExprPattern.qll 99072c50c5361966cdb312e9b1571c1c313cbcfffe5ea9e77247709f5ff9acf5 6ec3ad407528f0bd773103945e3184681ef2af990efdc8fcf1982799909c54bf +ql/lib/codeql/swift/generated/pattern/IsPattern.qll 3716a0e7153393f253fe046f479c2bc3bf1a2c5d7afb1bfa577bb830fcb6b52b 730324d250c4a4e9073b1c5b777aa1ab57759caf447696feee90068baa337f20 +ql/lib/codeql/swift/generated/pattern/NamedPattern.qll 5d25e51eb83e86363b95a6531ffb164e5a6070b4a577f3900140edbef0e83c71 9e88b2b2b90a547b402d4782e8d494bc555d4200763c094dd985fe3b7ebc1ec8 +ql/lib/codeql/swift/generated/pattern/OptionalSomePattern.qll 4230ba4adaac68868c7c5bd2bf30d1f8284f1025acb3ae9c47b6a87f09ccdcd9 449568950700d21854ec65f9751506fc4dc4e490a4744fb67ca421fc2956fc6a +ql/lib/codeql/swift/generated/pattern/ParenPattern.qll 4e5e2968ffdf07a68f5d5a49f4ecc1a2e7ff389c4fd498cc272e7afd7af7bea5 a143af906ab0cef8cbe3ed8ae06cb4dcb520ded3d70dbb800dab2227b9bf8d3c +ql/lib/codeql/swift/generated/pattern/Pattern.qll 0e96528a8dd87185f4fb23ba33ea418932762127e99739d7e56e5c8988e024d1 ba1e010c9f7f891048fb8c4ff8ea5a6c664c09e43d74b860d559f6459f82554a +ql/lib/codeql/swift/generated/pattern/TuplePattern.qll 4df0d495ac82b3bb4d1a4288218b6cd0394620c1452fbdc9b444e061c70da412 4ca0edab4e2c39166830f2a7951e36f95157c523326272c148af84bd0b87c60e +ql/lib/codeql/swift/generated/pattern/TypedPattern.qll e46078cd90a30379011f565fefb71d42b92b34b1d7fd4be915aad2bafbdbeaf3 aedf0e4a931f868cc2a171f791e96732c6e931a979b2f03e37907a9b2b776cad +ql/lib/codeql/swift/generated/stmt/BraceStmt.qll 7bfad90b392b7ac6b84af948ad0ff76192da22a916bb8cae8254ee1374d3f4c4 c35a36d1d32f046d914a543aad3acf8efbe75f69485157050d6a64dd36fd57ab +ql/lib/codeql/swift/generated/stmt/BreakStmt.qll 31d6b2969a919062c46e7bf0203f91c3489ee3c364e73fc2788f0e06ac109b25 7fca57698a821e81903204f271d0a220adfdd50ff144eafd6868286aa6aefa33 +ql/lib/codeql/swift/generated/stmt/CaseLabelItem.qll 0755fabf3ca7a5ee9a553dec0a6d8af3c8abdc99015c229ce1c4b154a3af80d9 b3c9b88610a3dc729a5eb4f9667710d84a5ac0f3acddcda3031e744309265c68 +ql/lib/codeql/swift/generated/stmt/CaseStmt.qll 32fdcdb193ec523a12b283bade57606dcde4f320f5d760be622782ac011ba908 2adfdff2d3105818c29dbf9571bc0e531fe758f11e85deea27f6e32bf190aabd +ql/lib/codeql/swift/generated/stmt/ConditionElement.qll fd53a99d1af1e16412424c0c48eae7c866db4fd491f2de6d5a5271f227a96275 599db45ed78be3943b76c1ff4ae24cd8a9ff8d1f875d1718ab884e4507843995 +ql/lib/codeql/swift/generated/stmt/ContinueStmt.qll 3213c4ede9c8240bcb1d1c02ee6171821cdfbf89056f1e5c607428dcfaf464f6 00756c533dfd9ee5402e739f360dfe5203ee2043e20fc1982d7782ca7a249f9a +ql/lib/codeql/swift/generated/stmt/DeferStmt.qll 69a8e04618569b61ce680bae1d20cda299eea6064f50433fa8a5787114a6cf5e 12c4f66fc74803f276bbb65e8a696f9bd47cc2a8edfebb286f5c3b2a5b6efce7 +ql/lib/codeql/swift/generated/stmt/DoCatchStmt.qll 92f095ee43b1637269a4c3ba7db4743011f6a10a92012cd02b972f41d3b2668f f90c5d82805e1d7b1f9799c440f82c772b167f68cd7df0967b2f02486b407766 +ql/lib/codeql/swift/generated/stmt/DoStmt.qll dfa2879944e9b6879be7b47ba7e2be3cbb066322a891453891c4719bf0eb4a43 581c57de1a60084f8122fc698934894bbb8848825cb759fa62ff4e07002840cb +ql/lib/codeql/swift/generated/stmt/FailStmt.qll d8f5816c51c5027fd6dacc8d9f5ddd21f691c138dfc80c6c79e250402a1fe165 d8f5816c51c5027fd6dacc8d9f5ddd21f691c138dfc80c6c79e250402a1fe165 +ql/lib/codeql/swift/generated/stmt/FallthroughStmt.qll 7574c3b0d4e7901509b64c4a1d0355a06c02a09fc1282c0c5e86fa7566359c2e 54e85e2fd57313a20dfc196ded519422e4adee5ae4b17f4cc47d47b89650bf47 +ql/lib/codeql/swift/generated/stmt/ForEachStmt.qll c58b8ba4bbcb7609ea52181bfd095ecd0f162cd48600b9ce909ae646127a286f af93281c6e6ad02b249d25b0ce35086da37395aaf77dc0801a7b7df406938b1d +ql/lib/codeql/swift/generated/stmt/GuardStmt.qll 18875adfca4a804932fcc035a0f1931fc781b3b4031e1df435c3e6a505d9edba 10f7a0ed8d4975d854f8b558654bfc2ab604b203c2429240e3a4b615e50c7ad8 +ql/lib/codeql/swift/generated/stmt/IfStmt.qll b55a7407988abba2ffc6f37803cff8d62abd5f27048d83a3fc64b8b6ce66590a 91def4db6dd271f5283e9a55a1e186e28e02962df334b5d753cea132731d7a85 +ql/lib/codeql/swift/generated/stmt/LabeledConditionalStmt.qll 42e8f32da8451cab4abf3a262abdf95aec8359606971700eb8c34d6dc3a3472f fa3c186f2cd57e16c7d09b5bf1dc3076db9e97ade0d78f4b12dd563b57207f00 +ql/lib/codeql/swift/generated/stmt/LabeledStmt.qll ffbfa0dc114399aabc217a9a245a8bcacbfbad6f20e6ff1078c62e29b051f093 33ddfd86495acc7a452fa34e02fe5cce755129aa7ee84f1c2ad67699574b55dc +ql/lib/codeql/swift/generated/stmt/PoundAssertStmt.qll a03dc4a5ef847d74a3cbae6529f7534b35c1345caf15c04694eab71decefd9ab f968f8e8766e19c91852856ea3a84f8fa3fc1b4923c47f2ea42d82118b6f2e0d +ql/lib/codeql/swift/generated/stmt/RepeatWhileStmt.qll adfebcb8a804842866c5f363c39856298de06fd538cca9ffe9c9cd4f59ddc6a7 19d74a05cb01fb586b08d3842a258de82721b1c709d556373e4a75c408e3c891 +ql/lib/codeql/swift/generated/stmt/ReturnStmt.qll 464dc2a4060ffdee4db3d405c344543c4d4e20b969ab536b47f0057b13ff0ce9 8d02dc871965db4947ee895f120ae6fe4c999d8d47e658a970990ea1bf76dd4c +ql/lib/codeql/swift/generated/stmt/Stmt.qll b2a4f3712e3575321a4bc65d31b9eb8ddcd2d20af9863f3b9240e78e4b32ccff e0fc13b3af867aa53b21f58a5be1b7d1333b3e8543a4d214a346468f783dbf40 +ql/lib/codeql/swift/generated/stmt/StmtCondition.qll 2275318cf6cc58deb57b81f3120ef3b3694ad1cd1e5fa8a21c84b9ff65fd53e9 266fc4e5daf8140cb1da5f354fa2033b2fe6b7bc422585cf7fafaad0007b8473 +ql/lib/codeql/swift/generated/stmt/SwitchStmt.qll 5bfa39b4e4a5fae1d7268f15e1c00059e888199a22615011cd18d4ad0aadc873 57eecf592b6cedf97f77e0016e789a6b314fcf3bf97a941f6d93a10ea58b2c60 +ql/lib/codeql/swift/generated/stmt/ThrowStmt.qll 480553a18c58c2fa594ee3c7bc6b69f8aafb1c209e27379b711681652cbe6dd3 23829747c8b8428d7a2eea6017bb01536df01d7346c136bd6b654ebdd04342de +ql/lib/codeql/swift/generated/stmt/WhileStmt.qll 1ac3c3638899386a953905f98f432b7ba5c89e23e28ca55def478ce726127f50 4ac6f0f62082a2a5c1a0119addbb6e4cdebe468a7f972c682c114a70a58c1e80 +ql/lib/codeql/swift/generated/stmt/YieldStmt.qll 442e6c7ef71a45eddb2aef9eb879dad7e3a8fe3ff09605c4bcca11d9279bd42a fc745260bc8783792a735464ef6b9d5083492de56c37a172b11cef878316ec9e +ql/lib/codeql/swift/generated/type/AnyBuiltinIntegerType.qll a263451163e027c4c4223ec288e090b7e0d399cc46eb962013342bfeac5f6b86 d850ec1ee1902945b172ddd0ecd8884e399e963f939c04bc8bfaadacebdf55a9 +ql/lib/codeql/swift/generated/type/AnyFunctionType.qll 4381225f3d267eca8bd2ecab8eaca93afe8860b59d3cc733c76e180995ace6c8 a96ac57a7737d584100d445d99b2e0ffedbc9a8ea827bf3f3a0f53052f5835b6 +ql/lib/codeql/swift/generated/type/AnyGenericType.qll af3e8060bec6128f3135960da1703a72c51c461e85737b9a336d72910fd33e7a 470e51991d606170482dba555bf4067a442e8fec25706a481ef38bdedb1531b1 +ql/lib/codeql/swift/generated/type/AnyMetatypeType.qll 6805a6895e748e02502105d844b66fab5111dbb0d727534d305a0396dacc9465 58e0794b8d6dccd9809f5b83bf64b162e69f3f84b5f3161b88aed10f16a8ede8 +ql/lib/codeql/swift/generated/type/ArchetypeType.qll 6c1590b59683ebd5b632bb77acf9a6f6fb20c3862a3d6c796e897f7aff72a32e ce7f20a8c20aff5d770216c939bae3d110ae70a9180a2203c5066430691566d9 +ql/lib/codeql/swift/generated/type/ArraySliceType.qll 72d0409e2704e89ebca364ae28d55c874152f55dd1deaac6c954617f6566f3c2 72d0409e2704e89ebca364ae28d55c874152f55dd1deaac6c954617f6566f3c2 +ql/lib/codeql/swift/generated/type/BoundGenericClassType.qll c82971dcd306a4cbc6bb885ae300556717eb2d068066b7752a36480e5eb14b5f c82971dcd306a4cbc6bb885ae300556717eb2d068066b7752a36480e5eb14b5f +ql/lib/codeql/swift/generated/type/BoundGenericEnumType.qll 89fcee52adbe6c9b130eae45cf43b2a2c302e8812f8519ea885e5d41dec3ec56 89fcee52adbe6c9b130eae45cf43b2a2c302e8812f8519ea885e5d41dec3ec56 +ql/lib/codeql/swift/generated/type/BoundGenericStructType.qll ff24933889dcc9579fe9a52bd5992b6ecd7b7a7b59c4b1005734e5cd367c8ed6 ff24933889dcc9579fe9a52bd5992b6ecd7b7a7b59c4b1005734e5cd367c8ed6 +ql/lib/codeql/swift/generated/type/BoundGenericType.qll 22451d348947604932c9c560bfade72c06264a53a378ad7553ef3e160e5f769a 64d848e4237febf3e693752478f4f8e4218a6d546c200536a270b4db809a1ee6 +ql/lib/codeql/swift/generated/type/BuiltinBridgeObjectType.qll 848291382ac6bd7cf5dd6707418d4881ec9750ca8e345f7eff9e358715c11264 848291382ac6bd7cf5dd6707418d4881ec9750ca8e345f7eff9e358715c11264 +ql/lib/codeql/swift/generated/type/BuiltinDefaultActorStorageType.qll 54e981860527a18660c9c76da60b14fa6dd3dae0441490ed7eb47d36f1190d8b 54e981860527a18660c9c76da60b14fa6dd3dae0441490ed7eb47d36f1190d8b +ql/lib/codeql/swift/generated/type/BuiltinExecutorType.qll 149642b70b123bcffb0a235ca0fca21a667939fe17cdae62fee09a54dca3e6be 149642b70b123bcffb0a235ca0fca21a667939fe17cdae62fee09a54dca3e6be +ql/lib/codeql/swift/generated/type/BuiltinFloatType.qll 7a1c769c34d67f278074f6179596ec8aee0f92fb30a7de64e8165df2f377cd3f 7a1c769c34d67f278074f6179596ec8aee0f92fb30a7de64e8165df2f377cd3f +ql/lib/codeql/swift/generated/type/BuiltinIntegerLiteralType.qll 94406446732709afdf28852160017c1ca286ad5b2b7812aa8a1a5c96952a7da1 94406446732709afdf28852160017c1ca286ad5b2b7812aa8a1a5c96952a7da1 +ql/lib/codeql/swift/generated/type/BuiltinIntegerType.qll c466054ad1bd06e225937cf67d947a0ae81a078475f9ab6149d4ffb23531c933 8813c8b99df42a489c6b38f7764daac5ab5a55b1c76167da200409b09a4d6244 +ql/lib/codeql/swift/generated/type/BuiltinJobType.qll 4ba48722281db420aeca34fc9bb638500832d273db80337aaff0a0fa709ec873 4ba48722281db420aeca34fc9bb638500832d273db80337aaff0a0fa709ec873 +ql/lib/codeql/swift/generated/type/BuiltinNativeObjectType.qll 7231290a65e31dbee4ec2a89b011ee1e5adb444848f6e8117e56bea0a1e11631 7231290a65e31dbee4ec2a89b011ee1e5adb444848f6e8117e56bea0a1e11631 +ql/lib/codeql/swift/generated/type/BuiltinRawPointerType.qll bc3f6c3388c08e05d6f7d086123dc2189480dae240fcb575aef2e0f24241d207 bc3f6c3388c08e05d6f7d086123dc2189480dae240fcb575aef2e0f24241d207 +ql/lib/codeql/swift/generated/type/BuiltinRawUnsafeContinuationType.qll f9e2ccc7c7505a44cca960c4ff32c33abbef350710bb4099dd8b7e2aaa4ba374 19f7e4b4e02825460374ac0d578544134a7a4d65940e32c1052e0c49b1b54aef +ql/lib/codeql/swift/generated/type/BuiltinType.qll 0f90f2fd18b67edf20712ff51484afd5343f95c0b1a73e4af90b0bc52aed14d9 35bb8ee31eed786a4544e6b77b3423a549330d7f1fb8c131ba728ca4db41b95f +ql/lib/codeql/swift/generated/type/BuiltinUnsafeValueBufferType.qll d569e7c255de5e87bb0eb68ae5e7fea011121e01b2868007485af91da7417cd6 d569e7c255de5e87bb0eb68ae5e7fea011121e01b2868007485af91da7417cd6 +ql/lib/codeql/swift/generated/type/BuiltinVectorType.qll f51ce577abec2a1de3ae77a5cd9719aa4a1a6f3f5ec492c7444e410fb1de802a f51ce577abec2a1de3ae77a5cd9719aa4a1a6f3f5ec492c7444e410fb1de802a +ql/lib/codeql/swift/generated/type/ClassType.qll b52f0383d3dcbf7cf56d0b143cbb63783cb5fa319bcbfc4754e362d935e0fb53 b52f0383d3dcbf7cf56d0b143cbb63783cb5fa319bcbfc4754e362d935e0fb53 +ql/lib/codeql/swift/generated/type/DependentMemberType.qll d9806aa84e0c9a7f0d96155ffeae586ced8ee1343e139f754ebd97d4476f0911 d0b3395e3263be150a6b6df550c02a2567cfa4a827dcb625d0bf1e7bf01956eb +ql/lib/codeql/swift/generated/type/DictionaryType.qll 8b9aad8e8eca8881c1b1516e354c25bf60f12f63f294e906d236f70de025307c 53b0102e1b8f9f5b2c502faa82982c2105dd0e7194eb9ff76d514bddfa50f1dd +ql/lib/codeql/swift/generated/type/DynamicSelfType.qll 9a2950762ad4d78bfacbf5b166ea9dc562b662cf3fcbfc50198aaacf1ea55047 8fb21715ed4ba88866b010cbba73fc004d6f8baef9ce63c747e4d680f382ca6e +ql/lib/codeql/swift/generated/type/EnumType.qll dcf653c7ee2e76882d9f415fbbc208905b8d8ed68cc32e36c0439a9205e65b35 dcf653c7ee2e76882d9f415fbbc208905b8d8ed68cc32e36c0439a9205e65b35 +ql/lib/codeql/swift/generated/type/ErrorType.qll cbc17f4d9977268b2ff0f8a517ca898978af869d97310b6c88519ff8d07efff3 cbc17f4d9977268b2ff0f8a517ca898978af869d97310b6c88519ff8d07efff3 +ql/lib/codeql/swift/generated/type/ExistentialMetatypeType.qll 3a7fd0829381fe4d3768d4c6b0b1257f8386be6c59a73458f68387f66ea23e05 3a7fd0829381fe4d3768d4c6b0b1257f8386be6c59a73458f68387f66ea23e05 +ql/lib/codeql/swift/generated/type/ExistentialType.qll 974537bfafdd509743ccd5173770c31d29aaa311acb07bb9808c62b7fa63f67a c6fbbfb8dacf78087828d68bc94db5d18db75f6c6183ab4425dfa13fccb6b220 +ql/lib/codeql/swift/generated/type/FunctionType.qll 36e1de86e127d2fb1b0a3a7abce68422bdf55a3ab207e2df03ea0a861ab5ccb4 36e1de86e127d2fb1b0a3a7abce68422bdf55a3ab207e2df03ea0a861ab5ccb4 +ql/lib/codeql/swift/generated/type/GenericFunctionType.qll 2465d7729e6b8950d04e9dbdf9018b1f651dba3716387d874de1a1175eb1bc42 a458be5441cd9d29d204c39ccd3e39c347f92c32d8ac2a75ad16fbe698545062 +ql/lib/codeql/swift/generated/type/GenericTypeParamType.qll f515debe8b21f3ea6551e4f8513cda14c3a5ed0cebd4cbfd3b533ff6f0e8b0bf f515debe8b21f3ea6551e4f8513cda14c3a5ed0cebd4cbfd3b533ff6f0e8b0bf +ql/lib/codeql/swift/generated/type/InOutType.qll c69d0f3c3f3d82c6300e052366709760c12f91a6580865ff8718f29057925235 2a9e1d66bec636a727f5ebc60827d90afcdbee69aabe8ae7501f0e089c6dbd5e +ql/lib/codeql/swift/generated/type/LValueType.qll 5159f8cf7004e497db76130d2bfd10228f60864f0e6e9e809fc9a2765eafa978 fc238183b7bf54632fa003e9e91a1c49fb9167170fe60c22358dc3a651acbf98 +ql/lib/codeql/swift/generated/type/MetatypeType.qll cd752f81257820f74c1f5c016e19bdc9b0f8ff8ddcc231daa68061a85c4b38e2 cd752f81257820f74c1f5c016e19bdc9b0f8ff8ddcc231daa68061a85c4b38e2 +ql/lib/codeql/swift/generated/type/ModuleType.qll 0198db803b999e2c42b65783f62a2556029c59d6c7cc52b788865fd7bb736e70 199f8fd9b4f9d48c44f6f8d11cb1be80eb35e9e5e71a0e92a549905092000e98 +ql/lib/codeql/swift/generated/type/NominalOrBoundGenericNominalType.qll 27d87dc4792b7f46fa1b708aadecef742ab2a78b23d4eb28ce392da49766122f 299c3ed5837dcb992a2a28d44ac6709c1d86a828879c62187fe29094e0e66c52 +ql/lib/codeql/swift/generated/type/NominalType.qll f7e85d544eaaa259c727b8b4ba691578861d15612a134d19936a20943270b629 87472017a129921d2af9d380f69c293f4deba788e7660b0fe085a455e76562e8 +ql/lib/codeql/swift/generated/type/OpaqueTypeArchetypeType.qll 74c840ae210fff84636fbfb75d8fce2c2e0bc5bda1489c57f312d2195fdfeda3 0c9986107dcf497798dc69842a277045dcaacfe8eec0ed1f5fc7244dd213ff56 +ql/lib/codeql/swift/generated/type/OpenedArchetypeType.qll ed97d3fb8810424643953a0d5ebd93e58d1b2e397ea01ccde0dcd8e68c41adb2 ed97d3fb8810424643953a0d5ebd93e58d1b2e397ea01ccde0dcd8e68c41adb2 +ql/lib/codeql/swift/generated/type/OptionalType.qll d99dd5ec5636cc6c3e0e52bf27d0d8bf8dfcff25739cd7e1b845f5d96b1a5ac9 d99dd5ec5636cc6c3e0e52bf27d0d8bf8dfcff25739cd7e1b845f5d96b1a5ac9 +ql/lib/codeql/swift/generated/type/ParameterizedProtocolType.qll 73308e43fc3db3218d5970505ddf698d4082fe38c9241077f5356f75cf422015 33508199a580da52644d1d592cc1ffc2065384e8bc22787cbf4ab9a45d2400bd +ql/lib/codeql/swift/generated/type/ParenType.qll 4c8db82abce7b0a1e9a77d2cf799a3e897348fc48f098488bad4ca46890b2646 9ae88f83b4d09a8b59b27f6272533c1aebf04517264804e1cecd42d55e236aa3 +ql/lib/codeql/swift/generated/type/PrimaryArchetypeType.qll 87279ab9a04415fcbcf825af0145b4fc7f118fc8ce57727b840cb18f7d203b59 87279ab9a04415fcbcf825af0145b4fc7f118fc8ce57727b840cb18f7d203b59 +ql/lib/codeql/swift/generated/type/ProtocolCompositionType.qll 644a0618321838b5762424673b040352607745119c45aa0f5dd1022966970f3c 2344abae4c1f5ebece0d62078d0cea10513a80acbb22a0cb1024a2743a49af80 +ql/lib/codeql/swift/generated/type/ProtocolType.qll 07eb08216ca978c9565a7907ab3a932aa915041b6e7520bc421450b32070dbcf 07eb08216ca978c9565a7907ab3a932aa915041b6e7520bc421450b32070dbcf +ql/lib/codeql/swift/generated/type/ReferenceStorageType.qll f565055bb52939ebb38eae4ec2fb9a70ee3045c1c7c9d604037ecf0557cce481 4d5b884f3947a1c0cb9673dc61b8735c9aeec19c9f0a87aa9b7fbe01f49fc957 +ql/lib/codeql/swift/generated/type/StructType.qll 5681060ec1cb83be082c4d5d521cdfc1c48a4095b56415efc03de7f960d1fa04 5681060ec1cb83be082c4d5d521cdfc1c48a4095b56415efc03de7f960d1fa04 +ql/lib/codeql/swift/generated/type/SubstitutableType.qll 9e74ec2d281cd3dedbc5791d66a820a56e0387260f7b2d30a5875dc3f5883389 619f0e4d509bdd9e8cfc061e5627762e9cbae8779bec998564556894a475f9d8 +ql/lib/codeql/swift/generated/type/SugarType.qll 4ea82201ae20e769c0c3e6e158bae86493e1b16bbd3ef6495e2a3760baa1fc6b 6c78df86db6f9c70398484819a9b9ecc8ee337b0a4ac2d84e17294951a6fd788 +ql/lib/codeql/swift/generated/type/SyntaxSugarType.qll 253e036452e0ba8ae3bb60d6ed22f4efb8436f4ef19f158f1114a6f9a14df42c 743fe4dede40ca173b19d5757d14e0f606fe36f51119445503e8eea7cf6df3b0 +ql/lib/codeql/swift/generated/type/TupleType.qll 036318b5e527c28d9bfc234e74ea60d8f0560737ed8c73d26e46b4d21cf49d78 8a50c7308cf91bc057bdce3e695bcb57d83831a7423cf8e946b005aaee36d5c2 +ql/lib/codeql/swift/generated/type/Type.qll 2bd40fd723b2feca4728efe1941ae4b7d830b1021b2de304e6d52c16d744f5a1 c9e44bc375a4dede3f5f1d5bcc8a2f667db0f1919f2549c8c2bb1af5eee899cf +ql/lib/codeql/swift/generated/type/TypeAliasType.qll 081916a36657d4e7df02d6c034715e674cdc980e7067d5317785f7f5bd1b6acb 47b1b7502f8e0792bbe31f03b9df0302cc3d7332b84e104d83304e09f425a06b +ql/lib/codeql/swift/generated/type/TypeRepr.qll 10febbf304b45c9c15f158ccc7f52aa4f4da0f7ca8856c082ef19823d9a1d114 89dcafe7b9939cf6915215ef2906becf5658a3fd2c7b20968b3fc72c3f5155ec +ql/lib/codeql/swift/generated/type/UnarySyntaxSugarType.qll ffdaa0851a0db7c69cf6b8f4437fe848a73d8a1f20e1be52917c682bd6200634 ca5a9912c9f99a9aa9c7685242de1692aad21182f8105cbdce3ba3e7f1118b40 +ql/lib/codeql/swift/generated/type/UnboundGenericType.qll 43549cbdaaa05c3c6e3d6757aca7c549b67f3c1f7d7f0a987121de0c80567a78 43549cbdaaa05c3c6e3d6757aca7c549b67f3c1f7d7f0a987121de0c80567a78 +ql/lib/codeql/swift/generated/type/UnmanagedStorageType.qll 198727a7c9557a0a92c6d833768086f0a0a18c546b4bfd486d7ff7ad5677a6aa 198727a7c9557a0a92c6d833768086f0a0a18c546b4bfd486d7ff7ad5677a6aa +ql/lib/codeql/swift/generated/type/UnownedStorageType.qll 062fd6e902ecbde78a7b8a6d80029731ffb7b4ca741fdc1573c19dd373b6df8e 062fd6e902ecbde78a7b8a6d80029731ffb7b4ca741fdc1573c19dd373b6df8e +ql/lib/codeql/swift/generated/type/UnresolvedType.qll 4bdb583cf2bf654a6a37486d06a14fd631b715f47f7e8aea314d939143c5c6c9 4bdb583cf2bf654a6a37486d06a14fd631b715f47f7e8aea314d939143c5c6c9 +ql/lib/codeql/swift/generated/type/VariadicSequenceType.qll 796537097d8e32eda38be55adde9ec935e25c74ff7450f7ce8cd687c50c0ba89 796537097d8e32eda38be55adde9ec935e25c74ff7450f7ce8cd687c50c0ba89 +ql/lib/codeql/swift/generated/type/WeakStorageType.qll dda4397a49f537ec44117a86dc09705a07d281e31bf4643738b15219053ed380 dda4397a49f537ec44117a86dc09705a07d281e31bf4643738b15219053ed380 +ql/test/extractor-tests/generated/Comment/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/Diagnostics/Diagnostics.ql 6a4a9480cc929381e0337b181e5ac519a7abc6d597ebe24fb6701acf79ced86f 199c5bf8bd38e161d989e0e4db1ea1d3ddcb4d7cf571afd9112ce3ed8d9b8d2a +ql/test/extractor-tests/generated/File/File.ql ab0968ae31b749da2b66462bd04e4dfb30604dba405a84594b575abfc4fa4c35 bcc0ff648b28c5ecd567e196e700272883756bbcc65296bbb880a979e3162628 +ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.ql f378065da46252a3fb7f960731645ad0d69639907bcbe4a5922c416a0c8efcf9 e80e09a2bb54c397f101aaa4c820c94a6d7df819dd746437e74325a8243405e0 +ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getBody.ql 1d42eb1a5b832cfaf1949b61a01a6a11448a6d4369a44f2511bb31d1d7fc10a8 b326a6743121353f8a66410d3d9151ca969939abcbbe5c411872ca290da45123 +ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getGenericTypeParam.ql 8648679e9403477c7f97b6df450a0fa623dc9aff0777021ee33f9cc96eef2611 59c384c35804bf205c3c63e8b956e6bc89d3ded7952911c40e7bf156acb56bf8 +ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getParam.ql 7c61c15d75f681c5f5817bdc1e0c1e2594afdc43a5a8889bd385b6cd007d6509 7f6111069c3f289fb3bd21933893757a0adbf8be8f21bf5f8960b6fb26840219 +ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getSelfParam.ql 0d773ccd4c84a5280f03341cccff8363479b668541d269311215db866a1cfd53 743d584a8d5d85aa11e96ca44151f1239c750bf8a429d60269129696411a0294 +ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl.ql 392e439539392e58582b366a5816ea0ec57c665910933ea42a9420d1feb06a0a f9c0720fb174e765385b70d512c894215713a658b442cb387a2658d43686b69c +ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl_getBaseType.ql 39d26252c242eec5aaef23951bd76755a4d3cdceff7349b15067fefb2ece14b3 214fdbaa77d32ee6f21bcccf112d46c9d26006552081cc1f90cbb00a527a9d7f +ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl.ql 8a717374e7ba42fb907fbcd013116679375998638056f7b81a1f67305a9e60ca fb4776c0231a6430e5e89f51a70a9627a1af5d3ee91331914220295977444002 +ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl_getBaseType.ql 5f4fddbb3fb3d003f1485dc4c5a56f7d0d26dfc1d691540085654c4c66e70e69 0b5a5b757ca92e664ef136d26ac682aa5a0e071494d9f09d85f66cd13807e81d +ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl_getGenericTypeParam.ql ca0b73a4f31eea47def7a1de017de36b5fdaec96ae98edb03ff00611bfcac572 f9badd62887a30113484496532b3ff9b67ff5047eb5a311aa2ec2e4d91321e0e +ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl_getMember.ql f73881b14bb4eaf83dacf60b9e46d440227f90566e2dfb8908a55567626ccdda f78a7261f7ccfe01ca55f7279bd5a1a302fc65ba36b13e779426d173c7465b84 +ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl.ql 650ab6b91b39fca2192f739a967edaf8190caa863223c50848a7786bfe0ca367 e5131d099e3aef634aa24cad937347a5f99902f6c7be7d398304485eccbfb95f +ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl_getBody.ql 3c742b9c8d8d8c23d1bef03f559e1b91f0d3848084ba5819f118c323dd1920a2 340d4e4a6312ffaf4c47bbc753828c1e478d84a2d399c66220288c081c8357ca +ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl_getGenericTypeParam.ql b5e64bf02a5991a1549794af0aaab9ae654c88b5d52a3e04b7ac525b3a64af5e 034a7d0bf7500afa952a28d184d1d073e71c3dcec3bc26fcefaed70aef9de3ce +ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl_getParam.ql 392bc906a24a432b0dd65a18248cab53874e1ea018b44fdf07d8acb55939c85d cf272febc8355d7171308c0b35f65ae0469106c022093f87ffd25d5951eef4a3 +ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl_getSelfParam.ql c8a593149db6785d9bc7017a3fcee305832ab434955b4c36ac2842e214f0acac b70a7c18085961d2c907631d69811071deb391c45c94ef7165bf7ce700dabaf9 +ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl.ql f736e383b4be2b927ba982ed41d863178a1a48b3fe92938ae59eea8dd348f6f6 fa468b5423243617ca5ad3fe9eea474a60ed045f441ed1fa47e03ec4e82e1f2d +ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.ql 7f1890b891402c7974087bd1621ce7ce2893008a2ab0218396c82e99ce2e6c9d 4d483e18ad2211759e3a57f973679844d28505b84fe2b10b2303a561d0ac7ca5 +ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAttachedPropertyWrapperType.ql 0fd114f752aae89ef80bc80e0532aa4849106f6d1af40b1861e4ba191898b69e fdf28e036a1c4dcb0a3aaaa9fb96dcc755ff530ab6f252270c319df9a1d0d7ac +ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentInitializer.ql c90aa3ae4249af7d436f976773e9208b41d784b57c6d73e23e1993f01262f592 3b1391d6b0605011bec7cc6f3f964ed476273bd5ed4bb5d6590f862aa4e7a2a3 +ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentPattern.ql a46347331698857119cd74495a25ea6cff6d20f8003741dc94e9d68b87e7ed1d c60aeb108f56485200eafbc677662869f4393f1d462a3385fa334926adff233c +ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getPropertyWrapperBackingVar.ql 370da9dd7a6bcb02c18246f680ec2af9e12c81504285b43cbf6ffd8963fbd6e4 d9e86f574111e15d42c0eaabe4e65882ad55d3604d9cc281baf28d4817e438a8 +ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getPropertyWrapperBackingVarBinding.ql addbf4e32d383fc35b7505a33c5a675feeedd708c4b94ce8fc89c5bc88c36f1f 549c8ec9cf2c1dc6881e848af8be9900d54604a747ded1f04bd5cadf93e5ede3 +ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getPropertyWrapperProjectionVar.ql 502a76b34c78d3cf8f38969671840dc9e28d478ba7afe671963145ba4dc9460d 6125a91820b6b8d139392c32478383e52e40e572e0f92a32f0e513409d2c4e11 +ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getPropertyWrapperProjectionVarBinding.ql 40274aac8b67cb6a285bf91ccdc725ae1556b13ebcc6854a43e759b029733687 44e569aac32148bcce4cd5e8ebb33d7418580b7f5f03dfbd18635db9965b28d9 +ql/test/extractor-tests/generated/decl/ConstructorDecl/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/decl/DestructorDecl/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/decl/EnumCaseDecl/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl.ql d735a44938c2ad55a09a135d4e24b47e8e3dad4ae00e3335ea7352d1d7137bbb 8bfd5d4c816fc989f031a85f534c61a55b04f69b678adc579d53f4ddb2f8b6a3 +ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl_getBaseType.ql 4ace6176a57dd4c759356ddbefc28b25481c80bdeddfeb396d91b07db55af22a d0d1337ccbba45a648fe68fefc51006e14506d4fb7211fb2bde45f7761c4dbf1 +ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl_getGenericTypeParam.ql 3a0927f87a21d69bfc309f5f7faedb3d0cc2956c071b16c38b2b4acd36f24ea9 aafed56a1744579f05b3817adef6a5fd011d1b5cb7da2db230a43b6f55a04649 +ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl_getMember.ql 621870b7dbeaeefa93cbbfc102e97810b15d39b49db685019c9e3cbf2423ffef e110630f0ba8f588e7f8ebc56a1a31c2ca2f22f2cc763baa76854beb3b3a4ece +ql/test/extractor-tests/generated/decl/EnumElementDecl/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/decl/ExtensionDecl/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/decl/GenericTypeParamDecl/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl.ql d6cb84e2beb3042390b177e8f47a6e030bd439582b698c0a635fb59654b1ca7e 08e06c55de5642be69b4155e400d5fe3a6a2eb51baeea0ba0386d47d8e79d88d +ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl_getActiveElement.ql 914165306a2eb5c8039750e1e03bda156a684946abc8709d786b4144d9c9eb3b 5e87dfd99858ae257506415369bff937a731b6309dac2242b03ea79ead045fc1 +ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl.ql eb56535b0c351b04fcfdd468c5abe5b0c53b7f84ba2813de9a3a236d2a3589a8 56d894aabbe8275754ee2d420e7400676866538f1befd9a3a2fc846a1966da48 +ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getDeclaration.ql a76c6360ed7b423229ec64dc4d03f586204fbf5107408b7d07c06ef43b30526e bc8569ecf097f0e6176da4f42379158137f70dcfb9b6d60f4c16f643b68f9d91 +ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getImportedModule.ql 0339867ca4f414cceba85df20d12eca64a3eea9847bb02829dc28fa95701e987 8c292768f56cecbdfeb92985212e6b39ecada819891921c3ba1532d88d84c43e +ql/test/extractor-tests/generated/decl/InfixOperatorDecl/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.ql e80e0f64d36027d9f064be0147711379a9cd82da8c52517bab39572e934ed1ac ff58e0dc81e399ee95496a4d2cf3f23974698c971dfe323b87d01164fa1de18f +ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getBaseType.ql 54a4bd2cfa666271ae9092285bb7217b082c88483d614066cfb599fc8ab84305 8b24ab8e93efe3922cb192eb5de5f517763058782e83e8732153421adddd68e1 +ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getExportedModule.ql cfca012f0951c86560d892ea5eae182d5eda661c9484a0df71ef9c905123e8f6 dfebda4fcad0e2f2a2c944782a7355b3caeac569e5a45621c582bc1bb243b2cc +ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getImportedModule.ql 44018a788205592c59cd10072f8b8d0558100bb15fff4b3e490176e86193e5b1 cc9fe6571713af8a0e844ac5da682c24feb1a2be4535e3feeb4cbbafba91a414 +ql/test/extractor-tests/generated/decl/OpaqueTypeDecl/OpaqueTypeDecl.ql 263d878d5a60ad0b63c9c8fc7a8463e71ad920de9b5e0afa5c657d44f5fcedb3 615435e94f0c55f1bcdf59176dace7c3737ed052e7b2a049e2a0706523de5fa2 +ql/test/extractor-tests/generated/decl/OpaqueTypeDecl/OpaqueTypeDecl_getBaseType.ql d030fd55ea5a5443c03e8ba1a024c03e3c68c96c948c850131f59fbac6409402 46816c1a75a4cf11db95884733382e46d5573b6c1116d5de0bfe5ae91fed4c3d +ql/test/extractor-tests/generated/decl/OpaqueTypeDecl/OpaqueTypeDecl_getGenericTypeParam.ql c147420a91c157ee37a900dd7739bdb386fba5eeaadd84e609d2642d3fdbf2e0 cf1c981b6cb7b84944e9430cfe361905dcc396d4356d7f20a0ba993352bd5b02 +ql/test/extractor-tests/generated/decl/OpaqueTypeDecl/OpaqueTypeDecl_getOpaqueGenericParam.ql 2b4264a68817f53ddd73e4fd80e9f7c3a5fcfa4d0692135e2d3b10c8a8379d98 c2efac460b655e726d898b2b80cbfce24820a922e26935804ddd21ae9c474085 +ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl.ql a02dc34d4f3cfab7d3080413062f320e8ce77162cfc4e61094b5f26a761e4949 e9737a4bec7afc503f7b6cfeb54d0a1753777cbfad03943209431b5387b7850a +ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAccessorDecl.ql bf6bd41b1eedad87a2d86acb4b183ddbd150119a0301ec56c6d7129fe5dee453 247fe28adde08cb86e03f9f21c32ea96b8bdc522b848bb84a592292338cac6b1 +ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAttachedPropertyWrapperType.ql 3642cfd3ecf47a6b81a1745dc043131df349b898a937445eadfdee9f69aec3fc 97137c6673c45b0743db310b0839426eab71f5bc80ccc7bab99c304b8198159f +ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentInitializer.ql f0ecd0352a7e34e13040f31440a6170b0661b625c65b35d13021731b6db0f441 9fc89925050c9538ba3ba0b8c45278e30dffba64b53002f675e3f7a9ef014539 +ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentPattern.ql d6cbe58a6fb294762d88cbad55e2a8a188573969c1c691e73a9d6f598001f01e ddc4c06dccebaa4e92dcf765304278ca10339070955ee6616dfec6c814074496 +ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getPropertyWrapperBackingVar.ql d8b0a5264ebfd405d7a400cb56feffe66b73cbeb8caac92d96a5ee9acfc7a59d c3fd21ee69682592135fc2c88633dba36f5a5c4b07a3ad756977afdc055b9d6b +ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getPropertyWrapperBackingVarBinding.ql 71ad0741b1db153c02506d324b4211526209884a4206a2fc12565aae9426f5f0 e90e963ba9b709743d2bc973027e7f2985f072e2f0dd2e92db9a9053e136de63 +ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getPropertyWrapperLocalWrappedVar.ql 97255410c46dcfae6b454eb71b377ae4a14b2c5ce5bd40e4ba57f351476e87ee 277094dbdde3018cc24d660e7dca9ecea732ce22d2a7c009f36644d3e9676f68 +ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getPropertyWrapperLocalWrappedVarBinding.ql 14f50b706a2dba7123888868d93fa72a4871e6e04949cc87a7df52e27b7197d1 680242c73f78a64a1687cf59b0a80f715c98b994b32ec90044bcedd2c258f786 +ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getPropertyWrapperProjectionVar.ql 406436f415d5a6895be712471e7ab2d8b945539ac01b845ce191c4186e1cd275 4fdd0bc67207fd5cbe30743df46fdc61eeb5e58d877ef4aef5c7d7f0f684ef05 +ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getPropertyWrapperProjectionVarBinding.ql c79a13e49d3375edac8e51b27a58318afee959a8df639f7b0d7d77de1e2d60bc 8c3b9dae1079e674854d15f4bd43f1f507b7fac6900f0831d92f2140aae268b4 +ql/test/extractor-tests/generated/decl/PatternBindingDecl/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/decl/PostfixOperatorDecl/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/decl/PoundDiagnosticDecl/PoundDiagnosticDecl.ql 5a84b0117ba0bd438a7b6d034a95b4cf487eaec6ed45fa5a24df421a666704e0 2dd647c445849cc0ecfaa55b918d36c4f06a7c6e15f1f01a7a2f9c25e2b3b45b +ql/test/extractor-tests/generated/decl/PrecedenceGroupDecl/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/decl/PrefixOperatorDecl/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/decl/ProtocolDecl/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/decl/StructDecl/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/decl/SubscriptDecl/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/decl/TopLevelCodeDecl/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/decl/TypeAliasDecl/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/AppliedPropertyWrapperExpr/AppliedPropertyWrapperExpr.ql 5fc96795860963e91b1073a18347b81ca60e57e364636b33d452bf721cd33d88 798e5804cf4a7cc53f150d081ca585b20aee66ff3e4f676e96806a84aabf4ba1 +ql/test/extractor-tests/generated/expr/AppliedPropertyWrapperExpr/AppliedPropertyWrapperExpr_getType.ql 1caa0b9c70afc6f63fb1cb05b30499a615a997849d5128006f9c7147b7f1d4a4 64474604bf6d9028bdcbbb8dd2a607c65cb74038e2d6e88e86908f82590ba7a7 +ql/test/extractor-tests/generated/expr/Argument/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/ArrayExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/AssignExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/AutoClosureExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/BinaryExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/BindOptionalExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/BooleanLiteralExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/CallExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/CaptureListExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/ClosureExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/CoerceExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/ConditionalCheckedCastExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/ConstructorRefCallExpr/ConstructorRefCallExpr.ql 1364aaeb8354078d479fc32b389febf5a76d18d86924be8357be5d7c59b68e48 816f5bf8b36e68c63d7849d883f3cf7fe9d19ee55d3244099d3178ae62aef1d3 +ql/test/extractor-tests/generated/expr/ConstructorRefCallExpr/ConstructorRefCallExpr_getArgument.ql a3a01f99aa8df3aafed50cc7828829e567e01fed7874854e7a620904f1641fc9 962669b36b9adbc3d75bae79a9a754692c20d6e14ee2b47aca8f3f93b27895da +ql/test/extractor-tests/generated/expr/ConstructorRefCallExpr/ConstructorRefCallExpr_getType.ql c3504dda8c41ebc386a9011deb06b0f5312538306b5ca10f7c4ff2e0f2c277dd aa6785ac86fe4954ef679fdfa6cd91f964d9281ab0162240b6e4b9eb67b0eda3 +ql/test/extractor-tests/generated/expr/DeclRefExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/DefaultArgumentExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/DictionaryExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/DiscardAssignmentExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/DotSyntaxBaseIgnoredExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr.ql 0065feb0a78820e5905518ed06b41095fead328ed10fa6c7e6318e845f06670f d37a87dd726d27888b0673aac38726f7b190d6522e57c443e1a56f77c15e7bee +ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.ql ab0023396a31a9fad384ac6ab2819fa3b45726d651fee6ee5d84ea4fbdb55992 410afe1ae14ca17bc245c9fa88f84ba1d02e20a7803910746316ddcacc062ace +ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getType.ql ea3d25737d4c02d6ecd405d23471a587945362dee1160f6346484fffa166835d 3edcaae4cd47839dc716640ac9c098a9c65f365a69fb5442d15eb1955c06dcaa +ql/test/extractor-tests/generated/expr/DynamicLookupExpr/DynamicLookupExpr.ql 626a984185cb3082e3138740cc44dcd94334340266f8dff4212d1df8b2950a7d 5b3af58bcb8eb2a05677f5e19bbd5dfd77ff340d020869b780329f5e21b985a9 +ql/test/extractor-tests/generated/expr/DynamicLookupExpr/DynamicLookupExpr_getMember.ql ab1669430da9e60e3b5187bd4f45e7a9b501348cd0c66e4d8570c6facc3a82a3 a2e5e9781c9af9c52fe9d5735f146dc4a2e077096f2baee8db75f2a2f82b0037 +ql/test/extractor-tests/generated/expr/DynamicLookupExpr/DynamicLookupExpr_getType.ql 216b9caa3388b85959b19db012c6a7af40981ef92e4749b9cc644caee830041c 32691b624baed5c89fbef438214ecb893f9c1d1a575194133b56d79877e3feec +ql/test/extractor-tests/generated/expr/DynamicTypeExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.ql 6828ec28bceddb96c23eaa9b4b2ee6d6223edbca47c9f30219c09093fa7c6465 334b8ecfb0b9fc40b2e1440173e25aeba65905765c35bfbbf68090ad864c10d0 +ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.ql edc2e175c971465f5667c4586bc4c77e5c245d267f80009a049b8f657238a5f4 5df26b5bdf975ba910a7c3446705c3ac82a67d05565d860fe58464ee82bafdde +ql/test/extractor-tests/generated/expr/FloatLiteralExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/ForceTryExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/ForceValueExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/ForcedCheckedCastExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/IdentityExpr/IdentityExpr.ql 682a734d58a9bc731f4b73b2c54467774243438be7bb8d5c8fe6483c66401332 cbe4c4df1b7163995c76b89eee41eacb1a573c774155323aa8dcf79e404379ed +ql/test/extractor-tests/generated/expr/IdentityExpr/IdentityExpr_getType.ql 7a8520abbf50642f886a3cdea37530b0577d509f31d76224467ad5d435bb0e39 a6fd63a7964cf778cc4b23ce5112138d7d5a5db96956e9514741ef9789bd1f19 +ql/test/extractor-tests/generated/expr/IfExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/ImplicitConversionExpr/ImplicitConversionExpr.ql c9e1a3f60f760077b2149c0bd647195628f1969758d885174665b7fb4c0c9b8a a3a9766f976499caaee2739ed5a81b63cf2f556924643713cee59fac4ab07e5d +ql/test/extractor-tests/generated/expr/ImplicitConversionExpr/ImplicitConversionExpr_getType.ql 184ff1dec5d65024c8a0c2b316706ac58c68c62c715c266211e947168750c89a 486fc8d65c0db86bdada2d540f665278caab43454a69ccc8c2e702729397fef0 +ql/test/extractor-tests/generated/expr/InOutExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/IntegerLiteralExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/InterpolatedStringLiteralExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/IsExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/KeyPathApplicationExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/KeyPathDotExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/KeyPathExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/LazyInitializerExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/MagicIdentifierLiteralExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/MakeTemporarilyEscapableExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/MemberRefExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/MethodRefExpr/MethodRefExpr.ql a2fd4e761b2425c3055b0035937e0303e1b3555ab48d699f765db91c31bac7ae 6a1c3b2379001592095ae2a48740373cf8cec3a256a308ffad8a1a1c74ae656e +ql/test/extractor-tests/generated/expr/MethodRefExpr/MethodRefExpr_getMember.ql 178794928d040a4a5ebbae0cd835936eac0214756fbb5b4bbbe29d4487e86d0c 6efedf486a073a487a45539f097219bb7ac9c11c0ce8d539e950a9e5035d8a61 +ql/test/extractor-tests/generated/expr/MethodRefExpr/MethodRefExpr_getType.ql 991f8855bd8297971aec205aa13d072674739133d4adb8cdaa272c6340848bb4 08810d4640f61ab4ede0ddb0d23c498936ae3b6ee3f40ab7f702b96ad5dba101 +ql/test/extractor-tests/generated/expr/NilLiteralExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/ObjectLiteralExpr/ObjectLiteralExpr.ql b47984c8a72cc757922beda3a38ec090c9286aa5ccba9b799fc27223f4f85952 9297bd78da12cc7db6d183e6c6de86e259220c44674a21a972a51e2661030d55 +ql/test/extractor-tests/generated/expr/ObjectLiteralExpr/ObjectLiteralExpr_getArgument.ql ab308c1fa027136070a6ee9ebe5149c69b34bb9ae910f201f37cecd8b6341ff8 deef69f4a1a94386a32ec964e696972a2c6a91c34d7e99c7e4a3811980f5ecc4 +ql/test/extractor-tests/generated/expr/ObjectLiteralExpr/ObjectLiteralExpr_getType.ql 07d59d9962f3705f8f32302c0d730c179ca980172dd000b724a72e768fbf39db cd146e19249590316bb83efec19dd41234723513025cf9df45313f78f2b364dd +ql/test/extractor-tests/generated/expr/OneWayExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/OpaqueValueExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/OpenExistentialExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/OptionalEvaluationExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/OptionalTryExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/OtherConstructorDeclRefExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/PostfixUnaryExpr/PostfixUnaryExpr.ql b6e8de27cc17a1bd3883948af8fb620fd7872b01e63ae3d030dadc09e8eccb18 378588263065a827aef9cca17ceda876cfc6f40295bb7e46d506d59400a86521 +ql/test/extractor-tests/generated/expr/PostfixUnaryExpr/PostfixUnaryExpr_getArgument.ql 3b0e6f81599e5565bb78aff753932776c933fefdc8dc49e57db9f5b4164017f6 43031a3d0baa58f69b89a8a5d69f1a40ffeeaddc8a630d241e107de63ea54532 +ql/test/extractor-tests/generated/expr/PostfixUnaryExpr/PostfixUnaryExpr_getType.ql fa909883140fe89084c289c18ebc681402c38d0f37159d01f043f62de80521fc 4cd748e201e9374e589eaa0e3cc10310a1378bba15272a327d5cf54dbd526e8f +ql/test/extractor-tests/generated/expr/PrefixUnaryExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/PropertyWrapperValuePlaceholderExpr/PropertyWrapperValuePlaceholderExpr.ql 3b24e7b4c80d3d2a614be7a9329c45d71691d82ba624b5a4512048a9aa560491 8209c8bcf99ed5b81f212bb8c9fac2c1562cf342b0f596116dc3d5c7c8e4eb83 +ql/test/extractor-tests/generated/expr/PropertyWrapperValuePlaceholderExpr/PropertyWrapperValuePlaceholderExpr_getType.ql 0972415a8ac29f460d480990f85c3976ad947e26510da447bbf74ee61d9b3f4e 463b8ce871911b99c495ea84669b4e6f8eafc645df483f6a99413e930bc0275e +ql/test/extractor-tests/generated/expr/PropertyWrapperValuePlaceholderExpr/PropertyWrapperValuePlaceholderExpr_getWrappedValue.ql 208153f062b04bec13a860b64ea51c1d531597140d81a6d4598294dc9f8649a2 dfaea19e1075c02dfc0366fac8fd2edfae8dde06308730eb462c54be5b571129 +ql/test/extractor-tests/generated/expr/RebindSelfInConstructorExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/RegexLiteralExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/StringLiteralExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/SubscriptExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/SuperRefExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/TapExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/TryExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/TupleElementExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/TupleExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/TypeExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/expr/VarargExpansionExpr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/pattern/AnyPattern/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/pattern/BindingPattern/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/pattern/BoolPattern/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/pattern/EnumElementPattern/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/pattern/ExprPattern/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/pattern/IsPattern/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/pattern/NamedPattern/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/pattern/OptionalSomePattern/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/pattern/ParenPattern/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/pattern/TuplePattern/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/pattern/TypedPattern/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/BraceStmt/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/BreakStmt/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/CaseLabelItem/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/CaseStmt/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/ConditionElement/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/ContinueStmt/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/DeferStmt/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/DoCatchStmt/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/DoStmt/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/FailStmt/FailStmt.ql 75bf8a697d3a610caf25cb0d25748f2d1620c20fdd84c278c3e2f2502bc3f418 6e2377b8d2a63deaadbf8661dc7da70e8523637020e7d5fd601ca6893f10a573 +ql/test/extractor-tests/generated/stmt/FallthroughStmt/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/ForEachStmt/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/GuardStmt/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/IfStmt/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/PoundAssertStmt/PoundAssertStmt.ql dc72e3a7ff4c5dc39530322c343931cdfe63565eb76b29deef64bb311bfe302a 18eb3dab5ae8cfada5d42f1e70be9cb464a61ab5ce91897ce5a44a34387915e7 +ql/test/extractor-tests/generated/stmt/RepeatWhileStmt/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/ReturnStmt/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/StmtCondition/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/SwitchStmt/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/ThrowStmt/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/WhileStmt/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/stmt/YieldStmt/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/ArraySliceType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/BoundGenericClassType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/BoundGenericEnumType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/BoundGenericStructType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.ql fd632ef56c3586fc9b96bf0553567cce61c9cb33bc6d4b3714a6cbbfd04be58a 7a396b997dfd287bca46c6e6c44a7e609015932370e3fb4fc240b462817d9e34 +ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType_getWidth.ql 61e99a3987c5a4b10d5d105184c60dacc1c08d8106cf41b81d491a7f0ac36ef2 b02395a219768e0f41cbf77e4111da3a271e777bfe448eea1ea5d6f0910ff1e8 +ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.ql 48f3b997bdb2c37dc22fd3dc2d18bc853888503d0d8d8cb075c6cd18657553e2 278d18e1fae3d8693a4d363b67c6ff111c111464f104d72ccad37793bc425200 +ql/test/extractor-tests/generated/type/ClassType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/DependentMemberType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/DictionaryType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.ql d2c942b55f3a9f5af2cde39999b736ce2d50ae4514f36cc1e3f750905b03c49b b7ccdcf083da1598eaf4b5ad22e393253b8d58577580048290651a20f6e6df2f +ql/test/extractor-tests/generated/type/EnumType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/ExistentialMetatypeType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.ql f7894f01a440b5db281dfaa9c083be0898d15b67e1b0047be3f9c959b97bdeb0 725a54f6ed26d53603a3e25cbf78c90b1f16837c1c0c39b56e7d3bdd51a78265 +ql/test/extractor-tests/generated/type/FunctionType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/GenericFunctionType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/GenericTypeParamType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/InOutType/InOutType.ql 35b7c048fbd053f6821ab1d996fabf55dada014873f25c5ed7141b59eb5e0fb6 06ca9b5be9a999cbd7e1ab2f26918a5923d7d351dd9ec74137550f1947013b7d +ql/test/extractor-tests/generated/type/LValueType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/MetatypeType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/ModuleType/ModuleType.ql 8f798fea381d1b502f262b5ee790758b38008cadcdee848d0ddba1bd9f8ff4f9 4c3d623607be1a5f6503500f3331ee3b3e5200e9e78cca8a4ef3d24c83d0e7ba +ql/test/extractor-tests/generated/type/OpaqueTypeArchetypeType/OpaqueTypeArchetypeType.ql d15e89cbf72f4cf278258df3e6885baefef86960f4c891178ef0dbad69ff1db7 fb6854084970e0da3ae743299a2b0f69bd724ebdd8dfacc777010aaa7f61304c +ql/test/extractor-tests/generated/type/OpaqueTypeArchetypeType/OpaqueTypeArchetypeType_getProtocol.ql fb9baf55660e0eedf1a387267d170ae066a8d1531156eab5447feca92f05b751 139529998fc2060a46a70cb645a9aa36240ab225bd9fbdb3decc3eaec3aa2261 +ql/test/extractor-tests/generated/type/OpaqueTypeArchetypeType/OpaqueTypeArchetypeType_getSuperclass.ql 3556a07117f10a070638f3049dff85dd41c042ff3d13be275e19b995b3e7af81 5f0f6d66d9852eff45c25451dae087117077aa7b11a7908178769489f3726e11 +ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType.ql 0de02f1777f4b9216609a8be67e2c1fe34ab0657ecdd0ab11ca8a78b7a9daa30 ab2d57361e4c11443531100b06dd97ce8ee6871a40f1a99ad395b45ba8b74dd0 +ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getProtocol.ql c208618d6bd7d4759581f06fad2b452077a0d865b4fb4288eff591fc7b16cd67 3bd6b8e1d1bc14bd27144a8356e07520d36ea21b6ea4adb61e84a2013e8701fc +ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getSuperclass.ql bb7fc71b2d84e8c5492bb4c61492dabbce898bfb680979aadd88c4de44ea5af7 acae343087222e8eb7e4dfa0e256097d9592a9668afcb5706bcba5548afc0770 +ql/test/extractor-tests/generated/type/OptionalType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/ParameterizedProtocolType/ParameterizedProtocolType.ql 79da7723c0eb935b061b08aa71d349b36db4a6b46bc7c3274f550c1d7c870a13 0cdb58f4d9a481927187dc5ec4af4847a6cd4882b87b03c25dc0eb96495439f7 +ql/test/extractor-tests/generated/type/ParameterizedProtocolType/ParameterizedProtocolType_getArg.ql 8d10c3c858dedba47f227ebc92745916a248cd040ad944b80bf0d7a19af229d3 a29e2e0df269034c4f1fbd8f6de6d5898e895ad8b90628d5c869a45b596b53fc +ql/test/extractor-tests/generated/type/ParenType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.ql e1c6ffa622b9a5635147311640709bdbf9bb708c5846902c36e1cefe08cf69e7 fcd271f52fc698e5d866da73226ef546aae0fc161a85647426886bbfb510ab48 +ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType_getProtocol.ql 8af9b686cb9c3d988aea21cdaca42a0b625985111caa71d3eebaba4aea883e9c beecb31ab8fccb05c853926bccec33e298bed519385a25d6158646c94a019af9 +ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType_getSuperclass.ql 3b752a38eac8204ae6d902d03da8caeaad4072f30206420c97056e4bf3639eb4 fc5959969d5b229fa5d90dde7d997aa0d1b91bdb9d77cc6811377044eed4a6cb +ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.ql 724be7f272566bb15acf34b32686df5a2bba7423baed8efcbffc1b6153e8d34c c6eb710b89fcca0410f0e1ac64ba76c12aa72d5b2ebc3889fc5d55c7168b2f0d +ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType_getMember.ql 8c1e8e5932cd775f0d0812a64954be5fd5b3eedd8a26eedb0bd6009cbc156e24 5c43ef8000bb67ed0e070bbd9d5fc167dcb7b6334ae34747d27eb8060af1a7e5 +ql/test/extractor-tests/generated/type/ProtocolType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/StructType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/TupleType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/TypeAliasType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/TypeRepr/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/UnboundGenericType/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd +ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.ql 3047ed64cbdb03d719d096fd3b2c4c54c92a2b65e46943424e84eeca705ab2d3 a8ee8ca4bf257c7472fa8cd7e661d352e8856b9e5855ebb3681f4d313209141c +ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.ql 11e205283b368b9c9dbc79636c6007df501c952e6f715a9f07e65ec452192b38 ceb1e9c1279df07c77f9b23356b71c3e7672ec4cd5253898e09b27b2b24e4b00 +ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.ql 8c44ebc1fd1fa0b5caad5eb5b280f227f002dcfaddba45131b2959dad0b458f6 5f497990e2bd57a3ea8e2eb7da598af0c4ba7c7b4cc89b549e45de0ae3712e60 +ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.ql 39f1d90f8884d98235618a0bb955840daa0b1626b5f100a8f8d3b507b3b4fb84 2bd89193e20cc756a774bee940733a0b1c09f103d106d08433274eaed318a256 From aeb7b0d050b482a6ea30d0109ac29505274bde55 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 18 Nov 2022 17:10:01 +0100 Subject: [PATCH 388/796] Swift: remove `ModifiedStubMarkedAsGeneratedError` --- swift/actions/setup-env/action.yml | 1 + swift/codegen/generators/qlgen.py | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/swift/actions/setup-env/action.yml b/swift/actions/setup-env/action.yml index 8e3bf3478f0..3ee90d9355f 100644 --- a/swift/actions/setup-env/action.yml +++ b/swift/actions/setup-env/action.yml @@ -21,3 +21,4 @@ runs: shell: bash run: | echo build --repository_cache=~/.cache/bazel-repository-cache --disk_cache=~/.cache/bazel-disk-cache > ~/.bazelrc + echo test --test_output=errors diff --git a/swift/codegen/generators/qlgen.py b/swift/codegen/generators/qlgen.py index 4a7d8435a1e..c1650974796 100755 --- a/swift/codegen/generators/qlgen.py +++ b/swift/codegen/generators/qlgen.py @@ -43,10 +43,6 @@ class FormatError(Error): pass -class ModifiedStubMarkedAsGeneratedError(Error): - pass - - class RootElementHasChildren(Error): pass From 6dcdf8c71f7c266209fa0305a7bd4547c083ae2a Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 18 Nov 2022 17:22:44 +0100 Subject: [PATCH 389/796] Swift: fix bazel setup --- swift/actions/setup-env/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/actions/setup-env/action.yml b/swift/actions/setup-env/action.yml index 3ee90d9355f..83c65d6f82a 100644 --- a/swift/actions/setup-env/action.yml +++ b/swift/actions/setup-env/action.yml @@ -21,4 +21,4 @@ runs: shell: bash run: | echo build --repository_cache=~/.cache/bazel-repository-cache --disk_cache=~/.cache/bazel-disk-cache > ~/.bazelrc - echo test --test_output=errors + echo test --test_output=errors >> ~/.bazelrc From b748ed8f43921ceb833425f3d990730cd0c4e761 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 16 Nov 2022 15:08:53 +0000 Subject: [PATCH 390/796] C++: Repair the 'MustFlow' library. --- .../semmle/code/cpp/ir/dataflow/MustFlow.qll | 52 +++++++++---------- .../ReturnStackAllocatedMemory.ql | 22 ++++---- cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql | 40 +++++++------- 3 files changed, 56 insertions(+), 58 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/MustFlow.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/MustFlow.qll index 08ee06acdda..904701144ca 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/MustFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/MustFlow.qll @@ -5,7 +5,6 @@ */ private import cpp -import semmle.code.cpp.ir.dataflow.DataFlow private import semmle.code.cpp.ir.IR /** @@ -25,18 +24,18 @@ abstract class MustFlowConfiguration extends string { /** * Holds if `source` is a relevant data flow source. */ - abstract predicate isSource(DataFlow::Node source); + abstract predicate isSource(Instruction source); /** * Holds if `sink` is a relevant data flow sink. */ - abstract predicate isSink(DataFlow::Node sink); + abstract predicate isSink(Operand sink); /** * Holds if the additional flow step from `node1` to `node2` must be taken * into account in the analysis. */ - predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { none() } + predicate isAdditionalFlowStep(Operand node1, Instruction node2) { none() } /** Holds if this configuration allows flow from arguments to parameters. */ predicate allowInterproceduralFlow() { any() } @@ -48,17 +47,17 @@ abstract class MustFlowConfiguration extends string { * included in the module `PathGraph`. */ final predicate hasFlowPath(MustFlowPathNode source, MustFlowPathSink sink) { - this.isSource(source.getNode()) and + this.isSource(source.getInstruction()) and source.getASuccessor+() = sink } } /** Holds if `node` flows from a source. */ pragma[nomagic] -private predicate flowsFromSource(DataFlow::Node node, MustFlowConfiguration config) { +private predicate flowsFromSource(Instruction node, MustFlowConfiguration config) { config.isSource(node) or - exists(DataFlow::Node mid | + exists(Instruction mid | step(mid, node, config) and flowsFromSource(mid, pragma[only_bind_into](config)) ) @@ -66,12 +65,12 @@ private predicate flowsFromSource(DataFlow::Node node, MustFlowConfiguration con /** Holds if `node` flows to a sink. */ pragma[nomagic] -private predicate flowsToSink(DataFlow::Node node, MustFlowConfiguration config) { +private predicate flowsToSink(Instruction node, MustFlowConfiguration config) { flowsFromSource(node, pragma[only_bind_into](config)) and ( - config.isSink(node) + config.isSink(node.getAUse()) or - exists(DataFlow::Node mid | + exists(Instruction mid | step(node, mid, config) and flowsToSink(mid, pragma[only_bind_into](config)) ) @@ -198,12 +197,13 @@ private module Cached { } cached - predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - instructionToOperandStep(nodeFrom.asInstruction(), nodeTo.asOperand()) + predicate step(Instruction nodeFrom, Instruction nodeTo) { + exists(Operand mid | + instructionToOperandStep(nodeFrom, mid) and + operandToInstructionStep(mid, nodeTo) + ) or - flowThroughCallable(nodeFrom.asInstruction(), nodeTo.asInstruction()) - or - operandToInstructionStep(nodeFrom.asOperand(), nodeTo.asInstruction()) + flowThroughCallable(nodeFrom, nodeTo) } } @@ -213,12 +213,12 @@ private module Cached { * way around. */ pragma[inline] -private Declaration getEnclosingCallable(DataFlow::Node n) { - pragma[only_bind_into](result) = pragma[only_bind_out](n).getEnclosingCallable() +private IRFunction getEnclosingCallable(Instruction n) { + pragma[only_bind_into](result) = pragma[only_bind_out](n).getEnclosingIRFunction() } /** Holds if `nodeFrom` flows to `nodeTo`. */ -private predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, MustFlowConfiguration config) { +private predicate step(Instruction nodeFrom, Instruction nodeTo, MustFlowConfiguration config) { exists(config) and Cached::step(pragma[only_bind_into](nodeFrom), pragma[only_bind_into](nodeTo)) and ( @@ -227,37 +227,37 @@ private predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, MustFlowC getEnclosingCallable(nodeFrom) = getEnclosingCallable(nodeTo) ) or - config.isAdditionalFlowStep(nodeFrom, nodeTo) + config.isAdditionalFlowStep(nodeFrom.getAUse(), nodeTo) } private newtype TLocalPathNode = - MkLocalPathNode(DataFlow::Node n, MustFlowConfiguration config) { + MkLocalPathNode(Instruction n, MustFlowConfiguration config) { flowsToSink(n, config) and ( config.isSource(n) or - exists(MustFlowPathNode mid | step(mid.getNode(), n, config)) + exists(MustFlowPathNode mid | step(mid.getInstruction(), n, config)) ) } /** A `Node` that is in a path from a source to a sink. */ class MustFlowPathNode extends TLocalPathNode { - DataFlow::Node n; + Instruction n; MustFlowPathNode() { this = MkLocalPathNode(n, _) } /** Gets the underlying node. */ - DataFlow::Node getNode() { result = n } + Instruction getInstruction() { result = n } /** Gets a textual representation of this node. */ - string toString() { result = n.toString() } + string toString() { result = n.getAst().toString() } /** Gets the location of this element. */ Location getLocation() { result = n.getLocation() } /** Gets a successor node, if any. */ MustFlowPathNode getASuccessor() { - step(this.getNode(), result.getNode(), this.getConfiguration()) + step(this.getInstruction(), result.getInstruction(), this.getConfiguration()) } /** Gets the associated configuration. */ @@ -265,7 +265,7 @@ class MustFlowPathNode extends TLocalPathNode { } private class MustFlowPathSink extends MustFlowPathNode { - MustFlowPathSink() { this.getConfiguration().isSink(this.getNode()) } + MustFlowPathSink() { this.getConfiguration().isSink(this.getInstruction().getAUse()) } } /** diff --git a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql index 26c8ae4c258..af4bd8c61a3 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql @@ -26,11 +26,11 @@ predicate intentionallyReturnsStackPointer(Function f) { class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration { ReturnStackAllocatedMemoryConfig() { this = "ReturnStackAllocatedMemoryConfig" } - override predicate isSource(DataFlow::Node source) { + override predicate isSource(Instruction source) { // Holds if `source` is a node that represents the use of a stack variable exists(VariableAddressInstruction var, Function func | - var = source.asInstruction() and - func = var.getEnclosingFunction() and + var = source and + func = source.getEnclosingFunction() and var.getAstVariable() instanceof StackVariable and // Pointer-to-member types aren't properly handled in the dbscheme. not var.getResultType() instanceof PointerToMemberType and @@ -40,7 +40,7 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration { ) } - override predicate isSink(DataFlow::Node sink) { + override predicate isSink(Operand sink) { // Holds if `sink` is a node that represents the `StoreInstruction` that is subsequently used in // a `ReturnValueInstruction`. // We use the `StoreInstruction` instead of the instruction that defines the @@ -48,7 +48,7 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration { exists(StoreInstruction store | store.getDestinationAddress().(VariableAddressInstruction).getIRVariable() instanceof IRReturnVariable and - sink.asOperand() = store.getSourceValueOperand() + sink = store.getSourceValueOperand() ) } @@ -77,10 +77,10 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration { * } * ``` */ - override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - node2.asInstruction().(FieldAddressInstruction).getObjectAddressOperand() = node1.asOperand() + override predicate isAdditionalFlowStep(Operand node1, Instruction node2) { + node2.(FieldAddressInstruction).getObjectAddressOperand() = node1 or - node2.asInstruction().(PointerOffsetInstruction).getLeftOperand() = node1.asOperand() + node2.(PointerOffsetInstruction).getLeftOperand() = node1 } } @@ -89,6 +89,6 @@ from ReturnStackAllocatedMemoryConfig conf where conf.hasFlowPath(pragma[only_bind_into](source), pragma[only_bind_into](sink)) and - source.getNode().asInstruction() = var -select sink.getNode(), source, sink, "May return stack-allocated memory from $@.", var.getAst(), - var.getAst().toString() + source.getInstruction() = var +select sink.getInstruction(), source, sink, "May return stack-allocated memory from $@.", + var.getAst(), var.getAst().toString() diff --git a/cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql b/cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql index db1816f7a72..39ee43a373a 100644 --- a/cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql +++ b/cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql @@ -22,37 +22,35 @@ import PathGraph class UnsafeUseOfThisConfig extends MustFlowConfiguration { UnsafeUseOfThisConfig() { this = "UnsafeUseOfThisConfig" } - override predicate isSource(DataFlow::Node source) { isSource(source, _, _) } + override predicate isSource(Instruction source) { isSource(source, _, _) } - override predicate isSink(DataFlow::Node sink) { isSink(sink, _) } + override predicate isSink(Operand sink) { isSink(sink, _) } } /** Holds if `instr` is a `this` pointer used by the call instruction `call`. */ -predicate isSink(DataFlow::Node sink, CallInstruction call) { +predicate isSink(Operand sink, CallInstruction call) { exists(PureVirtualFunction func | call.getStaticCallTarget() = func and - call.getThisArgument() = sink.asInstruction() and + call.getThisArgumentOperand() = sink and // Weed out implicit calls to destructors of a base class not func instanceof Destructor ) } /** Holds if `init` initializes the `this` pointer in class `c`. */ -predicate isSource(DataFlow::Node source, string msg, Class c) { - exists(InitializeParameterInstruction init | init = source.asInstruction() | - ( - exists(Constructor func | - not func instanceof CopyConstructor and - not func instanceof MoveConstructor and - func = init.getEnclosingFunction() and - msg = "construction" - ) - or - init.getEnclosingFunction() instanceof Destructor and msg = "destruction" - ) and - init.getIRVariable() instanceof IRThisVariable and - init.getEnclosingFunction().getDeclaringType() = c - ) +predicate isSource(InitializeParameterInstruction source, string msg, Class c) { + ( + exists(Constructor func | + not func instanceof CopyConstructor and + not func instanceof MoveConstructor and + func = source.getEnclosingFunction() and + msg = "construction" + ) + or + source.getEnclosingFunction() instanceof Destructor and msg = "destruction" + ) and + source.getIRVariable() instanceof IRThisVariable and + source.getEnclosingFunction().getDeclaringType() = c } /** @@ -68,8 +66,8 @@ predicate flows( ) { exists(UnsafeUseOfThisConfig conf | conf.hasFlowPath(source, sink) and - isSource(source.getNode(), msg, sourceClass) and - isSink(sink.getNode(), call) + isSource(source.getInstruction(), msg, sourceClass) and + isSink(sink.getInstruction().getAUse(), call) ) } From ef6b85fa77a919d0a7d0610f9661c06b2ce01e51 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 16 Nov 2022 15:10:18 +0000 Subject: [PATCH 391/796] C++: Accept test changes. --- .../UnsafeUseOfThis/UnsafeUseOfThis.expected | 108 +++----- .../ReturnStackAllocatedMemory.expected | 248 +++++------------- 2 files changed, 100 insertions(+), 256 deletions(-) diff --git a/cpp/ql/test/query-tests/Critical/UnsafeUseOfThis/UnsafeUseOfThis.expected b/cpp/ql/test/query-tests/Critical/UnsafeUseOfThis/UnsafeUseOfThis.expected index 067ba7ab4fc..7f1ee1356ab 100644 --- a/cpp/ql/test/query-tests/Critical/UnsafeUseOfThis/UnsafeUseOfThis.expected +++ b/cpp/ql/test/query-tests/Critical/UnsafeUseOfThis/UnsafeUseOfThis.expected @@ -1,103 +1,61 @@ edges -| test.cpp:7:3:7:3 | this | test.cpp:8:12:8:15 | Load | -| test.cpp:8:12:8:15 | Load | test.cpp:8:12:8:15 | this | +| test.cpp:7:3:7:3 | B | test.cpp:8:12:8:15 | this | | test.cpp:8:12:8:15 | this | test.cpp:34:16:34:16 | x | -| test.cpp:11:8:11:8 | b | test.cpp:12:5:12:5 | Load | -| test.cpp:12:5:12:5 | (reference dereference) | test.cpp:12:5:12:5 | Unary | -| test.cpp:12:5:12:5 | Load | test.cpp:12:5:12:5 | b | -| test.cpp:12:5:12:5 | Unary | test.cpp:12:5:12:5 | (A)... | -| test.cpp:12:5:12:5 | Unary | test.cpp:12:5:12:5 | (reference dereference) | -| test.cpp:12:5:12:5 | b | test.cpp:12:5:12:5 | Unary | -| test.cpp:15:3:15:4 | this | test.cpp:16:5:16:5 | Load | -| test.cpp:16:5:16:5 | Load | test.cpp:16:5:16:5 | this | -| test.cpp:16:5:16:5 | Unary | file://:0:0:0:0 | (A *)... | -| test.cpp:16:5:16:5 | this | test.cpp:16:5:16:5 | Unary | -| test.cpp:21:3:21:3 | Unary | test.cpp:21:13:21:13 | ConvertToNonVirtualBase | -| test.cpp:21:3:21:3 | this | test.cpp:21:3:21:3 | Unary | -| test.cpp:21:3:21:3 | this | test.cpp:22:12:22:15 | Load | -| test.cpp:21:3:21:3 | this | test.cpp:25:7:25:10 | Load | -| test.cpp:21:13:21:13 | ConvertToNonVirtualBase | test.cpp:7:3:7:3 | this | +| test.cpp:11:8:11:8 | b | test.cpp:12:5:12:5 | b | +| test.cpp:12:5:12:5 | (reference dereference) | test.cpp:12:5:12:5 | (A)... | +| test.cpp:12:5:12:5 | b | test.cpp:12:5:12:5 | (reference dereference) | +| test.cpp:15:3:15:4 | ~B | test.cpp:16:5:16:5 | this | +| test.cpp:16:5:16:5 | this | file://:0:0:0:0 | (A *)... | +| test.cpp:21:3:21:3 | C | test.cpp:21:13:21:13 | call to B | +| test.cpp:21:3:21:3 | C | test.cpp:22:12:22:15 | this | +| test.cpp:21:3:21:3 | C | test.cpp:25:7:25:10 | this | +| test.cpp:21:13:21:13 | call to B | test.cpp:7:3:7:3 | B | | test.cpp:22:12:22:15 | (B *)... | test.cpp:34:16:34:16 | x | -| test.cpp:22:12:22:15 | Load | test.cpp:22:12:22:15 | this | -| test.cpp:22:12:22:15 | Unary | test.cpp:22:12:22:15 | (B *)... | -| test.cpp:22:12:22:15 | this | test.cpp:22:12:22:15 | Unary | -| test.cpp:25:7:25:10 | (B *)... | test.cpp:25:7:25:10 | Unary | -| test.cpp:25:7:25:10 | Load | test.cpp:25:7:25:10 | this | -| test.cpp:25:7:25:10 | Unary | test.cpp:25:7:25:10 | (A *)... | -| test.cpp:25:7:25:10 | Unary | test.cpp:25:7:25:10 | (B *)... | -| test.cpp:25:7:25:10 | this | test.cpp:25:7:25:10 | Unary | -| test.cpp:31:3:31:3 | this | test.cpp:31:12:31:15 | Load | -| test.cpp:31:11:31:15 | (B)... | test.cpp:31:11:31:15 | Unary | +| test.cpp:22:12:22:15 | this | test.cpp:22:12:22:15 | (B *)... | +| test.cpp:25:7:25:10 | (B *)... | test.cpp:25:7:25:10 | (A *)... | +| test.cpp:25:7:25:10 | this | test.cpp:25:7:25:10 | (B *)... | +| test.cpp:31:3:31:3 | D | test.cpp:31:12:31:15 | this | +| test.cpp:31:11:31:15 | (B)... | test.cpp:31:11:31:15 | (reference to) | | test.cpp:31:11:31:15 | (reference to) | test.cpp:11:8:11:8 | b | -| test.cpp:31:11:31:15 | * ... | test.cpp:31:11:31:15 | Unary | -| test.cpp:31:11:31:15 | Unary | test.cpp:31:11:31:15 | (B)... | -| test.cpp:31:11:31:15 | Unary | test.cpp:31:11:31:15 | (reference to) | -| test.cpp:31:12:31:15 | Load | test.cpp:31:12:31:15 | this | -| test.cpp:31:12:31:15 | Unary | test.cpp:31:11:31:15 | * ... | -| test.cpp:31:12:31:15 | this | test.cpp:31:12:31:15 | Unary | -| test.cpp:34:16:34:16 | x | test.cpp:35:3:35:3 | Load | -| test.cpp:35:3:35:3 | Load | test.cpp:35:3:35:3 | x | -| test.cpp:35:3:35:3 | Unary | test.cpp:35:3:35:3 | (A *)... | -| test.cpp:35:3:35:3 | x | test.cpp:35:3:35:3 | Unary | -| test.cpp:47:3:47:3 | this | test.cpp:48:10:48:13 | Load | -| test.cpp:48:10:48:13 | (E *)... | test.cpp:48:10:48:13 | Unary | -| test.cpp:48:10:48:13 | Load | test.cpp:48:10:48:13 | this | -| test.cpp:48:10:48:13 | Unary | test.cpp:48:6:48:13 | (A *)... | -| test.cpp:48:10:48:13 | Unary | test.cpp:48:10:48:13 | (E *)... | -| test.cpp:48:10:48:13 | this | test.cpp:48:10:48:13 | Unary | +| test.cpp:31:11:31:15 | * ... | test.cpp:31:11:31:15 | (B)... | +| test.cpp:31:12:31:15 | this | test.cpp:31:11:31:15 | * ... | +| test.cpp:34:16:34:16 | x | test.cpp:35:3:35:3 | x | +| test.cpp:35:3:35:3 | x | test.cpp:35:3:35:3 | (A *)... | +| test.cpp:47:3:47:3 | F | test.cpp:48:10:48:13 | this | +| test.cpp:48:10:48:13 | (E *)... | test.cpp:48:6:48:13 | (A *)... | +| test.cpp:48:10:48:13 | this | test.cpp:48:10:48:13 | (E *)... | nodes | file://:0:0:0:0 | (A *)... | semmle.label | (A *)... | -| test.cpp:7:3:7:3 | this | semmle.label | this | -| test.cpp:8:12:8:15 | Load | semmle.label | Load | +| test.cpp:7:3:7:3 | B | semmle.label | B | | test.cpp:8:12:8:15 | this | semmle.label | this | | test.cpp:11:8:11:8 | b | semmle.label | b | | test.cpp:12:5:12:5 | (A)... | semmle.label | (A)... | | test.cpp:12:5:12:5 | (reference dereference) | semmle.label | (reference dereference) | -| test.cpp:12:5:12:5 | Load | semmle.label | Load | -| test.cpp:12:5:12:5 | Unary | semmle.label | Unary | -| test.cpp:12:5:12:5 | Unary | semmle.label | Unary | | test.cpp:12:5:12:5 | b | semmle.label | b | -| test.cpp:15:3:15:4 | this | semmle.label | this | -| test.cpp:16:5:16:5 | Load | semmle.label | Load | -| test.cpp:16:5:16:5 | Unary | semmle.label | Unary | +| test.cpp:15:3:15:4 | ~B | semmle.label | ~B | | test.cpp:16:5:16:5 | this | semmle.label | this | -| test.cpp:21:3:21:3 | Unary | semmle.label | Unary | -| test.cpp:21:3:21:3 | this | semmle.label | this | -| test.cpp:21:13:21:13 | ConvertToNonVirtualBase | semmle.label | ConvertToNonVirtualBase | +| test.cpp:21:3:21:3 | C | semmle.label | C | +| test.cpp:21:13:21:13 | call to B | semmle.label | call to B | | test.cpp:22:12:22:15 | (B *)... | semmle.label | (B *)... | -| test.cpp:22:12:22:15 | Load | semmle.label | Load | -| test.cpp:22:12:22:15 | Unary | semmle.label | Unary | | test.cpp:22:12:22:15 | this | semmle.label | this | | test.cpp:25:7:25:10 | (A *)... | semmle.label | (A *)... | | test.cpp:25:7:25:10 | (B *)... | semmle.label | (B *)... | -| test.cpp:25:7:25:10 | Load | semmle.label | Load | -| test.cpp:25:7:25:10 | Unary | semmle.label | Unary | -| test.cpp:25:7:25:10 | Unary | semmle.label | Unary | | test.cpp:25:7:25:10 | this | semmle.label | this | -| test.cpp:31:3:31:3 | this | semmle.label | this | +| test.cpp:31:3:31:3 | D | semmle.label | D | | test.cpp:31:11:31:15 | (B)... | semmle.label | (B)... | | test.cpp:31:11:31:15 | (reference to) | semmle.label | (reference to) | | test.cpp:31:11:31:15 | * ... | semmle.label | * ... | -| test.cpp:31:11:31:15 | Unary | semmle.label | Unary | -| test.cpp:31:11:31:15 | Unary | semmle.label | Unary | -| test.cpp:31:12:31:15 | Load | semmle.label | Load | -| test.cpp:31:12:31:15 | Unary | semmle.label | Unary | | test.cpp:31:12:31:15 | this | semmle.label | this | | test.cpp:34:16:34:16 | x | semmle.label | x | | test.cpp:35:3:35:3 | (A *)... | semmle.label | (A *)... | -| test.cpp:35:3:35:3 | Load | semmle.label | Load | -| test.cpp:35:3:35:3 | Unary | semmle.label | Unary | | test.cpp:35:3:35:3 | x | semmle.label | x | -| test.cpp:47:3:47:3 | this | semmle.label | this | +| test.cpp:47:3:47:3 | F | semmle.label | F | | test.cpp:48:6:48:13 | (A *)... | semmle.label | (A *)... | | test.cpp:48:10:48:13 | (E *)... | semmle.label | (E *)... | -| test.cpp:48:10:48:13 | Load | semmle.label | Load | -| test.cpp:48:10:48:13 | Unary | semmle.label | Unary | -| test.cpp:48:10:48:13 | Unary | semmle.label | Unary | | test.cpp:48:10:48:13 | this | semmle.label | this | #select -| test.cpp:12:7:12:7 | call to f | test.cpp:31:3:31:3 | this | test.cpp:12:5:12:5 | (A)... | Call to pure virtual function during construction. | -| test.cpp:16:5:16:5 | call to f | test.cpp:15:3:15:4 | this | file://:0:0:0:0 | (A *)... | Call to pure virtual function during destruction. | -| test.cpp:25:13:25:13 | call to f | test.cpp:21:3:21:3 | this | test.cpp:25:7:25:10 | (A *)... | Call to pure virtual function during construction. | -| test.cpp:35:6:35:6 | call to f | test.cpp:7:3:7:3 | this | test.cpp:35:3:35:3 | (A *)... | Call to pure virtual function during construction. | -| test.cpp:35:6:35:6 | call to f | test.cpp:21:3:21:3 | this | test.cpp:35:3:35:3 | (A *)... | Call to pure virtual function during construction. | +| test.cpp:12:7:12:7 | call to f | test.cpp:31:3:31:3 | D | test.cpp:12:5:12:5 | (A)... | Call to pure virtual function during construction. | +| test.cpp:16:5:16:5 | call to f | test.cpp:15:3:15:4 | ~B | file://:0:0:0:0 | (A *)... | Call to pure virtual function during destruction. | +| test.cpp:25:13:25:13 | call to f | test.cpp:21:3:21:3 | C | test.cpp:25:7:25:10 | (A *)... | Call to pure virtual function during construction. | +| test.cpp:35:6:35:6 | call to f | test.cpp:7:3:7:3 | B | test.cpp:35:3:35:3 | (A *)... | Call to pure virtual function during construction. | +| test.cpp:35:6:35:6 | call to f | test.cpp:21:3:21:3 | C | test.cpp:35:3:35:3 | (A *)... | Call to pure virtual function during construction. | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/ReturnStackAllocatedMemory.expected b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/ReturnStackAllocatedMemory.expected index 8f9d91fc1ad..b7b598a13c5 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/ReturnStackAllocatedMemory.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/ReturnStackAllocatedMemory.expected @@ -1,231 +1,117 @@ edges -| test.cpp:17:9:17:11 | & ... | test.cpp:17:9:17:11 | StoreValue | -| test.cpp:17:10:17:11 | Unary | test.cpp:17:9:17:11 | & ... | -| test.cpp:17:10:17:11 | mc | test.cpp:17:10:17:11 | Unary | -| test.cpp:23:17:23:19 | & ... | test.cpp:23:17:23:19 | StoreValue | -| test.cpp:23:17:23:19 | Store | test.cpp:25:9:25:11 | Load | -| test.cpp:23:17:23:19 | StoreValue | test.cpp:23:17:23:19 | Store | -| test.cpp:23:18:23:19 | Unary | test.cpp:23:17:23:19 | & ... | -| test.cpp:23:18:23:19 | mc | test.cpp:23:18:23:19 | Unary | -| test.cpp:25:9:25:11 | Load | test.cpp:25:9:25:11 | ptr | -| test.cpp:25:9:25:11 | ptr | test.cpp:25:9:25:11 | StoreValue | -| test.cpp:39:17:39:18 | (reference to) | test.cpp:39:17:39:18 | StoreValue | -| test.cpp:39:17:39:18 | Store | test.cpp:41:10:41:12 | Load | -| test.cpp:39:17:39:18 | StoreValue | test.cpp:39:17:39:18 | Store | -| test.cpp:39:17:39:18 | Unary | test.cpp:39:17:39:18 | (reference to) | -| test.cpp:39:17:39:18 | mc | test.cpp:39:17:39:18 | Unary | -| test.cpp:41:9:41:12 | & ... | test.cpp:41:9:41:12 | StoreValue | -| test.cpp:41:10:41:12 | (reference dereference) | test.cpp:41:10:41:12 | Unary | -| test.cpp:41:10:41:12 | Load | test.cpp:41:10:41:12 | ref | -| test.cpp:41:10:41:12 | Unary | test.cpp:41:9:41:12 | & ... | -| test.cpp:41:10:41:12 | Unary | test.cpp:41:10:41:12 | (reference dereference) | -| test.cpp:41:10:41:12 | ref | test.cpp:41:10:41:12 | Unary | -| test.cpp:47:9:47:10 | (reference to) | test.cpp:47:9:47:10 | StoreValue | -| test.cpp:47:9:47:10 | Unary | test.cpp:47:9:47:10 | (reference to) | -| test.cpp:47:9:47:10 | mc | test.cpp:47:9:47:10 | Unary | -| test.cpp:54:9:54:15 | & ... | test.cpp:54:9:54:15 | StoreValue | -| test.cpp:54:11:54:12 | Unary | test.cpp:54:14:54:14 | a | -| test.cpp:54:11:54:12 | mc | test.cpp:54:11:54:12 | Unary | -| test.cpp:54:14:54:14 | Unary | test.cpp:54:9:54:15 | & ... | -| test.cpp:54:14:54:14 | a | test.cpp:54:14:54:14 | Unary | -| test.cpp:89:3:89:11 | Store | test.cpp:92:9:92:11 | Load | -| test.cpp:89:9:89:11 | & ... | test.cpp:89:9:89:11 | StoreValue | -| test.cpp:89:9:89:11 | StoreValue | test.cpp:89:3:89:11 | Store | -| test.cpp:89:10:89:11 | Unary | test.cpp:89:9:89:11 | & ... | -| test.cpp:89:10:89:11 | mc | test.cpp:89:10:89:11 | Unary | -| test.cpp:92:9:92:11 | Load | test.cpp:92:9:92:11 | ptr | -| test.cpp:92:9:92:11 | ptr | test.cpp:92:9:92:11 | StoreValue | -| test.cpp:112:9:112:11 | Unary | test.cpp:112:9:112:11 | array to pointer conversion | -| test.cpp:112:9:112:11 | arr | test.cpp:112:9:112:11 | Unary | -| test.cpp:112:9:112:11 | array to pointer conversion | test.cpp:112:9:112:11 | StoreValue | -| test.cpp:119:9:119:18 | & ... | test.cpp:119:9:119:18 | StoreValue | -| test.cpp:119:11:119:13 | Left | test.cpp:119:11:119:17 | access to array | -| test.cpp:119:11:119:13 | Unary | test.cpp:119:11:119:13 | array to pointer conversion | -| test.cpp:119:11:119:13 | arr | test.cpp:119:11:119:13 | Unary | -| test.cpp:119:11:119:13 | array to pointer conversion | test.cpp:119:11:119:13 | Left | -| test.cpp:119:11:119:17 | Unary | test.cpp:119:9:119:18 | & ... | -| test.cpp:119:11:119:17 | access to array | test.cpp:119:11:119:17 | Unary | -| test.cpp:134:2:134:14 | Store | test.cpp:135:2:135:4 | Load | -| test.cpp:134:8:134:10 | Left | test.cpp:134:8:134:14 | ... + ... | -| test.cpp:134:8:134:10 | Unary | test.cpp:134:8:134:10 | array to pointer conversion | -| test.cpp:134:8:134:10 | arr | test.cpp:134:8:134:10 | Unary | -| test.cpp:134:8:134:10 | array to pointer conversion | test.cpp:134:8:134:10 | Left | -| test.cpp:134:8:134:14 | ... + ... | test.cpp:134:8:134:14 | StoreValue | -| test.cpp:134:8:134:14 | StoreValue | test.cpp:134:2:134:14 | Store | -| test.cpp:135:2:135:4 | Left | test.cpp:135:2:135:6 | PointerAdd | -| test.cpp:135:2:135:4 | Load | test.cpp:135:2:135:4 | ptr | -| test.cpp:135:2:135:4 | ptr | test.cpp:135:2:135:4 | Left | -| test.cpp:135:2:135:6 | PointerAdd | test.cpp:135:2:135:6 | StoreValue | -| test.cpp:135:2:135:6 | Store | test.cpp:137:9:137:11 | Load | -| test.cpp:135:2:135:6 | StoreValue | test.cpp:135:2:135:6 | Store | -| test.cpp:137:9:137:11 | Load | test.cpp:137:9:137:11 | ptr | -| test.cpp:137:9:137:11 | ptr | test.cpp:137:9:137:11 | StoreValue | -| test.cpp:170:26:170:41 | (void *)... | test.cpp:170:26:170:41 | StoreValue | -| test.cpp:170:26:170:41 | Store | test.cpp:171:10:171:23 | Load | -| test.cpp:170:26:170:41 | StoreValue | test.cpp:170:26:170:41 | Store | -| test.cpp:170:34:170:41 | & ... | test.cpp:170:34:170:41 | Unary | -| test.cpp:170:34:170:41 | Unary | test.cpp:170:26:170:41 | (void *)... | -| test.cpp:170:35:170:41 | Unary | test.cpp:170:34:170:41 | & ... | -| test.cpp:170:35:170:41 | myLocal | test.cpp:170:35:170:41 | Unary | -| test.cpp:171:10:171:23 | Load | test.cpp:171:10:171:23 | pointerToLocal | -| test.cpp:171:10:171:23 | pointerToLocal | test.cpp:171:10:171:23 | StoreValue | -| test.cpp:176:25:176:34 | Store | test.cpp:177:10:177:23 | Load | -| test.cpp:176:25:176:34 | StoreValue | test.cpp:176:25:176:34 | Store | -| test.cpp:176:25:176:34 | Unary | test.cpp:176:25:176:34 | array to pointer conversion | -| test.cpp:176:25:176:34 | array to pointer conversion | test.cpp:176:25:176:34 | StoreValue | -| test.cpp:176:25:176:34 | localArray | test.cpp:176:25:176:34 | Unary | -| test.cpp:177:10:177:23 | (void *)... | test.cpp:177:10:177:23 | StoreValue | -| test.cpp:177:10:177:23 | Load | test.cpp:177:10:177:23 | pointerToLocal | -| test.cpp:177:10:177:23 | Unary | test.cpp:177:10:177:23 | (void *)... | -| test.cpp:177:10:177:23 | pointerToLocal | test.cpp:177:10:177:23 | Unary | -| test.cpp:182:21:182:27 | (reference to) | test.cpp:182:21:182:27 | StoreValue | -| test.cpp:182:21:182:27 | Store | test.cpp:183:10:183:19 | Load | -| test.cpp:182:21:182:27 | StoreValue | test.cpp:182:21:182:27 | Store | -| test.cpp:182:21:182:27 | Unary | test.cpp:182:21:182:27 | (reference to) | -| test.cpp:182:21:182:27 | myLocal | test.cpp:182:21:182:27 | Unary | -| test.cpp:183:10:183:19 | (reference dereference) | test.cpp:183:10:183:19 | Unary | -| test.cpp:183:10:183:19 | (reference to) | test.cpp:183:10:183:19 | StoreValue | -| test.cpp:183:10:183:19 | Load | test.cpp:183:10:183:19 | refToLocal | -| test.cpp:183:10:183:19 | Unary | test.cpp:183:10:183:19 | (reference dereference) | -| test.cpp:183:10:183:19 | Unary | test.cpp:183:10:183:19 | (reference to) | -| test.cpp:183:10:183:19 | refToLocal | test.cpp:183:10:183:19 | Unary | -| test.cpp:189:16:189:16 | (reference to) | test.cpp:189:16:189:16 | StoreValue | -| test.cpp:189:16:189:16 | Store | test.cpp:190:10:190:13 | Load | -| test.cpp:189:16:189:16 | StoreValue | test.cpp:189:16:189:16 | Store | -| test.cpp:189:16:189:16 | Unary | test.cpp:189:16:189:16 | (reference to) | -| test.cpp:189:16:189:16 | p | test.cpp:189:16:189:16 | Unary | -| test.cpp:190:10:190:13 | (reference dereference) | test.cpp:190:10:190:13 | Unary | -| test.cpp:190:10:190:13 | (reference to) | test.cpp:190:10:190:13 | StoreValue | -| test.cpp:190:10:190:13 | Load | test.cpp:190:10:190:13 | pRef | -| test.cpp:190:10:190:13 | Unary | test.cpp:190:10:190:13 | (reference dereference) | -| test.cpp:190:10:190:13 | Unary | test.cpp:190:10:190:13 | (reference to) | -| test.cpp:190:10:190:13 | pRef | test.cpp:190:10:190:13 | Unary | +| test.cpp:17:10:17:11 | mc | test.cpp:17:9:17:11 | & ... | +| test.cpp:23:17:23:19 | & ... | test.cpp:23:17:23:19 | & ... | +| test.cpp:23:17:23:19 | & ... | test.cpp:25:9:25:11 | ptr | +| test.cpp:23:18:23:19 | mc | test.cpp:23:17:23:19 | & ... | +| test.cpp:39:17:39:18 | (reference to) | test.cpp:39:17:39:18 | (reference to) | +| test.cpp:39:17:39:18 | (reference to) | test.cpp:41:10:41:12 | ref | +| test.cpp:39:17:39:18 | mc | test.cpp:39:17:39:18 | (reference to) | +| test.cpp:41:10:41:12 | (reference dereference) | test.cpp:41:9:41:12 | & ... | +| test.cpp:41:10:41:12 | ref | test.cpp:41:10:41:12 | (reference dereference) | +| test.cpp:47:9:47:10 | mc | test.cpp:47:9:47:10 | (reference to) | +| test.cpp:54:11:54:12 | mc | test.cpp:54:14:54:14 | a | +| test.cpp:54:14:54:14 | a | test.cpp:54:9:54:15 | & ... | +| test.cpp:89:3:89:11 | ... = ... | test.cpp:92:9:92:11 | ptr | +| test.cpp:89:9:89:11 | & ... | test.cpp:89:3:89:11 | ... = ... | +| test.cpp:89:10:89:11 | mc | test.cpp:89:9:89:11 | & ... | +| test.cpp:112:9:112:11 | arr | test.cpp:112:9:112:11 | array to pointer conversion | +| test.cpp:119:11:119:13 | arr | test.cpp:119:11:119:13 | array to pointer conversion | +| test.cpp:119:11:119:13 | array to pointer conversion | test.cpp:119:11:119:17 | access to array | +| test.cpp:119:11:119:17 | access to array | test.cpp:119:9:119:18 | & ... | +| test.cpp:134:2:134:14 | ... = ... | test.cpp:135:2:135:4 | ptr | +| test.cpp:134:8:134:10 | arr | test.cpp:134:8:134:10 | array to pointer conversion | +| test.cpp:134:8:134:10 | array to pointer conversion | test.cpp:134:8:134:14 | ... + ... | +| test.cpp:134:8:134:14 | ... + ... | test.cpp:134:2:134:14 | ... = ... | +| test.cpp:135:2:135:4 | ptr | test.cpp:135:2:135:6 | ... ++ | +| test.cpp:135:2:135:6 | ... ++ | test.cpp:135:2:135:6 | ... ++ | +| test.cpp:135:2:135:6 | ... ++ | test.cpp:137:9:137:11 | ptr | +| test.cpp:170:26:170:41 | (void *)... | test.cpp:170:26:170:41 | (void *)... | +| test.cpp:170:26:170:41 | (void *)... | test.cpp:171:10:171:23 | pointerToLocal | +| test.cpp:170:34:170:41 | & ... | test.cpp:170:26:170:41 | (void *)... | +| test.cpp:170:35:170:41 | myLocal | test.cpp:170:34:170:41 | & ... | +| test.cpp:176:25:176:34 | array to pointer conversion | test.cpp:176:25:176:34 | array to pointer conversion | +| test.cpp:176:25:176:34 | array to pointer conversion | test.cpp:177:10:177:23 | pointerToLocal | +| test.cpp:176:25:176:34 | localArray | test.cpp:176:25:176:34 | array to pointer conversion | +| test.cpp:177:10:177:23 | pointerToLocal | test.cpp:177:10:177:23 | (void *)... | +| test.cpp:182:21:182:27 | (reference to) | test.cpp:182:21:182:27 | (reference to) | +| test.cpp:182:21:182:27 | (reference to) | test.cpp:183:10:183:19 | refToLocal | +| test.cpp:182:21:182:27 | myLocal | test.cpp:182:21:182:27 | (reference to) | +| test.cpp:183:10:183:19 | (reference dereference) | test.cpp:183:10:183:19 | (reference to) | +| test.cpp:183:10:183:19 | refToLocal | test.cpp:183:10:183:19 | (reference dereference) | +| test.cpp:189:16:189:16 | (reference to) | test.cpp:189:16:189:16 | (reference to) | +| test.cpp:189:16:189:16 | (reference to) | test.cpp:190:10:190:13 | pRef | +| test.cpp:189:16:189:16 | p | test.cpp:189:16:189:16 | (reference to) | +| test.cpp:190:10:190:13 | (reference dereference) | test.cpp:190:10:190:13 | (reference to) | +| test.cpp:190:10:190:13 | pRef | test.cpp:190:10:190:13 | (reference dereference) | nodes | test.cpp:17:9:17:11 | & ... | semmle.label | & ... | -| test.cpp:17:9:17:11 | StoreValue | semmle.label | StoreValue | -| test.cpp:17:10:17:11 | Unary | semmle.label | Unary | | test.cpp:17:10:17:11 | mc | semmle.label | mc | | test.cpp:23:17:23:19 | & ... | semmle.label | & ... | -| test.cpp:23:17:23:19 | Store | semmle.label | Store | -| test.cpp:23:17:23:19 | StoreValue | semmle.label | StoreValue | -| test.cpp:23:18:23:19 | Unary | semmle.label | Unary | +| test.cpp:23:17:23:19 | & ... | semmle.label | & ... | | test.cpp:23:18:23:19 | mc | semmle.label | mc | -| test.cpp:25:9:25:11 | Load | semmle.label | Load | -| test.cpp:25:9:25:11 | StoreValue | semmle.label | StoreValue | | test.cpp:25:9:25:11 | ptr | semmle.label | ptr | | test.cpp:39:17:39:18 | (reference to) | semmle.label | (reference to) | -| test.cpp:39:17:39:18 | Store | semmle.label | Store | -| test.cpp:39:17:39:18 | StoreValue | semmle.label | StoreValue | -| test.cpp:39:17:39:18 | Unary | semmle.label | Unary | +| test.cpp:39:17:39:18 | (reference to) | semmle.label | (reference to) | | test.cpp:39:17:39:18 | mc | semmle.label | mc | | test.cpp:41:9:41:12 | & ... | semmle.label | & ... | -| test.cpp:41:9:41:12 | StoreValue | semmle.label | StoreValue | | test.cpp:41:10:41:12 | (reference dereference) | semmle.label | (reference dereference) | -| test.cpp:41:10:41:12 | Load | semmle.label | Load | -| test.cpp:41:10:41:12 | Unary | semmle.label | Unary | -| test.cpp:41:10:41:12 | Unary | semmle.label | Unary | | test.cpp:41:10:41:12 | ref | semmle.label | ref | | test.cpp:47:9:47:10 | (reference to) | semmle.label | (reference to) | -| test.cpp:47:9:47:10 | StoreValue | semmle.label | StoreValue | -| test.cpp:47:9:47:10 | Unary | semmle.label | Unary | | test.cpp:47:9:47:10 | mc | semmle.label | mc | | test.cpp:54:9:54:15 | & ... | semmle.label | & ... | -| test.cpp:54:9:54:15 | StoreValue | semmle.label | StoreValue | -| test.cpp:54:11:54:12 | Unary | semmle.label | Unary | | test.cpp:54:11:54:12 | mc | semmle.label | mc | -| test.cpp:54:14:54:14 | Unary | semmle.label | Unary | | test.cpp:54:14:54:14 | a | semmle.label | a | -| test.cpp:89:3:89:11 | Store | semmle.label | Store | +| test.cpp:89:3:89:11 | ... = ... | semmle.label | ... = ... | | test.cpp:89:9:89:11 | & ... | semmle.label | & ... | -| test.cpp:89:9:89:11 | StoreValue | semmle.label | StoreValue | -| test.cpp:89:10:89:11 | Unary | semmle.label | Unary | | test.cpp:89:10:89:11 | mc | semmle.label | mc | -| test.cpp:92:9:92:11 | Load | semmle.label | Load | -| test.cpp:92:9:92:11 | StoreValue | semmle.label | StoreValue | | test.cpp:92:9:92:11 | ptr | semmle.label | ptr | -| test.cpp:112:9:112:11 | StoreValue | semmle.label | StoreValue | -| test.cpp:112:9:112:11 | Unary | semmle.label | Unary | | test.cpp:112:9:112:11 | arr | semmle.label | arr | | test.cpp:112:9:112:11 | array to pointer conversion | semmle.label | array to pointer conversion | | test.cpp:119:9:119:18 | & ... | semmle.label | & ... | -| test.cpp:119:9:119:18 | StoreValue | semmle.label | StoreValue | -| test.cpp:119:11:119:13 | Left | semmle.label | Left | -| test.cpp:119:11:119:13 | Unary | semmle.label | Unary | | test.cpp:119:11:119:13 | arr | semmle.label | arr | | test.cpp:119:11:119:13 | array to pointer conversion | semmle.label | array to pointer conversion | -| test.cpp:119:11:119:17 | Unary | semmle.label | Unary | | test.cpp:119:11:119:17 | access to array | semmle.label | access to array | -| test.cpp:134:2:134:14 | Store | semmle.label | Store | -| test.cpp:134:8:134:10 | Left | semmle.label | Left | -| test.cpp:134:8:134:10 | Unary | semmle.label | Unary | +| test.cpp:134:2:134:14 | ... = ... | semmle.label | ... = ... | | test.cpp:134:8:134:10 | arr | semmle.label | arr | | test.cpp:134:8:134:10 | array to pointer conversion | semmle.label | array to pointer conversion | | test.cpp:134:8:134:14 | ... + ... | semmle.label | ... + ... | -| test.cpp:134:8:134:14 | StoreValue | semmle.label | StoreValue | -| test.cpp:135:2:135:4 | Left | semmle.label | Left | -| test.cpp:135:2:135:4 | Load | semmle.label | Load | | test.cpp:135:2:135:4 | ptr | semmle.label | ptr | -| test.cpp:135:2:135:6 | PointerAdd | semmle.label | PointerAdd | -| test.cpp:135:2:135:6 | Store | semmle.label | Store | -| test.cpp:135:2:135:6 | StoreValue | semmle.label | StoreValue | -| test.cpp:137:9:137:11 | Load | semmle.label | Load | -| test.cpp:137:9:137:11 | StoreValue | semmle.label | StoreValue | +| test.cpp:135:2:135:6 | ... ++ | semmle.label | ... ++ | +| test.cpp:135:2:135:6 | ... ++ | semmle.label | ... ++ | | test.cpp:137:9:137:11 | ptr | semmle.label | ptr | | test.cpp:170:26:170:41 | (void *)... | semmle.label | (void *)... | -| test.cpp:170:26:170:41 | Store | semmle.label | Store | -| test.cpp:170:26:170:41 | StoreValue | semmle.label | StoreValue | +| test.cpp:170:26:170:41 | (void *)... | semmle.label | (void *)... | | test.cpp:170:34:170:41 | & ... | semmle.label | & ... | -| test.cpp:170:34:170:41 | Unary | semmle.label | Unary | -| test.cpp:170:35:170:41 | Unary | semmle.label | Unary | | test.cpp:170:35:170:41 | myLocal | semmle.label | myLocal | -| test.cpp:171:10:171:23 | Load | semmle.label | Load | -| test.cpp:171:10:171:23 | StoreValue | semmle.label | StoreValue | | test.cpp:171:10:171:23 | pointerToLocal | semmle.label | pointerToLocal | -| test.cpp:176:25:176:34 | Store | semmle.label | Store | -| test.cpp:176:25:176:34 | StoreValue | semmle.label | StoreValue | -| test.cpp:176:25:176:34 | Unary | semmle.label | Unary | +| test.cpp:176:25:176:34 | array to pointer conversion | semmle.label | array to pointer conversion | | test.cpp:176:25:176:34 | array to pointer conversion | semmle.label | array to pointer conversion | | test.cpp:176:25:176:34 | localArray | semmle.label | localArray | | test.cpp:177:10:177:23 | (void *)... | semmle.label | (void *)... | -| test.cpp:177:10:177:23 | Load | semmle.label | Load | -| test.cpp:177:10:177:23 | StoreValue | semmle.label | StoreValue | -| test.cpp:177:10:177:23 | Unary | semmle.label | Unary | | test.cpp:177:10:177:23 | pointerToLocal | semmle.label | pointerToLocal | | test.cpp:182:21:182:27 | (reference to) | semmle.label | (reference to) | -| test.cpp:182:21:182:27 | Store | semmle.label | Store | -| test.cpp:182:21:182:27 | StoreValue | semmle.label | StoreValue | -| test.cpp:182:21:182:27 | Unary | semmle.label | Unary | +| test.cpp:182:21:182:27 | (reference to) | semmle.label | (reference to) | | test.cpp:182:21:182:27 | myLocal | semmle.label | myLocal | | test.cpp:183:10:183:19 | (reference dereference) | semmle.label | (reference dereference) | | test.cpp:183:10:183:19 | (reference to) | semmle.label | (reference to) | -| test.cpp:183:10:183:19 | Load | semmle.label | Load | -| test.cpp:183:10:183:19 | StoreValue | semmle.label | StoreValue | -| test.cpp:183:10:183:19 | Unary | semmle.label | Unary | -| test.cpp:183:10:183:19 | Unary | semmle.label | Unary | | test.cpp:183:10:183:19 | refToLocal | semmle.label | refToLocal | | test.cpp:189:16:189:16 | (reference to) | semmle.label | (reference to) | -| test.cpp:189:16:189:16 | Store | semmle.label | Store | -| test.cpp:189:16:189:16 | StoreValue | semmle.label | StoreValue | -| test.cpp:189:16:189:16 | Unary | semmle.label | Unary | +| test.cpp:189:16:189:16 | (reference to) | semmle.label | (reference to) | | test.cpp:189:16:189:16 | p | semmle.label | p | | test.cpp:190:10:190:13 | (reference dereference) | semmle.label | (reference dereference) | | test.cpp:190:10:190:13 | (reference to) | semmle.label | (reference to) | -| test.cpp:190:10:190:13 | Load | semmle.label | Load | -| test.cpp:190:10:190:13 | StoreValue | semmle.label | StoreValue | -| test.cpp:190:10:190:13 | Unary | semmle.label | Unary | -| test.cpp:190:10:190:13 | Unary | semmle.label | Unary | | test.cpp:190:10:190:13 | pRef | semmle.label | pRef | #select -| test.cpp:17:9:17:11 | StoreValue | test.cpp:17:10:17:11 | mc | test.cpp:17:9:17:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:17:10:17:11 | mc | mc | -| test.cpp:25:9:25:11 | StoreValue | test.cpp:23:18:23:19 | mc | test.cpp:25:9:25:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:23:18:23:19 | mc | mc | -| test.cpp:41:9:41:12 | StoreValue | test.cpp:39:17:39:18 | mc | test.cpp:41:9:41:12 | StoreValue | May return stack-allocated memory from $@. | test.cpp:39:17:39:18 | mc | mc | -| test.cpp:47:9:47:10 | StoreValue | test.cpp:47:9:47:10 | mc | test.cpp:47:9:47:10 | StoreValue | May return stack-allocated memory from $@. | test.cpp:47:9:47:10 | mc | mc | -| test.cpp:54:9:54:15 | StoreValue | test.cpp:54:11:54:12 | mc | test.cpp:54:9:54:15 | StoreValue | May return stack-allocated memory from $@. | test.cpp:54:11:54:12 | mc | mc | -| test.cpp:92:9:92:11 | StoreValue | test.cpp:89:10:89:11 | mc | test.cpp:92:9:92:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:89:10:89:11 | mc | mc | -| test.cpp:112:9:112:11 | StoreValue | test.cpp:112:9:112:11 | arr | test.cpp:112:9:112:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:112:9:112:11 | arr | arr | -| test.cpp:119:9:119:18 | StoreValue | test.cpp:119:11:119:13 | arr | test.cpp:119:9:119:18 | StoreValue | May return stack-allocated memory from $@. | test.cpp:119:11:119:13 | arr | arr | -| test.cpp:137:9:137:11 | StoreValue | test.cpp:134:8:134:10 | arr | test.cpp:137:9:137:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:134:8:134:10 | arr | arr | -| test.cpp:171:10:171:23 | StoreValue | test.cpp:170:35:170:41 | myLocal | test.cpp:171:10:171:23 | StoreValue | May return stack-allocated memory from $@. | test.cpp:170:35:170:41 | myLocal | myLocal | -| test.cpp:177:10:177:23 | StoreValue | test.cpp:176:25:176:34 | localArray | test.cpp:177:10:177:23 | StoreValue | May return stack-allocated memory from $@. | test.cpp:176:25:176:34 | localArray | localArray | -| test.cpp:183:10:183:19 | StoreValue | test.cpp:182:21:182:27 | myLocal | test.cpp:183:10:183:19 | StoreValue | May return stack-allocated memory from $@. | test.cpp:182:21:182:27 | myLocal | myLocal | -| test.cpp:190:10:190:13 | StoreValue | test.cpp:189:16:189:16 | p | test.cpp:190:10:190:13 | StoreValue | May return stack-allocated memory from $@. | test.cpp:189:16:189:16 | p | p | +| test.cpp:17:9:17:11 | CopyValue: & ... | test.cpp:17:10:17:11 | mc | test.cpp:17:9:17:11 | & ... | May return stack-allocated memory from $@. | test.cpp:17:10:17:11 | mc | mc | +| test.cpp:25:9:25:11 | Load: ptr | test.cpp:23:18:23:19 | mc | test.cpp:25:9:25:11 | ptr | May return stack-allocated memory from $@. | test.cpp:23:18:23:19 | mc | mc | +| test.cpp:41:9:41:12 | CopyValue: & ... | test.cpp:39:17:39:18 | mc | test.cpp:41:9:41:12 | & ... | May return stack-allocated memory from $@. | test.cpp:39:17:39:18 | mc | mc | +| test.cpp:47:9:47:10 | CopyValue: (reference to) | test.cpp:47:9:47:10 | mc | test.cpp:47:9:47:10 | (reference to) | May return stack-allocated memory from $@. | test.cpp:47:9:47:10 | mc | mc | +| test.cpp:54:9:54:15 | CopyValue: & ... | test.cpp:54:11:54:12 | mc | test.cpp:54:9:54:15 | & ... | May return stack-allocated memory from $@. | test.cpp:54:11:54:12 | mc | mc | +| test.cpp:92:9:92:11 | Load: ptr | test.cpp:89:10:89:11 | mc | test.cpp:92:9:92:11 | ptr | May return stack-allocated memory from $@. | test.cpp:89:10:89:11 | mc | mc | +| test.cpp:112:9:112:11 | Convert: array to pointer conversion | test.cpp:112:9:112:11 | arr | test.cpp:112:9:112:11 | array to pointer conversion | May return stack-allocated memory from $@. | test.cpp:112:9:112:11 | arr | arr | +| test.cpp:119:9:119:18 | CopyValue: & ... | test.cpp:119:11:119:13 | arr | test.cpp:119:9:119:18 | & ... | May return stack-allocated memory from $@. | test.cpp:119:11:119:13 | arr | arr | +| test.cpp:137:9:137:11 | Load: ptr | test.cpp:134:8:134:10 | arr | test.cpp:137:9:137:11 | ptr | May return stack-allocated memory from $@. | test.cpp:134:8:134:10 | arr | arr | +| test.cpp:171:10:171:23 | Load: pointerToLocal | test.cpp:170:35:170:41 | myLocal | test.cpp:171:10:171:23 | pointerToLocal | May return stack-allocated memory from $@. | test.cpp:170:35:170:41 | myLocal | myLocal | +| test.cpp:177:10:177:23 | Convert: (void *)... | test.cpp:176:25:176:34 | localArray | test.cpp:177:10:177:23 | (void *)... | May return stack-allocated memory from $@. | test.cpp:176:25:176:34 | localArray | localArray | +| test.cpp:183:10:183:19 | CopyValue: (reference to) | test.cpp:182:21:182:27 | myLocal | test.cpp:183:10:183:19 | (reference to) | May return stack-allocated memory from $@. | test.cpp:182:21:182:27 | myLocal | myLocal | +| test.cpp:190:10:190:13 | CopyValue: (reference to) | test.cpp:189:16:189:16 | p | test.cpp:190:10:190:13 | (reference to) | May return stack-allocated memory from $@. | test.cpp:189:16:189:16 | p | p | From 4478ac2c17fe7d2ab8fc8bfc7f1a6c34557267aa Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 16 Nov 2022 15:19:53 +0000 Subject: [PATCH 392/796] C++: Add change note. --- cpp/ql/lib/change-notes/2022-11-16-must-flow.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2022-11-16-must-flow.md diff --git a/cpp/ql/lib/change-notes/2022-11-16-must-flow.md b/cpp/ql/lib/change-notes/2022-11-16-must-flow.md new file mode 100644 index 00000000000..bdb17d671a3 --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-11-16-must-flow.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +The predicates in the `MustFlow::Configuration` class used by the `MustFlow` library (`semmle.code.cpp.ir.dataflow.MustFlow`) has changed to be defined directly in terms of the C++ IR instead of IR dataflow nodes. From aaa96b20ed9637998a45db01f8a3c8e5706b4bfd Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 18 Nov 2022 17:51:20 +0100 Subject: [PATCH 393/796] Swift: fix python compatibility with CI --- swift/codegen/test/utils.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/swift/codegen/test/utils.py b/swift/codegen/test/utils.py index 2678190c9f8..3911206bfa5 100644 --- a/swift/codegen/test/utils.py +++ b/swift/codegen/test/utils.py @@ -39,9 +39,8 @@ def opts(): @pytest.fixture(autouse=True) def override_paths(tmp_path): - with (mock.patch("swift.codegen.lib.paths.swift_dir", tmp_path), - mock.patch("swift.codegen.lib.paths.exe_file", tmp_path / "exe"), - ): + with mock.patch("swift.codegen.lib.paths.swift_dir", tmp_path), \ + mock.patch("swift.codegen.lib.paths.exe_file", tmp_path / "exe"): yield From a97570be6364c939c39bf80306149b936aea5ad0 Mon Sep 17 00:00:00 2001 From: sigfaulterror <95027071+sigfaulterror@users.noreply.github.com> Date: Fri, 18 Nov 2022 18:54:03 +0100 Subject: [PATCH 394/796] Update analyzing-databases-with-the-codeql-cli.rst just small doc error --- .../codeql-cli/analyzing-databases-with-the-codeql-cli.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst index 72fb979c563..bc9924b740a 100644 --- a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst +++ b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst @@ -312,7 +312,7 @@ For more information, see "`Using CodeQL query packs in the CodeQL action Date: Fri, 18 Nov 2022 15:57:46 -0800 Subject: [PATCH 395/796] Suggestions from code review --- .../adaptivethreatmodeling/EndpointCharacteristics.qll | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index 5218f65b337..0f899d795d9 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -552,8 +552,7 @@ private class InIrrelevantFileCharacteristic extends StandardEndpointFilterChara override predicate getEndpoints(DataFlow::Node n) { // Ignore candidate sinks within externs, generated, library, and test code - ClassifyFiles::classify(n.getFile(), category) and - this = "in " + category + " file" + ClassifyFiles::classify(n.getFile(), category) } } @@ -575,10 +574,9 @@ private class DatabaseAccessCallHeuristicCharacteristic extends NosqlInjectionSi DatabaseAccessCallHeuristicCharacteristic() { this = "matches database access call heuristic" } override predicate getEndpoints(DataFlow::Node n) { - exists(DataFlow::CallNode call | n = call.getAnArgument() | + exists(DataFlow::MethodCallNode call | n = call.getAnArgument() | // additional databases accesses that aren't modeled yet - call.(DataFlow::MethodCallNode).getMethodName() = - ["create", "createCollection", "createIndexes"] + call.getMethodName() = ["create", "createCollection", "createIndexes"] ) } } From 41e8170d596bc92bd42bfa02986586caa9a8cfbb Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Sat, 19 Nov 2022 11:16:24 +0100 Subject: [PATCH 396/796] delete the rest of the qlcompile job in Ruby --- .github/workflows/ruby-qltest.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/ruby-qltest.yml b/.github/workflows/ruby-qltest.yml index 056543a237b..e3ede23479a 100644 --- a/.github/workflows/ruby-qltest.yml +++ b/.github/workflows/ruby-qltest.yml @@ -28,11 +28,6 @@ defaults: working-directory: ruby jobs: - qlcompile: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: ./.github/actions/fetch-codeql qlupgrade: runs-on: ubuntu-latest steps: From 1dbcf8eb10599dcadbcd1eccde2c5107d98fa3ee Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Sun, 20 Nov 2022 10:16:35 +0100 Subject: [PATCH 397/796] Ruby: Add `--check-undefined-labels` to QL test job --- .github/workflows/ruby-qltest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ruby-qltest.yml b/.github/workflows/ruby-qltest.yml index 125e2694fb0..73f8cecd1ab 100644 --- a/.github/workflows/ruby-qltest.yml +++ b/.github/workflows/ruby-qltest.yml @@ -69,6 +69,6 @@ jobs: - uses: ./ruby/actions/create-extractor-pack - name: Run QL tests run: | - codeql test run --threads=0 --ram 5000 --slice ${{ matrix.slice }} --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test + codeql test run --threads=0 --ram 5000 --slice ${{ matrix.slice }} --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test env: GITHUB_TOKEN: ${{ github.token }} From ca17c5b053e018034d817b0b1fcc51fb46683cb1 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 2 Nov 2022 15:08:28 +0100 Subject: [PATCH 398/796] Data flow: Add summary context to pruning stages 2-4 --- .../ruby/dataflow/internal/DataFlowImpl.qll | 240 +++++++++--------- .../dataflow/internal/DataFlowImplCommon.qll | 18 ++ 2 files changed, 144 insertions(+), 114 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index 3c41b1876dc..840a0a46796 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,21 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, Configuration config) { + throughFlowNodeCand(ret, config) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1156,7 +1169,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1252,8 +1267,7 @@ private module MkStage { ) { flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pragma[only_bind_into](config)) and matchesCall(ccc, call) } @@ -1262,29 +1276,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1312,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1390,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1398,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,13 +1421,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and @@ -1413,12 +1438,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, ret.getKind()) ) } @@ -1428,11 +1455,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,45 +1469,38 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + parameterFlowThroughAllowed(p, ret.getKind()) + } + + predicate returnMayFlowThrough(RetNodeEx ret, Configuration config) { + returnFlowsThrough(ret, _, _, _, _, _, config) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** @@ -1494,14 +1516,14 @@ private module MkStage { NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and returnAp = apNone() and @@ -1513,7 +1535,7 @@ private module MkStage { ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil @@ -1527,7 +1549,7 @@ private module MkStage { ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and toReturn = false and @@ -1536,7 +1558,7 @@ private module MkStage { ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and @@ -1561,6 +1583,7 @@ private module MkStage { revFlowInNotToReturn(node, state, returnAp, ap, config) and toReturn = false or + // flow through a callable exists(DataFlowCall call, Ap returnAp0 | revFlowInToReturn(call, node, state, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) @@ -1569,7 +1592,7 @@ private module MkStage { // flow out of a callable revFlowOut(_, node, state, _, _, ap, config) and toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) + if returnFlowsThrough(node, state, _, _, _, ap, config) then returnAp = apSome(ap) else returnAp = apNone() } @@ -1642,7 +1665,7 @@ private module MkStage { ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + returnFlowsThrough(ret, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1721,21 +1744,15 @@ private module MkStage { c = p.getEnclosingCallable() } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, RetNodeEx ret, FlowState state, Ap ap0, ParameterPosition pos | parameterFlow(p, ap, ap0, c, config) and c = ret.getEnclosingCallable() and revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and + returnFlowsThrough(ret, state, _, p.asNode(), ap, ap0, config) and p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), ret.getKind()) ) } @@ -1754,13 +1771,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -2021,8 +2038,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2234,7 +2251,8 @@ private predicate flowCandSummaryCtx( ) { exists(AccessPathFront apf | Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2508,13 +2526,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and + Stage4::parameterMayFlowThrough(p, _, _) and Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2540,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2550,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3471,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll index ae9c6f3f12e..9923fd955a8 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll @@ -915,6 +915,11 @@ private module Cached { TDataFlowCallNone() or TDataFlowCallSome(DataFlowCall call) + cached + newtype TParamNodeOption = + TParamNodeNone() or + TParamNodeSome(ParamNode p) + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1304,6 +1309,19 @@ class DataFlowCallOption extends TDataFlowCallOption { } } +/** An optional `ParamNode`. */ +class ParamNodeOption extends TParamNodeOption { + string toString() { + this = TParamNodeNone() and + result = "(none)" + or + exists(ParamNode p | + this = TParamNodeSome(p) and + result = p.toString() + ) + } +} + /** A `Content` tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; From 5adf10fcbab0969d74cd3f36fc2d9e90a179b996 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 2 Nov 2022 20:49:39 +0100 Subject: [PATCH 399/796] Data flow: Add return context to pruning stages 2-4 --- .../ruby/dataflow/internal/DataFlowImpl.qll | 128 ++++++++++-------- .../dataflow/internal/DataFlowImplCommon.qll | 31 +++++ 2 files changed, 102 insertions(+), 57 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index 840a0a46796..8ee4677fc96 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -1489,10 +1489,6 @@ private module MkStage { parameterFlowThroughAllowed(p, ret.getKind()) } - predicate returnMayFlowThrough(RetNodeEx ret, Configuration config) { - returnFlowsThrough(ret, _, _, _, _, _, config) - } - pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config @@ -1507,44 +1503,50 @@ private module MkStage { * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and + revFlow0(node, state, returnCtx, returnAp, ap, config) and fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or @@ -1552,7 +1554,7 @@ private module MkStage { fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) @@ -1562,47 +1564,50 @@ private module MkStage { additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or // flow through a callable - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and if returnFlowsThrough(node, state, _, _, _, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + then ( + returnCtx = TReturnCtxMaybeFlowThrough(node.(RetNodeEx).getReturnPosition()) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1622,11 +1627,11 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1637,7 +1642,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1645,12 +1650,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1661,11 +1668,13 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and + revFlowOut(call, ret, state, returnCtx, returnAp, ap, config) and returnFlowsThrough(ret, state, ccc, _, _, ap, config) and + pos = ret.getReturnPosition() and matchesCall(ccc, call) ) } @@ -1736,34 +1745,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } + pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(DataFlowCallable c, RetNodeEx ret, FlowState state, Ap ap0, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - returnFlowsThrough(ret, state, _, p.asNode(), ap, ap0, config) and - p.getPosition() = pos and - parameterFlowThroughAllowed(p.asNode(), ret.getKind()) + exists(RetNodeEx ret | + returnFlowsThrough(ret, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, ret.getReturnPosition(), config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, ret.getReturnPosition(), config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1786,8 +1800,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -2250,7 +2264,7 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, config) ) @@ -2530,7 +2544,7 @@ private predicate nodeMayUseSummary0( ) { exists(AccessPathApprox apa0 | Stage4::parameterMayFlowThrough(p, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), TAccessPathApproxSome(apa), apa0, config) ) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll index 9923fd955a8..621ed34f9d0 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll @@ -920,6 +920,12 @@ private module Cached { TParamNodeNone() or TParamNodeSome(ParamNode p) + cached + newtype TReturnCtx = + TReturnCtxNone() or + TReturnCtxNoFlowThrough() or + TReturnCtxMaybeFlowThrough(ReturnPosition pos) + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1322,6 +1328,31 @@ class ParamNodeOption extends TParamNodeOption { } } +/** + * A return context used to calculate flow summaries in reverse flow. + * + * The possible values are: + * + * - `TReturnCtxNone()`: no return flow. + * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. + * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * flow through may be possible. + */ +class ReturnCtx extends TReturnCtx { + string toString() { + this = TReturnCtxNone() and + result = "(none)" + or + this = TReturnCtxNoFlowThrough() and + result = "(no flow through)" + or + exists(ReturnPosition pos | + this = TReturnCtxMaybeFlowThrough(pos) and + result = pos.toString() + ) + } +} + /** A `Content` tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; From a3a3b46d54695a1164cf369327857b08b6ad79cc Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 7 Nov 2022 11:55:33 +0100 Subject: [PATCH 400/796] Data flow: Account for return nodes with multiple return kinds when restricting flow through For example, flow out via parameters allows for return nodes with multiple return kinds: ```csharp void SetXOrY(C x, C y, bool b) { C c = x; if (b) c = y; c.Field = taint; // post-update node for `c` has two return kinds } ``` --- .../ruby/dataflow/internal/DataFlowImpl.qll | 114 ++++++++++-------- 1 file changed, 63 insertions(+), 51 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index 8ee4677fc96..a52ad110662 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -1005,8 +1005,9 @@ private module Stage1 implements StageSig { } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, Configuration config) { - throughFlowNodeCand(ret, config) + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() } pragma[nomagic] @@ -1065,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1103,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1115,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1128,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1171,7 +1174,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1237,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1262,13 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1429,7 +1436,7 @@ private module MkStage { DataFlowCallable inner | fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1441,11 +1448,11 @@ private module MkStage { DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, ret.getKind()) + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1483,10 +1490,12 @@ private module MkStage { pragma[nomagic] private predicate returnFlowsThrough( - RetNodeEx ret, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, Configuration config + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config ) { fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - parameterFlowThroughAllowed(p, ret.getKind()) + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] @@ -1496,7 +1505,7 @@ private module MkStage { flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, pragma[only_bind_into](config)) and fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** @@ -1592,13 +1601,15 @@ private module MkStage { ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - if returnFlowsThrough(node, state, _, _, _, ap, config) - then ( - returnCtx = TReturnCtxMaybeFlowThrough(node.(RetNodeEx).getReturnPosition()) and - returnAp = apSome(ap) - ) else ( - returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) ) } @@ -1627,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, ReturnCtx returnCtx, ApOption returnAp, - Ap ap, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1672,9 +1683,8 @@ private module MkStage { Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, state, ccc, _, _, ap, config) and - pos = ret.getReturnPosition() and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1755,17 +1765,17 @@ private module MkStage { pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret | - returnFlowsThrough(ret, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, ret.getReturnPosition(), config) + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, ret.getReturnPosition(), config) + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } @@ -1946,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1982,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2053,7 +2064,7 @@ private module LocalFlowBigStep { jumpStep(node, next, config) or additionalJumpStep(node, next, config) or flowIntoCallNodeCand2(_, node, next, _, config) or - flowOutOfCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2194,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2500,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) From 99e70e9a50fdf85f151af20d1ef78f448029beb3 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 2 Nov 2022 21:03:05 +0100 Subject: [PATCH 401/796] Data flow: Sync files --- .../cpp/ir/dataflow/internal/DataFlowImpl.qll | 416 ++++++++++-------- .../ir/dataflow/internal/DataFlowImpl2.qll | 416 ++++++++++-------- .../ir/dataflow/internal/DataFlowImpl3.qll | 416 ++++++++++-------- .../ir/dataflow/internal/DataFlowImpl4.qll | 416 ++++++++++-------- .../dataflow/internal/DataFlowImplCommon.qll | 49 +++ .../cpp/dataflow/internal/DataFlowImpl.qll | 416 ++++++++++-------- .../cpp/dataflow/internal/DataFlowImpl2.qll | 416 ++++++++++-------- .../cpp/dataflow/internal/DataFlowImpl3.qll | 416 ++++++++++-------- .../cpp/dataflow/internal/DataFlowImpl4.qll | 416 ++++++++++-------- .../dataflow/internal/DataFlowImplCommon.qll | 49 +++ .../dataflow/internal/DataFlowImplLocal.qll | 416 ++++++++++-------- .../cpp/ir/dataflow/internal/DataFlowImpl.qll | 416 ++++++++++-------- .../ir/dataflow/internal/DataFlowImpl2.qll | 416 ++++++++++-------- .../ir/dataflow/internal/DataFlowImpl3.qll | 416 ++++++++++-------- .../ir/dataflow/internal/DataFlowImpl4.qll | 416 ++++++++++-------- .../dataflow/internal/DataFlowImplCommon.qll | 49 +++ .../csharp/dataflow/internal/DataFlowImpl.qll | 416 ++++++++++-------- .../dataflow/internal/DataFlowImpl2.qll | 416 ++++++++++-------- .../dataflow/internal/DataFlowImpl3.qll | 416 ++++++++++-------- .../dataflow/internal/DataFlowImpl4.qll | 416 ++++++++++-------- .../dataflow/internal/DataFlowImpl5.qll | 416 ++++++++++-------- .../dataflow/internal/DataFlowImplCommon.qll | 49 +++ .../DataFlowImplForContentDataFlow.qll | 416 ++++++++++-------- .../java/dataflow/internal/DataFlowImpl.qll | 416 ++++++++++-------- .../java/dataflow/internal/DataFlowImpl2.qll | 416 ++++++++++-------- .../java/dataflow/internal/DataFlowImpl3.qll | 416 ++++++++++-------- .../java/dataflow/internal/DataFlowImpl4.qll | 416 ++++++++++-------- .../java/dataflow/internal/DataFlowImpl5.qll | 416 ++++++++++-------- .../java/dataflow/internal/DataFlowImpl6.qll | 416 ++++++++++-------- .../dataflow/internal/DataFlowImplCommon.qll | 49 +++ .../DataFlowImplForOnActivityResult.qll | 416 ++++++++++-------- .../DataFlowImplForSerializability.qll | 416 ++++++++++-------- .../dataflow/new/internal/DataFlowImpl.qll | 416 ++++++++++-------- .../dataflow/new/internal/DataFlowImpl2.qll | 416 ++++++++++-------- .../dataflow/new/internal/DataFlowImpl3.qll | 416 ++++++++++-------- .../dataflow/new/internal/DataFlowImpl4.qll | 416 ++++++++++-------- .../new/internal/DataFlowImplCommon.qll | 49 +++ .../ruby/dataflow/internal/DataFlowImpl2.qll | 416 ++++++++++-------- .../DataFlowImplForHttpClientLibraries.qll | 416 ++++++++++-------- .../internal/DataFlowImplForPathname.qll | 416 ++++++++++-------- .../internal/DataFlowImplForRegExp.qll | 416 ++++++++++-------- .../swift/dataflow/internal/DataFlowImpl.qll | 416 ++++++++++-------- .../dataflow/internal/DataFlowImplCommon.qll | 49 +++ 43 files changed, 8515 insertions(+), 6804 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 3c41b1876dc..a52ad110662 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index 3c41b1876dc..a52ad110662 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index 3c41b1876dc..a52ad110662 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index 3c41b1876dc..a52ad110662 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll index ae9c6f3f12e..621ed34f9d0 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll @@ -915,6 +915,17 @@ private module Cached { TDataFlowCallNone() or TDataFlowCallSome(DataFlowCall call) + cached + newtype TParamNodeOption = + TParamNodeNone() or + TParamNodeSome(ParamNode p) + + cached + newtype TReturnCtx = + TReturnCtxNone() or + TReturnCtxNoFlowThrough() or + TReturnCtxMaybeFlowThrough(ReturnPosition pos) + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1304,6 +1315,44 @@ class DataFlowCallOption extends TDataFlowCallOption { } } +/** An optional `ParamNode`. */ +class ParamNodeOption extends TParamNodeOption { + string toString() { + this = TParamNodeNone() and + result = "(none)" + or + exists(ParamNode p | + this = TParamNodeSome(p) and + result = p.toString() + ) + } +} + +/** + * A return context used to calculate flow summaries in reverse flow. + * + * The possible values are: + * + * - `TReturnCtxNone()`: no return flow. + * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. + * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * flow through may be possible. + */ +class ReturnCtx extends TReturnCtx { + string toString() { + this = TReturnCtxNone() and + result = "(none)" + or + this = TReturnCtxNoFlowThrough() and + result = "(no flow through)" + or + exists(ReturnPosition pos | + this = TReturnCtxMaybeFlowThrough(pos) and + result = pos.toString() + ) + } +} + /** A `Content` tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index 3c41b1876dc..a52ad110662 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index 3c41b1876dc..a52ad110662 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index 3c41b1876dc..a52ad110662 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index 3c41b1876dc..a52ad110662 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll index ae9c6f3f12e..621ed34f9d0 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll @@ -915,6 +915,17 @@ private module Cached { TDataFlowCallNone() or TDataFlowCallSome(DataFlowCall call) + cached + newtype TParamNodeOption = + TParamNodeNone() or + TParamNodeSome(ParamNode p) + + cached + newtype TReturnCtx = + TReturnCtxNone() or + TReturnCtxNoFlowThrough() or + TReturnCtxMaybeFlowThrough(ReturnPosition pos) + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1304,6 +1315,44 @@ class DataFlowCallOption extends TDataFlowCallOption { } } +/** An optional `ParamNode`. */ +class ParamNodeOption extends TParamNodeOption { + string toString() { + this = TParamNodeNone() and + result = "(none)" + or + exists(ParamNode p | + this = TParamNodeSome(p) and + result = p.toString() + ) + } +} + +/** + * A return context used to calculate flow summaries in reverse flow. + * + * The possible values are: + * + * - `TReturnCtxNone()`: no return flow. + * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. + * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * flow through may be possible. + */ +class ReturnCtx extends TReturnCtx { + string toString() { + this = TReturnCtxNone() and + result = "(none)" + or + this = TReturnCtxNoFlowThrough() and + result = "(no flow through)" + or + exists(ReturnPosition pos | + this = TReturnCtxMaybeFlowThrough(pos) and + result = pos.toString() + ) + } +} + /** A `Content` tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index 3c41b1876dc..a52ad110662 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 3c41b1876dc..a52ad110662 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index 3c41b1876dc..a52ad110662 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index 3c41b1876dc..a52ad110662 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index 3c41b1876dc..a52ad110662 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll index ae9c6f3f12e..621ed34f9d0 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll @@ -915,6 +915,17 @@ private module Cached { TDataFlowCallNone() or TDataFlowCallSome(DataFlowCall call) + cached + newtype TParamNodeOption = + TParamNodeNone() or + TParamNodeSome(ParamNode p) + + cached + newtype TReturnCtx = + TReturnCtxNone() or + TReturnCtxNoFlowThrough() or + TReturnCtxMaybeFlowThrough(ReturnPosition pos) + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1304,6 +1315,44 @@ class DataFlowCallOption extends TDataFlowCallOption { } } +/** An optional `ParamNode`. */ +class ParamNodeOption extends TParamNodeOption { + string toString() { + this = TParamNodeNone() and + result = "(none)" + or + exists(ParamNode p | + this = TParamNodeSome(p) and + result = p.toString() + ) + } +} + +/** + * A return context used to calculate flow summaries in reverse flow. + * + * The possible values are: + * + * - `TReturnCtxNone()`: no return flow. + * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. + * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * flow through may be possible. + */ +class ReturnCtx extends TReturnCtx { + string toString() { + this = TReturnCtxNone() and + result = "(none)" + or + this = TReturnCtxNoFlowThrough() and + result = "(no flow through)" + or + exists(ReturnPosition pos | + this = TReturnCtxMaybeFlowThrough(pos) and + result = pos.toString() + ) + } +} + /** A `Content` tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index 3c41b1876dc..a52ad110662 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index 3c41b1876dc..a52ad110662 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index 3c41b1876dc..a52ad110662 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index 3c41b1876dc..a52ad110662 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index 3c41b1876dc..a52ad110662 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll index ae9c6f3f12e..621ed34f9d0 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll @@ -915,6 +915,17 @@ private module Cached { TDataFlowCallNone() or TDataFlowCallSome(DataFlowCall call) + cached + newtype TParamNodeOption = + TParamNodeNone() or + TParamNodeSome(ParamNode p) + + cached + newtype TReturnCtx = + TReturnCtxNone() or + TReturnCtxNoFlowThrough() or + TReturnCtxMaybeFlowThrough(ReturnPosition pos) + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1304,6 +1315,44 @@ class DataFlowCallOption extends TDataFlowCallOption { } } +/** An optional `ParamNode`. */ +class ParamNodeOption extends TParamNodeOption { + string toString() { + this = TParamNodeNone() and + result = "(none)" + or + exists(ParamNode p | + this = TParamNodeSome(p) and + result = p.toString() + ) + } +} + +/** + * A return context used to calculate flow summaries in reverse flow. + * + * The possible values are: + * + * - `TReturnCtxNone()`: no return flow. + * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. + * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * flow through may be possible. + */ +class ReturnCtx extends TReturnCtx { + string toString() { + this = TReturnCtxNone() and + result = "(none)" + or + this = TReturnCtxNoFlowThrough() and + result = "(no flow through)" + or + exists(ReturnPosition pos | + this = TReturnCtxMaybeFlowThrough(pos) and + result = pos.toString() + ) + } +} + /** A `Content` tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll index 3c41b1876dc..a52ad110662 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index 3c41b1876dc..a52ad110662 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index 3c41b1876dc..a52ad110662 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index 3c41b1876dc..a52ad110662 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index 3c41b1876dc..a52ad110662 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index 3c41b1876dc..a52ad110662 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index 3c41b1876dc..a52ad110662 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll index ae9c6f3f12e..621ed34f9d0 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll @@ -915,6 +915,17 @@ private module Cached { TDataFlowCallNone() or TDataFlowCallSome(DataFlowCall call) + cached + newtype TParamNodeOption = + TParamNodeNone() or + TParamNodeSome(ParamNode p) + + cached + newtype TReturnCtx = + TReturnCtxNone() or + TReturnCtxNoFlowThrough() or + TReturnCtxMaybeFlowThrough(ReturnPosition pos) + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1304,6 +1315,44 @@ class DataFlowCallOption extends TDataFlowCallOption { } } +/** An optional `ParamNode`. */ +class ParamNodeOption extends TParamNodeOption { + string toString() { + this = TParamNodeNone() and + result = "(none)" + or + exists(ParamNode p | + this = TParamNodeSome(p) and + result = p.toString() + ) + } +} + +/** + * A return context used to calculate flow summaries in reverse flow. + * + * The possible values are: + * + * - `TReturnCtxNone()`: no return flow. + * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. + * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * flow through may be possible. + */ +class ReturnCtx extends TReturnCtx { + string toString() { + this = TReturnCtxNone() and + result = "(none)" + or + this = TReturnCtxNoFlowThrough() and + result = "(no flow through)" + or + exists(ReturnPosition pos | + this = TReturnCtxMaybeFlowThrough(pos) and + result = pos.toString() + ) + } +} + /** A `Content` tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll index 3c41b1876dc..a52ad110662 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll index 3c41b1876dc..a52ad110662 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll index 3c41b1876dc..a52ad110662 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll index 3c41b1876dc..a52ad110662 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll index 3c41b1876dc..a52ad110662 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll index 3c41b1876dc..a52ad110662 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll index ae9c6f3f12e..621ed34f9d0 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll @@ -915,6 +915,17 @@ private module Cached { TDataFlowCallNone() or TDataFlowCallSome(DataFlowCall call) + cached + newtype TParamNodeOption = + TParamNodeNone() or + TParamNodeSome(ParamNode p) + + cached + newtype TReturnCtx = + TReturnCtxNone() or + TReturnCtxNoFlowThrough() or + TReturnCtxMaybeFlowThrough(ReturnPosition pos) + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1304,6 +1315,44 @@ class DataFlowCallOption extends TDataFlowCallOption { } } +/** An optional `ParamNode`. */ +class ParamNodeOption extends TParamNodeOption { + string toString() { + this = TParamNodeNone() and + result = "(none)" + or + exists(ParamNode p | + this = TParamNodeSome(p) and + result = p.toString() + ) + } +} + +/** + * A return context used to calculate flow summaries in reverse flow. + * + * The possible values are: + * + * - `TReturnCtxNone()`: no return flow. + * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. + * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * flow through may be possible. + */ +class ReturnCtx extends TReturnCtx { + string toString() { + this = TReturnCtxNone() and + result = "(none)" + or + this = TReturnCtxNoFlowThrough() and + result = "(no flow through)" + or + exists(ReturnPosition pos | + this = TReturnCtxMaybeFlowThrough(pos) and + result = pos.toString() + ) + } +} + /** A `Content` tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll index 3c41b1876dc..a52ad110662 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll index 3c41b1876dc..a52ad110662 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll index 3c41b1876dc..a52ad110662 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll index 3c41b1876dc..a52ad110662 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index 3c41b1876dc..a52ad110662 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,21 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +994,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p.asNode(), kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + throughFlowNodeCand(ret, config) and + pos = ret.getReturnPosition() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and Stage1::revFlow(ret, config) and not outBarrier(ret, config) and not inBarrier(out, config) @@ -1090,7 +1105,7 @@ private predicate flowIntoCallNodeCand1( private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1102,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) { private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1172,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1240,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1266,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnPosition pos | + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and + kind = pos.getKind() and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1262,29 +1283,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParamNodeNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1319,72 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1397,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1405,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1397,14 +1428,15 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, DataFlowCallable inner | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and inner = ret.getEnclosingCallable() and ccOut = getCallContextReturn(inner, call, innercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1413,12 +1445,14 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(summaryCtx, kind) ) } @@ -1428,11 +1462,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, + Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + p = param.asNode() ) } @@ -1440,146 +1476,149 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, + Configuration config + ) { + fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + returnCtx = TReturnCtxNone() or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,12 +1638,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1614,7 +1653,7 @@ private module MkStage { ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and flowIntoCall(_, arg, p, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1622,12 +1661,14 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, + Ap ap, Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) ) } @@ -1638,11 +1679,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1755,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and + parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) ) } @@ -1754,13 +1795,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1769,8 +1810,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1956,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +1992,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2063,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2205,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2275,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2511,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2552,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage4::parameterMayFlowThrough(p, _, _) and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2566,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2532,7 +2576,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3497,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) ) } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll index ae9c6f3f12e..621ed34f9d0 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll @@ -915,6 +915,17 @@ private module Cached { TDataFlowCallNone() or TDataFlowCallSome(DataFlowCall call) + cached + newtype TParamNodeOption = + TParamNodeNone() or + TParamNodeSome(ParamNode p) + + cached + newtype TReturnCtx = + TReturnCtxNone() or + TReturnCtxNoFlowThrough() or + TReturnCtxMaybeFlowThrough(ReturnPosition pos) + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1304,6 +1315,44 @@ class DataFlowCallOption extends TDataFlowCallOption { } } +/** An optional `ParamNode`. */ +class ParamNodeOption extends TParamNodeOption { + string toString() { + this = TParamNodeNone() and + result = "(none)" + or + exists(ParamNode p | + this = TParamNodeSome(p) and + result = p.toString() + ) + } +} + +/** + * A return context used to calculate flow summaries in reverse flow. + * + * The possible values are: + * + * - `TReturnCtxNone()`: no return flow. + * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. + * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * flow through may be possible. + */ +class ReturnCtx extends TReturnCtx { + string toString() { + this = TReturnCtxNone() and + result = "(none)" + or + this = TReturnCtxNoFlowThrough() and + result = "(no flow through)" + or + exists(ReturnPosition pos | + this = TReturnCtxMaybeFlowThrough(pos) and + result = pos.toString() + ) + } +} + /** A `Content` tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; From 26866a733785cf9f8a10adcb0cb7e3bbdbba420e Mon Sep 17 00:00:00 2001 From: Anders Fugmann Date: Mon, 21 Nov 2022 09:58:12 +0100 Subject: [PATCH 402/796] Swift: set @github/codeql-swift as owner --- CODEOWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 86f38eeee22..55ee2f974f7 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -5,7 +5,7 @@ /javascript/ @github/codeql-javascript /python/ @github/codeql-python /ruby/ @github/codeql-ruby -/swift/ @github/codeql-c +/swift/ @github/codeql-swift /java/kotlin-extractor/ @github/codeql-kotlin /java/kotlin-explorer/ @github/codeql-kotlin @@ -45,4 +45,4 @@ WORKSPACE.bazel @github/codeql-ci-reviewers /.github/workflows/js-ml-tests.yml @github/codeql-ml-powered-queries-reviewers /.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers /.github/workflows/ruby-* @github/codeql-ruby -/.github/workflows/swift.yml @github/codeql-c +/.github/workflows/swift.yml @github/codeql-swift From 2809c3a77cf4dbd64b824d78d0620ba85cb62ccc Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Mon, 21 Nov 2022 10:11:57 +0100 Subject: [PATCH 403/796] Handle disabled Maven repositories --- java/ql/lib/semmle/code/xml/MavenPom.qll | 9 +++++++++ .../CWE/CWE-829/InsecureDependencyResolution.ql | 3 ++- .../security/CWE-829/semmle/tests/secure-pom.xml | 12 ++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/xml/MavenPom.qll b/java/ql/lib/semmle/code/xml/MavenPom.qll index 8af6e6f0128..612c1468259 100644 --- a/java/ql/lib/semmle/code/xml/MavenPom.qll +++ b/java/ql/lib/semmle/code/xml/MavenPom.qll @@ -381,6 +381,15 @@ class DeclaredRepository extends PomElement { * be the string contents of that tag. */ string getRepositoryUrl() { result = this.getAChild("url").(PomElement).getValue() } + + /** + * Holds if this repository is disabled in both the `releases` and `snapshots` policies. + */ + predicate isDisabled() { + forex(PomElement policy | policy = this.getAChild(["releases", "snapshots"]) | + policy.getAChild("enabled").(PomElement).getValue() = "false" + ) + } } /** diff --git a/java/ql/src/Security/CWE/CWE-829/InsecureDependencyResolution.ql b/java/ql/src/Security/CWE/CWE-829/InsecureDependencyResolution.ql index ede03c50b00..dca1a9cc4b7 100644 --- a/java/ql/src/Security/CWE/CWE-829/InsecureDependencyResolution.ql +++ b/java/ql/src/Security/CWE/CWE-829/InsecureDependencyResolution.ql @@ -17,7 +17,8 @@ import java import semmle.code.xml.MavenPom predicate isInsecureRepositoryUsage(DeclaredRepository repository) { - repository.getRepositoryUrl().regexpMatch("(?i)^(http|ftp)://(?!localhost[:/]).*") + repository.getRepositoryUrl().regexpMatch("(?i)^(http|ftp)://(?!localhost[:/]).*") and + not repository.isDisabled() } from DeclaredRepository repository diff --git a/java/ql/test/query-tests/security/CWE-829/semmle/tests/secure-pom.xml b/java/ql/test/query-tests/security/CWE-829/semmle/tests/secure-pom.xml index 2f96052d584..2dc5709b320 100644 --- a/java/ql/test/query-tests/security/CWE-829/semmle/tests/secure-pom.xml +++ b/java/ql/test/query-tests/security/CWE-829/semmle/tests/secure-pom.xml @@ -61,5 +61,17 @@ https://insecure-repository.example + + disabled-repo + Disabled Repository + + false + + + false + + + http://insecure-repository.example + From aa2c7426ad63aead9fe3572421b40e44bf541a5f Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Mon, 21 Nov 2022 11:42:40 +0100 Subject: [PATCH 404/796] Add change note --- .../change-notes/2022-11-21-disabled-maven-repositories.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/src/change-notes/2022-11-21-disabled-maven-repositories.md diff --git a/java/ql/src/change-notes/2022-11-21-disabled-maven-repositories.md b/java/ql/src/change-notes/2022-11-21-disabled-maven-repositories.md new file mode 100644 index 00000000000..5d060b06076 --- /dev/null +++ b/java/ql/src/change-notes/2022-11-21-disabled-maven-repositories.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The query `java/maven/non-https-url` no longer alerts about disabled repositories. From 752bc2e980cd93f6db49a0cd1cbe16f37b3d2514 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Mon, 21 Nov 2022 11:45:09 +0100 Subject: [PATCH 405/796] C++: Accept test changes after AST-based GVN deprecation --- .../valuenumbering/GlobalValueNumbering/ast_gvn.expected | 1 + .../GlobalValueNumbering/ast_uniqueness.expected | 3 +++ .../valuenumbering/GlobalValueNumbering/diff_ir_expr.expected | 1 + 3 files changed, 5 insertions(+) diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.expected b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.expected index d5d46ee0b72..69c21b5e0b1 100644 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.expected +++ b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.expected @@ -1,3 +1,4 @@ +WARNING: Type GVN has been deprecated and may be removed in future (ast_gvn.ql:4,6-9) | test.cpp:5:3:5:3 | x | 5:c3-c3 6:c3-c3 | | test.cpp:5:7:5:8 | p0 | 5:c7-c8 6:c7-c8 | | test.cpp:5:7:5:13 | ... + ... | 5:c7-c13 6:c7-c13 7:c7-c7 | diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.expected b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.expected index e69de29bb2d..d94d58ad5ea 100644 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.expected +++ b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.expected @@ -0,0 +1,3 @@ +WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (ast_uniqueness.ql:7,13-30) +WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (ast_uniqueness.ql:8,30-47) +WARNING: Type GVN has been deprecated and may be removed in future (ast_uniqueness.ql:8,18-21) diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.expected b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.expected index b838a13d5af..810c83f197f 100644 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.expected +++ b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.expected @@ -1,3 +1,4 @@ +WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (diff_ir_expr.ql:8,29-51) | test.cpp:5:3:5:13 | ... = ... | test.cpp:5:3:5:13 | ... = ... | AST only | | test.cpp:6:3:6:13 | ... = ... | test.cpp:6:3:6:13 | ... = ... | AST only | | test.cpp:7:3:7:7 | ... = ... | test.cpp:7:3:7:7 | ... = ... | AST only | From 8c9431d278670f29d41784396d4bb69a2e325432 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 21 Nov 2022 11:58:59 +0100 Subject: [PATCH 406/796] CFG: Workaround in test output for source/sink pairs with multiple edges --- .../internal/ControlFlowGraphImplShared.qll | 10 +++++++--- .../library-tests/controlflow/graph/NodeGraph.expected | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll index dbd90ba0ae1..5039d09ff22 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll @@ -907,9 +907,13 @@ module TestOutput { query predicate edges(RelevantNode pred, RelevantNode succ, string attr, string val) { attr = "semmle.label" and - exists(SuccessorType t | succ = getASuccessor(pred, t) | - if successorTypeIsSimple(t) then val = "" else val = t.toString() - ) + val = + strictconcat(SuccessorType t, string s | + succ = getASuccessor(pred, t) and + if successorTypeIsSimple(t) then s = "" else s = t.toString() + | + s, ", " order by s + ) or attr = "semmle.order" and val = diff --git a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected index acabdc1835a..d5c2e78587d 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected @@ -2775,7 +2775,7 @@ Assert.cs: #-----| true -> access to parameter b2 # 140| [assertion failure] access to parameter b2 -#-----| false -> [assertion failure] access to parameter b3 +#-----| false, true -> [assertion failure] access to parameter b3 # 140| access to parameter b2 #-----| false -> [assertion success] access to parameter b3 @@ -4924,7 +4924,7 @@ ExitMethods.cs: #-----| -> ...; # 22| call to method ErrorAlways -#-----| exception(Exception) -> exit M3 (abnormal) +#-----| exception(ArgumentException), exception(Exception) -> exit M3 (abnormal) # 22| ...; #-----| -> true From e7ed056b6f27988b6ca90fb32dce3cf634c560fb Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 21 Nov 2022 12:00:36 +0100 Subject: [PATCH 407/796] Sync files --- .../internal/ControlFlowGraphImplShared.qll | 10 +++++++--- .../internal/ControlFlowGraphImplShared.qll | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll index dbd90ba0ae1..5039d09ff22 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll @@ -907,9 +907,13 @@ module TestOutput { query predicate edges(RelevantNode pred, RelevantNode succ, string attr, string val) { attr = "semmle.label" and - exists(SuccessorType t | succ = getASuccessor(pred, t) | - if successorTypeIsSimple(t) then val = "" else val = t.toString() - ) + val = + strictconcat(SuccessorType t, string s | + succ = getASuccessor(pred, t) and + if successorTypeIsSimple(t) then s = "" else s = t.toString() + | + s, ", " order by s + ) or attr = "semmle.order" and val = diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll index dbd90ba0ae1..5039d09ff22 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll @@ -907,9 +907,13 @@ module TestOutput { query predicate edges(RelevantNode pred, RelevantNode succ, string attr, string val) { attr = "semmle.label" and - exists(SuccessorType t | succ = getASuccessor(pred, t) | - if successorTypeIsSimple(t) then val = "" else val = t.toString() - ) + val = + strictconcat(SuccessorType t, string s | + succ = getASuccessor(pred, t) and + if successorTypeIsSimple(t) then s = "" else s = t.toString() + | + s, ", " order by s + ) or attr = "semmle.order" and val = From 256d8547c1b80739f7bdd757de364a7dc77e1d80 Mon Sep 17 00:00:00 2001 From: Gustav Date: Mon, 21 Nov 2022 12:29:16 +0100 Subject: [PATCH 408/796] Fix copy-paste error --- go/extractor/util/util.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/extractor/util/util.go b/go/extractor/util/util.go index 71ca932f366..b50651dbe98 100644 --- a/go/extractor/util/util.go +++ b/go/extractor/util/util.go @@ -123,8 +123,8 @@ func GetPkgsInfo(patterns []string, includingDeps bool, flags ...string) (map[st // It passes the `go list` the flags specified by `flags`. func GetPkgInfo(pkgpath string, flags ...string) PkgInfo { return PkgInfo{ - PkgDir: GetModDir(pkgpath, flags...), - ModDir: GetPkgDir(pkgpath, flags...), + PkgDir: GetPkgDir(pkgpath, flags...), + ModDir: GetModDir(pkgpath, flags...), } } From 2fac505221f7361066d02eb732b7703a4ca93f2e Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 21 Nov 2022 12:52:27 +0100 Subject: [PATCH 409/796] Ruby: Update expected test output --- .../controlflow/graph/Cfg.expected | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected b/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected index 9c26785029e..e51c50d2af5 100644 --- a/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -811,7 +811,7 @@ case.rb: #-----| -> [ ..., * ] # 35| [ ..., * ] -#-----| match -> x +#-----| false, match, true -> x #-----| no-match -> in ... then ... # 35| x @@ -821,7 +821,7 @@ case.rb: #-----| -> [ ..., * ] # 36| [ ..., * ] -#-----| match -> x +#-----| false, match, true -> x #-----| no-match -> in ... then ... # 36| x @@ -836,7 +836,7 @@ case.rb: # 37| [ ..., * ] #-----| raise -> exit case_match_array (abnormal) -#-----| match -> a +#-----| false, match, true -> a # 37| a #-----| match -> b @@ -881,7 +881,7 @@ case.rb: # 43| [ *,...,* ] #-----| raise -> exit case_match_find (abnormal) -#-----| match -> x +#-----| false, match, true -> x # 43| x #-----| -> 1 @@ -931,7 +931,7 @@ case.rb: #-----| no-match -> in ... then ... # 49| { ..., ** } -#-----| match -> 1 +#-----| false, match, true -> 1 #-----| no-match -> in ... then ... # 49| 1 @@ -952,7 +952,7 @@ case.rb: #-----| no-match -> in ... then ... # 50| { ..., ** } -#-----| match -> 1 +#-----| false, match, true -> 1 #-----| no-match -> in ... then ... # 50| 1 @@ -968,7 +968,7 @@ case.rb: # 51| { ..., ** } #-----| raise -> exit case_match_hash (abnormal) -#-----| match -> case ... +#-----| false, match, true -> case ... # 55| case_match_variable #-----| -> case_match_underscore @@ -1372,7 +1372,7 @@ case.rb: # 91| { ..., ** } #-----| raise -> exit case_match_various (abnormal) -#-----| match -> case ... +#-----| false, match, true -> case ... # 95| case_match_guard_no_else #-----| -> exit case.rb (normal) @@ -2559,7 +2559,7 @@ cfg.rb: #-----| -> type # 101| value -#-----| no-match -> 42 +#-----| false, no-match, true -> 42 #-----| match -> key # 101| 42 @@ -6535,7 +6535,7 @@ raise.rb: #-----| -> m11 # 121| p -#-----| no-match -> self +#-----| false, no-match, true -> self #-----| match -> self # 121| call to raise From 0d89f57680bf9d8fc8549af4a87c9a784a857668 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 21 Nov 2022 12:55:40 +0100 Subject: [PATCH 410/796] Swift: Update expected test output --- .../ql/test/library-tests/controlflow/graph/Cfg.expected | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected index c32c235ca1b..8146cf4fa3a 100644 --- a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -250,14 +250,14 @@ cfg.swift: #-----| match -> 0 # 33| .error1 -#-----| no-match -> ... is ... +#-----| match, no-match -> ... is ... # 33| ... is ... -#-----| no-match -> call to isZero(x:) +#-----| match, no-match -> call to isZero(x:) #-----| no-match -> case ... # 33| .error2 -#-----| no-match -> ... is ... +#-----| match, no-match -> ... is ... # 33| ... is ... where ... #-----| -> .error2 @@ -1577,7 +1577,7 @@ cfg.swift: #-----| -> =~ ... where ... # 144| =~ ... -#-----| no-match -> ... .&&(_:_:) ... +#-----| match, no-match -> ... .&&(_:_:) ... #-----| no-match -> case ... # 144| x From af58329931e4b8f1ae5c4ead2bb9722db5b4ba91 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 21 Nov 2022 14:30:29 +0100 Subject: [PATCH 411/796] split saving the compilation cache into a shared workflow --- .../cache-query-compilation/action.yml | 60 +++++++++++++++++++ .github/workflows/compile-queries.yml | 46 +++----------- 2 files changed, 67 insertions(+), 39 deletions(-) create mode 100644 .github/actions/cache-query-compilation/action.yml diff --git a/.github/actions/cache-query-compilation/action.yml b/.github/actions/cache-query-compilation/action.yml new file mode 100644 index 00000000000..55b1eb10ffa --- /dev/null +++ b/.github/actions/cache-query-compilation/action.yml @@ -0,0 +1,60 @@ +name: Cache query compilation +description: Caches CodeQL compilation caches - should be run both on PRs and pushes to main. + +inputs: + key: + description: 'The cache key to use - should be unique to the workflow' + required: true + +outputs: + cache-dir: + description: "The directory where the cache was stored" + value: ${{ steps.fill-compilation-dir.outputs.compdir }} + +runs: + using: composite + steps: + # Cache the query compilation caches. + # calculate the merge-base with main, in a way that works both on PRs and pushes to main. + - name: Calculate merge-base + shell: bash + if: ${{ github.event_name == 'pull_request' }} + env: + BASE_BRANCH: ${{ github.base_ref }} + run: | + MERGE_BASE=$(git cat-file commit $GITHUB_SHA | grep '^parent ' | head -1 | cut -f 2 -d " ") + echo "merge-base=$MERGE_BASE" >> $GITHUB_ENV + - name: Read CodeQL query compilation - PR + if: ${{ github.event_name == 'pull_request' }} + uses: actions/cache@v3 + with: + path: '**/.cache' + key: codeql-compile-${{ inputs.key }}-pr-${{ github.sha }} # deliberately not using the `compile-compile-main` keys here. + restore-keys: | + codeql-compile-${{ inputs.key }}-${{ github.base_ref }}-${{ env.merge-base }} + codeql-compile-${{ inputs.key }}-${{ github.base_ref }}- + codeql-compile-${{ inputs.key }}-main- + - name: Fill CodeQL query compilation cache - main + if: ${{ github.event_name != 'pull_request' }} + uses: actions/cache@v3 + with: + path: '**/.cache' + key: codeql-compile-${{ inputs.key }}-${{ github.ref_name }}-${{ github.sha }} # just fill on main + restore-keys: | # restore from another random commit, to speed up compilation. + codeql-compile-${{ inputs.key }}-${{ github.ref_name }}- + codeql-compile-${{ inputs.key }}-main- + - name: Fill compilation cache directory + id: fill-compilation-dir + shell: bash + run: | + # Move all the existing cache into another folder, so we only preserve the cache for the current queries. + mkdir -p ${COMBINED_CACHE_DIR} + rm -f **/.cache/{lock,size} # -f to avoid errors if the cache is empty. + # copy the contents of the .cache folders into the combined cache folder. + cp -r **/.cache/* ${COMBINED_CACHE_DIR}/ || : # ignore missing files + # clean up the .cache folders + rm -rf **/.cache/* + + echo "compdir=${COMBINED_CACHE_DIR}" >> $GITHUB_OUTPUT + env: + COMBINED_CACHE_DIR: ${{ github.workspace }}/compilation-dir \ No newline at end of file diff --git a/.github/workflows/compile-queries.yml b/.github/workflows/compile-queries.yml index d053b1cb7c1..ee6d48c45ea 100644 --- a/.github/workflows/compile-queries.yml +++ b/.github/workflows/compile-queries.yml @@ -14,58 +14,26 @@ jobs: steps: - uses: actions/checkout@v3 - # calculate the merge-base with main, in a way that works both on PRs and pushes to main. - - name: Calculate merge-base - if: ${{ github.event_name == 'pull_request' }} - env: - BASE_BRANCH: ${{ github.base_ref }} - run: | - MERGE_BASE=$(git cat-file commit $GITHUB_SHA | grep '^parent ' | head -1 | cut -f 2 -d " ") - echo "merge-base=$MERGE_BASE" >> $GITHUB_ENV - - name: Read CodeQL query compilation - PR - if: ${{ github.event_name == 'pull_request' }} - uses: actions/cache@v3 - with: - path: '**/.cache' - key: codeql-compile-pr-${{ github.sha }} # deliberately not using the `compile-compile-main` keys here. - restore-keys: | - codeql-compile-${{ github.base_ref }}-${{ env.merge-base }} - codeql-compile-${{ github.base_ref }}- - codeql-compile-main- - - name: Fill CodeQL query compilation cache - main - if: ${{ github.event_name != 'pull_request' }} - uses: actions/cache@v3 - with: - path: '**/.cache' - key: codeql-compile-${{ github.ref_name }}-${{ github.sha }} # just fill on main - restore-keys: | # restore from another random commit, to speed up compilation. - codeql-compile-${{ github.ref_name }}- - codeql-compile-main- - name: Setup CodeQL uses: ./.github/actions/fetch-codeql with: channel: 'release' + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: all-queries - name: check formatting run: find */ql -type f \( -name "*.qll" -o -name "*.ql" \) -print0 | xargs -0 codeql query format --check-only - name: compile queries - check-only # run with --check-only if running in a PR (github.sha != main) if : ${{ github.event_name == 'pull_request' }} shell: bash - run: codeql query compile -j0 */ql/{src,examples} --keep-going --warnings=error --check-only + run: codeql query compile -j0 */ql/{src,examples} --keep-going --warnings=error --check-only --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" - name: compile queries - full # do full compile if running on main - this populates the cache if : ${{ github.event_name != 'pull_request' }} shell: bash - run: | - # Move all the existing cache into another folder, so we only preserve the cache for the current queries. - mkdir -p ${COMBINED_CACHE_DIR} - rm -f */ql/{src,examples}/.cache/{lock,size} # -f to avoid errors if the cache is empty. - # copy the contents of the .cache folders into the combined cache folder. - cp -r */ql/{src,examples}/.cache/* ${COMBINED_CACHE_DIR}/ || : # ignore missing files - # clean up the .cache folders - rm -rf */ql/{src,examples}/.cache/* - - # compile the queries - codeql query compile -j0 */ql/{src,examples} --keep-going --warnings=error --compilation-cache ${COMBINED_CACHE_DIR} + run: codeql query compile -j0 */ql/{src,examples} --keep-going --warnings=error --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" env: COMBINED_CACHE_DIR: ${{ github.workspace }}/compilation-dir \ No newline at end of file From 24a973e545edd1fc4d5874713f7be05f0c205a5a Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 21 Nov 2022 14:31:24 +0100 Subject: [PATCH 412/796] run ruby qltest on a single XL worker --- .github/workflows/ruby-qltest.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ruby-qltest.yml b/.github/workflows/ruby-qltest.yml index 76727f626f0..dafeee4157c 100644 --- a/.github/workflows/ruby-qltest.yml +++ b/.github/workflows/ruby-qltest.yml @@ -48,17 +48,15 @@ jobs: xargs codeql execute upgrades testdb diff -q testdb/ruby.dbscheme downgrades/initial/ruby.dbscheme qltest: - runs-on: ubuntu-latest + runs-on: ubuntu-latest-xl strategy: fail-fast: false - matrix: - slice: ["1/2", "2/2"] steps: - uses: actions/checkout@v3 - uses: ./.github/actions/fetch-codeql - uses: ./ruby/actions/create-extractor-pack - name: Run QL tests run: | - codeql test run --threads=0 --ram 5000 --slice ${{ matrix.slice }} --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test + codeql test run --threads=0 --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test env: GITHUB_TOKEN: ${{ github.token }} From 4af8d5769a4efc19c548d8bf9a63fe582baf2c11 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 21 Nov 2022 14:32:18 +0100 Subject: [PATCH 413/796] use compilation cache in ruby qltest --- .github/workflows/ruby-qltest.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ruby-qltest.yml b/.github/workflows/ruby-qltest.yml index dafeee4157c..893e123ece5 100644 --- a/.github/workflows/ruby-qltest.yml +++ b/.github/workflows/ruby-qltest.yml @@ -55,8 +55,13 @@ jobs: - uses: actions/checkout@v3 - uses: ./.github/actions/fetch-codeql - uses: ./ruby/actions/create-extractor-pack + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: ruby-qltest - name: Run QL tests run: | - codeql test run --threads=0 --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test + codeql test run --threads=0 --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" env: GITHUB_TOKEN: ${{ github.token }} From a9c95a3230d4d4db5d353db9bf11110b03308155 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 21 Nov 2022 14:39:56 +0100 Subject: [PATCH 414/796] ruby: delete the path requirement when running qltest on branches --- .github/workflows/ruby-qltest.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/ruby-qltest.yml b/.github/workflows/ruby-qltest.yml index 893e123ece5..a6cd41a55bd 100644 --- a/.github/workflows/ruby-qltest.yml +++ b/.github/workflows/ruby-qltest.yml @@ -2,11 +2,7 @@ name: "Ruby: Run QL Tests" on: push: - paths: - - "ruby/**" - - .github/workflows/ruby-qltest.yml - - .github/actions/fetch-codeql/action.yml - - codeql-workspace.yml + # no path requirement on branch pushes, so the cache is more effective. branches: - main - "rc/*" From f50778ae2646ff72d48a59abd59f77f9bd575346 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 21 Nov 2022 15:02:14 +0100 Subject: [PATCH 415/796] Ruby: set ram usage to 52GB in the qltest workflow --- .github/workflows/ruby-qltest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ruby-qltest.yml b/.github/workflows/ruby-qltest.yml index a6cd41a55bd..abb6d2bf0eb 100644 --- a/.github/workflows/ruby-qltest.yml +++ b/.github/workflows/ruby-qltest.yml @@ -58,6 +58,6 @@ jobs: key: ruby-qltest - name: Run QL tests run: | - codeql test run --threads=0 --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" + codeql test run --threads=0 --ram 52000 --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" env: GITHUB_TOKEN: ${{ github.token }} From 57656d0a7edc8aa385cc519e20faae283ccf8f99 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Mon, 21 Nov 2022 15:14:02 +0100 Subject: [PATCH 416/796] Fix a couple of java.nio.file.Path(s) MaD rows --- .../lib/semmle/code/java/security/Files.qll | 4 +- java/ql/test/library-tests/paths/Test.java | 138 ++++++++++++++++-- 2 files changed, 129 insertions(+), 13 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/Files.qll b/java/ql/lib/semmle/code/java/security/Files.qll index 2cc55a1076f..52ea86bc5b7 100644 --- a/java/ql/lib/semmle/code/java/security/Files.qll +++ b/java/ql/lib/semmle/code/java/security/Files.qll @@ -84,13 +84,15 @@ private class FileSummaryModels extends SummaryModelCsv { "java.io;File;true;toPath;;;Argument[-1];ReturnValue;taint;manual", "java.io;File;true;toString;;;Argument[-1];ReturnValue;taint;manual", "java.io;File;true;toURI;;;Argument[-1];ReturnValue;taint;manual", + "java.nio.file;Path;true;getParent;;;Argument[-1];ReturnValue;taint;manual", "java.nio.file;Path;true;normalize;;;Argument[-1];ReturnValue;taint;manual", "java.nio.file;Path;true;resolve;;;Argument[-1..0];ReturnValue;taint;manual", "java.nio.file;Path;true;toAbsolutePath;;;Argument[-1];ReturnValue;taint;manual", "java.nio.file;Path;false;toFile;;;Argument[-1];ReturnValue;taint;manual", "java.nio.file;Path;true;toString;;;Argument[-1];ReturnValue;taint;manual", "java.nio.file;Path;true;toUri;;;Argument[-1];ReturnValue;taint;manual", - "java.nio.file;Paths;true;get;;;Argument[0..1];ReturnValue;taint;manual", + "java.nio.file;Paths;true;get;;;Argument[0];ReturnValue;taint;manual", + "java.nio.file;Paths;true;get;;;Argument[1].ArrayElement;ReturnValue;taint;manual", "java.nio.file;FileSystem;true;getPath;;;Argument[0];ReturnValue;taint;manual", "java.nio.file;FileSystem;true;getRootDirectories;;;Argument[0];ReturnValue;taint;manual" ] diff --git a/java/ql/test/library-tests/paths/Test.java b/java/ql/test/library-tests/paths/Test.java index 3ba4d97ca78..b00a667d823 100644 --- a/java/ql/test/library-tests/paths/Test.java +++ b/java/ql/test/library-tests/paths/Test.java @@ -2,6 +2,7 @@ package generatedtest; import java.io.File; import java.net.URI; +import java.nio.file.FileSystem; import java.nio.file.Path; import java.nio.file.Paths; @@ -13,6 +14,119 @@ public class Test { public void test() throws Exception { + { + // "java.io;File;false;File;;;Argument[0];Argument[-1];taint;manual" + File out = null; + File in = (File)source(); + out = new File(in, (String)null); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;false;File;;;Argument[0];Argument[-1];taint;manual" + File out = null; + String in = (String)source(); + out = new File(in); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;false;File;;;Argument[0];Argument[-1];taint;manual" + File out = null; + String in = (String)source(); + out = new File(in, (String)null); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;false;File;;;Argument[0];Argument[-1];taint;manual" + File out = null; + URI in = (URI)source(); + out = new File(in); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;false;File;;;Argument[1];Argument[-1];taint;manual" + File out = null; + String in = (String)source(); + out = new File((File)null, in); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;false;File;;;Argument[1];Argument[-1];taint;manual" + File out = null; + String in = (String)source(); + out = new File((String)null, in); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;true;getAbsoluteFile;;;Argument[-1];ReturnValue;taint;manual" + File out = null; + File in = (File)source(); + out = in.getAbsoluteFile(); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;true;getAbsolutePath;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + File in = (File)source(); + out = in.getAbsolutePath(); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;true;getCanonicalFile;;;Argument[-1];ReturnValue;taint;manual" + File out = null; + File in = (File)source(); + out = in.getCanonicalFile(); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;true;getCanonicalPath;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + File in = (File)source(); + out = in.getCanonicalPath(); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;true;toPath;;;Argument[-1];ReturnValue;taint;manual" + Path out = null; + File in = (File)source(); + out = in.toPath(); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;true;toString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + File in = (File)source(); + out = in.toString(); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;true;toURI;;;Argument[-1];ReturnValue;taint;manual" + URI out = null; + File in = (File)source(); + out = in.toURI(); + sink(out); // $ hasTaintFlow + } + { + // "java.nio.file;FileSystem;true;getPath;;;Argument[0];ReturnValue;taint;manual" + Path out = null; + String in = (String)source(); + FileSystem instance = null; + out = instance.getPath(in, (String[])null); + sink(out); // $ hasTaintFlow + } + { + // "java.nio.file;Path;false;toFile;;;Argument[-1];ReturnValue;taint;manual" + File out = null; + Path in = (Path)source(); + out = in.toFile(); + sink(out); // $ hasTaintFlow + } + { + // "java.nio.file;Path;true;getParent;;;Argument[-1];ReturnValue;taint;manual" + Path out = null; + Path in = (Path)source(); + out = in.getParent(); + sink(out); // $ hasTaintFlow + } { // "java.nio.file;Path;true;normalize;;;Argument[-1];ReturnValue;taint;manual" Path out = null; @@ -51,10 +165,10 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "java.nio.file;Path;true;toFile;;;Argument[-1];ReturnValue;taint;manual" - File out = null; + // "java.nio.file;Path;true;toAbsolutePath;;;Argument[-1];ReturnValue;taint;manual" + Path out = null; Path in = (Path)source(); - out = in.toFile(); + out = in.toAbsolutePath(); sink(out); // $ hasTaintFlow } { @@ -72,26 +186,26 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "java.nio.file;Paths;true;get;;;Argument[0..1];ReturnValue;taint;manual" + // "java.nio.file;Paths;true;get;;;Argument[0];ReturnValue;taint;manual" Path out = null; String in = (String)source(); out = Paths.get(in, (String[])null); sink(out); // $ hasTaintFlow } { - // "java.nio.file;Paths;true;get;;;Argument[0..1];ReturnValue;taint;manual" - Path out = null; - String[] in = (String[])source(); - out = Paths.get((String)null, in); - sink(out); // $ hasTaintFlow - } - { - // "java.nio.file;Paths;true;get;;;Argument[0..1];ReturnValue;taint;manual" + // "java.nio.file;Paths;true;get;;;Argument[0];ReturnValue;taint;manual" Path out = null; URI in = (URI)source(); out = Paths.get(in); sink(out); // $ hasTaintFlow } + { + // "java.nio.file;Paths;true;get;;;Argument[1].ArrayElement;ReturnValue;taint;manual" + Path out = null; + String[] in = (String[])new String[]{(String)source()}; + out = Paths.get((String)null, in); + sink(out); // $ hasTaintFlow + } } From 57a7f8948596bef0c8021975ceba582b9a96fe16 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 21 Nov 2022 15:15:12 +0100 Subject: [PATCH 417/796] change merge-base to merge_base --- .github/actions/cache-query-compilation/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/cache-query-compilation/action.yml b/.github/actions/cache-query-compilation/action.yml index 55b1eb10ffa..c071aa204d9 100644 --- a/.github/actions/cache-query-compilation/action.yml +++ b/.github/actions/cache-query-compilation/action.yml @@ -23,7 +23,7 @@ runs: BASE_BRANCH: ${{ github.base_ref }} run: | MERGE_BASE=$(git cat-file commit $GITHUB_SHA | grep '^parent ' | head -1 | cut -f 2 -d " ") - echo "merge-base=$MERGE_BASE" >> $GITHUB_ENV + echo "merge_base=$MERGE_BASE" >> $GITHUB_ENV - name: Read CodeQL query compilation - PR if: ${{ github.event_name == 'pull_request' }} uses: actions/cache@v3 @@ -31,7 +31,7 @@ runs: path: '**/.cache' key: codeql-compile-${{ inputs.key }}-pr-${{ github.sha }} # deliberately not using the `compile-compile-main` keys here. restore-keys: | - codeql-compile-${{ inputs.key }}-${{ github.base_ref }}-${{ env.merge-base }} + codeql-compile-${{ inputs.key }}-${{ github.base_ref }}-${{ env.merge_base }} codeql-compile-${{ inputs.key }}-${{ github.base_ref }}- codeql-compile-${{ inputs.key }}-main- - name: Fill CodeQL query compilation cache - main From fcd9dd0be4f67ee8742fca64152d675d4742c5cc Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 21 Nov 2022 14:18:20 +0000 Subject: [PATCH 418/796] Update cpp/ql/lib/change-notes/2022-11-16-must-flow.md Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com> --- cpp/ql/lib/change-notes/2022-11-16-must-flow.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/change-notes/2022-11-16-must-flow.md b/cpp/ql/lib/change-notes/2022-11-16-must-flow.md index bdb17d671a3..0f87b8d8bcd 100644 --- a/cpp/ql/lib/change-notes/2022-11-16-must-flow.md +++ b/cpp/ql/lib/change-notes/2022-11-16-must-flow.md @@ -1,4 +1,4 @@ --- category: breaking --- -The predicates in the `MustFlow::Configuration` class used by the `MustFlow` library (`semmle.code.cpp.ir.dataflow.MustFlow`) has changed to be defined directly in terms of the C++ IR instead of IR dataflow nodes. +The predicates in the `MustFlow::Configuration` class used by the `MustFlow` library (`semmle.code.cpp.ir.dataflow.MustFlow`) have changed to be defined directly in terms of the C++ IR instead of IR dataflow nodes. From 5000a1445188a5c7cd98472a9c56625843e04235 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Mon, 21 Nov 2022 15:22:26 +0100 Subject: [PATCH 419/796] Add change note --- java/ql/lib/change-notes/2022-11-21-paths-get-fix.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 java/ql/lib/change-notes/2022-11-21-paths-get-fix.md diff --git a/java/ql/lib/change-notes/2022-11-21-paths-get-fix.md b/java/ql/lib/change-notes/2022-11-21-paths-get-fix.md new file mode 100644 index 00000000000..a586cecf04b --- /dev/null +++ b/java/ql/lib/change-notes/2022-11-21-paths-get-fix.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Added a taint model for the method `java.nio.file.Path.getParent`. +* Fixed a problem in the taint model for the method `java.nio.file.Paths.get`. From a385e872733be4a0a6969abede237cca7b349e3e Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 21 Nov 2022 14:29:39 +0000 Subject: [PATCH 420/796] Python: Add change note for module resolution Also adapts the version-specific tests to support results specific to Python 2 (though at the moment there are no such tests). --- .../2022-11-21-module-resolution-rewrite.md | 5 +++++ .../import-resolution/importflow.ql | 17 ++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 python/ql/lib/change-notes/2022-11-21-module-resolution-rewrite.md diff --git a/python/ql/lib/change-notes/2022-11-21-module-resolution-rewrite.md b/python/ql/lib/change-notes/2022-11-21-module-resolution-rewrite.md new file mode 100644 index 00000000000..32484ffed56 --- /dev/null +++ b/python/ql/lib/change-notes/2022-11-21-module-resolution-rewrite.md @@ -0,0 +1,5 @@ +--- + category: minorAnalysis +--- + * The data-flow library has been rewritten to no longer rely on the points-to analysis in order to + resolve references to modules. This should result in more results for data-flow queries. diff --git a/python/ql/test/experimental/import-resolution/importflow.ql b/python/ql/test/experimental/import-resolution/importflow.ql index 6160560a3ee..875fb947901 100644 --- a/python/ql/test/experimental/import-resolution/importflow.ql +++ b/python/ql/test/experimental/import-resolution/importflow.ql @@ -93,26 +93,29 @@ class ResolutionTest extends InlineExpectationsTest { } } -class ResolutionTest3 extends InlineExpectationsTest { - ResolutionTest3() { this = "ResolutionTest3" } +class VersionSpecificResolutionTest extends InlineExpectationsTest { + VersionSpecificResolutionTest() { this = "VersionSpecificResolutionTest" } - override string getARelevantTag() { result = "prints3" and major_version() = 3 } + override string getARelevantTag() { result = getTagForVersion(_) } + + private string getTagForVersion(int version) { + result = "prints" + version and + version = major_version() + } override predicate hasActualResult(Location location, string element, string tag, string value) { ( exists(DataFlow::PathNode source, DataFlow::PathNode sink, ImportConfiguration config | config.hasFlowPath(source, sink) and - sink.getNode().(VersionGuardedNode).getVersion() = 3 and - tag = "prints3" and + tag = getTagForVersion(sink.getNode().(VersionGuardedNode).getVersion()) and location = sink.getNode().getLocation() and value = source.getNode().(SourceString).getContents() and element = sink.getNode().toString() ) or exists(ModuleRef ref | - ref.(VersionGuardedNode).getVersion() = 3 and ref instanceof CheckArgument and - tag = "prints3" and + tag = getTagForVersion(ref.(VersionGuardedNode).getVersion()) and location = ref.getLocation() and value = "\"\"" and element = ref.toString() From 7e80a57724da97d4527177742fddcccc691d89ab Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 21 Nov 2022 15:13:19 +0000 Subject: [PATCH 421/796] C++: Make ql-for-ql happy. --- cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql b/cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql index 39ee43a373a..bb62cfc1755 100644 --- a/cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql +++ b/cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql @@ -27,7 +27,7 @@ class UnsafeUseOfThisConfig extends MustFlowConfiguration { override predicate isSink(Operand sink) { isSink(sink, _) } } -/** Holds if `instr` is a `this` pointer used by the call instruction `call`. */ +/** Holds if `sink` is a `this` pointer used by the call instruction `call`. */ predicate isSink(Operand sink, CallInstruction call) { exists(PureVirtualFunction func | call.getStaticCallTarget() = func and @@ -37,7 +37,12 @@ predicate isSink(Operand sink, CallInstruction call) { ) } -/** Holds if `init` initializes the `this` pointer in class `c`. */ +/** + * Holds if `source` initializes the `this` pointer in class `c`. + * + * The string `msg` describes whether the enclosing function is a + * constructor or destructor. + */ predicate isSource(InitializeParameterInstruction source, string msg, Class c) { ( exists(Constructor func | From f12e15b46b0679fae1465620788d5fa3797933f2 Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 21 Nov 2022 15:23:13 +0000 Subject: [PATCH 422/796] Python: Fix implicit `this` warnings --- .../test/experimental/import-resolution/importflow.ql | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/ql/test/experimental/import-resolution/importflow.ql b/python/ql/test/experimental/import-resolution/importflow.ql index 875fb947901..e6e51afa963 100644 --- a/python/ql/test/experimental/import-resolution/importflow.ql +++ b/python/ql/test/experimental/import-resolution/importflow.ql @@ -93,16 +93,16 @@ class ResolutionTest extends InlineExpectationsTest { } } +private string getTagForVersion(int version) { + result = "prints" + version and + version = major_version() +} + class VersionSpecificResolutionTest extends InlineExpectationsTest { VersionSpecificResolutionTest() { this = "VersionSpecificResolutionTest" } override string getARelevantTag() { result = getTagForVersion(_) } - private string getTagForVersion(int version) { - result = "prints" + version and - version = major_version() - } - override predicate hasActualResult(Location location, string element, string tag, string value) { ( exists(DataFlow::PathNode source, DataFlow::PathNode sink, ImportConfiguration config | From 16a76853f4106867bbe4b0697eb0c7075757c1ff Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Tue, 8 Nov 2022 15:23:43 +0100 Subject: [PATCH 423/796] Add libxml2 sinks --- .../lib/codeql/swift/frameworks/Libxml2.qll | 54 +++++++++++ swift/ql/lib/codeql/swift/security/XXE.qll | 38 ++++++++ .../query-tests/Security/CWE-611/XXETest.ql | 7 ++ .../Security/CWE-611/testLibxmlXXE.swift | 96 +++++++++++++++++++ 4 files changed, 195 insertions(+) create mode 100644 swift/ql/lib/codeql/swift/frameworks/Libxml2.qll create mode 100644 swift/ql/test/query-tests/Security/CWE-611/testLibxmlXXE.swift diff --git a/swift/ql/lib/codeql/swift/frameworks/Libxml2.qll b/swift/ql/lib/codeql/swift/frameworks/Libxml2.qll new file mode 100644 index 00000000000..12f8603c69b --- /dev/null +++ b/swift/ql/lib/codeql/swift/frameworks/Libxml2.qll @@ -0,0 +1,54 @@ +import swift + +/** + * A call to a `libxml2` function that parses XML. + */ +class Libxml2ParseCall extends ApplyExpr { + int xmlArg; + int optionsArg; + + Libxml2ParseCall() { + exists(string fname | this.getStaticTarget().getName() = fname | + fname = "xmlCtxtUseOptions(_:_:)" and xmlArg = 0 and optionsArg = 1 + or + fname = "xmlReadFile(_:_:_:)" and xmlArg = 0 and optionsArg = 2 + or + fname = ["xmlReadDoc(_:_:_:_:)", "xmlReadFd(_:_:_:_:)"] and + xmlArg = 0 and + optionsArg = 3 + or + fname = ["xmlCtxtReadFile(_:_:_:_:)", "xmlParseInNodeContext(_:_:_:_:_:)"] and + xmlArg = 1 and + optionsArg = 3 + or + fname = ["xmlCtxtReadDoc(_:_:_:_:_:)", "xmlCtxtReadFd(_:_:_:_:_:)"] and + xmlArg = 1 and + optionsArg = 4 + or + fname = "xmlReadMemory(_:_:_:_:_:)" and xmlArg = 0 and optionsArg = 4 + or + fname = "xmlCtxtReadMemory(_:_:_:_:_:_:)" and xmlArg = 1 and optionsArg = 5 + or + fname = "xmlReadIO(_:_:_:_:_:_:)" and xmlArg = 0 and optionsArg = 5 + or + fname = "xmlCtxtReadIO(_:_:_:_:_:_:_:)" and xmlArg = 1 and optionsArg = 6 + ) + } + + /** + * Gets the argument that receives the XML raw data. + */ + Expr getXml() { result = this.getArgument(xmlArg).getExpr() } + + /** + * Gets the argument that specifies `xmlParserOption`s. + */ + Expr getOptions() { result = this.getArgument(optionsArg).getExpr() } +} + +/** + * An `xmlParserOption` for `libxml2` that is considered unsafe. + */ +class Libxml2BadOption extends ConcreteVarDecl { + Libxml2BadOption() { this.getName() = ["XML_PARSE_NOENT", "XML_PARSE_DTDLOAD"] } +} diff --git a/swift/ql/lib/codeql/swift/security/XXE.qll b/swift/ql/lib/codeql/swift/security/XXE.qll index 5f80426fa56..623be39060c 100644 --- a/swift/ql/lib/codeql/swift/security/XXE.qll +++ b/swift/ql/lib/codeql/swift/security/XXE.qll @@ -3,6 +3,7 @@ import swift private import codeql.swift.dataflow.DataFlow private import codeql.swift.frameworks.AEXML +private import codeql.swift.frameworks.Libxml2 /** A data flow sink for XML external entities (XXE) vulnerabilities. */ abstract class XxeSink extends DataFlow::Node { } @@ -163,3 +164,40 @@ private class AexmlOptions extends Expr { this.getType() = any(LValueType t | t.getObjectType() instanceof AexmlOptionsType) } } + +/** The XML argument of a `libxml2` parsing call vulnerable to XXE. */ +private class Libxml2XxeSink extends XxeSink { + Libxml2XxeSink() { + exists(Libxml2ParseCall c, Libxml2BadOption opt | + this.asExpr() = c.getXml() and + lib2xmlOptionLocalTaintStep*(DataFlow::exprNode(opt.getAnAccess()), + DataFlow::exprNode(c.getOptions())) + ) + } +} + +/** + * Holds if taint can flow from `source` to `sink` in one local step, + * including bitwise operations, accesses to `.rawValue`, and casts to `Int32`. + */ +private predicate lib2xmlOptionLocalTaintStep(DataFlow::Node source, DataFlow::Node sink) { + DataFlow::localFlowStep(source, sink) + or + source.asExpr() = sink.asExpr().(BitwiseOperation).getAnOperand() + or + exists(MemberRefExpr rawValue | rawValue.getMember().(VarDecl).getName() = "rawValue" | + source.asExpr() = rawValue.getBase() and sink.asExpr() = rawValue + ) + or + exists(ApplyExpr int32Init | + int32Init + .getStaticTarget() + .(ConstructorDecl) + .getEnclosingDecl() + .(ExtensionDecl) + .getExtendedTypeDecl() + .getName() = "SignedInteger" + | + source.asExpr() = int32Init.getAnArgument().getExpr() and sink.asExpr() = int32Init + ) +} diff --git a/swift/ql/test/query-tests/Security/CWE-611/XXETest.ql b/swift/ql/test/query-tests/Security/CWE-611/XXETest.ql index 817f55678ad..757e45a102b 100644 --- a/swift/ql/test/query-tests/Security/CWE-611/XXETest.ql +++ b/swift/ql/test/query-tests/Security/CWE-611/XXETest.ql @@ -1,7 +1,14 @@ import swift +import codeql.swift.dataflow.FlowSources import codeql.swift.security.XXEQuery import TestUtilities.InlineExpectationsTest +class TestRemoteSource extends RemoteFlowSource { + TestRemoteSource() { this.asExpr().(ApplyExpr).getStaticTarget().getName().matches("source%") } + + override string getSourceType() { result = "Test source" } +} + class XxeTest extends InlineExpectationsTest { XxeTest() { this = "XxeTest" } diff --git a/swift/ql/test/query-tests/Security/CWE-611/testLibxmlXXE.swift b/swift/ql/test/query-tests/Security/CWE-611/testLibxmlXXE.swift new file mode 100644 index 00000000000..b0e580c42a0 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-611/testLibxmlXXE.swift @@ -0,0 +1,96 @@ +// --- stubs --- + +class Data { + init(_ elements: S) {} + func copyBytes(to: UnsafeMutablePointer, count: Int) {} +} + +struct URL { + init?(string: String) {} +} + +extension String { + init(contentsOf: URL) { + let data = "" + self.init(data) + } +} + +struct xmlParserOption : Hashable { + let rawValue: UInt32 = 0 +} + +var XML_PARSE_NOENT: xmlParserOption { get { return xmlParserOption() } } +var XML_PARSE_DTDLOAD: xmlParserOption { get { return xmlParserOption() } } + +typealias xmlChar = UInt8 +typealias xmlDocPtr = UnsafeMutablePointer +typealias xmlNodePtr = UnsafeMutablePointer +typealias xmlParserCtxtPtr = UnsafeMutablePointer +struct xmlDoc {} +struct xmlNode {} +struct xmlParserCtxt {} +struct xmlParserErrors {} +struct xmlInputReadCallback {} +struct xmlInputCloseCallback {} + +func xmlCtxtUseOptions(_ ctxt: xmlParserCtxtPtr!, _ options: Int32) -> Int32 { return 0 } +func xmlReadDoc(_ cur: UnsafePointer!, _ URL: UnsafePointer!, _ encoding: UnsafePointer!, _ options: Int32) -> xmlDocPtr! { return xmlDocPtr.allocate(capacity: 0) } +func xmlReadFile(_ URL: UnsafePointer!, _ encoding: UnsafePointer!, _ options: Int32) -> xmlDocPtr! { return xmlDocPtr.allocate(capacity: 0) } +func xmlReadMemory(_ buffer: UnsafePointer!, _ size: Int32, _ URL: UnsafePointer!, _ encoding: UnsafePointer!, _ options: Int32) -> xmlDocPtr! { return xmlDocPtr.allocate(capacity: 0) } +func xmlReadFd(_ fd: Int32, _ URL: UnsafePointer!, _ encoding: UnsafePointer!, _ options: Int32) -> xmlDocPtr! { return xmlDocPtr.allocate(capacity: 0) } +func xmlReadIO(_ ioread: xmlInputReadCallback!, _ ioclose: xmlInputCloseCallback!, _ ioctx: UnsafeMutableRawPointer!, _ URL: UnsafePointer!, _ encoding: UnsafePointer!, _ options: Int32) -> xmlDocPtr! { return xmlDocPtr.allocate(capacity: 0) } +func xmlCtxtReadDoc(_ ctxt: xmlParserCtxtPtr!, _ cur: UnsafePointer!, _ URL: UnsafePointer!, _ encoding: UnsafePointer!, _ options: Int32) -> xmlDocPtr! { return xmlDocPtr.allocate(capacity: 0) } +func xmlCtxtReadFile(_ ctxt: xmlParserCtxtPtr!, _ filename: UnsafePointer!, _ encoding: UnsafePointer!, _ options: Int32) -> xmlDocPtr! { return xmlDocPtr.allocate(capacity: 0) } +func xmlParseInNodeContext(_ node: xmlNodePtr!, _ data: UnsafePointer!, _ datalen: Int32, _ options: Int32, _ lst: UnsafeMutablePointer!) -> xmlParserErrors { return xmlParserErrors() } +func xmlCtxtReadMemory(_ ctxt: xmlParserCtxtPtr!, _ buffer: UnsafePointer!, _ size: Int32, _ URL: UnsafePointer!, _ encoding: UnsafePointer!, _ options: Int32) -> xmlDocPtr! { return xmlDocPtr.allocate(capacity: 0) } +func xmlCtxtReadFd(_ ctxt: xmlParserCtxtPtr!, _ fd: Int32, _ URL: UnsafePointer!, _ encoding: UnsafePointer!, _ options: Int32) -> xmlDocPtr! { return xmlDocPtr.allocate(capacity: 0) } +func xmlCtxtReadIO(_ ctxt: xmlParserCtxtPtr!, _ ioread: xmlInputReadCallback!, _ ioclose: xmlInputCloseCallback!, _ ioctx: UnsafeMutableRawPointer!, _ URL: UnsafePointer!, _ encoding: UnsafePointer!, _ options: Int32) -> xmlDocPtr! { return xmlDocPtr.allocate(capacity: 0) } + +// --- tests --- + +func sourcePtr() -> UnsafeMutablePointer { return UnsafeMutablePointer.allocate(capacity: 0) } +func sourceCharPtr() -> UnsafeMutablePointer { return UnsafeMutablePointer.allocate(capacity: 0) } + +func test() { + let remotePtr = sourcePtr() + let remoteCharPtr = sourceCharPtr() + let _ = xmlReadFile(remoteCharPtr, nil, 0) // NO XXE: external entities not enabled + let _ = xmlReadFile(remoteCharPtr, nil, Int32(XML_PARSE_NOENT.rawValue)) // $ hasXXE=57 + let _ = xmlReadFile(remoteCharPtr, nil, Int32(XML_PARSE_DTDLOAD.rawValue)) // $ hasXXE=57 + let _ = xmlReadDoc(remotePtr, nil, nil, 0) // NO XXE: external entities not enabled + let _ = xmlReadDoc(remotePtr, nil, nil, Int32(XML_PARSE_NOENT.rawValue)) // $ hasXXE=56 + let _ = xmlReadDoc(remotePtr, nil, nil, Int32(XML_PARSE_DTDLOAD.rawValue)) // $ hasXXE=56 + let _ = xmlCtxtReadFile(nil, remoteCharPtr, nil, 0) // NO XXE: external entities not enabled + let _ = xmlCtxtReadFile(nil, remoteCharPtr, nil, Int32(XML_PARSE_NOENT.rawValue)) // $ hasXXE=57 + let _ = xmlCtxtReadFile(nil, remoteCharPtr, nil, Int32(XML_PARSE_DTDLOAD.rawValue)) // $ hasXXE=57 + let _ = xmlParseInNodeContext(nil, remoteCharPtr, -1, 0, nil) // NO XXE: external entities not enabled + let _ = xmlParseInNodeContext(nil, remoteCharPtr, -1, Int32(XML_PARSE_DTDLOAD.rawValue), nil) // $ hasXXE=57 + let _ = xmlParseInNodeContext(nil, remoteCharPtr, -1, Int32(XML_PARSE_NOENT.rawValue), nil) // $ hasXXE=57 + let _ = xmlCtxtReadDoc(nil, remotePtr, nil, nil, 0) // NO XXE: external entities not enabled + let _ = xmlCtxtReadDoc(nil, remotePtr, nil, nil, Int32(XML_PARSE_NOENT.rawValue)) // $ hasXXE=56 + let _ = xmlCtxtReadDoc(nil, remotePtr, nil, nil, Int32(XML_PARSE_DTDLOAD.rawValue)) // $ hasXXE=56 + let _ = xmlReadMemory(remoteCharPtr, -1, nil, nil, 0) // NO XXE: external entities not enabled + let _ = xmlReadMemory(remoteCharPtr, -1, nil, nil, Int32(XML_PARSE_NOENT.rawValue)) // $ hasXXE=57 + let _ = xmlReadMemory(remoteCharPtr, -1, nil, nil, Int32(XML_PARSE_DTDLOAD.rawValue)) // $ hasXXE=57 + let _ = xmlCtxtReadMemory(nil, remoteCharPtr, -1, nil, nil, 0) // NO XXE: external entities not enabled + let _ = xmlCtxtReadMemory(nil, remoteCharPtr, -1, nil, nil, Int32(XML_PARSE_NOENT.rawValue)) // $ hasXXE=57 + let _ = xmlCtxtReadMemory(nil, remoteCharPtr, -1, nil, nil, Int32(XML_PARSE_DTDLOAD.rawValue)) // $ hasXXE=57 + // TODO: We would need to model taint around `xmlParserCtxtPtr`, file descriptors, and `xmlInputReadCallback` + // to be able to alert on these methods. Not doing it for now because of the effort required vs the expected gain. + let _ = xmlCtxtUseOptions(nil, 0) + let _ = xmlCtxtUseOptions(nil, Int32(XML_PARSE_NOENT.rawValue)) + let _ = xmlCtxtUseOptions(nil, Int32(XML_PARSE_DTDLOAD.rawValue)) + let _ = xmlReadFd(0, nil, nil, 0) + let _ = xmlReadFd(0, nil, nil, Int32(XML_PARSE_NOENT.rawValue)) + let _ = xmlReadFd(0, nil, nil, Int32(XML_PARSE_DTDLOAD.rawValue)) + let _ = xmlCtxtReadFd(nil, 0, nil, nil, 0) + let _ = xmlCtxtReadFd(nil, 0, nil, nil, Int32(XML_PARSE_NOENT.rawValue)) + let _ = xmlCtxtReadFd(nil, 0, nil, nil, Int32(XML_PARSE_DTDLOAD.rawValue)) + let _ = xmlReadIO(nil, nil, nil, nil, nil, 0) + let _ = xmlReadIO(nil, nil, nil, nil, nil, Int32(XML_PARSE_NOENT.rawValue)) + let _ = xmlReadIO(nil, nil, nil, nil, nil, Int32(XML_PARSE_DTDLOAD.rawValue)) + let _ = xmlCtxtReadIO(nil, nil, nil, nil, nil, nil, 0) + let _ = xmlCtxtReadIO(nil, nil, nil, nil, nil, nil, Int32(XML_PARSE_NOENT.rawValue)) + let _ = xmlCtxtReadIO(nil, nil, nil, nil, nil, nil, Int32(XML_PARSE_DTDLOAD.rawValue)) +} From 1c9545e49a92ab13334decdf6c764e04944c95e7 Mon Sep 17 00:00:00 2001 From: tiferet Date: Mon, 21 Nov 2022 08:00:31 -0800 Subject: [PATCH 424/796] Address comment from code review: Make `SyntacticHeuristics` an explicit import --- .../EndpointCharacteristics.qll | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index 0f899d795d9..1b305fa0b11 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -8,7 +8,7 @@ private import semmle.javascript.security.dataflow.DomBasedXssCustomizations private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations private import semmle.javascript.security.dataflow.TaintedPathCustomizations private import CoreKnowledge as CoreKnowledge -private import semmle.javascript.heuristics.SyntacticHeuristics +private import semmle.javascript.heuristics.SyntacticHeuristics as SyntacticHeuristics private import semmle.javascript.filters.ClassifyFiles as ClassifyFiles private import StandardEndpointFilters as StandardEndpointFilters @@ -540,7 +540,9 @@ private class IsHashCharacteristic extends StandardEndpointFilterCharacteristic private class IsNumericCharacteristic extends StandardEndpointFilterCharacteristic { IsNumericCharacteristic() { this = "numeric" } - override predicate getEndpoints(DataFlow::Node n) { isReadFrom(n, ".*index.*") } + override predicate getEndpoints(DataFlow::Node n) { + SyntacticHeuristics::isReadFrom(n, ".*index.*") + } } private class InIrrelevantFileCharacteristic extends StandardEndpointFilterCharacteristic { @@ -676,8 +678,8 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkNosqlCh // heuristic sinks as known sinks. not n = StandardEndpointFilters::getALikelyExternalLibraryCall().getAnArgument() and not ( - isAssignedToOrConcatenatedWith(n, "(?i)(nosql|query)") or - isArgTo(n, "(?i)(query)") + SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)(nosql|query)") or + SyntacticHeuristics::isArgTo(n, "(?i)(query)") ) } } @@ -745,9 +747,9 @@ private class NotAnArgumentToLikelyExternalLibraryCallOrHeuristicSinkCharacteris // heuristic sinks as known sinks. not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(n) and not ( - isAssignedToOrConcatenatedWith(n, "(?i)(sql|query)") or - isArgTo(n, "(?i)(query)") or - isConcatenatedWithString(n, + SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)(sql|query)") or + SyntacticHeuristics::isArgTo(n, "(?i)(query)") or + SyntacticHeuristics::isConcatenatedWithString(n, "(?s).*(ALTER|COUNT|CREATE|DATABASE|DELETE|DISTINCT|DROP|FROM|GROUP|INSERT|INTO|LIMIT|ORDER|SELECT|TABLE|UPDATE|WHERE).*") ) } @@ -783,24 +785,24 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkTainted // heuristic sinks as known sinks. not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(n) and not ( - isAssignedToOrConcatenatedWith(n, "(?i)(file|folder|dir|absolute)") + SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)(file|folder|dir|absolute)") or - isArgTo(n, "(?i)(get|read)file") + SyntacticHeuristics::isArgTo(n, "(?i)(get|read)file") or exists(string pathPattern | // paths with at least two parts, and either a trailing or leading slash pathPattern = "(?i)([a-z0-9_.-]+/){2,}" or pathPattern = "(?i)(/[a-z0-9_.-]+){2,}" | - isConcatenatedWithString(n, pathPattern) + SyntacticHeuristics::isConcatenatedWithString(n, pathPattern) ) or - isConcatenatedWithStrings(".*/", n, "/.*") + SyntacticHeuristics::isConcatenatedWithStrings(".*/", n, "/.*") or // In addition to the names from `HeuristicTaintedPathSink` in the // `isAssignedToOrConcatenatedWith` predicate call above, we also allow the noisier "path" // name. - isAssignedToOrConcatenatedWith(n, "(?i)path") + SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)path") ) } } @@ -844,13 +846,13 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkXssChar // heuristic sinks as known sinks. not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(n) and not ( - isAssignedToOrConcatenatedWith(n, "(?i)(html|innerhtml)") + SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)(html|innerhtml)") or - isArgTo(n, "(?i)(html|render)") + SyntacticHeuristics::isArgTo(n, "(?i)(html|render)") or n instanceof StringOps::HtmlConcatenationLeaf or - isConcatenatedWithStrings("(?is).*<[a-z ]+.*", n, "(?s).*>.*") + SyntacticHeuristics::isConcatenatedWithStrings("(?is).*<[a-z ]+.*", n, "(?s).*>.*") or // In addition to the heuristic sinks from `HeuristicDomBasedXssSink`, explicitly allow // property writes like `elem.innerHTML = ` that may not be picked up as HTML From 937365141fe40761186189b6ab7cb788fb15b3e7 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 21 Nov 2022 13:04:22 +0100 Subject: [PATCH 425/796] QL: add redundant-assignment query --- ql/ql/src/codeql/GlobalValueNumbering.qll | 2 +- .../src/queries/style/RedundantAssignment.ql | 110 ++++++++++++++++++ 2 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 ql/ql/src/queries/style/RedundantAssignment.ql diff --git a/ql/ql/src/codeql/GlobalValueNumbering.qll b/ql/ql/src/codeql/GlobalValueNumbering.qll index cb9483200d0..21fe729fedc 100644 --- a/ql/ql/src/codeql/GlobalValueNumbering.qll +++ b/ql/ql/src/codeql/GlobalValueNumbering.qll @@ -237,7 +237,7 @@ private TValueNumber nonUniqueValueNumber(Expr e) { /** Gets the value number of an expression `e`. */ cached -TValueNumber valueNumber(Expr e) { +ValueNumber valueNumber(Expr e) { result = nonUniqueValueNumber(e) or uniqueValueNumber(e) and diff --git a/ql/ql/src/queries/style/RedundantAssignment.ql b/ql/ql/src/queries/style/RedundantAssignment.ql new file mode 100644 index 00000000000..7baf046b97a --- /dev/null +++ b/ql/ql/src/queries/style/RedundantAssignment.ql @@ -0,0 +1,110 @@ +/** + * @name Redundant assignment. + * @description Assigning the same value twice is redundant. + * @kind problem + * @problem.severity warning + * @precision high + * @id ql/redunant-assignment + * @tags maintainability + */ + +import ql + +/** + * A variable that is set equal to (assigned) a value one or more times. + */ +class AssignedVariable extends VarDecl { + AssignedVariable() { + exists(VarAccess access, ComparisonFormula comp | comp.getOperator() = "=" | + access.getDeclaration() = this and + comp.getAnOperand() = access + ) + } + + /** + * Gets an expression that is assigned to this variable. + */ + Expr getAnAssignedExpr() { + exists(VarAccess access, ComparisonFormula comp, Expr operand | + comp.getOperator() = "=" and + access.getDeclaration() = this and + comp.getAnOperand() = access and + operand = comp.getAnOperand() and + not operand.(VarAccess).getDeclaration() = this + | + result = operand and + not result instanceof Set + or + result = operand.(Set).getAnElement() + ) + } +} + +import codeql.GlobalValueNumbering as GVN + +/** + * Holds if `assigned1` and `assigned2` assigns the same value to `var`. + * The assignments may be on different branches of a disjunction. + */ +predicate candidateRedundantAssignment(AssignedVariable var, Expr assigned1, Expr assigned2) { + assigned1 = var.getAnAssignedExpr() and + assigned2 = var.getAnAssignedExpr() and + ( + GVN::valueNumber(assigned1) = GVN::valueNumber(assigned2) + or + // because GVN skips large strings, we need to check for equality manually + assigned1.(String).getValue() = assigned2.(String).getValue() + ) and + assigned1 != assigned2 +} + +/** + * Gets a (transitive) parent of `p`, where the parent is not a disjunction, and `p` is a candidate assignment from `candidateRedundantAssignment`. + */ +AstNode getConjunctionParentRec(AstNode p) { + candidateRedundantAssignment(_, p, _) and + result = p + or + result = getConjunctionParentRec(p).getParent() and + not result instanceof Disjunction and + not result instanceof IfFormula and + not result instanceof Implication and + not result instanceof Negation and + not result instanceof Predicate +} + +/** + * Gets which level in the AST `p` is at. + * E.g. the top-level is 0, the next level is 1, etc. + */ +int level(AstNode p) { + p instanceof TopLevel and result = 0 + or + result = level(p.getParent()) + 1 +} + +/** + * Gets the top-most parent of `p` that is not a disjunction. + */ +AstNode getConjunctionParent(AstNode p) { + result = + min(int level, AstNode parent | + parent = getConjunctionParentRec(p) and level = level(parent) + | + parent order by level + ) +} + +from AssignedVariable var, Expr assigned1, Expr assigned2 +where + candidateRedundantAssignment(var, assigned1, assigned2) and + getConjunctionParent(assigned1) = getConjunctionParent(assigned2) and + // de-duplcation: + ( + assigned1.getLocation().getStartLine() < assigned2.getLocation().getStartLine() + or + assigned1.getLocation().getStartLine() = assigned2.getLocation().getStartLine() and + assigned1.getLocation().getStartColumn() < assigned2.getLocation().getStartColumn() + ) +select assigned2, "$@ has previously been assigned $@.", var, "The variable " + var.getName(), + assigned1, "the same value" From 64707f4f7b47e1b64d313f3ef653b05998d54460 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 21 Nov 2022 17:40:57 +0100 Subject: [PATCH 426/796] remove redundant assignments --- .../Magic Constants/MagicConstants.qll | 40 +++++++++---------- .../library-tests/assemblies/assemblies.ql | 1 - .../OpenUrlRedirectCustomizations.qll | 2 +- .../java/dataflow/internal/ContainerFlow.qll | 1 - .../frameworks/android/ContentProviders.qll | 1 - .../java/frameworks/guava/Collections.qll | 1 - .../semmle/code/java/frameworks/guava/IO.qll | 1 - .../Magic Constants/MagicConstants.qll | 40 +++++++++---------- .../semmle/javascript/frameworks/NoSQL.qll | 2 +- .../LoopBoundInjectionCustomizations.qll | 8 ++-- 10 files changed, 46 insertions(+), 51 deletions(-) diff --git a/csharp/ql/src/Bad Practices/Magic Constants/MagicConstants.qll b/csharp/ql/src/Bad Practices/Magic Constants/MagicConstants.qll index b65cdcd1961..73b82c14700 100644 --- a/csharp/ql/src/Bad Practices/Magic Constants/MagicConstants.qll +++ b/csharp/ql/src/Bad Practices/Magic Constants/MagicConstants.qll @@ -10,26 +10,26 @@ private predicate trivialPositiveIntValue(string s) { s = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", - "17", "18", "19", "20", "16", "32", "64", "128", "256", "512", "1024", "2048", "4096", - "16384", "32768", "65536", "1048576", "2147483648", "4294967296", "15", "31", "63", "127", - "255", "511", "1023", "2047", "4095", "16383", "32767", "65535", "1048577", "2147483647", - "4294967295", "0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010", - "0x00000020", "0x00000040", "0x00000080", "0x00000100", "0x00000200", "0x00000400", - "0x00000800", "0x00001000", "0x00002000", "0x00004000", "0x00008000", "0x00010000", - "0x00020000", "0x00040000", "0x00080000", "0x00100000", "0x00200000", "0x00400000", - "0x00800000", "0x01000000", "0x02000000", "0x04000000", "0x08000000", "0x10000000", - "0x20000000", "0x40000000", "0x80000000", "0x00000001", "0x00000003", "0x00000007", - "0x0000000f", "0x0000001f", "0x0000003f", "0x0000007f", "0x000000ff", "0x000001ff", - "0x000003ff", "0x000007ff", "0x00000fff", "0x00001fff", "0x00003fff", "0x00007fff", - "0x0000ffff", "0x0001ffff", "0x0003ffff", "0x0007ffff", "0x000fffff", "0x001fffff", - "0x003fffff", "0x007fffff", "0x00ffffff", "0x01ffffff", "0x03ffffff", "0x07ffffff", - "0x0fffffff", "0x1fffffff", "0x3fffffff", "0x7fffffff", "0xffffffff", "0x0001", "0x0002", - "0x0004", "0x0008", "0x0010", "0x0020", "0x0040", "0x0080", "0x0100", "0x0200", "0x0400", - "0x0800", "0x1000", "0x2000", "0x4000", "0x8000", "0x0001", "0x0003", "0x0007", "0x000f", - "0x001f", "0x003f", "0x007f", "0x00ff", "0x01ff", "0x03ff", "0x07ff", "0x0fff", "0x1fff", - "0x3fff", "0x7fff", "0xffff", "0x01", "0x02", "0x04", "0x08", "0x10", "0x20", "0x40", "0x80", - "0x01", "0x03", "0x07", "0x0f", "0x1f", "0x3f", "0x7f", "0xff", "0x00", "10", "100", "1000", - "10000", "100000", "1000000", "10000000", "100000000", "1000000000" + "17", "18", "19", "20", "32", "64", "128", "256", "512", "1024", "2048", "4096", "16384", + "32768", "65536", "1048576", "2147483648", "4294967296", "31", "63", "127", "255", "511", + "1023", "2047", "4095", "16383", "32767", "65535", "1048577", "2147483647", "4294967295", + "0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010", "0x00000020", + "0x00000040", "0x00000080", "0x00000100", "0x00000200", "0x00000400", "0x00000800", + "0x00001000", "0x00002000", "0x00004000", "0x00008000", "0x00010000", "0x00020000", + "0x00040000", "0x00080000", "0x00100000", "0x00200000", "0x00400000", "0x00800000", + "0x01000000", "0x02000000", "0x04000000", "0x08000000", "0x10000000", "0x20000000", + "0x40000000", "0x80000000", "0x00000003", "0x00000007", "0x0000000f", "0x0000001f", + "0x0000003f", "0x0000007f", "0x000000ff", "0x000001ff", "0x000003ff", "0x000007ff", + "0x00000fff", "0x00001fff", "0x00003fff", "0x00007fff", "0x0000ffff", "0x0001ffff", + "0x0003ffff", "0x0007ffff", "0x000fffff", "0x001fffff", "0x003fffff", "0x007fffff", + "0x00ffffff", "0x01ffffff", "0x03ffffff", "0x07ffffff", "0x0fffffff", "0x1fffffff", + "0x3fffffff", "0x7fffffff", "0xffffffff", "0x0001", "0x0002", "0x0004", "0x0008", "0x0010", + "0x0020", "0x0040", "0x0080", "0x0100", "0x0200", "0x0400", "0x0800", "0x1000", "0x2000", + "0x4000", "0x8000", "0x0003", "0x0007", "0x000f", "0x001f", "0x003f", "0x007f", "0x00ff", + "0x01ff", "0x03ff", "0x07ff", "0x0fff", "0x1fff", "0x3fff", "0x7fff", "0xffff", "0x02", + "0x04", "0x08", "0x10", "0x20", "0x40", "0x80", "0x01", "0x03", "0x07", "0x0f", "0x1f", + "0x3f", "0x7f", "0xff", "0x00", "100", "1000", "10000", "100000", "1000000", "10000000", + "100000000", "1000000000" ] } diff --git a/csharp/ql/test/library-tests/assemblies/assemblies.ql b/csharp/ql/test/library-tests/assemblies/assemblies.ql index 98db2a0f973..9c072f0d51e 100644 --- a/csharp/ql/test/library-tests/assemblies/assemblies.ql +++ b/csharp/ql/test/library-tests/assemblies/assemblies.ql @@ -34,7 +34,6 @@ where f.hasName("f") and g.hasName("g") and a.getDeclaringType() = class1 and - a.getDeclaringType() = class1 and b.getDeclaringType() = class1 and c.getDeclaringType() = class1 and not exists(c.getParameter(0).getType().(KnownType)) and diff --git a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll index 80b9bb4a126..2d7f6948115 100644 --- a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll +++ b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll @@ -128,7 +128,7 @@ private class SafeUrlSink extends SafeUrlFlow::Sink { private class UnsafeFieldReadSanitizer extends SafeUrlFlow::SanitizerEdge { UnsafeFieldReadSanitizer() { exists(DataFlow::FieldReadNode frn, string name | - name = ["User", "RawQuery", "Fragment", "User"] and + name = ["User", "RawQuery", "Fragment"] and frn.getField().hasQualifiedName("net/url", "URL") | this = frn.getBase() diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll b/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll index 8f9a40ed8d0..aebe509816f 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll @@ -250,7 +250,6 @@ private class ContainerFlowSummaries extends SummaryModelCsv { "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual", "java.util;Scanner;true;findInLine;;;Argument[-1];ReturnValue;taint;manual", "java.util;Scanner;true;findWithinHorizon;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;findWithinHorizon;;;Argument[-1];ReturnValue;taint;manual", "java.util;Scanner;true;next;;;Argument[-1];ReturnValue;taint;manual", "java.util;Scanner;true;nextBigDecimal;;;Argument[-1];ReturnValue;taint;manual", "java.util;Scanner;true;nextBigInteger;;;Argument[-1];ReturnValue;taint;manual", diff --git a/java/ql/lib/semmle/code/java/frameworks/android/ContentProviders.qll b/java/ql/lib/semmle/code/java/frameworks/android/ContentProviders.qll index 1e10a01d451..bf47e98b8fb 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/ContentProviders.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/ContentProviders.qll @@ -56,7 +56,6 @@ private class SummaryModels extends SummaryModelCsv { "android.content;ContentValues;false;putAll;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", "android.content;ContentResolver;true;acquireContentProviderClient;;;Argument[0];ReturnValue;taint;manual", "android.content;ContentResolver;true;acquireUnstableContentProviderClient;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;acquireUnstableContentProviderClient;;;Argument[0];ReturnValue;taint;manual", "android.content;ContentResolver;true;applyBatch;;;Argument[1];ReturnValue;taint;manual", "android.content;ContentResolver;true;call;;;Argument[0];ReturnValue;taint;manual", "android.content;ContentResolver;true;canonicalize;;;Argument[0];ReturnValue;taint;manual", diff --git a/java/ql/lib/semmle/code/java/frameworks/guava/Collections.qll b/java/ql/lib/semmle/code/java/frameworks/guava/Collections.qll index d662e7ee7cd..feb27d22ec0 100644 --- a/java/ql/lib/semmle/code/java/frameworks/guava/Collections.qll +++ b/java/ql/lib/semmle/code/java/frameworks/guava/Collections.qll @@ -503,7 +503,6 @@ private class GuavaCollectCsv extends SummaryModelCsv { "com.google.common.collect;Sets;false;filter;(SortedSet,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", "com.google.common.collect;Sets;false;intersection;(Set,Set);;Argument[0..1].Element;ReturnValue.Element;value;manual", "com.google.common.collect;Sets;false;newConcurrentHashSet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newConcurrentHashSet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", "com.google.common.collect;Sets;false;newCopyOnWriteArraySet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", "com.google.common.collect;Sets;false;newHashSet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", "com.google.common.collect;Sets;false;newHashSet;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", diff --git a/java/ql/lib/semmle/code/java/frameworks/guava/IO.qll b/java/ql/lib/semmle/code/java/frameworks/guava/IO.qll index 6137a4e47f3..59fc0113e10 100644 --- a/java/ql/lib/semmle/code/java/frameworks/guava/IO.qll +++ b/java/ql/lib/semmle/code/java/frameworks/guava/IO.qll @@ -93,7 +93,6 @@ private class GuavaIoSinkCsv extends SinkModelCsv { "com.google.common.io;Resources;false;asByteSource;(URL);;Argument[0];url-open-stream;manual", "com.google.common.io;Resources;false;asCharSource;(URL,Charset);;Argument[0];url-open-stream;manual", "com.google.common.io;Resources;false;copy;(URL,OutputStream);;Argument[0];url-open-stream;manual", - "com.google.common.io;Resources;false;asByteSource;(URL);;Argument[0];url-open-stream;manual", "com.google.common.io;Resources;false;readLines;;;Argument[0];url-open-stream;manual", "com.google.common.io;Resources;false;toByteArray;(URL);;Argument[0];url-open-stream;manual", "com.google.common.io;Resources;false;toString;(URL,Charset);;Argument[0];url-open-stream;manual" diff --git a/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstants.qll b/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstants.qll index 11dbd5cd8d3..5fc7e9069cd 100644 --- a/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstants.qll +++ b/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstants.qll @@ -8,26 +8,26 @@ private predicate trivialPositiveIntValue(string s) { s = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", - "17", "18", "19", "20", "16", "32", "64", "128", "256", "512", "1024", "2048", "4096", - "16384", "32768", "65536", "1048576", "2147483648", "4294967296", "15", "31", "63", "127", - "255", "511", "1023", "2047", "4095", "16383", "32767", "65535", "1048577", "2147483647", - "4294967295", "0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010", - "0x00000020", "0x00000040", "0x00000080", "0x00000100", "0x00000200", "0x00000400", - "0x00000800", "0x00001000", "0x00002000", "0x00004000", "0x00008000", "0x00010000", - "0x00020000", "0x00040000", "0x00080000", "0x00100000", "0x00200000", "0x00400000", - "0x00800000", "0x01000000", "0x02000000", "0x04000000", "0x08000000", "0x10000000", - "0x20000000", "0x40000000", "0x80000000", "0x00000001", "0x00000003", "0x00000007", - "0x0000000f", "0x0000001f", "0x0000003f", "0x0000007f", "0x000000ff", "0x000001ff", - "0x000003ff", "0x000007ff", "0x00000fff", "0x00001fff", "0x00003fff", "0x00007fff", - "0x0000ffff", "0x0001ffff", "0x0003ffff", "0x0007ffff", "0x000fffff", "0x001fffff", - "0x003fffff", "0x007fffff", "0x00ffffff", "0x01ffffff", "0x03ffffff", "0x07ffffff", - "0x0fffffff", "0x1fffffff", "0x3fffffff", "0x7fffffff", "0xffffffff", "0x0001", "0x0002", - "0x0004", "0x0008", "0x0010", "0x0020", "0x0040", "0x0080", "0x0100", "0x0200", "0x0400", - "0x0800", "0x1000", "0x2000", "0x4000", "0x8000", "0x0001", "0x0003", "0x0007", "0x000f", - "0x001f", "0x003f", "0x007f", "0x00ff", "0x01ff", "0x03ff", "0x07ff", "0x0fff", "0x1fff", - "0x3fff", "0x7fff", "0xffff", "0x01", "0x02", "0x04", "0x08", "0x10", "0x20", "0x40", "0x80", - "0x01", "0x03", "0x07", "0x0f", "0x1f", "0x3f", "0x7f", "0xff", "0x00", "10", "100", "1000", - "10000", "100000", "1000000", "10000000", "100000000", "1000000000" + "17", "18", "19", "20", "32", "64", "128", "256", "512", "1024", "2048", "4096", "16384", + "32768", "65536", "1048576", "2147483648", "4294967296", "31", "63", "127", "255", "511", + "1023", "2047", "4095", "16383", "32767", "65535", "1048577", "2147483647", "4294967295", + "0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010", "0x00000020", + "0x00000040", "0x00000080", "0x00000100", "0x00000200", "0x00000400", "0x00000800", + "0x00001000", "0x00002000", "0x00004000", "0x00008000", "0x00010000", "0x00020000", + "0x00040000", "0x00080000", "0x00100000", "0x00200000", "0x00400000", "0x00800000", + "0x01000000", "0x02000000", "0x04000000", "0x08000000", "0x10000000", "0x20000000", + "0x40000000", "0x80000000", "0x00000003", "0x00000007", "0x0000000f", "0x0000001f", + "0x0000003f", "0x0000007f", "0x000000ff", "0x000001ff", "0x000003ff", "0x000007ff", + "0x00000fff", "0x00001fff", "0x00003fff", "0x00007fff", "0x0000ffff", "0x0001ffff", + "0x0003ffff", "0x0007ffff", "0x000fffff", "0x001fffff", "0x003fffff", "0x007fffff", + "0x00ffffff", "0x01ffffff", "0x03ffffff", "0x07ffffff", "0x0fffffff", "0x1fffffff", + "0x3fffffff", "0x7fffffff", "0xffffffff", "0x0001", "0x0002", "0x0004", "0x0008", "0x0010", + "0x0020", "0x0040", "0x0080", "0x0100", "0x0200", "0x0400", "0x0800", "0x1000", "0x2000", + "0x4000", "0x8000", "0x0003", "0x0007", "0x000f", "0x001f", "0x003f", "0x007f", "0x00ff", + "0x01ff", "0x03ff", "0x07ff", "0x0fff", "0x1fff", "0x3fff", "0x7fff", "0xffff", "0x01", + "0x02", "0x04", "0x08", "0x10", "0x20", "0x40", "0x80", "0x03", "0x07", "0x0f", "0x1f", + "0x3f", "0x7f", "0xff", "0x00", "100", "1000", "10000", "100000", "1000000", "10000000", + "100000000", "1000000000" ] } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll b/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll index 11f454eadd5..568ae3c93a1 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll @@ -251,7 +251,7 @@ private module Redis { "set", "publish", "append", "bitfield", "decrby", "getset", "hincrby", "hincrbyfloat", "hset", "hsetnx", "incrby", "incrbyfloat", "linsert", "lpush", "lpushx", "lset", "ltrim", "rename", "renamenx", "rpushx", "setbit", "setex", "smove", "zincrby", "zinterstore", - "hdel", "lpush", "pfadd", "rpush", "sadd", "sdiffstore", "srem" + "hdel", "pfadd", "rpush", "sadd", "sdiffstore", "srem" ] and argIndex = 0 or diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjectionCustomizations.qll index 2142d468b90..1c92ff66c5b 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjectionCustomizations.qll @@ -122,10 +122,10 @@ module LoopBoundInjection { "flattenDeep", "flattenDepth", "initial", "intersection", "intersectionBy", "intersectionWith", "join", "remove", "reverse", "slice", "sortedUniq", "sortedUniqBy", "tail", "union", "unionBy", "unionWith", "uniqBy", "unzip", "unzipWith", "without", "zip", - "zipObject", "zipObjectDeep", "zipWith", "countBy", "each", "forEach", "eachRight", - "forEachRight", "filter", "find", "findLast", "flatMap", "flatMapDeep", "flatMapDepth", - "forEach", "forEachRight", "groupBy", "invokeMap", "keyBy", "map", "orderBy", "partition", - "reduce", "reduceRight", "reject", "sortBy" + "zipObject", "zipObjectDeep", "zipWith", "countBy", "each", "eachRight", "forEachRight", + "filter", "find", "findLast", "flatMap", "flatMapDeep", "flatMapDepth", "forEach", + "groupBy", "invokeMap", "keyBy", "map", "orderBy", "partition", "reduce", "reduceRight", + "reject", "sortBy" ] } From 9c792902c7eab3ae5451092d0209bdc28ea846e2 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 21 Nov 2022 16:25:26 +0100 Subject: [PATCH 427/796] Ruby: cache the entire extractor --- ruby/actions/create-extractor-pack/action.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ruby/actions/create-extractor-pack/action.yml b/ruby/actions/create-extractor-pack/action.yml index b0907eff834..667158c264c 100644 --- a/ruby/actions/create-extractor-pack/action.yml +++ b/ruby/actions/create-extractor-pack/action.yml @@ -3,7 +3,15 @@ description: Builds the Ruby CodeQL pack runs: using: composite steps: - - uses: actions/cache@v3 + - name: Cache entire extractor + id: cache-extractor + uses: actions/cache@v3 + with: + path: ruby/extractor-pack + key: ${{ runner.os }}-extractor-${{ hashFiles('ruby/rust-toolchain.toml', 'ruby/**/Cargo.lock') }}-${{ hashFiles('ruby/**/*.rs') }}-${{ hashFiles('ruby/codeql-extractor.yml', 'ruby/downgrades', 'ruby/tools', 'ruby/ql/lib/ruby.dbscheme', 'ruby/ql/lib/ruby.dbscheme.stats') }} + - name: Cache cargo + uses: actions/cache@v3 + if: steps.cache-extractor.outputs.cache-hit != 'true' with: path: | ~/.cargo/registry @@ -11,6 +19,7 @@ runs: ruby/target key: ${{ runner.os }}-ruby-qltest-cargo-${{ hashFiles('ruby/rust-toolchain.toml', 'ruby/**/Cargo.lock') }} - name: Build Extractor + if: steps.cache-extractor.outputs.cache-hit != 'true' shell: bash run: scripts/create-extractor-pack.sh working-directory: ruby From b1db39020057ad96e2321ff08c6ca8da0e973613 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 21 Nov 2022 16:25:44 +0100 Subject: [PATCH 428/796] Ruby: use compilation cache in the ruby-build workflow --- .github/workflows/ruby-build.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index 2c4ddb8a582..3ba334b94a2 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -93,13 +93,18 @@ jobs: - uses: actions/checkout@v3 - name: Fetch CodeQL uses: ./.github/actions/fetch-codeql + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: ruby-build - name: Build Query Pack run: | - codeql pack create ../shared/ssa --output target/packs - codeql pack create ../misc/suite-helpers --output target/packs - codeql pack create ../shared/regex --output target/packs - codeql pack create ql/lib --output target/packs - codeql pack create ql/src --output target/packs + codeql pack create ../shared/ssa --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" + codeql pack create ../misc/suite-helpers --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" + codeql pack create ../shared/regex --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" + codeql pack create ql/lib --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" + codeql pack create ql/src --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" PACK_FOLDER=$(readlink -f target/packs/codeql/ruby-queries/*) codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src (cd ql/src; find queries \( -name '*.qhelp' -o -name '*.rb' -o -name '*.erb' \) -exec bash -c 'mkdir -p "'"${PACK_FOLDER}"'/$(dirname "{}")"' \; -exec cp "{}" "${PACK_FOLDER}/{}" \;) From 999e8ed0d08f442d0d51ddafdbd9b4e19985f21f Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 21 Nov 2022 16:30:15 +0100 Subject: [PATCH 429/796] Ruby: remove the path on branch pushes, for caching --- .github/workflows/ruby-build.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index 3ba334b94a2..6895e3afeb1 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -2,11 +2,7 @@ name: "Ruby: Build" on: push: - paths: - - "ruby/**" - - .github/workflows/ruby-build.yml - - .github/actions/fetch-codeql/action.yml - - codeql-workspace.yml + # No path requirement on branch pushes, so the cache is more effective. branches: - main - "rc/*" From 3b7ce0680d51b977cf0d8df64ea124ea2499d2b4 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 21 Nov 2022 16:35:11 +0100 Subject: [PATCH 430/796] Ruby: build queries on an XL worker, and use all the threads --- .github/workflows/ruby-build.yml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index 6895e3afeb1..cb9278f091e 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -82,9 +82,7 @@ jobs: ruby/target/release/ruby-extractor.exe retention-days: 1 compile-queries: - runs-on: ubuntu-latest - env: - CODEQL_THREADS: 4 # TODO: remove this once it's set by the CLI + runs-on: ubuntu-latest-xl steps: - uses: actions/checkout@v3 - name: Fetch CodeQL @@ -96,11 +94,11 @@ jobs: key: ruby-build - name: Build Query Pack run: | - codeql pack create ../shared/ssa --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" - codeql pack create ../misc/suite-helpers --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" - codeql pack create ../shared/regex --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" - codeql pack create ql/lib --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" - codeql pack create ql/src --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" + codeql pack create -j0 ../shared/ssa --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" + codeql pack create -j0 ../misc/suite-helpers --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" + codeql pack create -j0 ../shared/regex --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" + codeql pack create -j0 ql/lib --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" + codeql pack create -j0 ql/src --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" PACK_FOLDER=$(readlink -f target/packs/codeql/ruby-queries/*) codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src (cd ql/src; find queries \( -name '*.qhelp' -o -name '*.rb' -o -name '*.erb' \) -exec bash -c 'mkdir -p "'"${PACK_FOLDER}"'/$(dirname "{}")"' \; -exec cp "{}" "${PACK_FOLDER}/{}" \;) From 53ba22ab5c565770e1ac0c89362184f29f7ce3bf Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 21 Nov 2022 17:37:11 +0100 Subject: [PATCH 431/796] simplify pack creation Co-authored-by: Arthur Baars --- .github/workflows/ruby-build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index cb9278f091e..abca7bd8913 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -94,10 +94,10 @@ jobs: key: ruby-build - name: Build Query Pack run: | - codeql pack create -j0 ../shared/ssa --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" - codeql pack create -j0 ../misc/suite-helpers --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" - codeql pack create -j0 ../shared/regex --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" - codeql pack create -j0 ql/lib --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" + codeql pack create ../shared/ssa --output target/packs + codeql pack create ../misc/suite-helpers --output target/packs + codeql pack create ../shared/regex --output target/packs + codeql pack create ql/lib --output target/packs codeql pack create -j0 ql/src --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" PACK_FOLDER=$(readlink -f target/packs/codeql/ruby-queries/*) codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src From 76ceb498417dd15ba181c81f32c9c1371be1be1b Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 21 Nov 2022 17:52:06 +0100 Subject: [PATCH 432/796] re-introduce the paths requirements in the ruby workflows --- .github/workflows/ruby-build.yml | 6 +++++- .github/workflows/ruby-qltest.yml | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index abca7bd8913..784a7db3dc9 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -2,7 +2,11 @@ name: "Ruby: Build" on: push: - # No path requirement on branch pushes, so the cache is more effective. + paths: + - "ruby/**" + - .github/workflows/ruby-build.yml + - .github/actions/fetch-codeql/action.yml + - codeql-workspace.yml branches: - main - "rc/*" diff --git a/.github/workflows/ruby-qltest.yml b/.github/workflows/ruby-qltest.yml index abb6d2bf0eb..d8af552c8c6 100644 --- a/.github/workflows/ruby-qltest.yml +++ b/.github/workflows/ruby-qltest.yml @@ -2,7 +2,11 @@ name: "Ruby: Run QL Tests" on: push: - # no path requirement on branch pushes, so the cache is more effective. + paths: + - "ruby/**" + - .github/workflows/ruby-build.yml + - .github/actions/fetch-codeql/action.yml + - codeql-workspace.yml branches: - main - "rc/*" From 9e2ec9d12f599408f20a28d036163316b6eb077a Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Mon, 21 Nov 2022 13:39:46 -0500 Subject: [PATCH 433/796] apply docs review suggestion --- java/ql/src/Security/CWE/CWE-730/RegexInjection.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Security/CWE/CWE-730/RegexInjection.qhelp b/java/ql/src/Security/CWE/CWE-730/RegexInjection.qhelp index fc8ab33ca80..3e239d07107 100644 --- a/java/ql/src/Security/CWE/CWE-730/RegexInjection.qhelp +++ b/java/ql/src/Security/CWE/CWE-730/RegexInjection.qhelp @@ -25,7 +25,7 @@ The following example shows an HTTP request parameter that is used to construct

    In the first case the user-provided regex is not escaped. -If a malicious user provides a regex that has exponential worst case performance, +If a malicious user provides a regex whose worst-case performance is exponential, then this could lead to a Denial of Service.

    From 29055f770904c543a933fa8cbbffe2f2e8dc3763 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 22 Nov 2022 00:09:42 +0100 Subject: [PATCH 434/796] delete packs --- .github/workflows/ruby-build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index 784a7db3dc9..cbe7f32fb17 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -98,6 +98,7 @@ jobs: key: ruby-build - name: Build Query Pack run: | + rm -rf target/packs codeql pack create ../shared/ssa --output target/packs codeql pack create ../misc/suite-helpers --output target/packs codeql pack create ../shared/regex --output target/packs From e70eb3a3ee07c875ff7a0b0c8312725f778ca6e6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 22 Nov 2022 00:19:21 +0000 Subject: [PATCH 435/796] Add changed framework coverage reports --- .../library-coverage/coverage.csv | 260 +++++++++--------- .../library-coverage/coverage.rst | 6 +- 2 files changed, 133 insertions(+), 133 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index 189dbab6b94..75e3309bb4c 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -1,130 +1,130 @@ -package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jdbc-url,sink:jexl,sink:jndi-injection,sink:ldap,sink:logging,sink:mvel,sink:ognl-injection,sink:open-url,sink:pending-intent-sent,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:set-hostname-verifier,sink:sql,sink:ssti,sink:url-open-stream,sink:url-redirect,sink:write-file,sink:xpath,sink:xslt,sink:xss,source:android-external-storage-dir,source:android-widget,source:contentprovider,source:remote,summary:taint,summary:value -android.app,24,,103,,,,,,7,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,18,85 -android.content,24,31,154,,,,,,16,,,,,,,,,,,,,,,,,8,,,,,,,,4,,27,,63,91 -android.database,59,,39,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,,,,,39, -android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15 -android.os,,2,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,41,81 -android.util,6,16,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,16,, -android.webkit,3,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,2,, -android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,1, -androidx.core.app,6,,95,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,12,83 -androidx.slice,2,5,88,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,5,,27,61 -cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, -com.google.common.base,4,,85,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,,,,62,23 -com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 -com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 -com.google.common.flogger,29,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,,,, -com.google.common.io,6,,73,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,72,1 -com.hubspot.jinjava,2,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,, -com.mitchellbosecke.pebble,2,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,, -com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,,,, -com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7, -com.unboundid.ldap.sdk,17,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,,,, -com.zaxxer.hikari,2,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -freemarker.cache,1,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,, -freemarker.template,7,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,, -groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, -jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 -jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,, -jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, -jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 -java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -java.io,37,,40,,15,,,,,,,,,,,,,,,,,,,,,,,,,22,,,,,,,,40, -java.lang,13,,66,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,,54,12 -java.net,10,3,7,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,,3,7, -java.nio,15,,14,,13,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,14, -java.sql,11,,,,,,,,,4,,,,,,,,,,,,,,,,7,,,,,,,,,,,,, -java.util,44,,461,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,,,36,425 -javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, -javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57, -javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 -javax.management.remote,2,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,, -javax.naming,7,,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,,,,,,,,,, -javax.net.ssl,2,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,, -javax.script,1,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,, -javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,2, -javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,, -javax.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,, -javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, -javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 -javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,6, -javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,, -jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 -kotlin,12,,1835,,10,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,1828,7 -net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,,, -ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,, -okhttp3,2,,47,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,22,25 -org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, -org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 -org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 -org.apache.commons.io,106,,556,,91,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,542,14 -org.apache.commons.jexl2,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.jexl3,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.lang3,,,424,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,293,131 -org.apache.commons.logging,6,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52 -org.apache.directory.ldap.client.api,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,2,39, -org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2, -org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6 -org.apache.http,27,3,70,,,,,,,,,,,,,,25,,,,,,,,,,,,,,,,2,,,,3,62,8 -org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,57, -org.apache.log4j,11,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.logging.log4j,359,,8,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,,,4,4 -org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.shiro.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.velocity.app,4,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,, -org.apache.velocity.runtime,4,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,, -org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,,, -org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,,, -org.jboss.logging,324,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,,,, -org.jdbi.v3.core,6,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,, -org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38 -org.mvel2,16,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,,,, -org.scijava.log,13,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,,,, -org.slf4j,55,,6,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,,,2,4 -org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30 -org.springframework.boot.jdbc,1,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13 -org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -org.springframework.data.repository,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -org.springframework.http,14,,70,,,,,,,,,,,,,,14,,,,,,,,,,,,,,,,,,,,,60,10 -org.springframework.jdbc.core,10,,,,,,,,,,,,,,,,,,,,,,,,,10,,,,,,,,,,,,, -org.springframework.jdbc.datasource,4,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,,, -org.springframework.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.ldap,47,,,,,,,,,,,33,14,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,, -org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32 -org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,87,52 -org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13, -org.springframework.web.client,13,3,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,3,, -org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,, -org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13, -org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,, -org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,138,25 -org.thymeleaf,2,,2,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,2, -org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,, -play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,, -ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, -ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, -ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48 -ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 -ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, -ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, -ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 -retrofit2,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,, +package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jdbc-url,sink:jexl,sink:jndi-injection,sink:ldap,sink:logging,sink:mvel,sink:ognl-injection,sink:open-url,sink:pending-intent-sent,sink:regex-use,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:set-hostname-verifier,sink:sql,sink:ssti,sink:url-open-stream,sink:url-redirect,sink:write-file,sink:xpath,sink:xslt,sink:xss,source:android-external-storage-dir,source:android-widget,source:contentprovider,source:remote,summary:taint,summary:value +android.app,24,,103,,,,,,7,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,18,85 +android.content,24,31,154,,,,,,16,,,,,,,,,,,,,,,,,,8,,,,,,,,4,,27,,63,91 +android.database,59,,39,,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,,,,,39, +android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15 +android.os,,2,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,41,81 +android.util,6,16,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,16,, +android.webkit,3,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,2,, +android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,1, +androidx.core.app,6,,95,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,12,83 +androidx.slice,2,5,88,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,5,,27,61 +cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, +com.google.common.base,4,,85,,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,,,,62,23 +com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 +com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 +com.google.common.flogger,29,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,,,,, +com.google.common.io,6,,73,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,72,1 +com.hubspot.jinjava,2,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,, +com.mitchellbosecke.pebble,2,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,, +com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,,,,, +com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7, +com.unboundid.ldap.sdk,17,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,, +com.zaxxer.hikari,2,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 +freemarker.cache,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,, +freemarker.template,7,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,, +groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, +jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 +jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, +jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, +jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 +java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +java.io,37,,40,,15,,,,,,,,,,,,,,,,,,,,,,,,,,22,,,,,,,,40, +java.lang,13,,66,,,,,,,,,,,8,,,,,,4,,,1,,,,,,,,,,,,,,,,54,12 +java.net,10,3,7,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,,,3,7, +java.nio,15,,16,,13,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,16, +java.sql,11,,,,,,,,,4,,,,,,,,,,,,,,,,,7,,,,,,,,,,,,, +java.util,44,,461,,,,,,,,,,,34,,,,,,,5,2,,1,2,,,,,,,,,,,,,,36,425 +javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, +javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57, +javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 +javax.management.remote,2,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,, +javax.naming,7,,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,,,,,,,,,,, +javax.net.ssl,2,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,, +javax.script,1,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,, +javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,2, +javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,, +javax.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, +javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, +javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 +javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,6, +javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,, +jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 +kotlin,12,,1835,,10,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,1828,7 +net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,,, +ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,, +okhttp3,2,,47,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,22,25 +org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, +org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 +org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 +org.apache.commons.io,106,,556,,91,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,542,14 +org.apache.commons.jexl2,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.jexl3,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.lang3,6,,424,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,293,131 +org.apache.commons.logging,6,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52 +org.apache.directory.ldap.client.api,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,2,39, +org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2, +org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6 +org.apache.http,27,3,70,,,,,,,,,,,,,,25,,,,,,,,,,,,,,,,,2,,,,3,62,8 +org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,57, +org.apache.log4j,11,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.logging.log4j,359,,8,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,,,,4,4 +org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.shiro.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.velocity.app,4,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,, +org.apache.velocity.runtime,4,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,, +org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,,, +org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,,, +org.jboss.logging,324,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,,,,, +org.jdbi.v3.core,6,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,, +org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38 +org.mvel2,16,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,,,,, +org.scijava.log,13,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,,,,, +org.slf4j,55,,6,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,,,,2,4 +org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30 +org.springframework.boot.jdbc,1,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13 +org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +org.springframework.data.repository,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 +org.springframework.http,14,,70,,,,,,,,,,,,,,14,,,,,,,,,,,,,,,,,,,,,,60,10 +org.springframework.jdbc.core,10,,,,,,,,,,,,,,,,,,,,,,,,,,10,,,,,,,,,,,,, +org.springframework.jdbc.datasource,4,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,,, +org.springframework.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.ldap,47,,,,,,,,,,,33,14,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,, +org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32 +org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,87,52 +org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13, +org.springframework.web.client,13,3,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,3,, +org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,, +org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13, +org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,138,25 +org.thymeleaf,2,,2,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,2, +org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,, +play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,, +ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, +ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, +ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48 +ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 +ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, +ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, +ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 +retrofit2,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index 46da8bda328..703932814c1 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -11,17 +11,17 @@ Java framework & library support Android extensions,``androidx.*``,5,183,8,,,,,,, `Apache Commons Collections `_,"``org.apache.commons.collections``, ``org.apache.commons.collections4``",,1600,,,,,,,, `Apache Commons IO `_,``org.apache.commons.io``,,556,106,91,,,,,,15 - `Apache Commons Lang `_,``org.apache.commons.lang3``,,424,,,,,,,, + `Apache Commons Lang `_,``org.apache.commons.lang3``,,424,6,,,,,,, `Apache Commons Text `_,``org.apache.commons.text``,,272,,,,,,,, `Apache HttpComponents `_,"``org.apache.hc.core5.*``, ``org.apache.http``",5,136,28,,,3,,,,25 `Apache Log4j 2 `_,``org.apache.logging.log4j``,,8,359,,,,,,, `Google Guava `_,``com.google.common.*``,,728,39,,6,,,,, JBoss Logging,``org.jboss.logging``,,,324,,,,,,, `JSON-java `_,``org.json``,,236,,,,,,,, - Java Standard Library,``java.*``,3,589,130,28,,,7,,,10 + Java Standard Library,``java.*``,3,591,130,28,,,7,,,10 Java extensions,"``javax.*``, ``jakarta.*``",63,609,32,,,4,,1,1,2 Kotlin Standard Library,``kotlin*``,,1835,12,10,,,,,,2 `Spring `_,``org.springframework.*``,29,477,101,,,,19,14,,29 Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.hubspot.jinjava``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",60,300,269,,,,14,18,,3 - Totals,,217,8432,1524,129,6,10,107,33,1,86 + Totals,,217,8434,1530,129,6,10,107,33,1,86 From 313767539ad633e164e13c78d42137ecda54cf72 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 18 Nov 2022 15:59:06 +0100 Subject: [PATCH 436/796] C#: Add workflow for running QL tests --- .github/workflows/csharp-qltest.yml | 72 +++++++++++++++++++ .gitignore | 2 - csharp/.gitignore | 5 +- .../actions/create-extractor-pack/action.yml | 13 ++++ .../controlflow/internal/Completion.qll | 1 - csharp/scripts/create-extractor-pack.sh | 27 +++++++ 6 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/csharp-qltest.yml create mode 100644 csharp/actions/create-extractor-pack/action.yml create mode 100755 csharp/scripts/create-extractor-pack.sh diff --git a/.github/workflows/csharp-qltest.yml b/.github/workflows/csharp-qltest.yml new file mode 100644 index 00000000000..78b0ef6a87b --- /dev/null +++ b/.github/workflows/csharp-qltest.yml @@ -0,0 +1,72 @@ +name: "C#: Run QL Tests" + +on: + push: + paths: + - "csharp/**" + - "shared/**" + - .github/actions/fetch-codeql/action.yml + - codeql-workspace.yml + branches: + - main + - "rc/*" + pull_request: + paths: + - "csharp/**" + - "shared/**" + - .github/workflows/csharp-qltest.yml + - .github/actions/fetch-codeql/action.yml + - codeql-workspace.yml + branches: + - main + - "rc/*" + +defaults: + run: + working-directory: csharp + +jobs: + qlupgrade: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/fetch-codeql + - name: Check DB upgrade scripts + run: | + echo >empty.trap + codeql dataset import -S ql/lib/upgrades/initial/semmlecode.csharp.dbscheme testdb empty.trap + codeql dataset upgrade testdb --additional-packs ql/lib + diff -q testdb/semmlecode.csharp.dbscheme ql/lib/semmlecode.csharp.dbscheme + - name: Check DB downgrade scripts + run: | + echo >empty.trap + rm -rf testdb; codeql dataset import -S ql/lib/semmlecode.csharp.dbscheme testdb empty.trap + codeql resolve upgrades --format=lines --allow-downgrades --additional-packs downgrades \ + --dbscheme=ql/lib/semmlecode.csharp.dbscheme --target-dbscheme=downgrades/initial/semmlecode.csharp.dbscheme | + xargs codeql execute upgrades testdb + diff -q testdb/semmlecode.csharp.dbscheme downgrades/initial/semmlecode.csharp.dbscheme + qltest: + runs-on: ubuntu-latest-xl + strategy: + fail-fast: false + matrix: + slice: ["1/2", "2/2"] + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/fetch-codeql + - uses: ./csharp/actions/create-extractor-pack + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: csharp-qltest-${{ matrix.slice }} + - name: Run QL tests + run: | + CODEQL_PATH=$(gh codeql version --format=json | jq -r .unpackedLocation) + # The legacy ASP extractor is not in this repo, so take the one from the nightly build + mv "$CODEQL_PATH/csharp/tools/extractor-asp.jar" "${{ github.workspace }}/csharp/extractor-pack/tools" + # Safe guard against using the bundled extractor + rm -rf "$CODEQL_PATH/csharp" + codeql test run --threads=0 --ram 52000 --slice ${{ matrix.slice }} --search-path "${{ github.workspace }}/csharp/extractor-pack" --check-databases --check-undefined-labels --check-repeated-labels --check-redefined-labels --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" + env: + GITHUB_TOKEN: ${{ github.token }} diff --git a/.gitignore b/.gitignore index 7b8532b00d2..c81e23fc7f8 100644 --- a/.gitignore +++ b/.gitignore @@ -27,8 +27,6 @@ # It's useful (though not required) to be able to unpack codeql in the ql checkout itself /codeql/ -csharp/extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json - # Avoid committing cached package components .codeql diff --git a/csharp/.gitignore b/csharp/.gitignore index 0701c11fe1d..a030c9444fe 100644 --- a/csharp/.gitignore +++ b/csharp/.gitignore @@ -11,4 +11,7 @@ csharp.log *.tlog .vs *.user -.vscode/launch.json \ No newline at end of file +.vscode/launch.json + +extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json +extractor-pack \ No newline at end of file diff --git a/csharp/actions/create-extractor-pack/action.yml b/csharp/actions/create-extractor-pack/action.yml new file mode 100644 index 00000000000..43b0ec9c6fe --- /dev/null +++ b/csharp/actions/create-extractor-pack/action.yml @@ -0,0 +1,13 @@ +name: Build C# CodeQL pack +description: Builds the C# CodeQL pack +runs: + using: composite + steps: + - name: Setup dotnet + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 6.0.202 + - name: Build Extractor + shell: bash + run: scripts/create-extractor-pack.sh + working-directory: csharp diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Completion.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Completion.qll index bda14e0b4ae..4003e8cfac2 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Completion.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Completion.qll @@ -103,7 +103,6 @@ abstract class Completion extends TCompletion { * otherwise it is a normal non-Boolean completion. */ predicate isValidFor(ControlFlowElement cfe) { - cfe instanceof NonReturningCall and this = cfe.(NonReturningCall).getACompletion() or this = TThrowCompletion(cfe.(TriedControlFlowElement).getAThrownException()) diff --git a/csharp/scripts/create-extractor-pack.sh b/csharp/scripts/create-extractor-pack.sh new file mode 100755 index 00000000000..dbbe8219a02 --- /dev/null +++ b/csharp/scripts/create-extractor-pack.sh @@ -0,0 +1,27 @@ +#!/bin/bash +set -eux + +if [[ "$OSTYPE" == "linux-gnu"* ]]; then + platform="linux64" + dotnet_platform="linux-x64" +elif [[ "$OSTYPE" == "darwin"* ]]; then + platform="osx64" + dotnet_platform="osx-x64" +else + echo "Unknown OS" + exit 1 +fi + +rm -rf extractor-pack +mkdir -p extractor-pack +mkdir -p extractor-pack/tools/${platform} + +function dotnet_publish { + dotnet publish --self-contained --configuration Release --runtime ${dotnet_platform} -p:RuntimeFrameworkVersion=6.0.4 $1 --output extractor-pack/tools/${platform} +} + +dotnet_publish extractor/Semmle.Extraction.CSharp.Standalone +dotnet_publish extractor/Semmle.Extraction.CSharp.Driver +dotnet_publish autobuilder/Semmle.Autobuild.CSharp + +cp -r codeql-extractor.yml tools/* downgrades tools ql/lib/semmlecode.csharp.dbscheme ql/lib/semmlecode.csharp.dbscheme.stats extractor-pack/ From 10c602d9fbd3183079b81decbaf83807d6f3e7ff Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 22 Nov 2022 10:19:50 +0100 Subject: [PATCH 437/796] CI: use read-only-cache when running on a PR --- .github/actions/cache-query-compilation/action.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/actions/cache-query-compilation/action.yml b/.github/actions/cache-query-compilation/action.yml index c071aa204d9..9f7569e5f0c 100644 --- a/.github/actions/cache-query-compilation/action.yml +++ b/.github/actions/cache-query-compilation/action.yml @@ -26,9 +26,10 @@ runs: echo "merge_base=$MERGE_BASE" >> $GITHUB_ENV - name: Read CodeQL query compilation - PR if: ${{ github.event_name == 'pull_request' }} - uses: actions/cache@v3 + uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6 with: path: '**/.cache' + read-only: true key: codeql-compile-${{ inputs.key }}-pr-${{ github.sha }} # deliberately not using the `compile-compile-main` keys here. restore-keys: | codeql-compile-${{ inputs.key }}-${{ github.base_ref }}-${{ env.merge_base }} @@ -36,7 +37,7 @@ runs: codeql-compile-${{ inputs.key }}-main- - name: Fill CodeQL query compilation cache - main if: ${{ github.event_name != 'pull_request' }} - uses: actions/cache@v3 + uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6 with: path: '**/.cache' key: codeql-compile-${{ inputs.key }}-${{ github.ref_name }}-${{ github.sha }} # just fill on main From 414f18fc974088c4d587e0cf7a62d8d8801ee656 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 22 Nov 2022 10:44:47 +0100 Subject: [PATCH 438/796] Swift: fix extractor tests pack This allows `codeql query compile` to run on integration test queries. --- codeql-workspace.yml | 1 + swift/integration-tests/qlpack.yml | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/codeql-workspace.yml b/codeql-workspace.yml index f93ed4ac5c8..1e1691df082 100644 --- a/codeql-workspace.yml +++ b/codeql-workspace.yml @@ -25,6 +25,7 @@ provide: - "misc/suite-helpers/qlpack.yml" - "ruby/extractor-pack/codeql-extractor.yml" - "swift/extractor-pack/codeql-extractor.yml" + - "swift/integration-tests/qlpack.yml" - "ql/extractor-pack/codeql-extractor.ym" versionPolicies: diff --git a/swift/integration-tests/qlpack.yml b/swift/integration-tests/qlpack.yml index f5b65c68822..c0030d14bdf 100644 --- a/swift/integration-tests/qlpack.yml +++ b/swift/integration-tests/qlpack.yml @@ -1,5 +1,6 @@ name: integration-tests-swift version: 0.0.0 -extractor: swift dependencies: - codeql/swift-all: '*' + codeql/swift-all: ${workspace} +tests: . +extractor: swift From d876acde4c4b9fbd3e47e24593264d4b1aa4707c Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 22 Nov 2022 11:01:26 +0100 Subject: [PATCH 439/796] Python: Fix SINK/SINK_F usage for crosstalk tests As discussed in PR review https://github.com/github/codeql/pull/11208#discussion_r1022473421 --- .../dataflow/TestUtil/NormalDataflowTest.qll | 3 ++- .../experimental/dataflow/fieldflow/test.py | 25 ++++++++++++++----- .../test/experimental/dataflow/testConfig.qll | 7 +++--- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/python/ql/test/experimental/dataflow/TestUtil/NormalDataflowTest.qll b/python/ql/test/experimental/dataflow/TestUtil/NormalDataflowTest.qll index b0f0009b30d..f526a1f43ae 100644 --- a/python/ql/test/experimental/dataflow/TestUtil/NormalDataflowTest.qll +++ b/python/ql/test/experimental/dataflow/TestUtil/NormalDataflowTest.qll @@ -16,8 +16,9 @@ class DataFlowTest extends FlowTest { query predicate missingAnnotationOnSink(Location location, string error, string element) { error = "ERROR, you should add `# $ MISSING: flow` annotation" and exists(DataFlow::Node sink | + any(TestConfiguration config).isSink(sink) and + // note: we only care about `SINK` and not `SINK_F`, so we have to reconstruct manually. exists(DataFlow::CallCfgNode call | - // note: we only care about `SINK` and not `SINK_F`, so we have to reconstruct manually. call.getFunction().asCfgNode().(NameNode).getId() = "SINK" and (sink = call.getArg(_) or sink = call.getArgByName(_)) ) and diff --git a/python/ql/test/experimental/dataflow/fieldflow/test.py b/python/ql/test/experimental/dataflow/fieldflow/test.py index f5b20daff96..d9cb0280c73 100644 --- a/python/ql/test/experimental/dataflow/fieldflow/test.py +++ b/python/ql/test/experimental/dataflow/fieldflow/test.py @@ -13,7 +13,17 @@ def is_source(x): return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j -def SINK(x): +def SINK(x, *, not_present_at_runtime=False): + # not_present_at_runtime supports use-cases where we want flow from data-flow layer + # (so we want to use SINK), but we end up in a siaution where it's not possible to + # actually get flow from a source at runtime. The only use-case is for the + # cross-talk tests, where our ability to use if-then-else is limited because doing + # so would make cfg-splitting kick in, and that would solve the problem trivially + # (by the splitting). + if not_present_at_runtime: + print("OK") + return + if is_source(x): print("OK") else: @@ -186,6 +196,9 @@ def test_nested_obj_method(): # ------------------------------------------------------------------------------ # Crosstalk test -- using different function based on conditional # ------------------------------------------------------------------------------ +# NOTE: These tests use `SINK(objy.y, not_present_at_runtime=True)` since it's not +# possible to use if-then-else statements, since that would make cfg-splitting kick in, +# and that would solve the problem trivially (by the splitting). class CrosstalkTestX: def __init__(self): @@ -229,7 +242,7 @@ def test_no_crosstalk_reference(cond=True): SINK(objx.x) # $ flow="SOURCE, l:-4 -> objx.x" SINK_F(objx.y) SINK_F(objy.x) - SINK_F(objy.y) # $ flow="SOURCE, l:-5 -> objy.y" + SINK(objy.y, not_present_at_runtime=True) # $ flow="SOURCE, l:-5 -> objy.y" @expects(8) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) @@ -252,7 +265,7 @@ def test_potential_crosstalk_different_name(cond=True): SINK(objx.x) # $ MISSING: flow="SOURCE, l:-2 -> objx.x" SINK_F(objx.y) SINK_F(objy.x) - SINK_F(objy.y) # $ MISSING: flow="SOURCE, l:-5 -> objy.y" + SINK(objy.y, not_present_at_runtime=True) # $ MISSING: flow="SOURCE, l:-5 -> objy.y" @expects(8) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) @@ -275,7 +288,7 @@ def test_potential_crosstalk_same_name(cond=True): SINK(objx.x) # $ MISSING: flow="SOURCE, l:-2 -> objx.x" SINK_F(objx.y) SINK_F(objy.x) - SINK_F(objy.y) # $ MISSING: flow="SOURCE, l:-5 -> objy.y" + SINK(objy.y, not_present_at_runtime=True) # $ MISSING: flow="SOURCE, l:-5 -> objy.y" @expects(10) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) @@ -298,10 +311,10 @@ def test_potential_crosstalk_same_name_object_reference(cond=True): SINK(objx.x) # $ MISSING: flow="SOURCE, l:-2 -> objx.x" SINK_F(objx.y) SINK_F(objy.x) - SINK_F(objy.y) # $ MISSING: flow="SOURCE, l:-5 -> objy.y" + SINK(objy.y, not_present_at_runtime=True) # $ MISSING: flow="SOURCE, l:-5 -> objy.y" SINK(obj.x) # $ flow="SOURCE, l:-7 -> obj.x" - SINK_F(obj.y) # $ flow="SOURCE, l:-8 -> obj.y" + SINK(obj.y, not_present_at_runtime=True) # $ flow="SOURCE, l:-8 -> obj.y" # ------------------------------------------------------------------------------ diff --git a/python/ql/test/experimental/dataflow/testConfig.qll b/python/ql/test/experimental/dataflow/testConfig.qll index 03815e2f7f9..addbeefeebf 100644 --- a/python/ql/test/experimental/dataflow/testConfig.qll +++ b/python/ql/test/experimental/dataflow/testConfig.qll @@ -38,9 +38,10 @@ class TestConfiguration extends DataFlow::Configuration { } override predicate isSink(DataFlow::Node node) { - exists(CallNode call | - call.getFunction().(NameNode).getId() in ["SINK", "SINK_F"] and - node.(DataFlow::CfgNode).getNode() = call.getAnArg() + exists(DataFlow::CallCfgNode call | + call.getFunction().asCfgNode().(NameNode).getId() in ["SINK", "SINK_F"] and + (node = call.getArg(_) or node = call.getArgByName(_)) and + not node = call.getArgByName("not_present_at_runtime") ) } From 84faf49bf0d63f19dc43619ef2ccfaa1ef3f8be2 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 20 Sep 2022 14:28:44 +0200 Subject: [PATCH 440/796] Python: Add tests for compound arguments field flow --- .../experimental/dataflow/fieldflow/test.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/python/ql/test/experimental/dataflow/fieldflow/test.py b/python/ql/test/experimental/dataflow/fieldflow/test.py index d9cb0280c73..100ab6aac70 100644 --- a/python/ql/test/experimental/dataflow/fieldflow/test.py +++ b/python/ql/test/experimental/dataflow/fieldflow/test.py @@ -193,6 +193,39 @@ def test_nested_obj_method(): SINK(a.obj.foo) # $ flow="SOURCE, l:-3 -> a.obj.foo" +# ------------------------------------------------------------------------------ +# Field access on compound arguments +# ------------------------------------------------------------------------------ + +# TODO: Add support for this, see https://github.com/github/codeql/pull/10444 + +@expects(5) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) +def test_field_on_compound_arg(cond_true=True, cond_false=False): + class Ex: + def __init__(self): + self.attr = None + + def set_attr(obj): + obj.attr = SOURCE + + x = Ex() + y = Ex() + set_attr(x if cond_true else y) + SINK(x.attr) # $ MISSING: flow + + x = Ex() + y = Ex() + set_attr(x if cond_false else y) + SINK(y.attr) # $ MISSING: flow + + x = Ex() + y = Ex() + z = Ex() + set_attr(x if cond_false else (y if cond_true else z)) + SINK_F(x.attr) # $ MISSING: flow + SINK(y.attr) # $ MISSING: flow + SINK_F(z.attr) # $ MISSING: flow + # ------------------------------------------------------------------------------ # Crosstalk test -- using different function based on conditional # ------------------------------------------------------------------------------ From ce2ba21240e6690b3819178c8eccead8e12941b4 Mon Sep 17 00:00:00 2001 From: ka1n4t <574702476@qq.com> Date: Tue, 22 Nov 2022 18:32:14 +0800 Subject: [PATCH 441/796] Add binding between annotation and sink-param --- .../src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll b/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll index 3351af22a25..8399efcc229 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll @@ -134,7 +134,8 @@ predicate isMybatisXmlOrAnnotationSqlInjection( .matches("${" + annotation.getValue("value").(CompileTimeConstantExpr).getStringValue() + "%}") and annotation.getType() instanceof TypeParam and - ma.getAnArgument() = node.asExpr() + ma.getAnArgument() = node.asExpr() and + annotation.getTarget() = ma.getMethod().getParameter(node.asExpr().getIndex()) ) or // MyBatis default parameter sql injection vulnerabilities.the default parameter form of the method is arg[0...n] or param[1...n]. From 43f4dd8bc4db753aac52fc945832b6787494d608 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Mon, 21 Nov 2022 10:10:38 +0100 Subject: [PATCH 442/796] Consider taint through bitwise operations on PendingIntent flags --- .../code/java/security/ImplicitPendingIntents.qll | 15 +++++++++++++-- .../CWE-927/ImplicitPendingIntentsTest.java | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll index 3441cfaef18..bbfafc2d9c4 100644 --- a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll +++ b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll @@ -85,9 +85,11 @@ private class MutablePendingIntentFlowStep extends ImplicitPendingIntentAddition // unless it is at least sometimes explicitly marked immutable and never marked mutable. // Note: for API level < 31, PendingIntents were mutable by default, whereas since then // they are immutable by default. - not TaintTracking::localExprTaint(any(ImmutablePendingIntentFlag flag).getAnAccess(), flagArg) + not bitwiseLocalTaintStep*(DataFlow::exprNode(any(ImmutablePendingIntentFlag flag) + .getAnAccess()), DataFlow::exprNode(flagArg)) or - TaintTracking::localExprTaint(any(MutablePendingIntentFlag flag).getAnAccess(), flagArg) + bitwiseLocalTaintStep*(DataFlow::exprNode(any(MutablePendingIntentFlag flag).getAnAccess()), + DataFlow::exprNode(flagArg)) ) } } @@ -124,3 +126,12 @@ private class PendingIntentSentSinkModels extends SinkModelCsv { ] } } + +/** + * Holds if taint can flow from `source` to `sink` in one local step, + * including bitwise operations. + */ +private predicate bitwiseLocalTaintStep(DataFlow::Node source, DataFlow::Node sink) { + TaintTracking::localTaintStep(source, sink) or + source.asExpr() = sink.asExpr().(BitwiseExpr).(BinaryExpr).getAnOperand() +} diff --git a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java index 9c8f098d467..746c9ca83dc 100644 --- a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java +++ b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java @@ -156,7 +156,7 @@ public class ImplicitPendingIntentsTest { PendingIntent pi = PendingIntent.getActivity(ctx, 0, baseIntent, flag); // Sanitizer Intent fwdIntent = new Intent(); fwdIntent.putExtra("fwdIntent", pi); - ctx.startActivity(fwdIntent); // $ SPURIOUS: $ hasImplicitPendingIntent + ctx.startActivity(fwdIntent); // Safe } } From 1667fbad88abb40cd9970c3471bdf79a2ca26517 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Tue, 22 Nov 2022 11:48:21 +0100 Subject: [PATCH 443/796] Add change note --- .../change-notes/2022-11-22-bitwise-implicit-intent-flags.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/src/change-notes/2022-11-22-bitwise-implicit-intent-flags.md diff --git a/java/ql/src/change-notes/2022-11-22-bitwise-implicit-intent-flags.md b/java/ql/src/change-notes/2022-11-22-bitwise-implicit-intent-flags.md new file mode 100644 index 00000000000..20612e86325 --- /dev/null +++ b/java/ql/src/change-notes/2022-11-22-bitwise-implicit-intent-flags.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Fixed an issue in the query `java/android/implicit-pendingintents` by which an implicit Pending Intent marked as immutable was not correctly recognized as such. From 18be30d1774ab7a84452da1306f69941f2ea3b6b Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 22 Nov 2022 13:46:45 +0100 Subject: [PATCH 444/796] Python: Apply suggestion from review Co-authored-by: Rasmus Wriedt Larsen --- .../ql/lib/change-notes/2022-11-21-module-resolution-rewrite.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/change-notes/2022-11-21-module-resolution-rewrite.md b/python/ql/lib/change-notes/2022-11-21-module-resolution-rewrite.md index 32484ffed56..fa04c07e9d5 100644 --- a/python/ql/lib/change-notes/2022-11-21-module-resolution-rewrite.md +++ b/python/ql/lib/change-notes/2022-11-21-module-resolution-rewrite.md @@ -2,4 +2,4 @@ category: minorAnalysis --- * The data-flow library has been rewritten to no longer rely on the points-to analysis in order to - resolve references to modules. This should result in more results for data-flow queries. + resolve references to modules. Improvements in the module resolution can lead to more results. From e01df3ea7c502e5e6c19c6063b408ff2b474d48a Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 22 Nov 2022 13:38:10 +0100 Subject: [PATCH 445/796] Python: Prepare for new test .expected line changes :angry: --- .../CleartextLogging.expected | 12 ++++++------ .../Security/CWE-312-CleartextLogging/test.py | 5 +++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected index e9b5ac67585..00de056f78b 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected @@ -4,8 +4,8 @@ edges | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:23:58:23:65 | ControlFlowNode for password | | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:27:40:27:47 | ControlFlowNode for password | | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:30:58:30:65 | ControlFlowNode for password | -| test.py:65:14:68:5 | ControlFlowNode for Dict | test.py:69:11:69:31 | ControlFlowNode for Subscript | -| test.py:67:21:67:37 | ControlFlowNode for Attribute | test.py:65:14:68:5 | ControlFlowNode for Dict | +| test.py:70:14:73:5 | ControlFlowNode for Dict | test.py:74:11:74:31 | ControlFlowNode for Subscript | +| test.py:72:21:72:37 | ControlFlowNode for Attribute | test.py:70:14:73:5 | ControlFlowNode for Dict | nodes | test.py:19:16:19:29 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test.py:20:48:20:55 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | @@ -17,9 +17,9 @@ nodes | test.py:37:11:37:24 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test.py:39:22:39:35 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test.py:40:22:40:35 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | -| test.py:65:14:68:5 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| test.py:67:21:67:37 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:69:11:69:31 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | +| test.py:70:14:73:5 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| test.py:72:21:72:37 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:74:11:74:31 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | subpaths #select | test.py:20:48:20:55 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:20:48:20:55 | ControlFlowNode for password | This expression logs $@ as clear text. | test.py:19:16:19:29 | ControlFlowNode for get_password() | sensitive data (password) | @@ -31,4 +31,4 @@ subpaths | test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:37:11:37:24 | ControlFlowNode for get_password() | sensitive data (password) | | test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:39:22:39:35 | ControlFlowNode for get_password() | sensitive data (password) | | test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:40:22:40:35 | ControlFlowNode for get_password() | sensitive data (password) | -| test.py:69:11:69:31 | ControlFlowNode for Subscript | test.py:67:21:67:37 | ControlFlowNode for Attribute | test.py:69:11:69:31 | ControlFlowNode for Subscript | This expression logs $@ as clear text. | test.py:67:21:67:37 | ControlFlowNode for Attribute | sensitive data (password) | +| test.py:74:11:74:31 | ControlFlowNode for Subscript | test.py:72:21:72:37 | ControlFlowNode for Attribute | test.py:74:11:74:31 | ControlFlowNode for Subscript | This expression logs $@ as clear text. | test.py:72:21:72:37 | ControlFlowNode for Attribute | sensitive data (password) | diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/test.py b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/test.py index 0a3d97426e0..265bda6d53d 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/test.py +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/test.py @@ -39,6 +39,11 @@ def print_password(): sys.stdout.write(get_password()) # NOT OK sys.stderr.write(get_password()) # NOT OK + # import getpass + + # x = getpass.getpass() + # print(x) # NOT OK + def FPs(account, account_id): # we assume that any account parameter is sensitive (id/username) From 9342e3ba76ec910fabd19f739a85dd0192e93b3b Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 22 Nov 2022 13:59:59 +0100 Subject: [PATCH 446/796] Python: Enable new test But look at all those elements from getpass.py implementation :( --- .../CleartextLogging.expected | 35 +++++++++++++++++++ .../Security/CWE-312-CleartextLogging/test.py | 6 ++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected index 00de056f78b..9d8152dd627 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected @@ -1,12 +1,37 @@ edges +| file:///usr/lib/python3.8/getpass.py:44:14:44:17 | ControlFlowNode for None | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | +| file:///usr/lib/python3.8/getpass.py:44:14:44:17 | ControlFlowNode for None | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | +| file:///usr/lib/python3.8/getpass.py:44:14:44:17 | ControlFlowNode for None | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | +| file:///usr/lib/python3.8/getpass.py:62:26:62:57 | ControlFlowNode for fallback_getpass() | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | +| file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | +| file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | +| file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | +| file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | +| file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | +| file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | +| file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | test.py:44:9:44:25 | ControlFlowNode for Attribute() | +| file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | test.py:44:9:44:25 | ControlFlowNode for Attribute() | +| file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | test.py:44:9:44:25 | ControlFlowNode for Attribute() | | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:20:48:20:55 | ControlFlowNode for password | | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:22:58:22:65 | ControlFlowNode for password | | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:23:58:23:65 | ControlFlowNode for password | | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:27:40:27:47 | ControlFlowNode for password | | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:30:58:30:65 | ControlFlowNode for password | +| test.py:44:9:44:25 | ControlFlowNode for Attribute() | test.py:45:11:45:11 | ControlFlowNode for x | | test.py:70:14:73:5 | ControlFlowNode for Dict | test.py:74:11:74:31 | ControlFlowNode for Subscript | | test.py:72:21:72:37 | ControlFlowNode for Attribute | test.py:70:14:73:5 | ControlFlowNode for Dict | nodes +| file:///usr/lib/python3.8/getpass.py:44:14:44:17 | ControlFlowNode for None | semmle.label | ControlFlowNode for None | +| file:///usr/lib/python3.8/getpass.py:62:26:62:57 | ControlFlowNode for fallback_getpass() | semmle.label | ControlFlowNode for fallback_getpass() | +| file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | semmle.label | ControlFlowNode for _raw_input() | +| file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | semmle.label | ControlFlowNode for _raw_input() | +| file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | semmle.label | ControlFlowNode for _raw_input() | +| file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | semmle.label | ControlFlowNode for fallback_getpass() | +| file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | semmle.label | ControlFlowNode for fallback_getpass() | +| file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | semmle.label | ControlFlowNode for fallback_getpass() | +| file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | semmle.label | ControlFlowNode for passwd | +| file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | semmle.label | ControlFlowNode for passwd | +| file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | semmle.label | ControlFlowNode for passwd | | test.py:19:16:19:29 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test.py:20:48:20:55 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | | test.py:22:58:22:65 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | @@ -17,6 +42,8 @@ nodes | test.py:37:11:37:24 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test.py:39:22:39:35 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test.py:40:22:40:35 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | +| test.py:44:9:44:25 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:45:11:45:11 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | | test.py:70:14:73:5 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | | test.py:72:21:72:37 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:74:11:74:31 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -31,4 +58,12 @@ subpaths | test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:37:11:37:24 | ControlFlowNode for get_password() | sensitive data (password) | | test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:39:22:39:35 | ControlFlowNode for get_password() | sensitive data (password) | | test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:40:22:40:35 | ControlFlowNode for get_password() | sensitive data (password) | +| test.py:45:11:45:11 | ControlFlowNode for x | file:///usr/lib/python3.8/getpass.py:44:14:44:17 | ControlFlowNode for None | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | file:///usr/lib/python3.8/getpass.py:44:14:44:17 | ControlFlowNode for None | sensitive data (password) | +| test.py:45:11:45:11 | ControlFlowNode for x | file:///usr/lib/python3.8/getpass.py:62:26:62:57 | ControlFlowNode for fallback_getpass() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | file:///usr/lib/python3.8/getpass.py:62:26:62:57 | ControlFlowNode for fallback_getpass() | sensitive data (password) | +| test.py:45:11:45:11 | ControlFlowNode for x | file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | sensitive data (password) | +| test.py:45:11:45:11 | ControlFlowNode for x | file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | sensitive data (password) | +| test.py:45:11:45:11 | ControlFlowNode for x | file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | sensitive data (password) | +| test.py:45:11:45:11 | ControlFlowNode for x | file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | sensitive data (password) | +| test.py:45:11:45:11 | ControlFlowNode for x | file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | sensitive data (password) | +| test.py:45:11:45:11 | ControlFlowNode for x | file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | sensitive data (password) | | test.py:74:11:74:31 | ControlFlowNode for Subscript | test.py:72:21:72:37 | ControlFlowNode for Attribute | test.py:74:11:74:31 | ControlFlowNode for Subscript | This expression logs $@ as clear text. | test.py:72:21:72:37 | ControlFlowNode for Attribute | sensitive data (password) | diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/test.py b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/test.py index 265bda6d53d..b5ebe7593ba 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/test.py +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/test.py @@ -39,10 +39,10 @@ def print_password(): sys.stdout.write(get_password()) # NOT OK sys.stderr.write(get_password()) # NOT OK - # import getpass + import getpass - # x = getpass.getpass() - # print(x) # NOT OK + x = getpass.getpass() + print(x) # NOT OK def FPs(account, account_id): From 80e71b202a851dc8605862bfe774683ddce177db Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 22 Nov 2022 14:08:00 +0100 Subject: [PATCH 447/796] Python: Cleartext queires: Remove flow from getpass.py --- .../dataflow/new/SensitiveDataSources.qll | 12 ++++++- .../CleartextLogging.expected | 35 ------------------- 2 files changed, 11 insertions(+), 36 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/SensitiveDataSources.qll b/python/ql/lib/semmle/python/dataflow/new/SensitiveDataSources.qll index 65d334f1c38..e5ee3e346b5 100644 --- a/python/ql/lib/semmle/python/dataflow/new/SensitiveDataSources.qll +++ b/python/ql/lib/semmle/python/dataflow/new/SensitiveDataSources.qll @@ -23,7 +23,17 @@ module SensitiveDataClassification = SensitiveDataHeuristics::SensitiveDataClass class SensitiveDataSource extends DataFlow::Node { SensitiveDataSource::Range range; - SensitiveDataSource() { this = range } + SensitiveDataSource() { + this = range and + // ignore sensitive password sources in getpass.py, that can escape through `getpass.getpass()` return value, + // since `getpass.getpass()` is considered a source itself. + not exists(Module getpass | + getpass.getName() = "getpass" and + this.getScope().getEnclosingModule() = getpass and + // do allow this call if we're analyzing getpass.py as part of CPython though + not exists(getpass.getFile().getRelativePath()) + ) + } /** * Gets the classification of the sensitive data. diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected index 9d8152dd627..00de056f78b 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected @@ -1,37 +1,12 @@ edges -| file:///usr/lib/python3.8/getpass.py:44:14:44:17 | ControlFlowNode for None | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | -| file:///usr/lib/python3.8/getpass.py:44:14:44:17 | ControlFlowNode for None | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | -| file:///usr/lib/python3.8/getpass.py:44:14:44:17 | ControlFlowNode for None | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | -| file:///usr/lib/python3.8/getpass.py:62:26:62:57 | ControlFlowNode for fallback_getpass() | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | -| file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | -| file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | -| file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | -| file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | -| file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | -| file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | -| file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | test.py:44:9:44:25 | ControlFlowNode for Attribute() | -| file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | test.py:44:9:44:25 | ControlFlowNode for Attribute() | -| file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | test.py:44:9:44:25 | ControlFlowNode for Attribute() | | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:20:48:20:55 | ControlFlowNode for password | | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:22:58:22:65 | ControlFlowNode for password | | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:23:58:23:65 | ControlFlowNode for password | | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:27:40:27:47 | ControlFlowNode for password | | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:30:58:30:65 | ControlFlowNode for password | -| test.py:44:9:44:25 | ControlFlowNode for Attribute() | test.py:45:11:45:11 | ControlFlowNode for x | | test.py:70:14:73:5 | ControlFlowNode for Dict | test.py:74:11:74:31 | ControlFlowNode for Subscript | | test.py:72:21:72:37 | ControlFlowNode for Attribute | test.py:70:14:73:5 | ControlFlowNode for Dict | nodes -| file:///usr/lib/python3.8/getpass.py:44:14:44:17 | ControlFlowNode for None | semmle.label | ControlFlowNode for None | -| file:///usr/lib/python3.8/getpass.py:62:26:62:57 | ControlFlowNode for fallback_getpass() | semmle.label | ControlFlowNode for fallback_getpass() | -| file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | semmle.label | ControlFlowNode for _raw_input() | -| file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | semmle.label | ControlFlowNode for _raw_input() | -| file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | semmle.label | ControlFlowNode for _raw_input() | -| file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | semmle.label | ControlFlowNode for fallback_getpass() | -| file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | semmle.label | ControlFlowNode for fallback_getpass() | -| file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | semmle.label | ControlFlowNode for fallback_getpass() | -| file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | semmle.label | ControlFlowNode for passwd | -| file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | semmle.label | ControlFlowNode for passwd | -| file:///usr/lib/python3.8/getpass.py:94:16:94:21 | ControlFlowNode for passwd | semmle.label | ControlFlowNode for passwd | | test.py:19:16:19:29 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test.py:20:48:20:55 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | | test.py:22:58:22:65 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | @@ -42,8 +17,6 @@ nodes | test.py:37:11:37:24 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test.py:39:22:39:35 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test.py:40:22:40:35 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | -| test.py:44:9:44:25 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| test.py:45:11:45:11 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | | test.py:70:14:73:5 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | | test.py:72:21:72:37 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:74:11:74:31 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -58,12 +31,4 @@ subpaths | test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:37:11:37:24 | ControlFlowNode for get_password() | sensitive data (password) | | test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:39:22:39:35 | ControlFlowNode for get_password() | sensitive data (password) | | test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:40:22:40:35 | ControlFlowNode for get_password() | sensitive data (password) | -| test.py:45:11:45:11 | ControlFlowNode for x | file:///usr/lib/python3.8/getpass.py:44:14:44:17 | ControlFlowNode for None | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | file:///usr/lib/python3.8/getpass.py:44:14:44:17 | ControlFlowNode for None | sensitive data (password) | -| test.py:45:11:45:11 | ControlFlowNode for x | file:///usr/lib/python3.8/getpass.py:62:26:62:57 | ControlFlowNode for fallback_getpass() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | file:///usr/lib/python3.8/getpass.py:62:26:62:57 | ControlFlowNode for fallback_getpass() | sensitive data (password) | -| test.py:45:11:45:11 | ControlFlowNode for x | file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | sensitive data (password) | -| test.py:45:11:45:11 | ControlFlowNode for x | file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | sensitive data (password) | -| test.py:45:11:45:11 | ControlFlowNode for x | file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | file:///usr/lib/python3.8/getpass.py:77:30:77:68 | ControlFlowNode for _raw_input() | sensitive data (password) | -| test.py:45:11:45:11 | ControlFlowNode for x | file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | sensitive data (password) | -| test.py:45:11:45:11 | ControlFlowNode for x | file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | sensitive data (password) | -| test.py:45:11:45:11 | ControlFlowNode for x | file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | file:///usr/lib/python3.8/getpass.py:91:26:91:57 | ControlFlowNode for fallback_getpass() | sensitive data (password) | | test.py:74:11:74:31 | ControlFlowNode for Subscript | test.py:72:21:72:37 | ControlFlowNode for Attribute | test.py:74:11:74:31 | ControlFlowNode for Subscript | This expression logs $@ as clear text. | test.py:72:21:72:37 | ControlFlowNode for Attribute | sensitive data (password) | From 9195b73d8447b23670cb8433338af7be14073e8a Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 22 Nov 2022 14:08:16 +0100 Subject: [PATCH 448/796] Python: Model `getpass.getpass` as source of passwords --- .../python/dataflow/new/SensitiveDataSources.qll | 12 ++++++++++++ python/ql/src/change-notes/2022-11-22-getpass.md | 4 ++++ .../CleartextLogging.expected | 4 ++++ 3 files changed, 20 insertions(+) create mode 100644 python/ql/src/change-notes/2022-11-22-getpass.md diff --git a/python/ql/lib/semmle/python/dataflow/new/SensitiveDataSources.qll b/python/ql/lib/semmle/python/dataflow/new/SensitiveDataSources.qll index e5ee3e346b5..926ae46d33e 100644 --- a/python/ql/lib/semmle/python/dataflow/new/SensitiveDataSources.qll +++ b/python/ql/lib/semmle/python/dataflow/new/SensitiveDataSources.qll @@ -8,6 +8,7 @@ private import semmle.python.dataflow.new.DataFlow // Need to import `semmle.python.Frameworks` since frameworks can extend `SensitiveDataSource::Range` private import semmle.python.Frameworks private import semmle.python.security.internal.SensitiveDataHeuristics as SensitiveDataHeuristics +private import semmle.python.ApiGraphs // We export these explicitly, so we don't also export the `HeuristicNames` module. class SensitiveDataClassification = SensitiveDataHeuristics::SensitiveDataClassification; @@ -322,6 +323,17 @@ private module SensitiveDataModeling { override SensitiveDataClassification getClassification() { result = classification } } + + /** + * A call to `getpass.getpass`, see https://docs.python.org/3.10/library/getpass.html#getpass.getpass + */ + class GetPassCall extends SensitiveDataSource::Range, API::CallNode { + GetPassCall() { this = API::moduleImport("getpass").getMember("getpass").getACall() } + + override SensitiveDataClassification getClassification() { + result = SensitiveDataClassification::password() + } + } } predicate sensitiveDataExtraStepForCalls = SensitiveDataModeling::extraStepForCalls/2; diff --git a/python/ql/src/change-notes/2022-11-22-getpass.md b/python/ql/src/change-notes/2022-11-22-getpass.md new file mode 100644 index 00000000000..d9df302bc63 --- /dev/null +++ b/python/ql/src/change-notes/2022-11-22-getpass.md @@ -0,0 +1,4 @@ +--- + category: minorAnalysis +--- + * Added modeling of `getpass.getpass` as a source of passwords, which will be an additional source for `py/clear-text-logging-sensitive-data`, `py/clear-text-storage-sensitive-data`, and `py/weak-sensitive-data-hashing`. diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected index 00de056f78b..b2162352bae 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected @@ -4,6 +4,7 @@ edges | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:23:58:23:65 | ControlFlowNode for password | | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:27:40:27:47 | ControlFlowNode for password | | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:30:58:30:65 | ControlFlowNode for password | +| test.py:44:9:44:25 | ControlFlowNode for Attribute() | test.py:45:11:45:11 | ControlFlowNode for x | | test.py:70:14:73:5 | ControlFlowNode for Dict | test.py:74:11:74:31 | ControlFlowNode for Subscript | | test.py:72:21:72:37 | ControlFlowNode for Attribute | test.py:70:14:73:5 | ControlFlowNode for Dict | nodes @@ -17,6 +18,8 @@ nodes | test.py:37:11:37:24 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test.py:39:22:39:35 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test.py:40:22:40:35 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | +| test.py:44:9:44:25 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:45:11:45:11 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | | test.py:70:14:73:5 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | | test.py:72:21:72:37 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:74:11:74:31 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -31,4 +34,5 @@ subpaths | test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:37:11:37:24 | ControlFlowNode for get_password() | sensitive data (password) | | test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:39:22:39:35 | ControlFlowNode for get_password() | sensitive data (password) | | test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:40:22:40:35 | ControlFlowNode for get_password() | sensitive data (password) | +| test.py:45:11:45:11 | ControlFlowNode for x | test.py:44:9:44:25 | ControlFlowNode for Attribute() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | test.py:44:9:44:25 | ControlFlowNode for Attribute() | sensitive data (password) | | test.py:74:11:74:31 | ControlFlowNode for Subscript | test.py:72:21:72:37 | ControlFlowNode for Attribute | test.py:74:11:74:31 | ControlFlowNode for Subscript | This expression logs $@ as clear text. | test.py:72:21:72:37 | ControlFlowNode for Attribute | sensitive data (password) | From 2e1a78e1bfa2e8c412a1651c102c4f15e722bd34 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Tue, 22 Nov 2022 14:44:05 +0100 Subject: [PATCH 449/796] Add models for NSData and NSMutableData --- .../codeql/swift/dataflow/ExternalFlow.qll | 1 + .../frameworks/StandardLibrary/NSData.qll | 92 +++++ .../dataflow/flowsources/FlowSources.expected | 4 + .../dataflow/flowsources/nsdata.swift | 20 + .../dataflow/taint/LocalTaint.expected | 3 + .../dataflow/taint/Taint.expected | 363 ++++++++++++++++++ .../library-tests/dataflow/taint/nsdata.swift | 141 +++++++ .../dataflow/taint/nsmutabledata.swift | 50 +++ 8 files changed, 674 insertions(+) create mode 100644 swift/ql/lib/codeql/swift/frameworks/StandardLibrary/NSData.qll create mode 100644 swift/ql/test/library-tests/dataflow/flowsources/nsdata.swift create mode 100644 swift/ql/test/library-tests/dataflow/taint/nsdata.swift create mode 100644 swift/ql/test/library-tests/dataflow/taint/nsmutabledata.swift diff --git a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll index 4d563525830..9e0433958ba 100644 --- a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll +++ b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll @@ -81,6 +81,7 @@ private module Frameworks { private import codeql.swift.frameworks.StandardLibrary.CustomUrlSchemes private import codeql.swift.frameworks.StandardLibrary.Data private import codeql.swift.frameworks.StandardLibrary.InputStream + private import codeql.swift.frameworks.StandardLibrary.NSData private import codeql.swift.frameworks.StandardLibrary.String private import codeql.swift.frameworks.StandardLibrary.Url private import codeql.swift.frameworks.StandardLibrary.UrlSession diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/NSData.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/NSData.qll new file mode 100644 index 00000000000..4fd8cba33fc --- /dev/null +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/NSData.qll @@ -0,0 +1,92 @@ +/** Provides classes and models to work with `NSData`-related objects. */ + +import swift +private import codeql.swift.dataflow.DataFlow +private import codeql.swift.dataflow.ExternalFlow +private import codeql.swift.dataflow.FlowSteps + +/** The class `NSData`. */ +class NsData extends ClassDecl { + NsData() { this.getFullName() = "NSData" } +} + +/** The class `NSMutableData`. */ +class NsMutableData extends ClassDecl { + NsMutableData() { this.getFullName() = "NSMutableData" } +} + +private class NsDataSources extends SourceModelCsv { + override predicate row(string row) { + row = + [ + ";NSData;true;init(contentsOf:);;;ReturnValue;remote", + ";NSData;true;init(contentsOf:options:);;;ReturnValue;remote" + ] + } +} + +private class NsDataSummaries extends SummaryModelCsv { + override predicate row(string row) { + row = + [ + ";NSData;true;init(bytes:length:);;;Argument[0];ReturnValue;taint", + ";NSData;true;init(bytesNoCopy:length:);;;Argument[0];ReturnValue;taint", + ";NSData;true;init(bytesNoCopy:length:deallocator:);;;Argument[0];ReturnValue;taint", + ";NSData;true;init(bytesNoCopy:length:freeWhenDone:);;;Argument[0];ReturnValue;taint", + ";NSData;true;init(data:);;;Argument[0];ReturnValue;taint", + ";NSData;true;init(contentsOfFile:);;;Argument[0];ReturnValue;taint", + ";NSData;true;init(contentsOfFile:options:);;;Argument[0];ReturnValue;taint", + ";NSData;true;init(contentsOf:);;;Argument[0];ReturnValue;taint", + ";NSData;true;init(contentsOf:options:);;;Argument[0];ReturnValue;taint", + ";NSData;true;init(contentsOfMappedFile:);;;Argument[0];ReturnValue;taint", + ";NSData;true;init(base64Encoded:options:);;;Argument[0];ReturnValue;taint", + ";NSData;true;init(base64Encoding:);;;Argument[0];ReturnValue;taint", + ";NSData;true;base64EncodedData(options:);;;Argument[-1];ReturnValue;taint", + ";NSData;true;base64EncodedString(options:);;;Argument[-1];ReturnValue;taint", + ";NSData;true;base64Encoding();;;Argument[-1];ReturnValue;taint", + ";NSData;true;dataWithContentsOfMappedFile(_:);;;Argument[0];ReturnValue;taint", + // TODO: Needs block flow + // ";NSData;true;enumerateBytes(_:);;;Argument[-1];Argument[0].Parameter[0];taint" + ";NSData;true;getBytes(_:);;;Argument[-1];Argument[0];taint", + ";NSData;true;getBytes(_:length:);;;Argument[-1];Argument[0];taint", + ";NSData;true;getBytes(_:range:);;;Argument[-1];Argument[0];taint", + ";NSData;true;subdata(with:);;;Argument[-1];ReturnValue;taint", + ";NSData;true;compressed(using:);;;Argument[-1];ReturnValue;taint", + ";NSData;true;decompressed(using:);;;Argument[-1];ReturnValue;taint" + ] + } +} + +private class NsMutableDataSummaries extends SummaryModelCsv { + override predicate row(string row) { + row = + [ + ";NSMutableData;true;append(_:length:);;;Argument[0];Argument[-1];taint", + ";NSMutableData;true;append(_:);;;Argument[0];Argument[-1];taint", + ";NSMutableData;true;replaceBytes(in:withBytes:);;;Argument[1];Argument[-1];taint", + ";NSMutableData;true;replaceBytes(in:withBytes:length:);;;Argument[1];Argument[-1];taint", + ";NSMutableData;true;setData(_:);;;Argument[0];Argument[-1];taint", + ] + } +} + +/** A content implying that, if a `NSData` object is tainted, some of its fields are also tainted. */ +private class NsDataTaintedFields extends TaintInheritingContent, DataFlow::Content::FieldContent { + NsDataTaintedFields() { + exists(FieldDecl f | this.getField() = f | + f.getEnclosingDecl() instanceof NsData and + f.getName() = ["bytes", "description"] + ) + } +} + +/** A content implying that, if a `NSMutableData` object is tainted, some of its fields are also tainted. */ +private class NsMutableDataTaintedFields extends TaintInheritingContent, + DataFlow::Content::FieldContent { + NsMutableDataTaintedFields() { + exists(FieldDecl f | this.getField() = f | + f.getEnclosingDecl() instanceof NsMutableData and + f.getName() = "mutableBytes" + ) + } +} diff --git a/swift/ql/test/library-tests/dataflow/flowsources/FlowSources.expected b/swift/ql/test/library-tests/dataflow/flowsources/FlowSources.expected index d3deab14155..01c18633b5d 100644 --- a/swift/ql/test/library-tests/dataflow/flowsources/FlowSources.expected +++ b/swift/ql/test/library-tests/dataflow/flowsources/FlowSources.expected @@ -3,6 +3,10 @@ | customurlschemes.swift:38:52:38:62 | url | external | | customurlschemes.swift:43:9:43:28 | ...[...] | Remote URL in UIApplicationDelegate.application.launchOptions | | customurlschemes.swift:48:9:48:28 | ...[...] | Remote URL in UIApplicationDelegate.application.launchOptions | +| nsdata.swift:18:17:18:17 | call to init(contentsOf:) | external | +| nsdata.swift:18:17:18:40 | call to init(contentsOf:) | external | +| nsdata.swift:19:17:19:17 | call to init(contentsOf:options:) | external | +| nsdata.swift:19:17:19:53 | call to init(contentsOf:options:) | external | | string.swift:56:21:56:21 | call to init(contentsOf:) | external | | string.swift:56:21:56:44 | call to init(contentsOf:) | external | | string.swift:57:21:57:21 | call to init(contentsOf:encoding:) | external | diff --git a/swift/ql/test/library-tests/dataflow/flowsources/nsdata.swift b/swift/ql/test/library-tests/dataflow/flowsources/nsdata.swift new file mode 100644 index 00000000000..d1258f10364 --- /dev/null +++ b/swift/ql/test/library-tests/dataflow/flowsources/nsdata.swift @@ -0,0 +1,20 @@ +// --- stubs --- + +struct URL +{ + init?(string: String) {} +} + +class NSData { + struct ReadingOptions : OptionSet { let rawValue: Int } + init?(contentsOf: URL) {} + init?(contentsOf: URL, options: NSData.ReadingOptions) {} +} + +// --- tests --- + +func testNSData() { + let url = URL(string: "http://example.com/") + let _ = try NSData(contentsOf: url!) // SOURCE + let _ = try NSData(contentsOf: url!, options: []) // SOURCE +} diff --git a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected index c5b7944178a..e2c893738d3 100644 --- a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected @@ -1,3 +1,6 @@ +| nsdata.swift:139:15:139:15 | nsDataTainted24 | nsdata.swift:139:15:139:31 | .bytes | +| nsdata.swift:140:15:140:15 | nsDataTainted24 | nsdata.swift:140:15:140:31 | .description | +| nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 | nsmutabledata.swift:49:15:49:37 | .mutableBytes | | string.swift:7:13:7:13 | | string.swift:7:13:7:13 | [post] | | string.swift:7:13:7:13 | | string.swift:7:14:7:14 | [post] &... | | string.swift:7:13:7:13 | TapExpr | string.swift:7:13:7:13 | "..." | diff --git a/swift/ql/test/library-tests/dataflow/taint/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/Taint.expected index b562c44bdc5..16e2f0bec8d 100644 --- a/swift/ql/test/library-tests/dataflow/taint/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/Taint.expected @@ -1,5 +1,141 @@ edges | file://:0:0:0:0 | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : | url.swift:120:61:120:61 | data : | +| nsdata.swift:22:9:22:9 | self : | file://:0:0:0:0 | .bytes : | +| nsdata.swift:23:9:23:9 | self : | file://:0:0:0:0 | .description : | +| nsdata.swift:24:5:24:50 | [summary param] 0 in init(bytes:length:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytes:length:) : | +| nsdata.swift:25:5:25:68 | [summary param] 0 in init(bytesNoCopy:length:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:length:) : | +| nsdata.swift:26:5:26:130 | [summary param] 0 in init(bytesNoCopy:length:deallocator:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:length:deallocator:) : | +| nsdata.swift:27:5:27:90 | [summary param] 0 in init(bytesNoCopy:length:freeWhenDone:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:length:freeWhenDone:) : | +| nsdata.swift:28:5:28:23 | [summary param] 0 in init(data:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(data:) : | +| nsdata.swift:29:5:29:36 | [summary param] 0 in init(contentsOfFile:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOfFile:) : | +| nsdata.swift:30:5:30:93 | [summary param] 0 in init(contentsOfFile:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOfFile:options:) : | +| nsdata.swift:31:5:31:29 | [summary param] 0 in init(contentsOf:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOf:) : | +| nsdata.swift:32:5:32:61 | [summary param] 0 in init(contentsOf:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOf:options:) : | +| nsdata.swift:33:5:33:47 | [summary param] 0 in init(contentsOfMappedFile:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOfMappedFile:) : | +| nsdata.swift:34:5:34:88 | [summary param] 0 in init(base64Encoded:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | +| nsdata.swift:35:5:35:92 | [summary param] 0 in init(base64Encoded:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | +| nsdata.swift:36:5:36:49 | [summary param] 0 in init(base64Encoding:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoding:) : | +| nsdata.swift:37:5:37:98 | [summary param] this in base64EncodedData(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedData(options:) : | +| nsdata.swift:38:5:38:96 | [summary param] this in base64EncodedString(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedString(options:) : | +| nsdata.swift:39:5:39:49 | [summary param] this in base64Encoding() : | file://:0:0:0:0 | [summary] to write: return (return) in base64Encoding() : | +| nsdata.swift:40:5:40:82 | [summary param] 0 in dataWithContentsOfMappedFile(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in dataWithContentsOfMappedFile(_:) : | +| nsdata.swift:42:5:42:55 | [summary param] this in getBytes(_:) : | file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:) : | +| nsdata.swift:43:5:43:68 | [summary param] this in getBytes(_:length:) : | file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:length:) : | +| nsdata.swift:44:5:44:71 | [summary param] this in getBytes(_:range:) : | file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:range:) : | +| nsdata.swift:45:5:45:65 | [summary param] this in subdata(with:) : | file://:0:0:0:0 | [summary] to write: return (return) in subdata(with:) : | +| nsdata.swift:46:5:46:89 | [summary param] this in compressed(using:) : | file://:0:0:0:0 | [summary] to write: return (return) in compressed(using:) : | +| nsdata.swift:47:5:47:91 | [summary param] this in decompressed(using:) : | file://:0:0:0:0 | [summary] to write: return (return) in decompressed(using:) : | +| nsdata.swift:57:26:57:80 | call to init(bytes:length:) : | nsdata.swift:58:15:58:15 | nsDataTainted1 | +| nsdata.swift:57:40:57:47 | call to source() : | nsdata.swift:24:5:24:50 | [summary param] 0 in init(bytes:length:) : | +| nsdata.swift:57:40:57:47 | call to source() : | nsdata.swift:57:26:57:80 | call to init(bytes:length:) : | +| nsdata.swift:60:26:60:93 | call to init(bytesNoCopy:length:) : | nsdata.swift:61:15:61:15 | nsDataTainted2 | +| nsdata.swift:60:46:60:53 | call to source() : | nsdata.swift:25:5:25:68 | [summary param] 0 in init(bytesNoCopy:length:) : | +| nsdata.swift:60:46:60:53 | call to source() : | nsdata.swift:60:26:60:93 | call to init(bytesNoCopy:length:) : | +| nsdata.swift:63:26:63:111 | call to init(bytesNoCopy:length:deallocator:) : | nsdata.swift:64:15:64:15 | nsDataTainted3 | +| nsdata.swift:63:46:63:53 | call to source() : | nsdata.swift:26:5:26:130 | [summary param] 0 in init(bytesNoCopy:length:deallocator:) : | +| nsdata.swift:63:46:63:53 | call to source() : | nsdata.swift:63:26:63:111 | call to init(bytesNoCopy:length:deallocator:) : | +| nsdata.swift:66:26:66:113 | call to init(bytesNoCopy:length:freeWhenDone:) : | nsdata.swift:67:15:67:15 | nsDataTainted4 | +| nsdata.swift:66:46:66:53 | call to source() : | nsdata.swift:27:5:27:90 | [summary param] 0 in init(bytesNoCopy:length:freeWhenDone:) : | +| nsdata.swift:66:46:66:53 | call to source() : | nsdata.swift:66:26:66:113 | call to init(bytesNoCopy:length:freeWhenDone:) : | +| nsdata.swift:69:26:69:56 | call to init(data:) : | nsdata.swift:70:15:70:15 | nsDataTainted5 | +| nsdata.swift:69:39:69:46 | call to source() : | nsdata.swift:28:5:28:23 | [summary param] 0 in init(data:) : | +| nsdata.swift:69:39:69:46 | call to source() : | nsdata.swift:69:26:69:56 | call to init(data:) : | +| nsdata.swift:72:26:72:68 | call to init(contentsOfFile:) : | nsdata.swift:73:15:73:29 | ...! | +| nsdata.swift:72:49:72:56 | call to source() : | nsdata.swift:29:5:29:36 | [summary param] 0 in init(contentsOfFile:) : | +| nsdata.swift:72:49:72:56 | call to source() : | nsdata.swift:72:26:72:68 | call to init(contentsOfFile:) : | +| nsdata.swift:75:26:75:81 | call to init(contentsOfFile:options:) : | nsdata.swift:76:15:76:15 | nsDataTainted7 | +| nsdata.swift:75:49:75:56 | call to source() : | nsdata.swift:30:5:30:93 | [summary param] 0 in init(contentsOfFile:options:) : | +| nsdata.swift:75:49:75:56 | call to source() : | nsdata.swift:75:26:75:81 | call to init(contentsOfFile:options:) : | +| nsdata.swift:78:26:78:61 | call to init(contentsOf:) : | nsdata.swift:79:15:79:29 | ...! | +| nsdata.swift:78:45:78:52 | call to source() : | nsdata.swift:31:5:31:29 | [summary param] 0 in init(contentsOf:) : | +| nsdata.swift:78:45:78:52 | call to source() : | nsdata.swift:78:26:78:61 | call to init(contentsOf:) : | +| nsdata.swift:81:26:81:74 | call to init(contentsOf:options:) : | nsdata.swift:82:15:82:29 | ...! | +| nsdata.swift:81:45:81:52 | call to source() : | nsdata.swift:32:5:32:61 | [summary param] 0 in init(contentsOf:options:) : | +| nsdata.swift:81:45:81:52 | call to source() : | nsdata.swift:81:26:81:74 | call to init(contentsOf:options:) : | +| nsdata.swift:84:27:84:75 | call to init(contentsOfMappedFile:) : | nsdata.swift:85:15:85:30 | ...! | +| nsdata.swift:84:56:84:63 | call to source() : | nsdata.swift:33:5:33:47 | [summary param] 0 in init(contentsOfMappedFile:) : | +| nsdata.swift:84:56:84:63 | call to source() : | nsdata.swift:84:27:84:75 | call to init(contentsOfMappedFile:) : | +| nsdata.swift:87:27:87:79 | call to init(base64Encoded:options:) : | nsdata.swift:88:15:88:30 | ...! | +| nsdata.swift:87:49:87:56 | call to source() : | nsdata.swift:34:5:34:88 | [summary param] 0 in init(base64Encoded:options:) : | +| nsdata.swift:87:49:87:56 | call to source() : | nsdata.swift:87:27:87:79 | call to init(base64Encoded:options:) : | +| nsdata.swift:89:27:89:81 | call to init(base64Encoded:options:) : | nsdata.swift:90:15:90:30 | ...! | +| nsdata.swift:89:49:89:56 | call to source() : | nsdata.swift:35:5:35:92 | [summary param] 0 in init(base64Encoded:options:) : | +| nsdata.swift:89:49:89:56 | call to source() : | nsdata.swift:89:27:89:81 | call to init(base64Encoded:options:) : | +| nsdata.swift:92:27:92:69 | call to init(base64Encoding:) : | nsdata.swift:93:15:93:30 | ...! | +| nsdata.swift:92:50:92:57 | call to source() : | nsdata.swift:36:5:36:49 | [summary param] 0 in init(base64Encoding:) : | +| nsdata.swift:92:50:92:57 | call to source() : | nsdata.swift:92:27:92:69 | call to init(base64Encoding:) : | +| nsdata.swift:95:27:95:34 | call to source() : | nsdata.swift:96:15:96:15 | nsDataTainted14 : | +| nsdata.swift:95:27:95:34 | call to source() : | nsdata.swift:97:15:97:15 | nsDataTainted14 : | +| nsdata.swift:96:15:96:15 | nsDataTainted14 : | nsdata.swift:37:5:37:98 | [summary param] this in base64EncodedData(options:) : | +| nsdata.swift:96:15:96:15 | nsDataTainted14 : | nsdata.swift:96:15:96:49 | call to base64EncodedData(options:) | +| nsdata.swift:97:15:97:15 | nsDataTainted14 : | nsdata.swift:37:5:37:98 | [summary param] this in base64EncodedData(options:) : | +| nsdata.swift:97:15:97:15 | nsDataTainted14 : | nsdata.swift:97:15:97:60 | call to base64EncodedData(options:) | +| nsdata.swift:99:27:99:34 | call to source() : | nsdata.swift:100:15:100:15 | nsDataTainted15 : | +| nsdata.swift:99:27:99:34 | call to source() : | nsdata.swift:101:15:101:15 | nsDataTainted15 : | +| nsdata.swift:100:15:100:15 | nsDataTainted15 : | nsdata.swift:38:5:38:96 | [summary param] this in base64EncodedString(options:) : | +| nsdata.swift:100:15:100:15 | nsDataTainted15 : | nsdata.swift:100:15:100:51 | call to base64EncodedString(options:) | +| nsdata.swift:101:15:101:15 | nsDataTainted15 : | nsdata.swift:38:5:38:96 | [summary param] this in base64EncodedString(options:) : | +| nsdata.swift:101:15:101:15 | nsDataTainted15 : | nsdata.swift:101:15:101:62 | call to base64EncodedString(options:) | +| nsdata.swift:103:27:103:34 | call to source() : | nsdata.swift:104:15:104:15 | nsDataTainted16 : | +| nsdata.swift:104:15:104:15 | nsDataTainted16 : | nsdata.swift:39:5:39:49 | [summary param] this in base64Encoding() : | +| nsdata.swift:104:15:104:15 | nsDataTainted16 : | nsdata.swift:104:15:104:46 | call to base64Encoding() | +| nsdata.swift:106:15:106:70 | call to dataWithContentsOfMappedFile(_:) : | nsdata.swift:106:15:106:71 | ...! | +| nsdata.swift:106:51:106:58 | call to source() : | nsdata.swift:40:5:40:82 | [summary param] 0 in dataWithContentsOfMappedFile(_:) : | +| nsdata.swift:106:51:106:58 | call to source() : | nsdata.swift:106:15:106:70 | call to dataWithContentsOfMappedFile(_:) : | +| nsdata.swift:113:27:113:34 | call to source() : | nsdata.swift:115:5:115:5 | nsDataTainted18 : | +| nsdata.swift:115:5:115:5 | nsDataTainted18 : | nsdata.swift:42:5:42:55 | [summary param] this in getBytes(_:) : | +| nsdata.swift:115:5:115:5 | nsDataTainted18 : | nsdata.swift:115:30:115:30 | [post] bufferTainted18 : | +| nsdata.swift:115:30:115:30 | [post] bufferTainted18 : | nsdata.swift:116:15:116:15 | bufferTainted18 | +| nsdata.swift:118:27:118:34 | call to source() : | nsdata.swift:120:5:120:5 | nsDataTainted19 : | +| nsdata.swift:120:5:120:5 | nsDataTainted19 : | nsdata.swift:43:5:43:68 | [summary param] this in getBytes(_:length:) : | +| nsdata.swift:120:5:120:5 | nsDataTainted19 : | nsdata.swift:120:30:120:30 | [post] bufferTainted19 : | +| nsdata.swift:120:30:120:30 | [post] bufferTainted19 : | nsdata.swift:121:15:121:15 | bufferTainted19 | +| nsdata.swift:123:27:123:34 | call to source() : | nsdata.swift:125:5:125:5 | nsDataTainted20 : | +| nsdata.swift:125:5:125:5 | nsDataTainted20 : | nsdata.swift:44:5:44:71 | [summary param] this in getBytes(_:range:) : | +| nsdata.swift:125:5:125:5 | nsDataTainted20 : | nsdata.swift:125:30:125:30 | [post] bufferTainted20 : | +| nsdata.swift:125:30:125:30 | [post] bufferTainted20 : | nsdata.swift:126:15:126:15 | bufferTainted20 | +| nsdata.swift:128:27:128:34 | call to source() : | nsdata.swift:129:15:129:15 | nsDataTainted21 : | +| nsdata.swift:129:15:129:15 | nsDataTainted21 : | nsdata.swift:45:5:45:65 | [summary param] this in subdata(with:) : | +| nsdata.swift:129:15:129:15 | nsDataTainted21 : | nsdata.swift:129:15:129:54 | call to subdata(with:) | +| nsdata.swift:131:27:131:34 | call to source() : | nsdata.swift:132:15:132:15 | nsDataTainted22 : | +| nsdata.swift:132:15:132:15 | nsDataTainted22 : | nsdata.swift:46:5:46:89 | [summary param] this in compressed(using:) : | +| nsdata.swift:132:15:132:15 | nsDataTainted22 : | nsdata.swift:132:15:132:81 | call to compressed(using:) | +| nsdata.swift:134:27:134:34 | call to source() : | nsdata.swift:135:15:135:15 | nsDataTainted23 : | +| nsdata.swift:135:15:135:15 | nsDataTainted23 : | nsdata.swift:47:5:47:91 | [summary param] this in decompressed(using:) : | +| nsdata.swift:135:15:135:15 | nsDataTainted23 : | nsdata.swift:135:15:135:83 | call to decompressed(using:) | +| nsdata.swift:138:27:138:34 | call to source() : | nsdata.swift:139:15:139:15 | nsDataTainted24 : | +| nsdata.swift:138:27:138:34 | call to source() : | nsdata.swift:139:15:139:31 | .bytes | +| nsdata.swift:138:27:138:34 | call to source() : | nsdata.swift:140:15:140:15 | nsDataTainted24 : | +| nsdata.swift:138:27:138:34 | call to source() : | nsdata.swift:140:15:140:31 | .description | +| nsdata.swift:139:15:139:15 | nsDataTainted24 : | nsdata.swift:22:9:22:9 | self : | +| nsdata.swift:139:15:139:15 | nsDataTainted24 : | nsdata.swift:139:15:139:31 | .bytes | +| nsdata.swift:140:15:140:15 | nsDataTainted24 : | nsdata.swift:23:9:23:9 | self : | +| nsdata.swift:140:15:140:15 | nsDataTainted24 : | nsdata.swift:140:15:140:31 | .description | +| nsmutabledata.swift:13:9:13:9 | self : | file://:0:0:0:0 | .mutableBytes : | +| nsmutabledata.swift:14:5:14:58 | [summary param] 0 in append(_:length:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:length:) : | +| nsmutabledata.swift:15:5:15:33 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | +| nsmutabledata.swift:16:5:16:78 | [summary param] 1 in replaceBytes(in:withBytes:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceBytes(in:withBytes:) : | +| nsmutabledata.swift:17:5:17:121 | [summary param] 1 in replaceBytes(in:withBytes:length:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceBytes(in:withBytes:length:) : | +| nsmutabledata.swift:18:5:18:33 | [summary param] 0 in setData(_:) : | file://:0:0:0:0 | [summary] to write: argument this in setData(_:) : | +| nsmutabledata.swift:28:5:28:5 | [post] nsMutableDataTainted1 : | nsmutabledata.swift:29:15:29:15 | nsMutableDataTainted1 | +| nsmutabledata.swift:28:34:28:41 | call to source() : | nsmutabledata.swift:14:5:14:58 | [summary param] 0 in append(_:length:) : | +| nsmutabledata.swift:28:34:28:41 | call to source() : | nsmutabledata.swift:28:5:28:5 | [post] nsMutableDataTainted1 : | +| nsmutabledata.swift:32:5:32:5 | [post] nsMutableDataTainted2 : | nsmutabledata.swift:33:15:33:15 | nsMutableDataTainted2 | +| nsmutabledata.swift:32:34:32:41 | call to source() : | nsmutabledata.swift:15:5:15:33 | [summary param] 0 in append(_:) : | +| nsmutabledata.swift:32:34:32:41 | call to source() : | nsmutabledata.swift:32:5:32:5 | [post] nsMutableDataTainted2 : | +| nsmutabledata.swift:36:5:36:5 | [post] nsMutableDataTainted3 : | nsmutabledata.swift:37:15:37:15 | nsMutableDataTainted3 | +| nsmutabledata.swift:36:66:36:73 | call to source() : | nsmutabledata.swift:16:5:16:78 | [summary param] 1 in replaceBytes(in:withBytes:) : | +| nsmutabledata.swift:36:66:36:73 | call to source() : | nsmutabledata.swift:36:5:36:5 | [post] nsMutableDataTainted3 : | +| nsmutabledata.swift:40:5:40:5 | [post] nsMutableDataTainted4 : | nsmutabledata.swift:41:15:41:15 | nsMutableDataTainted4 | +| nsmutabledata.swift:40:66:40:73 | call to source() : | nsmutabledata.swift:17:5:17:121 | [summary param] 1 in replaceBytes(in:withBytes:length:) : | +| nsmutabledata.swift:40:66:40:73 | call to source() : | nsmutabledata.swift:40:5:40:5 | [post] nsMutableDataTainted4 : | +| nsmutabledata.swift:44:5:44:5 | [post] nsMutableDataTainted5 : | nsmutabledata.swift:45:15:45:15 | nsMutableDataTainted5 | +| nsmutabledata.swift:44:35:44:42 | call to source() : | nsmutabledata.swift:18:5:18:33 | [summary param] 0 in setData(_:) : | +| nsmutabledata.swift:44:35:44:42 | call to source() : | nsmutabledata.swift:44:5:44:5 | [post] nsMutableDataTainted5 : | +| nsmutabledata.swift:48:33:48:40 | call to source() : | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 : | +| nsmutabledata.swift:48:33:48:40 | call to source() : | nsmutabledata.swift:49:15:49:37 | .mutableBytes | +| nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 : | nsmutabledata.swift:13:9:13:9 | self : | +| nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 : | nsmutabledata.swift:49:15:49:37 | .mutableBytes | | string.swift:5:11:5:18 | call to source() : | string.swift:7:13:7:13 | "..." | | string.swift:5:11:5:18 | call to source() : | string.swift:9:13:9:13 | "..." | | string.swift:5:11:5:18 | call to source() : | string.swift:11:13:11:13 | "..." | @@ -240,13 +376,43 @@ edges | webview.swift:97:17:97:17 | s : | webview.swift:44:5:44:48 | [summary param] 0 in setValue(_:forProperty:) : | | webview.swift:97:17:97:17 | s : | webview.swift:97:5:97:5 | [post] v3 : | nodes +| file://:0:0:0:0 | .bytes : | semmle.label | .bytes : | +| file://:0:0:0:0 | .description : | semmle.label | .description : | +| file://:0:0:0:0 | .mutableBytes : | semmle.label | .mutableBytes : | +| file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:) : | semmle.label | [summary] to write: argument 0 in getBytes(_:) : | +| file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:length:) : | semmle.label | [summary] to write: argument 0 in getBytes(_:length:) : | +| file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:range:) : | semmle.label | [summary] to write: argument 0 in getBytes(_:range:) : | | file://:0:0:0:0 | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : | semmle.label | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : | +| file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | semmle.label | [summary] to write: argument this in append(_:) : | +| file://:0:0:0:0 | [summary] to write: argument this in append(_:length:) : | semmle.label | [summary] to write: argument this in append(_:length:) : | | file://:0:0:0:0 | [summary] to write: argument this in defineProperty(_:descriptor:) : | semmle.label | [summary] to write: argument this in defineProperty(_:descriptor:) : | +| file://:0:0:0:0 | [summary] to write: argument this in replaceBytes(in:withBytes:) : | semmle.label | [summary] to write: argument this in replaceBytes(in:withBytes:) : | +| file://:0:0:0:0 | [summary] to write: argument this in replaceBytes(in:withBytes:length:) : | semmle.label | [summary] to write: argument this in replaceBytes(in:withBytes:length:) : | +| file://:0:0:0:0 | [summary] to write: argument this in setData(_:) : | semmle.label | [summary] to write: argument this in setData(_:) : | | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:at:) : | semmle.label | [summary] to write: argument this in setValue(_:at:) : | | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:forProperty:) : | semmle.label | [summary] to write: argument this in setValue(_:forProperty:) : | | file://:0:0:0:0 | [summary] to write: return (return) in atIndex(_:) : | semmle.label | [summary] to write: return (return) in atIndex(_:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedData(options:) : | semmle.label | [summary] to write: return (return) in base64EncodedData(options:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedString(options:) : | semmle.label | [summary] to write: return (return) in base64EncodedString(options:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in base64Encoding() : | semmle.label | [summary] to write: return (return) in base64Encoding() : | +| file://:0:0:0:0 | [summary] to write: return (return) in compressed(using:) : | semmle.label | [summary] to write: return (return) in compressed(using:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in dataWithContentsOfMappedFile(_:) : | semmle.label | [summary] to write: return (return) in dataWithContentsOfMappedFile(_:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in decompressed(using:) : | semmle.label | [summary] to write: return (return) in decompressed(using:) : | | file://:0:0:0:0 | [summary] to write: return (return) in forProperty(_:) : | semmle.label | [summary] to write: return (return) in forProperty(_:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | semmle.label | [summary] to write: return (return) in init(base64Encoded:options:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | semmle.label | [summary] to write: return (return) in init(base64Encoded:options:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoding:) : | semmle.label | [summary] to write: return (return) in init(base64Encoding:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(bool:in:) : | semmle.label | [summary] to write: return (return) in init(bool:in:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(bytes:length:) : | semmle.label | [summary] to write: return (return) in init(bytes:length:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:length:) : | semmle.label | [summary] to write: return (return) in init(bytesNoCopy:length:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:length:deallocator:) : | semmle.label | [summary] to write: return (return) in init(bytesNoCopy:length:deallocator:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:length:freeWhenDone:) : | semmle.label | [summary] to write: return (return) in init(bytesNoCopy:length:freeWhenDone:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOf:) : | semmle.label | [summary] to write: return (return) in init(contentsOf:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOf:options:) : | semmle.label | [summary] to write: return (return) in init(contentsOf:options:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOfFile:) : | semmle.label | [summary] to write: return (return) in init(contentsOfFile:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOfFile:options:) : | semmle.label | [summary] to write: return (return) in init(contentsOfFile:options:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOfMappedFile:) : | semmle.label | [summary] to write: return (return) in init(contentsOfMappedFile:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(data:) : | semmle.label | [summary] to write: return (return) in init(data:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(double:in:) : | semmle.label | [summary] to write: return (return) in init(double:in:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(int32:in:) : | semmle.label | [summary] to write: return (return) in init(int32:in:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(object:in:) : | semmle.label | [summary] to write: return (return) in init(object:in:) : | @@ -258,6 +424,7 @@ nodes | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | semmle.label | [summary] to write: return (return) in init(string:relativeTo:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | semmle.label | [summary] to write: return (return) in init(string:relativeTo:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(uInt32:in:) : | semmle.label | [summary] to write: return (return) in init(uInt32:in:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in subdata(with:) : | semmle.label | [summary] to write: return (return) in subdata(with:) : | | file://:0:0:0:0 | [summary] to write: return (return) in toArray() : | semmle.label | [summary] to write: return (return) in toArray() : | | file://:0:0:0:0 | [summary] to write: return (return) in toBool() : | semmle.label | [summary] to write: return (return) in toBool() : | | file://:0:0:0:0 | [summary] to write: return (return) in toDate() : | semmle.label | [summary] to write: return (return) in toDate() : | @@ -273,6 +440,136 @@ nodes | file://:0:0:0:0 | [summary] to write: return (return) in toSize() : | semmle.label | [summary] to write: return (return) in toSize() : | | file://:0:0:0:0 | [summary] to write: return (return) in toString() : | semmle.label | [summary] to write: return (return) in toString() : | | file://:0:0:0:0 | [summary] to write: return (return) in toUInt32() : | semmle.label | [summary] to write: return (return) in toUInt32() : | +| nsdata.swift:22:9:22:9 | self : | semmle.label | self : | +| nsdata.swift:23:9:23:9 | self : | semmle.label | self : | +| nsdata.swift:24:5:24:50 | [summary param] 0 in init(bytes:length:) : | semmle.label | [summary param] 0 in init(bytes:length:) : | +| nsdata.swift:25:5:25:68 | [summary param] 0 in init(bytesNoCopy:length:) : | semmle.label | [summary param] 0 in init(bytesNoCopy:length:) : | +| nsdata.swift:26:5:26:130 | [summary param] 0 in init(bytesNoCopy:length:deallocator:) : | semmle.label | [summary param] 0 in init(bytesNoCopy:length:deallocator:) : | +| nsdata.swift:27:5:27:90 | [summary param] 0 in init(bytesNoCopy:length:freeWhenDone:) : | semmle.label | [summary param] 0 in init(bytesNoCopy:length:freeWhenDone:) : | +| nsdata.swift:28:5:28:23 | [summary param] 0 in init(data:) : | semmle.label | [summary param] 0 in init(data:) : | +| nsdata.swift:29:5:29:36 | [summary param] 0 in init(contentsOfFile:) : | semmle.label | [summary param] 0 in init(contentsOfFile:) : | +| nsdata.swift:30:5:30:93 | [summary param] 0 in init(contentsOfFile:options:) : | semmle.label | [summary param] 0 in init(contentsOfFile:options:) : | +| nsdata.swift:31:5:31:29 | [summary param] 0 in init(contentsOf:) : | semmle.label | [summary param] 0 in init(contentsOf:) : | +| nsdata.swift:32:5:32:61 | [summary param] 0 in init(contentsOf:options:) : | semmle.label | [summary param] 0 in init(contentsOf:options:) : | +| nsdata.swift:33:5:33:47 | [summary param] 0 in init(contentsOfMappedFile:) : | semmle.label | [summary param] 0 in init(contentsOfMappedFile:) : | +| nsdata.swift:34:5:34:88 | [summary param] 0 in init(base64Encoded:options:) : | semmle.label | [summary param] 0 in init(base64Encoded:options:) : | +| nsdata.swift:35:5:35:92 | [summary param] 0 in init(base64Encoded:options:) : | semmle.label | [summary param] 0 in init(base64Encoded:options:) : | +| nsdata.swift:36:5:36:49 | [summary param] 0 in init(base64Encoding:) : | semmle.label | [summary param] 0 in init(base64Encoding:) : | +| nsdata.swift:37:5:37:98 | [summary param] this in base64EncodedData(options:) : | semmle.label | [summary param] this in base64EncodedData(options:) : | +| nsdata.swift:38:5:38:96 | [summary param] this in base64EncodedString(options:) : | semmle.label | [summary param] this in base64EncodedString(options:) : | +| nsdata.swift:39:5:39:49 | [summary param] this in base64Encoding() : | semmle.label | [summary param] this in base64Encoding() : | +| nsdata.swift:40:5:40:82 | [summary param] 0 in dataWithContentsOfMappedFile(_:) : | semmle.label | [summary param] 0 in dataWithContentsOfMappedFile(_:) : | +| nsdata.swift:42:5:42:55 | [summary param] this in getBytes(_:) : | semmle.label | [summary param] this in getBytes(_:) : | +| nsdata.swift:43:5:43:68 | [summary param] this in getBytes(_:length:) : | semmle.label | [summary param] this in getBytes(_:length:) : | +| nsdata.swift:44:5:44:71 | [summary param] this in getBytes(_:range:) : | semmle.label | [summary param] this in getBytes(_:range:) : | +| nsdata.swift:45:5:45:65 | [summary param] this in subdata(with:) : | semmle.label | [summary param] this in subdata(with:) : | +| nsdata.swift:46:5:46:89 | [summary param] this in compressed(using:) : | semmle.label | [summary param] this in compressed(using:) : | +| nsdata.swift:47:5:47:91 | [summary param] this in decompressed(using:) : | semmle.label | [summary param] this in decompressed(using:) : | +| nsdata.swift:57:26:57:80 | call to init(bytes:length:) : | semmle.label | call to init(bytes:length:) : | +| nsdata.swift:57:40:57:47 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:58:15:58:15 | nsDataTainted1 | semmle.label | nsDataTainted1 | +| nsdata.swift:60:26:60:93 | call to init(bytesNoCopy:length:) : | semmle.label | call to init(bytesNoCopy:length:) : | +| nsdata.swift:60:46:60:53 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:61:15:61:15 | nsDataTainted2 | semmle.label | nsDataTainted2 | +| nsdata.swift:63:26:63:111 | call to init(bytesNoCopy:length:deallocator:) : | semmle.label | call to init(bytesNoCopy:length:deallocator:) : | +| nsdata.swift:63:46:63:53 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:64:15:64:15 | nsDataTainted3 | semmle.label | nsDataTainted3 | +| nsdata.swift:66:26:66:113 | call to init(bytesNoCopy:length:freeWhenDone:) : | semmle.label | call to init(bytesNoCopy:length:freeWhenDone:) : | +| nsdata.swift:66:46:66:53 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:67:15:67:15 | nsDataTainted4 | semmle.label | nsDataTainted4 | +| nsdata.swift:69:26:69:56 | call to init(data:) : | semmle.label | call to init(data:) : | +| nsdata.swift:69:39:69:46 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:70:15:70:15 | nsDataTainted5 | semmle.label | nsDataTainted5 | +| nsdata.swift:72:26:72:68 | call to init(contentsOfFile:) : | semmle.label | call to init(contentsOfFile:) : | +| nsdata.swift:72:49:72:56 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:73:15:73:29 | ...! | semmle.label | ...! | +| nsdata.swift:75:26:75:81 | call to init(contentsOfFile:options:) : | semmle.label | call to init(contentsOfFile:options:) : | +| nsdata.swift:75:49:75:56 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:76:15:76:15 | nsDataTainted7 | semmle.label | nsDataTainted7 | +| nsdata.swift:78:26:78:61 | call to init(contentsOf:) : | semmle.label | call to init(contentsOf:) : | +| nsdata.swift:78:45:78:52 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:79:15:79:29 | ...! | semmle.label | ...! | +| nsdata.swift:81:26:81:74 | call to init(contentsOf:options:) : | semmle.label | call to init(contentsOf:options:) : | +| nsdata.swift:81:45:81:52 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:82:15:82:29 | ...! | semmle.label | ...! | +| nsdata.swift:84:27:84:75 | call to init(contentsOfMappedFile:) : | semmle.label | call to init(contentsOfMappedFile:) : | +| nsdata.swift:84:56:84:63 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:85:15:85:30 | ...! | semmle.label | ...! | +| nsdata.swift:87:27:87:79 | call to init(base64Encoded:options:) : | semmle.label | call to init(base64Encoded:options:) : | +| nsdata.swift:87:49:87:56 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:88:15:88:30 | ...! | semmle.label | ...! | +| nsdata.swift:89:27:89:81 | call to init(base64Encoded:options:) : | semmle.label | call to init(base64Encoded:options:) : | +| nsdata.swift:89:49:89:56 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:90:15:90:30 | ...! | semmle.label | ...! | +| nsdata.swift:92:27:92:69 | call to init(base64Encoding:) : | semmle.label | call to init(base64Encoding:) : | +| nsdata.swift:92:50:92:57 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:93:15:93:30 | ...! | semmle.label | ...! | +| nsdata.swift:95:27:95:34 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:96:15:96:15 | nsDataTainted14 : | semmle.label | nsDataTainted14 : | +| nsdata.swift:96:15:96:49 | call to base64EncodedData(options:) | semmle.label | call to base64EncodedData(options:) | +| nsdata.swift:97:15:97:15 | nsDataTainted14 : | semmle.label | nsDataTainted14 : | +| nsdata.swift:97:15:97:60 | call to base64EncodedData(options:) | semmle.label | call to base64EncodedData(options:) | +| nsdata.swift:99:27:99:34 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:100:15:100:15 | nsDataTainted15 : | semmle.label | nsDataTainted15 : | +| nsdata.swift:100:15:100:51 | call to base64EncodedString(options:) | semmle.label | call to base64EncodedString(options:) | +| nsdata.swift:101:15:101:15 | nsDataTainted15 : | semmle.label | nsDataTainted15 : | +| nsdata.swift:101:15:101:62 | call to base64EncodedString(options:) | semmle.label | call to base64EncodedString(options:) | +| nsdata.swift:103:27:103:34 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:104:15:104:15 | nsDataTainted16 : | semmle.label | nsDataTainted16 : | +| nsdata.swift:104:15:104:46 | call to base64Encoding() | semmle.label | call to base64Encoding() | +| nsdata.swift:106:15:106:70 | call to dataWithContentsOfMappedFile(_:) : | semmle.label | call to dataWithContentsOfMappedFile(_:) : | +| nsdata.swift:106:15:106:71 | ...! | semmle.label | ...! | +| nsdata.swift:106:51:106:58 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:113:27:113:34 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:115:5:115:5 | nsDataTainted18 : | semmle.label | nsDataTainted18 : | +| nsdata.swift:115:30:115:30 | [post] bufferTainted18 : | semmle.label | [post] bufferTainted18 : | +| nsdata.swift:116:15:116:15 | bufferTainted18 | semmle.label | bufferTainted18 | +| nsdata.swift:118:27:118:34 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:120:5:120:5 | nsDataTainted19 : | semmle.label | nsDataTainted19 : | +| nsdata.swift:120:30:120:30 | [post] bufferTainted19 : | semmle.label | [post] bufferTainted19 : | +| nsdata.swift:121:15:121:15 | bufferTainted19 | semmle.label | bufferTainted19 | +| nsdata.swift:123:27:123:34 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:125:5:125:5 | nsDataTainted20 : | semmle.label | nsDataTainted20 : | +| nsdata.swift:125:30:125:30 | [post] bufferTainted20 : | semmle.label | [post] bufferTainted20 : | +| nsdata.swift:126:15:126:15 | bufferTainted20 | semmle.label | bufferTainted20 | +| nsdata.swift:128:27:128:34 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:129:15:129:15 | nsDataTainted21 : | semmle.label | nsDataTainted21 : | +| nsdata.swift:129:15:129:54 | call to subdata(with:) | semmle.label | call to subdata(with:) | +| nsdata.swift:131:27:131:34 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:132:15:132:15 | nsDataTainted22 : | semmle.label | nsDataTainted22 : | +| nsdata.swift:132:15:132:81 | call to compressed(using:) | semmle.label | call to compressed(using:) | +| nsdata.swift:134:27:134:34 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:135:15:135:15 | nsDataTainted23 : | semmle.label | nsDataTainted23 : | +| nsdata.swift:135:15:135:83 | call to decompressed(using:) | semmle.label | call to decompressed(using:) | +| nsdata.swift:138:27:138:34 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:139:15:139:15 | nsDataTainted24 : | semmle.label | nsDataTainted24 : | +| nsdata.swift:139:15:139:31 | .bytes | semmle.label | .bytes | +| nsdata.swift:140:15:140:15 | nsDataTainted24 : | semmle.label | nsDataTainted24 : | +| nsdata.swift:140:15:140:31 | .description | semmle.label | .description | +| nsmutabledata.swift:13:9:13:9 | self : | semmle.label | self : | +| nsmutabledata.swift:14:5:14:58 | [summary param] 0 in append(_:length:) : | semmle.label | [summary param] 0 in append(_:length:) : | +| nsmutabledata.swift:15:5:15:33 | [summary param] 0 in append(_:) : | semmle.label | [summary param] 0 in append(_:) : | +| nsmutabledata.swift:16:5:16:78 | [summary param] 1 in replaceBytes(in:withBytes:) : | semmle.label | [summary param] 1 in replaceBytes(in:withBytes:) : | +| nsmutabledata.swift:17:5:17:121 | [summary param] 1 in replaceBytes(in:withBytes:length:) : | semmle.label | [summary param] 1 in replaceBytes(in:withBytes:length:) : | +| nsmutabledata.swift:18:5:18:33 | [summary param] 0 in setData(_:) : | semmle.label | [summary param] 0 in setData(_:) : | +| nsmutabledata.swift:28:5:28:5 | [post] nsMutableDataTainted1 : | semmle.label | [post] nsMutableDataTainted1 : | +| nsmutabledata.swift:28:34:28:41 | call to source() : | semmle.label | call to source() : | +| nsmutabledata.swift:29:15:29:15 | nsMutableDataTainted1 | semmle.label | nsMutableDataTainted1 | +| nsmutabledata.swift:32:5:32:5 | [post] nsMutableDataTainted2 : | semmle.label | [post] nsMutableDataTainted2 : | +| nsmutabledata.swift:32:34:32:41 | call to source() : | semmle.label | call to source() : | +| nsmutabledata.swift:33:15:33:15 | nsMutableDataTainted2 | semmle.label | nsMutableDataTainted2 | +| nsmutabledata.swift:36:5:36:5 | [post] nsMutableDataTainted3 : | semmle.label | [post] nsMutableDataTainted3 : | +| nsmutabledata.swift:36:66:36:73 | call to source() : | semmle.label | call to source() : | +| nsmutabledata.swift:37:15:37:15 | nsMutableDataTainted3 | semmle.label | nsMutableDataTainted3 | +| nsmutabledata.swift:40:5:40:5 | [post] nsMutableDataTainted4 : | semmle.label | [post] nsMutableDataTainted4 : | +| nsmutabledata.swift:40:66:40:73 | call to source() : | semmle.label | call to source() : | +| nsmutabledata.swift:41:15:41:15 | nsMutableDataTainted4 | semmle.label | nsMutableDataTainted4 | +| nsmutabledata.swift:44:5:44:5 | [post] nsMutableDataTainted5 : | semmle.label | [post] nsMutableDataTainted5 : | +| nsmutabledata.swift:44:35:44:42 | call to source() : | semmle.label | call to source() : | +| nsmutabledata.swift:45:15:45:15 | nsMutableDataTainted5 | semmle.label | nsMutableDataTainted5 | +| nsmutabledata.swift:48:33:48:40 | call to source() : | semmle.label | call to source() : | +| nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 : | semmle.label | nsMutableDataTainted6 : | +| nsmutabledata.swift:49:15:49:37 | .mutableBytes | semmle.label | .mutableBytes | | string.swift:5:11:5:18 | call to source() : | semmle.label | call to source() : | | string.swift:7:13:7:13 | "..." | semmle.label | "..." | | string.swift:9:13:9:13 | "..." | semmle.label | "..." | @@ -474,6 +771,39 @@ nodes | webview.swift:97:17:97:17 | s : | semmle.label | s : | | webview.swift:98:10:98:10 | v3 | semmle.label | v3 | subpaths +| nsdata.swift:57:40:57:47 | call to source() : | nsdata.swift:24:5:24:50 | [summary param] 0 in init(bytes:length:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytes:length:) : | nsdata.swift:57:26:57:80 | call to init(bytes:length:) : | +| nsdata.swift:60:46:60:53 | call to source() : | nsdata.swift:25:5:25:68 | [summary param] 0 in init(bytesNoCopy:length:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:length:) : | nsdata.swift:60:26:60:93 | call to init(bytesNoCopy:length:) : | +| nsdata.swift:63:46:63:53 | call to source() : | nsdata.swift:26:5:26:130 | [summary param] 0 in init(bytesNoCopy:length:deallocator:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:length:deallocator:) : | nsdata.swift:63:26:63:111 | call to init(bytesNoCopy:length:deallocator:) : | +| nsdata.swift:66:46:66:53 | call to source() : | nsdata.swift:27:5:27:90 | [summary param] 0 in init(bytesNoCopy:length:freeWhenDone:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:length:freeWhenDone:) : | nsdata.swift:66:26:66:113 | call to init(bytesNoCopy:length:freeWhenDone:) : | +| nsdata.swift:69:39:69:46 | call to source() : | nsdata.swift:28:5:28:23 | [summary param] 0 in init(data:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(data:) : | nsdata.swift:69:26:69:56 | call to init(data:) : | +| nsdata.swift:72:49:72:56 | call to source() : | nsdata.swift:29:5:29:36 | [summary param] 0 in init(contentsOfFile:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOfFile:) : | nsdata.swift:72:26:72:68 | call to init(contentsOfFile:) : | +| nsdata.swift:75:49:75:56 | call to source() : | nsdata.swift:30:5:30:93 | [summary param] 0 in init(contentsOfFile:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOfFile:options:) : | nsdata.swift:75:26:75:81 | call to init(contentsOfFile:options:) : | +| nsdata.swift:78:45:78:52 | call to source() : | nsdata.swift:31:5:31:29 | [summary param] 0 in init(contentsOf:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOf:) : | nsdata.swift:78:26:78:61 | call to init(contentsOf:) : | +| nsdata.swift:81:45:81:52 | call to source() : | nsdata.swift:32:5:32:61 | [summary param] 0 in init(contentsOf:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOf:options:) : | nsdata.swift:81:26:81:74 | call to init(contentsOf:options:) : | +| nsdata.swift:84:56:84:63 | call to source() : | nsdata.swift:33:5:33:47 | [summary param] 0 in init(contentsOfMappedFile:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOfMappedFile:) : | nsdata.swift:84:27:84:75 | call to init(contentsOfMappedFile:) : | +| nsdata.swift:87:49:87:56 | call to source() : | nsdata.swift:34:5:34:88 | [summary param] 0 in init(base64Encoded:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | nsdata.swift:87:27:87:79 | call to init(base64Encoded:options:) : | +| nsdata.swift:89:49:89:56 | call to source() : | nsdata.swift:35:5:35:92 | [summary param] 0 in init(base64Encoded:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | nsdata.swift:89:27:89:81 | call to init(base64Encoded:options:) : | +| nsdata.swift:92:50:92:57 | call to source() : | nsdata.swift:36:5:36:49 | [summary param] 0 in init(base64Encoding:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoding:) : | nsdata.swift:92:27:92:69 | call to init(base64Encoding:) : | +| nsdata.swift:96:15:96:15 | nsDataTainted14 : | nsdata.swift:37:5:37:98 | [summary param] this in base64EncodedData(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedData(options:) : | nsdata.swift:96:15:96:49 | call to base64EncodedData(options:) | +| nsdata.swift:97:15:97:15 | nsDataTainted14 : | nsdata.swift:37:5:37:98 | [summary param] this in base64EncodedData(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedData(options:) : | nsdata.swift:97:15:97:60 | call to base64EncodedData(options:) | +| nsdata.swift:100:15:100:15 | nsDataTainted15 : | nsdata.swift:38:5:38:96 | [summary param] this in base64EncodedString(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedString(options:) : | nsdata.swift:100:15:100:51 | call to base64EncodedString(options:) | +| nsdata.swift:101:15:101:15 | nsDataTainted15 : | nsdata.swift:38:5:38:96 | [summary param] this in base64EncodedString(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedString(options:) : | nsdata.swift:101:15:101:62 | call to base64EncodedString(options:) | +| nsdata.swift:104:15:104:15 | nsDataTainted16 : | nsdata.swift:39:5:39:49 | [summary param] this in base64Encoding() : | file://:0:0:0:0 | [summary] to write: return (return) in base64Encoding() : | nsdata.swift:104:15:104:46 | call to base64Encoding() | +| nsdata.swift:106:51:106:58 | call to source() : | nsdata.swift:40:5:40:82 | [summary param] 0 in dataWithContentsOfMappedFile(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in dataWithContentsOfMappedFile(_:) : | nsdata.swift:106:15:106:70 | call to dataWithContentsOfMappedFile(_:) : | +| nsdata.swift:115:5:115:5 | nsDataTainted18 : | nsdata.swift:42:5:42:55 | [summary param] this in getBytes(_:) : | file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:) : | nsdata.swift:115:30:115:30 | [post] bufferTainted18 : | +| nsdata.swift:120:5:120:5 | nsDataTainted19 : | nsdata.swift:43:5:43:68 | [summary param] this in getBytes(_:length:) : | file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:length:) : | nsdata.swift:120:30:120:30 | [post] bufferTainted19 : | +| nsdata.swift:125:5:125:5 | nsDataTainted20 : | nsdata.swift:44:5:44:71 | [summary param] this in getBytes(_:range:) : | file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:range:) : | nsdata.swift:125:30:125:30 | [post] bufferTainted20 : | +| nsdata.swift:129:15:129:15 | nsDataTainted21 : | nsdata.swift:45:5:45:65 | [summary param] this in subdata(with:) : | file://:0:0:0:0 | [summary] to write: return (return) in subdata(with:) : | nsdata.swift:129:15:129:54 | call to subdata(with:) | +| nsdata.swift:132:15:132:15 | nsDataTainted22 : | nsdata.swift:46:5:46:89 | [summary param] this in compressed(using:) : | file://:0:0:0:0 | [summary] to write: return (return) in compressed(using:) : | nsdata.swift:132:15:132:81 | call to compressed(using:) | +| nsdata.swift:135:15:135:15 | nsDataTainted23 : | nsdata.swift:47:5:47:91 | [summary param] this in decompressed(using:) : | file://:0:0:0:0 | [summary] to write: return (return) in decompressed(using:) : | nsdata.swift:135:15:135:83 | call to decompressed(using:) | +| nsdata.swift:139:15:139:15 | nsDataTainted24 : | nsdata.swift:22:9:22:9 | self : | file://:0:0:0:0 | .bytes : | nsdata.swift:139:15:139:31 | .bytes | +| nsdata.swift:140:15:140:15 | nsDataTainted24 : | nsdata.swift:23:9:23:9 | self : | file://:0:0:0:0 | .description : | nsdata.swift:140:15:140:31 | .description | +| nsmutabledata.swift:28:34:28:41 | call to source() : | nsmutabledata.swift:14:5:14:58 | [summary param] 0 in append(_:length:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:length:) : | nsmutabledata.swift:28:5:28:5 | [post] nsMutableDataTainted1 : | +| nsmutabledata.swift:32:34:32:41 | call to source() : | nsmutabledata.swift:15:5:15:33 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | nsmutabledata.swift:32:5:32:5 | [post] nsMutableDataTainted2 : | +| nsmutabledata.swift:36:66:36:73 | call to source() : | nsmutabledata.swift:16:5:16:78 | [summary param] 1 in replaceBytes(in:withBytes:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceBytes(in:withBytes:) : | nsmutabledata.swift:36:5:36:5 | [post] nsMutableDataTainted3 : | +| nsmutabledata.swift:40:66:40:73 | call to source() : | nsmutabledata.swift:17:5:17:121 | [summary param] 1 in replaceBytes(in:withBytes:length:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceBytes(in:withBytes:length:) : | nsmutabledata.swift:40:5:40:5 | [post] nsMutableDataTainted4 : | +| nsmutabledata.swift:44:35:44:42 | call to source() : | nsmutabledata.swift:18:5:18:33 | [summary param] 0 in setData(_:) : | file://:0:0:0:0 | [summary] to write: argument this in setData(_:) : | nsmutabledata.swift:44:5:44:5 | [post] nsMutableDataTainted5 : | +| nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 : | nsmutabledata.swift:13:9:13:9 | self : | file://:0:0:0:0 | .mutableBytes : | nsmutabledata.swift:49:15:49:37 | .mutableBytes | | url.swift:59:31:59:31 | tainted : | url.swift:8:2:8:25 | [summary param] 0 in init(string:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | url.swift:59:19:59:38 | call to init(string:) : | | url.swift:83:24:83:24 | tainted : | url.swift:9:2:9:43 | [summary param] 0 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | url.swift:83:12:83:48 | call to init(string:relativeTo:) : | | url.swift:86:43:86:43 | urlTainted : | url.swift:9:2:9:43 | [summary param] 1 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | url.swift:86:12:86:53 | call to init(string:relativeTo:) : | @@ -524,6 +854,39 @@ subpaths | webview.swift:93:17:93:17 | s : | webview.swift:43:5:43:38 | [summary param] 0 in setValue(_:at:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:at:) : | webview.swift:93:5:93:5 | [post] v2 : | | webview.swift:97:17:97:17 | s : | webview.swift:44:5:44:48 | [summary param] 0 in setValue(_:forProperty:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:forProperty:) : | webview.swift:97:5:97:5 | [post] v3 : | #select +| nsdata.swift:58:15:58:15 | nsDataTainted1 | nsdata.swift:57:40:57:47 | call to source() : | nsdata.swift:58:15:58:15 | nsDataTainted1 | result | +| nsdata.swift:61:15:61:15 | nsDataTainted2 | nsdata.swift:60:46:60:53 | call to source() : | nsdata.swift:61:15:61:15 | nsDataTainted2 | result | +| nsdata.swift:64:15:64:15 | nsDataTainted3 | nsdata.swift:63:46:63:53 | call to source() : | nsdata.swift:64:15:64:15 | nsDataTainted3 | result | +| nsdata.swift:67:15:67:15 | nsDataTainted4 | nsdata.swift:66:46:66:53 | call to source() : | nsdata.swift:67:15:67:15 | nsDataTainted4 | result | +| nsdata.swift:70:15:70:15 | nsDataTainted5 | nsdata.swift:69:39:69:46 | call to source() : | nsdata.swift:70:15:70:15 | nsDataTainted5 | result | +| nsdata.swift:73:15:73:29 | ...! | nsdata.swift:72:49:72:56 | call to source() : | nsdata.swift:73:15:73:29 | ...! | result | +| nsdata.swift:76:15:76:15 | nsDataTainted7 | nsdata.swift:75:49:75:56 | call to source() : | nsdata.swift:76:15:76:15 | nsDataTainted7 | result | +| nsdata.swift:79:15:79:29 | ...! | nsdata.swift:78:45:78:52 | call to source() : | nsdata.swift:79:15:79:29 | ...! | result | +| nsdata.swift:82:15:82:29 | ...! | nsdata.swift:81:45:81:52 | call to source() : | nsdata.swift:82:15:82:29 | ...! | result | +| nsdata.swift:85:15:85:30 | ...! | nsdata.swift:84:56:84:63 | call to source() : | nsdata.swift:85:15:85:30 | ...! | result | +| nsdata.swift:88:15:88:30 | ...! | nsdata.swift:87:49:87:56 | call to source() : | nsdata.swift:88:15:88:30 | ...! | result | +| nsdata.swift:90:15:90:30 | ...! | nsdata.swift:89:49:89:56 | call to source() : | nsdata.swift:90:15:90:30 | ...! | result | +| nsdata.swift:93:15:93:30 | ...! | nsdata.swift:92:50:92:57 | call to source() : | nsdata.swift:93:15:93:30 | ...! | result | +| nsdata.swift:96:15:96:49 | call to base64EncodedData(options:) | nsdata.swift:95:27:95:34 | call to source() : | nsdata.swift:96:15:96:49 | call to base64EncodedData(options:) | result | +| nsdata.swift:97:15:97:60 | call to base64EncodedData(options:) | nsdata.swift:95:27:95:34 | call to source() : | nsdata.swift:97:15:97:60 | call to base64EncodedData(options:) | result | +| nsdata.swift:100:15:100:51 | call to base64EncodedString(options:) | nsdata.swift:99:27:99:34 | call to source() : | nsdata.swift:100:15:100:51 | call to base64EncodedString(options:) | result | +| nsdata.swift:101:15:101:62 | call to base64EncodedString(options:) | nsdata.swift:99:27:99:34 | call to source() : | nsdata.swift:101:15:101:62 | call to base64EncodedString(options:) | result | +| nsdata.swift:104:15:104:46 | call to base64Encoding() | nsdata.swift:103:27:103:34 | call to source() : | nsdata.swift:104:15:104:46 | call to base64Encoding() | result | +| nsdata.swift:106:15:106:71 | ...! | nsdata.swift:106:51:106:58 | call to source() : | nsdata.swift:106:15:106:71 | ...! | result | +| nsdata.swift:116:15:116:15 | bufferTainted18 | nsdata.swift:113:27:113:34 | call to source() : | nsdata.swift:116:15:116:15 | bufferTainted18 | result | +| nsdata.swift:121:15:121:15 | bufferTainted19 | nsdata.swift:118:27:118:34 | call to source() : | nsdata.swift:121:15:121:15 | bufferTainted19 | result | +| nsdata.swift:126:15:126:15 | bufferTainted20 | nsdata.swift:123:27:123:34 | call to source() : | nsdata.swift:126:15:126:15 | bufferTainted20 | result | +| nsdata.swift:129:15:129:54 | call to subdata(with:) | nsdata.swift:128:27:128:34 | call to source() : | nsdata.swift:129:15:129:54 | call to subdata(with:) | result | +| nsdata.swift:132:15:132:81 | call to compressed(using:) | nsdata.swift:131:27:131:34 | call to source() : | nsdata.swift:132:15:132:81 | call to compressed(using:) | result | +| nsdata.swift:135:15:135:83 | call to decompressed(using:) | nsdata.swift:134:27:134:34 | call to source() : | nsdata.swift:135:15:135:83 | call to decompressed(using:) | result | +| nsdata.swift:139:15:139:31 | .bytes | nsdata.swift:138:27:138:34 | call to source() : | nsdata.swift:139:15:139:31 | .bytes | result | +| nsdata.swift:140:15:140:31 | .description | nsdata.swift:138:27:138:34 | call to source() : | nsdata.swift:140:15:140:31 | .description | result | +| nsmutabledata.swift:29:15:29:15 | nsMutableDataTainted1 | nsmutabledata.swift:28:34:28:41 | call to source() : | nsmutabledata.swift:29:15:29:15 | nsMutableDataTainted1 | result | +| nsmutabledata.swift:33:15:33:15 | nsMutableDataTainted2 | nsmutabledata.swift:32:34:32:41 | call to source() : | nsmutabledata.swift:33:15:33:15 | nsMutableDataTainted2 | result | +| nsmutabledata.swift:37:15:37:15 | nsMutableDataTainted3 | nsmutabledata.swift:36:66:36:73 | call to source() : | nsmutabledata.swift:37:15:37:15 | nsMutableDataTainted3 | result | +| nsmutabledata.swift:41:15:41:15 | nsMutableDataTainted4 | nsmutabledata.swift:40:66:40:73 | call to source() : | nsmutabledata.swift:41:15:41:15 | nsMutableDataTainted4 | result | +| nsmutabledata.swift:45:15:45:15 | nsMutableDataTainted5 | nsmutabledata.swift:44:35:44:42 | call to source() : | nsmutabledata.swift:45:15:45:15 | nsMutableDataTainted5 | result | +| nsmutabledata.swift:49:15:49:37 | .mutableBytes | nsmutabledata.swift:48:33:48:40 | call to source() : | nsmutabledata.swift:49:15:49:37 | .mutableBytes | result | | string.swift:7:13:7:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:7:13:7:13 | "..." | result | | string.swift:9:13:9:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:9:13:9:13 | "..." | result | | string.swift:11:13:11:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:11:13:11:13 | "..." | result | diff --git a/swift/ql/test/library-tests/dataflow/taint/nsdata.swift b/swift/ql/test/library-tests/dataflow/taint/nsdata.swift new file mode 100644 index 00000000000..f6d82ede499 --- /dev/null +++ b/swift/ql/test/library-tests/dataflow/taint/nsdata.swift @@ -0,0 +1,141 @@ +// --- stubs --- + +struct URL +{ + init?(string: String) {} +} + +struct Data +{ + init(_ elements: S) {} +} + +struct NSRange {} + +struct ObjCBool {} + +class NSData { + struct ReadingOptions : OptionSet { let rawValue: Int } + struct Base64EncodingOptions : OptionSet { let rawValue: Int } + struct Base64DecodingOptions : OptionSet { let rawValue: Int } + enum CompressionAlgorithm : Int { case none } + var bytes: UnsafeRawPointer = UnsafeRawPointer(bitPattern: 0)! + var description: String = "" + init(bytes: UnsafeRawPointer?, length: Int) {} + init(bytesNoCopy bytes: UnsafeMutableRawPointer, length: Int) {} + init(bytesNoCopy bytes: UnsafeMutableRawPointer, length: Int, deallocator: ((UnsafeMutableRawPointer, Int) -> Void)? = nil) {} + init(bytesNoCopy bytes: UnsafeMutableRawPointer, length: Int, freeWhenDone b: Bool) {} + init(data: Data) {} + init?(contentsOfFile: String) {} + init(contentsOfFile path: String, options readOptionsMask: NSData.ReadingOptions = []) {} + init?(contentsOf: URL) {} + init?(contentsOf: URL, options: NSData.ReadingOptions) {} + init?(contentsOfMappedFile path: String) {} + init?(base64Encoded base64Data: Data, options: NSData.Base64DecodingOptions = []) {} + init?(base64Encoded base64String: String, options: NSData.Base64DecodingOptions = []) {} + init?(base64Encoding base64String: String) {} + func base64EncodedData(options: NSData.Base64EncodingOptions = []) -> Data { return Data("") } + func base64EncodedString(options: NSData.Base64EncodingOptions = []) -> String { return "" } + func base64Encoding() -> String { return "" } + class func dataWithContentsOfMappedFile(_ path: String) -> Any? { return nil } + func enumerateBytes(_ block: (UnsafeRawPointer, NSRange, UnsafeMutablePointer) -> Void) {} + func getBytes(_ buffer: UnsafeMutableRawPointer) {} + func getBytes(_ buffer: UnsafeMutableRawPointer, length: Int) {} + func getBytes(_ buffer: UnsafeMutableRawPointer, range: NSRange) {} + func subdata(with range: NSRange) -> Data { return Data("") } + func compressed(using algorithm: NSData.CompressionAlgorithm) -> Self { return self } + func decompressed(using algorithm: NSData.CompressionAlgorithm) -> Self { return self } +} + +// --- tests --- + +func source() -> Any { return "" } +func sink(arg: Any) {} + +func test() { + // ";NSData;true;init(bytes:length:);;;Argument[0];ReturnValue;taint", + let nsDataTainted1 = NSData(bytes: source() as? UnsafeRawPointer, length: 0) + sink(arg: nsDataTainted1) // $ tainted=57 + // ";NSData;true;init(bytesNoCopy:length:);;;Argument[0];ReturnValue;taint", + let nsDataTainted2 = NSData(bytesNoCopy: source() as! UnsafeMutableRawPointer, length: 0) + sink(arg: nsDataTainted2) // $ tainted=60 + // ";NSData;true;init(bytesNoCopy:length:deallocator:);;;Argument[0];ReturnValue;taint", + let nsDataTainted3 = NSData(bytesNoCopy: source() as! UnsafeMutableRawPointer, length: 0, deallocator: nil) + sink(arg: nsDataTainted3) // $ tainted=63 + // ";NSData;true;init(bytesNoCopy:length:freeWhenDone:);;;Argument[0];ReturnValue;taint", + let nsDataTainted4 = NSData(bytesNoCopy: source() as! UnsafeMutableRawPointer, length: 0, freeWhenDone: true) + sink(arg: nsDataTainted4) // $ tainted=66 + // ";NSData;true;init(data:);;;Argument[0];ReturnValue;taint", + let nsDataTainted5 = NSData(data: source() as! Data) + sink(arg: nsDataTainted5) // $ tainted=69 + // ";NSData;true;init(contentsOfFile:);;;Argument[0];ReturnValue;taint", + let nsDataTainted6 = NSData(contentsOfFile: source() as! String) + sink(arg: nsDataTainted6!) // $ tainted=72 + // ";NSData;true;init(contentsOfFile:options:);;;Argument[0];ReturnValue;taint", + let nsDataTainted7 = NSData(contentsOfFile: source() as! String, options: []) + sink(arg: nsDataTainted7) // $ tainted=75 + // ";NSData;true;init(contentsOf:);;;Argument[0];ReturnValue;taint", + let nsDataTainted8 = NSData(contentsOf: source() as! URL) + sink(arg: nsDataTainted8!) // $ tainted=78 + // ";NSData;true;init(contentsOf:options:);;;Argument[0];ReturnValue;taint", + let nsDataTainted9 = NSData(contentsOf: source() as! URL, options: []) + sink(arg: nsDataTainted9!) // $ tainted=81 + // ";NSData;true;init(contentsOfMappedFile:);;;Argument[0];ReturnValue;taint", + let nsDataTainted10 = NSData(contentsOfMappedFile: source() as! String) + sink(arg: nsDataTainted10!) // $ tainted=84 + // ";NSData;true;init(base64Encoded:options:);;;Argument[0];ReturnValue;taint", + let nsDataTainted11 = NSData(base64Encoded: source() as! Data, options: []) + sink(arg: nsDataTainted11!) // $ tainted=87 + let nsDataTainted12 = NSData(base64Encoded: source() as! String, options: []) + sink(arg: nsDataTainted12!) // $ tainted=89 + // ";NSData;true;init(base64Encoding:);;;Argument[0];ReturnValue;taint", + let nsDataTainted13 = NSData(base64Encoding: source() as! String) + sink(arg: nsDataTainted13!) // $ tainted=92 + // ";NSData;true;base64EncodedData(options:);;;Argument[-1];ReturnValue;taint", + let nsDataTainted14 = source() as! NSData + sink(arg: nsDataTainted14.base64EncodedData()) // $ tainted=95 + sink(arg: nsDataTainted14.base64EncodedData(options: [])) // $ tainted=95 + // ";NSData;true;base64EncodedString(options:);;;Argument[-1];ReturnValue;taint", + let nsDataTainted15 = source() as! NSData + sink(arg: nsDataTainted15.base64EncodedString()) // $ tainted=99 + sink(arg: nsDataTainted15.base64EncodedString(options: [])) // $ tainted=99 + // ";NSData;true;base64Encoding();;;Argument[-1];ReturnValue;taint", + let nsDataTainted16 = source() as! NSData + sink(arg: nsDataTainted16.base64Encoding()) // $ tainted=103 + // ";NSData;true;dataWithContentsOfMappedFile(_:);;;Argument[0];ReturnValue;taint", + sink(arg: NSData.dataWithContentsOfMappedFile(source() as! String)!) // $ tainted=106 + // ";NSData;true;enumerateBytes(_:);;;Argument[-1];Argument[0].Parameter[0];taint" + let nsDataTainted17 = source() as! NSData + nsDataTainted17.enumerateBytes { + bytes, byteRange, stop in sink(arg: bytes) // $ MISSING: tainted=108 + } + // ";NSData;true;getBytes(_:);;;Argument[-1];Argument[0];taint", + let nsDataTainted18 = source() as! NSData + let bufferTainted18 = UnsafeMutableRawPointer(bitPattern: 0)! + nsDataTainted18.getBytes(bufferTainted18) + sink(arg: bufferTainted18) // $ tainted=113 + // ";NSData;true;getBytes(_:length:);;;Argument[-1];Argument[0];taint", + let nsDataTainted19 = source() as! NSData + let bufferTainted19 = UnsafeMutableRawPointer(bitPattern: 0)! + nsDataTainted19.getBytes(bufferTainted19, length: 0) + sink(arg: bufferTainted19) // $ tainted=118 + // ";NSData;true;getBytes(_:range:);;;Argument[-1];Argument[0];taint", + let nsDataTainted20 = source() as! NSData + let bufferTainted20 = UnsafeMutableRawPointer(bitPattern: 0)! + nsDataTainted20.getBytes(bufferTainted20, range: NSRange()) + sink(arg: bufferTainted20) // $ tainted=123 + // ";NSData;true;subdata(with:);;;Argument[-1];ReturnValue;taint", + let nsDataTainted21 = source() as! NSData + sink(arg: nsDataTainted21.subdata(with: NSRange())) // $ tainted=128 + // ";NSData;true;compressed(using:);;;Argument[-1];ReturnValue;taint", + let nsDataTainted22 = source() as! NSData + sink(arg: nsDataTainted22.compressed(using: NSData.CompressionAlgorithm.none)) // $ tainted=131 + // ";NSData;true;decompressed(using:);;;Argument[-1];ReturnValue;taint" + let nsDataTainted23 = source() as! NSData + sink(arg: nsDataTainted23.decompressed(using: NSData.CompressionAlgorithm.none)) // $ tainted=134 + + // Fields + let nsDataTainted24 = source() as! NSData + sink(arg: nsDataTainted24.bytes) // $ tainted=138 + sink(arg: nsDataTainted24.description) // $ tainted=138 +} diff --git a/swift/ql/test/library-tests/dataflow/taint/nsmutabledata.swift b/swift/ql/test/library-tests/dataflow/taint/nsmutabledata.swift new file mode 100644 index 00000000000..20f2739f9f9 --- /dev/null +++ b/swift/ql/test/library-tests/dataflow/taint/nsmutabledata.swift @@ -0,0 +1,50 @@ +// --- stubs --- + +struct Data +{ + init(_ elements: S) {} +} + +struct NSRange {} + +class NSData {} + +class NSMutableData : NSData { + var mutableBytes: UnsafeMutableRawPointer = UnsafeMutableRawPointer(bitPattern: 0)! + func append(_ bytes: UnsafeRawPointer, length: Int) {} + func append(_ other: Data) {} + func replaceBytes(in range: NSRange, withBytes bytes: UnsafeRawPointer) {} + func replaceBytes(in range: NSRange, withBytes replacementBytes: UnsafeRawPointer?, length replacementLength: Int) {} + func setData(_ data: Data) {} +} + +// --- tests --- +func source() -> Any { return "" } +func sink(arg: Any) {} + +func test() { + // ";NSMutableData;true;append(_:length:);;;Argument[0];Argument[-1];taint", + let nsMutableDataTainted1 = NSMutableData() + nsMutableDataTainted1.append(source() as! UnsafeRawPointer, length: 0) + sink(arg: nsMutableDataTainted1) // $ tainted=28 + // ";MutableNSData;true;append(_:);;;Argument[0];Argument[-1];taint", + let nsMutableDataTainted2 = NSMutableData() + nsMutableDataTainted2.append(source() as! Data) + sink(arg: nsMutableDataTainted2) // $ tainted=32 + // ";NSMutableData;true;replaceBytes(in:withBytes:);;;Argument[1];Argument[-1];taint", + let nsMutableDataTainted3 = NSMutableData() + nsMutableDataTainted3.replaceBytes(in: NSRange(), withBytes: source() as! UnsafeRawPointer) + sink(arg: nsMutableDataTainted3) // $ tainted=36 + // ";NSMutableData;true;replaceBytes(in:withBytes:length:);;;Argument[1];Argument[-1];taint", + let nsMutableDataTainted4 = NSMutableData() + nsMutableDataTainted4.replaceBytes(in: NSRange(), withBytes: source() as? UnsafeRawPointer, length: 0) + sink(arg: nsMutableDataTainted4) // $ tainted=40 + // ";NSMutableData;true;setData(_:);;;Argument[1];Argument[-1];taint", + let nsMutableDataTainted5 = NSMutableData() + nsMutableDataTainted5.setData(source() as! Data) + sink(arg: nsMutableDataTainted5) // $ tainted=44 + + // Fields + let nsMutableDataTainted6 = source() as! NSMutableData + sink(arg: nsMutableDataTainted6.mutableBytes) // $ tainted=48 +} From a2ac1384cb7dd36365265561ef3f1aff9e3bec35 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Tue, 22 Nov 2022 17:16:57 +0100 Subject: [PATCH 450/796] Swift: do not abort if cannot archive a source file --- swift/extractor/SwiftExtractor.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index 981ab7c1370..349943f2869 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -46,7 +46,6 @@ static void archiveFile(const SwiftExtractorConfiguration& config, swift::Source if (ec) { std::cerr << "Cannot archive source file " << srcFilePath << " -> " << dstFilePath << ": " << ec.message() << "\n"; - std::abort(); } } From 8f02463411efd9f90a2bce28cc0845df9ede7b16 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Tue, 22 Nov 2022 13:47:24 +0100 Subject: [PATCH 451/796] Swift: fix remapping bug This issue has slipped during a recent refactoring: https://github.com/github/codeql/pull/10987/files#diff-c5ab26a06a93c4507a834859a6a56878d5bfe16c4d7cbac4afc4f081d46f461aL63-R64 --- swift/extractor/remapping/SwiftOpenInterception.macOS.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/extractor/remapping/SwiftOpenInterception.macOS.cpp b/swift/extractor/remapping/SwiftOpenInterception.macOS.cpp index 035492fd385..0ac23d14cbc 100644 --- a/swift/extractor/remapping/SwiftOpenInterception.macOS.cpp +++ b/swift/extractor/remapping/SwiftOpenInterception.macOS.cpp @@ -61,7 +61,7 @@ void finalizeRemapping( } auto hash = originalHashFile(original); auto hashed = scratchDir / hash; - if (!hash.empty() && fs::exists(hashed)) { + if (!hash.empty() && fs::exists(patched)) { std::error_code ec; fs::create_symlink(/* target */ patched, /* symlink */ hashed, ec); if (ec) { From 24c413fbf98eb3e66521d2f8496505ab2dd00003 Mon Sep 17 00:00:00 2001 From: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Date: Tue, 22 Nov 2022 18:33:24 +0000 Subject: [PATCH 452/796] Adds Kotlin (beta) content --- .../codeql-cli/creating-codeql-databases.rst | 4 +++- ...with-codeql-packs-in-visual-studio-code.rst | 2 +- ...-classes-for-working-with-java-programs.rst | 2 ++ .../analyzing-data-flow-in-java.rst | 2 ++ .../codeql-language-guides/codeql-for-java.rst | 14 +++++++++++--- .../codeql-overview/system-requirements.rst | 2 ++ docs/codeql/query-help/codeql-cwe-coverage.rst | 2 ++ docs/codeql/query-help/index.rst | 4 +++- docs/codeql/reusables/extractors.rst | 2 +- docs/codeql/reusables/kotlin-beta-note.rst | 4 ++++ .../reusables/kotlin-java-differences.rst | 18 ++++++++++++++++++ docs/codeql/support/reusables/frameworks.rst | 4 +++- 12 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 docs/codeql/reusables/kotlin-beta-note.rst create mode 100644 docs/codeql/reusables/kotlin-java-differences.rst diff --git a/docs/codeql/codeql-cli/creating-codeql-databases.rst b/docs/codeql/codeql-cli/creating-codeql-databases.rst index b305c6e1cb6..326f260fc70 100644 --- a/docs/codeql/codeql-cli/creating-codeql-databases.rst +++ b/docs/codeql/codeql-cli/creating-codeql-databases.rst @@ -168,7 +168,9 @@ generate a database, therefore the build method must be available to the CLI. Detecting the build system ~~~~~~~~~~~~~~~~~~~~~~~~~~ -The CodeQL CLI includes autobuilders for C/C++, C#, Go, and Java code. CodeQL +.. include:: ../reusables/kotlin-beta-note.rst + +The CodeQL CLI includes autobuilders for C/C++, C#, Go, Java and Kotlin code. CodeQL autobuilders allow you to build projects for compiled languages without specifying any build commands. When an autobuilder is invoked, CodeQL examines the source for evidence of a build system and attempts to run the optimal set of diff --git a/docs/codeql/codeql-for-visual-studio-code/working-with-codeql-packs-in-visual-studio-code.rst b/docs/codeql/codeql-for-visual-studio-code/working-with-codeql-packs-in-visual-studio-code.rst index a13832239dc..65cf1ef78ef 100644 --- a/docs/codeql/codeql-for-visual-studio-code/working-with-codeql-packs-in-visual-studio-code.rst +++ b/docs/codeql/codeql-for-visual-studio-code/working-with-codeql-packs-in-visual-studio-code.rst @@ -30,7 +30,7 @@ You can then use the CodeQL CLI to publish your pack to share with others. For m Viewing CodeQL packs and their dependencies in Visual Studio Code ----------------------------------------------------------------- To download a CodeQL pack that someone else has created, run the **CodeQL: Download Packs** command from the Command Palette. -You can download all the core CodeQL query packs, or enter the full name of a specific pack to download. For example, to download the core queries for analyzing Java, enter ``codeql/java-queries``. +You can download all the core CodeQL query packs, or enter the full name of a specific pack to download. For example, to download the core queries for analyzing Java or Kotlin, enter ``codeql/java-queries``. Whether you have downloaded a CodeQL pack or created your own, you can open the ``qlpack.yml`` file in the root of a CodeQL pack directory in Visual Studio Code and view the dependencies section to see what libraries the pack depends on. diff --git a/docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-java-programs.rst b/docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-java-programs.rst index 83bce3652b9..7819f762b98 100644 --- a/docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-java-programs.rst +++ b/docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-java-programs.rst @@ -7,6 +7,8 @@ CodeQL has a large selection of classes for representing the abstract syntax tre .. include:: ../reusables/abstract-syntax-tree.rst +.. include:: ../reusables/kotlin-java-differences.rst + Statement classes ----------------- diff --git a/docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst index 75309842ad5..cd64a18bcad 100644 --- a/docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst +++ b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst @@ -5,6 +5,8 @@ Analyzing data flow in Java You can use CodeQL to track the flow of data through a Java program to its use. +.. include:: ../reusables/kotlin-java-differences.rst + About this article ------------------ diff --git a/docs/codeql/codeql-language-guides/codeql-for-java.rst b/docs/codeql/codeql-language-guides/codeql-for-java.rst index 53489bc5207..6a16ea0658d 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-java.rst @@ -1,9 +1,17 @@ .. _codeql-for-java: -CodeQL for Java -=============== +CodeQL for Java and Kotlin +========================== -Experiment and learn how to write effective and efficient queries for CodeQL databases generated from Java codebases. +Experiment and learn how to write effective and efficient queries for CodeQL databases generated from Java and Kotlin codebases. + +.. include:: ../reusables/kotlin-beta-note.rst + +.. include:: ../reusables/kotlin-java-differences.rst + +.. pull-quote:: Enabling Kotlin support + + To enable Kotlin support, you should enable `java` as a language. .. toctree:: :hidden: diff --git a/docs/codeql/codeql-overview/system-requirements.rst b/docs/codeql/codeql-overview/system-requirements.rst index 5569462e5ae..fd4465f9ba4 100644 --- a/docs/codeql/codeql-overview/system-requirements.rst +++ b/docs/codeql/codeql-overview/system-requirements.rst @@ -11,6 +11,8 @@ Supported platforms ####################### .. include:: ../support/reusables/platforms.rst + +.. include:: ../reusables/kotlin-beta-note.rst Additional software requirements ################################ diff --git a/docs/codeql/query-help/codeql-cwe-coverage.rst b/docs/codeql/query-help/codeql-cwe-coverage.rst index c0b36646df8..680f41b1056 100644 --- a/docs/codeql/query-help/codeql-cwe-coverage.rst +++ b/docs/codeql/query-help/codeql-cwe-coverage.rst @@ -3,6 +3,8 @@ CodeQL CWE coverage You can view the full coverage of MITRE's Common Weakness Enumeration (CWE) or coverage by language for the latest release of CodeQL. +.. include:: ../reusables/kotlin-beta-note.rst + About CWEs ########## diff --git a/docs/codeql/query-help/index.rst b/docs/codeql/query-help/index.rst index b45b3a5bf87..6dad02ce2b1 100644 --- a/docs/codeql/query-help/index.rst +++ b/docs/codeql/query-help/index.rst @@ -6,11 +6,13 @@ View the query help for the queries included in the ``code-scanning``, ``securit - :doc:`CodeQL query help for C and C++ ` - :doc:`CodeQL query help for C# ` - :doc:`CodeQL query help for Go ` -- :doc:`CodeQL query help for Java ` +- :doc:`CodeQL query help for Java and Kotlin ` - :doc:`CodeQL query help for JavaScript ` - :doc:`CodeQL query help for Python ` - :doc:`CodeQL query help for Ruby ` +.. include:: ../reusables/kotlin-beta-note.rst + .. pull-quote:: Information Each query help article includes: diff --git a/docs/codeql/reusables/extractors.rst b/docs/codeql/reusables/extractors.rst index a3a4952811d..606c57d0208 100644 --- a/docs/codeql/reusables/extractors.rst +++ b/docs/codeql/reusables/extractors.rst @@ -10,7 +10,7 @@ - ``csharp`` * - Go - ``go`` - * - Java + * - Java/Kotlin - ``java`` * - JavaScript/TypeScript - ``javascript`` diff --git a/docs/codeql/reusables/kotlin-beta-note.rst b/docs/codeql/reusables/kotlin-beta-note.rst new file mode 100644 index 00000000000..d05d137a13e --- /dev/null +++ b/docs/codeql/reusables/kotlin-beta-note.rst @@ -0,0 +1,4 @@ + .. pull-quote:: Note + + CodeQL analysis for Kotlin is currently in beta. During the beta, analysis of Kotlin code, + and the accompanying documentation, will not be as comprehensive as for other languages. \ No newline at end of file diff --git a/docs/codeql/reusables/kotlin-java-differences.rst b/docs/codeql/reusables/kotlin-java-differences.rst new file mode 100644 index 00000000000..b9d792d6d9f --- /dev/null +++ b/docs/codeql/reusables/kotlin-java-differences.rst @@ -0,0 +1,18 @@ +Writing CodeQL queries in Kotlin versus Java +-------------------------------------------- + +When writing Kotlin-specific elements (such as a `WhenExpr`) you’ll need to use Kotlin-specific CodeQL classes, but writing queries for Kotlin and Java is largely the same. The two make use of the same libraries such as DataFlow, TaintTracking, or SSA, and the same classes such as `MethodAccess` or `Class`. + +There are however some important cases where writing queries for Kotlin can produce surprising results compared to writing Java queries, as CodeQL works with the JVM bytecode representation of the source code. + +Be careful when trying to model code elements that don’t exist in Java, such as `NotNullExpr (expr!!)`, because they could interact in unexpected ways with common predicates. For example, `MethodAccess.getQualifier()` gets a `NotNullExpr `instead of a `VarAccess`` in the following Kotlin code: + +`someVar!!.someMethodCall()` + +In that specific case, you can use the predicate `Expr.getUnderlyingExpr()`. This goes directly to the underlying `VarAccess`` to produce a more similar behavior to that in Java. + +Nullable elements (`?`) can also produce unexpected behavior. To avoid a `NullPointerException`, Kotlin may inline calls like `expr.toString()` to `String.valueOf(expr)` when `expr` is nullable. Make sure that you write CodeQL around the extracted code, and do not directly modify the source code in the codebase. + +Another example is that if-else expressions are translated into `WhenExprs` in CodeQL, instead of the more typical `IfStmt` in Java. + +In general, you can debug these issues with the AST (you can use the `CodeQL: View AST`` command from Visual Studio Code’s CodeQL extension, or run the `PrintAst.ql`` query) and checking what exactly CodeQL is extracting from your code. \ No newline at end of file diff --git a/docs/codeql/support/reusables/frameworks.rst b/docs/codeql/support/reusables/frameworks.rst index b83b26f486a..191b40b4896 100644 --- a/docs/codeql/support/reusables/frameworks.rst +++ b/docs/codeql/support/reusables/frameworks.rst @@ -93,9 +93,11 @@ and the CodeQL library pack ``codeql/go-all`` (`changelog `_, Serialization `zap `_, Logging library -Java built-in support +Java and Kotlin built-in support ================================== +.. include:: ../reusables/kotlin-beta-note.rst + Provided by the current versions of the CodeQL query pack ``codeql/java-queries`` (`changelog `__, `source `__) and the CodeQL library pack ``codeql/java-all`` (`changelog `__, `source `__). From 4ad7d2d8220126b21ea1abcec6d056d02b96ec1e Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 22 Nov 2022 19:51:44 +0100 Subject: [PATCH 453/796] C#: Also include extractor unit tests in `csharp-qltest.yml` --- .github/workflows/csharp-qltest.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/csharp-qltest.yml b/.github/workflows/csharp-qltest.yml index 78b0ef6a87b..28b3fb7477d 100644 --- a/.github/workflows/csharp-qltest.yml +++ b/.github/workflows/csharp-qltest.yml @@ -70,3 +70,16 @@ jobs: codeql test run --threads=0 --ram 52000 --slice ${{ matrix.slice }} --search-path "${{ github.workspace }}/csharp/extractor-pack" --check-databases --check-undefined-labels --check-repeated-labels --check-redefined-labels --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" env: GITHUB_TOKEN: ${{ github.token }} + unit-tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Setup dotnet + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 6.0.202 + - name: Extractor unit tests + run: | + dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/csharp/extractor/Semmle.Util.Tests" + dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/csharp/extractor/Semmle.Extraction.Tests" + dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests" From d113fb23c839723e96709db42b071b7f90c484e4 Mon Sep 17 00:00:00 2001 From: ka1n4t <574702476@qq.com> Date: Wed, 23 Nov 2022 11:05:58 +0800 Subject: [PATCH 454/796] Add test case for PR-11368 --- .../MyBatisAnnotationSqlInjection.expected | 14 +++++++++++ .../CWE-089/src/main/MybatisSqlInjection.java | 12 +++++++++- .../src/main/MybatisSqlInjectionService.java | 8 +++++++ .../CWE-089/src/main/SqlInjectionMapper.java | 23 ++++++++++++------- 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MyBatisAnnotationSqlInjection.expected b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MyBatisAnnotationSqlInjection.expected index dfc923f9b58..481c8307ac3 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MyBatisAnnotationSqlInjection.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MyBatisAnnotationSqlInjection.expected @@ -1,16 +1,30 @@ edges | MybatisSqlInjection.java:62:19:62:43 | name : String | MybatisSqlInjection.java:63:35:63:38 | name : String | | MybatisSqlInjection.java:63:35:63:38 | name : String | MybatisSqlInjectionService.java:48:19:48:29 | name : String | +| MybatisSqlInjection.java:94:21:94:45 | name : String | MybatisSqlInjection.java:95:37:95:40 | name : String | +| MybatisSqlInjection.java:95:37:95:40 | name : String | MybatisSqlInjectionService.java:76:21:76:31 | name : String | +| MybatisSqlInjection.java:99:21:99:44 | age : String | MybatisSqlInjection.java:100:37:100:39 | age : String | +| MybatisSqlInjection.java:100:37:100:39 | age : String | MybatisSqlInjectionService.java:80:21:80:30 | age : String | | MybatisSqlInjectionService.java:48:19:48:29 | name : String | MybatisSqlInjectionService.java:50:23:50:26 | name : String | | MybatisSqlInjectionService.java:50:3:50:9 | hashMap [post update] [] : String | MybatisSqlInjectionService.java:51:27:51:33 | hashMap | | MybatisSqlInjectionService.java:50:23:50:26 | name : String | MybatisSqlInjectionService.java:50:3:50:9 | hashMap [post update] [] : String | +| MybatisSqlInjectionService.java:76:21:76:31 | name : String | MybatisSqlInjectionService.java:77:29:77:32 | name | +| MybatisSqlInjectionService.java:80:21:80:30 | age : String | MybatisSqlInjectionService.java:81:29:81:31 | age | nodes | MybatisSqlInjection.java:62:19:62:43 | name : String | semmle.label | name : String | | MybatisSqlInjection.java:63:35:63:38 | name : String | semmle.label | name : String | +| MybatisSqlInjection.java:94:21:94:45 | name : String | semmle.label | name : String | +| MybatisSqlInjection.java:95:37:95:40 | name : String | semmle.label | name : String | +| MybatisSqlInjection.java:99:21:99:44 | age : String | semmle.label | age : String | +| MybatisSqlInjection.java:100:37:100:39 | age : String | semmle.label | age : String | | MybatisSqlInjectionService.java:48:19:48:29 | name : String | semmle.label | name : String | | MybatisSqlInjectionService.java:50:3:50:9 | hashMap [post update] [] : String | semmle.label | hashMap [post update] [] : String | | MybatisSqlInjectionService.java:50:23:50:26 | name : String | semmle.label | name : String | | MybatisSqlInjectionService.java:51:27:51:33 | hashMap | semmle.label | hashMap | +| MybatisSqlInjectionService.java:76:21:76:31 | name : String | semmle.label | name : String | +| MybatisSqlInjectionService.java:77:29:77:32 | name | semmle.label | name | +| MybatisSqlInjectionService.java:80:21:80:30 | age : String | semmle.label | age : String | +| MybatisSqlInjectionService.java:81:29:81:31 | age | semmle.label | age | subpaths #select | MybatisSqlInjectionService.java:51:27:51:33 | hashMap | MybatisSqlInjection.java:62:19:62:43 | name : String | MybatisSqlInjectionService.java:51:27:51:33 | hashMap | MyBatis annotation SQL injection might include code from $@ to $@. | MybatisSqlInjection.java:62:19:62:43 | name | this user input | SqlInjectionMapper.java:33:2:33:54 | Select | this SQL operation | diff --git a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjection.java b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjection.java index 624f27ad81d..5aa6876e00c 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjection.java +++ b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjection.java @@ -79,7 +79,7 @@ public class MybatisSqlInjection { public void badDelete(@RequestParam String name) { mybatisSqlInjectionService.badDelete(name); } - + @GetMapping(value = "badUpdate") public void badUpdate(@RequestParam String name) { mybatisSqlInjectionService.badUpdate(name); @@ -89,4 +89,14 @@ public class MybatisSqlInjection { public void badInsert(@RequestParam String name) { mybatisSqlInjectionService.badInsert(name); } + + @GetMapping(value = "kkbad1") + public void kkbad1(@RequestParam String name, @RequestParam Integer age) { + mybatisSqlInjectionService.kkbad1(name, age); + } + + @GetMapping(value = "kkbad2") + public void kkbad2(@RequestParam String age) { + mybatisSqlInjectionService.kkbad2(age); + } } diff --git a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjectionService.java b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjectionService.java index 89dbd599d71..28b9bebc1f4 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjectionService.java +++ b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjectionService.java @@ -72,4 +72,12 @@ public class MybatisSqlInjectionService { public void badInsert(String input) { sqlInjectionMapper.badInsert(input); } + + public void kkbad1(String name, Integer age){ + sqlInjectionMapper.kkbad1(name, age); + } + + public void kkbad2(String age){ + sqlInjectionMapper.kkbad2(age); + } } diff --git a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.java b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.java index 5b159817297..50801558eb8 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.java +++ b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.java @@ -37,26 +37,33 @@ public interface SqlInjectionMapper { //using providers @SelectProvider( - type = MyBatisProvider.class, - method = "badSelect" + type = MyBatisProvider.class, + method = "badSelect" ) String badSelect(String input); @DeleteProvider( - type = MyBatisProvider.class, - method = "badDelete" + type = MyBatisProvider.class, + method = "badDelete" ) void badDelete(String input); @UpdateProvider( - type = MyBatisProvider.class, - method = "badUpdate" + type = MyBatisProvider.class, + method = "badUpdate" ) void badUpdate(String input); @InsertProvider( - type = MyBatisProvider.class, - method = "badInsert" + type = MyBatisProvider.class, + method = "badInsert" ) void badInsert(String input); + + @Select("select * from user_info where name = #{name} and age = ${age}") + String kkbad1(@Param("name") String name, Integer age); + + @Select("select * from user_info where age = #{age}") + String kkbad2(@Param("age") String age); + } From 556d68aeed7bd6177c410c7badf472645de43ce8 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 23 Nov 2022 09:17:18 +0000 Subject: [PATCH 455/796] Update swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql Co-authored-by: Tony Torralba --- swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql index 21c1c538462..04108a33d29 100644 --- a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql +++ b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql @@ -66,8 +66,7 @@ class AlamofireTransmitted extends Transmitted { fName.regexpMatch("(request|streamRequest|download)\\(.*") and ( call.getArgument(0).getExpr() = this or - call.getArgumentWithLabel("parameters").getExpr() = this or - call.getArgumentWithLabel("headers").getExpr() = this + call.getArgumentWithLabel(["headers", "parameters"]).getExpr() = this ) ) } From e16bdc4d07741ba024d1ebcc27cd17157f0c8e74 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Wed, 23 Nov 2022 09:43:15 +0000 Subject: [PATCH 456/796] Ruby/QL: only create dbscheme case-splits for columns on defining tables --- ql/node-types/src/lib.rs | 17 +++++++++++++---- ruby/node-types/src/lib.rs | 17 +++++++++++++---- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/ql/node-types/src/lib.rs b/ql/node-types/src/lib.rs index 0472443a380..9467e23fd62 100644 --- a/ql/node-types/src/lib.rs +++ b/ql/node-types/src/lib.rs @@ -81,6 +81,14 @@ pub enum Storage { }, } +impl Storage { + pub fn is_column(&self) -> bool { + match self { + Storage::Column { .. } => true, + _ => false, + } + } +} pub fn read_node_types(prefix: &str, node_types_path: &Path) -> std::io::Result { let file = fs::File::open(node_types_path)?; let node_types: Vec = serde_json::from_reader(file)?; @@ -245,10 +253,11 @@ fn add_field( } }; let converted_types = convert_types(&field_info.types); - let type_info = if field_info - .types - .iter() - .all(|t| !t.named && token_kinds.contains(&convert_type(t))) + let type_info = if storage.is_column() + && field_info + .types + .iter() + .all(|t| !t.named && token_kinds.contains(&convert_type(t))) { // All possible types for this field are reserved words. The db // representation will be an `int` with a `case @foo.field = ...` to diff --git a/ruby/node-types/src/lib.rs b/ruby/node-types/src/lib.rs index a48e9ddbf9a..97b535ae912 100644 --- a/ruby/node-types/src/lib.rs +++ b/ruby/node-types/src/lib.rs @@ -81,6 +81,14 @@ pub enum Storage { }, } +impl Storage { + pub fn is_column(&self) -> bool { + match self { + Storage::Column { .. } => true, + _ => false, + } + } +} pub fn read_node_types(prefix: &str, node_types_path: &Path) -> std::io::Result { let file = fs::File::open(node_types_path)?; let node_types: Vec = serde_json::from_reader(file)?; @@ -245,10 +253,11 @@ fn add_field( } }; let converted_types = convert_types(&field_info.types); - let type_info = if field_info - .types - .iter() - .all(|t| !t.named && token_kinds.contains(&convert_type(t))) + let type_info = if storage.is_column() + && field_info + .types + .iter() + .all(|t| !t.named && token_kinds.contains(&convert_type(t))) { // All possible types for this field are reserved words. The db // representation will be an `int` with a `case @foo.field = ...` to From e2240abc7853cc1ef3d64c56ec335ee6a32de279 Mon Sep 17 00:00:00 2001 From: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Date: Wed, 23 Nov 2022 10:06:34 +0000 Subject: [PATCH 457/796] Update docs/codeql/codeql-language-guides/codeql-for-java.rst Co-authored-by: Felicity Chapman --- docs/codeql/codeql-language-guides/codeql-for-java.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/codeql-for-java.rst b/docs/codeql/codeql-language-guides/codeql-for-java.rst index 6a16ea0658d..536dfbc294e 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-java.rst @@ -11,7 +11,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat .. pull-quote:: Enabling Kotlin support - To enable Kotlin support, you should enable `java` as a language. + To enable Kotlin support, you should enable ``java`` as a language. .. toctree:: :hidden: From 605c7113a2b1f7b947be9c45518c84807b589521 Mon Sep 17 00:00:00 2001 From: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Date: Wed, 23 Nov 2022 10:06:48 +0000 Subject: [PATCH 458/796] Update docs/codeql/reusables/kotlin-java-differences.rst Co-authored-by: Felicity Chapman --- docs/codeql/reusables/kotlin-java-differences.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/codeql/reusables/kotlin-java-differences.rst b/docs/codeql/reusables/kotlin-java-differences.rst index b9d792d6d9f..7f091d2b7a8 100644 --- a/docs/codeql/reusables/kotlin-java-differences.rst +++ b/docs/codeql/reusables/kotlin-java-differences.rst @@ -1,5 +1,5 @@ -Writing CodeQL queries in Kotlin versus Java --------------------------------------------- +Writing CodeQL queries for Kotlin versus Java analysis +------------------------------------------------------ When writing Kotlin-specific elements (such as a `WhenExpr`) you’ll need to use Kotlin-specific CodeQL classes, but writing queries for Kotlin and Java is largely the same. The two make use of the same libraries such as DataFlow, TaintTracking, or SSA, and the same classes such as `MethodAccess` or `Class`. From 4bd7e24b5fac88d428867dca0103b30984035dee Mon Sep 17 00:00:00 2001 From: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Date: Wed, 23 Nov 2022 10:06:57 +0000 Subject: [PATCH 459/796] Update docs/codeql/reusables/kotlin-java-differences.rst Co-authored-by: Felicity Chapman --- docs/codeql/reusables/kotlin-java-differences.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/codeql/reusables/kotlin-java-differences.rst b/docs/codeql/reusables/kotlin-java-differences.rst index 7f091d2b7a8..f36b1c62845 100644 --- a/docs/codeql/reusables/kotlin-java-differences.rst +++ b/docs/codeql/reusables/kotlin-java-differences.rst @@ -7,7 +7,8 @@ There are however some important cases where writing queries for Kotlin can prod Be careful when trying to model code elements that don’t exist in Java, such as `NotNullExpr (expr!!)`, because they could interact in unexpected ways with common predicates. For example, `MethodAccess.getQualifier()` gets a `NotNullExpr `instead of a `VarAccess`` in the following Kotlin code: -`someVar!!.someMethodCall()` +.. code-block:: kotlin + someVar!!.someMethodCall() In that specific case, you can use the predicate `Expr.getUnderlyingExpr()`. This goes directly to the underlying `VarAccess`` to produce a more similar behavior to that in Java. From c663da5be6d90734ab34e06b316e4218a39743d3 Mon Sep 17 00:00:00 2001 From: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Date: Wed, 23 Nov 2022 10:07:03 +0000 Subject: [PATCH 460/796] Update docs/codeql/reusables/kotlin-java-differences.rst Co-authored-by: Felicity Chapman --- docs/codeql/reusables/kotlin-java-differences.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/reusables/kotlin-java-differences.rst b/docs/codeql/reusables/kotlin-java-differences.rst index f36b1c62845..39d7e39d21e 100644 --- a/docs/codeql/reusables/kotlin-java-differences.rst +++ b/docs/codeql/reusables/kotlin-java-differences.rst @@ -5,7 +5,7 @@ When writing Kotlin-specific elements (such as a `WhenExpr`) you’ll need to us There are however some important cases where writing queries for Kotlin can produce surprising results compared to writing Java queries, as CodeQL works with the JVM bytecode representation of the source code. -Be careful when trying to model code elements that don’t exist in Java, such as `NotNullExpr (expr!!)`, because they could interact in unexpected ways with common predicates. For example, `MethodAccess.getQualifier()` gets a `NotNullExpr `instead of a `VarAccess`` in the following Kotlin code: +Be careful when you model code elements that don’t exist in Java, such as ``NotNullExpr (expr!!)``, because they could interact in unexpected ways with common predicates. For example, ``MethodAccess.getQualifier()`` returns a ``NotNullExpr`` instead of a ``VarAccess`` in the following Kotlin code: .. code-block:: kotlin someVar!!.someMethodCall() From c06b8a68e5211f193c6956de395480b5f8349e06 Mon Sep 17 00:00:00 2001 From: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Date: Wed, 23 Nov 2022 10:08:00 +0000 Subject: [PATCH 461/796] Update docs/codeql/reusables/kotlin-java-differences.rst Co-authored-by: Felicity Chapman --- docs/codeql/reusables/kotlin-java-differences.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/reusables/kotlin-java-differences.rst b/docs/codeql/reusables/kotlin-java-differences.rst index 39d7e39d21e..7a228408104 100644 --- a/docs/codeql/reusables/kotlin-java-differences.rst +++ b/docs/codeql/reusables/kotlin-java-differences.rst @@ -3,7 +3,7 @@ Writing CodeQL queries for Kotlin versus Java analysis When writing Kotlin-specific elements (such as a `WhenExpr`) you’ll need to use Kotlin-specific CodeQL classes, but writing queries for Kotlin and Java is largely the same. The two make use of the same libraries such as DataFlow, TaintTracking, or SSA, and the same classes such as `MethodAccess` or `Class`. -There are however some important cases where writing queries for Kotlin can produce surprising results compared to writing Java queries, as CodeQL works with the JVM bytecode representation of the source code. +There are however some important cases where writing queries for Kotlin can produce surprising results compared to writing queries for Java, as CodeQL works with the JVM bytecode representation of the Kotlin source code. Be careful when you model code elements that don’t exist in Java, such as ``NotNullExpr (expr!!)``, because they could interact in unexpected ways with common predicates. For example, ``MethodAccess.getQualifier()`` returns a ``NotNullExpr`` instead of a ``VarAccess`` in the following Kotlin code: From df7f0cf9a96c11ea1eed51cb1f9f301bdd1302f8 Mon Sep 17 00:00:00 2001 From: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Date: Wed, 23 Nov 2022 10:08:10 +0000 Subject: [PATCH 462/796] Update docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst --- .../codeql-language-guides/analyzing-data-flow-in-java.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst index cd64a18bcad..2eccdf5e103 100644 --- a/docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst +++ b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst @@ -5,6 +5,8 @@ Analyzing data flow in Java You can use CodeQL to track the flow of data through a Java program to its use. +.. include:: ../reusables/kotlin-beta-note.rst + .. include:: ../reusables/kotlin-java-differences.rst About this article From 0a91ee10195a35743dd8bb1be2c5630acfa25c0e Mon Sep 17 00:00:00 2001 From: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Date: Wed, 23 Nov 2022 10:08:20 +0000 Subject: [PATCH 463/796] Update docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-java-programs.rst --- ...tract-syntax-tree-classes-for-working-with-java-programs.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-java-programs.rst b/docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-java-programs.rst index 7819f762b98..7d41785ea89 100644 --- a/docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-java-programs.rst +++ b/docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-java-programs.rst @@ -7,6 +7,8 @@ CodeQL has a large selection of classes for representing the abstract syntax tre .. include:: ../reusables/abstract-syntax-tree.rst +.. include:: ../reusables/kotlin-beta-note.rst + .. include:: ../reusables/kotlin-java-differences.rst Statement classes From 7644ecad52fdb11d1d511a179d6d18280e9bdd4a Mon Sep 17 00:00:00 2001 From: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Date: Wed, 23 Nov 2022 10:08:29 +0000 Subject: [PATCH 464/796] Update docs/codeql/reusables/kotlin-java-differences.rst Co-authored-by: Felicity Chapman --- docs/codeql/reusables/kotlin-java-differences.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/reusables/kotlin-java-differences.rst b/docs/codeql/reusables/kotlin-java-differences.rst index 7a228408104..15831b5d2bc 100644 --- a/docs/codeql/reusables/kotlin-java-differences.rst +++ b/docs/codeql/reusables/kotlin-java-differences.rst @@ -16,4 +16,4 @@ Nullable elements (`?`) can also produce unexpected behavior. To avoid a `NullPo Another example is that if-else expressions are translated into `WhenExprs` in CodeQL, instead of the more typical `IfStmt` in Java. -In general, you can debug these issues with the AST (you can use the `CodeQL: View AST`` command from Visual Studio Code’s CodeQL extension, or run the `PrintAst.ql`` query) and checking what exactly CodeQL is extracting from your code. \ No newline at end of file +In general, you can debug these issues with the AST (you can use the ``CodeQL: View AST`` command from Visual Studio Code’s CodeQL extension, or run the ``PrintAst.ql`` query) and see exactly what CodeQL is extracting from your code. \ No newline at end of file From 093ff4061dab1b6dde2b898559c788ff6d77c23d Mon Sep 17 00:00:00 2001 From: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Date: Wed, 23 Nov 2022 10:08:45 +0000 Subject: [PATCH 465/796] Update docs/codeql/reusables/kotlin-java-differences.rst Co-authored-by: Felicity Chapman --- docs/codeql/reusables/kotlin-java-differences.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/reusables/kotlin-java-differences.rst b/docs/codeql/reusables/kotlin-java-differences.rst index 15831b5d2bc..2cefb35a6ea 100644 --- a/docs/codeql/reusables/kotlin-java-differences.rst +++ b/docs/codeql/reusables/kotlin-java-differences.rst @@ -1,7 +1,7 @@ Writing CodeQL queries for Kotlin versus Java analysis ------------------------------------------------------ -When writing Kotlin-specific elements (such as a `WhenExpr`) you’ll need to use Kotlin-specific CodeQL classes, but writing queries for Kotlin and Java is largely the same. The two make use of the same libraries such as DataFlow, TaintTracking, or SSA, and the same classes such as `MethodAccess` or `Class`. +Generally you use the same classes to write queries for Kotlin and for Java. You use the same libraries such as DataFlow, TaintTracking, or SSA, and the same classes such as `MethodAccess` or `Class` for both languages. When you want to access Kotlin-specific elements (such as a ``WhenExpr``) you’ll need to use Kotlin-specific CodeQL classes. There are however some important cases where writing queries for Kotlin can produce surprising results compared to writing queries for Java, as CodeQL works with the JVM bytecode representation of the Kotlin source code. From 2e3413c9b8db194fa5eaf7e6e3df5e96fe3bd043 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 11 Nov 2022 13:07:38 +0100 Subject: [PATCH 466/796] JS: Merge package/type columns --- .../ql/lib/semmle/javascript/ApiGraphs.qll | 3 + .../semmle/javascript/frameworks/NoSQL.qll | 26 +- .../lib/semmle/javascript/frameworks/SQL.qll | 18 +- .../data/internal/ApiGraphModels.qll | 312 ++-- .../data/internal/ApiGraphModelsSpecific.qll | 85 +- .../javascript/frameworks/minimongo/Model.qll | 150 +- .../frameworks/minimongo/model.json | 150 +- .../javascript/frameworks/mongodb/Model.qll | 1338 ++++++++-------- .../javascript/frameworks/mongodb/model.json | 1352 ++++++++--------- .../javascript/frameworks/mssql/Model.qll | 68 +- .../javascript/frameworks/mssql/model.json | 74 +- .../javascript/frameworks/mysql/Model.qll | 120 +- .../javascript/frameworks/mysql/model.json | 138 +- .../semmle/javascript/frameworks/pg/Model.qll | 150 +- .../javascript/frameworks/pg/model.json | 166 +- .../javascript/frameworks/sequelize/Model.qll | 520 +++---- .../frameworks/sequelize/model.json | 522 +++---- .../javascript/frameworks/spanner/Model.qll | 348 ++--- .../javascript/frameworks/spanner/model.json | 348 ++--- .../javascript/frameworks/sqlite3/Model.qll | 36 +- .../javascript/frameworks/sqlite3/model.json | 38 +- .../test/ApiGraphs/typed/NodeOfType.expected | 5 + .../frameworks/data/test.expected | 1 + .../library-tests/frameworks/data/test.ql | 95 +- .../frameworks/data/warnings.expected | 4 +- .../library-tests/frameworks/data/warnings.ql | 14 +- 26 files changed, 3050 insertions(+), 3031 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/ApiGraphs.qll b/javascript/ql/lib/semmle/javascript/ApiGraphs.qll index 72d5a50cebe..f7460d802f5 100644 --- a/javascript/ql/lib/semmle/javascript/ApiGraphs.qll +++ b/javascript/ql/lib/semmle/javascript/ApiGraphs.qll @@ -562,6 +562,9 @@ module API { /** Gets a node whose type has the given qualified name, not including types from models. */ Node getANodeOfTypeRaw(string moduleName, string exportedName) { result = Impl::MkTypeUse(moduleName, exportedName).(Node).getInstance() + or + exportedName = "" and + result = getAModuleImportRaw(moduleName) } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll b/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll index 11f454eadd5..3fa7b3bd3e2 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll @@ -24,7 +24,7 @@ private module MongoDB { override predicate row(string row) { // In Mongo version 2.x, a client and a database handle were the same concept, but in 3.x // they were separated. To handle everything with a single model, we treat them as the same here. - row = "mongodb;Db;mongodb;MongoClient;" + row = "mongodb.Db;mongodb.MongoClient;" } } @@ -42,11 +42,11 @@ private module MongoDB { /** A call to a MongoDB query method. */ private class QueryCall extends DatabaseAccess, API::CallNode { QueryCall() { - this = ModelOutput::getATypeNode("mongodb", "Collection").getAMember().getACall() and + this = ModelOutput::getATypeNode("mongodb.Collection").getAMember().getACall() and not this.getCalleeName() = ["toString", "valueOf", "getLogger"] or this = - ModelOutput::getATypeNode("mongodb", ["Db", "MongoClient"]) + ModelOutput::getATypeNode(["mongodb.Db", "mongodb.MongoClient"]) .getMember(["watch", "aggregate"]) .getACall() } @@ -63,7 +63,7 @@ private module MongoDB { private class Insertion extends DatabaseAccess, API::CallNode { Insertion() { - this = ModelOutput::getATypeNode("mongodb", "Collection").getAMember().getACall() and + this = ModelOutput::getATypeNode("mongodb.Collection").getAMember().getACall() and this.getCalleeName().matches("insert%") } @@ -105,9 +105,7 @@ private module Mongoose { private class QueryCall extends DatabaseAccess, API::CallNode { QueryCall() { this = - ModelOutput::getATypeNode("mongoose", "Query") - .getMember(["exec", "then", "catch"]) - .getACall() + ModelOutput::getATypeNode("mongoose.Query").getMember(["exec", "then", "catch"]).getACall() } override DataFlow::Node getAQueryArgument() { result = this.getReceiver() } @@ -132,10 +130,10 @@ private module Mongoose { private class QueryWithCallback extends DatabaseAccess, API::CallNode { QueryWithCallback() { this = - ModelOutput::getATypeNode("mongoose", ["Document", "Model", "Query"]) + ModelOutput::getATypeNode(["mongoose.Document", "mongoose.Model", "mongoose.Query"]) .getAMember() .getACall() and - this.getReturn() = ModelOutput::getATypeNode("mongoose", "Query") and + this.getReturn() = ModelOutput::getATypeNode("mongoose.Query") and exists(this.getLastArgument().getABoundFunctionValue(_)) } @@ -152,7 +150,7 @@ private module Mongoose { QueryAwait() { astNode.getOperand().flow() = - ModelOutput::getATypeNode("mongoose", "Query").getAValueReachableFromSource() + ModelOutput::getATypeNode("mongoose.Query").getAValueReachableFromSource() } override DataFlow::Node getAQueryArgument() { result = astNode.getOperand().flow() } @@ -162,7 +160,7 @@ private module Mongoose { class Insertion extends DatabaseAccess, API::CallNode { Insertion() { - this = ModelOutput::getATypeNode("mongoose", "Model").getAMember().getACall() and + this = ModelOutput::getATypeNode("mongoose.Model").getAMember().getACall() and this.getCalleeName().matches("insert%") } @@ -180,9 +178,9 @@ private module MarsDB { override predicate row(string row) { row = [ - "mongoose;Query;marsdb;;Member[Collection].Instance", - "mongoose;Model;marsdb;;Member[Collection].Instance", - "mongoose;Query;mongoose;Query;Member[sortFunc].ReturnValue", + "mongoose.Query;marsdb;Member[Collection].Instance", + "mongoose.Model;marsdb;Member[Collection].Instance", + "mongoose.Query;mongoose.Query;Member[sortFunc].ReturnValue", ] } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/SQL.qll b/javascript/ql/lib/semmle/javascript/frameworks/SQL.qll index 8bbeb1cbf55..80694f0c723 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/SQL.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/SQL.qll @@ -357,7 +357,7 @@ private module Sequelize { // Note: the sinks are specified directly in the MaD model class SequelizeSource extends ModelInput::SourceModelCsv { override predicate row(string row) { - row = "sequelize;Sequelize;Member[query].ReturnValue.Awaited;database-access-result" + row = "sequelize.Sequelize;Member[query].ReturnValue.Awaited;database-access-result" } } } @@ -368,10 +368,10 @@ private module SpannerCsv { // package; type; path; kind row = [ - "@google-cloud/spanner;~SqlExecutorDirect;Argument[0];sql-injection", - "@google-cloud/spanner;~SqlExecutorDirect;Argument[0].Member[sql];sql-injection", - "@google-cloud/spanner;Transaction;Member[batchUpdate].Argument[0];sql-injection", - "@google-cloud/spanner;Transaction;Member[batchUpdate].Argument[0].ArrayElement.Member[sql];sql-injection", + "@google-cloud/spanner.~SqlExecutorDirect;Argument[0];sql-injection", + "@google-cloud/spanner.~SqlExecutorDirect;Argument[0].Member[sql];sql-injection", + "@google-cloud/spanner.Transaction;Member[batchUpdate].Argument[0];sql-injection", + "@google-cloud/spanner.Transaction;Member[batchUpdate].Argument[0].ArrayElement.Member[sql];sql-injection", ] } } @@ -380,10 +380,10 @@ private module SpannerCsv { override predicate row(string row) { row = [ - "@google-cloud/spanner;~SpannerObject;Member[executeSql].Argument[0..].Parameter[1];database-access-result", - "@google-cloud/spanner;~SpannerObject;Member[executeSql].ReturnValue.Awaited.Member[0];database-access-result", - "@google-cloud/spanner;~SpannerObject;Member[run].ReturnValue.Awaited;database-access-result", - "@google-cloud/spanner;~SpannerObject;Member[run].Argument[0..].Parameter[1];database-access-result", + "@google-cloud/spanner.~SpannerObject;Member[executeSql].Argument[0..].Parameter[1];database-access-result", + "@google-cloud/spanner.~SpannerObject;Member[executeSql].ReturnValue.Awaited.Member[0];database-access-result", + "@google-cloud/spanner.~SpannerObject;Member[run].ReturnValue.Awaited;database-access-result", + "@google-cloud/spanner.~SpannerObject;Member[run].Argument[0..].Parameter[1];database-access-result", ] } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll index 9b2428f3413..0e744ba801a 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll @@ -5,23 +5,20 @@ * * The CSV specification has the following columns: * - Sources: - * `package; type; path; kind` + * `type; path; kind` * - Sinks: - * `package; type; path; kind` + * `type; path; kind` * - Summaries: - * `package; type; path; input; output; kind` + * `type; path; input; output; kind` * - Types: - * `package1; type1; package2; type2; path` + * `type1; type2; path` * * The interpretation of a row is similar to API-graphs with a left-to-right * reading. - * 1. The `package` column selects a package name, as it would be referenced in the source code, - * such as an NPM package, PIP package, or Ruby gem. (See `ModelsAsData.qll` for language-specific details). - * It may also be a synthetic package used for a type definition (see type definitions below). - * 2. The `type` column selects all instances of a named type originating from that package, - * or the empty string if referring to the package itself. + * 1. The `type` column selects all instances of a named type. The syntax of this column is language-specific. + * The language defines some type names that the analysis knows how to identify without models. * It can also be a synthetic type name defined by a type definition (see type definitions below). - * 3. The `path` column is a `.`-separated list of "access path tokens" to resolve, starting at the node selected by `package` and `type`. + * 2. The `path` column is a `.`-separated list of "access path tokens" to resolve, starting at the node selected by `type`. * * Every language supports the following tokens: * - Argument[n]: the n-th argument to a call. May be a range of form `x..y` (inclusive) and/or a comma-separated list. @@ -42,10 +39,10 @@ * * For the time being, please consult `ApiGraphModelsSpecific.qll` to see which language-specific tokens are currently supported. * - * 4. The `input` and `output` columns specify how data enters and leaves the element selected by the - * first `(package, type, path)` tuple. Both strings are `.`-separated access paths + * 3. The `input` and `output` columns specify how data enters and leaves the element selected by the + * first `(type, path)` tuple. Both strings are `.`-separated access paths * of the same syntax as the `path` column. - * 5. The `kind` column is a tag that can be referenced from QL to determine to + * 4. The `kind` column is a tag that can be referenced from QL to determine to * which classes the interpreted elements should be added. For example, for * sources `"remote"` indicates a default remote flow source, and for summaries * `"taint"` indicates a default additional taint step and `"value"` indicates a @@ -53,17 +50,17 @@ * * ### Types * - * A type row of form `package1; type1; package2; type2; path` indicates that `package2; type2; path` - * should be seen as an instance of the type `package1; type1`. + * A type row of form `type1; type2; path` indicates that `type2; path` + * should be seen as an instance of the type `type1`. * - * A `(package,type)` pair may refer to a static type or a synthetic type name used internally in the model. + * A type may refer to a static type or a synthetic type name used internally in the model. * Synthetic type names can be used to reuse intermediate sub-paths, when there are multiple ways to access the same * element. - * See `ModelsAsData.qll` for the language-specific interpretation of packages and static type names. + * See `ModelsAsData.qll` for the language-specific interpretation of type names. * - * By convention, if one wants to avoid clashes with static types from the package, the type name - * should be prefixed with a tilde character (`~`). For example, `(foo, ~Bar)` can be used to indicate that - * the type is related to the `foo` package but is not intended to match a static type. + * By convention, if one wants to avoid clashes with static types, the type name + * should be prefixed with a tilde character (`~`). For example, `~Bar` can be used to indicate that + * the type is not intended to match a static type. */ private import ApiGraphModelsSpecific as Specific @@ -89,9 +86,9 @@ module ModelInput { * * A row of form * ``` - * package;type;path;kind + * type;path;kind * ``` - * indicates that the value at `(package, type, path)` should be seen as a flow + * indicates that the value at `(type, path)` should be seen as a flow * source of the given `kind`. * * The kind `remote` represents a general remote flow source. @@ -110,9 +107,9 @@ module ModelInput { * * A row of form * ``` - * package;type;path;kind + * type;path;kind * ``` - * indicates that the value at `(package, type, path)` should be seen as a sink + * indicates that the value at `(type, path)` should be seen as a sink * of the given `kind`. */ abstract predicate row(string row); @@ -129,9 +126,9 @@ module ModelInput { * * A row of form * ``` - * package;type;path;input;output;kind + * type;path;input;output;kind * ``` - * indicates that for each call to `(package, type, path)`, the value referred to by `input` + * indicates that for each call to `(type, path)`, the value referred to by `input` * can flow to the value referred to by `output`. * * `kind` should be either `value` or `taint`, for value-preserving or taint-preserving steps, @@ -151,9 +148,9 @@ module ModelInput { * * A row of form, * ``` - * package1;type1;package2;type2;path + * type1;type2;path * ``` - * indicates that `(package2, type2, path)` should be seen as an instance of `(package1, type1)`. + * indicates that `(type2, path)` should be seen as an instance of `type1`. */ abstract predicate row(string row); } @@ -163,28 +160,28 @@ module ModelInput { */ class TypeModel extends Unit { /** - * Gets a data-flow node that is a source of the type `package;type`. + * Gets a data-flow node that is a source of the given `type`. * * This must not depend on API graphs, but ensures that an API node is generated for * the source. */ - DataFlow::Node getASource(string package, string type) { none() } + DataFlow::Node getASource(string type) { none() } /** - * Gets a data-flow node that is a sink of the type `package;type`, + * Gets a data-flow node that is a sink of the given `type`, * usually because it is an argument passed to a parameter of that type. * * This must not depend on API graphs, but ensures that an API node is generated for * the sink. */ - DataFlow::Node getASink(string package, string type) { none() } + DataFlow::Node getASink(string type) { none() } /** - * Gets an API node that is a source or sink of the type `package;type`. + * Gets an API node that is a source or sink of the given `type`. * * Unlike `getASource` and `getASink`, this may depend on API graphs. */ - API::Node getAnApiNode(string package, string type) { none() } + API::Node getAnApiNode(string type) { none() } } /** @@ -209,7 +206,7 @@ private import ModelInput /** * An empty class, except in specific tests. * - * If this is non-empty, all models are parsed even if the package is not + * If this is non-empty, all models are parsed even if the type name is not * considered relevant for the current database. */ abstract class TestAllModels extends Unit { } @@ -232,53 +229,44 @@ private predicate typeModel(string row) { any(TypeModelCsv s).row(inversePad(row private predicate typeVariableModel(string row) { any(TypeVariableModelCsv s).row(inversePad(row)) } /** Holds if a source model exists for the given parameters. */ -predicate sourceModel(string package, string type, string path, string kind) { +predicate sourceModel(string type, string path, string kind) { exists(string row | sourceModel(row) and - row.splitAt(";", 0) = package and - row.splitAt(";", 1) = type and - row.splitAt(";", 2) = path and - row.splitAt(";", 3) = kind + row.splitAt(";", 0) = type and + row.splitAt(";", 1) = path and + row.splitAt(";", 2) = kind ) } /** Holds if a sink model exists for the given parameters. */ -private predicate sinkModel(string package, string type, string path, string kind) { +private predicate sinkModel(string type, string path, string kind) { exists(string row | sinkModel(row) and - row.splitAt(";", 0) = package and - row.splitAt(";", 1) = type and - row.splitAt(";", 2) = path and - row.splitAt(";", 3) = kind + row.splitAt(";", 0) = type and + row.splitAt(";", 1) = path and + row.splitAt(";", 2) = kind ) } /** Holds if a summary model `row` exists for the given parameters. */ -private predicate summaryModel( - string package, string type, string path, string input, string output, string kind -) { +private predicate summaryModel(string type, string path, string input, string output, string kind) { exists(string row | summaryModel(row) and - row.splitAt(";", 0) = package and - row.splitAt(";", 1) = type and - row.splitAt(";", 2) = path and - row.splitAt(";", 3) = input and - row.splitAt(";", 4) = output and - row.splitAt(";", 5) = kind + row.splitAt(";", 0) = type and + row.splitAt(";", 1) = path and + row.splitAt(";", 2) = input and + row.splitAt(";", 3) = output and + row.splitAt(";", 4) = kind ) } /** Holds if a type model exists for the given parameters. */ -private predicate typeModel( - string package1, string type1, string package2, string type2, string path -) { +private predicate typeModel(string type1, string type2, string path) { exists(string row | typeModel(row) and - row.splitAt(";", 0) = package1 and - row.splitAt(";", 1) = type1 and - row.splitAt(";", 2) = package2 and - row.splitAt(";", 3) = type2 and - row.splitAt(";", 4) = path + row.splitAt(";", 0) = type1 and + row.splitAt(";", 1) = type2 and + row.splitAt(";", 2) = path ) } @@ -292,61 +280,50 @@ private predicate typeVariableModel(string name, string path) { } /** - * Gets a package that should be seen as an alias for the given other `package`, - * or the `package` itself. + * Holds if CSV rows involving `type` might be relevant for the analysis of this database. */ -bindingset[package] -bindingset[result] -string getAPackageAlias(string package) { - typeModel(package, "", result, "", "") - or - result = package -} - -/** - * Holds if CSV rows involving `package` might be relevant for the analysis of this database. - */ -private predicate isRelevantPackage(string package) { +predicate isRelevantType(string type) { ( - sourceModel(package, _, _, _) or - sinkModel(package, _, _, _) or - summaryModel(package, _, _, _, _, _) or - typeModel(_, _, package, _, _) + sourceModel(type, _, _) or + sinkModel(type, _, _) or + summaryModel(type, _, _, _, _) or + typeModel(_, type, _) ) and ( - Specific::isPackageUsed(package) + Specific::isTypeUsed(type) or exists(TestAllModels t) ) or - exists(string other | - isRelevantPackage(other) and - typeModel(package, _, other, _, _) + exists(string other | isRelevantType(other) | + typeModel(type, other, _) + or + Specific::hasImplicitTypeModel(type, other) ) } /** - * Holds if `package,type,path` is used in some CSV row. + * Holds if `type,path` is used in some CSV row. */ pragma[nomagic] -predicate isRelevantFullPath(string package, string type, string path) { - isRelevantPackage(package) and +predicate isRelevantFullPath(string type, string path) { + isRelevantType(type) and ( - sourceModel(package, type, path, _) or - sinkModel(package, type, path, _) or - summaryModel(package, type, path, _, _, _) or - typeModel(_, _, package, type, path) + sourceModel(type, path, _) or + sinkModel(type, path, _) or + summaryModel(type, path, _, _, _) or + typeModel(_, type, path) ) } /** A string from a CSV row that should be parsed as an access path. */ private class AccessPathRange extends AccessPath::Range { AccessPathRange() { - isRelevantFullPath(_, _, this) + isRelevantFullPath(_, this) or - exists(string package | isRelevantPackage(package) | - summaryModel(package, _, _, this, _, _) or - summaryModel(package, _, _, _, this, _) + exists(string type | isRelevantType(type) | + summaryModel(type, _, this, _, _) or + summaryModel(type, _, _, this, _) ) or typeVariableModel(_, this) @@ -400,83 +377,73 @@ private predicate invocationMatchesCallSiteFilter(Specific::InvokeNode invoke, A } private class TypeModelUseEntry extends API::EntryPoint { - private string package; private string type; TypeModelUseEntry() { - exists(any(TypeModel tm).getASource(package, type)) and - this = "TypeModelUseEntry;" + package + ";" + type + exists(any(TypeModel tm).getASource(type)) and + this = "TypeModelUseEntry;" + type } - override DataFlow::LocalSourceNode getASource() { - result = any(TypeModel tm).getASource(package, type) - } + override DataFlow::LocalSourceNode getASource() { result = any(TypeModel tm).getASource(type) } - API::Node getNodeForType(string package_, string type_) { - package = package_ and type = type_ and result = this.getANode() - } + API::Node getNodeForType(string type_) { type = type_ and result = this.getANode() } } private class TypeModelDefEntry extends API::EntryPoint { - private string package; private string type; TypeModelDefEntry() { - exists(any(TypeModel tm).getASink(package, type)) and - this = "TypeModelDefEntry;" + package + ";" + type + exists(any(TypeModel tm).getASink(type)) and + this = "TypeModelDefEntry;" + type } - override DataFlow::Node getASink() { result = any(TypeModel tm).getASink(package, type) } + override DataFlow::Node getASink() { result = any(TypeModel tm).getASink(type) } - API::Node getNodeForType(string package_, string type_) { - package = package_ and type = type_ and result = this.getANode() - } + API::Node getNodeForType(string type_) { type = type_ and result = this.getANode() } } /** - * Gets an API node identified by the given `(package,type)` pair. + * Gets an API node identified by the given `type`. */ pragma[nomagic] -private API::Node getNodeFromType(string package, string type) { - exists(string package2, string type2, AccessPath path2 | - typeModel(package, type, package2, type2, path2) and - result = getNodeFromPath(package2, type2, path2) +private API::Node getNodeFromType(string type) { + exists(string type2, AccessPath path2 | + typeModel(type, type2, path2) and + result = getNodeFromPath(type2, path2) ) or - result = any(TypeModelUseEntry e).getNodeForType(package, type) + result = any(TypeModelUseEntry e).getNodeForType(type) or - result = any(TypeModelDefEntry e).getNodeForType(package, type) + result = any(TypeModelDefEntry e).getNodeForType(type) or - result = any(TypeModel t).getAnApiNode(package, type) + result = any(TypeModel t).getAnApiNode(type) or - result = Specific::getExtraNodeFromType(package, type) + result = Specific::getExtraNodeFromType(type) } /** - * Gets the API node identified by the first `n` tokens of `path` in the given `(package, type, path)` tuple. + * Gets the API node identified by the first `n` tokens of `path` in the given `(type, path)` tuple. */ pragma[nomagic] -private API::Node getNodeFromPath(string package, string type, AccessPath path, int n) { - isRelevantFullPath(package, type, path) and +private API::Node getNodeFromPath(string type, AccessPath path, int n) { + isRelevantFullPath(type, path) and ( n = 0 and - result = getNodeFromType(package, type) + result = getNodeFromType(type) or - result = Specific::getExtraNodeFromPath(package, type, path, n) + result = Specific::getExtraNodeFromPath(type, path, n) ) or - result = getSuccessorFromNode(getNodeFromPath(package, type, path, n - 1), path.getToken(n - 1)) + result = getSuccessorFromNode(getNodeFromPath(type, path, n - 1), path.getToken(n - 1)) or // Similar to the other recursive case, but where the path may have stepped through one or more call-site filters - result = - getSuccessorFromInvoke(getInvocationFromPath(package, type, path, n - 1), path.getToken(n - 1)) + result = getSuccessorFromInvoke(getInvocationFromPath(type, path, n - 1), path.getToken(n - 1)) or // Apply a subpath - result = - getNodeFromSubPath(getNodeFromPath(package, type, path, n - 1), getSubPathAt(path, n - 1)) + result = getNodeFromSubPath(getNodeFromPath(type, path, n - 1), getSubPathAt(path, n - 1)) or // Apply a type step - typeStep(getNodeFromPath(package, type, path, n), result) + typeStep(getNodeFromPath(type, path, n), result) } /** @@ -496,15 +463,15 @@ private AccessPath getSubPathAt(AccessPath path, int n) { pragma[nomagic] private API::Node getNodeFromSubPath(API::Node base, AccessPath subPath, int n) { exists(AccessPath path, int k | - base = [getNodeFromPath(_, _, path, k), getNodeFromSubPath(_, path, k)] and + base = [getNodeFromPath(_, path, k), getNodeFromSubPath(_, path, k)] and subPath = getSubPathAt(path, k) and result = base and n = 0 ) or - exists(string package, string type, AccessPath basePath | - typeStepModel(package, type, basePath, subPath) and - base = getNodeFromPath(package, type, basePath) and + exists(string type, AccessPath basePath | + typeStepModel(type, basePath, subPath) and + base = getNodeFromPath(type, basePath) and result = base and n = 0 ) @@ -543,42 +510,40 @@ private API::Node getNodeFromSubPath(API::Node base, AccessPath subPath) { result = getNodeFromSubPath(base, subPath, subPath.getNumToken()) } -/** Gets the node identified by the given `(package, type, path)` tuple. */ -private API::Node getNodeFromPath(string package, string type, AccessPath path) { - result = getNodeFromPath(package, type, path, path.getNumToken()) +/** Gets the node identified by the given `(type, path)` tuple. */ +private API::Node getNodeFromPath(string type, AccessPath path) { + result = getNodeFromPath(type, path, path.getNumToken()) } pragma[nomagic] -private predicate typeStepModel(string package, string type, AccessPath basePath, AccessPath output) { - summaryModel(package, type, basePath, "", output, "type") +private predicate typeStepModel(string type, AccessPath basePath, AccessPath output) { + summaryModel(type, basePath, "", output, "type") } pragma[nomagic] private predicate typeStep(API::Node pred, API::Node succ) { - exists(string package, string type, AccessPath basePath, AccessPath output | - typeStepModel(package, type, basePath, output) and - pred = getNodeFromPath(package, type, basePath) and + exists(string type, AccessPath basePath, AccessPath output | + typeStepModel(type, basePath, output) and + pred = getNodeFromPath(type, basePath) and succ = getNodeFromSubPath(pred, output) ) } /** - * Gets an invocation identified by the given `(package, type, path)` tuple. + * Gets an invocation identified by the given `(type, path)` tuple. * * Unlike `getNodeFromPath`, the `path` may end with one or more call-site filters. */ -private Specific::InvokeNode getInvocationFromPath( - string package, string type, AccessPath path, int n -) { - result = Specific::getAnInvocationOf(getNodeFromPath(package, type, path, n)) +private Specific::InvokeNode getInvocationFromPath(string type, AccessPath path, int n) { + result = Specific::getAnInvocationOf(getNodeFromPath(type, path, n)) or - result = getInvocationFromPath(package, type, path, n - 1) and + result = getInvocationFromPath(type, path, n - 1) and invocationMatchesCallSiteFilter(result, path.getToken(n - 1)) } -/** Gets an invocation identified by the given `(package, type, path)` tuple. */ -private Specific::InvokeNode getInvocationFromPath(string package, string type, AccessPath path) { - result = getInvocationFromPath(package, type, path, path.getNumToken()) +/** Gets an invocation identified by the given `(type, path)` tuple. */ +private Specific::InvokeNode getInvocationFromPath(string type, AccessPath path) { + result = getInvocationFromPath(type, path, path.getNumToken()) } /** @@ -631,9 +596,9 @@ module ModelOutput { */ cached API::Node getASourceNode(string kind) { - exists(string package, string type, string path | - sourceModel(package, type, path, kind) and - result = getNodeFromPath(package, type, path) + exists(string type, string path | + sourceModel(type, path, kind) and + result = getNodeFromPath(type, path) ) } @@ -642,9 +607,9 @@ module ModelOutput { */ cached API::Node getASinkNode(string kind) { - exists(string package, string type, string path | - sinkModel(package, type, path, kind) and - result = getNodeFromPath(package, type, path) + exists(string type, string path | + sinkModel(type, path, kind) and + result = getNodeFromPath(type, path) ) } @@ -653,32 +618,31 @@ module ModelOutput { */ cached predicate relevantSummaryModel( - string package, string type, string path, string input, string output, string kind + string type, string path, string input, string output, string kind ) { - isRelevantPackage(package) and - summaryModel(package, type, path, input, output, kind) + isRelevantType(type) and + summaryModel(type, path, input, output, kind) } /** - * Holds if a `baseNode` is an invocation identified by the `package,type,path` part of a summary row. + * Holds if a `baseNode` is an invocation identified by the `type,path` part of a summary row. */ cached - predicate resolvedSummaryBase( - string package, string type, string path, Specific::InvokeNode baseNode - ) { - summaryModel(package, type, path, _, _, _) and - baseNode = getInvocationFromPath(package, type, path) + predicate resolvedSummaryBase(string type, string path, Specific::InvokeNode baseNode) { + summaryModel(type, path, _, _, _) and + baseNode = getInvocationFromPath(type, path) } /** - * Holds if `node` is seen as an instance of `(package,type)` due to a type definition + * Holds if `node` is seen as an instance of `type` due to a type definition * contributed by a CSV model. */ cached - API::Node getATypeNode(string package, string type) { result = getNodeFromType(package, type) } + API::Node getATypeNode(string type) { result = getNodeFromType(type) } } import Cached + import Specific::ModelOutputSpecific /** * Gets an error message relating to an invalid CSV row in a model. @@ -686,13 +650,13 @@ module ModelOutput { string getAWarning() { // Check number of columns exists(string row, string kind, int expectedArity, int actualArity | - any(SourceModelCsv csv).row(row) and kind = "source" and expectedArity = 4 + any(SourceModelCsv csv).row(row) and kind = "source" and expectedArity = 3 or - any(SinkModelCsv csv).row(row) and kind = "sink" and expectedArity = 4 + any(SinkModelCsv csv).row(row) and kind = "sink" and expectedArity = 3 or - any(SummaryModelCsv csv).row(row) and kind = "summary" and expectedArity = 6 + any(SummaryModelCsv csv).row(row) and kind = "summary" and expectedArity = 5 or - any(TypeModelCsv csv).row(row) and kind = "type" and expectedArity = 5 + any(TypeModelCsv csv).row(row) and kind = "type" and expectedArity = 3 or any(TypeVariableModelCsv csv).row(row) and kind = "type-variable" and expectedArity = 2 | @@ -705,7 +669,7 @@ module ModelOutput { or // Check names and arguments of access path tokens exists(AccessPath path, AccessPathToken token | - (isRelevantFullPath(_, _, path) or typeVariableModel(_, path)) and + (isRelevantFullPath(_, path) or typeVariableModel(_, path)) and token = path.getToken(_) | not isValidTokenNameInIdentifyingAccessPath(token.getName()) and diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll index 097a46fd11a..73a2fd28d0c 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll @@ -31,6 +31,15 @@ import semmle.javascript.frameworks.data.internal.AccessPathSyntax as AccessPath import JS::DataFlow as DataFlow private import AccessPathSyntax +bindingset[rawType] +predicate parseTypeString(string rawType, string package, string qualifiedName) { + exists(string regexp | + regexp = "('[^']+'|[^.]+)(.*)" and + package = rawType.regexpCapture(regexp, 1).regexpReplaceAll("^'|'$", "") and + qualifiedName = rawType.regexpCapture(regexp, 2).regexpReplaceAll("^\\.", "") + ) +} + /** * Holds if models describing `package` may be relevant for the analysis of this database. */ @@ -42,10 +51,30 @@ predicate isPackageUsed(string package) { any(DataFlow::SourceNode sn).hasUnderlyingType(package, _) } +bindingset[type] +predicate isTypeUsed(string type) { + exists(string package | + parseTypeString(type, package, _) and + isPackageUsed(package) + ) +} + +/** + * Holds if `type` can be obtained from an instance of `otherType` due to + * language semantics modeled by `getExtraNodeFromType`. + */ +predicate hasImplicitTypeModel(string type, string otherType) { none() } + +pragma[nomagic] +private predicate parseRelevantTypeString(string rawType, string package, string qualifiedName) { + isRelevantFullPath(rawType, _) and + parseTypeString(rawType, package, qualifiedName) +} + /** Holds if `global` is a global variable referenced via a the `global` package in a CSV row. */ private predicate isRelevantGlobal(string global) { exists(AccessPath path, AccessPathToken token | - isRelevantFullPath("global", "", path) and + isRelevantFullPath("global", path) and token = path.getToken(0) and token.getName() = "Member" and global = token.getAnArgument() @@ -74,13 +103,12 @@ private API::Node getGlobalNode(string globalName) { result = any(GlobalApiEntryPoint e | e.getGlobal() = globalName).getANode() } -/** Gets a JavaScript-specific interpretation of the `(package, type, path)` tuple after resolving the first `n` access path tokens. */ -bindingset[package, type, path] -API::Node getExtraNodeFromPath(string package, string type, AccessPath path, int n) { +/** Gets a JavaScript-specific interpretation of the `(type, path)` tuple after resolving the first `n` access path tokens. */ +bindingset[type, path] +API::Node getExtraNodeFromPath(string type, AccessPath path, int n) { // Global variable accesses is via the 'global' package exists(AccessPathToken token | - package = getAPackageAlias("global") and - type = "" and + type = "global" and token = path.getToken(0) and token.getName() = "Member" and result = getGlobalNode(token.getAnArgument()) and @@ -89,12 +117,16 @@ API::Node getExtraNodeFromPath(string package, string type, AccessPath path, int } /** Gets a JavaScript-specific interpretation of the `(package, type)` tuple. */ -API::Node getExtraNodeFromType(string package, string type) { - type = "" and - result = API::moduleImport(package) - or - // Access instance of a type based on type annotations - result = API::Internal::getANodeOfTypeRaw(getAPackageAlias(package), type) +API::Node getExtraNodeFromType(string type) { + exists(string package, string qualifiedName | + parseRelevantTypeString(type, package, qualifiedName) + | + qualifiedName = "" and + result = API::moduleImport(package) + or + // Access instance of a type based on type annotations + result = API::Internal::getANodeOfTypeRaw(package, qualifiedName) + ) } /** @@ -184,9 +216,9 @@ predicate invocationMatchesExtraCallSiteFilter(API::InvokeNode invoke, AccessPat */ pragma[nomagic] private predicate relevantInputOutputPath(API::InvokeNode base, AccessPath inputOrOutput) { - exists(string package, string type, string input, string output, string path | - ModelOutput::relevantSummaryModel(package, type, path, input, output, _) and - ModelOutput::resolvedSummaryBase(package, type, path, base) and + exists(string type, string input, string output, string path | + ModelOutput::relevantSummaryModel(type, path, input, output, _) and + ModelOutput::resolvedSummaryBase(type, path, base) and inputOrOutput = [input, output] ) } @@ -216,12 +248,9 @@ private API::Node getNodeFromInputOutputPath(API::InvokeNode baseNode, AccessPat * Holds if a CSV summary contributed the step `pred -> succ` of the given `kind`. */ predicate summaryStep(API::Node pred, API::Node succ, string kind) { - exists( - string package, string type, string path, API::InvokeNode base, AccessPath input, - AccessPath output - | - ModelOutput::relevantSummaryModel(package, type, path, input, output, kind) and - ModelOutput::resolvedSummaryBase(package, type, path, base) and + exists(string type, string path, API::InvokeNode base, AccessPath input, AccessPath output | + ModelOutput::relevantSummaryModel(type, path, input, output, kind) and + ModelOutput::resolvedSummaryBase(type, path, base) and pred = getNodeFromInputOutputPath(base, input) and succ = getNodeFromInputOutputPath(base, output) ) @@ -270,3 +299,17 @@ predicate isExtraValidTokenArgumentInIdentifyingAccessPath(string name, string a exists(argument.indexOf("=")) and exists(AccessPath::parseIntWithArity(argument.splitAt("=", 0), 10)) } + +module ModelOutputSpecific { + /** + * Gets a node that should be seen as an instance of `package,type` due to a type definition + * contributed by a CSV model. + */ + cached + API::Node getATypeNode(string package, string qualifiedName) { + exists(string rawType | + result = ModelOutput::getATypeNode(rawType) and + parseTypeString(rawType, package, qualifiedName) + ) + } +} diff --git a/javascript/ql/lib/semmle/javascript/frameworks/minimongo/Model.qll b/javascript/ql/lib/semmle/javascript/frameworks/minimongo/Model.qll index d0ba6c3ed23..56b1470166b 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/minimongo/Model.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/minimongo/Model.qll @@ -6,81 +6,81 @@ private class Types extends ModelInput::TypeModelCsv { override predicate row(string row) { row = [ - "minimongo/IndexedDb;IndexedDbCollection;minimongo/IndexedDb;IndexedDbCollectionStatic;Instance", // - "minimongo/IndexedDb;IndexedDbCollection;minimongo/lib/IndexedDb;default;Member[collections].AnyMember", // - "minimongo/MemoryDb;Collection;minimongo/MemoryDb;CollectionStatic;Instance", // - "minimongo/MemoryDb;Collection;minimongo/lib/MemoryDb;default;Member[collections].AnyMember", // - "minimongo/RemoteDb;Collection;minimongo/RemoteDb;CollectionStatic;Instance", // - "minimongo/RemoteDb;Collection;minimongo/lib/RemoteDb;default;Member[collections].AnyMember", // - "minimongo/ReplicatingDb;Collection;minimongo/ReplicatingDb;CollectionStatic;Instance", // - "minimongo/ReplicatingDb;Collection;minimongo/lib/ReplicatingDb;default;Member[collections].AnyMember", // - "minimongo/lib/HybridDb;default;minimongo/lib/HybridDb;defaultStatic;Instance", // - "minimongo/lib/HybridDb;defaultStatic;minimongo/lib/HybridDb;;Member[default]", // - "minimongo/lib/HybridDb;defaultStatic;minimongo;;Member[HybridDb]", // - "minimongo/lib/IndexedDb;default;minimongo/lib/IndexedDb;defaultStatic;Instance", // - "minimongo/lib/IndexedDb;default;minimongo;;Member[utils].Member[autoselectLocalDb].ReturnValue", // - "minimongo/lib/IndexedDb;defaultStatic;minimongo/lib/IndexedDb;;Member[default]", // - "minimongo/lib/IndexedDb;defaultStatic;minimongo;;Member[IndexedDb]", // - "minimongo/lib/LocalStorageDb;default;minimongo/lib/LocalStorageDb;defaultStatic;Instance", // - "minimongo/lib/LocalStorageDb;default;minimongo;;Member[utils].Member[autoselectLocalDb].ReturnValue", // - "minimongo/lib/LocalStorageDb;defaultStatic;minimongo/lib/LocalStorageDb;;Member[default]", // - "minimongo/lib/LocalStorageDb;defaultStatic;minimongo;;Member[LocalStorageDb]", // - "minimongo/lib/MemoryDb;default;minimongo/lib/MemoryDb;defaultStatic;Instance", // - "minimongo/lib/MemoryDb;default;minimongo;;Member[utils].Member[autoselectLocalDb].ReturnValue", // - "minimongo/lib/MemoryDb;defaultStatic;minimongo/lib/MemoryDb;;Member[default]", // - "minimongo/lib/MemoryDb;defaultStatic;minimongo;;Member[MemoryDb]", // - "minimongo/lib/RemoteDb;default;minimongo/lib/RemoteDb;defaultStatic;Instance", // - "minimongo/lib/RemoteDb;defaultStatic;minimongo/lib/RemoteDb;;Member[default]", // - "minimongo/lib/RemoteDb;defaultStatic;minimongo;;Member[RemoteDb]", // - "minimongo/lib/ReplicatingDb;default;minimongo/lib/ReplicatingDb;defaultStatic;Instance", // - "minimongo/lib/ReplicatingDb;defaultStatic;minimongo/lib/ReplicatingDb;;Member[default]", // - "minimongo/lib/ReplicatingDb;defaultStatic;minimongo;;Member[ReplicatingDb]", // - "minimongo/lib/WebSQLDb;default;minimongo/lib/WebSQLDb;defaultStatic;Instance", // - "minimongo/lib/WebSQLDb;default;minimongo;;Member[utils].Member[autoselectLocalDb].ReturnValue", // - "minimongo/lib/WebSQLDb;defaultStatic;minimongo/lib/WebSQLDb;;Member[default]", // - "minimongo/lib/WebSQLDb;defaultStatic;minimongo;;Member[WebSQLDb]", // - "minimongo;HybridCollection;minimongo/lib/HybridDb;HybridCollection;", // - "minimongo;HybridCollection;minimongo/lib/HybridDb;default;Member[collections].AnyMember", // - "minimongo;HybridCollection;minimongo;HybridCollectionStatic;Instance", // - "minimongo;HybridCollectionStatic;minimongo/lib/HybridDb;;Member[HybridCollection]", // - "minimongo;HybridCollectionStatic;minimongo/lib/HybridDb;HybridCollectionStatic;", // - "minimongo;HybridCollectionStatic;minimongo;;Member[HybridCollection]", // - "minimongo;MinimongoBaseCollection;minimongo/RemoteDb;Collection;", // - "minimongo;MinimongoBaseCollection;minimongo/lib/types;MinimongoBaseCollection;", // - "minimongo;MinimongoBaseCollection;minimongo;HybridCollection;", // - "minimongo;MinimongoBaseCollection;minimongo;MinimongoCollection;", // - "minimongo;MinimongoBaseCollection;minimongo;MinimongoDb;AnyMember", // - "minimongo;MinimongoBaseCollection;minimongo;MinimongoLocalCollection;", // - "minimongo;MinimongoCollection;minimongo/lib/LocalStorageDb;default;Member[collections].AnyMember", // - "minimongo;MinimongoCollection;minimongo/lib/WebSQLDb;default;Member[collections].AnyMember", // - "minimongo;MinimongoCollection;minimongo/lib/types;MinimongoCollection;", // - "minimongo;MinimongoCollection;minimongo;HybridCollection;Member[remoteCol]", // - "minimongo;MinimongoCollection;minimongo;MinimongoDb;Member[collections].AnyMember", // - "minimongo;MinimongoDb;minimongo/lib/HybridDb;default;", // - "minimongo;MinimongoDb;minimongo/lib/HybridDb;default;Member[remoteDb]", // - "minimongo;MinimongoDb;minimongo/lib/LocalStorageDb;default;", // - "minimongo;MinimongoDb;minimongo/lib/MemoryDb;default;", // - "minimongo;MinimongoDb;minimongo/lib/RemoteDb;default;", // - "minimongo;MinimongoDb;minimongo/lib/ReplicatingDb;default;Member[masterDb,replicaDb]", // - "minimongo;MinimongoDb;minimongo/lib/WebSQLDb;default;", // - "minimongo;MinimongoDb;minimongo/lib/types;MinimongoDb;", // - "minimongo;MinimongoDb;minimongo;MinimongoDb;Member[remoteDb]", // - "minimongo;MinimongoDb;minimongo;MinimongoLocalDb;", // - "minimongo;MinimongoLocalCollection;minimongo/IndexedDb;IndexedDbCollection;", // - "minimongo;MinimongoLocalCollection;minimongo/MemoryDb;Collection;", // - "minimongo;MinimongoLocalCollection;minimongo/ReplicatingDb;Collection;", // - "minimongo;MinimongoLocalCollection;minimongo/ReplicatingDb;Collection;Member[masterCol,replicaCol]", // - "minimongo;MinimongoLocalCollection;minimongo/lib/types;MinimongoLocalCollection;", // - "minimongo;MinimongoLocalCollection;minimongo;HybridCollection;Member[localCol]", // - "minimongo;MinimongoLocalCollection;minimongo;MinimongoCollection;", // - "minimongo;MinimongoLocalCollection;minimongo;MinimongoLocalDb;Member[addCollection].Argument[2].Argument[0]", // - "minimongo;MinimongoLocalCollection;minimongo;MinimongoLocalDb;Member[collections].AnyMember", // - "minimongo;MinimongoLocalDb;minimongo/lib/HybridDb;default;Member[localDb]", // - "minimongo;MinimongoLocalDb;minimongo/lib/IndexedDb;default;", // - "minimongo;MinimongoLocalDb;minimongo/lib/ReplicatingDb;default;", // - "minimongo;MinimongoLocalDb;minimongo/lib/types;MinimongoLocalDb;", // - "minimongo;MinimongoLocalDb;minimongo;MinimongoDb;Member[localDb]", // - "mongodb;Collection;minimongo;MinimongoBaseCollection;", // + "minimongo.HybridCollection;minimongo.HybridCollectionStatic;Instance", // + "minimongo.HybridCollection;minimongo/lib/HybridDb.HybridCollection;", // + "minimongo.HybridCollection;minimongo/lib/HybridDb.default;Member[collections].AnyMember", // + "minimongo.HybridCollectionStatic;minimongo/lib/HybridDb.HybridCollectionStatic;", // + "minimongo.HybridCollectionStatic;minimongo/lib/HybridDb;Member[HybridCollection]", // + "minimongo.HybridCollectionStatic;minimongo;Member[HybridCollection]", // + "minimongo.MinimongoBaseCollection;minimongo.HybridCollection;", // + "minimongo.MinimongoBaseCollection;minimongo.MinimongoCollection;", // + "minimongo.MinimongoBaseCollection;minimongo.MinimongoDb;AnyMember", // + "minimongo.MinimongoBaseCollection;minimongo.MinimongoLocalCollection;", // + "minimongo.MinimongoBaseCollection;minimongo/RemoteDb.Collection;", // + "minimongo.MinimongoBaseCollection;minimongo/lib/types.MinimongoBaseCollection;", // + "minimongo.MinimongoCollection;minimongo.HybridCollection;Member[remoteCol]", // + "minimongo.MinimongoCollection;minimongo.MinimongoDb;Member[collections].AnyMember", // + "minimongo.MinimongoCollection;minimongo/lib/LocalStorageDb.default;Member[collections].AnyMember", // + "minimongo.MinimongoCollection;minimongo/lib/WebSQLDb.default;Member[collections].AnyMember", // + "minimongo.MinimongoCollection;minimongo/lib/types.MinimongoCollection;", // + "minimongo.MinimongoDb;minimongo.MinimongoDb;Member[remoteDb]", // + "minimongo.MinimongoDb;minimongo.MinimongoLocalDb;", // + "minimongo.MinimongoDb;minimongo/lib/HybridDb.default;", // + "minimongo.MinimongoDb;minimongo/lib/HybridDb.default;Member[remoteDb]", // + "minimongo.MinimongoDb;minimongo/lib/LocalStorageDb.default;", // + "minimongo.MinimongoDb;minimongo/lib/MemoryDb.default;", // + "minimongo.MinimongoDb;minimongo/lib/RemoteDb.default;", // + "minimongo.MinimongoDb;minimongo/lib/ReplicatingDb.default;Member[masterDb,replicaDb]", // + "minimongo.MinimongoDb;minimongo/lib/WebSQLDb.default;", // + "minimongo.MinimongoDb;minimongo/lib/types.MinimongoDb;", // + "minimongo.MinimongoLocalCollection;minimongo.HybridCollection;Member[localCol]", // + "minimongo.MinimongoLocalCollection;minimongo.MinimongoCollection;", // + "minimongo.MinimongoLocalCollection;minimongo.MinimongoLocalDb;Member[addCollection].Argument[2].Argument[0]", // + "minimongo.MinimongoLocalCollection;minimongo.MinimongoLocalDb;Member[collections].AnyMember", // + "minimongo.MinimongoLocalCollection;minimongo/IndexedDb.IndexedDbCollection;", // + "minimongo.MinimongoLocalCollection;minimongo/MemoryDb.Collection;", // + "minimongo.MinimongoLocalCollection;minimongo/ReplicatingDb.Collection;", // + "minimongo.MinimongoLocalCollection;minimongo/ReplicatingDb.Collection;Member[masterCol,replicaCol]", // + "minimongo.MinimongoLocalCollection;minimongo/lib/types.MinimongoLocalCollection;", // + "minimongo.MinimongoLocalDb;minimongo.MinimongoDb;Member[localDb]", // + "minimongo.MinimongoLocalDb;minimongo/lib/HybridDb.default;Member[localDb]", // + "minimongo.MinimongoLocalDb;minimongo/lib/IndexedDb.default;", // + "minimongo.MinimongoLocalDb;minimongo/lib/ReplicatingDb.default;", // + "minimongo.MinimongoLocalDb;minimongo/lib/types.MinimongoLocalDb;", // + "minimongo/IndexedDb.IndexedDbCollection;minimongo/IndexedDb.IndexedDbCollectionStatic;Instance", // + "minimongo/IndexedDb.IndexedDbCollection;minimongo/lib/IndexedDb.default;Member[collections].AnyMember", // + "minimongo/MemoryDb.Collection;minimongo/MemoryDb.CollectionStatic;Instance", // + "minimongo/MemoryDb.Collection;minimongo/lib/MemoryDb.default;Member[collections].AnyMember", // + "minimongo/RemoteDb.Collection;minimongo/RemoteDb.CollectionStatic;Instance", // + "minimongo/RemoteDb.Collection;minimongo/lib/RemoteDb.default;Member[collections].AnyMember", // + "minimongo/ReplicatingDb.Collection;minimongo/ReplicatingDb.CollectionStatic;Instance", // + "minimongo/ReplicatingDb.Collection;minimongo/lib/ReplicatingDb.default;Member[collections].AnyMember", // + "minimongo/lib/HybridDb.default;minimongo/lib/HybridDb.defaultStatic;Instance", // + "minimongo/lib/HybridDb.defaultStatic;minimongo/lib/HybridDb;Member[default]", // + "minimongo/lib/HybridDb.defaultStatic;minimongo;Member[HybridDb]", // + "minimongo/lib/IndexedDb.default;minimongo/lib/IndexedDb.defaultStatic;Instance", // + "minimongo/lib/IndexedDb.default;minimongo;Member[utils].Member[autoselectLocalDb].ReturnValue", // + "minimongo/lib/IndexedDb.defaultStatic;minimongo/lib/IndexedDb;Member[default]", // + "minimongo/lib/IndexedDb.defaultStatic;minimongo;Member[IndexedDb]", // + "minimongo/lib/LocalStorageDb.default;minimongo/lib/LocalStorageDb.defaultStatic;Instance", // + "minimongo/lib/LocalStorageDb.default;minimongo;Member[utils].Member[autoselectLocalDb].ReturnValue", // + "minimongo/lib/LocalStorageDb.defaultStatic;minimongo/lib/LocalStorageDb;Member[default]", // + "minimongo/lib/LocalStorageDb.defaultStatic;minimongo;Member[LocalStorageDb]", // + "minimongo/lib/MemoryDb.default;minimongo/lib/MemoryDb.defaultStatic;Instance", // + "minimongo/lib/MemoryDb.default;minimongo;Member[utils].Member[autoselectLocalDb].ReturnValue", // + "minimongo/lib/MemoryDb.defaultStatic;minimongo/lib/MemoryDb;Member[default]", // + "minimongo/lib/MemoryDb.defaultStatic;minimongo;Member[MemoryDb]", // + "minimongo/lib/RemoteDb.default;minimongo/lib/RemoteDb.defaultStatic;Instance", // + "minimongo/lib/RemoteDb.defaultStatic;minimongo/lib/RemoteDb;Member[default]", // + "minimongo/lib/RemoteDb.defaultStatic;minimongo;Member[RemoteDb]", // + "minimongo/lib/ReplicatingDb.default;minimongo/lib/ReplicatingDb.defaultStatic;Instance", // + "minimongo/lib/ReplicatingDb.defaultStatic;minimongo/lib/ReplicatingDb;Member[default]", // + "minimongo/lib/ReplicatingDb.defaultStatic;minimongo;Member[ReplicatingDb]", // + "minimongo/lib/WebSQLDb.default;minimongo/lib/WebSQLDb.defaultStatic;Instance", // + "minimongo/lib/WebSQLDb.default;minimongo;Member[utils].Member[autoselectLocalDb].ReturnValue", // + "minimongo/lib/WebSQLDb.defaultStatic;minimongo/lib/WebSQLDb;Member[default]", // + "minimongo/lib/WebSQLDb.defaultStatic;minimongo;Member[WebSQLDb]", // + "mongodb.Collection;minimongo.MinimongoBaseCollection;", // ] } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/minimongo/model.json b/javascript/ql/lib/semmle/javascript/frameworks/minimongo/model.json index 9911cd9b3c8..2a254ea3a69 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/minimongo/model.json +++ b/javascript/ql/lib/semmle/javascript/frameworks/minimongo/model.json @@ -6,87 +6,87 @@ "language": "javascript", "model": { "typeDefinitions": [ - "mongodb;Collection;minimongo;MinimongoBaseCollection;", - "minimongo;MinimongoBaseCollection;minimongo;MinimongoDb;AnyMember" + "mongodb.Collection;minimongo.MinimongoBaseCollection;", + "minimongo.MinimongoBaseCollection;minimongo.MinimongoDb;AnyMember" ], "sinks": [] }, "generatedModel": { "//": "Autogenerated section. Manual edits in here will be lost.", "typeDefinitions": [ - "minimongo/IndexedDb;IndexedDbCollection;minimongo/IndexedDb;IndexedDbCollectionStatic;Instance", - "minimongo/IndexedDb;IndexedDbCollection;minimongo/lib/IndexedDb;default;Member[collections].AnyMember", - "minimongo/MemoryDb;Collection;minimongo/MemoryDb;CollectionStatic;Instance", - "minimongo/MemoryDb;Collection;minimongo/lib/MemoryDb;default;Member[collections].AnyMember", - "minimongo/RemoteDb;Collection;minimongo/RemoteDb;CollectionStatic;Instance", - "minimongo/RemoteDb;Collection;minimongo/lib/RemoteDb;default;Member[collections].AnyMember", - "minimongo/ReplicatingDb;Collection;minimongo/ReplicatingDb;CollectionStatic;Instance", - "minimongo/ReplicatingDb;Collection;minimongo/lib/ReplicatingDb;default;Member[collections].AnyMember", - "minimongo/lib/HybridDb;default;minimongo/lib/HybridDb;defaultStatic;Instance", - "minimongo/lib/HybridDb;defaultStatic;minimongo/lib/HybridDb;;Member[default]", - "minimongo/lib/HybridDb;defaultStatic;minimongo;;Member[HybridDb]", - "minimongo/lib/IndexedDb;default;minimongo/lib/IndexedDb;defaultStatic;Instance", - "minimongo/lib/IndexedDb;default;minimongo;;Member[utils].Member[autoselectLocalDb].ReturnValue", - "minimongo/lib/IndexedDb;defaultStatic;minimongo/lib/IndexedDb;;Member[default]", - "minimongo/lib/IndexedDb;defaultStatic;minimongo;;Member[IndexedDb]", - "minimongo/lib/LocalStorageDb;default;minimongo/lib/LocalStorageDb;defaultStatic;Instance", - "minimongo/lib/LocalStorageDb;default;minimongo;;Member[utils].Member[autoselectLocalDb].ReturnValue", - "minimongo/lib/LocalStorageDb;defaultStatic;minimongo/lib/LocalStorageDb;;Member[default]", - "minimongo/lib/LocalStorageDb;defaultStatic;minimongo;;Member[LocalStorageDb]", - "minimongo/lib/MemoryDb;default;minimongo/lib/MemoryDb;defaultStatic;Instance", - "minimongo/lib/MemoryDb;default;minimongo;;Member[utils].Member[autoselectLocalDb].ReturnValue", - "minimongo/lib/MemoryDb;defaultStatic;minimongo/lib/MemoryDb;;Member[default]", - "minimongo/lib/MemoryDb;defaultStatic;minimongo;;Member[MemoryDb]", - "minimongo/lib/RemoteDb;default;minimongo/lib/RemoteDb;defaultStatic;Instance", - "minimongo/lib/RemoteDb;defaultStatic;minimongo/lib/RemoteDb;;Member[default]", - "minimongo/lib/RemoteDb;defaultStatic;minimongo;;Member[RemoteDb]", - "minimongo/lib/ReplicatingDb;default;minimongo/lib/ReplicatingDb;defaultStatic;Instance", - "minimongo/lib/ReplicatingDb;defaultStatic;minimongo/lib/ReplicatingDb;;Member[default]", - "minimongo/lib/ReplicatingDb;defaultStatic;minimongo;;Member[ReplicatingDb]", - "minimongo/lib/WebSQLDb;default;minimongo/lib/WebSQLDb;defaultStatic;Instance", - "minimongo/lib/WebSQLDb;default;minimongo;;Member[utils].Member[autoselectLocalDb].ReturnValue", - "minimongo/lib/WebSQLDb;defaultStatic;minimongo/lib/WebSQLDb;;Member[default]", - "minimongo/lib/WebSQLDb;defaultStatic;minimongo;;Member[WebSQLDb]", - "minimongo;HybridCollection;minimongo/lib/HybridDb;HybridCollection;", - "minimongo;HybridCollection;minimongo/lib/HybridDb;default;Member[collections].AnyMember", - "minimongo;HybridCollection;minimongo;HybridCollectionStatic;Instance", - "minimongo;HybridCollectionStatic;minimongo/lib/HybridDb;;Member[HybridCollection]", - "minimongo;HybridCollectionStatic;minimongo/lib/HybridDb;HybridCollectionStatic;", - "minimongo;HybridCollectionStatic;minimongo;;Member[HybridCollection]", - "minimongo;MinimongoBaseCollection;minimongo/RemoteDb;Collection;", - "minimongo;MinimongoBaseCollection;minimongo/lib/types;MinimongoBaseCollection;", - "minimongo;MinimongoBaseCollection;minimongo;HybridCollection;", - "minimongo;MinimongoBaseCollection;minimongo;MinimongoCollection;", - "minimongo;MinimongoBaseCollection;minimongo;MinimongoLocalCollection;", - "minimongo;MinimongoCollection;minimongo/lib/LocalStorageDb;default;Member[collections].AnyMember", - "minimongo;MinimongoCollection;minimongo/lib/WebSQLDb;default;Member[collections].AnyMember", - "minimongo;MinimongoCollection;minimongo/lib/types;MinimongoCollection;", - "minimongo;MinimongoCollection;minimongo;HybridCollection;Member[remoteCol]", - "minimongo;MinimongoCollection;minimongo;MinimongoDb;Member[collections].AnyMember", - "minimongo;MinimongoDb;minimongo/lib/HybridDb;default;", - "minimongo;MinimongoDb;minimongo/lib/HybridDb;default;Member[remoteDb]", - "minimongo;MinimongoDb;minimongo/lib/LocalStorageDb;default;", - "minimongo;MinimongoDb;minimongo/lib/MemoryDb;default;", - "minimongo;MinimongoDb;minimongo/lib/RemoteDb;default;", - "minimongo;MinimongoDb;minimongo/lib/ReplicatingDb;default;Member[masterDb,replicaDb]", - "minimongo;MinimongoDb;minimongo/lib/WebSQLDb;default;", - "minimongo;MinimongoDb;minimongo/lib/types;MinimongoDb;", - "minimongo;MinimongoDb;minimongo;MinimongoDb;Member[remoteDb]", - "minimongo;MinimongoDb;minimongo;MinimongoLocalDb;", - "minimongo;MinimongoLocalCollection;minimongo/IndexedDb;IndexedDbCollection;", - "minimongo;MinimongoLocalCollection;minimongo/MemoryDb;Collection;", - "minimongo;MinimongoLocalCollection;minimongo/ReplicatingDb;Collection;", - "minimongo;MinimongoLocalCollection;minimongo/ReplicatingDb;Collection;Member[masterCol,replicaCol]", - "minimongo;MinimongoLocalCollection;minimongo/lib/types;MinimongoLocalCollection;", - "minimongo;MinimongoLocalCollection;minimongo;HybridCollection;Member[localCol]", - "minimongo;MinimongoLocalCollection;minimongo;MinimongoCollection;", - "minimongo;MinimongoLocalCollection;minimongo;MinimongoLocalDb;Member[addCollection].Argument[2].Argument[0]", - "minimongo;MinimongoLocalCollection;minimongo;MinimongoLocalDb;Member[collections].AnyMember", - "minimongo;MinimongoLocalDb;minimongo/lib/HybridDb;default;Member[localDb]", - "minimongo;MinimongoLocalDb;minimongo/lib/IndexedDb;default;", - "minimongo;MinimongoLocalDb;minimongo/lib/ReplicatingDb;default;", - "minimongo;MinimongoLocalDb;minimongo/lib/types;MinimongoLocalDb;", - "minimongo;MinimongoLocalDb;minimongo;MinimongoDb;Member[localDb]" + "minimongo.HybridCollection;minimongo.HybridCollectionStatic;Instance", + "minimongo.HybridCollection;minimongo/lib/HybridDb.HybridCollection;", + "minimongo.HybridCollection;minimongo/lib/HybridDb.default;Member[collections].AnyMember", + "minimongo.HybridCollectionStatic;minimongo/lib/HybridDb.HybridCollectionStatic;", + "minimongo.HybridCollectionStatic;minimongo/lib/HybridDb;Member[HybridCollection]", + "minimongo.HybridCollectionStatic;minimongo;Member[HybridCollection]", + "minimongo.MinimongoBaseCollection;minimongo.HybridCollection;", + "minimongo.MinimongoBaseCollection;minimongo.MinimongoCollection;", + "minimongo.MinimongoBaseCollection;minimongo.MinimongoLocalCollection;", + "minimongo.MinimongoBaseCollection;minimongo/RemoteDb.Collection;", + "minimongo.MinimongoBaseCollection;minimongo/lib/types.MinimongoBaseCollection;", + "minimongo.MinimongoCollection;minimongo.HybridCollection;Member[remoteCol]", + "minimongo.MinimongoCollection;minimongo.MinimongoDb;Member[collections].AnyMember", + "minimongo.MinimongoCollection;minimongo/lib/LocalStorageDb.default;Member[collections].AnyMember", + "minimongo.MinimongoCollection;minimongo/lib/WebSQLDb.default;Member[collections].AnyMember", + "minimongo.MinimongoCollection;minimongo/lib/types.MinimongoCollection;", + "minimongo.MinimongoDb;minimongo.MinimongoDb;Member[remoteDb]", + "minimongo.MinimongoDb;minimongo.MinimongoLocalDb;", + "minimongo.MinimongoDb;minimongo/lib/HybridDb.default;", + "minimongo.MinimongoDb;minimongo/lib/HybridDb.default;Member[remoteDb]", + "minimongo.MinimongoDb;minimongo/lib/LocalStorageDb.default;", + "minimongo.MinimongoDb;minimongo/lib/MemoryDb.default;", + "minimongo.MinimongoDb;minimongo/lib/RemoteDb.default;", + "minimongo.MinimongoDb;minimongo/lib/ReplicatingDb.default;Member[masterDb,replicaDb]", + "minimongo.MinimongoDb;minimongo/lib/WebSQLDb.default;", + "minimongo.MinimongoDb;minimongo/lib/types.MinimongoDb;", + "minimongo.MinimongoLocalCollection;minimongo.HybridCollection;Member[localCol]", + "minimongo.MinimongoLocalCollection;minimongo.MinimongoCollection;", + "minimongo.MinimongoLocalCollection;minimongo.MinimongoLocalDb;Member[addCollection].Argument[2].Argument[0]", + "minimongo.MinimongoLocalCollection;minimongo.MinimongoLocalDb;Member[collections].AnyMember", + "minimongo.MinimongoLocalCollection;minimongo/IndexedDb.IndexedDbCollection;", + "minimongo.MinimongoLocalCollection;minimongo/MemoryDb.Collection;", + "minimongo.MinimongoLocalCollection;minimongo/ReplicatingDb.Collection;", + "minimongo.MinimongoLocalCollection;minimongo/ReplicatingDb.Collection;Member[masterCol,replicaCol]", + "minimongo.MinimongoLocalCollection;minimongo/lib/types.MinimongoLocalCollection;", + "minimongo.MinimongoLocalDb;minimongo.MinimongoDb;Member[localDb]", + "minimongo.MinimongoLocalDb;minimongo/lib/HybridDb.default;Member[localDb]", + "minimongo.MinimongoLocalDb;minimongo/lib/IndexedDb.default;", + "minimongo.MinimongoLocalDb;minimongo/lib/ReplicatingDb.default;", + "minimongo.MinimongoLocalDb;minimongo/lib/types.MinimongoLocalDb;", + "minimongo/IndexedDb.IndexedDbCollection;minimongo/IndexedDb.IndexedDbCollectionStatic;Instance", + "minimongo/IndexedDb.IndexedDbCollection;minimongo/lib/IndexedDb.default;Member[collections].AnyMember", + "minimongo/MemoryDb.Collection;minimongo/MemoryDb.CollectionStatic;Instance", + "minimongo/MemoryDb.Collection;minimongo/lib/MemoryDb.default;Member[collections].AnyMember", + "minimongo/RemoteDb.Collection;minimongo/RemoteDb.CollectionStatic;Instance", + "minimongo/RemoteDb.Collection;minimongo/lib/RemoteDb.default;Member[collections].AnyMember", + "minimongo/ReplicatingDb.Collection;minimongo/ReplicatingDb.CollectionStatic;Instance", + "minimongo/ReplicatingDb.Collection;minimongo/lib/ReplicatingDb.default;Member[collections].AnyMember", + "minimongo/lib/HybridDb.default;minimongo/lib/HybridDb.defaultStatic;Instance", + "minimongo/lib/HybridDb.defaultStatic;minimongo/lib/HybridDb;Member[default]", + "minimongo/lib/HybridDb.defaultStatic;minimongo;Member[HybridDb]", + "minimongo/lib/IndexedDb.default;minimongo/lib/IndexedDb.defaultStatic;Instance", + "minimongo/lib/IndexedDb.default;minimongo;Member[utils].Member[autoselectLocalDb].ReturnValue", + "minimongo/lib/IndexedDb.defaultStatic;minimongo/lib/IndexedDb;Member[default]", + "minimongo/lib/IndexedDb.defaultStatic;minimongo;Member[IndexedDb]", + "minimongo/lib/LocalStorageDb.default;minimongo/lib/LocalStorageDb.defaultStatic;Instance", + "minimongo/lib/LocalStorageDb.default;minimongo;Member[utils].Member[autoselectLocalDb].ReturnValue", + "minimongo/lib/LocalStorageDb.defaultStatic;minimongo/lib/LocalStorageDb;Member[default]", + "minimongo/lib/LocalStorageDb.defaultStatic;minimongo;Member[LocalStorageDb]", + "minimongo/lib/MemoryDb.default;minimongo/lib/MemoryDb.defaultStatic;Instance", + "minimongo/lib/MemoryDb.default;minimongo;Member[utils].Member[autoselectLocalDb].ReturnValue", + "minimongo/lib/MemoryDb.defaultStatic;minimongo/lib/MemoryDb;Member[default]", + "minimongo/lib/MemoryDb.defaultStatic;minimongo;Member[MemoryDb]", + "minimongo/lib/RemoteDb.default;minimongo/lib/RemoteDb.defaultStatic;Instance", + "minimongo/lib/RemoteDb.defaultStatic;minimongo/lib/RemoteDb;Member[default]", + "minimongo/lib/RemoteDb.defaultStatic;minimongo;Member[RemoteDb]", + "minimongo/lib/ReplicatingDb.default;minimongo/lib/ReplicatingDb.defaultStatic;Instance", + "minimongo/lib/ReplicatingDb.defaultStatic;minimongo/lib/ReplicatingDb;Member[default]", + "minimongo/lib/ReplicatingDb.defaultStatic;minimongo;Member[ReplicatingDb]", + "minimongo/lib/WebSQLDb.default;minimongo/lib/WebSQLDb.defaultStatic;Instance", + "minimongo/lib/WebSQLDb.default;minimongo;Member[utils].Member[autoselectLocalDb].ReturnValue", + "minimongo/lib/WebSQLDb.defaultStatic;minimongo/lib/WebSQLDb;Member[default]", + "minimongo/lib/WebSQLDb.defaultStatic;minimongo;Member[WebSQLDb]" ], "summaries": [], "typeVariables": [] diff --git a/javascript/ql/lib/semmle/javascript/frameworks/mongodb/Model.qll b/javascript/ql/lib/semmle/javascript/frameworks/mongodb/Model.qll index 9509a5a34e0..4cceff77185 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/mongodb/Model.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/mongodb/Model.qll @@ -6,32 +6,32 @@ private class Sinks extends ModelInput::SinkModelCsv { override predicate row(string row) { row = [ - "mongodb;Collection;Member[aggregate,count,countDocuments,deleteMany,deleteOne,find,findOne,findOneAndDelete,findOneAndReplace,remove,replaceOne,watch].Argument[0];mongodb.sink", // - "mongodb;Collection;Member[distinct].Argument[1];mongodb.sink", // - "mongodb;Collection;Member[findOneAndUpdate,update,updateMany,updateOne].Argument[0,1];mongodb.sink", // - "mongodb;Db;Member[aggregate,watch].Argument[0];mongodb.sink", // - "mongodb;DeleteManyModel;Member[filter];mongodb.sink", // - "mongodb;DeleteOneModel;Member[filter];mongodb.sink", // - "mongodb;MongoClient;Member[watch].Argument[0];mongodb.sink", // - "mongodb;UpdateManyModel;Member[filter,update];mongodb.sink", // - "mongodb;UpdateOneModel;Member[filter,update];mongodb.sink", // - "mongoose;CollectionBase;Member[findAndModify].Argument[0];mongodb.sink", // - "mongoose;Connection;Member[watch].Argument[0];mongodb.sink", // - "mongoose;Document;Member[update,updateOne].Argument[0];mongodb.sink", // - "mongoose;Model;Member[$where,aggregate,exists,find,findById,findByIdAndDelete,findByIdAndRemove,findOne,findOneAndDelete,findOneAndRemove,findOneAndReplace,geoSearch,remove,replaceOne,watch].Argument[0];mongodb.sink", // - "mongoose;Model;Member[count,where].WithArity[1,2].Argument[0];mongodb.sink", // - "mongoose;Model;Member[countDocuments].WithArity[1,2,3].Argument[0];mongodb.sink", // - "mongoose;Model;Member[deleteMany,deleteOne].WithArity[0,1,2,3].Argument[0];mongodb.sink", // - "mongoose;Model;Member[distinct,where].Argument[1];mongodb.sink", // - "mongoose;Model;Member[findByIdAndUpdate,findOneAndUpdate,update,updateMany,updateOne].Argument[0,1];mongodb.sink", // - "mongoose;Model;Member[find].WithArity[1,2,3,4].Argument[0];mongodb.sink", // - "mongoose;Query;Member[$where,and,find,findByIdAndDelete,findOne,findOneAndDelete,findOneAndRemove,nor,or,remove,replaceOne,setUpdate].Argument[0];mongodb.sink", // - "mongoose;Query;Member[count,where].WithArity[1,2].Argument[0];mongodb.sink", // - "mongoose;Query;Member[deleteMany,deleteOne].WithArity[0,1,2,3].Argument[0];mongodb.sink", // - "mongoose;Query;Member[distinct,where].Argument[1];mongodb.sink", // - "mongoose;Query;Member[findByIdAndUpdate,findOneAndUpdate,update,updateMany,updateOne].Argument[0,1];mongodb.sink", // - "mongoose;Query;Member[find].WithArity[1,2,3,4].Argument[0];mongodb.sink", // - "mongoose;QueryStatic;Argument[2];mongodb.sink", // + "mongodb.Collection;Member[aggregate,count,countDocuments,deleteMany,deleteOne,find,findOne,findOneAndDelete,findOneAndReplace,remove,replaceOne,watch].Argument[0];mongodb.sink", // + "mongodb.Collection;Member[distinct].Argument[1];mongodb.sink", // + "mongodb.Collection;Member[findOneAndUpdate,update,updateMany,updateOne].Argument[0,1];mongodb.sink", // + "mongodb.Db;Member[aggregate,watch].Argument[0];mongodb.sink", // + "mongodb.DeleteManyModel;Member[filter];mongodb.sink", // + "mongodb.DeleteOneModel;Member[filter];mongodb.sink", // + "mongodb.MongoClient;Member[watch].Argument[0];mongodb.sink", // + "mongodb.UpdateManyModel;Member[filter,update];mongodb.sink", // + "mongodb.UpdateOneModel;Member[filter,update];mongodb.sink", // + "mongoose.CollectionBase;Member[findAndModify].Argument[0];mongodb.sink", // + "mongoose.Connection;Member[watch].Argument[0];mongodb.sink", // + "mongoose.Document;Member[update,updateOne].Argument[0];mongodb.sink", // + "mongoose.Model;Member[$where,aggregate,exists,find,findById,findByIdAndDelete,findByIdAndRemove,findOne,findOneAndDelete,findOneAndRemove,findOneAndReplace,geoSearch,remove,replaceOne,watch].Argument[0];mongodb.sink", // + "mongoose.Model;Member[count,where].WithArity[1,2].Argument[0];mongodb.sink", // + "mongoose.Model;Member[countDocuments].WithArity[1,2,3].Argument[0];mongodb.sink", // + "mongoose.Model;Member[deleteMany,deleteOne].WithArity[0,1,2,3].Argument[0];mongodb.sink", // + "mongoose.Model;Member[distinct,where].Argument[1];mongodb.sink", // + "mongoose.Model;Member[findByIdAndUpdate,findOneAndUpdate,update,updateMany,updateOne].Argument[0,1];mongodb.sink", // + "mongoose.Model;Member[find].WithArity[1,2,3,4].Argument[0];mongodb.sink", // + "mongoose.Query;Member[$where,and,find,findByIdAndDelete,findOne,findOneAndDelete,findOneAndRemove,nor,or,remove,replaceOne,setUpdate].Argument[0];mongodb.sink", // + "mongoose.Query;Member[count,where].WithArity[1,2].Argument[0];mongodb.sink", // + "mongoose.Query;Member[deleteMany,deleteOne].WithArity[0,1,2,3].Argument[0];mongodb.sink", // + "mongoose.Query;Member[distinct,where].Argument[1];mongodb.sink", // + "mongoose.Query;Member[findByIdAndUpdate,findOneAndUpdate,update,updateMany,updateOne].Argument[0,1];mongodb.sink", // + "mongoose.Query;Member[find].WithArity[1,2,3,4].Argument[0];mongodb.sink", // + "mongoose.QueryStatic;Argument[2];mongodb.sink", // ] } } @@ -40,617 +40,617 @@ private class Types extends ModelInput::TypeModelCsv { override predicate row(string row) { row = [ - "mongodb;;mongoose;;Member[mongodb]", // - "mongodb;AbstractCursor;mongodb;FindCursor;", // - "mongodb;AbstractCursor;mongodb;ListCollectionsCursor;", // - "mongodb;AbstractCursor;mongodb;ListIndexesCursor;", // - "mongodb;AbstractCursorOptions;mongodb/mongodb;AbstractCursorOptions;", // - "mongodb;AbstractCursorOptions;mongodb;AggregationCursorOptions;", // - "mongodb;AbstractCursorOptions;mongoose;mongodb.AbstractCursorOptions;", // - "mongodb;AddUserOptions;mongodb/mongodb;AddUserOptions;", // - "mongodb;AddUserOptions;mongodb;Admin;Member[addUser].Argument[1,2]", // - "mongodb;AddUserOptions;mongodb;Db;Member[addUser].Argument[1,2]", // - "mongodb;AddUserOptions;mongoose;mongodb.AddUserOptions;", // - "mongodb;Admin;mongodb/mongodb;Admin;", // - "mongodb;Admin;mongodb;AdminStatic;Instance", // - "mongodb;Admin;mongodb;Db;Member[admin].ReturnValue", // - "mongodb;Admin;mongoose;mongodb.Admin;", // - "mongodb;AdminStatic;mongodb/mongodb;AdminStatic;", // - "mongodb;AdminStatic;mongodb;;Member[Admin]", // - "mongodb;AdminStatic;mongoose;mongodb.AdminStatic;", // - "mongodb;AggregateOptions;mongodb/mongodb;AggregateOptions;", // - "mongodb;AggregateOptions;mongodb;AggregationCursorOptions;", // - "mongodb;AggregateOptions;mongodb;ChangeStreamOptions;", // - "mongodb;AggregateOptions;mongodb;Collection;Member[aggregate].Argument[1]", // - "mongodb;AggregateOptions;mongodb;CountDocumentsOptions;", // - "mongodb;AggregateOptions;mongodb;Db;Member[aggregate].Argument[1]", // - "mongodb;AggregateOptions;mongoose;mongodb.AggregateOptions;", // - "mongodb;AggregationCursorOptions;mongodb/mongodb;AggregationCursorOptions;", // - "mongodb;AggregationCursorOptions;mongoose;mongodb.AggregationCursorOptions;", // - "mongodb;AnyBulkWriteOperation;mongodb/mongodb;AnyBulkWriteOperation;", // - "mongodb;AnyBulkWriteOperation;mongodb;BulkOperationBase;Member[raw].Argument[0]", // - "mongodb;AnyBulkWriteOperation;mongodb;Collection;Member[bulkWrite].Argument[0].ArrayElement", // - "mongodb;AnyBulkWriteOperation;mongoose;mongodb.AnyBulkWriteOperation;", // - "mongodb;Auth;mongodb/mongodb;Auth;", // - "mongodb;Auth;mongodb;MongoClientOptions;Member[auth]", // - "mongodb;Auth;mongoose;mongodb.Auth;", // - "mongodb;AutoEncrypter;mongodb/mongodb;AutoEncrypter;", // - "mongodb;AutoEncrypter;mongodb;AutoEncrypter;Instance", // - "mongodb;AutoEncrypter;mongodb;ConnectionOptions;Member[autoEncrypter]", // - "mongodb;AutoEncrypter;mongodb;MongoClient;Member[autoEncrypter]", // - "mongodb;AutoEncrypter;mongodb;MongoOptions;Member[autoEncrypter]", // - "mongodb;AutoEncrypter;mongoose;mongodb.AutoEncrypter;", // - "mongodb;AutoEncryptionOptions;mongodb/mongodb;AutoEncryptionOptions;", // - "mongodb;AutoEncryptionOptions;mongodb;AutoEncrypter;Argument[1]", // - "mongodb;AutoEncryptionOptions;mongodb;MongoClientOptions;Member[autoEncryption]", // - "mongodb;AutoEncryptionOptions;mongoose;mongodb.AutoEncryptionOptions;", // - "mongodb;BulkOperationBase;mongodb/mongodb;BulkOperationBase;", // - "mongodb;BulkOperationBase;mongodb;BulkOperationBase;Member[addToOperationsList,insert,raw].ReturnValue", // - "mongodb;BulkOperationBase;mongodb;BulkOperationBaseStatic;Instance", // - "mongodb;BulkOperationBase;mongodb;FindOperators;Member[bulkOperation]", // - "mongodb;BulkOperationBase;mongodb;FindOperators;Member[delete,deleteOne,replaceOne,update,updateOne].ReturnValue", // - "mongodb;BulkOperationBase;mongodb;OrderedBulkOperation;", // - "mongodb;BulkOperationBase;mongodb;UnorderedBulkOperation;", // - "mongodb;BulkOperationBase;mongoose;mongodb.BulkOperationBase;", // - "mongodb;BulkOperationBaseStatic;mongodb/mongodb;BulkOperationBaseStatic;", // - "mongodb;BulkOperationBaseStatic;mongodb;;Member[BulkOperationBase]", // - "mongodb;BulkOperationBaseStatic;mongoose;mongodb.BulkOperationBaseStatic;", // - "mongodb;BulkWriteOptions;mongodb/mongodb;BulkWriteOptions;", // - "mongodb;BulkWriteOptions;mongodb;BulkOperationBase;Member[execute].WithArity[0,1,2].Argument[0]", // - "mongodb;BulkWriteOptions;mongodb;Collection;Member[bulkWrite,insert,insertMany].Argument[1]", // - "mongodb;BulkWriteOptions;mongodb;Collection;Member[initializeOrderedBulkOp,initializeUnorderedBulkOp].Argument[0]", // - "mongodb;BulkWriteOptions;mongodb;OrderedBulkOperationStatic;Argument[1]", // - "mongodb;BulkWriteOptions;mongodb;UnorderedBulkOperationStatic;Argument[1]", // - "mongodb;BulkWriteOptions;mongoose;mongodb.BulkWriteOptions;", // - "mongodb;ChangeStream;mongodb/mongodb;ChangeStream;", // - "mongodb;ChangeStream;mongodb;ChangeStreamStatic;Instance", // - "mongodb;ChangeStream;mongodb;Collection;Member[watch].ReturnValue", // - "mongodb;ChangeStream;mongodb;Db;Member[watch].ReturnValue", // - "mongodb;ChangeStream;mongodb;MongoClient;Member[watch].ReturnValue", // - "mongodb;ChangeStream;mongoose;mongodb.ChangeStream;", // - "mongodb;ChangeStreamOptions;mongodb/mongodb;ChangeStreamOptions;", // - "mongodb;ChangeStreamOptions;mongodb;ChangeStream;Member[options]", // - "mongodb;ChangeStreamOptions;mongodb;Collection;Member[watch].Argument[1]", // - "mongodb;ChangeStreamOptions;mongodb;Db;Member[watch].Argument[1]", // - "mongodb;ChangeStreamOptions;mongodb;MongoClient;Member[watch].Argument[1]", // - "mongodb;ChangeStreamOptions;mongoose;mongodb.ChangeStreamOptions;", // - "mongodb;ChangeStreamStatic;mongodb/mongodb;ChangeStreamStatic;", // - "mongodb;ChangeStreamStatic;mongodb;;Member[ChangeStream]", // - "mongodb;ChangeStreamStatic;mongoose;mongodb.ChangeStreamStatic;", // - "mongodb;ClientSession;mongodb/mongodb;ClientSession;", // - "mongodb;ClientSession;mongodb;AbstractCursorOptions;Member[session]", // - "mongodb;ClientSession;mongodb;ClientSession;Member[equals].Argument[0]", // - "mongodb;ClientSession;mongodb;ClientSessionEvents;Member[ended].Argument[0]", // - "mongodb;ClientSession;mongodb;ClientSessionStatic;Instance", // - "mongodb;ClientSession;mongodb;IndexInformationOptions;Member[session]", // - "mongodb;ClientSession;mongodb;MongoClient;Member[startSession].ReturnValue", // - "mongodb;ClientSession;mongodb;OperationOptions;Member[session]", // - "mongodb;ClientSession;mongodb;ReadPreferenceFromOptions;Member[session]", // - "mongodb;ClientSession;mongodb;SelectServerOptions;Member[session]", // - "mongodb;ClientSession;mongodb;WithSessionCallback;Argument[0]", // - "mongodb;ClientSession;mongodb;WithTransactionCallback;Argument[0]", // - "mongodb;ClientSession;mongoose;mongodb.ClientSession;", // - "mongodb;ClientSessionEvents;mongodb/mongodb;ClientSessionEvents;", // - "mongodb;ClientSessionEvents;mongoose;mongodb.ClientSessionEvents;", // - "mongodb;ClientSessionOptions;mongodb/mongodb;ClientSessionOptions;", // - "mongodb;ClientSessionOptions;mongodb;MongoClient;Member[startSession].Argument[0]", // - "mongodb;ClientSessionOptions;mongodb;MongoClient;Member[withSession].WithArity[2].Argument[0]", // - "mongodb;ClientSessionOptions;mongoose;mongodb.ClientSessionOptions;", // - "mongodb;ClientSessionStatic;mongodb/mongodb;ClientSessionStatic;", // - "mongodb;ClientSessionStatic;mongodb;;Member[ClientSession]", // - "mongodb;ClientSessionStatic;mongoose;mongodb.ClientSessionStatic;", // - "mongodb;CollStatsOptions;mongodb/mongodb;CollStatsOptions;", // - "mongodb;CollStatsOptions;mongodb;Collection;Member[stats].Argument[0]", // - "mongodb;CollStatsOptions;mongoose;mongodb.CollStatsOptions;", // - "mongodb;Collection;mongodb/mongodb;Collection;", // - "mongodb;Collection;mongodb;ChangeStream;Member[parent]", // - "mongodb;Collection;mongodb;Collection;Member[rename].Argument[1,2].TypeVar[mongodb.Callback.0]", // - "mongodb;Collection;mongodb;Collection;Member[rename].WithArity[1,2].ReturnValue.Awaited", // - "mongodb;Collection;mongodb;CollectionStatic;Instance", // - "mongodb;Collection;mongodb;Db;Member[collection].ReturnValue", // - "mongodb;Collection;mongodb;Db;Member[collections].Argument[0,1].TypeVar[mongodb.Callback.0].ArrayElement", // - "mongodb;Collection;mongodb;Db;Member[collections].WithArity[0,1].ReturnValue.Awaited.ArrayElement", // - "mongodb;Collection;mongodb;Db;Member[createCollection].Argument[2].TypeVar[mongodb.Callback.0]", // - "mongodb;Collection;mongodb;Db;Member[createCollection].WithArity[1,2].ReturnValue.Awaited", // - "mongodb;Collection;mongodb;Db;Member[createCollection].WithArity[2].Argument[1].TypeVar[mongodb.Callback.0]", // - "mongodb;Collection;mongodb;Db;Member[renameCollection].Argument[2,3].TypeVar[mongodb.Callback.0]", // - "mongodb;Collection;mongodb;Db;Member[renameCollection].WithArity[2,3].ReturnValue.Awaited", // - "mongodb;Collection;mongodb;GridFSBucketWriteStream;Member[chunks,files]", // - "mongodb;Collection;mongodb;ListIndexesCursor;Member[parent]", // - "mongodb;Collection;mongodb;ListIndexesCursorStatic;Argument[0]", // - "mongodb;Collection;mongodb;OrderedBulkOperationStatic;Argument[0]", // - "mongodb;Collection;mongodb;UnorderedBulkOperationStatic;Argument[0]", // - "mongodb;Collection;mongoose;mongodb.Collection;", // - "mongodb;CollectionStatic;mongodb/mongodb;CollectionStatic;", // - "mongodb;CollectionStatic;mongodb;;Member[Collection]", // - "mongodb;CollectionStatic;mongoose;mongodb.CollectionStatic;", // - "mongodb;CommandOperationOptions;mongodb/mongodb;CommandOperationOptions;", // - "mongodb;CommandOperationOptions;mongodb;AddUserOptions;", // - "mongodb;CommandOperationOptions;mongodb;Admin;Member[buildInfo,ping,replSetGetStatus,serverInfo,serverStatus].Argument[0]", // - "mongodb;CommandOperationOptions;mongodb;AggregateOptions;", // - "mongodb;CommandOperationOptions;mongodb;BulkWriteOptions;", // - "mongodb;CommandOperationOptions;mongodb;CollStatsOptions;", // - "mongodb;CommandOperationOptions;mongodb;CountOptions;", // - "mongodb;CommandOperationOptions;mongodb;CreateCollectionOptions;", // - "mongodb;CommandOperationOptions;mongodb;CreateIndexesOptions;", // - "mongodb;CommandOperationOptions;mongodb;DbStatsOptions;", // - "mongodb;CommandOperationOptions;mongodb;DeleteOptions;", // - "mongodb;CommandOperationOptions;mongodb;DistinctOptions;", // - "mongodb;CommandOperationOptions;mongodb;DropCollectionOptions;", // - "mongodb;CommandOperationOptions;mongodb;DropDatabaseOptions;", // - "mongodb;CommandOperationOptions;mongodb;DropIndexesOptions;", // - "mongodb;CommandOperationOptions;mongodb;EstimatedDocumentCountOptions;", // - "mongodb;CommandOperationOptions;mongodb;EvalOptions;", // - "mongodb;CommandOperationOptions;mongodb;FindOneAndDeleteOptions;", // - "mongodb;CommandOperationOptions;mongodb;FindOneAndReplaceOptions;", // - "mongodb;CommandOperationOptions;mongodb;FindOneAndUpdateOptions;", // - "mongodb;CommandOperationOptions;mongodb;FindOptions;", // - "mongodb;CommandOperationOptions;mongodb;InsertOneOptions;", // - "mongodb;CommandOperationOptions;mongodb;ListCollectionsOptions;", // - "mongodb;CommandOperationOptions;mongodb;ListDatabasesOptions;", // - "mongodb;CommandOperationOptions;mongodb;ListIndexesOptions;", // - "mongodb;CommandOperationOptions;mongodb;MapReduceOptions;", // - "mongodb;CommandOperationOptions;mongodb;ProfilingLevelOptions;", // - "mongodb;CommandOperationOptions;mongodb;RemoveUserOptions;", // - "mongodb;CommandOperationOptions;mongodb;RenameOptions;", // - "mongodb;CommandOperationOptions;mongodb;ReplaceOptions;", // - "mongodb;CommandOperationOptions;mongodb;RunCommandOptions;", // - "mongodb;CommandOperationOptions;mongodb;SetProfilingLevelOptions;", // - "mongodb;CommandOperationOptions;mongodb;TransactionOptions;", // - "mongodb;CommandOperationOptions;mongodb;UpdateOptions;", // - "mongodb;CommandOperationOptions;mongodb;ValidateCollectionOptions;", // - "mongodb;CommandOperationOptions;mongoose;mongodb.CommandOperationOptions;", // - "mongodb;ConnectionOptions;mongodb/mongodb;ConnectionOptions;", // - "mongodb;ConnectionOptions;mongoose;mongodb.ConnectionOptions;", // - "mongodb;CountDocumentsOptions;mongodb/mongodb;CountDocumentsOptions;", // - "mongodb;CountDocumentsOptions;mongodb;Collection;Member[countDocuments].Argument[1]", // - "mongodb;CountDocumentsOptions;mongoose;mongodb.CountDocumentsOptions;", // - "mongodb;CountOptions;mongodb/mongodb;CountOptions;", // - "mongodb;CountOptions;mongodb;Collection;Member[count].Argument[1]", // - "mongodb;CountOptions;mongodb;FindCursor;Member[count].Argument[0]", // - "mongodb;CountOptions;mongoose;mongodb.CountOptions;", // - "mongodb;CreateCollectionOptions;mongodb/mongodb;CreateCollectionOptions;", // - "mongodb;CreateCollectionOptions;mongodb;Db;Member[createCollection].WithArity[1,2,3].Argument[1]", // - "mongodb;CreateCollectionOptions;mongoose;mongodb.CreateCollectionOptions;", // - "mongodb;CreateIndexesOptions;mongodb/mongodb;CreateIndexesOptions;", // - "mongodb;CreateIndexesOptions;mongodb;Collection;Member[createIndex,createIndexes].Argument[1]", // - "mongodb;CreateIndexesOptions;mongodb;Db;Member[createIndex].Argument[2]", // - "mongodb;CreateIndexesOptions;mongoose;mongodb.CreateIndexesOptions;", // - "mongodb;Db;mongodb/mongodb;Db;", // - "mongodb;Db;mongodb;ChangeStream;Member[parent]", // - "mongodb;Db;mongodb;DbStatic;Instance", // - "mongodb;Db;mongodb;GridFSBucketStatic;Argument[0]", // - "mongodb;Db;mongodb;ListCollectionsCursor;Member[parent]", // - "mongodb;Db;mongodb;ListCollectionsCursorStatic;Argument[0]", // - "mongodb;Db;mongodb;MongoClient;Member[db].ReturnValue", // - "mongodb;Db;mongoose;mongodb.Db;", // - "mongodb;DbStatic;mongodb/mongodb;DbStatic;", // - "mongodb;DbStatic;mongodb;;Member[Db]", // - "mongodb;DbStatic;mongoose;mongodb.DbStatic;", // - "mongodb;DbStatsOptions;mongodb/mongodb;DbStatsOptions;", // - "mongodb;DbStatsOptions;mongodb;Db;Member[stats].Argument[0]", // - "mongodb;DbStatsOptions;mongoose;mongodb.DbStatsOptions;", // - "mongodb;DeleteManyModel;mongodb/mongodb;DeleteManyModel;", // - "mongodb;DeleteManyModel;mongodb;AnyBulkWriteOperation;Member[deleteMany]", // - "mongodb;DeleteManyModel;mongoose;mongodb.DeleteManyModel;", // - "mongodb;DeleteOneModel;mongodb/mongodb;DeleteOneModel;", // - "mongodb;DeleteOneModel;mongodb;AnyBulkWriteOperation;Member[deleteOne]", // - "mongodb;DeleteOneModel;mongoose;mongodb.DeleteOneModel;", // - "mongodb;DeleteOptions;mongodb/mongodb;DeleteOptions;", // - "mongodb;DeleteOptions;mongodb;Collection;Member[deleteMany,deleteOne,remove].Argument[1]", // - "mongodb;DeleteOptions;mongoose;mongodb.DeleteOptions;", // - "mongodb;DistinctOptions;mongodb/mongodb;DistinctOptions;", // - "mongodb;DistinctOptions;mongodb;Collection;Member[distinct].Argument[2]", // - "mongodb;DistinctOptions;mongoose;mongodb.DistinctOptions;", // - "mongodb;DropCollectionOptions;mongodb/mongodb;DropCollectionOptions;", // - "mongodb;DropCollectionOptions;mongodb;Collection;Member[drop].Argument[0]", // - "mongodb;DropCollectionOptions;mongodb;Db;Member[dropCollection].Argument[1]", // - "mongodb;DropCollectionOptions;mongoose;mongodb.DropCollectionOptions;", // - "mongodb;DropDatabaseOptions;mongodb/mongodb;DropDatabaseOptions;", // - "mongodb;DropDatabaseOptions;mongodb;Db;Member[dropDatabase].Argument[0]", // - "mongodb;DropDatabaseOptions;mongoose;mongodb.DropDatabaseOptions;", // - "mongodb;DropIndexesOptions;mongodb/mongodb;DropIndexesOptions;", // - "mongodb;DropIndexesOptions;mongodb;Collection;Member[dropIndex].Argument[1]", // - "mongodb;DropIndexesOptions;mongodb;Collection;Member[dropIndexes].Argument[0]", // - "mongodb;DropIndexesOptions;mongoose;mongodb.DropIndexesOptions;", // - "mongodb;EstimatedDocumentCountOptions;mongodb/mongodb;EstimatedDocumentCountOptions;", // - "mongodb;EstimatedDocumentCountOptions;mongodb;Collection;Member[estimatedDocumentCount].Argument[0]", // - "mongodb;EstimatedDocumentCountOptions;mongoose;mongodb.EstimatedDocumentCountOptions;", // - "mongodb;EvalOptions;mongodb/mongodb;EvalOptions;", // - "mongodb;EvalOptions;mongoose;mongodb.EvalOptions;", // - "mongodb;FindCursor;mongodb/mongodb;FindCursor;", // - "mongodb;FindCursor;mongodb;Collection;Member[find].WithArity[0,1,2].ReturnValue", // - "mongodb;FindCursor;mongodb;FindCursor;Member[addQueryModifier,allowDiskUse,clone,collation,comment,filter,hint,limit,map,max,maxAwaitTimeMS,maxTimeMS,min,project,returnKey,showRecordId,skip,sort].ReturnValue", // - "mongodb;FindCursor;mongodb;FindCursorStatic;Instance", // - "mongodb;FindCursor;mongodb;GridFSBucket;Member[find].ReturnValue", // - "mongodb;FindCursor;mongoose;mongodb.FindCursor;", // - "mongodb;FindCursorStatic;mongodb/mongodb;FindCursorStatic;", // - "mongodb;FindCursorStatic;mongodb;;Member[FindCursor]", // - "mongodb;FindCursorStatic;mongoose;mongodb.FindCursorStatic;", // - "mongodb;FindOneAndDeleteOptions;mongodb/mongodb;FindOneAndDeleteOptions;", // - "mongodb;FindOneAndDeleteOptions;mongodb;Collection;Member[findOneAndDelete].Argument[1]", // - "mongodb;FindOneAndDeleteOptions;mongoose;mongodb.FindOneAndDeleteOptions;", // - "mongodb;FindOneAndReplaceOptions;mongodb/mongodb;FindOneAndReplaceOptions;", // - "mongodb;FindOneAndReplaceOptions;mongodb;Collection;Member[findOneAndReplace].Argument[2]", // - "mongodb;FindOneAndReplaceOptions;mongoose;mongodb.FindOneAndReplaceOptions;", // - "mongodb;FindOneAndUpdateOptions;mongodb/mongodb;FindOneAndUpdateOptions;", // - "mongodb;FindOneAndUpdateOptions;mongodb;Collection;Member[findOneAndUpdate].Argument[2]", // - "mongodb;FindOneAndUpdateOptions;mongoose;mongodb.FindOneAndUpdateOptions;", // - "mongodb;FindOperators;mongodb/mongodb;FindOperators;", // - "mongodb;FindOperators;mongodb;BulkOperationBase;Member[find].ReturnValue", // - "mongodb;FindOperators;mongodb;FindOperators;Member[arrayFilters,collation,upsert].ReturnValue", // - "mongodb;FindOperators;mongodb;FindOperatorsStatic;Instance", // - "mongodb;FindOperators;mongoose;mongodb.FindOperators;", // - "mongodb;FindOperatorsStatic;mongodb/mongodb;FindOperatorsStatic;", // - "mongodb;FindOperatorsStatic;mongodb;;Member[FindOperators]", // - "mongodb;FindOperatorsStatic;mongoose;mongodb.FindOperatorsStatic;", // - "mongodb;FindOptions;mongodb/mongodb;FindOptions;", // - "mongodb;FindOptions;mongodb;Collection;Member[find,findOne].Argument[1]", // - "mongodb;FindOptions;mongodb;GridFSBucket;Member[find].Argument[1]", // - "mongodb;FindOptions;mongoose;mongodb.FindOptions;", // - "mongodb;GridFSBucket;mongodb/mongodb;GridFSBucket;", // - "mongodb;GridFSBucket;mongodb;GridFSBucketStatic;Instance", // - "mongodb;GridFSBucket;mongodb;GridFSBucketWriteStream;Member[bucket]", // - "mongodb;GridFSBucket;mongoose;mongodb.GridFSBucket;", // - "mongodb;GridFSBucketStatic;mongodb/mongodb;GridFSBucketStatic;", // - "mongodb;GridFSBucketStatic;mongodb;;Member[GridFSBucket]", // - "mongodb;GridFSBucketStatic;mongoose;mongodb.GridFSBucketStatic;", // - "mongodb;GridFSBucketWriteStream;mongodb/mongodb;GridFSBucketWriteStream;", // - "mongodb;GridFSBucketWriteStream;mongodb;GridFSBucket;Member[openUploadStream,openUploadStreamWithId].ReturnValue", // - "mongodb;GridFSBucketWriteStream;mongodb;GridFSBucketWriteStream;Member[end].ReturnValue", // - "mongodb;GridFSBucketWriteStream;mongodb;GridFSBucketWriteStreamStatic;Instance", // - "mongodb;GridFSBucketWriteStream;mongoose;mongodb.GridFSBucketWriteStream;", // - "mongodb;GridFSBucketWriteStreamStatic;mongodb/mongodb;GridFSBucketWriteStreamStatic;", // - "mongodb;GridFSBucketWriteStreamStatic;mongodb;;Member[GridFSBucketWriteStream]", // - "mongodb;GridFSBucketWriteStreamStatic;mongoose;mongodb.GridFSBucketWriteStreamStatic;", // - "mongodb;IndexInformationOptions;mongodb/mongodb;IndexInformationOptions;", // - "mongodb;IndexInformationOptions;mongodb;Collection;Member[indexExists].Argument[1]", // - "mongodb;IndexInformationOptions;mongodb;Collection;Member[indexInformation,indexes].Argument[0]", // - "mongodb;IndexInformationOptions;mongodb;Db;Member[indexInformation].Argument[1]", // - "mongodb;IndexInformationOptions;mongoose;mongodb.IndexInformationOptions;", // - "mongodb;InsertOneOptions;mongodb/mongodb;InsertOneOptions;", // - "mongodb;InsertOneOptions;mongodb;Collection;Member[insertOne].Argument[1]", // - "mongodb;InsertOneOptions;mongoose;mongodb.InsertOneOptions;", // - "mongodb;ListCollectionsCursor;mongodb/mongodb;ListCollectionsCursor;", // - "mongodb;ListCollectionsCursor;mongodb;Db;Member[listCollections].WithArity[0,1,2].ReturnValue", // - "mongodb;ListCollectionsCursor;mongodb;ListCollectionsCursor;Member[clone].ReturnValue", // - "mongodb;ListCollectionsCursor;mongodb;ListCollectionsCursorStatic;Instance", // - "mongodb;ListCollectionsCursor;mongoose;mongodb.ListCollectionsCursor;", // - "mongodb;ListCollectionsCursorStatic;mongodb/mongodb;ListCollectionsCursorStatic;", // - "mongodb;ListCollectionsCursorStatic;mongodb;;Member[ListCollectionsCursor]", // - "mongodb;ListCollectionsCursorStatic;mongoose;mongodb.ListCollectionsCursorStatic;", // - "mongodb;ListCollectionsOptions;mongodb/mongodb;ListCollectionsOptions;", // - "mongodb;ListCollectionsOptions;mongodb;Db;Member[collections].Argument[0]", // - "mongodb;ListCollectionsOptions;mongodb;Db;Member[listCollections].WithArity[0,1,2].Argument[1]", // - "mongodb;ListCollectionsOptions;mongodb;ListCollectionsCursor;Member[options]", // - "mongodb;ListCollectionsOptions;mongodb;ListCollectionsCursorStatic;Argument[2]", // - "mongodb;ListCollectionsOptions;mongoose;mongodb.ListCollectionsOptions;", // - "mongodb;ListDatabasesOptions;mongodb/mongodb;ListDatabasesOptions;", // - "mongodb;ListDatabasesOptions;mongodb;Admin;Member[listDatabases].Argument[0]", // - "mongodb;ListDatabasesOptions;mongoose;mongodb.ListDatabasesOptions;", // - "mongodb;ListIndexesCursor;mongodb/mongodb;ListIndexesCursor;", // - "mongodb;ListIndexesCursor;mongodb;Collection;Member[listIndexes].ReturnValue", // - "mongodb;ListIndexesCursor;mongodb;ListIndexesCursor;Member[clone].ReturnValue", // - "mongodb;ListIndexesCursor;mongodb;ListIndexesCursorStatic;Instance", // - "mongodb;ListIndexesCursor;mongoose;mongodb.ListIndexesCursor;", // - "mongodb;ListIndexesCursorStatic;mongodb/mongodb;ListIndexesCursorStatic;", // - "mongodb;ListIndexesCursorStatic;mongodb;;Member[ListIndexesCursor]", // - "mongodb;ListIndexesCursorStatic;mongoose;mongodb.ListIndexesCursorStatic;", // - "mongodb;ListIndexesOptions;mongodb/mongodb;ListIndexesOptions;", // - "mongodb;ListIndexesOptions;mongodb;Collection;Member[listIndexes].Argument[0]", // - "mongodb;ListIndexesOptions;mongodb;ListIndexesCursor;Member[options]", // - "mongodb;ListIndexesOptions;mongodb;ListIndexesCursorStatic;Argument[1]", // - "mongodb;ListIndexesOptions;mongoose;mongodb.ListIndexesOptions;", // - "mongodb;MapReduceOptions;mongodb/mongodb;MapReduceOptions;", // - "mongodb;MapReduceOptions;mongodb;Collection;Member[mapReduce].Argument[2]", // - "mongodb;MapReduceOptions;mongoose;mongodb.MapReduceOptions;", // - "mongodb;MongoClient;mongodb/mongodb;MongoClient;", // - "mongodb;MongoClient;mongodb;AutoEncrypter;Argument[0]", // - "mongodb;MongoClient;mongodb;AutoEncryptionOptions;Member[keyVaultClient]", // - "mongodb;MongoClient;mongodb;ChangeStream;Member[parent]", // - "mongodb;MongoClient;mongodb;DbStatic;Argument[0]", // - "mongodb;MongoClient;mongodb;MongoClient;Member[connect].Argument[0].TypeVar[mongodb.Callback.0]", // - "mongodb;MongoClient;mongodb;MongoClient;Member[connect].WithArity[0].ReturnValue.Awaited", // - "mongodb;MongoClient;mongodb;MongoClientEvents;Member[open].Argument[0]", // - "mongodb;MongoClient;mongodb;MongoClientStatic;Instance", // - "mongodb;MongoClient;mongodb;MongoClientStatic;Member[connect].Argument[1,2].TypeVar[mongodb.Callback.0]", // - "mongodb;MongoClient;mongodb;MongoClientStatic;Member[connect].WithArity[1,2].ReturnValue.Awaited", // - "mongodb;MongoClient;mongoose;mongodb.MongoClient;", // - "mongodb;MongoClientEvents;mongodb/mongodb;MongoClientEvents;", // - "mongodb;MongoClientEvents;mongoose;mongodb.MongoClientEvents;", // - "mongodb;MongoClientOptions;mongodb/mongodb;MongoClientOptions;", // - "mongodb;MongoClientOptions;mongodb;MongoClientStatic;Argument[1]", // - "mongodb;MongoClientOptions;mongodb;MongoClientStatic;Member[connect].Argument[1]", // - "mongodb;MongoClientOptions;mongoose;mongodb.MongoClientOptions;", // - "mongodb;MongoClientStatic;mongodb/mongodb;MongoClientStatic;", // - "mongodb;MongoClientStatic;mongodb;;Member[MongoClient]", // - "mongodb;MongoClientStatic;mongoose;mongodb.MongoClientStatic;", // - "mongodb;MongoOptions;mongodb/mongodb;MongoOptions;", // - "mongodb;MongoOptions;mongodb;ClientSession;Member[clientOptions]", // - "mongodb;MongoOptions;mongodb;MongoClient;Member[options]", // - "mongodb;MongoOptions;mongoose;mongodb.MongoOptions;", // - "mongodb;OperationOptions;mongodb/mongodb;OperationOptions;", // - "mongodb;OperationOptions;mongodb;Collection;Member[isCapped,options].Argument[0]", // - "mongodb;OperationOptions;mongodb;CommandOperationOptions;", // - "mongodb;OperationOptions;mongoose;mongodb.OperationOptions;", // - "mongodb;OrderedBulkOperation;mongodb/mongodb;OrderedBulkOperation;", // - "mongodb;OrderedBulkOperation;mongodb;Collection;Member[initializeOrderedBulkOp].ReturnValue", // - "mongodb;OrderedBulkOperation;mongodb;OrderedBulkOperation;Member[addToOperationsList].ReturnValue", // - "mongodb;OrderedBulkOperation;mongodb;OrderedBulkOperationStatic;Instance", // - "mongodb;OrderedBulkOperation;mongoose;mongodb.OrderedBulkOperation;", // - "mongodb;OrderedBulkOperationStatic;mongodb/mongodb;OrderedBulkOperationStatic;", // - "mongodb;OrderedBulkOperationStatic;mongodb;;Member[OrderedBulkOperation]", // - "mongodb;OrderedBulkOperationStatic;mongoose;mongodb.OrderedBulkOperationStatic;", // - "mongodb;ProfilingLevelOptions;mongodb/mongodb;ProfilingLevelOptions;", // - "mongodb;ProfilingLevelOptions;mongodb;Db;Member[profilingLevel].Argument[0]", // - "mongodb;ProfilingLevelOptions;mongoose;mongodb.ProfilingLevelOptions;", // - "mongodb;ReadPreferenceFromOptions;mongodb/mongodb;ReadPreferenceFromOptions;", // - "mongodb;ReadPreferenceFromOptions;mongodb;ReadPreferenceStatic;Member[fromOptions].Argument[0]", // - "mongodb;ReadPreferenceFromOptions;mongoose;mongodb.ReadPreferenceFromOptions;", // - "mongodb;ReadPreferenceStatic;mongodb/mongodb;ReadPreferenceStatic;", // - "mongodb;ReadPreferenceStatic;mongodb;;Member[ReadPreference]", // - "mongodb;ReadPreferenceStatic;mongoose;mongodb.ReadPreferenceStatic;", // - "mongodb;RemoveUserOptions;mongodb/mongodb;RemoveUserOptions;", // - "mongodb;RemoveUserOptions;mongodb;Admin;Member[removeUser].Argument[1]", // - "mongodb;RemoveUserOptions;mongodb;Db;Member[removeUser].Argument[1]", // - "mongodb;RemoveUserOptions;mongoose;mongodb.RemoveUserOptions;", // - "mongodb;RenameOptions;mongodb/mongodb;RenameOptions;", // - "mongodb;RenameOptions;mongodb;Collection;Member[rename].Argument[1]", // - "mongodb;RenameOptions;mongodb;Db;Member[renameCollection].Argument[2]", // - "mongodb;RenameOptions;mongoose;mongodb.RenameOptions;", // - "mongodb;ReplaceOptions;mongodb/mongodb;ReplaceOptions;", // - "mongodb;ReplaceOptions;mongodb;Collection;Member[replaceOne].Argument[2]", // - "mongodb;ReplaceOptions;mongoose;mongodb.ReplaceOptions;", // - "mongodb;RunCommandOptions;mongodb/mongodb;RunCommandOptions;", // - "mongodb;RunCommandOptions;mongodb;Admin;Member[command].Argument[1]", // - "mongodb;RunCommandOptions;mongodb;Db;Member[command].Argument[1]", // - "mongodb;RunCommandOptions;mongoose;mongodb.RunCommandOptions;", // - "mongodb;SelectServerOptions;mongodb/mongodb;SelectServerOptions;", // - "mongodb;SelectServerOptions;mongoose;mongodb.SelectServerOptions;", // - "mongodb;SetProfilingLevelOptions;mongodb/mongodb;SetProfilingLevelOptions;", // - "mongodb;SetProfilingLevelOptions;mongodb;Db;Member[setProfilingLevel].Argument[1]", // - "mongodb;SetProfilingLevelOptions;mongoose;mongodb.SetProfilingLevelOptions;", // - "mongodb;Transaction;mongodb/mongodb;Transaction;", // - "mongodb;Transaction;mongodb;ClientSession;Member[transaction]", // - "mongodb;Transaction;mongodb;TransactionStatic;Instance", // - "mongodb;Transaction;mongoose;mongodb.Transaction;", // - "mongodb;TransactionOptions;mongodb/mongodb;TransactionOptions;", // - "mongodb;TransactionOptions;mongodb;ClientSession;Member[defaultTransactionOptions]", // - "mongodb;TransactionOptions;mongodb;ClientSession;Member[startTransaction].Argument[0]", // - "mongodb;TransactionOptions;mongodb;ClientSession;Member[withTransaction].Argument[1]", // - "mongodb;TransactionOptions;mongodb;ClientSessionOptions;Member[defaultTransactionOptions]", // - "mongodb;TransactionOptions;mongodb;Transaction;Member[options]", // - "mongodb;TransactionOptions;mongoose;mongodb.TransactionOptions;", // - "mongodb;TransactionStatic;mongodb/mongodb;TransactionStatic;", // - "mongodb;TransactionStatic;mongodb;;Member[Transaction]", // - "mongodb;TransactionStatic;mongoose;mongodb.TransactionStatic;", // - "mongodb;TypedEventEmitter;mongodb;AbstractCursor;", // - "mongodb;TypedEventEmitter;mongodb;ChangeStream;", // - "mongodb;TypedEventEmitter;mongodb;ClientSession;", // - "mongodb;TypedEventEmitter;mongodb;GridFSBucket;", // - "mongodb;TypedEventEmitter;mongodb;MongoClient;", // - "mongodb;UnorderedBulkOperation;mongodb/mongodb;UnorderedBulkOperation;", // - "mongodb;UnorderedBulkOperation;mongodb;Collection;Member[initializeUnorderedBulkOp].ReturnValue", // - "mongodb;UnorderedBulkOperation;mongodb;UnorderedBulkOperation;Member[addToOperationsList].ReturnValue", // - "mongodb;UnorderedBulkOperation;mongodb;UnorderedBulkOperationStatic;Instance", // - "mongodb;UnorderedBulkOperation;mongoose;mongodb.UnorderedBulkOperation;", // - "mongodb;UnorderedBulkOperationStatic;mongodb/mongodb;UnorderedBulkOperationStatic;", // - "mongodb;UnorderedBulkOperationStatic;mongodb;;Member[UnorderedBulkOperation]", // - "mongodb;UnorderedBulkOperationStatic;mongoose;mongodb.UnorderedBulkOperationStatic;", // - "mongodb;UpdateManyModel;mongodb/mongodb;UpdateManyModel;", // - "mongodb;UpdateManyModel;mongodb;AnyBulkWriteOperation;Member[updateMany]", // - "mongodb;UpdateManyModel;mongoose;mongodb.UpdateManyModel;", // - "mongodb;UpdateOneModel;mongodb/mongodb;UpdateOneModel;", // - "mongodb;UpdateOneModel;mongodb;AnyBulkWriteOperation;Member[updateOne]", // - "mongodb;UpdateOneModel;mongoose;mongodb.UpdateOneModel;", // - "mongodb;UpdateOptions;mongodb/mongodb;UpdateOptions;", // - "mongodb;UpdateOptions;mongodb;Collection;Member[update,updateMany,updateOne].Argument[2]", // - "mongodb;UpdateOptions;mongoose;mongodb.UpdateOptions;", // - "mongodb;ValidateCollectionOptions;mongodb/mongodb;ValidateCollectionOptions;", // - "mongodb;ValidateCollectionOptions;mongodb;Admin;Member[validateCollection].Argument[1]", // - "mongodb;ValidateCollectionOptions;mongoose;mongodb.ValidateCollectionOptions;", // - "mongodb;WithSessionCallback;mongodb/mongodb;WithSessionCallback;", // - "mongodb;WithSessionCallback;mongodb;MongoClient;Member[withSession].Argument[1]", // - "mongodb;WithSessionCallback;mongodb;MongoClient;Member[withSession].WithArity[1].Argument[0]", // - "mongodb;WithSessionCallback;mongoose;mongodb.WithSessionCallback;", // - "mongodb;WithTransactionCallback;mongodb/mongodb;WithTransactionCallback;", // - "mongodb;WithTransactionCallback;mongodb;ClientSession;Member[withTransaction].Argument[0]", // - "mongodb;WithTransactionCallback;mongoose;mongodb.WithTransactionCallback;", // - "mongoose/inferschematype;ResolvePathType;mongoose/inferschematype;ObtainDocumentPathType;", // - "mongoose/inferschematype;ResolvePathType;mongoose/inferschematype;ResolvePathType;TypeVar[mongoose.IfEquals.3].ArrayElement", // - "mongoose/inferschematype;ResolvePathType;mongoose/inferschematype;ResolvePathType;TypeVar[mongoose.IfEquals.3].TypeVar[mongoose.Types.DocumentArray.0]", // - "mongoose;;mongoose;;Member[mongoose]", // - "mongoose;AcceptsDiscriminator;mongoose;Model;", // - "mongoose;AcceptsDiscriminator;mongoose;Schema.Types.Array;", // - "mongoose;AcceptsDiscriminator;mongoose;Schema.Types.DocumentArray;", // - "mongoose;AcceptsDiscriminator;mongoose;Schema.Types.Subdocument;", // - "mongoose;Aggregate;mongoose;Aggregate;Member[addCursorFlag,addFields,allowDiskUse,append,collation,count,facet,graphLookup,group,hint,limit,lookup,match,model,near,option,project,read,readConcern,redact,replaceRoot,sample,search,session,skip,sort,sortByCount,unionWith,unwind].ReturnValue", // - "mongoose;Aggregate;mongoose;AggregateStatic;Instance", // - "mongoose;Aggregate;mongoose;Model;Member[aggregate].ReturnValue", // - "mongoose;AggregateStatic;mongoose;;Member[Aggregate]", // - "mongoose;Collection;mongoose;;Member[Collection]", // - "mongoose;Collection;mongoose;Collection;Instance", // - "mongoose;Collection;mongoose;Connection;Member[collection].ReturnValue", // - "mongoose;Collection;mongoose;Connection;Member[collections].AnyMember", // - "mongoose;Collection;mongoose;Document;Member[collection]", // - "mongoose;Collection;mongoose;Model;Member[collection]", // - "mongoose;CollectionBase;mongoose;Collection;", // - "mongoose;CompileModelOptions;mongoose;;Member[model].Argument[3]", // - "mongoose;CompileModelOptions;mongoose;Connection;Member[model].Argument[3]", // - "mongoose;ConnectOptions;mongoose;;Member[connect,createConnection].WithArity[1,2,3].Argument[1]", // - "mongoose;ConnectOptions;mongoose;Connection;Member[openUri].WithArity[1,2,3].Argument[1]", // - "mongoose;Connection;mongoose;;Member[connection]", // - "mongoose;Connection;mongoose;;Member[connections].ArrayElement", // - "mongoose;Connection;mongoose;;Member[createConnection].Argument[2].TypeVar[mongoose.Callback.0]", // - "mongoose;Connection;mongoose;;Member[createConnection].WithArity[0,1,2].ReturnValue", // - "mongoose;Connection;mongoose;;Member[createConnection].WithArity[2].Argument[1].TypeVar[mongoose.Callback.0]", // - "mongoose;Connection;mongoose;Collection;Argument[1]", // - "mongoose;Connection;mongoose;CollectionBase;Member[conn]", // - "mongoose;Connection;mongoose;CompileModelOptions;Member[connection]", // - "mongoose;Connection;mongoose;Connection;Member[asPromise].ReturnValue.Awaited", // - "mongoose;Connection;mongoose;Connection;Member[deleteModel,plugin,setClient,useDb].ReturnValue", // - "mongoose;Connection;mongoose;Connection;Member[openUri].Argument[2].TypeVar[mongoose.Callback.0]", // - "mongoose;Connection;mongoose;Connection;Member[openUri].WithArity[1,2].ReturnValue.Awaited", // - "mongoose;Connection;mongoose;Connection;Member[openUri].WithArity[2,3].ReturnValue", // - "mongoose;Connection;mongoose;Connection;Member[openUri].WithArity[2].Argument[1].TypeVar[mongoose.Callback.0]", // - "mongoose;Connection;mongoose;ConnectionStatic;Instance", // - "mongoose;Connection;mongoose;Document;Member[db]", // - "mongoose;Connection;mongoose;Model;Member[db]", // - "mongoose;ConnectionStatic;mongoose;;Member[Connection]", // - "mongoose;Cursor;mongoose;Query;Member[cursor].ReturnValue", // - "mongoose;DiscriminatorModel;mongoose;DiscriminatorSchema;TypeVar[mongoose.Schema.1]", // - "mongoose;Document;mongoose;Document;Member[$getAllSubdocs,$getPopulatedDocs].ReturnValue.ArrayElement", // - "mongoose;Document;mongoose;Document;Member[$inc,$parent,$set,depopulate,increment,init,overwrite,set].ReturnValue", // - "mongoose;Document;mongoose;Document;Member[delete,deleteOne].WithArity[0,1].ReturnValue.TypeVar[mongoose.QueryWithHelpers.1]", // - "mongoose;Document;mongoose;Document;Member[equals].Argument[0]", // - "mongoose;Document;mongoose;Document;Member[init].Argument[2].TypeVar[mongoose.Callback.0]", // - "mongoose;Document;mongoose;Document;Member[remove,save].WithArity[0,1].ReturnValue.Awaited", // - "mongoose;Document;mongoose;Document;Member[replaceOne,update,updateOne].ReturnValue.TypeVar[mongoose.Query.1]", // - "mongoose;Document;mongoose;Document;Member[save].Argument[1].TypeVar[mongoose.Callback.0]", // - "mongoose;Document;mongoose;Document;Member[save].WithArity[1].Argument[0].TypeVar[mongoose.Callback.0]", // - "mongoose;Document;mongoose;DocumentStatic;Instance", // - "mongoose;Document;mongoose;Error.VersionErrorStatic;Argument[0]", // - "mongoose;Document;mongoose;HydratedDocument;", // - "mongoose;Document;mongoose;HydratedDocument;TypeVar[mongoose.Require_id.0]", // - "mongoose;Document;mongoose;Model;Member[bulkSave].Argument[0].ArrayElement", // - "mongoose;Document;mongoose;TVirtualPathFN;Argument[2]", // - "mongoose;Document;mongoose;Types.Subdocument;", // - "mongoose;Document;mongoose;Types.Subdocument;Member[$parent,ownerDocument,parent].ReturnValue", // - "mongoose;Document;mongoose;VirtualType;Member[applyGetters,applySetters].Argument[1]", // - "mongoose;DocumentStatic;mongoose;;Member[Document]", // - "mongoose;Error.VersionErrorStatic;mongoose;;Member[Error].Member[VersionError]", // - "mongoose;HydratedDocument;mongoose;Model;Instance", // - "mongoose;HydratedDocument;mongoose;Model;Member[$where,count,countDocuments,deleteMany,deleteOne,distinct,estimatedDocumentCount,find,geoSearch,remove,replaceOne,update,updateMany,updateOne,where].ReturnValue.TypeVar[mongoose.QueryWithHelpers.1]", // - "mongoose;HydratedDocument;mongoose;Model;Member[$where,find,geoSearch,where].ReturnValue.TypeVar[mongoose.QueryWithHelpers.0].ArrayElement", // - "mongoose;HydratedDocument;mongoose;Model;Member[create,insertMany].WithArity[2].Argument[1].TypeVar[mongoose.Callback.0].ArrayElement", // - "mongoose;HydratedDocument;mongoose;Model;Member[create].WithArity[0..,1,2].ReturnValue.Awaited.ArrayElement", // - "mongoose;HydratedDocument;mongoose;Model;Member[create].WithArity[1].ReturnValue.Awaited", // - "mongoose;HydratedDocument;mongoose;Model;Member[create].WithArity[2].Argument[1].TypeVar[mongoose.Callback.0]", // - "mongoose;HydratedDocument;mongoose;Model;Member[exists].WithArity[1,2].ReturnValue.TypeVar[mongoose.QueryWithHelpers.1]", // - "mongoose;HydratedDocument;mongoose;Model;Member[find,insertMany].WithArity[3].Argument[2].TypeVar[mongoose.Callback.0].ArrayElement", // - "mongoose;HydratedDocument;mongoose;Model;Member[findById,findByIdAndDelete,findByIdAndRemove,findOne,findOneAndDelete,findOneAndRemove].ReturnValue.TypeVar[mongoose.QueryWithHelpers.0,mongoose.QueryWithHelpers.1]", // - "mongoose;HydratedDocument;mongoose;Model;Member[findById,findOne].Argument[3].TypeVar[mongoose.Callback.0]", // - "mongoose;HydratedDocument;mongoose;Model;Member[findByIdAndDelete,findByIdAndRemove,findOneAndDelete,findOneAndRemove].Argument[2].Argument[1]", // - "mongoose;HydratedDocument;mongoose;Model;Member[findByIdAndUpdate,findOneAndReplace,findOneAndUpdate].WithArity[0,1,2,3,4].ReturnValue.TypeVar[mongoose.QueryWithHelpers.0,mongoose.QueryWithHelpers.1]", // - "mongoose;HydratedDocument;mongoose;Model;Member[findByIdAndUpdate,findOneAndReplace,findOneAndUpdate].WithArity[3,4].ReturnValue.TypeVar[mongoose.QueryWithHelpers.0].TypeVar[mongoose.ModifyResult.0]", // - "mongoose;HydratedDocument;mongoose;Model;Member[findByIdAndUpdate].WithArity[0,1,2,4].Argument[3].Argument[1]", // - "mongoose;HydratedDocument;mongoose;Model;Member[findByIdAndUpdate].WithArity[3].Argument[2,3].Argument[1]", // - "mongoose;HydratedDocument;mongoose;Model;Member[findById].WithArity[1,2,3].Argument[2].TypeVar[mongoose.Callback.0]", // - "mongoose;HydratedDocument;mongoose;Model;Member[findOneAndReplace].WithArity[0,1,2,3,4].Argument[3].Argument[1]", // - "mongoose;HydratedDocument;mongoose;Model;Member[findOneAndUpdate].WithArity[3,4].Argument[3].Argument[1]", // - "mongoose;HydratedDocument;mongoose;Model;Member[findOne].WithArity[0,1,2].Argument[1,2].TypeVar[mongoose.Callback.0]", // - "mongoose;HydratedDocument;mongoose;Model;Member[findOne].WithArity[3].Argument[2].TypeVar[mongoose.Callback.0]", // - "mongoose;HydratedDocument;mongoose;Model;Member[find].Argument[3].TypeVar[mongoose.Callback.0].ArrayElement", // - "mongoose;HydratedDocument;mongoose;Model;Member[find].WithArity[0].Argument[0].TypeVar[mongoose.Callback.0].ArrayElement", // - "mongoose;HydratedDocument;mongoose;Model;Member[find].WithArity[1].Argument[0,1,2].TypeVar[mongoose.Callback.0].ArrayElement", // - "mongoose;HydratedDocument;mongoose;Model;Member[find].WithArity[2].Argument[1,2].TypeVar[mongoose.Callback.0].ArrayElement", // - "mongoose;HydratedDocument;mongoose;Model;Member[geoSearch].Argument[2].TypeVar[mongoose.Callback.0].ArrayElement", // - "mongoose;HydratedDocument;mongoose;Model;Member[hydrate].ReturnValue", // - "mongoose;HydratedDocument;mongoose;Model;Member[init].ReturnValue.Awaited", // - "mongoose;HydratedDocument;mongoose;Model;Member[insertMany].WithArity[1,2].ReturnValue.Awaited.ArrayElement", // - "mongoose;HydratedDocument;mongoose;Model;Member[populate].WithArity[2,3].Argument[2].TypeVar[mongoose.Callback.0]", // - "mongoose;HydratedDocument;mongoose;Model;Member[populate].WithArity[2,3].Argument[2].TypeVar[mongoose.Callback.0].ArrayElement", // - "mongoose;HydratedDocument;mongoose;Model;Member[populate].WithArity[2,3].ReturnValue.Awaited", // - "mongoose;HydratedDocument;mongoose;Model;Member[populate].WithArity[2,3].ReturnValue.Awaited.ArrayElement", // - "mongoose;HydratedDocument;mongoose;TVirtualPathFN;Argument[1].TypeVar[mongoose.VirtualType.0]", // - "mongoose;HydratedDocument;mongoose;VirtualPathFunctions;Member[options].TypeVar[mongoose.VirtualTypeOptions.0]", // - "mongoose;InsertManyOptions;mongoose;Model;Member[insertMany].WithArity[2,3].Argument[1]", // - "mongoose;Model;mongoose;;Member[Model]", // - "mongoose;Model;mongoose;;Member[model].ReturnValue", // - "mongoose;Model;mongoose;AcceptsDiscriminator;Member[discriminator].WithArity[2,3].ReturnValue", // - "mongoose;Model;mongoose;Aggregate;Member[model].Argument[0]", // - "mongoose;Model;mongoose;Connection;Member[model].WithArity[1,2,3,4].ReturnValue", // - "mongoose;Model;mongoose;Connection;Member[models].AnyMember", // - "mongoose;Model;mongoose;DiscriminatorModel;", // - "mongoose;Model;mongoose;Document;Member[$model].ReturnValue", // - "mongoose;Model;mongoose;Document;Member[populate].Argument[2]", // - "mongoose;Model;mongoose;Model;Member[discriminators].AnyMember", // - "mongoose;Model;mongoose;Models;AnyMember", // - "mongoose;Model;mongoose;PopulateOptions;Member[model]", // - "mongoose;Model;mongoose;Query;Member[cast].Argument[0]", // - "mongoose;Model;mongoose;Query;Member[populate].Argument[2]", // - "mongoose;Model;mongoose;Schema.Types.Array;Member[discriminator].WithArity[2,3].ReturnValue", // - "mongoose;Model;mongoose;Schema.Types.DocumentArray;Member[discriminator].WithArity[2,3].ReturnValue", // - "mongoose;Model;mongoose;Schema.Types.Subdocument;Member[discriminator].WithArity[2,3].ReturnValue", // - "mongoose;Model;mongoose;SchemaStatic;Instance.TypeVar[mongoose.Schema.1]", // - "mongoose;Models;mongoose;;Member[models]", // - "mongoose;PopulateOption;mongoose;InsertManyOptions;", // - "mongoose;PopulateOption;mongoose;QueryOptions;", // - "mongoose;PopulateOptions;mongoose;Document;Member[populate].Argument[4]", // - "mongoose;PopulateOptions;mongoose;Document;Member[populate].WithArity[1,2].Argument[0]", // - "mongoose;PopulateOptions;mongoose;Document;Member[populate].WithArity[1,2].Argument[0].ArrayElement", // - "mongoose;PopulateOptions;mongoose;Model;Member[populate].Argument[1]", // - "mongoose;PopulateOptions;mongoose;Model;Member[populate].Argument[1].ArrayElement", // - "mongoose;PopulateOptions;mongoose;PopulateOption;Member[populate]", // - "mongoose;PopulateOptions;mongoose;PopulateOption;Member[populate].ArrayElement", // - "mongoose;PopulateOptions;mongoose;PopulateOptions;Member[populate]", // - "mongoose;PopulateOptions;mongoose;PopulateOptions;Member[populate].ArrayElement", // - "mongoose;PopulateOptions;mongoose;Query;Member[populate].WithArity[1].Argument[0]", // - "mongoose;PopulateOptions;mongoose;Query;Member[populate].WithArity[1].Argument[0].ArrayElement", // - "mongoose;Query;mongoose;Document;Member[replaceOne,update,updateOne].ReturnValue", // - "mongoose;Query;mongoose;HydratedDocument;TypeVar[mongoose.Require_id.0]", // - "mongoose;Query;mongoose;Query;Member[all,allowDiskUse,and,batchSize,box,circle,clone,collation,comment,elemMatch,equals,exists,explain,geometry,gt,gte,hint,in,intersects,j,limit,lt,lte,maxDistance,maxScan,maxTimeMS,merge,mod,ne,near,nin,nor,or,polygon,read,readConcern,regex,remove,select,session,set,setOptions,size,skip,slice,snapshot,sort,tailable,w,where,within,wtimeout].ReturnValue", // - "mongoose;Query;mongoose;Query;Member[error].WithArity[1].ReturnValue", // - "mongoose;Query;mongoose;Query;Member[merge].Argument[0]", // - "mongoose;Query;mongoose;QueryStatic;Instance", // - "mongoose;Query;mongoose;QueryWithHelpers;", // - "mongoose;QueryOptions;mongoose;Document;Member[delete,deleteOne,remove].WithArity[0,1,2].Argument[0]", // - "mongoose;QueryOptions;mongoose;Document;Member[replaceOne,update,updateOne].Argument[1]", // - "mongoose;QueryOptions;mongoose;Model;Member[countDocuments,findByIdAndDelete,findByIdAndRemove,findOneAndDelete,findOneAndRemove].Argument[1]", // - "mongoose;QueryOptions;mongoose;Model;Member[deleteMany,deleteOne].WithArity[0,1,2,3].Argument[1]", // - "mongoose;QueryOptions;mongoose;Model;Member[estimatedDocumentCount].Argument[0]", // - "mongoose;QueryOptions;mongoose;Model;Member[find,findById].WithArity[1,2,3,4].Argument[2]", // - "mongoose;QueryOptions;mongoose;Model;Member[findByIdAndUpdate,findOne,findOneAndReplace,findOneAndUpdate].WithArity[0,1,2,3,4].Argument[2]", // - "mongoose;QueryOptions;mongoose;Model;Member[replaceOne,update,updateMany,updateOne].Argument[2]", // - "mongoose;QueryOptions;mongoose;PopulateOptions;Member[options]", // - "mongoose;QueryOptions;mongoose;Query;Member[countDocuments,findByIdAndDelete,findOneAndDelete,findOneAndRemove].Argument[1]", // - "mongoose;QueryOptions;mongoose;Query;Member[cursor,estimatedDocumentCount,setOptions].Argument[0]", // - "mongoose;QueryOptions;mongoose;Query;Member[cursor].ReturnValue.TypeVar[mongoose.Cursor.1]", // - "mongoose;QueryOptions;mongoose;Query;Member[deleteMany,deleteOne].WithArity[0,1,2,3].Argument[1]", // - "mongoose;QueryOptions;mongoose;Query;Member[findByIdAndUpdate,findOne,findOneAndUpdate].WithArity[0,1,2,3,4].Argument[2]", // - "mongoose;QueryOptions;mongoose;Query;Member[find].WithArity[1,2,3,4].Argument[2]", // - "mongoose;QueryOptions;mongoose;Query;Member[getOptions].ReturnValue", // - "mongoose;QueryOptions;mongoose;Query;Member[replaceOne,update,updateMany,updateOne].Argument[2]", // - "mongoose;QueryOptions;mongoose;VirtualTypeOptions;Member[options]", // - "mongoose;QueryStatic;mongoose;;Member[Query]", // - "mongoose;QueryWithHelpers;mongoose;Document;Member[delete,deleteOne].WithArity[0,1].ReturnValue", // - "mongoose;QueryWithHelpers;mongoose;Model;Member[$where,count,countDocuments,deleteMany,deleteOne,distinct,estimatedDocumentCount,find,findById,findByIdAndDelete,findByIdAndRemove,findOne,findOneAndDelete,findOneAndRemove,geoSearch,remove,replaceOne,update,updateMany,updateOne,where].ReturnValue", // - "mongoose;QueryWithHelpers;mongoose;Model;Member[exists].WithArity[1,2].ReturnValue", // - "mongoose;QueryWithHelpers;mongoose;Model;Member[findByIdAndUpdate,findOneAndReplace,findOneAndUpdate].WithArity[0,1,2,3,4].ReturnValue", // - "mongoose;QueryWithHelpers;mongoose;Query;Member[$where,count,countDocuments,deleteMany,deleteOne,distinct,estimatedDocumentCount,find,findByIdAndDelete,findOne,findOneAndDelete,findOneAndRemove,lean,orFail,populate,replaceOne,transform,update,updateMany,updateOne].ReturnValue", // - "mongoose;QueryWithHelpers;mongoose;Query;Member[findByIdAndUpdate,findOneAndUpdate].WithArity[0,1,2,3,4].ReturnValue", // - "mongoose;QueryWithHelpers;mongoose;Query;Member[toConstructor].ReturnValue.Instance", // - "mongoose;Schema.Types.Array;mongoose;Schema.Types.Array;Member[enum].ReturnValue", // - "mongoose;Schema.Types.Array;mongoose;Schema.Types.ArrayStatic;Instance", // - "mongoose;Schema.Types.ArrayStatic;mongoose;;Member[Schema].Member[Types].Member[Array]", // - "mongoose;Schema.Types.DocumentArray;mongoose;Schema.Types.DocumentArrayStatic;Instance", // - "mongoose;Schema.Types.DocumentArrayStatic;mongoose;;Member[Schema].Member[Types].Member[DocumentArray]", // - "mongoose;Schema.Types.Subdocument;mongoose;Schema.Types.SubdocumentStatic;Instance", // - "mongoose;Schema.Types.SubdocumentStatic;mongoose;;Member[Schema].Member[Types].Member[Subdocument]", // - "mongoose;Schema.Types.SubdocumentStatic;mongoose;Schema.Types.DocumentArray;Member[caster]", // - "mongoose;SchemaStatic;mongoose;;Member[Schema]", // - "mongoose;SessionOperation;mongoose;Aggregate;", // - "mongoose;SessionOperation;mongoose;Query;", // - "mongoose;TVirtualPathFN;mongoose;VirtualPathFunctions;Member[get,set]", // - "mongoose;Types.Array;mongoose;Types.DocumentArray;", // - "mongoose;Types.ArraySubdocument;mongoose;Types.ArraySubdocumentStatic;Instance", // - "mongoose;Types.ArraySubdocumentStatic;mongoose;;Member[Types].Member[ArraySubdocument]", // - "mongoose;Types.DocumentArray;mongoose/inferschematype;ResolvePathType;TypeVar[mongoose.IfEquals.3]", // - "mongoose;Types.DocumentArray;mongoose;Types.ArraySubdocument;Member[parentArray].ReturnValue", // - "mongoose;Types.DocumentArray;mongoose;Types.DocumentArrayStatic;Instance", // - "mongoose;Types.DocumentArrayStatic;mongoose;;Member[Types].Member[DocumentArray]", // - "mongoose;Types.ObjectId;mongoose/inferschematype;ResolvePathType;", // - "mongoose;Types.Subdocument;mongoose;Types.ArraySubdocument;", // - "mongoose;Types.Subdocument;mongoose;Types.DocumentArray;Member[create,id].ReturnValue", // - "mongoose;Types.Subdocument;mongoose;Types.DocumentArray;TypeVar[mongoose.Types.Array.0]", // - "mongoose;Types.Subdocument;mongoose;Types.SubdocumentStatic;Instance", // - "mongoose;Types.SubdocumentStatic;mongoose;;Member[Types].Member[Subdocument]", // - "mongoose;VirtualType;mongoose;TVirtualPathFN;Argument[1]", // - "mongoose;VirtualType;mongoose;VirtualType;Member[get,set].Argument[0].Argument[1]", // - "mongoose;VirtualType;mongoose;VirtualType;Member[get,set].ReturnValue", // - "mongoose;VirtualType;mongoose;VirtualTypeStatic;Instance", // - "mongoose;VirtualTypeOptions;mongoose;VirtualPathFunctions;Member[options]", // - "mongoose;VirtualTypeStatic;mongoose;;Member[VirtualType]", // + "mongodb.AbstractCursor;mongodb.FindCursor;", // + "mongodb.AbstractCursor;mongodb.ListCollectionsCursor;", // + "mongodb.AbstractCursor;mongodb.ListIndexesCursor;", // + "mongodb.AbstractCursorOptions;mongodb.AggregationCursorOptions;", // + "mongodb.AbstractCursorOptions;mongodb/mongodb.AbstractCursorOptions;", // + "mongodb.AbstractCursorOptions;mongoose.mongodb.AbstractCursorOptions;", // + "mongodb.AddUserOptions;mongodb.Admin;Member[addUser].Argument[1,2]", // + "mongodb.AddUserOptions;mongodb.Db;Member[addUser].Argument[1,2]", // + "mongodb.AddUserOptions;mongodb/mongodb.AddUserOptions;", // + "mongodb.AddUserOptions;mongoose.mongodb.AddUserOptions;", // + "mongodb.Admin;mongodb.AdminStatic;Instance", // + "mongodb.Admin;mongodb.Db;Member[admin].ReturnValue", // + "mongodb.Admin;mongodb/mongodb.Admin;", // + "mongodb.Admin;mongoose.mongodb.Admin;", // + "mongodb.AdminStatic;mongodb/mongodb.AdminStatic;", // + "mongodb.AdminStatic;mongodb;Member[Admin]", // + "mongodb.AdminStatic;mongoose.mongodb.AdminStatic;", // + "mongodb.AggregateOptions;mongodb.AggregationCursorOptions;", // + "mongodb.AggregateOptions;mongodb.ChangeStreamOptions;", // + "mongodb.AggregateOptions;mongodb.Collection;Member[aggregate].Argument[1]", // + "mongodb.AggregateOptions;mongodb.CountDocumentsOptions;", // + "mongodb.AggregateOptions;mongodb.Db;Member[aggregate].Argument[1]", // + "mongodb.AggregateOptions;mongodb/mongodb.AggregateOptions;", // + "mongodb.AggregateOptions;mongoose.mongodb.AggregateOptions;", // + "mongodb.AggregationCursorOptions;mongodb/mongodb.AggregationCursorOptions;", // + "mongodb.AggregationCursorOptions;mongoose.mongodb.AggregationCursorOptions;", // + "mongodb.AnyBulkWriteOperation;mongodb.BulkOperationBase;Member[raw].Argument[0]", // + "mongodb.AnyBulkWriteOperation;mongodb.Collection;Member[bulkWrite].Argument[0].ArrayElement", // + "mongodb.AnyBulkWriteOperation;mongodb/mongodb.AnyBulkWriteOperation;", // + "mongodb.AnyBulkWriteOperation;mongoose.mongodb.AnyBulkWriteOperation;", // + "mongodb.Auth;mongodb.MongoClientOptions;Member[auth]", // + "mongodb.Auth;mongodb/mongodb.Auth;", // + "mongodb.Auth;mongoose.mongodb.Auth;", // + "mongodb.AutoEncrypter;mongodb.AutoEncrypter;Instance", // + "mongodb.AutoEncrypter;mongodb.ConnectionOptions;Member[autoEncrypter]", // + "mongodb.AutoEncrypter;mongodb.MongoClient;Member[autoEncrypter]", // + "mongodb.AutoEncrypter;mongodb.MongoOptions;Member[autoEncrypter]", // + "mongodb.AutoEncrypter;mongodb/mongodb.AutoEncrypter;", // + "mongodb.AutoEncrypter;mongoose.mongodb.AutoEncrypter;", // + "mongodb.AutoEncryptionOptions;mongodb.AutoEncrypter;Argument[1]", // + "mongodb.AutoEncryptionOptions;mongodb.MongoClientOptions;Member[autoEncryption]", // + "mongodb.AutoEncryptionOptions;mongodb/mongodb.AutoEncryptionOptions;", // + "mongodb.AutoEncryptionOptions;mongoose.mongodb.AutoEncryptionOptions;", // + "mongodb.BulkOperationBase;mongodb.BulkOperationBase;Member[addToOperationsList,insert,raw].ReturnValue", // + "mongodb.BulkOperationBase;mongodb.BulkOperationBaseStatic;Instance", // + "mongodb.BulkOperationBase;mongodb.FindOperators;Member[bulkOperation]", // + "mongodb.BulkOperationBase;mongodb.FindOperators;Member[delete,deleteOne,replaceOne,update,updateOne].ReturnValue", // + "mongodb.BulkOperationBase;mongodb.OrderedBulkOperation;", // + "mongodb.BulkOperationBase;mongodb.UnorderedBulkOperation;", // + "mongodb.BulkOperationBase;mongodb/mongodb.BulkOperationBase;", // + "mongodb.BulkOperationBase;mongoose.mongodb.BulkOperationBase;", // + "mongodb.BulkOperationBaseStatic;mongodb/mongodb.BulkOperationBaseStatic;", // + "mongodb.BulkOperationBaseStatic;mongodb;Member[BulkOperationBase]", // + "mongodb.BulkOperationBaseStatic;mongoose.mongodb.BulkOperationBaseStatic;", // + "mongodb.BulkWriteOptions;mongodb.BulkOperationBase;Member[execute].WithArity[0,1,2].Argument[0]", // + "mongodb.BulkWriteOptions;mongodb.Collection;Member[bulkWrite,insert,insertMany].Argument[1]", // + "mongodb.BulkWriteOptions;mongodb.Collection;Member[initializeOrderedBulkOp,initializeUnorderedBulkOp].Argument[0]", // + "mongodb.BulkWriteOptions;mongodb.OrderedBulkOperationStatic;Argument[1]", // + "mongodb.BulkWriteOptions;mongodb.UnorderedBulkOperationStatic;Argument[1]", // + "mongodb.BulkWriteOptions;mongodb/mongodb.BulkWriteOptions;", // + "mongodb.BulkWriteOptions;mongoose.mongodb.BulkWriteOptions;", // + "mongodb.ChangeStream;mongodb.ChangeStreamStatic;Instance", // + "mongodb.ChangeStream;mongodb.Collection;Member[watch].ReturnValue", // + "mongodb.ChangeStream;mongodb.Db;Member[watch].ReturnValue", // + "mongodb.ChangeStream;mongodb.MongoClient;Member[watch].ReturnValue", // + "mongodb.ChangeStream;mongodb/mongodb.ChangeStream;", // + "mongodb.ChangeStream;mongoose.mongodb.ChangeStream;", // + "mongodb.ChangeStreamOptions;mongodb.ChangeStream;Member[options]", // + "mongodb.ChangeStreamOptions;mongodb.Collection;Member[watch].Argument[1]", // + "mongodb.ChangeStreamOptions;mongodb.Db;Member[watch].Argument[1]", // + "mongodb.ChangeStreamOptions;mongodb.MongoClient;Member[watch].Argument[1]", // + "mongodb.ChangeStreamOptions;mongodb/mongodb.ChangeStreamOptions;", // + "mongodb.ChangeStreamOptions;mongoose.mongodb.ChangeStreamOptions;", // + "mongodb.ChangeStreamStatic;mongodb/mongodb.ChangeStreamStatic;", // + "mongodb.ChangeStreamStatic;mongodb;Member[ChangeStream]", // + "mongodb.ChangeStreamStatic;mongoose.mongodb.ChangeStreamStatic;", // + "mongodb.ClientSession;mongodb.AbstractCursorOptions;Member[session]", // + "mongodb.ClientSession;mongodb.ClientSession;Member[equals].Argument[0]", // + "mongodb.ClientSession;mongodb.ClientSessionEvents;Member[ended].Argument[0]", // + "mongodb.ClientSession;mongodb.ClientSessionStatic;Instance", // + "mongodb.ClientSession;mongodb.IndexInformationOptions;Member[session]", // + "mongodb.ClientSession;mongodb.MongoClient;Member[startSession].ReturnValue", // + "mongodb.ClientSession;mongodb.OperationOptions;Member[session]", // + "mongodb.ClientSession;mongodb.ReadPreferenceFromOptions;Member[session]", // + "mongodb.ClientSession;mongodb.SelectServerOptions;Member[session]", // + "mongodb.ClientSession;mongodb.WithSessionCallback;Argument[0]", // + "mongodb.ClientSession;mongodb.WithTransactionCallback;Argument[0]", // + "mongodb.ClientSession;mongodb/mongodb.ClientSession;", // + "mongodb.ClientSession;mongoose.mongodb.ClientSession;", // + "mongodb.ClientSessionEvents;mongodb/mongodb.ClientSessionEvents;", // + "mongodb.ClientSessionEvents;mongoose.mongodb.ClientSessionEvents;", // + "mongodb.ClientSessionOptions;mongodb.MongoClient;Member[startSession].Argument[0]", // + "mongodb.ClientSessionOptions;mongodb.MongoClient;Member[withSession].WithArity[2].Argument[0]", // + "mongodb.ClientSessionOptions;mongodb/mongodb.ClientSessionOptions;", // + "mongodb.ClientSessionOptions;mongoose.mongodb.ClientSessionOptions;", // + "mongodb.ClientSessionStatic;mongodb/mongodb.ClientSessionStatic;", // + "mongodb.ClientSessionStatic;mongodb;Member[ClientSession]", // + "mongodb.ClientSessionStatic;mongoose.mongodb.ClientSessionStatic;", // + "mongodb.CollStatsOptions;mongodb.Collection;Member[stats].Argument[0]", // + "mongodb.CollStatsOptions;mongodb/mongodb.CollStatsOptions;", // + "mongodb.CollStatsOptions;mongoose.mongodb.CollStatsOptions;", // + "mongodb.Collection;mongodb.ChangeStream;Member[parent]", // + "mongodb.Collection;mongodb.Collection;Member[rename].Argument[1,2].TypeVar[mongodb.Callback.0]", // + "mongodb.Collection;mongodb.Collection;Member[rename].WithArity[1,2].ReturnValue.Awaited", // + "mongodb.Collection;mongodb.CollectionStatic;Instance", // + "mongodb.Collection;mongodb.Db;Member[collection].ReturnValue", // + "mongodb.Collection;mongodb.Db;Member[collections].Argument[0,1].TypeVar[mongodb.Callback.0].ArrayElement", // + "mongodb.Collection;mongodb.Db;Member[collections].WithArity[0,1].ReturnValue.Awaited.ArrayElement", // + "mongodb.Collection;mongodb.Db;Member[createCollection].Argument[2].TypeVar[mongodb.Callback.0]", // + "mongodb.Collection;mongodb.Db;Member[createCollection].WithArity[1,2].ReturnValue.Awaited", // + "mongodb.Collection;mongodb.Db;Member[createCollection].WithArity[2].Argument[1].TypeVar[mongodb.Callback.0]", // + "mongodb.Collection;mongodb.Db;Member[renameCollection].Argument[2,3].TypeVar[mongodb.Callback.0]", // + "mongodb.Collection;mongodb.Db;Member[renameCollection].WithArity[2,3].ReturnValue.Awaited", // + "mongodb.Collection;mongodb.GridFSBucketWriteStream;Member[chunks,files]", // + "mongodb.Collection;mongodb.ListIndexesCursor;Member[parent]", // + "mongodb.Collection;mongodb.ListIndexesCursorStatic;Argument[0]", // + "mongodb.Collection;mongodb.OrderedBulkOperationStatic;Argument[0]", // + "mongodb.Collection;mongodb.UnorderedBulkOperationStatic;Argument[0]", // + "mongodb.Collection;mongodb/mongodb.Collection;", // + "mongodb.Collection;mongoose.mongodb.Collection;", // + "mongodb.CollectionStatic;mongodb/mongodb.CollectionStatic;", // + "mongodb.CollectionStatic;mongodb;Member[Collection]", // + "mongodb.CollectionStatic;mongoose.mongodb.CollectionStatic;", // + "mongodb.CommandOperationOptions;mongodb.AddUserOptions;", // + "mongodb.CommandOperationOptions;mongodb.Admin;Member[buildInfo,ping,replSetGetStatus,serverInfo,serverStatus].Argument[0]", // + "mongodb.CommandOperationOptions;mongodb.AggregateOptions;", // + "mongodb.CommandOperationOptions;mongodb.BulkWriteOptions;", // + "mongodb.CommandOperationOptions;mongodb.CollStatsOptions;", // + "mongodb.CommandOperationOptions;mongodb.CountOptions;", // + "mongodb.CommandOperationOptions;mongodb.CreateCollectionOptions;", // + "mongodb.CommandOperationOptions;mongodb.CreateIndexesOptions;", // + "mongodb.CommandOperationOptions;mongodb.DbStatsOptions;", // + "mongodb.CommandOperationOptions;mongodb.DeleteOptions;", // + "mongodb.CommandOperationOptions;mongodb.DistinctOptions;", // + "mongodb.CommandOperationOptions;mongodb.DropCollectionOptions;", // + "mongodb.CommandOperationOptions;mongodb.DropDatabaseOptions;", // + "mongodb.CommandOperationOptions;mongodb.DropIndexesOptions;", // + "mongodb.CommandOperationOptions;mongodb.EstimatedDocumentCountOptions;", // + "mongodb.CommandOperationOptions;mongodb.EvalOptions;", // + "mongodb.CommandOperationOptions;mongodb.FindOneAndDeleteOptions;", // + "mongodb.CommandOperationOptions;mongodb.FindOneAndReplaceOptions;", // + "mongodb.CommandOperationOptions;mongodb.FindOneAndUpdateOptions;", // + "mongodb.CommandOperationOptions;mongodb.FindOptions;", // + "mongodb.CommandOperationOptions;mongodb.InsertOneOptions;", // + "mongodb.CommandOperationOptions;mongodb.ListCollectionsOptions;", // + "mongodb.CommandOperationOptions;mongodb.ListDatabasesOptions;", // + "mongodb.CommandOperationOptions;mongodb.ListIndexesOptions;", // + "mongodb.CommandOperationOptions;mongodb.MapReduceOptions;", // + "mongodb.CommandOperationOptions;mongodb.ProfilingLevelOptions;", // + "mongodb.CommandOperationOptions;mongodb.RemoveUserOptions;", // + "mongodb.CommandOperationOptions;mongodb.RenameOptions;", // + "mongodb.CommandOperationOptions;mongodb.ReplaceOptions;", // + "mongodb.CommandOperationOptions;mongodb.RunCommandOptions;", // + "mongodb.CommandOperationOptions;mongodb.SetProfilingLevelOptions;", // + "mongodb.CommandOperationOptions;mongodb.TransactionOptions;", // + "mongodb.CommandOperationOptions;mongodb.UpdateOptions;", // + "mongodb.CommandOperationOptions;mongodb.ValidateCollectionOptions;", // + "mongodb.CommandOperationOptions;mongodb/mongodb.CommandOperationOptions;", // + "mongodb.CommandOperationOptions;mongoose.mongodb.CommandOperationOptions;", // + "mongodb.ConnectionOptions;mongodb/mongodb.ConnectionOptions;", // + "mongodb.ConnectionOptions;mongoose.mongodb.ConnectionOptions;", // + "mongodb.CountDocumentsOptions;mongodb.Collection;Member[countDocuments].Argument[1]", // + "mongodb.CountDocumentsOptions;mongodb/mongodb.CountDocumentsOptions;", // + "mongodb.CountDocumentsOptions;mongoose.mongodb.CountDocumentsOptions;", // + "mongodb.CountOptions;mongodb.Collection;Member[count].Argument[1]", // + "mongodb.CountOptions;mongodb.FindCursor;Member[count].Argument[0]", // + "mongodb.CountOptions;mongodb/mongodb.CountOptions;", // + "mongodb.CountOptions;mongoose.mongodb.CountOptions;", // + "mongodb.CreateCollectionOptions;mongodb.Db;Member[createCollection].WithArity[1,2,3].Argument[1]", // + "mongodb.CreateCollectionOptions;mongodb/mongodb.CreateCollectionOptions;", // + "mongodb.CreateCollectionOptions;mongoose.mongodb.CreateCollectionOptions;", // + "mongodb.CreateIndexesOptions;mongodb.Collection;Member[createIndex,createIndexes].Argument[1]", // + "mongodb.CreateIndexesOptions;mongodb.Db;Member[createIndex].Argument[2]", // + "mongodb.CreateIndexesOptions;mongodb/mongodb.CreateIndexesOptions;", // + "mongodb.CreateIndexesOptions;mongoose.mongodb.CreateIndexesOptions;", // + "mongodb.Db;mongodb.ChangeStream;Member[parent]", // + "mongodb.Db;mongodb.DbStatic;Instance", // + "mongodb.Db;mongodb.GridFSBucketStatic;Argument[0]", // + "mongodb.Db;mongodb.ListCollectionsCursor;Member[parent]", // + "mongodb.Db;mongodb.ListCollectionsCursorStatic;Argument[0]", // + "mongodb.Db;mongodb.MongoClient;Member[db].ReturnValue", // + "mongodb.Db;mongodb/mongodb.Db;", // + "mongodb.Db;mongoose.mongodb.Db;", // + "mongodb.DbStatic;mongodb/mongodb.DbStatic;", // + "mongodb.DbStatic;mongodb;Member[Db]", // + "mongodb.DbStatic;mongoose.mongodb.DbStatic;", // + "mongodb.DbStatsOptions;mongodb.Db;Member[stats].Argument[0]", // + "mongodb.DbStatsOptions;mongodb/mongodb.DbStatsOptions;", // + "mongodb.DbStatsOptions;mongoose.mongodb.DbStatsOptions;", // + "mongodb.DeleteManyModel;mongodb.AnyBulkWriteOperation;Member[deleteMany]", // + "mongodb.DeleteManyModel;mongodb/mongodb.DeleteManyModel;", // + "mongodb.DeleteManyModel;mongoose.mongodb.DeleteManyModel;", // + "mongodb.DeleteOneModel;mongodb.AnyBulkWriteOperation;Member[deleteOne]", // + "mongodb.DeleteOneModel;mongodb/mongodb.DeleteOneModel;", // + "mongodb.DeleteOneModel;mongoose.mongodb.DeleteOneModel;", // + "mongodb.DeleteOptions;mongodb.Collection;Member[deleteMany,deleteOne,remove].Argument[1]", // + "mongodb.DeleteOptions;mongodb/mongodb.DeleteOptions;", // + "mongodb.DeleteOptions;mongoose.mongodb.DeleteOptions;", // + "mongodb.DistinctOptions;mongodb.Collection;Member[distinct].Argument[2]", // + "mongodb.DistinctOptions;mongodb/mongodb.DistinctOptions;", // + "mongodb.DistinctOptions;mongoose.mongodb.DistinctOptions;", // + "mongodb.DropCollectionOptions;mongodb.Collection;Member[drop].Argument[0]", // + "mongodb.DropCollectionOptions;mongodb.Db;Member[dropCollection].Argument[1]", // + "mongodb.DropCollectionOptions;mongodb/mongodb.DropCollectionOptions;", // + "mongodb.DropCollectionOptions;mongoose.mongodb.DropCollectionOptions;", // + "mongodb.DropDatabaseOptions;mongodb.Db;Member[dropDatabase].Argument[0]", // + "mongodb.DropDatabaseOptions;mongodb/mongodb.DropDatabaseOptions;", // + "mongodb.DropDatabaseOptions;mongoose.mongodb.DropDatabaseOptions;", // + "mongodb.DropIndexesOptions;mongodb.Collection;Member[dropIndex].Argument[1]", // + "mongodb.DropIndexesOptions;mongodb.Collection;Member[dropIndexes].Argument[0]", // + "mongodb.DropIndexesOptions;mongodb/mongodb.DropIndexesOptions;", // + "mongodb.DropIndexesOptions;mongoose.mongodb.DropIndexesOptions;", // + "mongodb.EstimatedDocumentCountOptions;mongodb.Collection;Member[estimatedDocumentCount].Argument[0]", // + "mongodb.EstimatedDocumentCountOptions;mongodb/mongodb.EstimatedDocumentCountOptions;", // + "mongodb.EstimatedDocumentCountOptions;mongoose.mongodb.EstimatedDocumentCountOptions;", // + "mongodb.EvalOptions;mongodb/mongodb.EvalOptions;", // + "mongodb.EvalOptions;mongoose.mongodb.EvalOptions;", // + "mongodb.FindCursor;mongodb.Collection;Member[find].WithArity[0,1,2].ReturnValue", // + "mongodb.FindCursor;mongodb.FindCursor;Member[addQueryModifier,allowDiskUse,clone,collation,comment,filter,hint,limit,map,max,maxAwaitTimeMS,maxTimeMS,min,project,returnKey,showRecordId,skip,sort].ReturnValue", // + "mongodb.FindCursor;mongodb.FindCursorStatic;Instance", // + "mongodb.FindCursor;mongodb.GridFSBucket;Member[find].ReturnValue", // + "mongodb.FindCursor;mongodb/mongodb.FindCursor;", // + "mongodb.FindCursor;mongoose.mongodb.FindCursor;", // + "mongodb.FindCursorStatic;mongodb/mongodb.FindCursorStatic;", // + "mongodb.FindCursorStatic;mongodb;Member[FindCursor]", // + "mongodb.FindCursorStatic;mongoose.mongodb.FindCursorStatic;", // + "mongodb.FindOneAndDeleteOptions;mongodb.Collection;Member[findOneAndDelete].Argument[1]", // + "mongodb.FindOneAndDeleteOptions;mongodb/mongodb.FindOneAndDeleteOptions;", // + "mongodb.FindOneAndDeleteOptions;mongoose.mongodb.FindOneAndDeleteOptions;", // + "mongodb.FindOneAndReplaceOptions;mongodb.Collection;Member[findOneAndReplace].Argument[2]", // + "mongodb.FindOneAndReplaceOptions;mongodb/mongodb.FindOneAndReplaceOptions;", // + "mongodb.FindOneAndReplaceOptions;mongoose.mongodb.FindOneAndReplaceOptions;", // + "mongodb.FindOneAndUpdateOptions;mongodb.Collection;Member[findOneAndUpdate].Argument[2]", // + "mongodb.FindOneAndUpdateOptions;mongodb/mongodb.FindOneAndUpdateOptions;", // + "mongodb.FindOneAndUpdateOptions;mongoose.mongodb.FindOneAndUpdateOptions;", // + "mongodb.FindOperators;mongodb.BulkOperationBase;Member[find].ReturnValue", // + "mongodb.FindOperators;mongodb.FindOperators;Member[arrayFilters,collation,upsert].ReturnValue", // + "mongodb.FindOperators;mongodb.FindOperatorsStatic;Instance", // + "mongodb.FindOperators;mongodb/mongodb.FindOperators;", // + "mongodb.FindOperators;mongoose.mongodb.FindOperators;", // + "mongodb.FindOperatorsStatic;mongodb/mongodb.FindOperatorsStatic;", // + "mongodb.FindOperatorsStatic;mongodb;Member[FindOperators]", // + "mongodb.FindOperatorsStatic;mongoose.mongodb.FindOperatorsStatic;", // + "mongodb.FindOptions;mongodb.Collection;Member[find,findOne].Argument[1]", // + "mongodb.FindOptions;mongodb.GridFSBucket;Member[find].Argument[1]", // + "mongodb.FindOptions;mongodb/mongodb.FindOptions;", // + "mongodb.FindOptions;mongoose.mongodb.FindOptions;", // + "mongodb.GridFSBucket;mongodb.GridFSBucketStatic;Instance", // + "mongodb.GridFSBucket;mongodb.GridFSBucketWriteStream;Member[bucket]", // + "mongodb.GridFSBucket;mongodb/mongodb.GridFSBucket;", // + "mongodb.GridFSBucket;mongoose.mongodb.GridFSBucket;", // + "mongodb.GridFSBucketStatic;mongodb/mongodb.GridFSBucketStatic;", // + "mongodb.GridFSBucketStatic;mongodb;Member[GridFSBucket]", // + "mongodb.GridFSBucketStatic;mongoose.mongodb.GridFSBucketStatic;", // + "mongodb.GridFSBucketWriteStream;mongodb.GridFSBucket;Member[openUploadStream,openUploadStreamWithId].ReturnValue", // + "mongodb.GridFSBucketWriteStream;mongodb.GridFSBucketWriteStream;Member[end].ReturnValue", // + "mongodb.GridFSBucketWriteStream;mongodb.GridFSBucketWriteStreamStatic;Instance", // + "mongodb.GridFSBucketWriteStream;mongodb/mongodb.GridFSBucketWriteStream;", // + "mongodb.GridFSBucketWriteStream;mongoose.mongodb.GridFSBucketWriteStream;", // + "mongodb.GridFSBucketWriteStreamStatic;mongodb/mongodb.GridFSBucketWriteStreamStatic;", // + "mongodb.GridFSBucketWriteStreamStatic;mongodb;Member[GridFSBucketWriteStream]", // + "mongodb.GridFSBucketWriteStreamStatic;mongoose.mongodb.GridFSBucketWriteStreamStatic;", // + "mongodb.IndexInformationOptions;mongodb.Collection;Member[indexExists].Argument[1]", // + "mongodb.IndexInformationOptions;mongodb.Collection;Member[indexInformation,indexes].Argument[0]", // + "mongodb.IndexInformationOptions;mongodb.Db;Member[indexInformation].Argument[1]", // + "mongodb.IndexInformationOptions;mongodb/mongodb.IndexInformationOptions;", // + "mongodb.IndexInformationOptions;mongoose.mongodb.IndexInformationOptions;", // + "mongodb.InsertOneOptions;mongodb.Collection;Member[insertOne].Argument[1]", // + "mongodb.InsertOneOptions;mongodb/mongodb.InsertOneOptions;", // + "mongodb.InsertOneOptions;mongoose.mongodb.InsertOneOptions;", // + "mongodb.ListCollectionsCursor;mongodb.Db;Member[listCollections].WithArity[0,1,2].ReturnValue", // + "mongodb.ListCollectionsCursor;mongodb.ListCollectionsCursor;Member[clone].ReturnValue", // + "mongodb.ListCollectionsCursor;mongodb.ListCollectionsCursorStatic;Instance", // + "mongodb.ListCollectionsCursor;mongodb/mongodb.ListCollectionsCursor;", // + "mongodb.ListCollectionsCursor;mongoose.mongodb.ListCollectionsCursor;", // + "mongodb.ListCollectionsCursorStatic;mongodb/mongodb.ListCollectionsCursorStatic;", // + "mongodb.ListCollectionsCursorStatic;mongodb;Member[ListCollectionsCursor]", // + "mongodb.ListCollectionsCursorStatic;mongoose.mongodb.ListCollectionsCursorStatic;", // + "mongodb.ListCollectionsOptions;mongodb.Db;Member[collections].Argument[0]", // + "mongodb.ListCollectionsOptions;mongodb.Db;Member[listCollections].WithArity[0,1,2].Argument[1]", // + "mongodb.ListCollectionsOptions;mongodb.ListCollectionsCursor;Member[options]", // + "mongodb.ListCollectionsOptions;mongodb.ListCollectionsCursorStatic;Argument[2]", // + "mongodb.ListCollectionsOptions;mongodb/mongodb.ListCollectionsOptions;", // + "mongodb.ListCollectionsOptions;mongoose.mongodb.ListCollectionsOptions;", // + "mongodb.ListDatabasesOptions;mongodb.Admin;Member[listDatabases].Argument[0]", // + "mongodb.ListDatabasesOptions;mongodb/mongodb.ListDatabasesOptions;", // + "mongodb.ListDatabasesOptions;mongoose.mongodb.ListDatabasesOptions;", // + "mongodb.ListIndexesCursor;mongodb.Collection;Member[listIndexes].ReturnValue", // + "mongodb.ListIndexesCursor;mongodb.ListIndexesCursor;Member[clone].ReturnValue", // + "mongodb.ListIndexesCursor;mongodb.ListIndexesCursorStatic;Instance", // + "mongodb.ListIndexesCursor;mongodb/mongodb.ListIndexesCursor;", // + "mongodb.ListIndexesCursor;mongoose.mongodb.ListIndexesCursor;", // + "mongodb.ListIndexesCursorStatic;mongodb/mongodb.ListIndexesCursorStatic;", // + "mongodb.ListIndexesCursorStatic;mongodb;Member[ListIndexesCursor]", // + "mongodb.ListIndexesCursorStatic;mongoose.mongodb.ListIndexesCursorStatic;", // + "mongodb.ListIndexesOptions;mongodb.Collection;Member[listIndexes].Argument[0]", // + "mongodb.ListIndexesOptions;mongodb.ListIndexesCursor;Member[options]", // + "mongodb.ListIndexesOptions;mongodb.ListIndexesCursorStatic;Argument[1]", // + "mongodb.ListIndexesOptions;mongodb/mongodb.ListIndexesOptions;", // + "mongodb.ListIndexesOptions;mongoose.mongodb.ListIndexesOptions;", // + "mongodb.MapReduceOptions;mongodb.Collection;Member[mapReduce].Argument[2]", // + "mongodb.MapReduceOptions;mongodb/mongodb.MapReduceOptions;", // + "mongodb.MapReduceOptions;mongoose.mongodb.MapReduceOptions;", // + "mongodb.MongoClient;mongodb.AutoEncrypter;Argument[0]", // + "mongodb.MongoClient;mongodb.AutoEncryptionOptions;Member[keyVaultClient]", // + "mongodb.MongoClient;mongodb.ChangeStream;Member[parent]", // + "mongodb.MongoClient;mongodb.DbStatic;Argument[0]", // + "mongodb.MongoClient;mongodb.MongoClient;Member[connect].Argument[0].TypeVar[mongodb.Callback.0]", // + "mongodb.MongoClient;mongodb.MongoClient;Member[connect].WithArity[0].ReturnValue.Awaited", // + "mongodb.MongoClient;mongodb.MongoClientEvents;Member[open].Argument[0]", // + "mongodb.MongoClient;mongodb.MongoClientStatic;Instance", // + "mongodb.MongoClient;mongodb.MongoClientStatic;Member[connect].Argument[1,2].TypeVar[mongodb.Callback.0]", // + "mongodb.MongoClient;mongodb.MongoClientStatic;Member[connect].WithArity[1,2].ReturnValue.Awaited", // + "mongodb.MongoClient;mongodb/mongodb.MongoClient;", // + "mongodb.MongoClient;mongoose.mongodb.MongoClient;", // + "mongodb.MongoClientEvents;mongodb/mongodb.MongoClientEvents;", // + "mongodb.MongoClientEvents;mongoose.mongodb.MongoClientEvents;", // + "mongodb.MongoClientOptions;mongodb.MongoClientStatic;Argument[1]", // + "mongodb.MongoClientOptions;mongodb.MongoClientStatic;Member[connect].Argument[1]", // + "mongodb.MongoClientOptions;mongodb/mongodb.MongoClientOptions;", // + "mongodb.MongoClientOptions;mongoose.mongodb.MongoClientOptions;", // + "mongodb.MongoClientStatic;mongodb/mongodb.MongoClientStatic;", // + "mongodb.MongoClientStatic;mongodb;Member[MongoClient]", // + "mongodb.MongoClientStatic;mongoose.mongodb.MongoClientStatic;", // + "mongodb.MongoOptions;mongodb.ClientSession;Member[clientOptions]", // + "mongodb.MongoOptions;mongodb.MongoClient;Member[options]", // + "mongodb.MongoOptions;mongodb/mongodb.MongoOptions;", // + "mongodb.MongoOptions;mongoose.mongodb.MongoOptions;", // + "mongodb.OperationOptions;mongodb.Collection;Member[isCapped,options].Argument[0]", // + "mongodb.OperationOptions;mongodb.CommandOperationOptions;", // + "mongodb.OperationOptions;mongodb/mongodb.OperationOptions;", // + "mongodb.OperationOptions;mongoose.mongodb.OperationOptions;", // + "mongodb.OrderedBulkOperation;mongodb.Collection;Member[initializeOrderedBulkOp].ReturnValue", // + "mongodb.OrderedBulkOperation;mongodb.OrderedBulkOperation;Member[addToOperationsList].ReturnValue", // + "mongodb.OrderedBulkOperation;mongodb.OrderedBulkOperationStatic;Instance", // + "mongodb.OrderedBulkOperation;mongodb/mongodb.OrderedBulkOperation;", // + "mongodb.OrderedBulkOperation;mongoose.mongodb.OrderedBulkOperation;", // + "mongodb.OrderedBulkOperationStatic;mongodb/mongodb.OrderedBulkOperationStatic;", // + "mongodb.OrderedBulkOperationStatic;mongodb;Member[OrderedBulkOperation]", // + "mongodb.OrderedBulkOperationStatic;mongoose.mongodb.OrderedBulkOperationStatic;", // + "mongodb.ProfilingLevelOptions;mongodb.Db;Member[profilingLevel].Argument[0]", // + "mongodb.ProfilingLevelOptions;mongodb/mongodb.ProfilingLevelOptions;", // + "mongodb.ProfilingLevelOptions;mongoose.mongodb.ProfilingLevelOptions;", // + "mongodb.ReadPreferenceFromOptions;mongodb.ReadPreferenceStatic;Member[fromOptions].Argument[0]", // + "mongodb.ReadPreferenceFromOptions;mongodb/mongodb.ReadPreferenceFromOptions;", // + "mongodb.ReadPreferenceFromOptions;mongoose.mongodb.ReadPreferenceFromOptions;", // + "mongodb.ReadPreferenceStatic;mongodb/mongodb.ReadPreferenceStatic;", // + "mongodb.ReadPreferenceStatic;mongodb;Member[ReadPreference]", // + "mongodb.ReadPreferenceStatic;mongoose.mongodb.ReadPreferenceStatic;", // + "mongodb.RemoveUserOptions;mongodb.Admin;Member[removeUser].Argument[1]", // + "mongodb.RemoveUserOptions;mongodb.Db;Member[removeUser].Argument[1]", // + "mongodb.RemoveUserOptions;mongodb/mongodb.RemoveUserOptions;", // + "mongodb.RemoveUserOptions;mongoose.mongodb.RemoveUserOptions;", // + "mongodb.RenameOptions;mongodb.Collection;Member[rename].Argument[1]", // + "mongodb.RenameOptions;mongodb.Db;Member[renameCollection].Argument[2]", // + "mongodb.RenameOptions;mongodb/mongodb.RenameOptions;", // + "mongodb.RenameOptions;mongoose.mongodb.RenameOptions;", // + "mongodb.ReplaceOptions;mongodb.Collection;Member[replaceOne].Argument[2]", // + "mongodb.ReplaceOptions;mongodb/mongodb.ReplaceOptions;", // + "mongodb.ReplaceOptions;mongoose.mongodb.ReplaceOptions;", // + "mongodb.RunCommandOptions;mongodb.Admin;Member[command].Argument[1]", // + "mongodb.RunCommandOptions;mongodb.Db;Member[command].Argument[1]", // + "mongodb.RunCommandOptions;mongodb/mongodb.RunCommandOptions;", // + "mongodb.RunCommandOptions;mongoose.mongodb.RunCommandOptions;", // + "mongodb.SelectServerOptions;mongodb/mongodb.SelectServerOptions;", // + "mongodb.SelectServerOptions;mongoose.mongodb.SelectServerOptions;", // + "mongodb.SetProfilingLevelOptions;mongodb.Db;Member[setProfilingLevel].Argument[1]", // + "mongodb.SetProfilingLevelOptions;mongodb/mongodb.SetProfilingLevelOptions;", // + "mongodb.SetProfilingLevelOptions;mongoose.mongodb.SetProfilingLevelOptions;", // + "mongodb.Transaction;mongodb.ClientSession;Member[transaction]", // + "mongodb.Transaction;mongodb.TransactionStatic;Instance", // + "mongodb.Transaction;mongodb/mongodb.Transaction;", // + "mongodb.Transaction;mongoose.mongodb.Transaction;", // + "mongodb.TransactionOptions;mongodb.ClientSession;Member[defaultTransactionOptions]", // + "mongodb.TransactionOptions;mongodb.ClientSession;Member[startTransaction].Argument[0]", // + "mongodb.TransactionOptions;mongodb.ClientSession;Member[withTransaction].Argument[1]", // + "mongodb.TransactionOptions;mongodb.ClientSessionOptions;Member[defaultTransactionOptions]", // + "mongodb.TransactionOptions;mongodb.Transaction;Member[options]", // + "mongodb.TransactionOptions;mongodb/mongodb.TransactionOptions;", // + "mongodb.TransactionOptions;mongoose.mongodb.TransactionOptions;", // + "mongodb.TransactionStatic;mongodb/mongodb.TransactionStatic;", // + "mongodb.TransactionStatic;mongodb;Member[Transaction]", // + "mongodb.TransactionStatic;mongoose.mongodb.TransactionStatic;", // + "mongodb.TypedEventEmitter;mongodb.AbstractCursor;", // + "mongodb.TypedEventEmitter;mongodb.ChangeStream;", // + "mongodb.TypedEventEmitter;mongodb.ClientSession;", // + "mongodb.TypedEventEmitter;mongodb.GridFSBucket;", // + "mongodb.TypedEventEmitter;mongodb.MongoClient;", // + "mongodb.UnorderedBulkOperation;mongodb.Collection;Member[initializeUnorderedBulkOp].ReturnValue", // + "mongodb.UnorderedBulkOperation;mongodb.UnorderedBulkOperation;Member[addToOperationsList].ReturnValue", // + "mongodb.UnorderedBulkOperation;mongodb.UnorderedBulkOperationStatic;Instance", // + "mongodb.UnorderedBulkOperation;mongodb/mongodb.UnorderedBulkOperation;", // + "mongodb.UnorderedBulkOperation;mongoose.mongodb.UnorderedBulkOperation;", // + "mongodb.UnorderedBulkOperationStatic;mongodb/mongodb.UnorderedBulkOperationStatic;", // + "mongodb.UnorderedBulkOperationStatic;mongodb;Member[UnorderedBulkOperation]", // + "mongodb.UnorderedBulkOperationStatic;mongoose.mongodb.UnorderedBulkOperationStatic;", // + "mongodb.UpdateManyModel;mongodb.AnyBulkWriteOperation;Member[updateMany]", // + "mongodb.UpdateManyModel;mongodb/mongodb.UpdateManyModel;", // + "mongodb.UpdateManyModel;mongoose.mongodb.UpdateManyModel;", // + "mongodb.UpdateOneModel;mongodb.AnyBulkWriteOperation;Member[updateOne]", // + "mongodb.UpdateOneModel;mongodb/mongodb.UpdateOneModel;", // + "mongodb.UpdateOneModel;mongoose.mongodb.UpdateOneModel;", // + "mongodb.UpdateOptions;mongodb.Collection;Member[update,updateMany,updateOne].Argument[2]", // + "mongodb.UpdateOptions;mongodb/mongodb.UpdateOptions;", // + "mongodb.UpdateOptions;mongoose.mongodb.UpdateOptions;", // + "mongodb.ValidateCollectionOptions;mongodb.Admin;Member[validateCollection].Argument[1]", // + "mongodb.ValidateCollectionOptions;mongodb/mongodb.ValidateCollectionOptions;", // + "mongodb.ValidateCollectionOptions;mongoose.mongodb.ValidateCollectionOptions;", // + "mongodb.WithSessionCallback;mongodb.MongoClient;Member[withSession].Argument[1]", // + "mongodb.WithSessionCallback;mongodb.MongoClient;Member[withSession].WithArity[1].Argument[0]", // + "mongodb.WithSessionCallback;mongodb/mongodb.WithSessionCallback;", // + "mongodb.WithSessionCallback;mongoose.mongodb.WithSessionCallback;", // + "mongodb.WithTransactionCallback;mongodb.ClientSession;Member[withTransaction].Argument[0]", // + "mongodb.WithTransactionCallback;mongodb/mongodb.WithTransactionCallback;", // + "mongodb.WithTransactionCallback;mongoose.mongodb.WithTransactionCallback;", // + "mongodb;mongoose;Member[mongodb]", // + "mongoose.AcceptsDiscriminator;mongoose.Model;", // + "mongoose.AcceptsDiscriminator;mongoose.Schema.Types.Array;", // + "mongoose.AcceptsDiscriminator;mongoose.Schema.Types.DocumentArray;", // + "mongoose.AcceptsDiscriminator;mongoose.Schema.Types.Subdocument;", // + "mongoose.Aggregate;mongoose.Aggregate;Member[addCursorFlag,addFields,allowDiskUse,append,collation,count,facet,graphLookup,group,hint,limit,lookup,match,model,near,option,project,read,readConcern,redact,replaceRoot,sample,search,session,skip,sort,sortByCount,unionWith,unwind].ReturnValue", // + "mongoose.Aggregate;mongoose.AggregateStatic;Instance", // + "mongoose.Aggregate;mongoose.Model;Member[aggregate].ReturnValue", // + "mongoose.AggregateStatic;mongoose;Member[Aggregate]", // + "mongoose.Collection;mongoose.Collection;Instance", // + "mongoose.Collection;mongoose.Connection;Member[collection].ReturnValue", // + "mongoose.Collection;mongoose.Connection;Member[collections].AnyMember", // + "mongoose.Collection;mongoose.Document;Member[collection]", // + "mongoose.Collection;mongoose.Model;Member[collection]", // + "mongoose.Collection;mongoose;Member[Collection]", // + "mongoose.CollectionBase;mongoose.Collection;", // + "mongoose.CompileModelOptions;mongoose.Connection;Member[model].Argument[3]", // + "mongoose.CompileModelOptions;mongoose;Member[model].Argument[3]", // + "mongoose.ConnectOptions;mongoose.Connection;Member[openUri].WithArity[1,2,3].Argument[1]", // + "mongoose.ConnectOptions;mongoose;Member[connect,createConnection].WithArity[1,2,3].Argument[1]", // + "mongoose.Connection;mongoose.Collection;Argument[1]", // + "mongoose.Connection;mongoose.CollectionBase;Member[conn]", // + "mongoose.Connection;mongoose.CompileModelOptions;Member[connection]", // + "mongoose.Connection;mongoose.Connection;Member[asPromise].ReturnValue.Awaited", // + "mongoose.Connection;mongoose.Connection;Member[deleteModel,plugin,setClient,useDb].ReturnValue", // + "mongoose.Connection;mongoose.Connection;Member[openUri].Argument[2].TypeVar[mongoose.Callback.0]", // + "mongoose.Connection;mongoose.Connection;Member[openUri].WithArity[1,2].ReturnValue.Awaited", // + "mongoose.Connection;mongoose.Connection;Member[openUri].WithArity[2,3].ReturnValue", // + "mongoose.Connection;mongoose.Connection;Member[openUri].WithArity[2].Argument[1].TypeVar[mongoose.Callback.0]", // + "mongoose.Connection;mongoose.ConnectionStatic;Instance", // + "mongoose.Connection;mongoose.Document;Member[db]", // + "mongoose.Connection;mongoose.Model;Member[db]", // + "mongoose.Connection;mongoose;Member[connection]", // + "mongoose.Connection;mongoose;Member[connections].ArrayElement", // + "mongoose.Connection;mongoose;Member[createConnection].Argument[2].TypeVar[mongoose.Callback.0]", // + "mongoose.Connection;mongoose;Member[createConnection].WithArity[0,1,2].ReturnValue", // + "mongoose.Connection;mongoose;Member[createConnection].WithArity[2].Argument[1].TypeVar[mongoose.Callback.0]", // + "mongoose.ConnectionStatic;mongoose;Member[Connection]", // + "mongoose.Cursor;mongoose.Query;Member[cursor].ReturnValue", // + "mongoose.DiscriminatorModel;mongoose.DiscriminatorSchema;TypeVar[mongoose.Schema.1]", // + "mongoose.Document;mongoose.Document;Member[$getAllSubdocs,$getPopulatedDocs].ReturnValue.ArrayElement", // + "mongoose.Document;mongoose.Document;Member[$inc,$parent,$set,depopulate,increment,init,overwrite,set].ReturnValue", // + "mongoose.Document;mongoose.Document;Member[delete,deleteOne].WithArity[0,1].ReturnValue.TypeVar[mongoose.QueryWithHelpers.1]", // + "mongoose.Document;mongoose.Document;Member[equals].Argument[0]", // + "mongoose.Document;mongoose.Document;Member[init].Argument[2].TypeVar[mongoose.Callback.0]", // + "mongoose.Document;mongoose.Document;Member[remove,save].WithArity[0,1].ReturnValue.Awaited", // + "mongoose.Document;mongoose.Document;Member[replaceOne,update,updateOne].ReturnValue.TypeVar[mongoose.Query.1]", // + "mongoose.Document;mongoose.Document;Member[save].Argument[1].TypeVar[mongoose.Callback.0]", // + "mongoose.Document;mongoose.Document;Member[save].WithArity[1].Argument[0].TypeVar[mongoose.Callback.0]", // + "mongoose.Document;mongoose.DocumentStatic;Instance", // + "mongoose.Document;mongoose.Error.VersionErrorStatic;Argument[0]", // + "mongoose.Document;mongoose.HydratedDocument;", // + "mongoose.Document;mongoose.HydratedDocument;TypeVar[mongoose.Require_id.0]", // + "mongoose.Document;mongoose.Model;Member[bulkSave].Argument[0].ArrayElement", // + "mongoose.Document;mongoose.TVirtualPathFN;Argument[2]", // + "mongoose.Document;mongoose.Types.Subdocument;", // + "mongoose.Document;mongoose.Types.Subdocument;Member[$parent,ownerDocument,parent].ReturnValue", // + "mongoose.Document;mongoose.VirtualType;Member[applyGetters,applySetters].Argument[1]", // + "mongoose.DocumentStatic;mongoose;Member[Document]", // + "mongoose.Error.VersionErrorStatic;mongoose;Member[Error].Member[VersionError]", // + "mongoose.HydratedDocument;mongoose.Model;Instance", // + "mongoose.HydratedDocument;mongoose.Model;Member[$where,count,countDocuments,deleteMany,deleteOne,distinct,estimatedDocumentCount,find,geoSearch,remove,replaceOne,update,updateMany,updateOne,where].ReturnValue.TypeVar[mongoose.QueryWithHelpers.1]", // + "mongoose.HydratedDocument;mongoose.Model;Member[$where,find,geoSearch,where].ReturnValue.TypeVar[mongoose.QueryWithHelpers.0].ArrayElement", // + "mongoose.HydratedDocument;mongoose.Model;Member[create,insertMany].WithArity[2].Argument[1].TypeVar[mongoose.Callback.0].ArrayElement", // + "mongoose.HydratedDocument;mongoose.Model;Member[create].WithArity[0..,1,2].ReturnValue.Awaited.ArrayElement", // + "mongoose.HydratedDocument;mongoose.Model;Member[create].WithArity[1].ReturnValue.Awaited", // + "mongoose.HydratedDocument;mongoose.Model;Member[create].WithArity[2].Argument[1].TypeVar[mongoose.Callback.0]", // + "mongoose.HydratedDocument;mongoose.Model;Member[exists].WithArity[1,2].ReturnValue.TypeVar[mongoose.QueryWithHelpers.1]", // + "mongoose.HydratedDocument;mongoose.Model;Member[find,insertMany].WithArity[3].Argument[2].TypeVar[mongoose.Callback.0].ArrayElement", // + "mongoose.HydratedDocument;mongoose.Model;Member[findById,findByIdAndDelete,findByIdAndRemove,findOne,findOneAndDelete,findOneAndRemove].ReturnValue.TypeVar[mongoose.QueryWithHelpers.0,mongoose.QueryWithHelpers.1]", // + "mongoose.HydratedDocument;mongoose.Model;Member[findById,findOne].Argument[3].TypeVar[mongoose.Callback.0]", // + "mongoose.HydratedDocument;mongoose.Model;Member[findByIdAndDelete,findByIdAndRemove,findOneAndDelete,findOneAndRemove].Argument[2].Argument[1]", // + "mongoose.HydratedDocument;mongoose.Model;Member[findByIdAndUpdate,findOneAndReplace,findOneAndUpdate].WithArity[0,1,2,3,4].ReturnValue.TypeVar[mongoose.QueryWithHelpers.0,mongoose.QueryWithHelpers.1]", // + "mongoose.HydratedDocument;mongoose.Model;Member[findByIdAndUpdate,findOneAndReplace,findOneAndUpdate].WithArity[3,4].ReturnValue.TypeVar[mongoose.QueryWithHelpers.0].TypeVar[mongoose.ModifyResult.0]", // + "mongoose.HydratedDocument;mongoose.Model;Member[findByIdAndUpdate].WithArity[0,1,2,4].Argument[3].Argument[1]", // + "mongoose.HydratedDocument;mongoose.Model;Member[findByIdAndUpdate].WithArity[3].Argument[2,3].Argument[1]", // + "mongoose.HydratedDocument;mongoose.Model;Member[findById].WithArity[1,2,3].Argument[2].TypeVar[mongoose.Callback.0]", // + "mongoose.HydratedDocument;mongoose.Model;Member[findOneAndReplace].WithArity[0,1,2,3,4].Argument[3].Argument[1]", // + "mongoose.HydratedDocument;mongoose.Model;Member[findOneAndUpdate].WithArity[3,4].Argument[3].Argument[1]", // + "mongoose.HydratedDocument;mongoose.Model;Member[findOne].WithArity[0,1,2].Argument[1,2].TypeVar[mongoose.Callback.0]", // + "mongoose.HydratedDocument;mongoose.Model;Member[findOne].WithArity[3].Argument[2].TypeVar[mongoose.Callback.0]", // + "mongoose.HydratedDocument;mongoose.Model;Member[find].Argument[3].TypeVar[mongoose.Callback.0].ArrayElement", // + "mongoose.HydratedDocument;mongoose.Model;Member[find].WithArity[0].Argument[0].TypeVar[mongoose.Callback.0].ArrayElement", // + "mongoose.HydratedDocument;mongoose.Model;Member[find].WithArity[1].Argument[0,1,2].TypeVar[mongoose.Callback.0].ArrayElement", // + "mongoose.HydratedDocument;mongoose.Model;Member[find].WithArity[2].Argument[1,2].TypeVar[mongoose.Callback.0].ArrayElement", // + "mongoose.HydratedDocument;mongoose.Model;Member[geoSearch].Argument[2].TypeVar[mongoose.Callback.0].ArrayElement", // + "mongoose.HydratedDocument;mongoose.Model;Member[hydrate].ReturnValue", // + "mongoose.HydratedDocument;mongoose.Model;Member[init].ReturnValue.Awaited", // + "mongoose.HydratedDocument;mongoose.Model;Member[insertMany].WithArity[1,2].ReturnValue.Awaited.ArrayElement", // + "mongoose.HydratedDocument;mongoose.Model;Member[populate].WithArity[2,3].Argument[2].TypeVar[mongoose.Callback.0]", // + "mongoose.HydratedDocument;mongoose.Model;Member[populate].WithArity[2,3].Argument[2].TypeVar[mongoose.Callback.0].ArrayElement", // + "mongoose.HydratedDocument;mongoose.Model;Member[populate].WithArity[2,3].ReturnValue.Awaited", // + "mongoose.HydratedDocument;mongoose.Model;Member[populate].WithArity[2,3].ReturnValue.Awaited.ArrayElement", // + "mongoose.HydratedDocument;mongoose.TVirtualPathFN;Argument[1].TypeVar[mongoose.VirtualType.0]", // + "mongoose.HydratedDocument;mongoose.VirtualPathFunctions;Member[options].TypeVar[mongoose.VirtualTypeOptions.0]", // + "mongoose.InsertManyOptions;mongoose.Model;Member[insertMany].WithArity[2,3].Argument[1]", // + "mongoose.Model;mongoose.AcceptsDiscriminator;Member[discriminator].WithArity[2,3].ReturnValue", // + "mongoose.Model;mongoose.Aggregate;Member[model].Argument[0]", // + "mongoose.Model;mongoose.Connection;Member[model].WithArity[1,2,3,4].ReturnValue", // + "mongoose.Model;mongoose.Connection;Member[models].AnyMember", // + "mongoose.Model;mongoose.DiscriminatorModel;", // + "mongoose.Model;mongoose.Document;Member[$model].ReturnValue", // + "mongoose.Model;mongoose.Document;Member[populate].Argument[2]", // + "mongoose.Model;mongoose.Model;Member[discriminators].AnyMember", // + "mongoose.Model;mongoose.Models;AnyMember", // + "mongoose.Model;mongoose.PopulateOptions;Member[model]", // + "mongoose.Model;mongoose.Query;Member[cast].Argument[0]", // + "mongoose.Model;mongoose.Query;Member[populate].Argument[2]", // + "mongoose.Model;mongoose.Schema.Types.Array;Member[discriminator].WithArity[2,3].ReturnValue", // + "mongoose.Model;mongoose.Schema.Types.DocumentArray;Member[discriminator].WithArity[2,3].ReturnValue", // + "mongoose.Model;mongoose.Schema.Types.Subdocument;Member[discriminator].WithArity[2,3].ReturnValue", // + "mongoose.Model;mongoose.SchemaStatic;Instance.TypeVar[mongoose.Schema.1]", // + "mongoose.Model;mongoose;Member[Model]", // + "mongoose.Model;mongoose;Member[model].ReturnValue", // + "mongoose.Models;mongoose;Member[models]", // + "mongoose.PopulateOption;mongoose.InsertManyOptions;", // + "mongoose.PopulateOption;mongoose.QueryOptions;", // + "mongoose.PopulateOptions;mongoose.Document;Member[populate].Argument[4]", // + "mongoose.PopulateOptions;mongoose.Document;Member[populate].WithArity[1,2].Argument[0]", // + "mongoose.PopulateOptions;mongoose.Document;Member[populate].WithArity[1,2].Argument[0].ArrayElement", // + "mongoose.PopulateOptions;mongoose.Model;Member[populate].Argument[1]", // + "mongoose.PopulateOptions;mongoose.Model;Member[populate].Argument[1].ArrayElement", // + "mongoose.PopulateOptions;mongoose.PopulateOption;Member[populate]", // + "mongoose.PopulateOptions;mongoose.PopulateOption;Member[populate].ArrayElement", // + "mongoose.PopulateOptions;mongoose.PopulateOptions;Member[populate]", // + "mongoose.PopulateOptions;mongoose.PopulateOptions;Member[populate].ArrayElement", // + "mongoose.PopulateOptions;mongoose.Query;Member[populate].WithArity[1].Argument[0]", // + "mongoose.PopulateOptions;mongoose.Query;Member[populate].WithArity[1].Argument[0].ArrayElement", // + "mongoose.Query;mongoose.Document;Member[replaceOne,update,updateOne].ReturnValue", // + "mongoose.Query;mongoose.HydratedDocument;TypeVar[mongoose.Require_id.0]", // + "mongoose.Query;mongoose.Query;Member[all,allowDiskUse,and,batchSize,box,circle,clone,collation,comment,elemMatch,equals,exists,explain,geometry,gt,gte,hint,in,intersects,j,limit,lt,lte,maxDistance,maxScan,maxTimeMS,merge,mod,ne,near,nin,nor,or,polygon,read,readConcern,regex,remove,select,session,set,setOptions,size,skip,slice,snapshot,sort,tailable,w,where,within,wtimeout].ReturnValue", // + "mongoose.Query;mongoose.Query;Member[error].WithArity[1].ReturnValue", // + "mongoose.Query;mongoose.Query;Member[merge].Argument[0]", // + "mongoose.Query;mongoose.QueryStatic;Instance", // + "mongoose.Query;mongoose.QueryWithHelpers;", // + "mongoose.QueryOptions;mongoose.Document;Member[delete,deleteOne,remove].WithArity[0,1,2].Argument[0]", // + "mongoose.QueryOptions;mongoose.Document;Member[replaceOne,update,updateOne].Argument[1]", // + "mongoose.QueryOptions;mongoose.Model;Member[countDocuments,findByIdAndDelete,findByIdAndRemove,findOneAndDelete,findOneAndRemove].Argument[1]", // + "mongoose.QueryOptions;mongoose.Model;Member[deleteMany,deleteOne].WithArity[0,1,2,3].Argument[1]", // + "mongoose.QueryOptions;mongoose.Model;Member[estimatedDocumentCount].Argument[0]", // + "mongoose.QueryOptions;mongoose.Model;Member[find,findById].WithArity[1,2,3,4].Argument[2]", // + "mongoose.QueryOptions;mongoose.Model;Member[findByIdAndUpdate,findOne,findOneAndReplace,findOneAndUpdate].WithArity[0,1,2,3,4].Argument[2]", // + "mongoose.QueryOptions;mongoose.Model;Member[replaceOne,update,updateMany,updateOne].Argument[2]", // + "mongoose.QueryOptions;mongoose.PopulateOptions;Member[options]", // + "mongoose.QueryOptions;mongoose.Query;Member[countDocuments,findByIdAndDelete,findOneAndDelete,findOneAndRemove].Argument[1]", // + "mongoose.QueryOptions;mongoose.Query;Member[cursor,estimatedDocumentCount,setOptions].Argument[0]", // + "mongoose.QueryOptions;mongoose.Query;Member[cursor].ReturnValue.TypeVar[mongoose.Cursor.1]", // + "mongoose.QueryOptions;mongoose.Query;Member[deleteMany,deleteOne].WithArity[0,1,2,3].Argument[1]", // + "mongoose.QueryOptions;mongoose.Query;Member[findByIdAndUpdate,findOne,findOneAndUpdate].WithArity[0,1,2,3,4].Argument[2]", // + "mongoose.QueryOptions;mongoose.Query;Member[find].WithArity[1,2,3,4].Argument[2]", // + "mongoose.QueryOptions;mongoose.Query;Member[getOptions].ReturnValue", // + "mongoose.QueryOptions;mongoose.Query;Member[replaceOne,update,updateMany,updateOne].Argument[2]", // + "mongoose.QueryOptions;mongoose.VirtualTypeOptions;Member[options]", // + "mongoose.QueryStatic;mongoose;Member[Query]", // + "mongoose.QueryWithHelpers;mongoose.Document;Member[delete,deleteOne].WithArity[0,1].ReturnValue", // + "mongoose.QueryWithHelpers;mongoose.Model;Member[$where,count,countDocuments,deleteMany,deleteOne,distinct,estimatedDocumentCount,find,findById,findByIdAndDelete,findByIdAndRemove,findOne,findOneAndDelete,findOneAndRemove,geoSearch,remove,replaceOne,update,updateMany,updateOne,where].ReturnValue", // + "mongoose.QueryWithHelpers;mongoose.Model;Member[exists].WithArity[1,2].ReturnValue", // + "mongoose.QueryWithHelpers;mongoose.Model;Member[findByIdAndUpdate,findOneAndReplace,findOneAndUpdate].WithArity[0,1,2,3,4].ReturnValue", // + "mongoose.QueryWithHelpers;mongoose.Query;Member[$where,count,countDocuments,deleteMany,deleteOne,distinct,estimatedDocumentCount,find,findByIdAndDelete,findOne,findOneAndDelete,findOneAndRemove,lean,orFail,populate,replaceOne,transform,update,updateMany,updateOne].ReturnValue", // + "mongoose.QueryWithHelpers;mongoose.Query;Member[findByIdAndUpdate,findOneAndUpdate].WithArity[0,1,2,3,4].ReturnValue", // + "mongoose.QueryWithHelpers;mongoose.Query;Member[toConstructor].ReturnValue.Instance", // + "mongoose.Schema.Types.Array;mongoose.Schema.Types.Array;Member[enum].ReturnValue", // + "mongoose.Schema.Types.Array;mongoose.Schema.Types.ArrayStatic;Instance", // + "mongoose.Schema.Types.ArrayStatic;mongoose;Member[Schema].Member[Types].Member[Array]", // + "mongoose.Schema.Types.DocumentArray;mongoose.Schema.Types.DocumentArrayStatic;Instance", // + "mongoose.Schema.Types.DocumentArrayStatic;mongoose;Member[Schema].Member[Types].Member[DocumentArray]", // + "mongoose.Schema.Types.Subdocument;mongoose.Schema.Types.SubdocumentStatic;Instance", // + "mongoose.Schema.Types.SubdocumentStatic;mongoose.Schema.Types.DocumentArray;Member[caster]", // + "mongoose.Schema.Types.SubdocumentStatic;mongoose;Member[Schema].Member[Types].Member[Subdocument]", // + "mongoose.SchemaStatic;mongoose;Member[Schema]", // + "mongoose.SessionOperation;mongoose.Aggregate;", // + "mongoose.SessionOperation;mongoose.Query;", // + "mongoose.TVirtualPathFN;mongoose.VirtualPathFunctions;Member[get,set]", // + "mongoose.Types.Array;mongoose.Types.DocumentArray;", // + "mongoose.Types.ArraySubdocument;mongoose.Types.ArraySubdocumentStatic;Instance", // + "mongoose.Types.ArraySubdocumentStatic;mongoose;Member[Types].Member[ArraySubdocument]", // + "mongoose.Types.DocumentArray;mongoose.Types.ArraySubdocument;Member[parentArray].ReturnValue", // + "mongoose.Types.DocumentArray;mongoose.Types.DocumentArrayStatic;Instance", // + "mongoose.Types.DocumentArray;mongoose/inferschematype.ResolvePathType;TypeVar[mongoose.IfEquals.3]", // + "mongoose.Types.DocumentArrayStatic;mongoose;Member[Types].Member[DocumentArray]", // + "mongoose.Types.ObjectId;mongoose/inferschematype.ResolvePathType;", // + "mongoose.Types.Subdocument;mongoose.Types.ArraySubdocument;", // + "mongoose.Types.Subdocument;mongoose.Types.DocumentArray;Member[create,id].ReturnValue", // + "mongoose.Types.Subdocument;mongoose.Types.DocumentArray;TypeVar[mongoose.Types.Array.0]", // + "mongoose.Types.Subdocument;mongoose.Types.SubdocumentStatic;Instance", // + "mongoose.Types.SubdocumentStatic;mongoose;Member[Types].Member[Subdocument]", // + "mongoose.VirtualType;mongoose.TVirtualPathFN;Argument[1]", // + "mongoose.VirtualType;mongoose.VirtualType;Member[get,set].Argument[0].Argument[1]", // + "mongoose.VirtualType;mongoose.VirtualType;Member[get,set].ReturnValue", // + "mongoose.VirtualType;mongoose.VirtualTypeStatic;Instance", // + "mongoose.VirtualTypeOptions;mongoose.VirtualPathFunctions;Member[options]", // + "mongoose.VirtualTypeStatic;mongoose;Member[VirtualType]", // + "mongoose/inferschematype.ResolvePathType;mongoose/inferschematype.ObtainDocumentPathType;", // + "mongoose/inferschematype.ResolvePathType;mongoose/inferschematype.ResolvePathType;TypeVar[mongoose.IfEquals.3].ArrayElement", // + "mongoose/inferschematype.ResolvePathType;mongoose/inferschematype.ResolvePathType;TypeVar[mongoose.IfEquals.3].TypeVar[mongoose.Types.DocumentArray.0]", // + "mongoose;mongoose;Member[mongoose]", // ] } } @@ -659,38 +659,38 @@ private class Summaries extends ModelInput::SummaryModelCsv { override predicate row(string row) { row = [ - "mongodb;AbstractCursor;;;Member[addCursorFlag,batchSize,maxTimeMS,withReadConcern,withReadPreference].ReturnValue;type", // - "mongodb;BulkOperationBase;;;Member[addToOperationsList,raw].ReturnValue;type", // - "mongodb;FindCursor;;;Member[addQueryModifier,allowDiskUse,collation,comment,filter,hint,limit,max,maxAwaitTimeMS,maxTimeMS,min,returnKey,showRecordId,skip,sort].ReturnValue;type", // - "mongodb;FindOperators;;;Member[arrayFilters,collation,upsert].ReturnValue;type", // - "mongodb;GridFSBucketWriteStream;;;Member[end].ReturnValue;type", // - "mongodb;MongoClient;;;Member[connect].Argument[0].TypeVar[mongodb.Callback.0];type", // - "mongodb;MongoClient;;;Member[connect].WithArity[0].ReturnValue.Awaited;type", // - "mongodb;OrderedBulkOperation;;;Member[addToOperationsList].ReturnValue;type", // - "mongodb;TypedEventEmitter;;;Member[addListener,off,on,once,prependListener,prependOnceListener,removeAllListeners,removeListener,setMaxListeners].ReturnValue;type", // - "mongodb;UnorderedBulkOperation;;;Member[addToOperationsList].ReturnValue;type", // - "mongoose;Aggregate;;;Member[addCursorFlag,addFields,allowDiskUse,append,collation,count,facet,graphLookup,group,hint,limit,lookup,match,model,near,option,project,read,readConcern,redact,replaceRoot,sample,search,session,skip,sort,sortByCount,unionWith,unwind].ReturnValue;type", // - "mongoose;Connection;;;Member[asPromise].ReturnValue.Awaited;type", // - "mongoose;Connection;;;Member[deleteModel,setClient].ReturnValue;type", // - "mongoose;Cursor;;;Member[addCursorFlag].ReturnValue;type", // - "mongoose;Document;;;Member[$inc,$set,depopulate,increment,init,overwrite,set].ReturnValue;type", // - "mongoose;Document;;;Member[delete,deleteOne].WithArity[0,1].ReturnValue.TypeVar[mongoose.QueryWithHelpers.1];type", // - "mongoose;Document;;;Member[getChanges].ReturnValue.TypeVar[mongoose.UpdateQuery.0];type", // - "mongoose;Document;;;Member[init].Argument[2].TypeVar[mongoose.Callback.0];type", // - "mongoose;Document;;;Member[populate].Argument[1,5].TypeVar[mongoose.Callback.0].TypeVar[mongoose.MergeType.0];type", // - "mongoose;Document;;;Member[populate].WithArity[1,2,3,4,5].ReturnValue.Awaited.TypeVar[mongoose.MergeType.0];type", // - "mongoose;Document;;;Member[remove,save].WithArity[0,1].ReturnValue.Awaited;type", // - "mongoose;Document;;;Member[replaceOne,update,updateOne].ReturnValue.TypeVar[mongoose.Query.1];type", // - "mongoose;Document;;;Member[save].Argument[1].TypeVar[mongoose.Callback.0];type", // - "mongoose;Document;;;Member[save].WithArity[1].Argument[0].TypeVar[mongoose.Callback.0];type", // - "mongoose;Document;;;Member[update,updateOne].Argument[0].TypeVar[mongoose.UpdateQuery.0];type", // - "mongoose;Query;;;Member[all,allowDiskUse,and,batchSize,box,circle,clone,collation,comment,elemMatch,equals,exists,explain,geometry,gt,gte,hint,in,intersects,j,limit,lt,lte,maxDistance,maxScan,maxTimeMS,merge,mod,ne,near,nin,nor,or,polygon,read,readConcern,regex,select,session,set,setOptions,size,skip,slice,snapshot,sort,tailable,w,where,within,wtimeout].ReturnValue;type", // - "mongoose;Query;;;Member[error].WithArity[1].ReturnValue;type", // - "mongoose;Schema.Types.Array;;;Member[enum].ReturnValue;type", // - "mongoose;SessionOperation;;;Member[session].ReturnValue;type", // - "mongoose;Types.Array;;;Member[pull,remove,set].ReturnValue;type", // - "mongoose;Types.ObjectId;;;Member[_id];type", // - "mongoose;VirtualType;;;Member[get,set].ReturnValue;type", // + "mongodb.AbstractCursor;;;Member[addCursorFlag,batchSize,maxTimeMS,withReadConcern,withReadPreference].ReturnValue;type", // + "mongodb.BulkOperationBase;;;Member[addToOperationsList,raw].ReturnValue;type", // + "mongodb.FindCursor;;;Member[addQueryModifier,allowDiskUse,collation,comment,filter,hint,limit,max,maxAwaitTimeMS,maxTimeMS,min,returnKey,showRecordId,skip,sort].ReturnValue;type", // + "mongodb.FindOperators;;;Member[arrayFilters,collation,upsert].ReturnValue;type", // + "mongodb.GridFSBucketWriteStream;;;Member[end].ReturnValue;type", // + "mongodb.MongoClient;;;Member[connect].Argument[0].TypeVar[mongodb.Callback.0];type", // + "mongodb.MongoClient;;;Member[connect].WithArity[0].ReturnValue.Awaited;type", // + "mongodb.OrderedBulkOperation;;;Member[addToOperationsList].ReturnValue;type", // + "mongodb.TypedEventEmitter;;;Member[addListener,off,on,once,prependListener,prependOnceListener,removeAllListeners,removeListener,setMaxListeners].ReturnValue;type", // + "mongodb.UnorderedBulkOperation;;;Member[addToOperationsList].ReturnValue;type", // + "mongoose.Aggregate;;;Member[addCursorFlag,addFields,allowDiskUse,append,collation,count,facet,graphLookup,group,hint,limit,lookup,match,model,near,option,project,read,readConcern,redact,replaceRoot,sample,search,session,skip,sort,sortByCount,unionWith,unwind].ReturnValue;type", // + "mongoose.Connection;;;Member[asPromise].ReturnValue.Awaited;type", // + "mongoose.Connection;;;Member[deleteModel,setClient].ReturnValue;type", // + "mongoose.Cursor;;;Member[addCursorFlag].ReturnValue;type", // + "mongoose.Document;;;Member[$inc,$set,depopulate,increment,init,overwrite,set].ReturnValue;type", // + "mongoose.Document;;;Member[delete,deleteOne].WithArity[0,1].ReturnValue.TypeVar[mongoose.QueryWithHelpers.1];type", // + "mongoose.Document;;;Member[getChanges].ReturnValue.TypeVar[mongoose.UpdateQuery.0];type", // + "mongoose.Document;;;Member[init].Argument[2].TypeVar[mongoose.Callback.0];type", // + "mongoose.Document;;;Member[populate].Argument[1,5].TypeVar[mongoose.Callback.0].TypeVar[mongoose.MergeType.0];type", // + "mongoose.Document;;;Member[populate].WithArity[1,2,3,4,5].ReturnValue.Awaited.TypeVar[mongoose.MergeType.0];type", // + "mongoose.Document;;;Member[remove,save].WithArity[0,1].ReturnValue.Awaited;type", // + "mongoose.Document;;;Member[replaceOne,update,updateOne].ReturnValue.TypeVar[mongoose.Query.1];type", // + "mongoose.Document;;;Member[save].Argument[1].TypeVar[mongoose.Callback.0];type", // + "mongoose.Document;;;Member[save].WithArity[1].Argument[0].TypeVar[mongoose.Callback.0];type", // + "mongoose.Document;;;Member[update,updateOne].Argument[0].TypeVar[mongoose.UpdateQuery.0];type", // + "mongoose.Query;;;Member[all,allowDiskUse,and,batchSize,box,circle,clone,collation,comment,elemMatch,equals,exists,explain,geometry,gt,gte,hint,in,intersects,j,limit,lt,lte,maxDistance,maxScan,maxTimeMS,merge,mod,ne,near,nin,nor,or,polygon,read,readConcern,regex,select,session,set,setOptions,size,skip,slice,snapshot,sort,tailable,w,where,within,wtimeout].ReturnValue;type", // + "mongoose.Query;;;Member[error].WithArity[1].ReturnValue;type", // + "mongoose.Schema.Types.Array;;;Member[enum].ReturnValue;type", // + "mongoose.SessionOperation;;;Member[session].ReturnValue;type", // + "mongoose.Types.Array;;;Member[pull,remove,set].ReturnValue;type", // + "mongoose.Types.ObjectId;;;Member[_id];type", // + "mongoose.VirtualType;;;Member[get,set].ReturnValue;type", // ] } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/mongodb/model.json b/javascript/ql/lib/semmle/javascript/frameworks/mongodb/model.json index 583347db454..1111a250741 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/mongodb/model.json +++ b/javascript/ql/lib/semmle/javascript/frameworks/mongodb/model.json @@ -15,700 +15,700 @@ }, "language": "javascript", "replaceTypeParameters": [ - "mongoose;HydratedDocument;0;mongoose;Document", - "mongoose;HydratedDocument;0;mongoose;Query" + "mongoose.HydratedDocument;0;mongoose.Document", + "mongoose.HydratedDocument;0;mongoose.Query" ], "usedTypes": { "sinks": [ - "mongoose;ConnectOptions", - "mongodb;Auth" + "mongoose.ConnectOptions", + "mongodb.Auth" ] }, "ignoredTypes": { "sourcesAndSinks": [ - "mongoose;Schema", - "mongoose;SchemaType", - "mongoose;SchemaTypeOptions" + "mongoose.Schema", + "mongoose.SchemaType", + "mongoose.SchemaTypeOptions" ] }, "model": { "sinks": [ - "mongodb;Collection;Member[aggregate,count,countDocuments,deleteMany,deleteOne,find,findOne,findOneAndDelete,findOneAndReplace,remove,replaceOne,watch].Argument[0];mongodb.sink", - "mongodb;Collection;Member[distinct].Argument[1];mongodb.sink", - "mongodb;Collection;Member[findOneAndUpdate,update,updateMany,updateOne].Argument[0,1];mongodb.sink", - "mongodb;Db;Member[aggregate,watch].Argument[0];mongodb.sink", - "mongodb;DeleteManyModel;Member[filter];mongodb.sink", - "mongodb;DeleteOneModel;Member[filter];mongodb.sink", - "mongodb;MongoClient;Member[watch].Argument[0];mongodb.sink", - "mongodb;UpdateManyModel;Member[filter,update];mongodb.sink", - "mongodb;UpdateOneModel;Member[filter,update];mongodb.sink", - "mongoose;CollectionBase;Member[findAndModify].Argument[0];mongodb.sink", - "mongoose;Connection;Member[watch].Argument[0];mongodb.sink", - "mongoose;Document;Member[update,updateOne].Argument[0];mongodb.sink", - "mongoose;Model;Member[$where,aggregate,exists,find,findById,findByIdAndDelete,findByIdAndRemove,findOne,findOneAndDelete,findOneAndRemove,findOneAndReplace,geoSearch,remove,replaceOne,watch].Argument[0];mongodb.sink", - "mongoose;Model;Member[count,where].WithArity[1,2].Argument[0];mongodb.sink", - "mongoose;Model;Member[countDocuments].WithArity[1,2,3].Argument[0];mongodb.sink", - "mongoose;Model;Member[deleteMany,deleteOne].WithArity[0,1,2,3].Argument[0];mongodb.sink", - "mongoose;Model;Member[distinct,where].Argument[1];mongodb.sink", - "mongoose;Model;Member[findByIdAndUpdate,findOneAndUpdate,update,updateMany,updateOne].Argument[0,1];mongodb.sink", - "mongoose;Model;Member[find].WithArity[1,2,3,4].Argument[0];mongodb.sink", - "mongoose;Query;Member[$where,and,find,findByIdAndDelete,findOne,findOneAndDelete,findOneAndRemove,nor,or,remove,replaceOne,setUpdate].Argument[0];mongodb.sink", - "mongoose;Query;Member[count,where].WithArity[1,2].Argument[0];mongodb.sink", - "mongoose;Query;Member[deleteMany,deleteOne].WithArity[0,1,2,3].Argument[0];mongodb.sink", - "mongoose;Query;Member[distinct,where].Argument[1];mongodb.sink", - "mongoose;Query;Member[findByIdAndUpdate,findOneAndUpdate,update,updateMany,updateOne].Argument[0,1];mongodb.sink", - "mongoose;Query;Member[find].WithArity[1,2,3,4].Argument[0];mongodb.sink", - "mongoose;QueryStatic;Argument[2];mongodb.sink" + "mongodb.Collection;Member[aggregate,count,countDocuments,deleteMany,deleteOne,find,findOne,findOneAndDelete,findOneAndReplace,remove,replaceOne,watch].Argument[0];mongodb.sink", + "mongodb.Collection;Member[distinct].Argument[1];mongodb.sink", + "mongodb.Collection;Member[findOneAndUpdate,update,updateMany,updateOne].Argument[0,1];mongodb.sink", + "mongodb.Db;Member[aggregate,watch].Argument[0];mongodb.sink", + "mongodb.DeleteManyModel;Member[filter];mongodb.sink", + "mongodb.DeleteOneModel;Member[filter];mongodb.sink", + "mongodb.MongoClient;Member[watch].Argument[0];mongodb.sink", + "mongodb.UpdateManyModel;Member[filter,update];mongodb.sink", + "mongodb.UpdateOneModel;Member[filter,update];mongodb.sink", + "mongoose.CollectionBase;Member[findAndModify].Argument[0];mongodb.sink", + "mongoose.Connection;Member[watch].Argument[0];mongodb.sink", + "mongoose.Document;Member[update,updateOne].Argument[0];mongodb.sink", + "mongoose.Model;Member[$where,aggregate,exists,find,findById,findByIdAndDelete,findByIdAndRemove,findOne,findOneAndDelete,findOneAndRemove,findOneAndReplace,geoSearch,remove,replaceOne,watch].Argument[0];mongodb.sink", + "mongoose.Model;Member[count,where].WithArity[1,2].Argument[0];mongodb.sink", + "mongoose.Model;Member[countDocuments].WithArity[1,2,3].Argument[0];mongodb.sink", + "mongoose.Model;Member[deleteMany,deleteOne].WithArity[0,1,2,3].Argument[0];mongodb.sink", + "mongoose.Model;Member[distinct,where].Argument[1];mongodb.sink", + "mongoose.Model;Member[findByIdAndUpdate,findOneAndUpdate,update,updateMany,updateOne].Argument[0,1];mongodb.sink", + "mongoose.Model;Member[find].WithArity[1,2,3,4].Argument[0];mongodb.sink", + "mongoose.Query;Member[$where,and,find,findByIdAndDelete,findOne,findOneAndDelete,findOneAndRemove,nor,or,remove,replaceOne,setUpdate].Argument[0];mongodb.sink", + "mongoose.Query;Member[count,where].WithArity[1,2].Argument[0];mongodb.sink", + "mongoose.Query;Member[deleteMany,deleteOne].WithArity[0,1,2,3].Argument[0];mongodb.sink", + "mongoose.Query;Member[distinct,where].Argument[1];mongodb.sink", + "mongoose.Query;Member[findByIdAndUpdate,findOneAndUpdate,update,updateMany,updateOne].Argument[0,1];mongodb.sink", + "mongoose.Query;Member[find].WithArity[1,2,3,4].Argument[0];mongodb.sink", + "mongoose.QueryStatic;Argument[2];mongodb.sink" ] }, "generatedModel": { "//": "Autogenerated section. Manual edits in here will be lost.", "typeDefinitions": [ - "mongodb;;mongoose;;Member[mongodb]", - "mongodb;AbstractCursor;mongodb;FindCursor;", - "mongodb;AbstractCursor;mongodb;ListCollectionsCursor;", - "mongodb;AbstractCursor;mongodb;ListIndexesCursor;", - "mongodb;AbstractCursorOptions;mongodb/mongodb;AbstractCursorOptions;", - "mongodb;AbstractCursorOptions;mongodb;AggregationCursorOptions;", - "mongodb;AbstractCursorOptions;mongoose;mongodb.AbstractCursorOptions;", - "mongodb;AddUserOptions;mongodb/mongodb;AddUserOptions;", - "mongodb;AddUserOptions;mongodb;Admin;Member[addUser].Argument[1,2]", - "mongodb;AddUserOptions;mongodb;Db;Member[addUser].Argument[1,2]", - "mongodb;AddUserOptions;mongoose;mongodb.AddUserOptions;", - "mongodb;Admin;mongodb/mongodb;Admin;", - "mongodb;Admin;mongodb;AdminStatic;Instance", - "mongodb;Admin;mongodb;Db;Member[admin].ReturnValue", - "mongodb;Admin;mongoose;mongodb.Admin;", - "mongodb;AdminStatic;mongodb/mongodb;AdminStatic;", - "mongodb;AdminStatic;mongodb;;Member[Admin]", - "mongodb;AdminStatic;mongoose;mongodb.AdminStatic;", - "mongodb;AggregateOptions;mongodb/mongodb;AggregateOptions;", - "mongodb;AggregateOptions;mongodb;AggregationCursorOptions;", - "mongodb;AggregateOptions;mongodb;ChangeStreamOptions;", - "mongodb;AggregateOptions;mongodb;Collection;Member[aggregate].Argument[1]", - "mongodb;AggregateOptions;mongodb;CountDocumentsOptions;", - "mongodb;AggregateOptions;mongodb;Db;Member[aggregate].Argument[1]", - "mongodb;AggregateOptions;mongoose;mongodb.AggregateOptions;", - "mongodb;AggregationCursorOptions;mongodb/mongodb;AggregationCursorOptions;", - "mongodb;AggregationCursorOptions;mongoose;mongodb.AggregationCursorOptions;", - "mongodb;AnyBulkWriteOperation;mongodb/mongodb;AnyBulkWriteOperation;", - "mongodb;AnyBulkWriteOperation;mongodb;BulkOperationBase;Member[raw].Argument[0]", - "mongodb;AnyBulkWriteOperation;mongodb;Collection;Member[bulkWrite].Argument[0].ArrayElement", - "mongodb;AnyBulkWriteOperation;mongoose;mongodb.AnyBulkWriteOperation;", - "mongodb;Auth;mongodb/mongodb;Auth;", - "mongodb;Auth;mongodb;MongoClientOptions;Member[auth]", - "mongodb;Auth;mongoose;mongodb.Auth;", - "mongodb;AutoEncrypter;mongodb/mongodb;AutoEncrypter;", - "mongodb;AutoEncrypter;mongodb;AutoEncrypter;Instance", - "mongodb;AutoEncrypter;mongodb;ConnectionOptions;Member[autoEncrypter]", - "mongodb;AutoEncrypter;mongodb;MongoClient;Member[autoEncrypter]", - "mongodb;AutoEncrypter;mongodb;MongoOptions;Member[autoEncrypter]", - "mongodb;AutoEncrypter;mongoose;mongodb.AutoEncrypter;", - "mongodb;AutoEncryptionOptions;mongodb/mongodb;AutoEncryptionOptions;", - "mongodb;AutoEncryptionOptions;mongodb;AutoEncrypter;Argument[1]", - "mongodb;AutoEncryptionOptions;mongodb;MongoClientOptions;Member[autoEncryption]", - "mongodb;AutoEncryptionOptions;mongoose;mongodb.AutoEncryptionOptions;", - "mongodb;BulkOperationBase;mongodb/mongodb;BulkOperationBase;", - "mongodb;BulkOperationBase;mongodb;BulkOperationBase;Member[addToOperationsList,insert,raw].ReturnValue", - "mongodb;BulkOperationBase;mongodb;BulkOperationBaseStatic;Instance", - "mongodb;BulkOperationBase;mongodb;FindOperators;Member[bulkOperation]", - "mongodb;BulkOperationBase;mongodb;FindOperators;Member[delete,deleteOne,replaceOne,update,updateOne].ReturnValue", - "mongodb;BulkOperationBase;mongodb;OrderedBulkOperation;", - "mongodb;BulkOperationBase;mongodb;UnorderedBulkOperation;", - "mongodb;BulkOperationBase;mongoose;mongodb.BulkOperationBase;", - "mongodb;BulkOperationBaseStatic;mongodb/mongodb;BulkOperationBaseStatic;", - "mongodb;BulkOperationBaseStatic;mongodb;;Member[BulkOperationBase]", - "mongodb;BulkOperationBaseStatic;mongoose;mongodb.BulkOperationBaseStatic;", - "mongodb;BulkWriteOptions;mongodb/mongodb;BulkWriteOptions;", - "mongodb;BulkWriteOptions;mongodb;BulkOperationBase;Member[execute].WithArity[0,1,2].Argument[0]", - "mongodb;BulkWriteOptions;mongodb;Collection;Member[bulkWrite,insert,insertMany].Argument[1]", - "mongodb;BulkWriteOptions;mongodb;Collection;Member[initializeOrderedBulkOp,initializeUnorderedBulkOp].Argument[0]", - "mongodb;BulkWriteOptions;mongodb;OrderedBulkOperationStatic;Argument[1]", - "mongodb;BulkWriteOptions;mongodb;UnorderedBulkOperationStatic;Argument[1]", - "mongodb;BulkWriteOptions;mongoose;mongodb.BulkWriteOptions;", - "mongodb;ChangeStream;mongodb/mongodb;ChangeStream;", - "mongodb;ChangeStream;mongodb;ChangeStreamStatic;Instance", - "mongodb;ChangeStream;mongodb;Collection;Member[watch].ReturnValue", - "mongodb;ChangeStream;mongodb;Db;Member[watch].ReturnValue", - "mongodb;ChangeStream;mongodb;MongoClient;Member[watch].ReturnValue", - "mongodb;ChangeStream;mongoose;mongodb.ChangeStream;", - "mongodb;ChangeStreamOptions;mongodb/mongodb;ChangeStreamOptions;", - "mongodb;ChangeStreamOptions;mongodb;ChangeStream;Member[options]", - "mongodb;ChangeStreamOptions;mongodb;Collection;Member[watch].Argument[1]", - "mongodb;ChangeStreamOptions;mongodb;Db;Member[watch].Argument[1]", - "mongodb;ChangeStreamOptions;mongodb;MongoClient;Member[watch].Argument[1]", - "mongodb;ChangeStreamOptions;mongoose;mongodb.ChangeStreamOptions;", - "mongodb;ChangeStreamStatic;mongodb/mongodb;ChangeStreamStatic;", - "mongodb;ChangeStreamStatic;mongodb;;Member[ChangeStream]", - "mongodb;ChangeStreamStatic;mongoose;mongodb.ChangeStreamStatic;", - "mongodb;ClientSession;mongodb/mongodb;ClientSession;", - "mongodb;ClientSession;mongodb;AbstractCursorOptions;Member[session]", - "mongodb;ClientSession;mongodb;ClientSession;Member[equals].Argument[0]", - "mongodb;ClientSession;mongodb;ClientSessionEvents;Member[ended].Argument[0]", - "mongodb;ClientSession;mongodb;ClientSessionStatic;Instance", - "mongodb;ClientSession;mongodb;IndexInformationOptions;Member[session]", - "mongodb;ClientSession;mongodb;MongoClient;Member[startSession].ReturnValue", - "mongodb;ClientSession;mongodb;OperationOptions;Member[session]", - "mongodb;ClientSession;mongodb;ReadPreferenceFromOptions;Member[session]", - "mongodb;ClientSession;mongodb;SelectServerOptions;Member[session]", - "mongodb;ClientSession;mongodb;WithSessionCallback;Argument[0]", - "mongodb;ClientSession;mongodb;WithTransactionCallback;Argument[0]", - "mongodb;ClientSession;mongoose;mongodb.ClientSession;", - "mongodb;ClientSessionEvents;mongodb/mongodb;ClientSessionEvents;", - "mongodb;ClientSessionEvents;mongoose;mongodb.ClientSessionEvents;", - "mongodb;ClientSessionOptions;mongodb/mongodb;ClientSessionOptions;", - "mongodb;ClientSessionOptions;mongodb;MongoClient;Member[startSession].Argument[0]", - "mongodb;ClientSessionOptions;mongodb;MongoClient;Member[withSession].WithArity[2].Argument[0]", - "mongodb;ClientSessionOptions;mongoose;mongodb.ClientSessionOptions;", - "mongodb;ClientSessionStatic;mongodb/mongodb;ClientSessionStatic;", - "mongodb;ClientSessionStatic;mongodb;;Member[ClientSession]", - "mongodb;ClientSessionStatic;mongoose;mongodb.ClientSessionStatic;", - "mongodb;CollStatsOptions;mongodb/mongodb;CollStatsOptions;", - "mongodb;CollStatsOptions;mongodb;Collection;Member[stats].Argument[0]", - "mongodb;CollStatsOptions;mongoose;mongodb.CollStatsOptions;", - "mongodb;Collection;mongodb/mongodb;Collection;", - "mongodb;Collection;mongodb;ChangeStream;Member[parent]", - "mongodb;Collection;mongodb;Collection;Member[rename].Argument[1,2].TypeVar[mongodb.Callback.0]", - "mongodb;Collection;mongodb;Collection;Member[rename].WithArity[1,2].ReturnValue.Awaited", - "mongodb;Collection;mongodb;CollectionStatic;Instance", - "mongodb;Collection;mongodb;Db;Member[collection].ReturnValue", - "mongodb;Collection;mongodb;Db;Member[collections].Argument[0,1].TypeVar[mongodb.Callback.0].ArrayElement", - "mongodb;Collection;mongodb;Db;Member[collections].WithArity[0,1].ReturnValue.Awaited.ArrayElement", - "mongodb;Collection;mongodb;Db;Member[createCollection].Argument[2].TypeVar[mongodb.Callback.0]", - "mongodb;Collection;mongodb;Db;Member[createCollection].WithArity[1,2].ReturnValue.Awaited", - "mongodb;Collection;mongodb;Db;Member[createCollection].WithArity[2].Argument[1].TypeVar[mongodb.Callback.0]", - "mongodb;Collection;mongodb;Db;Member[renameCollection].Argument[2,3].TypeVar[mongodb.Callback.0]", - "mongodb;Collection;mongodb;Db;Member[renameCollection].WithArity[2,3].ReturnValue.Awaited", - "mongodb;Collection;mongodb;GridFSBucketWriteStream;Member[chunks,files]", - "mongodb;Collection;mongodb;ListIndexesCursor;Member[parent]", - "mongodb;Collection;mongodb;ListIndexesCursorStatic;Argument[0]", - "mongodb;Collection;mongodb;OrderedBulkOperationStatic;Argument[0]", - "mongodb;Collection;mongodb;UnorderedBulkOperationStatic;Argument[0]", - "mongodb;Collection;mongoose;mongodb.Collection;", - "mongodb;CollectionStatic;mongodb/mongodb;CollectionStatic;", - "mongodb;CollectionStatic;mongodb;;Member[Collection]", - "mongodb;CollectionStatic;mongoose;mongodb.CollectionStatic;", - "mongodb;CommandOperationOptions;mongodb/mongodb;CommandOperationOptions;", - "mongodb;CommandOperationOptions;mongodb;AddUserOptions;", - "mongodb;CommandOperationOptions;mongodb;Admin;Member[buildInfo,ping,replSetGetStatus,serverInfo,serverStatus].Argument[0]", - "mongodb;CommandOperationOptions;mongodb;AggregateOptions;", - "mongodb;CommandOperationOptions;mongodb;BulkWriteOptions;", - "mongodb;CommandOperationOptions;mongodb;CollStatsOptions;", - "mongodb;CommandOperationOptions;mongodb;CountOptions;", - "mongodb;CommandOperationOptions;mongodb;CreateCollectionOptions;", - "mongodb;CommandOperationOptions;mongodb;CreateIndexesOptions;", - "mongodb;CommandOperationOptions;mongodb;DbStatsOptions;", - "mongodb;CommandOperationOptions;mongodb;DeleteOptions;", - "mongodb;CommandOperationOptions;mongodb;DistinctOptions;", - "mongodb;CommandOperationOptions;mongodb;DropCollectionOptions;", - "mongodb;CommandOperationOptions;mongodb;DropDatabaseOptions;", - "mongodb;CommandOperationOptions;mongodb;DropIndexesOptions;", - "mongodb;CommandOperationOptions;mongodb;EstimatedDocumentCountOptions;", - "mongodb;CommandOperationOptions;mongodb;EvalOptions;", - "mongodb;CommandOperationOptions;mongodb;FindOneAndDeleteOptions;", - "mongodb;CommandOperationOptions;mongodb;FindOneAndReplaceOptions;", - "mongodb;CommandOperationOptions;mongodb;FindOneAndUpdateOptions;", - "mongodb;CommandOperationOptions;mongodb;FindOptions;", - "mongodb;CommandOperationOptions;mongodb;InsertOneOptions;", - "mongodb;CommandOperationOptions;mongodb;ListCollectionsOptions;", - "mongodb;CommandOperationOptions;mongodb;ListDatabasesOptions;", - "mongodb;CommandOperationOptions;mongodb;ListIndexesOptions;", - "mongodb;CommandOperationOptions;mongodb;MapReduceOptions;", - "mongodb;CommandOperationOptions;mongodb;ProfilingLevelOptions;", - "mongodb;CommandOperationOptions;mongodb;RemoveUserOptions;", - "mongodb;CommandOperationOptions;mongodb;RenameOptions;", - "mongodb;CommandOperationOptions;mongodb;ReplaceOptions;", - "mongodb;CommandOperationOptions;mongodb;RunCommandOptions;", - "mongodb;CommandOperationOptions;mongodb;SetProfilingLevelOptions;", - "mongodb;CommandOperationOptions;mongodb;TransactionOptions;", - "mongodb;CommandOperationOptions;mongodb;UpdateOptions;", - "mongodb;CommandOperationOptions;mongodb;ValidateCollectionOptions;", - "mongodb;CommandOperationOptions;mongoose;mongodb.CommandOperationOptions;", - "mongodb;ConnectionOptions;mongodb/mongodb;ConnectionOptions;", - "mongodb;ConnectionOptions;mongoose;mongodb.ConnectionOptions;", - "mongodb;CountDocumentsOptions;mongodb/mongodb;CountDocumentsOptions;", - "mongodb;CountDocumentsOptions;mongodb;Collection;Member[countDocuments].Argument[1]", - "mongodb;CountDocumentsOptions;mongoose;mongodb.CountDocumentsOptions;", - "mongodb;CountOptions;mongodb/mongodb;CountOptions;", - "mongodb;CountOptions;mongodb;Collection;Member[count].Argument[1]", - "mongodb;CountOptions;mongodb;FindCursor;Member[count].Argument[0]", - "mongodb;CountOptions;mongoose;mongodb.CountOptions;", - "mongodb;CreateCollectionOptions;mongodb/mongodb;CreateCollectionOptions;", - "mongodb;CreateCollectionOptions;mongodb;Db;Member[createCollection].WithArity[1,2,3].Argument[1]", - "mongodb;CreateCollectionOptions;mongoose;mongodb.CreateCollectionOptions;", - "mongodb;CreateIndexesOptions;mongodb/mongodb;CreateIndexesOptions;", - "mongodb;CreateIndexesOptions;mongodb;Collection;Member[createIndex,createIndexes].Argument[1]", - "mongodb;CreateIndexesOptions;mongodb;Db;Member[createIndex].Argument[2]", - "mongodb;CreateIndexesOptions;mongoose;mongodb.CreateIndexesOptions;", - "mongodb;Db;mongodb/mongodb;Db;", - "mongodb;Db;mongodb;ChangeStream;Member[parent]", - "mongodb;Db;mongodb;DbStatic;Instance", - "mongodb;Db;mongodb;GridFSBucketStatic;Argument[0]", - "mongodb;Db;mongodb;ListCollectionsCursor;Member[parent]", - "mongodb;Db;mongodb;ListCollectionsCursorStatic;Argument[0]", - "mongodb;Db;mongodb;MongoClient;Member[db].ReturnValue", - "mongodb;Db;mongoose;mongodb.Db;", - "mongodb;DbStatic;mongodb/mongodb;DbStatic;", - "mongodb;DbStatic;mongodb;;Member[Db]", - "mongodb;DbStatic;mongoose;mongodb.DbStatic;", - "mongodb;DbStatsOptions;mongodb/mongodb;DbStatsOptions;", - "mongodb;DbStatsOptions;mongodb;Db;Member[stats].Argument[0]", - "mongodb;DbStatsOptions;mongoose;mongodb.DbStatsOptions;", - "mongodb;DeleteManyModel;mongodb/mongodb;DeleteManyModel;", - "mongodb;DeleteManyModel;mongodb;AnyBulkWriteOperation;Member[deleteMany]", - "mongodb;DeleteManyModel;mongoose;mongodb.DeleteManyModel;", - "mongodb;DeleteOneModel;mongodb/mongodb;DeleteOneModel;", - "mongodb;DeleteOneModel;mongodb;AnyBulkWriteOperation;Member[deleteOne]", - "mongodb;DeleteOneModel;mongoose;mongodb.DeleteOneModel;", - "mongodb;DeleteOptions;mongodb/mongodb;DeleteOptions;", - "mongodb;DeleteOptions;mongodb;Collection;Member[deleteMany,deleteOne,remove].Argument[1]", - "mongodb;DeleteOptions;mongoose;mongodb.DeleteOptions;", - "mongodb;DistinctOptions;mongodb/mongodb;DistinctOptions;", - "mongodb;DistinctOptions;mongodb;Collection;Member[distinct].Argument[2]", - "mongodb;DistinctOptions;mongoose;mongodb.DistinctOptions;", - "mongodb;DropCollectionOptions;mongodb/mongodb;DropCollectionOptions;", - "mongodb;DropCollectionOptions;mongodb;Collection;Member[drop].Argument[0]", - "mongodb;DropCollectionOptions;mongodb;Db;Member[dropCollection].Argument[1]", - "mongodb;DropCollectionOptions;mongoose;mongodb.DropCollectionOptions;", - "mongodb;DropDatabaseOptions;mongodb/mongodb;DropDatabaseOptions;", - "mongodb;DropDatabaseOptions;mongodb;Db;Member[dropDatabase].Argument[0]", - "mongodb;DropDatabaseOptions;mongoose;mongodb.DropDatabaseOptions;", - "mongodb;DropIndexesOptions;mongodb/mongodb;DropIndexesOptions;", - "mongodb;DropIndexesOptions;mongodb;Collection;Member[dropIndex].Argument[1]", - "mongodb;DropIndexesOptions;mongodb;Collection;Member[dropIndexes].Argument[0]", - "mongodb;DropIndexesOptions;mongoose;mongodb.DropIndexesOptions;", - "mongodb;EstimatedDocumentCountOptions;mongodb/mongodb;EstimatedDocumentCountOptions;", - "mongodb;EstimatedDocumentCountOptions;mongodb;Collection;Member[estimatedDocumentCount].Argument[0]", - "mongodb;EstimatedDocumentCountOptions;mongoose;mongodb.EstimatedDocumentCountOptions;", - "mongodb;EvalOptions;mongodb/mongodb;EvalOptions;", - "mongodb;EvalOptions;mongoose;mongodb.EvalOptions;", - "mongodb;FindCursor;mongodb/mongodb;FindCursor;", - "mongodb;FindCursor;mongodb;Collection;Member[find].WithArity[0,1,2].ReturnValue", - "mongodb;FindCursor;mongodb;FindCursor;Member[addQueryModifier,allowDiskUse,clone,collation,comment,filter,hint,limit,map,max,maxAwaitTimeMS,maxTimeMS,min,project,returnKey,showRecordId,skip,sort].ReturnValue", - "mongodb;FindCursor;mongodb;FindCursorStatic;Instance", - "mongodb;FindCursor;mongodb;GridFSBucket;Member[find].ReturnValue", - "mongodb;FindCursor;mongoose;mongodb.FindCursor;", - "mongodb;FindCursorStatic;mongodb/mongodb;FindCursorStatic;", - "mongodb;FindCursorStatic;mongodb;;Member[FindCursor]", - "mongodb;FindCursorStatic;mongoose;mongodb.FindCursorStatic;", - "mongodb;FindOneAndDeleteOptions;mongodb/mongodb;FindOneAndDeleteOptions;", - "mongodb;FindOneAndDeleteOptions;mongodb;Collection;Member[findOneAndDelete].Argument[1]", - "mongodb;FindOneAndDeleteOptions;mongoose;mongodb.FindOneAndDeleteOptions;", - "mongodb;FindOneAndReplaceOptions;mongodb/mongodb;FindOneAndReplaceOptions;", - "mongodb;FindOneAndReplaceOptions;mongodb;Collection;Member[findOneAndReplace].Argument[2]", - "mongodb;FindOneAndReplaceOptions;mongoose;mongodb.FindOneAndReplaceOptions;", - "mongodb;FindOneAndUpdateOptions;mongodb/mongodb;FindOneAndUpdateOptions;", - "mongodb;FindOneAndUpdateOptions;mongodb;Collection;Member[findOneAndUpdate].Argument[2]", - "mongodb;FindOneAndUpdateOptions;mongoose;mongodb.FindOneAndUpdateOptions;", - "mongodb;FindOperators;mongodb/mongodb;FindOperators;", - "mongodb;FindOperators;mongodb;BulkOperationBase;Member[find].ReturnValue", - "mongodb;FindOperators;mongodb;FindOperators;Member[arrayFilters,collation,upsert].ReturnValue", - "mongodb;FindOperators;mongodb;FindOperatorsStatic;Instance", - "mongodb;FindOperators;mongoose;mongodb.FindOperators;", - "mongodb;FindOperatorsStatic;mongodb/mongodb;FindOperatorsStatic;", - "mongodb;FindOperatorsStatic;mongodb;;Member[FindOperators]", - "mongodb;FindOperatorsStatic;mongoose;mongodb.FindOperatorsStatic;", - "mongodb;FindOptions;mongodb/mongodb;FindOptions;", - "mongodb;FindOptions;mongodb;Collection;Member[find,findOne].Argument[1]", - "mongodb;FindOptions;mongodb;GridFSBucket;Member[find].Argument[1]", - "mongodb;FindOptions;mongoose;mongodb.FindOptions;", - "mongodb;GridFSBucket;mongodb/mongodb;GridFSBucket;", - "mongodb;GridFSBucket;mongodb;GridFSBucketStatic;Instance", - "mongodb;GridFSBucket;mongodb;GridFSBucketWriteStream;Member[bucket]", - "mongodb;GridFSBucket;mongoose;mongodb.GridFSBucket;", - "mongodb;GridFSBucketStatic;mongodb/mongodb;GridFSBucketStatic;", - "mongodb;GridFSBucketStatic;mongodb;;Member[GridFSBucket]", - "mongodb;GridFSBucketStatic;mongoose;mongodb.GridFSBucketStatic;", - "mongodb;GridFSBucketWriteStream;mongodb/mongodb;GridFSBucketWriteStream;", - "mongodb;GridFSBucketWriteStream;mongodb;GridFSBucket;Member[openUploadStream,openUploadStreamWithId].ReturnValue", - "mongodb;GridFSBucketWriteStream;mongodb;GridFSBucketWriteStream;Member[end].ReturnValue", - "mongodb;GridFSBucketWriteStream;mongodb;GridFSBucketWriteStreamStatic;Instance", - "mongodb;GridFSBucketWriteStream;mongoose;mongodb.GridFSBucketWriteStream;", - "mongodb;GridFSBucketWriteStreamStatic;mongodb/mongodb;GridFSBucketWriteStreamStatic;", - "mongodb;GridFSBucketWriteStreamStatic;mongodb;;Member[GridFSBucketWriteStream]", - "mongodb;GridFSBucketWriteStreamStatic;mongoose;mongodb.GridFSBucketWriteStreamStatic;", - "mongodb;IndexInformationOptions;mongodb/mongodb;IndexInformationOptions;", - "mongodb;IndexInformationOptions;mongodb;Collection;Member[indexExists].Argument[1]", - "mongodb;IndexInformationOptions;mongodb;Collection;Member[indexInformation,indexes].Argument[0]", - "mongodb;IndexInformationOptions;mongodb;Db;Member[indexInformation].Argument[1]", - "mongodb;IndexInformationOptions;mongoose;mongodb.IndexInformationOptions;", - "mongodb;InsertOneOptions;mongodb/mongodb;InsertOneOptions;", - "mongodb;InsertOneOptions;mongodb;Collection;Member[insertOne].Argument[1]", - "mongodb;InsertOneOptions;mongoose;mongodb.InsertOneOptions;", - "mongodb;ListCollectionsCursor;mongodb/mongodb;ListCollectionsCursor;", - "mongodb;ListCollectionsCursor;mongodb;Db;Member[listCollections].WithArity[0,1,2].ReturnValue", - "mongodb;ListCollectionsCursor;mongodb;ListCollectionsCursor;Member[clone].ReturnValue", - "mongodb;ListCollectionsCursor;mongodb;ListCollectionsCursorStatic;Instance", - "mongodb;ListCollectionsCursor;mongoose;mongodb.ListCollectionsCursor;", - "mongodb;ListCollectionsCursorStatic;mongodb/mongodb;ListCollectionsCursorStatic;", - "mongodb;ListCollectionsCursorStatic;mongodb;;Member[ListCollectionsCursor]", - "mongodb;ListCollectionsCursorStatic;mongoose;mongodb.ListCollectionsCursorStatic;", - "mongodb;ListCollectionsOptions;mongodb/mongodb;ListCollectionsOptions;", - "mongodb;ListCollectionsOptions;mongodb;Db;Member[collections].Argument[0]", - "mongodb;ListCollectionsOptions;mongodb;Db;Member[listCollections].WithArity[0,1,2].Argument[1]", - "mongodb;ListCollectionsOptions;mongodb;ListCollectionsCursor;Member[options]", - "mongodb;ListCollectionsOptions;mongodb;ListCollectionsCursorStatic;Argument[2]", - "mongodb;ListCollectionsOptions;mongoose;mongodb.ListCollectionsOptions;", - "mongodb;ListDatabasesOptions;mongodb/mongodb;ListDatabasesOptions;", - "mongodb;ListDatabasesOptions;mongodb;Admin;Member[listDatabases].Argument[0]", - "mongodb;ListDatabasesOptions;mongoose;mongodb.ListDatabasesOptions;", - "mongodb;ListIndexesCursor;mongodb/mongodb;ListIndexesCursor;", - "mongodb;ListIndexesCursor;mongodb;Collection;Member[listIndexes].ReturnValue", - "mongodb;ListIndexesCursor;mongodb;ListIndexesCursor;Member[clone].ReturnValue", - "mongodb;ListIndexesCursor;mongodb;ListIndexesCursorStatic;Instance", - "mongodb;ListIndexesCursor;mongoose;mongodb.ListIndexesCursor;", - "mongodb;ListIndexesCursorStatic;mongodb/mongodb;ListIndexesCursorStatic;", - "mongodb;ListIndexesCursorStatic;mongodb;;Member[ListIndexesCursor]", - "mongodb;ListIndexesCursorStatic;mongoose;mongodb.ListIndexesCursorStatic;", - "mongodb;ListIndexesOptions;mongodb/mongodb;ListIndexesOptions;", - "mongodb;ListIndexesOptions;mongodb;Collection;Member[listIndexes].Argument[0]", - "mongodb;ListIndexesOptions;mongodb;ListIndexesCursor;Member[options]", - "mongodb;ListIndexesOptions;mongodb;ListIndexesCursorStatic;Argument[1]", - "mongodb;ListIndexesOptions;mongoose;mongodb.ListIndexesOptions;", - "mongodb;MapReduceOptions;mongodb/mongodb;MapReduceOptions;", - "mongodb;MapReduceOptions;mongodb;Collection;Member[mapReduce].Argument[2]", - "mongodb;MapReduceOptions;mongoose;mongodb.MapReduceOptions;", - "mongodb;MongoClient;mongodb/mongodb;MongoClient;", - "mongodb;MongoClient;mongodb;AutoEncrypter;Argument[0]", - "mongodb;MongoClient;mongodb;AutoEncryptionOptions;Member[keyVaultClient]", - "mongodb;MongoClient;mongodb;ChangeStream;Member[parent]", - "mongodb;MongoClient;mongodb;DbStatic;Argument[0]", - "mongodb;MongoClient;mongodb;MongoClient;Member[connect].Argument[0].TypeVar[mongodb.Callback.0]", - "mongodb;MongoClient;mongodb;MongoClient;Member[connect].WithArity[0].ReturnValue.Awaited", - "mongodb;MongoClient;mongodb;MongoClientEvents;Member[open].Argument[0]", - "mongodb;MongoClient;mongodb;MongoClientStatic;Instance", - "mongodb;MongoClient;mongodb;MongoClientStatic;Member[connect].Argument[1,2].TypeVar[mongodb.Callback.0]", - "mongodb;MongoClient;mongodb;MongoClientStatic;Member[connect].WithArity[1,2].ReturnValue.Awaited", - "mongodb;MongoClient;mongoose;mongodb.MongoClient;", - "mongodb;MongoClientEvents;mongodb/mongodb;MongoClientEvents;", - "mongodb;MongoClientEvents;mongoose;mongodb.MongoClientEvents;", - "mongodb;MongoClientOptions;mongodb/mongodb;MongoClientOptions;", - "mongodb;MongoClientOptions;mongodb;MongoClientStatic;Argument[1]", - "mongodb;MongoClientOptions;mongodb;MongoClientStatic;Member[connect].Argument[1]", - "mongodb;MongoClientOptions;mongoose;mongodb.MongoClientOptions;", - "mongodb;MongoClientStatic;mongodb/mongodb;MongoClientStatic;", - "mongodb;MongoClientStatic;mongodb;;Member[MongoClient]", - "mongodb;MongoClientStatic;mongoose;mongodb.MongoClientStatic;", - "mongodb;MongoOptions;mongodb/mongodb;MongoOptions;", - "mongodb;MongoOptions;mongodb;ClientSession;Member[clientOptions]", - "mongodb;MongoOptions;mongodb;MongoClient;Member[options]", - "mongodb;MongoOptions;mongoose;mongodb.MongoOptions;", - "mongodb;OperationOptions;mongodb/mongodb;OperationOptions;", - "mongodb;OperationOptions;mongodb;Collection;Member[isCapped,options].Argument[0]", - "mongodb;OperationOptions;mongodb;CommandOperationOptions;", - "mongodb;OperationOptions;mongoose;mongodb.OperationOptions;", - "mongodb;OrderedBulkOperation;mongodb/mongodb;OrderedBulkOperation;", - "mongodb;OrderedBulkOperation;mongodb;Collection;Member[initializeOrderedBulkOp].ReturnValue", - "mongodb;OrderedBulkOperation;mongodb;OrderedBulkOperation;Member[addToOperationsList].ReturnValue", - "mongodb;OrderedBulkOperation;mongodb;OrderedBulkOperationStatic;Instance", - "mongodb;OrderedBulkOperation;mongoose;mongodb.OrderedBulkOperation;", - "mongodb;OrderedBulkOperationStatic;mongodb/mongodb;OrderedBulkOperationStatic;", - "mongodb;OrderedBulkOperationStatic;mongodb;;Member[OrderedBulkOperation]", - "mongodb;OrderedBulkOperationStatic;mongoose;mongodb.OrderedBulkOperationStatic;", - "mongodb;ProfilingLevelOptions;mongodb/mongodb;ProfilingLevelOptions;", - "mongodb;ProfilingLevelOptions;mongodb;Db;Member[profilingLevel].Argument[0]", - "mongodb;ProfilingLevelOptions;mongoose;mongodb.ProfilingLevelOptions;", - "mongodb;ReadPreferenceFromOptions;mongodb/mongodb;ReadPreferenceFromOptions;", - "mongodb;ReadPreferenceFromOptions;mongodb;ReadPreferenceStatic;Member[fromOptions].Argument[0]", - "mongodb;ReadPreferenceFromOptions;mongoose;mongodb.ReadPreferenceFromOptions;", - "mongodb;ReadPreferenceStatic;mongodb/mongodb;ReadPreferenceStatic;", - "mongodb;ReadPreferenceStatic;mongodb;;Member[ReadPreference]", - "mongodb;ReadPreferenceStatic;mongoose;mongodb.ReadPreferenceStatic;", - "mongodb;RemoveUserOptions;mongodb/mongodb;RemoveUserOptions;", - "mongodb;RemoveUserOptions;mongodb;Admin;Member[removeUser].Argument[1]", - "mongodb;RemoveUserOptions;mongodb;Db;Member[removeUser].Argument[1]", - "mongodb;RemoveUserOptions;mongoose;mongodb.RemoveUserOptions;", - "mongodb;RenameOptions;mongodb/mongodb;RenameOptions;", - "mongodb;RenameOptions;mongodb;Collection;Member[rename].Argument[1]", - "mongodb;RenameOptions;mongodb;Db;Member[renameCollection].Argument[2]", - "mongodb;RenameOptions;mongoose;mongodb.RenameOptions;", - "mongodb;ReplaceOptions;mongodb/mongodb;ReplaceOptions;", - "mongodb;ReplaceOptions;mongodb;Collection;Member[replaceOne].Argument[2]", - "mongodb;ReplaceOptions;mongoose;mongodb.ReplaceOptions;", - "mongodb;RunCommandOptions;mongodb/mongodb;RunCommandOptions;", - "mongodb;RunCommandOptions;mongodb;Admin;Member[command].Argument[1]", - "mongodb;RunCommandOptions;mongodb;Db;Member[command].Argument[1]", - "mongodb;RunCommandOptions;mongoose;mongodb.RunCommandOptions;", - "mongodb;SelectServerOptions;mongodb/mongodb;SelectServerOptions;", - "mongodb;SelectServerOptions;mongoose;mongodb.SelectServerOptions;", - "mongodb;SetProfilingLevelOptions;mongodb/mongodb;SetProfilingLevelOptions;", - "mongodb;SetProfilingLevelOptions;mongodb;Db;Member[setProfilingLevel].Argument[1]", - "mongodb;SetProfilingLevelOptions;mongoose;mongodb.SetProfilingLevelOptions;", - "mongodb;Transaction;mongodb/mongodb;Transaction;", - "mongodb;Transaction;mongodb;ClientSession;Member[transaction]", - "mongodb;Transaction;mongodb;TransactionStatic;Instance", - "mongodb;Transaction;mongoose;mongodb.Transaction;", - "mongodb;TransactionOptions;mongodb/mongodb;TransactionOptions;", - "mongodb;TransactionOptions;mongodb;ClientSession;Member[defaultTransactionOptions]", - "mongodb;TransactionOptions;mongodb;ClientSession;Member[startTransaction].Argument[0]", - "mongodb;TransactionOptions;mongodb;ClientSession;Member[withTransaction].Argument[1]", - "mongodb;TransactionOptions;mongodb;ClientSessionOptions;Member[defaultTransactionOptions]", - "mongodb;TransactionOptions;mongodb;Transaction;Member[options]", - "mongodb;TransactionOptions;mongoose;mongodb.TransactionOptions;", - "mongodb;TransactionStatic;mongodb/mongodb;TransactionStatic;", - "mongodb;TransactionStatic;mongodb;;Member[Transaction]", - "mongodb;TransactionStatic;mongoose;mongodb.TransactionStatic;", - "mongodb;TypedEventEmitter;mongodb;AbstractCursor;", - "mongodb;TypedEventEmitter;mongodb;ChangeStream;", - "mongodb;TypedEventEmitter;mongodb;ClientSession;", - "mongodb;TypedEventEmitter;mongodb;GridFSBucket;", - "mongodb;TypedEventEmitter;mongodb;MongoClient;", - "mongodb;UnorderedBulkOperation;mongodb/mongodb;UnorderedBulkOperation;", - "mongodb;UnorderedBulkOperation;mongodb;Collection;Member[initializeUnorderedBulkOp].ReturnValue", - "mongodb;UnorderedBulkOperation;mongodb;UnorderedBulkOperation;Member[addToOperationsList].ReturnValue", - "mongodb;UnorderedBulkOperation;mongodb;UnorderedBulkOperationStatic;Instance", - "mongodb;UnorderedBulkOperation;mongoose;mongodb.UnorderedBulkOperation;", - "mongodb;UnorderedBulkOperationStatic;mongodb/mongodb;UnorderedBulkOperationStatic;", - "mongodb;UnorderedBulkOperationStatic;mongodb;;Member[UnorderedBulkOperation]", - "mongodb;UnorderedBulkOperationStatic;mongoose;mongodb.UnorderedBulkOperationStatic;", - "mongodb;UpdateManyModel;mongodb/mongodb;UpdateManyModel;", - "mongodb;UpdateManyModel;mongodb;AnyBulkWriteOperation;Member[updateMany]", - "mongodb;UpdateManyModel;mongoose;mongodb.UpdateManyModel;", - "mongodb;UpdateOneModel;mongodb/mongodb;UpdateOneModel;", - "mongodb;UpdateOneModel;mongodb;AnyBulkWriteOperation;Member[updateOne]", - "mongodb;UpdateOneModel;mongoose;mongodb.UpdateOneModel;", - "mongodb;UpdateOptions;mongodb/mongodb;UpdateOptions;", - "mongodb;UpdateOptions;mongodb;Collection;Member[update,updateMany,updateOne].Argument[2]", - "mongodb;UpdateOptions;mongoose;mongodb.UpdateOptions;", - "mongodb;ValidateCollectionOptions;mongodb/mongodb;ValidateCollectionOptions;", - "mongodb;ValidateCollectionOptions;mongodb;Admin;Member[validateCollection].Argument[1]", - "mongodb;ValidateCollectionOptions;mongoose;mongodb.ValidateCollectionOptions;", - "mongodb;WithSessionCallback;mongodb/mongodb;WithSessionCallback;", - "mongodb;WithSessionCallback;mongodb;MongoClient;Member[withSession].Argument[1]", - "mongodb;WithSessionCallback;mongodb;MongoClient;Member[withSession].WithArity[1].Argument[0]", - "mongodb;WithSessionCallback;mongoose;mongodb.WithSessionCallback;", - "mongodb;WithTransactionCallback;mongodb/mongodb;WithTransactionCallback;", - "mongodb;WithTransactionCallback;mongodb;ClientSession;Member[withTransaction].Argument[0]", - "mongodb;WithTransactionCallback;mongoose;mongodb.WithTransactionCallback;", - "mongoose/inferschematype;ResolvePathType;mongoose/inferschematype;ObtainDocumentPathType;", - "mongoose/inferschematype;ResolvePathType;mongoose/inferschematype;ResolvePathType;TypeVar[mongoose.IfEquals.3].ArrayElement", - "mongoose/inferschematype;ResolvePathType;mongoose/inferschematype;ResolvePathType;TypeVar[mongoose.IfEquals.3].TypeVar[mongoose.Types.DocumentArray.0]", - "mongoose;;mongoose;;Member[mongoose]", - "mongoose;AcceptsDiscriminator;mongoose;Model;", - "mongoose;AcceptsDiscriminator;mongoose;Schema.Types.Array;", - "mongoose;AcceptsDiscriminator;mongoose;Schema.Types.DocumentArray;", - "mongoose;AcceptsDiscriminator;mongoose;Schema.Types.Subdocument;", - "mongoose;Aggregate;mongoose;Aggregate;Member[addCursorFlag,addFields,allowDiskUse,append,collation,count,facet,graphLookup,group,hint,limit,lookup,match,model,near,option,project,read,readConcern,redact,replaceRoot,sample,search,session,skip,sort,sortByCount,unionWith,unwind].ReturnValue", - "mongoose;Aggregate;mongoose;AggregateStatic;Instance", - "mongoose;Aggregate;mongoose;Model;Member[aggregate].ReturnValue", - "mongoose;AggregateStatic;mongoose;;Member[Aggregate]", - "mongoose;Collection;mongoose;;Member[Collection]", - "mongoose;Collection;mongoose;Collection;Instance", - "mongoose;Collection;mongoose;Connection;Member[collection].ReturnValue", - "mongoose;Collection;mongoose;Connection;Member[collections].AnyMember", - "mongoose;Collection;mongoose;Document;Member[collection]", - "mongoose;Collection;mongoose;Model;Member[collection]", - "mongoose;CollectionBase;mongoose;Collection;", - "mongoose;CompileModelOptions;mongoose;;Member[model].Argument[3]", - "mongoose;CompileModelOptions;mongoose;Connection;Member[model].Argument[3]", - "mongoose;ConnectOptions;mongoose;;Member[connect,createConnection].WithArity[1,2,3].Argument[1]", - "mongoose;ConnectOptions;mongoose;Connection;Member[openUri].WithArity[1,2,3].Argument[1]", - "mongoose;Connection;mongoose;;Member[connection]", - "mongoose;Connection;mongoose;;Member[connections].ArrayElement", - "mongoose;Connection;mongoose;;Member[createConnection].Argument[2].TypeVar[mongoose.Callback.0]", - "mongoose;Connection;mongoose;;Member[createConnection].WithArity[0,1,2].ReturnValue", - "mongoose;Connection;mongoose;;Member[createConnection].WithArity[2].Argument[1].TypeVar[mongoose.Callback.0]", - "mongoose;Connection;mongoose;Collection;Argument[1]", - "mongoose;Connection;mongoose;CollectionBase;Member[conn]", - "mongoose;Connection;mongoose;CompileModelOptions;Member[connection]", - "mongoose;Connection;mongoose;Connection;Member[asPromise].ReturnValue.Awaited", - "mongoose;Connection;mongoose;Connection;Member[deleteModel,plugin,setClient,useDb].ReturnValue", - "mongoose;Connection;mongoose;Connection;Member[openUri].Argument[2].TypeVar[mongoose.Callback.0]", - "mongoose;Connection;mongoose;Connection;Member[openUri].WithArity[1,2].ReturnValue.Awaited", - "mongoose;Connection;mongoose;Connection;Member[openUri].WithArity[2,3].ReturnValue", - "mongoose;Connection;mongoose;Connection;Member[openUri].WithArity[2].Argument[1].TypeVar[mongoose.Callback.0]", - "mongoose;Connection;mongoose;ConnectionStatic;Instance", - "mongoose;Connection;mongoose;Document;Member[db]", - "mongoose;Connection;mongoose;Model;Member[db]", - "mongoose;ConnectionStatic;mongoose;;Member[Connection]", - "mongoose;Cursor;mongoose;Query;Member[cursor].ReturnValue", - "mongoose;DiscriminatorModel;mongoose;DiscriminatorSchema;TypeVar[mongoose.Schema.1]", - "mongoose;Document;mongoose;Document;Member[$getAllSubdocs,$getPopulatedDocs].ReturnValue.ArrayElement", - "mongoose;Document;mongoose;Document;Member[$inc,$parent,$set,depopulate,increment,init,overwrite,set].ReturnValue", - "mongoose;Document;mongoose;Document;Member[delete,deleteOne].WithArity[0,1].ReturnValue.TypeVar[mongoose.QueryWithHelpers.1]", - "mongoose;Document;mongoose;Document;Member[equals].Argument[0]", - "mongoose;Document;mongoose;Document;Member[init].Argument[2].TypeVar[mongoose.Callback.0]", - "mongoose;Document;mongoose;Document;Member[remove,save].WithArity[0,1].ReturnValue.Awaited", - "mongoose;Document;mongoose;Document;Member[replaceOne,update,updateOne].ReturnValue.TypeVar[mongoose.Query.1]", - "mongoose;Document;mongoose;Document;Member[save].Argument[1].TypeVar[mongoose.Callback.0]", - "mongoose;Document;mongoose;Document;Member[save].WithArity[1].Argument[0].TypeVar[mongoose.Callback.0]", - "mongoose;Document;mongoose;DocumentStatic;Instance", - "mongoose;Document;mongoose;Error.VersionErrorStatic;Argument[0]", - "mongoose;Document;mongoose;HydratedDocument;", - "mongoose;Document;mongoose;HydratedDocument;TypeVar[mongoose.Require_id.0]", - "mongoose;Document;mongoose;Model;Member[bulkSave].Argument[0].ArrayElement", - "mongoose;Document;mongoose;TVirtualPathFN;Argument[2]", - "mongoose;Document;mongoose;Types.Subdocument;", - "mongoose;Document;mongoose;Types.Subdocument;Member[$parent,ownerDocument,parent].ReturnValue", - "mongoose;Document;mongoose;VirtualType;Member[applyGetters,applySetters].Argument[1]", - "mongoose;DocumentStatic;mongoose;;Member[Document]", - "mongoose;Error.VersionErrorStatic;mongoose;;Member[Error].Member[VersionError]", - "mongoose;HydratedDocument;mongoose;Model;Instance", - "mongoose;HydratedDocument;mongoose;Model;Member[$where,count,countDocuments,deleteMany,deleteOne,distinct,estimatedDocumentCount,find,geoSearch,remove,replaceOne,update,updateMany,updateOne,where].ReturnValue.TypeVar[mongoose.QueryWithHelpers.1]", - "mongoose;HydratedDocument;mongoose;Model;Member[$where,find,geoSearch,where].ReturnValue.TypeVar[mongoose.QueryWithHelpers.0].ArrayElement", - "mongoose;HydratedDocument;mongoose;Model;Member[create,insertMany].WithArity[2].Argument[1].TypeVar[mongoose.Callback.0].ArrayElement", - "mongoose;HydratedDocument;mongoose;Model;Member[create].WithArity[0..,1,2].ReturnValue.Awaited.ArrayElement", - "mongoose;HydratedDocument;mongoose;Model;Member[create].WithArity[1].ReturnValue.Awaited", - "mongoose;HydratedDocument;mongoose;Model;Member[create].WithArity[2].Argument[1].TypeVar[mongoose.Callback.0]", - "mongoose;HydratedDocument;mongoose;Model;Member[exists].WithArity[1,2].ReturnValue.TypeVar[mongoose.QueryWithHelpers.1]", - "mongoose;HydratedDocument;mongoose;Model;Member[find,insertMany].WithArity[3].Argument[2].TypeVar[mongoose.Callback.0].ArrayElement", - "mongoose;HydratedDocument;mongoose;Model;Member[findById,findByIdAndDelete,findByIdAndRemove,findOne,findOneAndDelete,findOneAndRemove].ReturnValue.TypeVar[mongoose.QueryWithHelpers.0,mongoose.QueryWithHelpers.1]", - "mongoose;HydratedDocument;mongoose;Model;Member[findById,findOne].Argument[3].TypeVar[mongoose.Callback.0]", - "mongoose;HydratedDocument;mongoose;Model;Member[findByIdAndDelete,findByIdAndRemove,findOneAndDelete,findOneAndRemove].Argument[2].Argument[1]", - "mongoose;HydratedDocument;mongoose;Model;Member[findByIdAndUpdate,findOneAndReplace,findOneAndUpdate].WithArity[0,1,2,3,4].ReturnValue.TypeVar[mongoose.QueryWithHelpers.0,mongoose.QueryWithHelpers.1]", - "mongoose;HydratedDocument;mongoose;Model;Member[findByIdAndUpdate,findOneAndReplace,findOneAndUpdate].WithArity[3,4].ReturnValue.TypeVar[mongoose.QueryWithHelpers.0].TypeVar[mongoose.ModifyResult.0]", - "mongoose;HydratedDocument;mongoose;Model;Member[findByIdAndUpdate].WithArity[0,1,2,4].Argument[3].Argument[1]", - "mongoose;HydratedDocument;mongoose;Model;Member[findByIdAndUpdate].WithArity[3].Argument[2,3].Argument[1]", - "mongoose;HydratedDocument;mongoose;Model;Member[findById].WithArity[1,2,3].Argument[2].TypeVar[mongoose.Callback.0]", - "mongoose;HydratedDocument;mongoose;Model;Member[findOneAndReplace].WithArity[0,1,2,3,4].Argument[3].Argument[1]", - "mongoose;HydratedDocument;mongoose;Model;Member[findOneAndUpdate].WithArity[3,4].Argument[3].Argument[1]", - "mongoose;HydratedDocument;mongoose;Model;Member[findOne].WithArity[0,1,2].Argument[1,2].TypeVar[mongoose.Callback.0]", - "mongoose;HydratedDocument;mongoose;Model;Member[findOne].WithArity[3].Argument[2].TypeVar[mongoose.Callback.0]", - "mongoose;HydratedDocument;mongoose;Model;Member[find].Argument[3].TypeVar[mongoose.Callback.0].ArrayElement", - "mongoose;HydratedDocument;mongoose;Model;Member[find].WithArity[0].Argument[0].TypeVar[mongoose.Callback.0].ArrayElement", - "mongoose;HydratedDocument;mongoose;Model;Member[find].WithArity[1].Argument[0,1,2].TypeVar[mongoose.Callback.0].ArrayElement", - "mongoose;HydratedDocument;mongoose;Model;Member[find].WithArity[2].Argument[1,2].TypeVar[mongoose.Callback.0].ArrayElement", - "mongoose;HydratedDocument;mongoose;Model;Member[geoSearch].Argument[2].TypeVar[mongoose.Callback.0].ArrayElement", - "mongoose;HydratedDocument;mongoose;Model;Member[hydrate].ReturnValue", - "mongoose;HydratedDocument;mongoose;Model;Member[init].ReturnValue.Awaited", - "mongoose;HydratedDocument;mongoose;Model;Member[insertMany].WithArity[1,2].ReturnValue.Awaited.ArrayElement", - "mongoose;HydratedDocument;mongoose;Model;Member[populate].WithArity[2,3].Argument[2].TypeVar[mongoose.Callback.0]", - "mongoose;HydratedDocument;mongoose;Model;Member[populate].WithArity[2,3].Argument[2].TypeVar[mongoose.Callback.0].ArrayElement", - "mongoose;HydratedDocument;mongoose;Model;Member[populate].WithArity[2,3].ReturnValue.Awaited", - "mongoose;HydratedDocument;mongoose;Model;Member[populate].WithArity[2,3].ReturnValue.Awaited.ArrayElement", - "mongoose;HydratedDocument;mongoose;TVirtualPathFN;Argument[1].TypeVar[mongoose.VirtualType.0]", - "mongoose;HydratedDocument;mongoose;VirtualPathFunctions;Member[options].TypeVar[mongoose.VirtualTypeOptions.0]", - "mongoose;InsertManyOptions;mongoose;Model;Member[insertMany].WithArity[2,3].Argument[1]", - "mongoose;Model;mongoose;;Member[Model]", - "mongoose;Model;mongoose;;Member[model].ReturnValue", - "mongoose;Model;mongoose;AcceptsDiscriminator;Member[discriminator].WithArity[2,3].ReturnValue", - "mongoose;Model;mongoose;Aggregate;Member[model].Argument[0]", - "mongoose;Model;mongoose;Connection;Member[model].WithArity[1,2,3,4].ReturnValue", - "mongoose;Model;mongoose;Connection;Member[models].AnyMember", - "mongoose;Model;mongoose;DiscriminatorModel;", - "mongoose;Model;mongoose;Document;Member[$model].ReturnValue", - "mongoose;Model;mongoose;Document;Member[populate].Argument[2]", - "mongoose;Model;mongoose;Model;Member[discriminators].AnyMember", - "mongoose;Model;mongoose;Models;AnyMember", - "mongoose;Model;mongoose;PopulateOptions;Member[model]", - "mongoose;Model;mongoose;Query;Member[cast].Argument[0]", - "mongoose;Model;mongoose;Query;Member[populate].Argument[2]", - "mongoose;Model;mongoose;Schema.Types.Array;Member[discriminator].WithArity[2,3].ReturnValue", - "mongoose;Model;mongoose;Schema.Types.DocumentArray;Member[discriminator].WithArity[2,3].ReturnValue", - "mongoose;Model;mongoose;Schema.Types.Subdocument;Member[discriminator].WithArity[2,3].ReturnValue", - "mongoose;Model;mongoose;SchemaStatic;Instance.TypeVar[mongoose.Schema.1]", - "mongoose;Models;mongoose;;Member[models]", - "mongoose;PopulateOption;mongoose;InsertManyOptions;", - "mongoose;PopulateOption;mongoose;QueryOptions;", - "mongoose;PopulateOptions;mongoose;Document;Member[populate].Argument[4]", - "mongoose;PopulateOptions;mongoose;Document;Member[populate].WithArity[1,2].Argument[0]", - "mongoose;PopulateOptions;mongoose;Document;Member[populate].WithArity[1,2].Argument[0].ArrayElement", - "mongoose;PopulateOptions;mongoose;Model;Member[populate].Argument[1]", - "mongoose;PopulateOptions;mongoose;Model;Member[populate].Argument[1].ArrayElement", - "mongoose;PopulateOptions;mongoose;PopulateOption;Member[populate]", - "mongoose;PopulateOptions;mongoose;PopulateOption;Member[populate].ArrayElement", - "mongoose;PopulateOptions;mongoose;PopulateOptions;Member[populate]", - "mongoose;PopulateOptions;mongoose;PopulateOptions;Member[populate].ArrayElement", - "mongoose;PopulateOptions;mongoose;Query;Member[populate].WithArity[1].Argument[0]", - "mongoose;PopulateOptions;mongoose;Query;Member[populate].WithArity[1].Argument[0].ArrayElement", - "mongoose;Query;mongoose;Document;Member[replaceOne,update,updateOne].ReturnValue", - "mongoose;Query;mongoose;HydratedDocument;TypeVar[mongoose.Require_id.0]", - "mongoose;Query;mongoose;Query;Member[all,allowDiskUse,and,batchSize,box,circle,clone,collation,comment,elemMatch,equals,exists,explain,geometry,gt,gte,hint,in,intersects,j,limit,lt,lte,maxDistance,maxScan,maxTimeMS,merge,mod,ne,near,nin,nor,or,polygon,read,readConcern,regex,remove,select,session,set,setOptions,size,skip,slice,snapshot,sort,tailable,w,where,within,wtimeout].ReturnValue", - "mongoose;Query;mongoose;Query;Member[error].WithArity[1].ReturnValue", - "mongoose;Query;mongoose;Query;Member[merge].Argument[0]", - "mongoose;Query;mongoose;QueryStatic;Instance", - "mongoose;Query;mongoose;QueryWithHelpers;", - "mongoose;QueryOptions;mongoose;Document;Member[delete,deleteOne,remove].WithArity[0,1,2].Argument[0]", - "mongoose;QueryOptions;mongoose;Document;Member[replaceOne,update,updateOne].Argument[1]", - "mongoose;QueryOptions;mongoose;Model;Member[countDocuments,findByIdAndDelete,findByIdAndRemove,findOneAndDelete,findOneAndRemove].Argument[1]", - "mongoose;QueryOptions;mongoose;Model;Member[deleteMany,deleteOne].WithArity[0,1,2,3].Argument[1]", - "mongoose;QueryOptions;mongoose;Model;Member[estimatedDocumentCount].Argument[0]", - "mongoose;QueryOptions;mongoose;Model;Member[find,findById].WithArity[1,2,3,4].Argument[2]", - "mongoose;QueryOptions;mongoose;Model;Member[findByIdAndUpdate,findOne,findOneAndReplace,findOneAndUpdate].WithArity[0,1,2,3,4].Argument[2]", - "mongoose;QueryOptions;mongoose;Model;Member[replaceOne,update,updateMany,updateOne].Argument[2]", - "mongoose;QueryOptions;mongoose;PopulateOptions;Member[options]", - "mongoose;QueryOptions;mongoose;Query;Member[countDocuments,findByIdAndDelete,findOneAndDelete,findOneAndRemove].Argument[1]", - "mongoose;QueryOptions;mongoose;Query;Member[cursor,estimatedDocumentCount,setOptions].Argument[0]", - "mongoose;QueryOptions;mongoose;Query;Member[cursor].ReturnValue.TypeVar[mongoose.Cursor.1]", - "mongoose;QueryOptions;mongoose;Query;Member[deleteMany,deleteOne].WithArity[0,1,2,3].Argument[1]", - "mongoose;QueryOptions;mongoose;Query;Member[findByIdAndUpdate,findOne,findOneAndUpdate].WithArity[0,1,2,3,4].Argument[2]", - "mongoose;QueryOptions;mongoose;Query;Member[find].WithArity[1,2,3,4].Argument[2]", - "mongoose;QueryOptions;mongoose;Query;Member[getOptions].ReturnValue", - "mongoose;QueryOptions;mongoose;Query;Member[replaceOne,update,updateMany,updateOne].Argument[2]", - "mongoose;QueryOptions;mongoose;VirtualTypeOptions;Member[options]", - "mongoose;QueryStatic;mongoose;;Member[Query]", - "mongoose;QueryWithHelpers;mongoose;Document;Member[delete,deleteOne].WithArity[0,1].ReturnValue", - "mongoose;QueryWithHelpers;mongoose;Model;Member[$where,count,countDocuments,deleteMany,deleteOne,distinct,estimatedDocumentCount,find,findById,findByIdAndDelete,findByIdAndRemove,findOne,findOneAndDelete,findOneAndRemove,geoSearch,remove,replaceOne,update,updateMany,updateOne,where].ReturnValue", - "mongoose;QueryWithHelpers;mongoose;Model;Member[exists].WithArity[1,2].ReturnValue", - "mongoose;QueryWithHelpers;mongoose;Model;Member[findByIdAndUpdate,findOneAndReplace,findOneAndUpdate].WithArity[0,1,2,3,4].ReturnValue", - "mongoose;QueryWithHelpers;mongoose;Query;Member[$where,count,countDocuments,deleteMany,deleteOne,distinct,estimatedDocumentCount,find,findByIdAndDelete,findOne,findOneAndDelete,findOneAndRemove,lean,orFail,populate,replaceOne,transform,update,updateMany,updateOne].ReturnValue", - "mongoose;QueryWithHelpers;mongoose;Query;Member[findByIdAndUpdate,findOneAndUpdate].WithArity[0,1,2,3,4].ReturnValue", - "mongoose;QueryWithHelpers;mongoose;Query;Member[toConstructor].ReturnValue.Instance", - "mongoose;Schema.Types.Array;mongoose;Schema.Types.Array;Member[enum].ReturnValue", - "mongoose;Schema.Types.Array;mongoose;Schema.Types.ArrayStatic;Instance", - "mongoose;Schema.Types.ArrayStatic;mongoose;;Member[Schema].Member[Types].Member[Array]", - "mongoose;Schema.Types.DocumentArray;mongoose;Schema.Types.DocumentArrayStatic;Instance", - "mongoose;Schema.Types.DocumentArrayStatic;mongoose;;Member[Schema].Member[Types].Member[DocumentArray]", - "mongoose;Schema.Types.Subdocument;mongoose;Schema.Types.SubdocumentStatic;Instance", - "mongoose;Schema.Types.SubdocumentStatic;mongoose;;Member[Schema].Member[Types].Member[Subdocument]", - "mongoose;Schema.Types.SubdocumentStatic;mongoose;Schema.Types.DocumentArray;Member[caster]", - "mongoose;SchemaStatic;mongoose;;Member[Schema]", - "mongoose;SessionOperation;mongoose;Aggregate;", - "mongoose;SessionOperation;mongoose;Query;", - "mongoose;TVirtualPathFN;mongoose;VirtualPathFunctions;Member[get,set]", - "mongoose;Types.Array;mongoose;Types.DocumentArray;", - "mongoose;Types.ArraySubdocument;mongoose;Types.ArraySubdocumentStatic;Instance", - "mongoose;Types.ArraySubdocumentStatic;mongoose;;Member[Types].Member[ArraySubdocument]", - "mongoose;Types.DocumentArray;mongoose/inferschematype;ResolvePathType;TypeVar[mongoose.IfEquals.3]", - "mongoose;Types.DocumentArray;mongoose;Types.ArraySubdocument;Member[parentArray].ReturnValue", - "mongoose;Types.DocumentArray;mongoose;Types.DocumentArrayStatic;Instance", - "mongoose;Types.DocumentArrayStatic;mongoose;;Member[Types].Member[DocumentArray]", - "mongoose;Types.ObjectId;mongoose/inferschematype;ResolvePathType;", - "mongoose;Types.Subdocument;mongoose;Types.ArraySubdocument;", - "mongoose;Types.Subdocument;mongoose;Types.DocumentArray;Member[create,id].ReturnValue", - "mongoose;Types.Subdocument;mongoose;Types.DocumentArray;TypeVar[mongoose.Types.Array.0]", - "mongoose;Types.Subdocument;mongoose;Types.SubdocumentStatic;Instance", - "mongoose;Types.SubdocumentStatic;mongoose;;Member[Types].Member[Subdocument]", - "mongoose;VirtualType;mongoose;TVirtualPathFN;Argument[1]", - "mongoose;VirtualType;mongoose;VirtualType;Member[get,set].Argument[0].Argument[1]", - "mongoose;VirtualType;mongoose;VirtualType;Member[get,set].ReturnValue", - "mongoose;VirtualType;mongoose;VirtualTypeStatic;Instance", - "mongoose;VirtualTypeOptions;mongoose;VirtualPathFunctions;Member[options]", - "mongoose;VirtualTypeStatic;mongoose;;Member[VirtualType]" + "mongodb.AbstractCursor;mongodb.FindCursor;", + "mongodb.AbstractCursor;mongodb.ListCollectionsCursor;", + "mongodb.AbstractCursor;mongodb.ListIndexesCursor;", + "mongodb.AbstractCursorOptions;mongodb.AggregationCursorOptions;", + "mongodb.AbstractCursorOptions;mongodb/mongodb.AbstractCursorOptions;", + "mongodb.AbstractCursorOptions;mongoose.mongodb.AbstractCursorOptions;", + "mongodb.AddUserOptions;mongodb.Admin;Member[addUser].Argument[1,2]", + "mongodb.AddUserOptions;mongodb.Db;Member[addUser].Argument[1,2]", + "mongodb.AddUserOptions;mongodb/mongodb.AddUserOptions;", + "mongodb.AddUserOptions;mongoose.mongodb.AddUserOptions;", + "mongodb.Admin;mongodb.AdminStatic;Instance", + "mongodb.Admin;mongodb.Db;Member[admin].ReturnValue", + "mongodb.Admin;mongodb/mongodb.Admin;", + "mongodb.Admin;mongoose.mongodb.Admin;", + "mongodb.AdminStatic;mongodb/mongodb.AdminStatic;", + "mongodb.AdminStatic;mongodb;Member[Admin]", + "mongodb.AdminStatic;mongoose.mongodb.AdminStatic;", + "mongodb.AggregateOptions;mongodb.AggregationCursorOptions;", + "mongodb.AggregateOptions;mongodb.ChangeStreamOptions;", + "mongodb.AggregateOptions;mongodb.Collection;Member[aggregate].Argument[1]", + "mongodb.AggregateOptions;mongodb.CountDocumentsOptions;", + "mongodb.AggregateOptions;mongodb.Db;Member[aggregate].Argument[1]", + "mongodb.AggregateOptions;mongodb/mongodb.AggregateOptions;", + "mongodb.AggregateOptions;mongoose.mongodb.AggregateOptions;", + "mongodb.AggregationCursorOptions;mongodb/mongodb.AggregationCursorOptions;", + "mongodb.AggregationCursorOptions;mongoose.mongodb.AggregationCursorOptions;", + "mongodb.AnyBulkWriteOperation;mongodb.BulkOperationBase;Member[raw].Argument[0]", + "mongodb.AnyBulkWriteOperation;mongodb.Collection;Member[bulkWrite].Argument[0].ArrayElement", + "mongodb.AnyBulkWriteOperation;mongodb/mongodb.AnyBulkWriteOperation;", + "mongodb.AnyBulkWriteOperation;mongoose.mongodb.AnyBulkWriteOperation;", + "mongodb.Auth;mongodb.MongoClientOptions;Member[auth]", + "mongodb.Auth;mongodb/mongodb.Auth;", + "mongodb.Auth;mongoose.mongodb.Auth;", + "mongodb.AutoEncrypter;mongodb.AutoEncrypter;Instance", + "mongodb.AutoEncrypter;mongodb.ConnectionOptions;Member[autoEncrypter]", + "mongodb.AutoEncrypter;mongodb.MongoClient;Member[autoEncrypter]", + "mongodb.AutoEncrypter;mongodb.MongoOptions;Member[autoEncrypter]", + "mongodb.AutoEncrypter;mongodb/mongodb.AutoEncrypter;", + "mongodb.AutoEncrypter;mongoose.mongodb.AutoEncrypter;", + "mongodb.AutoEncryptionOptions;mongodb.AutoEncrypter;Argument[1]", + "mongodb.AutoEncryptionOptions;mongodb.MongoClientOptions;Member[autoEncryption]", + "mongodb.AutoEncryptionOptions;mongodb/mongodb.AutoEncryptionOptions;", + "mongodb.AutoEncryptionOptions;mongoose.mongodb.AutoEncryptionOptions;", + "mongodb.BulkOperationBase;mongodb.BulkOperationBase;Member[addToOperationsList,insert,raw].ReturnValue", + "mongodb.BulkOperationBase;mongodb.BulkOperationBaseStatic;Instance", + "mongodb.BulkOperationBase;mongodb.FindOperators;Member[bulkOperation]", + "mongodb.BulkOperationBase;mongodb.FindOperators;Member[delete,deleteOne,replaceOne,update,updateOne].ReturnValue", + "mongodb.BulkOperationBase;mongodb.OrderedBulkOperation;", + "mongodb.BulkOperationBase;mongodb.UnorderedBulkOperation;", + "mongodb.BulkOperationBase;mongodb/mongodb.BulkOperationBase;", + "mongodb.BulkOperationBase;mongoose.mongodb.BulkOperationBase;", + "mongodb.BulkOperationBaseStatic;mongodb/mongodb.BulkOperationBaseStatic;", + "mongodb.BulkOperationBaseStatic;mongodb;Member[BulkOperationBase]", + "mongodb.BulkOperationBaseStatic;mongoose.mongodb.BulkOperationBaseStatic;", + "mongodb.BulkWriteOptions;mongodb.BulkOperationBase;Member[execute].WithArity[0,1,2].Argument[0]", + "mongodb.BulkWriteOptions;mongodb.Collection;Member[bulkWrite,insert,insertMany].Argument[1]", + "mongodb.BulkWriteOptions;mongodb.Collection;Member[initializeOrderedBulkOp,initializeUnorderedBulkOp].Argument[0]", + "mongodb.BulkWriteOptions;mongodb.OrderedBulkOperationStatic;Argument[1]", + "mongodb.BulkWriteOptions;mongodb.UnorderedBulkOperationStatic;Argument[1]", + "mongodb.BulkWriteOptions;mongodb/mongodb.BulkWriteOptions;", + "mongodb.BulkWriteOptions;mongoose.mongodb.BulkWriteOptions;", + "mongodb.ChangeStream;mongodb.ChangeStreamStatic;Instance", + "mongodb.ChangeStream;mongodb.Collection;Member[watch].ReturnValue", + "mongodb.ChangeStream;mongodb.Db;Member[watch].ReturnValue", + "mongodb.ChangeStream;mongodb.MongoClient;Member[watch].ReturnValue", + "mongodb.ChangeStream;mongodb/mongodb.ChangeStream;", + "mongodb.ChangeStream;mongoose.mongodb.ChangeStream;", + "mongodb.ChangeStreamOptions;mongodb.ChangeStream;Member[options]", + "mongodb.ChangeStreamOptions;mongodb.Collection;Member[watch].Argument[1]", + "mongodb.ChangeStreamOptions;mongodb.Db;Member[watch].Argument[1]", + "mongodb.ChangeStreamOptions;mongodb.MongoClient;Member[watch].Argument[1]", + "mongodb.ChangeStreamOptions;mongodb/mongodb.ChangeStreamOptions;", + "mongodb.ChangeStreamOptions;mongoose.mongodb.ChangeStreamOptions;", + "mongodb.ChangeStreamStatic;mongodb/mongodb.ChangeStreamStatic;", + "mongodb.ChangeStreamStatic;mongodb;Member[ChangeStream]", + "mongodb.ChangeStreamStatic;mongoose.mongodb.ChangeStreamStatic;", + "mongodb.ClientSession;mongodb.AbstractCursorOptions;Member[session]", + "mongodb.ClientSession;mongodb.ClientSession;Member[equals].Argument[0]", + "mongodb.ClientSession;mongodb.ClientSessionEvents;Member[ended].Argument[0]", + "mongodb.ClientSession;mongodb.ClientSessionStatic;Instance", + "mongodb.ClientSession;mongodb.IndexInformationOptions;Member[session]", + "mongodb.ClientSession;mongodb.MongoClient;Member[startSession].ReturnValue", + "mongodb.ClientSession;mongodb.OperationOptions;Member[session]", + "mongodb.ClientSession;mongodb.ReadPreferenceFromOptions;Member[session]", + "mongodb.ClientSession;mongodb.SelectServerOptions;Member[session]", + "mongodb.ClientSession;mongodb.WithSessionCallback;Argument[0]", + "mongodb.ClientSession;mongodb.WithTransactionCallback;Argument[0]", + "mongodb.ClientSession;mongodb/mongodb.ClientSession;", + "mongodb.ClientSession;mongoose.mongodb.ClientSession;", + "mongodb.ClientSessionEvents;mongodb/mongodb.ClientSessionEvents;", + "mongodb.ClientSessionEvents;mongoose.mongodb.ClientSessionEvents;", + "mongodb.ClientSessionOptions;mongodb.MongoClient;Member[startSession].Argument[0]", + "mongodb.ClientSessionOptions;mongodb.MongoClient;Member[withSession].WithArity[2].Argument[0]", + "mongodb.ClientSessionOptions;mongodb/mongodb.ClientSessionOptions;", + "mongodb.ClientSessionOptions;mongoose.mongodb.ClientSessionOptions;", + "mongodb.ClientSessionStatic;mongodb/mongodb.ClientSessionStatic;", + "mongodb.ClientSessionStatic;mongodb;Member[ClientSession]", + "mongodb.ClientSessionStatic;mongoose.mongodb.ClientSessionStatic;", + "mongodb.CollStatsOptions;mongodb.Collection;Member[stats].Argument[0]", + "mongodb.CollStatsOptions;mongodb/mongodb.CollStatsOptions;", + "mongodb.CollStatsOptions;mongoose.mongodb.CollStatsOptions;", + "mongodb.Collection;mongodb.ChangeStream;Member[parent]", + "mongodb.Collection;mongodb.Collection;Member[rename].Argument[1,2].TypeVar[mongodb.Callback.0]", + "mongodb.Collection;mongodb.Collection;Member[rename].WithArity[1,2].ReturnValue.Awaited", + "mongodb.Collection;mongodb.CollectionStatic;Instance", + "mongodb.Collection;mongodb.Db;Member[collection].ReturnValue", + "mongodb.Collection;mongodb.Db;Member[collections].Argument[0,1].TypeVar[mongodb.Callback.0].ArrayElement", + "mongodb.Collection;mongodb.Db;Member[collections].WithArity[0,1].ReturnValue.Awaited.ArrayElement", + "mongodb.Collection;mongodb.Db;Member[createCollection].Argument[2].TypeVar[mongodb.Callback.0]", + "mongodb.Collection;mongodb.Db;Member[createCollection].WithArity[1,2].ReturnValue.Awaited", + "mongodb.Collection;mongodb.Db;Member[createCollection].WithArity[2].Argument[1].TypeVar[mongodb.Callback.0]", + "mongodb.Collection;mongodb.Db;Member[renameCollection].Argument[2,3].TypeVar[mongodb.Callback.0]", + "mongodb.Collection;mongodb.Db;Member[renameCollection].WithArity[2,3].ReturnValue.Awaited", + "mongodb.Collection;mongodb.GridFSBucketWriteStream;Member[chunks,files]", + "mongodb.Collection;mongodb.ListIndexesCursor;Member[parent]", + "mongodb.Collection;mongodb.ListIndexesCursorStatic;Argument[0]", + "mongodb.Collection;mongodb.OrderedBulkOperationStatic;Argument[0]", + "mongodb.Collection;mongodb.UnorderedBulkOperationStatic;Argument[0]", + "mongodb.Collection;mongodb/mongodb.Collection;", + "mongodb.Collection;mongoose.mongodb.Collection;", + "mongodb.CollectionStatic;mongodb/mongodb.CollectionStatic;", + "mongodb.CollectionStatic;mongodb;Member[Collection]", + "mongodb.CollectionStatic;mongoose.mongodb.CollectionStatic;", + "mongodb.CommandOperationOptions;mongodb.AddUserOptions;", + "mongodb.CommandOperationOptions;mongodb.Admin;Member[buildInfo,ping,replSetGetStatus,serverInfo,serverStatus].Argument[0]", + "mongodb.CommandOperationOptions;mongodb.AggregateOptions;", + "mongodb.CommandOperationOptions;mongodb.BulkWriteOptions;", + "mongodb.CommandOperationOptions;mongodb.CollStatsOptions;", + "mongodb.CommandOperationOptions;mongodb.CountOptions;", + "mongodb.CommandOperationOptions;mongodb.CreateCollectionOptions;", + "mongodb.CommandOperationOptions;mongodb.CreateIndexesOptions;", + "mongodb.CommandOperationOptions;mongodb.DbStatsOptions;", + "mongodb.CommandOperationOptions;mongodb.DeleteOptions;", + "mongodb.CommandOperationOptions;mongodb.DistinctOptions;", + "mongodb.CommandOperationOptions;mongodb.DropCollectionOptions;", + "mongodb.CommandOperationOptions;mongodb.DropDatabaseOptions;", + "mongodb.CommandOperationOptions;mongodb.DropIndexesOptions;", + "mongodb.CommandOperationOptions;mongodb.EstimatedDocumentCountOptions;", + "mongodb.CommandOperationOptions;mongodb.EvalOptions;", + "mongodb.CommandOperationOptions;mongodb.FindOneAndDeleteOptions;", + "mongodb.CommandOperationOptions;mongodb.FindOneAndReplaceOptions;", + "mongodb.CommandOperationOptions;mongodb.FindOneAndUpdateOptions;", + "mongodb.CommandOperationOptions;mongodb.FindOptions;", + "mongodb.CommandOperationOptions;mongodb.InsertOneOptions;", + "mongodb.CommandOperationOptions;mongodb.ListCollectionsOptions;", + "mongodb.CommandOperationOptions;mongodb.ListDatabasesOptions;", + "mongodb.CommandOperationOptions;mongodb.ListIndexesOptions;", + "mongodb.CommandOperationOptions;mongodb.MapReduceOptions;", + "mongodb.CommandOperationOptions;mongodb.ProfilingLevelOptions;", + "mongodb.CommandOperationOptions;mongodb.RemoveUserOptions;", + "mongodb.CommandOperationOptions;mongodb.RenameOptions;", + "mongodb.CommandOperationOptions;mongodb.ReplaceOptions;", + "mongodb.CommandOperationOptions;mongodb.RunCommandOptions;", + "mongodb.CommandOperationOptions;mongodb.SetProfilingLevelOptions;", + "mongodb.CommandOperationOptions;mongodb.TransactionOptions;", + "mongodb.CommandOperationOptions;mongodb.UpdateOptions;", + "mongodb.CommandOperationOptions;mongodb.ValidateCollectionOptions;", + "mongodb.CommandOperationOptions;mongodb/mongodb.CommandOperationOptions;", + "mongodb.CommandOperationOptions;mongoose.mongodb.CommandOperationOptions;", + "mongodb.ConnectionOptions;mongodb/mongodb.ConnectionOptions;", + "mongodb.ConnectionOptions;mongoose.mongodb.ConnectionOptions;", + "mongodb.CountDocumentsOptions;mongodb.Collection;Member[countDocuments].Argument[1]", + "mongodb.CountDocumentsOptions;mongodb/mongodb.CountDocumentsOptions;", + "mongodb.CountDocumentsOptions;mongoose.mongodb.CountDocumentsOptions;", + "mongodb.CountOptions;mongodb.Collection;Member[count].Argument[1]", + "mongodb.CountOptions;mongodb.FindCursor;Member[count].Argument[0]", + "mongodb.CountOptions;mongodb/mongodb.CountOptions;", + "mongodb.CountOptions;mongoose.mongodb.CountOptions;", + "mongodb.CreateCollectionOptions;mongodb.Db;Member[createCollection].WithArity[1,2,3].Argument[1]", + "mongodb.CreateCollectionOptions;mongodb/mongodb.CreateCollectionOptions;", + "mongodb.CreateCollectionOptions;mongoose.mongodb.CreateCollectionOptions;", + "mongodb.CreateIndexesOptions;mongodb.Collection;Member[createIndex,createIndexes].Argument[1]", + "mongodb.CreateIndexesOptions;mongodb.Db;Member[createIndex].Argument[2]", + "mongodb.CreateIndexesOptions;mongodb/mongodb.CreateIndexesOptions;", + "mongodb.CreateIndexesOptions;mongoose.mongodb.CreateIndexesOptions;", + "mongodb.Db;mongodb.ChangeStream;Member[parent]", + "mongodb.Db;mongodb.DbStatic;Instance", + "mongodb.Db;mongodb.GridFSBucketStatic;Argument[0]", + "mongodb.Db;mongodb.ListCollectionsCursor;Member[parent]", + "mongodb.Db;mongodb.ListCollectionsCursorStatic;Argument[0]", + "mongodb.Db;mongodb.MongoClient;Member[db].ReturnValue", + "mongodb.Db;mongodb/mongodb.Db;", + "mongodb.Db;mongoose.mongodb.Db;", + "mongodb.DbStatic;mongodb/mongodb.DbStatic;", + "mongodb.DbStatic;mongodb;Member[Db]", + "mongodb.DbStatic;mongoose.mongodb.DbStatic;", + "mongodb.DbStatsOptions;mongodb.Db;Member[stats].Argument[0]", + "mongodb.DbStatsOptions;mongodb/mongodb.DbStatsOptions;", + "mongodb.DbStatsOptions;mongoose.mongodb.DbStatsOptions;", + "mongodb.DeleteManyModel;mongodb.AnyBulkWriteOperation;Member[deleteMany]", + "mongodb.DeleteManyModel;mongodb/mongodb.DeleteManyModel;", + "mongodb.DeleteManyModel;mongoose.mongodb.DeleteManyModel;", + "mongodb.DeleteOneModel;mongodb.AnyBulkWriteOperation;Member[deleteOne]", + "mongodb.DeleteOneModel;mongodb/mongodb.DeleteOneModel;", + "mongodb.DeleteOneModel;mongoose.mongodb.DeleteOneModel;", + "mongodb.DeleteOptions;mongodb.Collection;Member[deleteMany,deleteOne,remove].Argument[1]", + "mongodb.DeleteOptions;mongodb/mongodb.DeleteOptions;", + "mongodb.DeleteOptions;mongoose.mongodb.DeleteOptions;", + "mongodb.DistinctOptions;mongodb.Collection;Member[distinct].Argument[2]", + "mongodb.DistinctOptions;mongodb/mongodb.DistinctOptions;", + "mongodb.DistinctOptions;mongoose.mongodb.DistinctOptions;", + "mongodb.DropCollectionOptions;mongodb.Collection;Member[drop].Argument[0]", + "mongodb.DropCollectionOptions;mongodb.Db;Member[dropCollection].Argument[1]", + "mongodb.DropCollectionOptions;mongodb/mongodb.DropCollectionOptions;", + "mongodb.DropCollectionOptions;mongoose.mongodb.DropCollectionOptions;", + "mongodb.DropDatabaseOptions;mongodb.Db;Member[dropDatabase].Argument[0]", + "mongodb.DropDatabaseOptions;mongodb/mongodb.DropDatabaseOptions;", + "mongodb.DropDatabaseOptions;mongoose.mongodb.DropDatabaseOptions;", + "mongodb.DropIndexesOptions;mongodb.Collection;Member[dropIndex].Argument[1]", + "mongodb.DropIndexesOptions;mongodb.Collection;Member[dropIndexes].Argument[0]", + "mongodb.DropIndexesOptions;mongodb/mongodb.DropIndexesOptions;", + "mongodb.DropIndexesOptions;mongoose.mongodb.DropIndexesOptions;", + "mongodb.EstimatedDocumentCountOptions;mongodb.Collection;Member[estimatedDocumentCount].Argument[0]", + "mongodb.EstimatedDocumentCountOptions;mongodb/mongodb.EstimatedDocumentCountOptions;", + "mongodb.EstimatedDocumentCountOptions;mongoose.mongodb.EstimatedDocumentCountOptions;", + "mongodb.EvalOptions;mongodb/mongodb.EvalOptions;", + "mongodb.EvalOptions;mongoose.mongodb.EvalOptions;", + "mongodb.FindCursor;mongodb.Collection;Member[find].WithArity[0,1,2].ReturnValue", + "mongodb.FindCursor;mongodb.FindCursor;Member[addQueryModifier,allowDiskUse,clone,collation,comment,filter,hint,limit,map,max,maxAwaitTimeMS,maxTimeMS,min,project,returnKey,showRecordId,skip,sort].ReturnValue", + "mongodb.FindCursor;mongodb.FindCursorStatic;Instance", + "mongodb.FindCursor;mongodb.GridFSBucket;Member[find].ReturnValue", + "mongodb.FindCursor;mongodb/mongodb.FindCursor;", + "mongodb.FindCursor;mongoose.mongodb.FindCursor;", + "mongodb.FindCursorStatic;mongodb/mongodb.FindCursorStatic;", + "mongodb.FindCursorStatic;mongodb;Member[FindCursor]", + "mongodb.FindCursorStatic;mongoose.mongodb.FindCursorStatic;", + "mongodb.FindOneAndDeleteOptions;mongodb.Collection;Member[findOneAndDelete].Argument[1]", + "mongodb.FindOneAndDeleteOptions;mongodb/mongodb.FindOneAndDeleteOptions;", + "mongodb.FindOneAndDeleteOptions;mongoose.mongodb.FindOneAndDeleteOptions;", + "mongodb.FindOneAndReplaceOptions;mongodb.Collection;Member[findOneAndReplace].Argument[2]", + "mongodb.FindOneAndReplaceOptions;mongodb/mongodb.FindOneAndReplaceOptions;", + "mongodb.FindOneAndReplaceOptions;mongoose.mongodb.FindOneAndReplaceOptions;", + "mongodb.FindOneAndUpdateOptions;mongodb.Collection;Member[findOneAndUpdate].Argument[2]", + "mongodb.FindOneAndUpdateOptions;mongodb/mongodb.FindOneAndUpdateOptions;", + "mongodb.FindOneAndUpdateOptions;mongoose.mongodb.FindOneAndUpdateOptions;", + "mongodb.FindOperators;mongodb.BulkOperationBase;Member[find].ReturnValue", + "mongodb.FindOperators;mongodb.FindOperators;Member[arrayFilters,collation,upsert].ReturnValue", + "mongodb.FindOperators;mongodb.FindOperatorsStatic;Instance", + "mongodb.FindOperators;mongodb/mongodb.FindOperators;", + "mongodb.FindOperators;mongoose.mongodb.FindOperators;", + "mongodb.FindOperatorsStatic;mongodb/mongodb.FindOperatorsStatic;", + "mongodb.FindOperatorsStatic;mongodb;Member[FindOperators]", + "mongodb.FindOperatorsStatic;mongoose.mongodb.FindOperatorsStatic;", + "mongodb.FindOptions;mongodb.Collection;Member[find,findOne].Argument[1]", + "mongodb.FindOptions;mongodb.GridFSBucket;Member[find].Argument[1]", + "mongodb.FindOptions;mongodb/mongodb.FindOptions;", + "mongodb.FindOptions;mongoose.mongodb.FindOptions;", + "mongodb.GridFSBucket;mongodb.GridFSBucketStatic;Instance", + "mongodb.GridFSBucket;mongodb.GridFSBucketWriteStream;Member[bucket]", + "mongodb.GridFSBucket;mongodb/mongodb.GridFSBucket;", + "mongodb.GridFSBucket;mongoose.mongodb.GridFSBucket;", + "mongodb.GridFSBucketStatic;mongodb/mongodb.GridFSBucketStatic;", + "mongodb.GridFSBucketStatic;mongodb;Member[GridFSBucket]", + "mongodb.GridFSBucketStatic;mongoose.mongodb.GridFSBucketStatic;", + "mongodb.GridFSBucketWriteStream;mongodb.GridFSBucket;Member[openUploadStream,openUploadStreamWithId].ReturnValue", + "mongodb.GridFSBucketWriteStream;mongodb.GridFSBucketWriteStream;Member[end].ReturnValue", + "mongodb.GridFSBucketWriteStream;mongodb.GridFSBucketWriteStreamStatic;Instance", + "mongodb.GridFSBucketWriteStream;mongodb/mongodb.GridFSBucketWriteStream;", + "mongodb.GridFSBucketWriteStream;mongoose.mongodb.GridFSBucketWriteStream;", + "mongodb.GridFSBucketWriteStreamStatic;mongodb/mongodb.GridFSBucketWriteStreamStatic;", + "mongodb.GridFSBucketWriteStreamStatic;mongodb;Member[GridFSBucketWriteStream]", + "mongodb.GridFSBucketWriteStreamStatic;mongoose.mongodb.GridFSBucketWriteStreamStatic;", + "mongodb.IndexInformationOptions;mongodb.Collection;Member[indexExists].Argument[1]", + "mongodb.IndexInformationOptions;mongodb.Collection;Member[indexInformation,indexes].Argument[0]", + "mongodb.IndexInformationOptions;mongodb.Db;Member[indexInformation].Argument[1]", + "mongodb.IndexInformationOptions;mongodb/mongodb.IndexInformationOptions;", + "mongodb.IndexInformationOptions;mongoose.mongodb.IndexInformationOptions;", + "mongodb.InsertOneOptions;mongodb.Collection;Member[insertOne].Argument[1]", + "mongodb.InsertOneOptions;mongodb/mongodb.InsertOneOptions;", + "mongodb.InsertOneOptions;mongoose.mongodb.InsertOneOptions;", + "mongodb.ListCollectionsCursor;mongodb.Db;Member[listCollections].WithArity[0,1,2].ReturnValue", + "mongodb.ListCollectionsCursor;mongodb.ListCollectionsCursor;Member[clone].ReturnValue", + "mongodb.ListCollectionsCursor;mongodb.ListCollectionsCursorStatic;Instance", + "mongodb.ListCollectionsCursor;mongodb/mongodb.ListCollectionsCursor;", + "mongodb.ListCollectionsCursor;mongoose.mongodb.ListCollectionsCursor;", + "mongodb.ListCollectionsCursorStatic;mongodb/mongodb.ListCollectionsCursorStatic;", + "mongodb.ListCollectionsCursorStatic;mongodb;Member[ListCollectionsCursor]", + "mongodb.ListCollectionsCursorStatic;mongoose.mongodb.ListCollectionsCursorStatic;", + "mongodb.ListCollectionsOptions;mongodb.Db;Member[collections].Argument[0]", + "mongodb.ListCollectionsOptions;mongodb.Db;Member[listCollections].WithArity[0,1,2].Argument[1]", + "mongodb.ListCollectionsOptions;mongodb.ListCollectionsCursor;Member[options]", + "mongodb.ListCollectionsOptions;mongodb.ListCollectionsCursorStatic;Argument[2]", + "mongodb.ListCollectionsOptions;mongodb/mongodb.ListCollectionsOptions;", + "mongodb.ListCollectionsOptions;mongoose.mongodb.ListCollectionsOptions;", + "mongodb.ListDatabasesOptions;mongodb.Admin;Member[listDatabases].Argument[0]", + "mongodb.ListDatabasesOptions;mongodb/mongodb.ListDatabasesOptions;", + "mongodb.ListDatabasesOptions;mongoose.mongodb.ListDatabasesOptions;", + "mongodb.ListIndexesCursor;mongodb.Collection;Member[listIndexes].ReturnValue", + "mongodb.ListIndexesCursor;mongodb.ListIndexesCursor;Member[clone].ReturnValue", + "mongodb.ListIndexesCursor;mongodb.ListIndexesCursorStatic;Instance", + "mongodb.ListIndexesCursor;mongodb/mongodb.ListIndexesCursor;", + "mongodb.ListIndexesCursor;mongoose.mongodb.ListIndexesCursor;", + "mongodb.ListIndexesCursorStatic;mongodb/mongodb.ListIndexesCursorStatic;", + "mongodb.ListIndexesCursorStatic;mongodb;Member[ListIndexesCursor]", + "mongodb.ListIndexesCursorStatic;mongoose.mongodb.ListIndexesCursorStatic;", + "mongodb.ListIndexesOptions;mongodb.Collection;Member[listIndexes].Argument[0]", + "mongodb.ListIndexesOptions;mongodb.ListIndexesCursor;Member[options]", + "mongodb.ListIndexesOptions;mongodb.ListIndexesCursorStatic;Argument[1]", + "mongodb.ListIndexesOptions;mongodb/mongodb.ListIndexesOptions;", + "mongodb.ListIndexesOptions;mongoose.mongodb.ListIndexesOptions;", + "mongodb.MapReduceOptions;mongodb.Collection;Member[mapReduce].Argument[2]", + "mongodb.MapReduceOptions;mongodb/mongodb.MapReduceOptions;", + "mongodb.MapReduceOptions;mongoose.mongodb.MapReduceOptions;", + "mongodb.MongoClient;mongodb.AutoEncrypter;Argument[0]", + "mongodb.MongoClient;mongodb.AutoEncryptionOptions;Member[keyVaultClient]", + "mongodb.MongoClient;mongodb.ChangeStream;Member[parent]", + "mongodb.MongoClient;mongodb.DbStatic;Argument[0]", + "mongodb.MongoClient;mongodb.MongoClient;Member[connect].Argument[0].TypeVar[mongodb.Callback.0]", + "mongodb.MongoClient;mongodb.MongoClient;Member[connect].WithArity[0].ReturnValue.Awaited", + "mongodb.MongoClient;mongodb.MongoClientEvents;Member[open].Argument[0]", + "mongodb.MongoClient;mongodb.MongoClientStatic;Instance", + "mongodb.MongoClient;mongodb.MongoClientStatic;Member[connect].Argument[1,2].TypeVar[mongodb.Callback.0]", + "mongodb.MongoClient;mongodb.MongoClientStatic;Member[connect].WithArity[1,2].ReturnValue.Awaited", + "mongodb.MongoClient;mongodb/mongodb.MongoClient;", + "mongodb.MongoClient;mongoose.mongodb.MongoClient;", + "mongodb.MongoClientEvents;mongodb/mongodb.MongoClientEvents;", + "mongodb.MongoClientEvents;mongoose.mongodb.MongoClientEvents;", + "mongodb.MongoClientOptions;mongodb.MongoClientStatic;Argument[1]", + "mongodb.MongoClientOptions;mongodb.MongoClientStatic;Member[connect].Argument[1]", + "mongodb.MongoClientOptions;mongodb/mongodb.MongoClientOptions;", + "mongodb.MongoClientOptions;mongoose.mongodb.MongoClientOptions;", + "mongodb.MongoClientStatic;mongodb/mongodb.MongoClientStatic;", + "mongodb.MongoClientStatic;mongodb;Member[MongoClient]", + "mongodb.MongoClientStatic;mongoose.mongodb.MongoClientStatic;", + "mongodb.MongoOptions;mongodb.ClientSession;Member[clientOptions]", + "mongodb.MongoOptions;mongodb.MongoClient;Member[options]", + "mongodb.MongoOptions;mongodb/mongodb.MongoOptions;", + "mongodb.MongoOptions;mongoose.mongodb.MongoOptions;", + "mongodb.OperationOptions;mongodb.Collection;Member[isCapped,options].Argument[0]", + "mongodb.OperationOptions;mongodb.CommandOperationOptions;", + "mongodb.OperationOptions;mongodb/mongodb.OperationOptions;", + "mongodb.OperationOptions;mongoose.mongodb.OperationOptions;", + "mongodb.OrderedBulkOperation;mongodb.Collection;Member[initializeOrderedBulkOp].ReturnValue", + "mongodb.OrderedBulkOperation;mongodb.OrderedBulkOperation;Member[addToOperationsList].ReturnValue", + "mongodb.OrderedBulkOperation;mongodb.OrderedBulkOperationStatic;Instance", + "mongodb.OrderedBulkOperation;mongodb/mongodb.OrderedBulkOperation;", + "mongodb.OrderedBulkOperation;mongoose.mongodb.OrderedBulkOperation;", + "mongodb.OrderedBulkOperationStatic;mongodb/mongodb.OrderedBulkOperationStatic;", + "mongodb.OrderedBulkOperationStatic;mongodb;Member[OrderedBulkOperation]", + "mongodb.OrderedBulkOperationStatic;mongoose.mongodb.OrderedBulkOperationStatic;", + "mongodb.ProfilingLevelOptions;mongodb.Db;Member[profilingLevel].Argument[0]", + "mongodb.ProfilingLevelOptions;mongodb/mongodb.ProfilingLevelOptions;", + "mongodb.ProfilingLevelOptions;mongoose.mongodb.ProfilingLevelOptions;", + "mongodb.ReadPreferenceFromOptions;mongodb.ReadPreferenceStatic;Member[fromOptions].Argument[0]", + "mongodb.ReadPreferenceFromOptions;mongodb/mongodb.ReadPreferenceFromOptions;", + "mongodb.ReadPreferenceFromOptions;mongoose.mongodb.ReadPreferenceFromOptions;", + "mongodb.ReadPreferenceStatic;mongodb/mongodb.ReadPreferenceStatic;", + "mongodb.ReadPreferenceStatic;mongodb;Member[ReadPreference]", + "mongodb.ReadPreferenceStatic;mongoose.mongodb.ReadPreferenceStatic;", + "mongodb.RemoveUserOptions;mongodb.Admin;Member[removeUser].Argument[1]", + "mongodb.RemoveUserOptions;mongodb.Db;Member[removeUser].Argument[1]", + "mongodb.RemoveUserOptions;mongodb/mongodb.RemoveUserOptions;", + "mongodb.RemoveUserOptions;mongoose.mongodb.RemoveUserOptions;", + "mongodb.RenameOptions;mongodb.Collection;Member[rename].Argument[1]", + "mongodb.RenameOptions;mongodb.Db;Member[renameCollection].Argument[2]", + "mongodb.RenameOptions;mongodb/mongodb.RenameOptions;", + "mongodb.RenameOptions;mongoose.mongodb.RenameOptions;", + "mongodb.ReplaceOptions;mongodb.Collection;Member[replaceOne].Argument[2]", + "mongodb.ReplaceOptions;mongodb/mongodb.ReplaceOptions;", + "mongodb.ReplaceOptions;mongoose.mongodb.ReplaceOptions;", + "mongodb.RunCommandOptions;mongodb.Admin;Member[command].Argument[1]", + "mongodb.RunCommandOptions;mongodb.Db;Member[command].Argument[1]", + "mongodb.RunCommandOptions;mongodb/mongodb.RunCommandOptions;", + "mongodb.RunCommandOptions;mongoose.mongodb.RunCommandOptions;", + "mongodb.SelectServerOptions;mongodb/mongodb.SelectServerOptions;", + "mongodb.SelectServerOptions;mongoose.mongodb.SelectServerOptions;", + "mongodb.SetProfilingLevelOptions;mongodb.Db;Member[setProfilingLevel].Argument[1]", + "mongodb.SetProfilingLevelOptions;mongodb/mongodb.SetProfilingLevelOptions;", + "mongodb.SetProfilingLevelOptions;mongoose.mongodb.SetProfilingLevelOptions;", + "mongodb.Transaction;mongodb.ClientSession;Member[transaction]", + "mongodb.Transaction;mongodb.TransactionStatic;Instance", + "mongodb.Transaction;mongodb/mongodb.Transaction;", + "mongodb.Transaction;mongoose.mongodb.Transaction;", + "mongodb.TransactionOptions;mongodb.ClientSession;Member[defaultTransactionOptions]", + "mongodb.TransactionOptions;mongodb.ClientSession;Member[startTransaction].Argument[0]", + "mongodb.TransactionOptions;mongodb.ClientSession;Member[withTransaction].Argument[1]", + "mongodb.TransactionOptions;mongodb.ClientSessionOptions;Member[defaultTransactionOptions]", + "mongodb.TransactionOptions;mongodb.Transaction;Member[options]", + "mongodb.TransactionOptions;mongodb/mongodb.TransactionOptions;", + "mongodb.TransactionOptions;mongoose.mongodb.TransactionOptions;", + "mongodb.TransactionStatic;mongodb/mongodb.TransactionStatic;", + "mongodb.TransactionStatic;mongodb;Member[Transaction]", + "mongodb.TransactionStatic;mongoose.mongodb.TransactionStatic;", + "mongodb.TypedEventEmitter;mongodb.AbstractCursor;", + "mongodb.TypedEventEmitter;mongodb.ChangeStream;", + "mongodb.TypedEventEmitter;mongodb.ClientSession;", + "mongodb.TypedEventEmitter;mongodb.GridFSBucket;", + "mongodb.TypedEventEmitter;mongodb.MongoClient;", + "mongodb.UnorderedBulkOperation;mongodb.Collection;Member[initializeUnorderedBulkOp].ReturnValue", + "mongodb.UnorderedBulkOperation;mongodb.UnorderedBulkOperation;Member[addToOperationsList].ReturnValue", + "mongodb.UnorderedBulkOperation;mongodb.UnorderedBulkOperationStatic;Instance", + "mongodb.UnorderedBulkOperation;mongodb/mongodb.UnorderedBulkOperation;", + "mongodb.UnorderedBulkOperation;mongoose.mongodb.UnorderedBulkOperation;", + "mongodb.UnorderedBulkOperationStatic;mongodb/mongodb.UnorderedBulkOperationStatic;", + "mongodb.UnorderedBulkOperationStatic;mongodb;Member[UnorderedBulkOperation]", + "mongodb.UnorderedBulkOperationStatic;mongoose.mongodb.UnorderedBulkOperationStatic;", + "mongodb.UpdateManyModel;mongodb.AnyBulkWriteOperation;Member[updateMany]", + "mongodb.UpdateManyModel;mongodb/mongodb.UpdateManyModel;", + "mongodb.UpdateManyModel;mongoose.mongodb.UpdateManyModel;", + "mongodb.UpdateOneModel;mongodb.AnyBulkWriteOperation;Member[updateOne]", + "mongodb.UpdateOneModel;mongodb/mongodb.UpdateOneModel;", + "mongodb.UpdateOneModel;mongoose.mongodb.UpdateOneModel;", + "mongodb.UpdateOptions;mongodb.Collection;Member[update,updateMany,updateOne].Argument[2]", + "mongodb.UpdateOptions;mongodb/mongodb.UpdateOptions;", + "mongodb.UpdateOptions;mongoose.mongodb.UpdateOptions;", + "mongodb.ValidateCollectionOptions;mongodb.Admin;Member[validateCollection].Argument[1]", + "mongodb.ValidateCollectionOptions;mongodb/mongodb.ValidateCollectionOptions;", + "mongodb.ValidateCollectionOptions;mongoose.mongodb.ValidateCollectionOptions;", + "mongodb.WithSessionCallback;mongodb.MongoClient;Member[withSession].Argument[1]", + "mongodb.WithSessionCallback;mongodb.MongoClient;Member[withSession].WithArity[1].Argument[0]", + "mongodb.WithSessionCallback;mongodb/mongodb.WithSessionCallback;", + "mongodb.WithSessionCallback;mongoose.mongodb.WithSessionCallback;", + "mongodb.WithTransactionCallback;mongodb.ClientSession;Member[withTransaction].Argument[0]", + "mongodb.WithTransactionCallback;mongodb/mongodb.WithTransactionCallback;", + "mongodb.WithTransactionCallback;mongoose.mongodb.WithTransactionCallback;", + "mongodb;mongoose;Member[mongodb]", + "mongoose.AcceptsDiscriminator;mongoose.Model;", + "mongoose.AcceptsDiscriminator;mongoose.Schema.Types.Array;", + "mongoose.AcceptsDiscriminator;mongoose.Schema.Types.DocumentArray;", + "mongoose.AcceptsDiscriminator;mongoose.Schema.Types.Subdocument;", + "mongoose.Aggregate;mongoose.Aggregate;Member[addCursorFlag,addFields,allowDiskUse,append,collation,count,facet,graphLookup,group,hint,limit,lookup,match,model,near,option,project,read,readConcern,redact,replaceRoot,sample,search,session,skip,sort,sortByCount,unionWith,unwind].ReturnValue", + "mongoose.Aggregate;mongoose.AggregateStatic;Instance", + "mongoose.Aggregate;mongoose.Model;Member[aggregate].ReturnValue", + "mongoose.AggregateStatic;mongoose;Member[Aggregate]", + "mongoose.Collection;mongoose.Collection;Instance", + "mongoose.Collection;mongoose.Connection;Member[collection].ReturnValue", + "mongoose.Collection;mongoose.Connection;Member[collections].AnyMember", + "mongoose.Collection;mongoose.Document;Member[collection]", + "mongoose.Collection;mongoose.Model;Member[collection]", + "mongoose.Collection;mongoose;Member[Collection]", + "mongoose.CollectionBase;mongoose.Collection;", + "mongoose.CompileModelOptions;mongoose.Connection;Member[model].Argument[3]", + "mongoose.CompileModelOptions;mongoose;Member[model].Argument[3]", + "mongoose.ConnectOptions;mongoose.Connection;Member[openUri].WithArity[1,2,3].Argument[1]", + "mongoose.ConnectOptions;mongoose;Member[connect,createConnection].WithArity[1,2,3].Argument[1]", + "mongoose.Connection;mongoose.Collection;Argument[1]", + "mongoose.Connection;mongoose.CollectionBase;Member[conn]", + "mongoose.Connection;mongoose.CompileModelOptions;Member[connection]", + "mongoose.Connection;mongoose.Connection;Member[asPromise].ReturnValue.Awaited", + "mongoose.Connection;mongoose.Connection;Member[deleteModel,plugin,setClient,useDb].ReturnValue", + "mongoose.Connection;mongoose.Connection;Member[openUri].Argument[2].TypeVar[mongoose.Callback.0]", + "mongoose.Connection;mongoose.Connection;Member[openUri].WithArity[1,2].ReturnValue.Awaited", + "mongoose.Connection;mongoose.Connection;Member[openUri].WithArity[2,3].ReturnValue", + "mongoose.Connection;mongoose.Connection;Member[openUri].WithArity[2].Argument[1].TypeVar[mongoose.Callback.0]", + "mongoose.Connection;mongoose.ConnectionStatic;Instance", + "mongoose.Connection;mongoose.Document;Member[db]", + "mongoose.Connection;mongoose.Model;Member[db]", + "mongoose.Connection;mongoose;Member[connection]", + "mongoose.Connection;mongoose;Member[connections].ArrayElement", + "mongoose.Connection;mongoose;Member[createConnection].Argument[2].TypeVar[mongoose.Callback.0]", + "mongoose.Connection;mongoose;Member[createConnection].WithArity[0,1,2].ReturnValue", + "mongoose.Connection;mongoose;Member[createConnection].WithArity[2].Argument[1].TypeVar[mongoose.Callback.0]", + "mongoose.ConnectionStatic;mongoose;Member[Connection]", + "mongoose.Cursor;mongoose.Query;Member[cursor].ReturnValue", + "mongoose.DiscriminatorModel;mongoose.DiscriminatorSchema;TypeVar[mongoose.Schema.1]", + "mongoose.Document;mongoose.Document;Member[$getAllSubdocs,$getPopulatedDocs].ReturnValue.ArrayElement", + "mongoose.Document;mongoose.Document;Member[$inc,$parent,$set,depopulate,increment,init,overwrite,set].ReturnValue", + "mongoose.Document;mongoose.Document;Member[delete,deleteOne].WithArity[0,1].ReturnValue.TypeVar[mongoose.QueryWithHelpers.1]", + "mongoose.Document;mongoose.Document;Member[equals].Argument[0]", + "mongoose.Document;mongoose.Document;Member[init].Argument[2].TypeVar[mongoose.Callback.0]", + "mongoose.Document;mongoose.Document;Member[remove,save].WithArity[0,1].ReturnValue.Awaited", + "mongoose.Document;mongoose.Document;Member[replaceOne,update,updateOne].ReturnValue.TypeVar[mongoose.Query.1]", + "mongoose.Document;mongoose.Document;Member[save].Argument[1].TypeVar[mongoose.Callback.0]", + "mongoose.Document;mongoose.Document;Member[save].WithArity[1].Argument[0].TypeVar[mongoose.Callback.0]", + "mongoose.Document;mongoose.DocumentStatic;Instance", + "mongoose.Document;mongoose.Error.VersionErrorStatic;Argument[0]", + "mongoose.Document;mongoose.HydratedDocument;", + "mongoose.Document;mongoose.HydratedDocument;TypeVar[mongoose.Require_id.0]", + "mongoose.Document;mongoose.Model;Member[bulkSave].Argument[0].ArrayElement", + "mongoose.Document;mongoose.TVirtualPathFN;Argument[2]", + "mongoose.Document;mongoose.Types.Subdocument;", + "mongoose.Document;mongoose.Types.Subdocument;Member[$parent,ownerDocument,parent].ReturnValue", + "mongoose.Document;mongoose.VirtualType;Member[applyGetters,applySetters].Argument[1]", + "mongoose.DocumentStatic;mongoose;Member[Document]", + "mongoose.Error.VersionErrorStatic;mongoose;Member[Error].Member[VersionError]", + "mongoose.HydratedDocument;mongoose.Model;Instance", + "mongoose.HydratedDocument;mongoose.Model;Member[$where,count,countDocuments,deleteMany,deleteOne,distinct,estimatedDocumentCount,find,geoSearch,remove,replaceOne,update,updateMany,updateOne,where].ReturnValue.TypeVar[mongoose.QueryWithHelpers.1]", + "mongoose.HydratedDocument;mongoose.Model;Member[$where,find,geoSearch,where].ReturnValue.TypeVar[mongoose.QueryWithHelpers.0].ArrayElement", + "mongoose.HydratedDocument;mongoose.Model;Member[create,insertMany].WithArity[2].Argument[1].TypeVar[mongoose.Callback.0].ArrayElement", + "mongoose.HydratedDocument;mongoose.Model;Member[create].WithArity[0..,1,2].ReturnValue.Awaited.ArrayElement", + "mongoose.HydratedDocument;mongoose.Model;Member[create].WithArity[1].ReturnValue.Awaited", + "mongoose.HydratedDocument;mongoose.Model;Member[create].WithArity[2].Argument[1].TypeVar[mongoose.Callback.0]", + "mongoose.HydratedDocument;mongoose.Model;Member[exists].WithArity[1,2].ReturnValue.TypeVar[mongoose.QueryWithHelpers.1]", + "mongoose.HydratedDocument;mongoose.Model;Member[find,insertMany].WithArity[3].Argument[2].TypeVar[mongoose.Callback.0].ArrayElement", + "mongoose.HydratedDocument;mongoose.Model;Member[findById,findByIdAndDelete,findByIdAndRemove,findOne,findOneAndDelete,findOneAndRemove].ReturnValue.TypeVar[mongoose.QueryWithHelpers.0,mongoose.QueryWithHelpers.1]", + "mongoose.HydratedDocument;mongoose.Model;Member[findById,findOne].Argument[3].TypeVar[mongoose.Callback.0]", + "mongoose.HydratedDocument;mongoose.Model;Member[findByIdAndDelete,findByIdAndRemove,findOneAndDelete,findOneAndRemove].Argument[2].Argument[1]", + "mongoose.HydratedDocument;mongoose.Model;Member[findByIdAndUpdate,findOneAndReplace,findOneAndUpdate].WithArity[0,1,2,3,4].ReturnValue.TypeVar[mongoose.QueryWithHelpers.0,mongoose.QueryWithHelpers.1]", + "mongoose.HydratedDocument;mongoose.Model;Member[findByIdAndUpdate,findOneAndReplace,findOneAndUpdate].WithArity[3,4].ReturnValue.TypeVar[mongoose.QueryWithHelpers.0].TypeVar[mongoose.ModifyResult.0]", + "mongoose.HydratedDocument;mongoose.Model;Member[findByIdAndUpdate].WithArity[0,1,2,4].Argument[3].Argument[1]", + "mongoose.HydratedDocument;mongoose.Model;Member[findByIdAndUpdate].WithArity[3].Argument[2,3].Argument[1]", + "mongoose.HydratedDocument;mongoose.Model;Member[findById].WithArity[1,2,3].Argument[2].TypeVar[mongoose.Callback.0]", + "mongoose.HydratedDocument;mongoose.Model;Member[findOneAndReplace].WithArity[0,1,2,3,4].Argument[3].Argument[1]", + "mongoose.HydratedDocument;mongoose.Model;Member[findOneAndUpdate].WithArity[3,4].Argument[3].Argument[1]", + "mongoose.HydratedDocument;mongoose.Model;Member[findOne].WithArity[0,1,2].Argument[1,2].TypeVar[mongoose.Callback.0]", + "mongoose.HydratedDocument;mongoose.Model;Member[findOne].WithArity[3].Argument[2].TypeVar[mongoose.Callback.0]", + "mongoose.HydratedDocument;mongoose.Model;Member[find].Argument[3].TypeVar[mongoose.Callback.0].ArrayElement", + "mongoose.HydratedDocument;mongoose.Model;Member[find].WithArity[0].Argument[0].TypeVar[mongoose.Callback.0].ArrayElement", + "mongoose.HydratedDocument;mongoose.Model;Member[find].WithArity[1].Argument[0,1,2].TypeVar[mongoose.Callback.0].ArrayElement", + "mongoose.HydratedDocument;mongoose.Model;Member[find].WithArity[2].Argument[1,2].TypeVar[mongoose.Callback.0].ArrayElement", + "mongoose.HydratedDocument;mongoose.Model;Member[geoSearch].Argument[2].TypeVar[mongoose.Callback.0].ArrayElement", + "mongoose.HydratedDocument;mongoose.Model;Member[hydrate].ReturnValue", + "mongoose.HydratedDocument;mongoose.Model;Member[init].ReturnValue.Awaited", + "mongoose.HydratedDocument;mongoose.Model;Member[insertMany].WithArity[1,2].ReturnValue.Awaited.ArrayElement", + "mongoose.HydratedDocument;mongoose.Model;Member[populate].WithArity[2,3].Argument[2].TypeVar[mongoose.Callback.0]", + "mongoose.HydratedDocument;mongoose.Model;Member[populate].WithArity[2,3].Argument[2].TypeVar[mongoose.Callback.0].ArrayElement", + "mongoose.HydratedDocument;mongoose.Model;Member[populate].WithArity[2,3].ReturnValue.Awaited", + "mongoose.HydratedDocument;mongoose.Model;Member[populate].WithArity[2,3].ReturnValue.Awaited.ArrayElement", + "mongoose.HydratedDocument;mongoose.TVirtualPathFN;Argument[1].TypeVar[mongoose.VirtualType.0]", + "mongoose.HydratedDocument;mongoose.VirtualPathFunctions;Member[options].TypeVar[mongoose.VirtualTypeOptions.0]", + "mongoose.InsertManyOptions;mongoose.Model;Member[insertMany].WithArity[2,3].Argument[1]", + "mongoose.Model;mongoose.AcceptsDiscriminator;Member[discriminator].WithArity[2,3].ReturnValue", + "mongoose.Model;mongoose.Aggregate;Member[model].Argument[0]", + "mongoose.Model;mongoose.Connection;Member[model].WithArity[1,2,3,4].ReturnValue", + "mongoose.Model;mongoose.Connection;Member[models].AnyMember", + "mongoose.Model;mongoose.DiscriminatorModel;", + "mongoose.Model;mongoose.Document;Member[$model].ReturnValue", + "mongoose.Model;mongoose.Document;Member[populate].Argument[2]", + "mongoose.Model;mongoose.Model;Member[discriminators].AnyMember", + "mongoose.Model;mongoose.Models;AnyMember", + "mongoose.Model;mongoose.PopulateOptions;Member[model]", + "mongoose.Model;mongoose.Query;Member[cast].Argument[0]", + "mongoose.Model;mongoose.Query;Member[populate].Argument[2]", + "mongoose.Model;mongoose.Schema.Types.Array;Member[discriminator].WithArity[2,3].ReturnValue", + "mongoose.Model;mongoose.Schema.Types.DocumentArray;Member[discriminator].WithArity[2,3].ReturnValue", + "mongoose.Model;mongoose.Schema.Types.Subdocument;Member[discriminator].WithArity[2,3].ReturnValue", + "mongoose.Model;mongoose.SchemaStatic;Instance.TypeVar[mongoose.Schema.1]", + "mongoose.Model;mongoose;Member[Model]", + "mongoose.Model;mongoose;Member[model].ReturnValue", + "mongoose.Models;mongoose;Member[models]", + "mongoose.PopulateOption;mongoose.InsertManyOptions;", + "mongoose.PopulateOption;mongoose.QueryOptions;", + "mongoose.PopulateOptions;mongoose.Document;Member[populate].Argument[4]", + "mongoose.PopulateOptions;mongoose.Document;Member[populate].WithArity[1,2].Argument[0]", + "mongoose.PopulateOptions;mongoose.Document;Member[populate].WithArity[1,2].Argument[0].ArrayElement", + "mongoose.PopulateOptions;mongoose.Model;Member[populate].Argument[1]", + "mongoose.PopulateOptions;mongoose.Model;Member[populate].Argument[1].ArrayElement", + "mongoose.PopulateOptions;mongoose.PopulateOption;Member[populate]", + "mongoose.PopulateOptions;mongoose.PopulateOption;Member[populate].ArrayElement", + "mongoose.PopulateOptions;mongoose.PopulateOptions;Member[populate]", + "mongoose.PopulateOptions;mongoose.PopulateOptions;Member[populate].ArrayElement", + "mongoose.PopulateOptions;mongoose.Query;Member[populate].WithArity[1].Argument[0]", + "mongoose.PopulateOptions;mongoose.Query;Member[populate].WithArity[1].Argument[0].ArrayElement", + "mongoose.Query;mongoose.Document;Member[replaceOne,update,updateOne].ReturnValue", + "mongoose.Query;mongoose.HydratedDocument;TypeVar[mongoose.Require_id.0]", + "mongoose.Query;mongoose.Query;Member[all,allowDiskUse,and,batchSize,box,circle,clone,collation,comment,elemMatch,equals,exists,explain,geometry,gt,gte,hint,in,intersects,j,limit,lt,lte,maxDistance,maxScan,maxTimeMS,merge,mod,ne,near,nin,nor,or,polygon,read,readConcern,regex,remove,select,session,set,setOptions,size,skip,slice,snapshot,sort,tailable,w,where,within,wtimeout].ReturnValue", + "mongoose.Query;mongoose.Query;Member[error].WithArity[1].ReturnValue", + "mongoose.Query;mongoose.Query;Member[merge].Argument[0]", + "mongoose.Query;mongoose.QueryStatic;Instance", + "mongoose.Query;mongoose.QueryWithHelpers;", + "mongoose.QueryOptions;mongoose.Document;Member[delete,deleteOne,remove].WithArity[0,1,2].Argument[0]", + "mongoose.QueryOptions;mongoose.Document;Member[replaceOne,update,updateOne].Argument[1]", + "mongoose.QueryOptions;mongoose.Model;Member[countDocuments,findByIdAndDelete,findByIdAndRemove,findOneAndDelete,findOneAndRemove].Argument[1]", + "mongoose.QueryOptions;mongoose.Model;Member[deleteMany,deleteOne].WithArity[0,1,2,3].Argument[1]", + "mongoose.QueryOptions;mongoose.Model;Member[estimatedDocumentCount].Argument[0]", + "mongoose.QueryOptions;mongoose.Model;Member[find,findById].WithArity[1,2,3,4].Argument[2]", + "mongoose.QueryOptions;mongoose.Model;Member[findByIdAndUpdate,findOne,findOneAndReplace,findOneAndUpdate].WithArity[0,1,2,3,4].Argument[2]", + "mongoose.QueryOptions;mongoose.Model;Member[replaceOne,update,updateMany,updateOne].Argument[2]", + "mongoose.QueryOptions;mongoose.PopulateOptions;Member[options]", + "mongoose.QueryOptions;mongoose.Query;Member[countDocuments,findByIdAndDelete,findOneAndDelete,findOneAndRemove].Argument[1]", + "mongoose.QueryOptions;mongoose.Query;Member[cursor,estimatedDocumentCount,setOptions].Argument[0]", + "mongoose.QueryOptions;mongoose.Query;Member[cursor].ReturnValue.TypeVar[mongoose.Cursor.1]", + "mongoose.QueryOptions;mongoose.Query;Member[deleteMany,deleteOne].WithArity[0,1,2,3].Argument[1]", + "mongoose.QueryOptions;mongoose.Query;Member[findByIdAndUpdate,findOne,findOneAndUpdate].WithArity[0,1,2,3,4].Argument[2]", + "mongoose.QueryOptions;mongoose.Query;Member[find].WithArity[1,2,3,4].Argument[2]", + "mongoose.QueryOptions;mongoose.Query;Member[getOptions].ReturnValue", + "mongoose.QueryOptions;mongoose.Query;Member[replaceOne,update,updateMany,updateOne].Argument[2]", + "mongoose.QueryOptions;mongoose.VirtualTypeOptions;Member[options]", + "mongoose.QueryStatic;mongoose;Member[Query]", + "mongoose.QueryWithHelpers;mongoose.Document;Member[delete,deleteOne].WithArity[0,1].ReturnValue", + "mongoose.QueryWithHelpers;mongoose.Model;Member[$where,count,countDocuments,deleteMany,deleteOne,distinct,estimatedDocumentCount,find,findById,findByIdAndDelete,findByIdAndRemove,findOne,findOneAndDelete,findOneAndRemove,geoSearch,remove,replaceOne,update,updateMany,updateOne,where].ReturnValue", + "mongoose.QueryWithHelpers;mongoose.Model;Member[exists].WithArity[1,2].ReturnValue", + "mongoose.QueryWithHelpers;mongoose.Model;Member[findByIdAndUpdate,findOneAndReplace,findOneAndUpdate].WithArity[0,1,2,3,4].ReturnValue", + "mongoose.QueryWithHelpers;mongoose.Query;Member[$where,count,countDocuments,deleteMany,deleteOne,distinct,estimatedDocumentCount,find,findByIdAndDelete,findOne,findOneAndDelete,findOneAndRemove,lean,orFail,populate,replaceOne,transform,update,updateMany,updateOne].ReturnValue", + "mongoose.QueryWithHelpers;mongoose.Query;Member[findByIdAndUpdate,findOneAndUpdate].WithArity[0,1,2,3,4].ReturnValue", + "mongoose.QueryWithHelpers;mongoose.Query;Member[toConstructor].ReturnValue.Instance", + "mongoose.Schema.Types.Array;mongoose.Schema.Types.Array;Member[enum].ReturnValue", + "mongoose.Schema.Types.Array;mongoose.Schema.Types.ArrayStatic;Instance", + "mongoose.Schema.Types.ArrayStatic;mongoose;Member[Schema].Member[Types].Member[Array]", + "mongoose.Schema.Types.DocumentArray;mongoose.Schema.Types.DocumentArrayStatic;Instance", + "mongoose.Schema.Types.DocumentArrayStatic;mongoose;Member[Schema].Member[Types].Member[DocumentArray]", + "mongoose.Schema.Types.Subdocument;mongoose.Schema.Types.SubdocumentStatic;Instance", + "mongoose.Schema.Types.SubdocumentStatic;mongoose.Schema.Types.DocumentArray;Member[caster]", + "mongoose.Schema.Types.SubdocumentStatic;mongoose;Member[Schema].Member[Types].Member[Subdocument]", + "mongoose.SchemaStatic;mongoose;Member[Schema]", + "mongoose.SessionOperation;mongoose.Aggregate;", + "mongoose.SessionOperation;mongoose.Query;", + "mongoose.TVirtualPathFN;mongoose.VirtualPathFunctions;Member[get,set]", + "mongoose.Types.Array;mongoose.Types.DocumentArray;", + "mongoose.Types.ArraySubdocument;mongoose.Types.ArraySubdocumentStatic;Instance", + "mongoose.Types.ArraySubdocumentStatic;mongoose;Member[Types].Member[ArraySubdocument]", + "mongoose.Types.DocumentArray;mongoose.Types.ArraySubdocument;Member[parentArray].ReturnValue", + "mongoose.Types.DocumentArray;mongoose.Types.DocumentArrayStatic;Instance", + "mongoose.Types.DocumentArray;mongoose/inferschematype.ResolvePathType;TypeVar[mongoose.IfEquals.3]", + "mongoose.Types.DocumentArrayStatic;mongoose;Member[Types].Member[DocumentArray]", + "mongoose.Types.ObjectId;mongoose/inferschematype.ResolvePathType;", + "mongoose.Types.Subdocument;mongoose.Types.ArraySubdocument;", + "mongoose.Types.Subdocument;mongoose.Types.DocumentArray;Member[create,id].ReturnValue", + "mongoose.Types.Subdocument;mongoose.Types.DocumentArray;TypeVar[mongoose.Types.Array.0]", + "mongoose.Types.Subdocument;mongoose.Types.SubdocumentStatic;Instance", + "mongoose.Types.SubdocumentStatic;mongoose;Member[Types].Member[Subdocument]", + "mongoose.VirtualType;mongoose.TVirtualPathFN;Argument[1]", + "mongoose.VirtualType;mongoose.VirtualType;Member[get,set].Argument[0].Argument[1]", + "mongoose.VirtualType;mongoose.VirtualType;Member[get,set].ReturnValue", + "mongoose.VirtualType;mongoose.VirtualTypeStatic;Instance", + "mongoose.VirtualTypeOptions;mongoose.VirtualPathFunctions;Member[options]", + "mongoose.VirtualTypeStatic;mongoose;Member[VirtualType]", + "mongoose/inferschematype.ResolvePathType;mongoose/inferschematype.ObtainDocumentPathType;", + "mongoose/inferschematype.ResolvePathType;mongoose/inferschematype.ResolvePathType;TypeVar[mongoose.IfEquals.3].ArrayElement", + "mongoose/inferschematype.ResolvePathType;mongoose/inferschematype.ResolvePathType;TypeVar[mongoose.IfEquals.3].TypeVar[mongoose.Types.DocumentArray.0]", + "mongoose;mongoose;Member[mongoose]" ], "summaries": [ - "mongodb;AbstractCursor;;;Member[addCursorFlag,batchSize,maxTimeMS,withReadConcern,withReadPreference].ReturnValue;type", - "mongodb;BulkOperationBase;;;Member[addToOperationsList,raw].ReturnValue;type", - "mongodb;FindCursor;;;Member[addQueryModifier,allowDiskUse,collation,comment,filter,hint,limit,max,maxAwaitTimeMS,maxTimeMS,min,returnKey,showRecordId,skip,sort].ReturnValue;type", - "mongodb;FindOperators;;;Member[arrayFilters,collation,upsert].ReturnValue;type", - "mongodb;GridFSBucketWriteStream;;;Member[end].ReturnValue;type", - "mongodb;MongoClient;;;Member[connect].Argument[0].TypeVar[mongodb.Callback.0];type", - "mongodb;MongoClient;;;Member[connect].WithArity[0].ReturnValue.Awaited;type", - "mongodb;OrderedBulkOperation;;;Member[addToOperationsList].ReturnValue;type", - "mongodb;TypedEventEmitter;;;Member[addListener,off,on,once,prependListener,prependOnceListener,removeAllListeners,removeListener,setMaxListeners].ReturnValue;type", - "mongodb;UnorderedBulkOperation;;;Member[addToOperationsList].ReturnValue;type", - "mongoose;Aggregate;;;Member[addCursorFlag,addFields,allowDiskUse,append,collation,count,facet,graphLookup,group,hint,limit,lookup,match,model,near,option,project,read,readConcern,redact,replaceRoot,sample,search,session,skip,sort,sortByCount,unionWith,unwind].ReturnValue;type", - "mongoose;Connection;;;Member[asPromise].ReturnValue.Awaited;type", - "mongoose;Connection;;;Member[deleteModel,setClient].ReturnValue;type", - "mongoose;Cursor;;;Member[addCursorFlag].ReturnValue;type", - "mongoose;Document;;;Member[$inc,$set,depopulate,increment,init,overwrite,set].ReturnValue;type", - "mongoose;Document;;;Member[delete,deleteOne].WithArity[0,1].ReturnValue.TypeVar[mongoose.QueryWithHelpers.1];type", - "mongoose;Document;;;Member[getChanges].ReturnValue.TypeVar[mongoose.UpdateQuery.0];type", - "mongoose;Document;;;Member[init].Argument[2].TypeVar[mongoose.Callback.0];type", - "mongoose;Document;;;Member[populate].Argument[1,5].TypeVar[mongoose.Callback.0].TypeVar[mongoose.MergeType.0];type", - "mongoose;Document;;;Member[populate].WithArity[1,2,3,4,5].ReturnValue.Awaited.TypeVar[mongoose.MergeType.0];type", - "mongoose;Document;;;Member[remove,save].WithArity[0,1].ReturnValue.Awaited;type", - "mongoose;Document;;;Member[replaceOne,update,updateOne].ReturnValue.TypeVar[mongoose.Query.1];type", - "mongoose;Document;;;Member[save].Argument[1].TypeVar[mongoose.Callback.0];type", - "mongoose;Document;;;Member[save].WithArity[1].Argument[0].TypeVar[mongoose.Callback.0];type", - "mongoose;Document;;;Member[update,updateOne].Argument[0].TypeVar[mongoose.UpdateQuery.0];type", - "mongoose;Query;;;Member[all,allowDiskUse,and,batchSize,box,circle,clone,collation,comment,elemMatch,equals,exists,explain,geometry,gt,gte,hint,in,intersects,j,limit,lt,lte,maxDistance,maxScan,maxTimeMS,merge,mod,ne,near,nin,nor,or,polygon,read,readConcern,regex,select,session,set,setOptions,size,skip,slice,snapshot,sort,tailable,w,where,within,wtimeout].ReturnValue;type", - "mongoose;Query;;;Member[error].WithArity[1].ReturnValue;type", - "mongoose;Schema.Types.Array;;;Member[enum].ReturnValue;type", - "mongoose;SessionOperation;;;Member[session].ReturnValue;type", - "mongoose;Types.Array;;;Member[pull,remove,set].ReturnValue;type", - "mongoose;Types.ObjectId;;;Member[_id];type", - "mongoose;VirtualType;;;Member[get,set].ReturnValue;type" + "mongodb.AbstractCursor;;;Member[addCursorFlag,batchSize,maxTimeMS,withReadConcern,withReadPreference].ReturnValue;type", + "mongodb.BulkOperationBase;;;Member[addToOperationsList,raw].ReturnValue;type", + "mongodb.FindCursor;;;Member[addQueryModifier,allowDiskUse,collation,comment,filter,hint,limit,max,maxAwaitTimeMS,maxTimeMS,min,returnKey,showRecordId,skip,sort].ReturnValue;type", + "mongodb.FindOperators;;;Member[arrayFilters,collation,upsert].ReturnValue;type", + "mongodb.GridFSBucketWriteStream;;;Member[end].ReturnValue;type", + "mongodb.MongoClient;;;Member[connect].Argument[0].TypeVar[mongodb.Callback.0];type", + "mongodb.MongoClient;;;Member[connect].WithArity[0].ReturnValue.Awaited;type", + "mongodb.OrderedBulkOperation;;;Member[addToOperationsList].ReturnValue;type", + "mongodb.TypedEventEmitter;;;Member[addListener,off,on,once,prependListener,prependOnceListener,removeAllListeners,removeListener,setMaxListeners].ReturnValue;type", + "mongodb.UnorderedBulkOperation;;;Member[addToOperationsList].ReturnValue;type", + "mongoose.Aggregate;;;Member[addCursorFlag,addFields,allowDiskUse,append,collation,count,facet,graphLookup,group,hint,limit,lookup,match,model,near,option,project,read,readConcern,redact,replaceRoot,sample,search,session,skip,sort,sortByCount,unionWith,unwind].ReturnValue;type", + "mongoose.Connection;;;Member[asPromise].ReturnValue.Awaited;type", + "mongoose.Connection;;;Member[deleteModel,setClient].ReturnValue;type", + "mongoose.Cursor;;;Member[addCursorFlag].ReturnValue;type", + "mongoose.Document;;;Member[$inc,$set,depopulate,increment,init,overwrite,set].ReturnValue;type", + "mongoose.Document;;;Member[delete,deleteOne].WithArity[0,1].ReturnValue.TypeVar[mongoose.QueryWithHelpers.1];type", + "mongoose.Document;;;Member[getChanges].ReturnValue.TypeVar[mongoose.UpdateQuery.0];type", + "mongoose.Document;;;Member[init].Argument[2].TypeVar[mongoose.Callback.0];type", + "mongoose.Document;;;Member[populate].Argument[1,5].TypeVar[mongoose.Callback.0].TypeVar[mongoose.MergeType.0];type", + "mongoose.Document;;;Member[populate].WithArity[1,2,3,4,5].ReturnValue.Awaited.TypeVar[mongoose.MergeType.0];type", + "mongoose.Document;;;Member[remove,save].WithArity[0,1].ReturnValue.Awaited;type", + "mongoose.Document;;;Member[replaceOne,update,updateOne].ReturnValue.TypeVar[mongoose.Query.1];type", + "mongoose.Document;;;Member[save].Argument[1].TypeVar[mongoose.Callback.0];type", + "mongoose.Document;;;Member[save].WithArity[1].Argument[0].TypeVar[mongoose.Callback.0];type", + "mongoose.Document;;;Member[update,updateOne].Argument[0].TypeVar[mongoose.UpdateQuery.0];type", + "mongoose.Query;;;Member[all,allowDiskUse,and,batchSize,box,circle,clone,collation,comment,elemMatch,equals,exists,explain,geometry,gt,gte,hint,in,intersects,j,limit,lt,lte,maxDistance,maxScan,maxTimeMS,merge,mod,ne,near,nin,nor,or,polygon,read,readConcern,regex,select,session,set,setOptions,size,skip,slice,snapshot,sort,tailable,w,where,within,wtimeout].ReturnValue;type", + "mongoose.Query;;;Member[error].WithArity[1].ReturnValue;type", + "mongoose.Schema.Types.Array;;;Member[enum].ReturnValue;type", + "mongoose.SessionOperation;;;Member[session].ReturnValue;type", + "mongoose.Types.Array;;;Member[pull,remove,set].ReturnValue;type", + "mongoose.Types.ObjectId;;;Member[_id];type", + "mongoose.VirtualType;;;Member[get,set].ReturnValue;type" ], "typeVariables": [ "mongodb.Callback.0;Argument[1]", diff --git a/javascript/ql/lib/semmle/javascript/frameworks/mssql/Model.qll b/javascript/ql/lib/semmle/javascript/frameworks/mssql/Model.qll index 0d69eea01e0..7d119ebfc02 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/mssql/Model.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/mssql/Model.qll @@ -6,40 +6,40 @@ private class Types extends ModelInput::TypeModelCsv { override predicate row(string row) { row = [ - "mssql;ConnectionPool;mssql/msnodesqlv8;;Member[connect].ReturnValue.Awaited", // - "mssql;ConnectionPool;mssql/msnodesqlv8;;Member[pool]", // - "mssql;ConnectionPool;mssql;;Member[connect].ReturnValue.Awaited", // - "mssql;ConnectionPool;mssql;;Member[pool]", // - "mssql;ConnectionPool;mssql;ConnectionPool;Member[connect].WithArity[0].ReturnValue.Awaited", // - "mssql;ConnectionPool;mssql;ConnectionPoolStatic;Instance", // - "mssql;ConnectionPoolStatic;mssql/msnodesqlv8;;Member[ConnectionPool]", // - "mssql;ConnectionPoolStatic;mssql;;Member[ConnectionPool]", // - "mssql;PreparedStatement;mssql;PreparedStatement;Member[input,output].ReturnValue", // - "mssql;PreparedStatement;mssql;PreparedStatement;Member[prepare].WithArity[0,1,2].ReturnValue", // - "mssql;PreparedStatement;mssql;PreparedStatement;Member[unprepare].WithArity[1].ReturnValue", // - "mssql;PreparedStatement;mssql;PreparedStatementStatic;Instance", // - "mssql;PreparedStatement;mssql;Request;Member[pstatement]", // - "mssql;PreparedStatementStatic;mssql/msnodesqlv8;;Member[PreparedStatement]", // - "mssql;PreparedStatementStatic;mssql;;Member[PreparedStatement]", // - "mssql;Request;mssql;ConnectionPool;Member[request].ReturnValue", // - "mssql;Request;mssql;PreparedStatement;Member[execute].WithArity[2].ReturnValue", // - "mssql;Request;mssql;Request;Member[input,output,replaceInput].ReturnValue", // - "mssql;Request;mssql;Request;Member[replaceOutput].ReturnValue", // - "mssql;Request;mssql;RequestStatic;Instance", // - "mssql;Request;mssql;Transaction;Member[request].ReturnValue", // - "mssql;RequestStatic;mssql/msnodesqlv8;;Member[Request]", // - "mssql;RequestStatic;mssql;;Member[Request]", // - "mssql;Transaction;mssql;ConnectionPool;Member[transaction].ReturnValue", // - "mssql;Transaction;mssql;PreparedStatement;Member[transaction]", // - "mssql;Transaction;mssql;Request;Member[transaction]", // - "mssql;Transaction;mssql;Transaction;Member[begin].WithArity[0,1,2].ReturnValue", // - "mssql;Transaction;mssql;Transaction;Member[begin].WithArity[0,1].ReturnValue.Awaited", // - "mssql;Transaction;mssql;TransactionStatic;Instance", // - "mssql;TransactionStatic;mssql/msnodesqlv8;;Member[Transaction]", // - "mssql;TransactionStatic;mssql;;Member[Transaction]", // - "mssql;config;mssql/msnodesqlv8;;Member[connect].Argument[0]", // - "mssql;config;mssql;;Member[connect].Argument[0]", // - "mssql;config;mssql;ConnectionPoolStatic;WithArity[1,2].Argument[0]", // + "mssql.ConnectionPool;mssql.ConnectionPool;Member[connect].WithArity[0].ReturnValue.Awaited", // + "mssql.ConnectionPool;mssql.ConnectionPoolStatic;Instance", // + "mssql.ConnectionPool;mssql/msnodesqlv8;Member[connect].ReturnValue.Awaited", // + "mssql.ConnectionPool;mssql/msnodesqlv8;Member[pool]", // + "mssql.ConnectionPool;mssql;Member[connect].ReturnValue.Awaited", // + "mssql.ConnectionPool;mssql;Member[pool]", // + "mssql.ConnectionPoolStatic;mssql/msnodesqlv8;Member[ConnectionPool]", // + "mssql.ConnectionPoolStatic;mssql;Member[ConnectionPool]", // + "mssql.PreparedStatement;mssql.PreparedStatement;Member[input,output].ReturnValue", // + "mssql.PreparedStatement;mssql.PreparedStatement;Member[prepare].WithArity[0,1,2].ReturnValue", // + "mssql.PreparedStatement;mssql.PreparedStatement;Member[unprepare].WithArity[1].ReturnValue", // + "mssql.PreparedStatement;mssql.PreparedStatementStatic;Instance", // + "mssql.PreparedStatement;mssql.Request;Member[pstatement]", // + "mssql.PreparedStatementStatic;mssql/msnodesqlv8;Member[PreparedStatement]", // + "mssql.PreparedStatementStatic;mssql;Member[PreparedStatement]", // + "mssql.Request;mssql.ConnectionPool;Member[request].ReturnValue", // + "mssql.Request;mssql.PreparedStatement;Member[execute].WithArity[2].ReturnValue", // + "mssql.Request;mssql.Request;Member[input,output,replaceInput].ReturnValue", // + "mssql.Request;mssql.Request;Member[replaceOutput].ReturnValue", // + "mssql.Request;mssql.RequestStatic;Instance", // + "mssql.Request;mssql.Transaction;Member[request].ReturnValue", // + "mssql.RequestStatic;mssql/msnodesqlv8;Member[Request]", // + "mssql.RequestStatic;mssql;Member[Request]", // + "mssql.Transaction;mssql.ConnectionPool;Member[transaction].ReturnValue", // + "mssql.Transaction;mssql.PreparedStatement;Member[transaction]", // + "mssql.Transaction;mssql.Request;Member[transaction]", // + "mssql.Transaction;mssql.Transaction;Member[begin].WithArity[0,1,2].ReturnValue", // + "mssql.Transaction;mssql.Transaction;Member[begin].WithArity[0,1].ReturnValue.Awaited", // + "mssql.Transaction;mssql.TransactionStatic;Instance", // + "mssql.TransactionStatic;mssql/msnodesqlv8;Member[Transaction]", // + "mssql.TransactionStatic;mssql;Member[Transaction]", // + "mssql.config;mssql.ConnectionPoolStatic;WithArity[1,2].Argument[0]", // + "mssql.config;mssql/msnodesqlv8;Member[connect].Argument[0]", // + "mssql.config;mssql;Member[connect].Argument[0]", // ] } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/mssql/model.json b/javascript/ql/lib/semmle/javascript/frameworks/mssql/model.json index bd8e780a881..5dc81faeb49 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/mssql/model.json +++ b/javascript/ql/lib/semmle/javascript/frameworks/mssql/model.json @@ -10,55 +10,55 @@ "language": "javascript", "usedTypes": { "sources": [ - "mssql;Request", - "mssql;ConnectionPool" + "mssql.Request", + "mssql.ConnectionPool" ], "sinks": [ - "mssql;config" + "mssql.config" ] }, "model": { "typeDefinitions": [ - "mssql;Request;mssql;Request;Member[replaceOutput].ReturnValue" + "mssql.Request;mssql.Request;Member[replaceOutput].ReturnValue" ], "sinks": [] }, "generatedModel": { "//": "Autogenerated section. Manual edits in here will be lost.", "typeDefinitions": [ - "mssql;ConnectionPool;mssql/msnodesqlv8;;Member[connect].ReturnValue.Awaited", - "mssql;ConnectionPool;mssql/msnodesqlv8;;Member[pool]", - "mssql;ConnectionPool;mssql;;Member[connect].ReturnValue.Awaited", - "mssql;ConnectionPool;mssql;;Member[pool]", - "mssql;ConnectionPool;mssql;ConnectionPool;Member[connect].WithArity[0].ReturnValue.Awaited", - "mssql;ConnectionPool;mssql;ConnectionPoolStatic;Instance", - "mssql;ConnectionPoolStatic;mssql/msnodesqlv8;;Member[ConnectionPool]", - "mssql;ConnectionPoolStatic;mssql;;Member[ConnectionPool]", - "mssql;PreparedStatement;mssql;PreparedStatement;Member[input,output].ReturnValue", - "mssql;PreparedStatement;mssql;PreparedStatement;Member[prepare].WithArity[0,1,2].ReturnValue", - "mssql;PreparedStatement;mssql;PreparedStatement;Member[unprepare].WithArity[1].ReturnValue", - "mssql;PreparedStatement;mssql;PreparedStatementStatic;Instance", - "mssql;PreparedStatement;mssql;Request;Member[pstatement]", - "mssql;PreparedStatementStatic;mssql/msnodesqlv8;;Member[PreparedStatement]", - "mssql;PreparedStatementStatic;mssql;;Member[PreparedStatement]", - "mssql;Request;mssql;ConnectionPool;Member[request].ReturnValue", - "mssql;Request;mssql;PreparedStatement;Member[execute].WithArity[2].ReturnValue", - "mssql;Request;mssql;Request;Member[input,output,replaceInput].ReturnValue", - "mssql;Request;mssql;RequestStatic;Instance", - "mssql;Request;mssql;Transaction;Member[request].ReturnValue", - "mssql;RequestStatic;mssql/msnodesqlv8;;Member[Request]", - "mssql;RequestStatic;mssql;;Member[Request]", - "mssql;Transaction;mssql;ConnectionPool;Member[transaction].ReturnValue", - "mssql;Transaction;mssql;PreparedStatement;Member[transaction]", - "mssql;Transaction;mssql;Request;Member[transaction]", - "mssql;Transaction;mssql;Transaction;Member[begin].WithArity[0,1,2].ReturnValue", - "mssql;Transaction;mssql;Transaction;Member[begin].WithArity[0,1].ReturnValue.Awaited", - "mssql;Transaction;mssql;TransactionStatic;Instance", - "mssql;TransactionStatic;mssql/msnodesqlv8;;Member[Transaction]", - "mssql;TransactionStatic;mssql;;Member[Transaction]", - "mssql;config;mssql/msnodesqlv8;;Member[connect].Argument[0]", - "mssql;config;mssql;;Member[connect].Argument[0]", - "mssql;config;mssql;ConnectionPoolStatic;WithArity[1,2].Argument[0]" + "mssql.ConnectionPool;mssql.ConnectionPool;Member[connect].WithArity[0].ReturnValue.Awaited", + "mssql.ConnectionPool;mssql.ConnectionPoolStatic;Instance", + "mssql.ConnectionPool;mssql/msnodesqlv8;Member[connect].ReturnValue.Awaited", + "mssql.ConnectionPool;mssql/msnodesqlv8;Member[pool]", + "mssql.ConnectionPool;mssql;Member[connect].ReturnValue.Awaited", + "mssql.ConnectionPool;mssql;Member[pool]", + "mssql.ConnectionPoolStatic;mssql/msnodesqlv8;Member[ConnectionPool]", + "mssql.ConnectionPoolStatic;mssql;Member[ConnectionPool]", + "mssql.PreparedStatement;mssql.PreparedStatement;Member[input,output].ReturnValue", + "mssql.PreparedStatement;mssql.PreparedStatement;Member[prepare].WithArity[0,1,2].ReturnValue", + "mssql.PreparedStatement;mssql.PreparedStatement;Member[unprepare].WithArity[1].ReturnValue", + "mssql.PreparedStatement;mssql.PreparedStatementStatic;Instance", + "mssql.PreparedStatement;mssql.Request;Member[pstatement]", + "mssql.PreparedStatementStatic;mssql/msnodesqlv8;Member[PreparedStatement]", + "mssql.PreparedStatementStatic;mssql;Member[PreparedStatement]", + "mssql.Request;mssql.ConnectionPool;Member[request].ReturnValue", + "mssql.Request;mssql.PreparedStatement;Member[execute].WithArity[2].ReturnValue", + "mssql.Request;mssql.Request;Member[input,output,replaceInput].ReturnValue", + "mssql.Request;mssql.RequestStatic;Instance", + "mssql.Request;mssql.Transaction;Member[request].ReturnValue", + "mssql.RequestStatic;mssql/msnodesqlv8;Member[Request]", + "mssql.RequestStatic;mssql;Member[Request]", + "mssql.Transaction;mssql.ConnectionPool;Member[transaction].ReturnValue", + "mssql.Transaction;mssql.PreparedStatement;Member[transaction]", + "mssql.Transaction;mssql.Request;Member[transaction]", + "mssql.Transaction;mssql.Transaction;Member[begin].WithArity[0,1,2].ReturnValue", + "mssql.Transaction;mssql.Transaction;Member[begin].WithArity[0,1].ReturnValue.Awaited", + "mssql.Transaction;mssql.TransactionStatic;Instance", + "mssql.TransactionStatic;mssql/msnodesqlv8;Member[Transaction]", + "mssql.TransactionStatic;mssql;Member[Transaction]", + "mssql.config;mssql.ConnectionPoolStatic;WithArity[1,2].Argument[0]", + "mssql.config;mssql/msnodesqlv8;Member[connect].Argument[0]", + "mssql.config;mssql;Member[connect].Argument[0]" ], "summaries": [], "typeVariables": [] diff --git a/javascript/ql/lib/semmle/javascript/frameworks/mysql/Model.qll b/javascript/ql/lib/semmle/javascript/frameworks/mysql/Model.qll index e8019d5a435..34ea14abb0b 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/mysql/Model.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/mysql/Model.qll @@ -6,63 +6,63 @@ private class Types extends ModelInput::TypeModelCsv { override predicate row(string row) { row = [ - "mysql2/promise;Connection;mysql2/promise;;Member[createConnectionPromise].ReturnValue.Awaited", // - "mysql2/promise;Connection;mysql2/promise;;Member[createConnection].ReturnValue.Awaited", // - "mysql2/promise;Connection;mysql2/promise;PoolConnection;", // - "mysql2/promise;Connection;mysql2;;Member[createConnectionPromise].ReturnValue.Awaited", // - "mysql2/promise;Connection;mysql2;Connection;Member[promise].ReturnValue", // - "mysql2/promise;Pool;mysql2/promise;;Member[createPool].ReturnValue", // - "mysql2/promise;Pool;mysql2/promise;Pool;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", // - "mysql2/promise;Pool;mysql2;Pool;Member[promise].ReturnValue", // - "mysql2/promise;PoolConnection;mysql2/promise;Pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connection,0=release].Argument[1].Argument[0]", // - "mysql2/promise;PoolConnection;mysql2/promise;Pool;Member[getConnection].ReturnValue.Awaited", // - "mysql2/promise;PoolConnection;mysql2;PoolConnection;Member[promise].ReturnValue", // - "mysql2/typings/mysql/lib/Connection;;mysql2/typings/mysql/lib/PoolConnection;;", // - "mysql2/typings/mysql/lib/Connection;;mysql2/typings/mysql;Connection;", // - "mysql2/typings/mysql/lib/PoolConnection;;mysql2/typings/mysql;PoolConnection;", // - "mysql2/typings/mysql;Connection;mysql2;Connection;", // - "mysql2/typings/mysql;Connection;mysql2;Pool;", // - "mysql2/typings/mysql;PoolConnection;mysql2;PoolConnection;", // - "mysql2;Connection;mysql2;;Member[createConnection].ReturnValue", // - "mysql2;Connection;mysql2;PoolConnection;", // - "mysql2;Connection;mysql2;authPlugins;Argument[0].Member[connection]", // - "mysql2;ConnectionOptions;mysql2/promise;;Member[createConnection].Argument[0]", // - "mysql2;ConnectionOptions;mysql2/promise;Connection;Member[changeUser].Argument[0]", // - "mysql2;ConnectionOptions;mysql2/promise;Connection;Member[config]", // - "mysql2;ConnectionOptions;mysql2;;Member[createConnection].Argument[0]", // - "mysql2;ConnectionOptions;mysql2;PoolOptions;", // - "mysql2;Pool;mysql2;;Member[createPool].ReturnValue", // - "mysql2;Pool;mysql2;Pool;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", // - "mysql2;PoolConnection;mysql2;Pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connection,0=release].Argument[1].Argument[0]", // - "mysql2;PoolConnection;mysql2;Pool;Member[getConnection].Argument[0].Argument[1]", // - "mysql2;PoolOptions;mysql2/promise;;Member[createPool].Argument[0]", // - "mysql2;PoolOptions;mysql2;;Member[createPool].Argument[0]", // - "mysql2;authPlugins;mysql2;ConnectionOptions;Member[authPlugins].AnyMember", // - "mysql;Connection;mysql;;Member[createConnection].ReturnValue", // - "mysql;Connection;mysql;Pool;Member[on,addListener].WithStringArgument[0=acquire,0=connection,0=release].Argument[1].Argument[0]", // - "mysql;Connection;mysql;PoolConnection;", // - "mysql;Connection;mysql;Query;Member[RowDataPacket].Argument[2]", // - "mysql;ConnectionConfig;mysql;;Member[createConnection].Argument[0]", // - "mysql;ConnectionConfig;mysql;Connection;Member[config]", // - "mysql;ConnectionConfig;mysql;PoolConfig;", // - "mysql;ConnectionOptions;mysql;Connection;Member[changeUser].WithArity[1,2].Argument[0]", // - "mysql;ConnectionOptions;mysql;ConnectionConfig;", // - "mysql;Pool;mysql;;Member[createPool].ReturnValue", // - "mysql;Pool;mysql;PoolCluster;Member[of].ReturnValue", // - "mysql;PoolCluster;mysql;;Member[createPoolCluster].ReturnValue", // - "mysql;PoolConfig;mysql;;Member[createPool].Argument[0]", // - "mysql;PoolConfig;mysql;PoolCluster;Member[add].Argument[1]", // - "mysql;PoolConfig;mysql;PoolCluster;Member[add].WithArity[1].Argument[0]", // - "mysql;PoolConnection;mysql;Pool;Member[acquireConnection].Argument[0]", // - "mysql;PoolConnection;mysql;Pool;Member[acquireConnection].Argument[1].Argument[1]", // - "mysql;PoolConnection;mysql;Pool;Member[getConnection].Argument[0].Argument[1]", // - "mysql;PoolConnection;mysql;PoolCluster;Member[getConnection].Argument[1,2].Argument[1]", // - "mysql;PoolConnection;mysql;PoolCluster;Member[getConnection].WithArity[1].Argument[0].Argument[1]", // - "mysql;Query;mysql;Query;Member[on].ReturnValue", // - "mysql;Query;mysql;QueryFunction;ReturnValue", // - "mysql;Query;mysql;QueryFunction;WithArity[1].Argument[0]", // - "mysql;QueryFunction;mysql;Connection;Member[createQuery,query]", // - "mysql;QueryFunction;mysql;Pool;Member[query]", // + "mysql.Connection;mysql.Pool;Member[on,addListener].WithStringArgument[0=acquire,0=connection,0=release].Argument[1].Argument[0]", // + "mysql.Connection;mysql.PoolConnection;", // + "mysql.Connection;mysql.Query;Member[RowDataPacket].Argument[2]", // + "mysql.Connection;mysql;Member[createConnection].ReturnValue", // + "mysql.ConnectionConfig;mysql.Connection;Member[config]", // + "mysql.ConnectionConfig;mysql.PoolConfig;", // + "mysql.ConnectionConfig;mysql;Member[createConnection].Argument[0]", // + "mysql.ConnectionOptions;mysql.Connection;Member[changeUser].WithArity[1,2].Argument[0]", // + "mysql.ConnectionOptions;mysql.ConnectionConfig;", // + "mysql.Pool;mysql.PoolCluster;Member[of].ReturnValue", // + "mysql.Pool;mysql;Member[createPool].ReturnValue", // + "mysql.PoolCluster;mysql;Member[createPoolCluster].ReturnValue", // + "mysql.PoolConfig;mysql.PoolCluster;Member[add].Argument[1]", // + "mysql.PoolConfig;mysql.PoolCluster;Member[add].WithArity[1].Argument[0]", // + "mysql.PoolConfig;mysql;Member[createPool].Argument[0]", // + "mysql.PoolConnection;mysql.Pool;Member[acquireConnection].Argument[0]", // + "mysql.PoolConnection;mysql.Pool;Member[acquireConnection].Argument[1].Argument[1]", // + "mysql.PoolConnection;mysql.Pool;Member[getConnection].Argument[0].Argument[1]", // + "mysql.PoolConnection;mysql.PoolCluster;Member[getConnection].Argument[1,2].Argument[1]", // + "mysql.PoolConnection;mysql.PoolCluster;Member[getConnection].WithArity[1].Argument[0].Argument[1]", // + "mysql.Query;mysql.Query;Member[on].ReturnValue", // + "mysql.Query;mysql.QueryFunction;ReturnValue", // + "mysql.Query;mysql.QueryFunction;WithArity[1].Argument[0]", // + "mysql.QueryFunction;mysql.Connection;Member[createQuery,query]", // + "mysql.QueryFunction;mysql.Pool;Member[query]", // + "mysql2.Connection;mysql2.PoolConnection;", // + "mysql2.Connection;mysql2.authPlugins;Argument[0].Member[connection]", // + "mysql2.Connection;mysql2;Member[createConnection].ReturnValue", // + "mysql2.ConnectionOptions;mysql2.PoolOptions;", // + "mysql2.ConnectionOptions;mysql2/promise.Connection;Member[changeUser].Argument[0]", // + "mysql2.ConnectionOptions;mysql2/promise.Connection;Member[config]", // + "mysql2.ConnectionOptions;mysql2/promise;Member[createConnection].Argument[0]", // + "mysql2.ConnectionOptions;mysql2;Member[createConnection].Argument[0]", // + "mysql2.Pool;mysql2.Pool;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", // + "mysql2.Pool;mysql2;Member[createPool].ReturnValue", // + "mysql2.PoolConnection;mysql2.Pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connection,0=release].Argument[1].Argument[0]", // + "mysql2.PoolConnection;mysql2.Pool;Member[getConnection].Argument[0].Argument[1]", // + "mysql2.PoolOptions;mysql2/promise;Member[createPool].Argument[0]", // + "mysql2.PoolOptions;mysql2;Member[createPool].Argument[0]", // + "mysql2.authPlugins;mysql2.ConnectionOptions;Member[authPlugins].AnyMember", // + "mysql2/promise.Connection;mysql2.Connection;Member[promise].ReturnValue", // + "mysql2/promise.Connection;mysql2/promise.PoolConnection;", // + "mysql2/promise.Connection;mysql2/promise;Member[createConnectionPromise].ReturnValue.Awaited", // + "mysql2/promise.Connection;mysql2/promise;Member[createConnection].ReturnValue.Awaited", // + "mysql2/promise.Connection;mysql2;Member[createConnectionPromise].ReturnValue.Awaited", // + "mysql2/promise.Pool;mysql2.Pool;Member[promise].ReturnValue", // + "mysql2/promise.Pool;mysql2/promise.Pool;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", // + "mysql2/promise.Pool;mysql2/promise;Member[createPool].ReturnValue", // + "mysql2/promise.PoolConnection;mysql2.PoolConnection;Member[promise].ReturnValue", // + "mysql2/promise.PoolConnection;mysql2/promise.Pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connection,0=release].Argument[1].Argument[0]", // + "mysql2/promise.PoolConnection;mysql2/promise.Pool;Member[getConnection].ReturnValue.Awaited", // + "mysql2/typings/mysql.Connection;mysql2.Connection;", // + "mysql2/typings/mysql.Connection;mysql2.Pool;", // + "mysql2/typings/mysql.PoolConnection;mysql2.PoolConnection;", // + "mysql2/typings/mysql/lib/Connection;mysql2/typings/mysql.Connection;", // + "mysql2/typings/mysql/lib/Connection;mysql2/typings/mysql/lib/PoolConnection;", // + "mysql2/typings/mysql/lib/PoolConnection;mysql2/typings/mysql.PoolConnection;", // ] } } @@ -71,9 +71,9 @@ private class Summaries extends ModelInput::SummaryModelCsv { override predicate row(string row) { row = [ - "mysql2/promise;Pool;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", // - "mysql2/typings/mysql/lib/Connection;;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", // - "mysql2;Pool;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", // + "mysql2.Pool;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", // + "mysql2/promise.Pool;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", // + "mysql2/typings/mysql/lib/Connection;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", // ] } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/mysql/model.json b/javascript/ql/lib/semmle/javascript/frameworks/mysql/model.json index 759956faa11..69add1ddad9 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/mysql/model.json +++ b/javascript/ql/lib/semmle/javascript/frameworks/mysql/model.json @@ -11,89 +11,89 @@ "language": "javascript", "usedTypes": { "sources": [ - "mysql;Pool", - "mysql;Connection", - "mysql2;Pool", - "mysql2;Connection", - "mysql2/promise;Pool", - "mysql2/promise;Connection" + "mysql.Pool", + "mysql.Connection", + "mysql2.Pool", + "mysql2.Connection", + "mysql2/promise.Pool", + "mysql2/promise.Connection" ], "sinks": [ - "mysql;ConnectionOptions", - "mysql2;ConnectionOptions", - "mysql2/promise;ConnectionOptions" + "mysql.ConnectionOptions", + "mysql2.ConnectionOptions", + "mysql2/promise.ConnectionOptions" ] }, "model": { "sinks": [], "typeDefinitions": [ - "mysql;Connection;mysql;Pool;Member[on,addListener].WithStringArgument[0=acquire,0=connection,0=release].Argument[1].Argument[0]", - "mysql2/promise;Connection;mysql2;;Member[createConnectionPromise].ReturnValue.Awaited", - "mysql2/promise;Connection;mysql2/promise;;Member[createConnectionPromise].ReturnValue.Awaited" + "mysql.Connection;mysql.Pool;Member[on,addListener].WithStringArgument[0=acquire,0=connection,0=release].Argument[1].Argument[0]", + "mysql2/promise.Connection;mysql2;Member[createConnectionPromise].ReturnValue.Awaited", + "mysql2/promise.Connection;mysql2/promise;Member[createConnectionPromise].ReturnValue.Awaited" ] }, "generatedModel": { "//": "Autogenerated section. Manual edits in here will be lost.", "typeDefinitions": [ - "mysql2/promise;Connection;mysql2/promise;;Member[createConnection].ReturnValue.Awaited", - "mysql2/promise;Connection;mysql2/promise;PoolConnection;", - "mysql2/promise;Connection;mysql2;Connection;Member[promise].ReturnValue", - "mysql2/promise;Pool;mysql2/promise;;Member[createPool].ReturnValue", - "mysql2/promise;Pool;mysql2/promise;Pool;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", - "mysql2/promise;Pool;mysql2;Pool;Member[promise].ReturnValue", - "mysql2/promise;PoolConnection;mysql2/promise;Pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connection,0=release].Argument[1].Argument[0]", - "mysql2/promise;PoolConnection;mysql2/promise;Pool;Member[getConnection].ReturnValue.Awaited", - "mysql2/promise;PoolConnection;mysql2;PoolConnection;Member[promise].ReturnValue", - "mysql2/typings/mysql/lib/Connection;;mysql2/typings/mysql/lib/PoolConnection;;", - "mysql2/typings/mysql/lib/Connection;;mysql2/typings/mysql;Connection;", - "mysql2/typings/mysql/lib/PoolConnection;;mysql2/typings/mysql;PoolConnection;", - "mysql2/typings/mysql;Connection;mysql2;Connection;", - "mysql2/typings/mysql;Connection;mysql2;Pool;", - "mysql2/typings/mysql;PoolConnection;mysql2;PoolConnection;", - "mysql2;Connection;mysql2;;Member[createConnection].ReturnValue", - "mysql2;Connection;mysql2;PoolConnection;", - "mysql2;Connection;mysql2;authPlugins;Argument[0].Member[connection]", - "mysql2;ConnectionOptions;mysql2/promise;;Member[createConnection].Argument[0]", - "mysql2;ConnectionOptions;mysql2/promise;Connection;Member[changeUser].Argument[0]", - "mysql2;ConnectionOptions;mysql2/promise;Connection;Member[config]", - "mysql2;ConnectionOptions;mysql2;;Member[createConnection].Argument[0]", - "mysql2;ConnectionOptions;mysql2;PoolOptions;", - "mysql2;Pool;mysql2;;Member[createPool].ReturnValue", - "mysql2;Pool;mysql2;Pool;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", - "mysql2;PoolConnection;mysql2;Pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connection,0=release].Argument[1].Argument[0]", - "mysql2;PoolConnection;mysql2;Pool;Member[getConnection].Argument[0].Argument[1]", - "mysql2;PoolOptions;mysql2/promise;;Member[createPool].Argument[0]", - "mysql2;PoolOptions;mysql2;;Member[createPool].Argument[0]", - "mysql2;authPlugins;mysql2;ConnectionOptions;Member[authPlugins].AnyMember", - "mysql;Connection;mysql;;Member[createConnection].ReturnValue", - "mysql;Connection;mysql;PoolConnection;", - "mysql;Connection;mysql;Query;Member[RowDataPacket].Argument[2]", - "mysql;ConnectionConfig;mysql;;Member[createConnection].Argument[0]", - "mysql;ConnectionConfig;mysql;Connection;Member[config]", - "mysql;ConnectionConfig;mysql;PoolConfig;", - "mysql;ConnectionOptions;mysql;Connection;Member[changeUser].WithArity[1,2].Argument[0]", - "mysql;ConnectionOptions;mysql;ConnectionConfig;", - "mysql;Pool;mysql;;Member[createPool].ReturnValue", - "mysql;Pool;mysql;PoolCluster;Member[of].ReturnValue", - "mysql;PoolCluster;mysql;;Member[createPoolCluster].ReturnValue", - "mysql;PoolConfig;mysql;;Member[createPool].Argument[0]", - "mysql;PoolConfig;mysql;PoolCluster;Member[add].Argument[1]", - "mysql;PoolConfig;mysql;PoolCluster;Member[add].WithArity[1].Argument[0]", - "mysql;PoolConnection;mysql;Pool;Member[acquireConnection].Argument[0]", - "mysql;PoolConnection;mysql;Pool;Member[acquireConnection].Argument[1].Argument[1]", - "mysql;PoolConnection;mysql;Pool;Member[getConnection].Argument[0].Argument[1]", - "mysql;PoolConnection;mysql;PoolCluster;Member[getConnection].Argument[1,2].Argument[1]", - "mysql;PoolConnection;mysql;PoolCluster;Member[getConnection].WithArity[1].Argument[0].Argument[1]", - "mysql;Query;mysql;Query;Member[on].ReturnValue", - "mysql;Query;mysql;QueryFunction;ReturnValue", - "mysql;Query;mysql;QueryFunction;WithArity[1].Argument[0]", - "mysql;QueryFunction;mysql;Connection;Member[createQuery,query]", - "mysql;QueryFunction;mysql;Pool;Member[query]" + "mysql.Connection;mysql.PoolConnection;", + "mysql.Connection;mysql.Query;Member[RowDataPacket].Argument[2]", + "mysql.Connection;mysql;Member[createConnection].ReturnValue", + "mysql.ConnectionConfig;mysql.Connection;Member[config]", + "mysql.ConnectionConfig;mysql.PoolConfig;", + "mysql.ConnectionConfig;mysql;Member[createConnection].Argument[0]", + "mysql.ConnectionOptions;mysql.Connection;Member[changeUser].WithArity[1,2].Argument[0]", + "mysql.ConnectionOptions;mysql.ConnectionConfig;", + "mysql.Pool;mysql.PoolCluster;Member[of].ReturnValue", + "mysql.Pool;mysql;Member[createPool].ReturnValue", + "mysql.PoolCluster;mysql;Member[createPoolCluster].ReturnValue", + "mysql.PoolConfig;mysql.PoolCluster;Member[add].Argument[1]", + "mysql.PoolConfig;mysql.PoolCluster;Member[add].WithArity[1].Argument[0]", + "mysql.PoolConfig;mysql;Member[createPool].Argument[0]", + "mysql.PoolConnection;mysql.Pool;Member[acquireConnection].Argument[0]", + "mysql.PoolConnection;mysql.Pool;Member[acquireConnection].Argument[1].Argument[1]", + "mysql.PoolConnection;mysql.Pool;Member[getConnection].Argument[0].Argument[1]", + "mysql.PoolConnection;mysql.PoolCluster;Member[getConnection].Argument[1,2].Argument[1]", + "mysql.PoolConnection;mysql.PoolCluster;Member[getConnection].WithArity[1].Argument[0].Argument[1]", + "mysql.Query;mysql.Query;Member[on].ReturnValue", + "mysql.Query;mysql.QueryFunction;ReturnValue", + "mysql.Query;mysql.QueryFunction;WithArity[1].Argument[0]", + "mysql.QueryFunction;mysql.Connection;Member[createQuery,query]", + "mysql.QueryFunction;mysql.Pool;Member[query]", + "mysql2.Connection;mysql2.PoolConnection;", + "mysql2.Connection;mysql2.authPlugins;Argument[0].Member[connection]", + "mysql2.Connection;mysql2;Member[createConnection].ReturnValue", + "mysql2.ConnectionOptions;mysql2.PoolOptions;", + "mysql2.ConnectionOptions;mysql2/promise.Connection;Member[changeUser].Argument[0]", + "mysql2.ConnectionOptions;mysql2/promise.Connection;Member[config]", + "mysql2.ConnectionOptions;mysql2/promise;Member[createConnection].Argument[0]", + "mysql2.ConnectionOptions;mysql2;Member[createConnection].Argument[0]", + "mysql2.Pool;mysql2.Pool;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", + "mysql2.Pool;mysql2;Member[createPool].ReturnValue", + "mysql2.PoolConnection;mysql2.Pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connection,0=release].Argument[1].Argument[0]", + "mysql2.PoolConnection;mysql2.Pool;Member[getConnection].Argument[0].Argument[1]", + "mysql2.PoolOptions;mysql2/promise;Member[createPool].Argument[0]", + "mysql2.PoolOptions;mysql2;Member[createPool].Argument[0]", + "mysql2.authPlugins;mysql2.ConnectionOptions;Member[authPlugins].AnyMember", + "mysql2/promise.Connection;mysql2.Connection;Member[promise].ReturnValue", + "mysql2/promise.Connection;mysql2/promise.PoolConnection;", + "mysql2/promise.Connection;mysql2/promise;Member[createConnection].ReturnValue.Awaited", + "mysql2/promise.Pool;mysql2.Pool;Member[promise].ReturnValue", + "mysql2/promise.Pool;mysql2/promise.Pool;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", + "mysql2/promise.Pool;mysql2/promise;Member[createPool].ReturnValue", + "mysql2/promise.PoolConnection;mysql2.PoolConnection;Member[promise].ReturnValue", + "mysql2/promise.PoolConnection;mysql2/promise.Pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connection,0=release].Argument[1].Argument[0]", + "mysql2/promise.PoolConnection;mysql2/promise.Pool;Member[getConnection].ReturnValue.Awaited", + "mysql2/typings/mysql.Connection;mysql2.Connection;", + "mysql2/typings/mysql.Connection;mysql2.Pool;", + "mysql2/typings/mysql.PoolConnection;mysql2.PoolConnection;", + "mysql2/typings/mysql/lib/Connection;mysql2/typings/mysql.Connection;", + "mysql2/typings/mysql/lib/Connection;mysql2/typings/mysql/lib/PoolConnection;", + "mysql2/typings/mysql/lib/PoolConnection;mysql2/typings/mysql.PoolConnection;" ], "summaries": [ - "mysql2/promise;Pool;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", - "mysql2/typings/mysql/lib/Connection;;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", - "mysql2;Pool;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type" + "mysql2.Pool;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", + "mysql2/promise.Pool;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", + "mysql2/typings/mysql/lib/Connection;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type" ], "typeVariables": [] } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/pg/Model.qll b/javascript/ql/lib/semmle/javascript/frameworks/pg/Model.qll index 82a43df3174..979b98bd0c5 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/pg/Model.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/pg/Model.qll @@ -6,71 +6,71 @@ private class Types extends ModelInput::TypeModelCsv { override predicate row(string row) { row = [ - "events;;pg-cursor;;", // - "events;;pg-promise/pg-subset;pg.IClient;", // - "events;;pg-promise/pg-subset;pg.IConnection;", // - "events;;pg-promise/pg-subset;pg.IPool;", // - "events;;pg;ClientBase;", // - "events;;pg;Events;", // - "events;;pg;Pool;", // - "global;NodeJS.EventEmitter;events;;", // - "pg-cursor;;pg-cursor;Static;Instance", // - "pg-cursor;Static;pg-cursor;;", // - "pg-pool;;pg-pool;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", // - "pg-pool;;pg-pool;Static;Instance", // - "pg-pool;Static;pg-pool;;", // - "pg-promise/pg-subset;pg.IClient;pg-promise/pg-subset;;Member[Client].Instance", // - "pg-promise/pg-subset;pg.IClient;pg-promise;;Argument[0].TypeVar[pg-promise.IInitOptions.1]", // - "pg-promise/pg-subset;pg.IClient;pg-promise;IMain;Argument[0].TypeVar[pg-promise/pg-subset.pg.IConnectionParameters.0]", // - "pg-promise/pg-subset;pg.IClient;pg-promise;IMain;ReturnValue.TypeVar[pg-promise.IDatabase.1]", // - "pg-promise/pg-subset;pg.IConnection;pg-promise/pg-subset;pg.IClient;Member[connection]", // - "pg-promise/pg-subset;pg.IPool;pg-promise;IDatabase;Member[$pool]", // - "pg-promise;IBaseProtocol;pg-promise/typescript/pg-promise;IBaseProtocol;", // - "pg-promise;IBaseProtocol;pg-promise;IConnected;", // - "pg-promise;IBaseProtocol;pg-promise;IDatabase;", // - "pg-promise;IBaseProtocol;pg-promise;ITask;", // - "pg-promise;IConnected;pg-promise/typescript/pg-promise;IConnected;", // - "pg-promise;IConnected;pg-promise;IDatabase;Member[connect].ReturnValue.Awaited", // - "pg-promise;IDatabase;pg-promise/typescript/pg-promise;IDatabase;", // - "pg-promise;IDatabase;pg-promise;IInitOptions;Member[extend].Argument[0]", // - "pg-promise;IDatabase;pg-promise;IMain;ReturnValue", // - "pg-promise;IInitOptions;pg-promise/typescript/pg-promise;IInitOptions;", // - "pg-promise;IInitOptions;pg-promise;;Argument[0]", // - "pg-promise;IInitOptions;pg-promise;ILibConfig;Member[options]", // - "pg-promise;ILibConfig;pg-promise/typescript/pg-promise;ILibConfig;", // - "pg-promise;ILibConfig;pg-promise;IDatabase;Member[$config]", // - "pg-promise;IMain;pg-promise/typescript/pg-promise;IMain;", // - "pg-promise;IMain;pg-promise;;ReturnValue", // - "pg-promise;IMain;pg-promise;ILibConfig;Member[pgp]", // - "pg-promise;ITask;pg-promise/typescript/pg-promise;ITask;", // - "pg-promise;ITask;pg-promise;IBaseProtocol;Member[task,taskIf,tx,txIf].Argument[1].Argument[0]", // - "pg-promise;ITask;pg-promise;IBaseProtocol;Member[task,taskIf,tx,txIf].WithArity[1].Argument[0].Argument[0]", // - "pg-promise;ITask;pg-promise;IBaseProtocol;Member[taskIf].WithArity[2].Argument[0].Member[cnd].Argument[0]", // - "pg-promise;ITask;pg-promise;IBaseProtocol;Member[txIf].WithArity[2].Argument[0].Member[cnd,reusable].Argument[0]", // - "pg;Client;pg-pool;Static;Instance.TypeVar[pg-pool..0]", // - "pg;Client;pg-promise/pg-subset;pg.IClient;", // - "pg;Client;pg;ClientStatic;Instance", // - "pg;Client;pg;Events;Member[addListener,on,once,prependListener,prependOnceListener].Argument[1].Argument[1]", // - "pg;ClientBase;pg;Client;", // - "pg;ClientBase;pg;PoolClient;", // - "pg;ClientStatic;pg;;Member[Client]", // - "pg;Connection;pg-promise/pg-subset;pg.IConnection;", // - "pg;Events;pg;Events;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", // - "pg;Events;pg;EventsStatic;Instance", // - "pg;EventsStatic;pg;;Member[Events]", // - "pg;Pool;pg-pool;;", // - "pg;Pool;pg-promise/pg-subset;pg.IPool;", // - "pg;Pool;pg;Pool;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", // - "pg;Pool;pg;PoolStatic;Instance", // - "pg;PoolClient;pg-pool;;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connect,0=remove].Argument[1].Argument[0]", // - "pg;PoolClient;pg-pool;;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=error].Argument[1].Argument[1]", // - "pg;PoolClient;pg-pool;;Member[connect].Argument[0].Argument[1]", // - "pg;PoolClient;pg-pool;;Member[connect].WithArity[0].ReturnValue.Awaited", // - "pg;PoolClient;pg;Pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connect,0=remove].Argument[1].Argument[0]", // - "pg;PoolClient;pg;Pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=error].Argument[1].Argument[1]", // - "pg;PoolClient;pg;Pool;Member[connect].Argument[0].Argument[1]", // - "pg;PoolClient;pg;Pool;Member[connect].WithArity[0].ReturnValue.Awaited", // - "pg;PoolStatic;pg;;Member[Pool]", // + "events;pg-cursor;", // + "events;pg-promise/pg-subset.pg.IClient;", // + "events;pg-promise/pg-subset.pg.IConnection;", // + "events;pg-promise/pg-subset.pg.IPool;", // + "events;pg.ClientBase;", // + "events;pg.Events;", // + "events;pg.Pool;", // + "global.NodeJS.EventEmitter;events;", // + "pg-cursor.Static;pg-cursor;", // + "pg-cursor;pg-cursor.Static;Instance", // + "pg-pool.Static;pg-pool;", // + "pg-pool;pg-pool.Static;Instance", // + "pg-pool;pg-pool;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", // + "pg-promise.IBaseProtocol;pg-promise.IConnected;", // + "pg-promise.IBaseProtocol;pg-promise.IDatabase;", // + "pg-promise.IBaseProtocol;pg-promise.ITask;", // + "pg-promise.IBaseProtocol;pg-promise/typescript/pg-promise.IBaseProtocol;", // + "pg-promise.IConnected;pg-promise.IDatabase;Member[connect].ReturnValue.Awaited", // + "pg-promise.IConnected;pg-promise/typescript/pg-promise.IConnected;", // + "pg-promise.IDatabase;pg-promise.IInitOptions;Member[extend].Argument[0]", // + "pg-promise.IDatabase;pg-promise.IMain;ReturnValue", // + "pg-promise.IDatabase;pg-promise/typescript/pg-promise.IDatabase;", // + "pg-promise.IInitOptions;pg-promise.ILibConfig;Member[options]", // + "pg-promise.IInitOptions;pg-promise/typescript/pg-promise.IInitOptions;", // + "pg-promise.IInitOptions;pg-promise;Argument[0]", // + "pg-promise.ILibConfig;pg-promise.IDatabase;Member[$config]", // + "pg-promise.ILibConfig;pg-promise/typescript/pg-promise.ILibConfig;", // + "pg-promise.IMain;pg-promise.ILibConfig;Member[pgp]", // + "pg-promise.IMain;pg-promise/typescript/pg-promise.IMain;", // + "pg-promise.IMain;pg-promise;ReturnValue", // + "pg-promise.ITask;pg-promise.IBaseProtocol;Member[task,taskIf,tx,txIf].Argument[1].Argument[0]", // + "pg-promise.ITask;pg-promise.IBaseProtocol;Member[task,taskIf,tx,txIf].WithArity[1].Argument[0].Argument[0]", // + "pg-promise.ITask;pg-promise.IBaseProtocol;Member[taskIf].WithArity[2].Argument[0].Member[cnd].Argument[0]", // + "pg-promise.ITask;pg-promise.IBaseProtocol;Member[txIf].WithArity[2].Argument[0].Member[cnd,reusable].Argument[0]", // + "pg-promise.ITask;pg-promise/typescript/pg-promise.ITask;", // + "pg-promise/pg-subset.pg.IClient;pg-promise.IMain;Argument[0].TypeVar[pg-promise/pg-subset.pg.IConnectionParameters.0]", // + "pg-promise/pg-subset.pg.IClient;pg-promise.IMain;ReturnValue.TypeVar[pg-promise.IDatabase.1]", // + "pg-promise/pg-subset.pg.IClient;pg-promise/pg-subset;Member[Client].Instance", // + "pg-promise/pg-subset.pg.IClient;pg-promise;Argument[0].TypeVar[pg-promise.IInitOptions.1]", // + "pg-promise/pg-subset.pg.IConnection;pg-promise/pg-subset.pg.IClient;Member[connection]", // + "pg-promise/pg-subset.pg.IPool;pg-promise.IDatabase;Member[$pool]", // + "pg.Client;pg-pool.Static;Instance.TypeVar[pg-pool.0]", // + "pg.Client;pg-promise/pg-subset.pg.IClient;", // + "pg.Client;pg.ClientStatic;Instance", // + "pg.Client;pg.Events;Member[addListener,on,once,prependListener,prependOnceListener].Argument[1].Argument[1]", // + "pg.ClientBase;pg.Client;", // + "pg.ClientBase;pg.PoolClient;", // + "pg.ClientStatic;pg;Member[Client]", // + "pg.Connection;pg-promise/pg-subset.pg.IConnection;", // + "pg.Events;pg.Events;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", // + "pg.Events;pg.EventsStatic;Instance", // + "pg.EventsStatic;pg;Member[Events]", // + "pg.Pool;pg-pool;", // + "pg.Pool;pg-promise/pg-subset.pg.IPool;", // + "pg.Pool;pg.Pool;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", // + "pg.Pool;pg.PoolStatic;Instance", // + "pg.PoolClient;pg-pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connect,0=remove].Argument[1].Argument[0]", // + "pg.PoolClient;pg-pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=error].Argument[1].Argument[1]", // + "pg.PoolClient;pg-pool;Member[connect].Argument[0].Argument[1]", // + "pg.PoolClient;pg-pool;Member[connect].WithArity[0].ReturnValue.Awaited", // + "pg.PoolClient;pg.Pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connect,0=remove].Argument[1].Argument[0]", // + "pg.PoolClient;pg.Pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=error].Argument[1].Argument[1]", // + "pg.PoolClient;pg.Pool;Member[connect].Argument[0].Argument[1]", // + "pg.PoolClient;pg.Pool;Member[connect].WithArity[0].ReturnValue.Awaited", // + "pg.PoolStatic;pg;Member[Pool]", // ] } } @@ -79,11 +79,11 @@ private class Summaries extends ModelInput::SummaryModelCsv { override predicate row(string row) { row = [ - "global;NodeJS.EventEmitter;;;Member[addListener,off,on,once,prependListener,prependOnceListener,removeAllListeners,removeListener,setMaxListeners].ReturnValue;type", // - "pg-pool;;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", // - "pg;ClientBase;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", // - "pg;Events;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", // - "pg;Pool;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", // + "global.NodeJS.EventEmitter;;;Member[addListener,off,on,once,prependListener,prependOnceListener,removeAllListeners,removeListener,setMaxListeners].ReturnValue;type", // + "pg-pool;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", // + "pg.ClientBase;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", // + "pg.Events;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", // + "pg.Pool;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", // ] } } @@ -92,11 +92,11 @@ private class TypeVariables extends ModelInput::TypeVariableModelCsv { override predicate row(string row) { row = [ - "pg-pool..0;Member[Client].TypeVar[pg-pool.ClientLikeCtr.0]", // - "pg-pool..0;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connect,0=remove].Argument[1].Argument[0]", // - "pg-pool..0;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=error].Argument[1].Argument[1]", // - "pg-pool..0;Member[connect].Argument[0].Argument[1]", // - "pg-pool..0;Member[connect].WithArity[0].ReturnValue.Awaited", // + "pg-pool.0;Member[Client].TypeVar[pg-pool.ClientLikeCtr.0]", // + "pg-pool.0;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connect,0=remove].Argument[1].Argument[0]", // + "pg-pool.0;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=error].Argument[1].Argument[1]", // + "pg-pool.0;Member[connect].Argument[0].Argument[1]", // + "pg-pool.0;Member[connect].WithArity[0].ReturnValue.Awaited", // "pg-pool.ClientLikeCtr.0;Instance", // "pg-promise.IConnected.1;Member[client]", // "pg-promise.IConnectionOptions.0;Member[onLost].Argument[1].TypeVar[pg-promise.ILostContext.0]", // diff --git a/javascript/ql/lib/semmle/javascript/frameworks/pg/model.json b/javascript/ql/lib/semmle/javascript/frameworks/pg/model.json index 50e1c6c8949..783759df4b9 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/pg/model.json +++ b/javascript/ql/lib/semmle/javascript/frameworks/pg/model.json @@ -18,103 +18,103 @@ "language": "javascript", "usedTypes": { "sources": [ - "pg-cursor;", - "pg-pool;", - "pg-promise;IBaseProtocol", - "pg;Client", - "pg;ClientStatic", - "pg;Pool", - "pg;PoolClient", - "pg;PoolStatic" + "pg-cursor", + "pg-pool", + "pg-promise.IBaseProtocol", + "pg.Client", + "pg.ClientStatic", + "pg.Pool", + "pg.PoolClient", + "pg.PoolStatic" ] }, "model": { "typeDefinitions": [ - "pg;Client;pg-promise/pg-subset;pg.IClient;", - "pg;Connection;pg-promise/pg-subset;pg.IConnection;", - "pg;Pool;pg-promise/pg-subset;pg.IPool;" + "pg.Client;pg-promise/pg-subset.pg.IClient;", + "pg.Connection;pg-promise/pg-subset.pg.IConnection;", + "pg.Pool;pg-promise/pg-subset.pg.IPool;" ], "sinks": [] }, "generatedModel": { "//": "Autogenerated section. Manual edits in here will be lost.", "typeDefinitions": [ - "events;;pg-cursor;;", - "events;;pg-promise/pg-subset;pg.IClient;", - "events;;pg-promise/pg-subset;pg.IConnection;", - "events;;pg-promise/pg-subset;pg.IPool;", - "events;;pg;ClientBase;", - "events;;pg;Events;", - "events;;pg;Pool;", - "global;NodeJS.EventEmitter;events;;", - "pg-cursor;;pg-cursor;Static;Instance", - "pg-cursor;Static;pg-cursor;;", - "pg-pool;;pg-pool;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", - "pg-pool;;pg-pool;Static;Instance", - "pg-pool;Static;pg-pool;;", - "pg-promise/pg-subset;pg.IClient;pg-promise/pg-subset;;Member[Client].Instance", - "pg-promise/pg-subset;pg.IClient;pg-promise;;Argument[0].TypeVar[pg-promise.IInitOptions.1]", - "pg-promise/pg-subset;pg.IClient;pg-promise;IMain;Argument[0].TypeVar[pg-promise/pg-subset.pg.IConnectionParameters.0]", - "pg-promise/pg-subset;pg.IClient;pg-promise;IMain;ReturnValue.TypeVar[pg-promise.IDatabase.1]", - "pg-promise/pg-subset;pg.IConnection;pg-promise/pg-subset;pg.IClient;Member[connection]", - "pg-promise/pg-subset;pg.IPool;pg-promise;IDatabase;Member[$pool]", - "pg-promise;IBaseProtocol;pg-promise/typescript/pg-promise;IBaseProtocol;", - "pg-promise;IBaseProtocol;pg-promise;IConnected;", - "pg-promise;IBaseProtocol;pg-promise;IDatabase;", - "pg-promise;IBaseProtocol;pg-promise;ITask;", - "pg-promise;IConnected;pg-promise/typescript/pg-promise;IConnected;", - "pg-promise;IConnected;pg-promise;IDatabase;Member[connect].ReturnValue.Awaited", - "pg-promise;IDatabase;pg-promise/typescript/pg-promise;IDatabase;", - "pg-promise;IDatabase;pg-promise;IInitOptions;Member[extend].Argument[0]", - "pg-promise;IDatabase;pg-promise;IMain;ReturnValue", - "pg-promise;IInitOptions;pg-promise/typescript/pg-promise;IInitOptions;", - "pg-promise;IInitOptions;pg-promise;;Argument[0]", - "pg-promise;IInitOptions;pg-promise;ILibConfig;Member[options]", - "pg-promise;ILibConfig;pg-promise/typescript/pg-promise;ILibConfig;", - "pg-promise;ILibConfig;pg-promise;IDatabase;Member[$config]", - "pg-promise;IMain;pg-promise/typescript/pg-promise;IMain;", - "pg-promise;IMain;pg-promise;;ReturnValue", - "pg-promise;IMain;pg-promise;ILibConfig;Member[pgp]", - "pg-promise;ITask;pg-promise/typescript/pg-promise;ITask;", - "pg-promise;ITask;pg-promise;IBaseProtocol;Member[task,taskIf,tx,txIf].Argument[1].Argument[0]", - "pg-promise;ITask;pg-promise;IBaseProtocol;Member[task,taskIf,tx,txIf].WithArity[1].Argument[0].Argument[0]", - "pg-promise;ITask;pg-promise;IBaseProtocol;Member[taskIf].WithArity[2].Argument[0].Member[cnd].Argument[0]", - "pg-promise;ITask;pg-promise;IBaseProtocol;Member[txIf].WithArity[2].Argument[0].Member[cnd,reusable].Argument[0]", - "pg;Client;pg-pool;Static;Instance.TypeVar[pg-pool..0]", - "pg;Client;pg;ClientStatic;Instance", - "pg;Client;pg;Events;Member[addListener,on,once,prependListener,prependOnceListener].Argument[1].Argument[1]", - "pg;ClientBase;pg;Client;", - "pg;ClientBase;pg;PoolClient;", - "pg;ClientStatic;pg;;Member[Client]", - "pg;Events;pg;Events;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", - "pg;Events;pg;EventsStatic;Instance", - "pg;EventsStatic;pg;;Member[Events]", - "pg;Pool;pg-pool;;", - "pg;Pool;pg;Pool;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", - "pg;Pool;pg;PoolStatic;Instance", - "pg;PoolClient;pg-pool;;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connect,0=remove].Argument[1].Argument[0]", - "pg;PoolClient;pg-pool;;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=error].Argument[1].Argument[1]", - "pg;PoolClient;pg-pool;;Member[connect].Argument[0].Argument[1]", - "pg;PoolClient;pg-pool;;Member[connect].WithArity[0].ReturnValue.Awaited", - "pg;PoolClient;pg;Pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connect,0=remove].Argument[1].Argument[0]", - "pg;PoolClient;pg;Pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=error].Argument[1].Argument[1]", - "pg;PoolClient;pg;Pool;Member[connect].Argument[0].Argument[1]", - "pg;PoolClient;pg;Pool;Member[connect].WithArity[0].ReturnValue.Awaited", - "pg;PoolStatic;pg;;Member[Pool]" + "events;pg-cursor;", + "events;pg-promise/pg-subset.pg.IClient;", + "events;pg-promise/pg-subset.pg.IConnection;", + "events;pg-promise/pg-subset.pg.IPool;", + "events;pg.ClientBase;", + "events;pg.Events;", + "events;pg.Pool;", + "global.NodeJS.EventEmitter;events;", + "pg-cursor.Static;pg-cursor;", + "pg-cursor;pg-cursor.Static;Instance", + "pg-pool.Static;pg-pool;", + "pg-pool;pg-pool.Static;Instance", + "pg-pool;pg-pool;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", + "pg-promise.IBaseProtocol;pg-promise.IConnected;", + "pg-promise.IBaseProtocol;pg-promise.IDatabase;", + "pg-promise.IBaseProtocol;pg-promise.ITask;", + "pg-promise.IBaseProtocol;pg-promise/typescript/pg-promise.IBaseProtocol;", + "pg-promise.IConnected;pg-promise.IDatabase;Member[connect].ReturnValue.Awaited", + "pg-promise.IConnected;pg-promise/typescript/pg-promise.IConnected;", + "pg-promise.IDatabase;pg-promise.IInitOptions;Member[extend].Argument[0]", + "pg-promise.IDatabase;pg-promise.IMain;ReturnValue", + "pg-promise.IDatabase;pg-promise/typescript/pg-promise.IDatabase;", + "pg-promise.IInitOptions;pg-promise.ILibConfig;Member[options]", + "pg-promise.IInitOptions;pg-promise/typescript/pg-promise.IInitOptions;", + "pg-promise.IInitOptions;pg-promise;Argument[0]", + "pg-promise.ILibConfig;pg-promise.IDatabase;Member[$config]", + "pg-promise.ILibConfig;pg-promise/typescript/pg-promise.ILibConfig;", + "pg-promise.IMain;pg-promise.ILibConfig;Member[pgp]", + "pg-promise.IMain;pg-promise/typescript/pg-promise.IMain;", + "pg-promise.IMain;pg-promise;ReturnValue", + "pg-promise.ITask;pg-promise.IBaseProtocol;Member[task,taskIf,tx,txIf].Argument[1].Argument[0]", + "pg-promise.ITask;pg-promise.IBaseProtocol;Member[task,taskIf,tx,txIf].WithArity[1].Argument[0].Argument[0]", + "pg-promise.ITask;pg-promise.IBaseProtocol;Member[taskIf].WithArity[2].Argument[0].Member[cnd].Argument[0]", + "pg-promise.ITask;pg-promise.IBaseProtocol;Member[txIf].WithArity[2].Argument[0].Member[cnd,reusable].Argument[0]", + "pg-promise.ITask;pg-promise/typescript/pg-promise.ITask;", + "pg-promise/pg-subset.pg.IClient;pg-promise.IMain;Argument[0].TypeVar[pg-promise/pg-subset.pg.IConnectionParameters.0]", + "pg-promise/pg-subset.pg.IClient;pg-promise.IMain;ReturnValue.TypeVar[pg-promise.IDatabase.1]", + "pg-promise/pg-subset.pg.IClient;pg-promise/pg-subset;Member[Client].Instance", + "pg-promise/pg-subset.pg.IClient;pg-promise;Argument[0].TypeVar[pg-promise.IInitOptions.1]", + "pg-promise/pg-subset.pg.IConnection;pg-promise/pg-subset.pg.IClient;Member[connection]", + "pg-promise/pg-subset.pg.IPool;pg-promise.IDatabase;Member[$pool]", + "pg.Client;pg-pool.Static;Instance.TypeVar[pg-pool.0]", + "pg.Client;pg.ClientStatic;Instance", + "pg.Client;pg.Events;Member[addListener,on,once,prependListener,prependOnceListener].Argument[1].Argument[1]", + "pg.ClientBase;pg.Client;", + "pg.ClientBase;pg.PoolClient;", + "pg.ClientStatic;pg;Member[Client]", + "pg.Events;pg.Events;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", + "pg.Events;pg.EventsStatic;Instance", + "pg.EventsStatic;pg;Member[Events]", + "pg.Pool;pg-pool;", + "pg.Pool;pg.Pool;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue", + "pg.Pool;pg.PoolStatic;Instance", + "pg.PoolClient;pg-pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connect,0=remove].Argument[1].Argument[0]", + "pg.PoolClient;pg-pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=error].Argument[1].Argument[1]", + "pg.PoolClient;pg-pool;Member[connect].Argument[0].Argument[1]", + "pg.PoolClient;pg-pool;Member[connect].WithArity[0].ReturnValue.Awaited", + "pg.PoolClient;pg.Pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connect,0=remove].Argument[1].Argument[0]", + "pg.PoolClient;pg.Pool;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=error].Argument[1].Argument[1]", + "pg.PoolClient;pg.Pool;Member[connect].Argument[0].Argument[1]", + "pg.PoolClient;pg.Pool;Member[connect].WithArity[0].ReturnValue.Awaited", + "pg.PoolStatic;pg;Member[Pool]" ], "summaries": [ - "global;NodeJS.EventEmitter;;;Member[addListener,off,on,once,prependListener,prependOnceListener,removeAllListeners,removeListener,setMaxListeners].ReturnValue;type", - "pg-pool;;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", - "pg;ClientBase;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", - "pg;Events;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", - "pg;Pool;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type" + "global.NodeJS.EventEmitter;;;Member[addListener,off,on,once,prependListener,prependOnceListener,removeAllListeners,removeListener,setMaxListeners].ReturnValue;type", + "pg-pool;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", + "pg.ClientBase;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", + "pg.Events;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type", + "pg.Pool;;;Member[addListener,on,once,prependListener,prependOnceListener].ReturnValue;type" ], "typeVariables": [ - "pg-pool..0;Member[Client].TypeVar[pg-pool.ClientLikeCtr.0]", - "pg-pool..0;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connect,0=remove].Argument[1].Argument[0]", - "pg-pool..0;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=error].Argument[1].Argument[1]", - "pg-pool..0;Member[connect].Argument[0].Argument[1]", - "pg-pool..0;Member[connect].WithArity[0].ReturnValue.Awaited", + "pg-pool.0;Member[Client].TypeVar[pg-pool.ClientLikeCtr.0]", + "pg-pool.0;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=acquire,0=connect,0=remove].Argument[1].Argument[0]", + "pg-pool.0;Member[addListener,on,once,prependListener,prependOnceListener].WithArity[2].WithStringArgument[0=error].Argument[1].Argument[1]", + "pg-pool.0;Member[connect].Argument[0].Argument[1]", + "pg-pool.0;Member[connect].WithArity[0].ReturnValue.Awaited", "pg-pool.ClientLikeCtr.0;Instance", "pg-promise.IConnected.1;Member[client]", "pg-promise.IConnectionOptions.0;Member[onLost].Argument[1].TypeVar[pg-promise.ILostContext.0]", diff --git a/javascript/ql/lib/semmle/javascript/frameworks/sequelize/Model.qll b/javascript/ql/lib/semmle/javascript/frameworks/sequelize/Model.qll index f9c06c3739a..ba4d9669661 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/sequelize/Model.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/sequelize/Model.qll @@ -6,13 +6,13 @@ private class Sinks extends ModelInput::SinkModelCsv { override predicate row(string row) { row = [ - "sequelize;;Argument[0..].Member[password];credentials[password]", // - "sequelize;;Argument[0..].Member[username];credentials[username]", // - "sequelize;;Argument[1];credentials[username]", // - "sequelize;;Argument[2];credentials[password]", // - "sequelize;Sequelize;Member[query].Argument[0].Member[query];sql-injection", // - "sequelize;Sequelize;Member[query].Argument[0];sql-injection", // - "sequelize;SequelizeStaticAndInstance;Member[asIs,literal].Argument[0];sql-injection", // + "sequelize.Sequelize;Member[query].Argument[0].Member[query];sql-injection", // + "sequelize.Sequelize;Member[query].Argument[0];sql-injection", // + "sequelize.SequelizeStaticAndInstance;Member[asIs,literal].Argument[0];sql-injection", // + "sequelize;Argument[0..].Member[password];credentials[password]", // + "sequelize;Argument[0..].Member[username];credentials[username]", // + "sequelize;Argument[1];credentials[username]", // + "sequelize;Argument[2];credentials[password]", // ] } } @@ -21,254 +21,254 @@ private class Types extends ModelInput::TypeModelCsv { override predicate row(string row) { row = [ - "sequelize-typescript/associations/foreign-key/foreign-key-meta;ForeignKeyMeta;sequelize-typescript/associations/foreign-key/foreign-key-service;;Member[getForeignKeys].ReturnValue.ArrayElement", // - "sequelize-typescript/model/model/association/association-create-options;AssociationCreateOptions;sequelize-typescript;Model;Member[$create].Argument[2]", // - "sequelize-typescript/model/shared/model-not-initialized-error;ModelNotInitializedErrorStatic;sequelize-typescript/model/shared/model-not-initialized-error;;Member[ModelNotInitializedError]", // - "sequelize-typescript;AssociationCountOptions;sequelize-typescript/model/model/association/association-count-options;AssociationCountOptions;", // - "sequelize-typescript;AssociationCountOptions;sequelize-typescript;Model;Member[$count].Argument[1]", // - "sequelize-typescript;AssociationGetOptions;sequelize-typescript/model/model/association/association-get-options;AssociationGetOptions;", // - "sequelize-typescript;AssociationGetOptions;sequelize-typescript;Model;Member[$get].Argument[1]", // - "sequelize-typescript;AssociationGetOptions;sequelize-typescript;Model;Member[$has].Argument[2]", // - "sequelize-typescript;BaseAssociation;sequelize-typescript/associations/shared/association-service;;Member[addAssociation].Argument[1]", // - "sequelize-typescript;BaseAssociation;sequelize-typescript/associations/shared/association-service;;Member[getAssociations,getAssociationsByRelation].ReturnValue.ArrayElement", // - "sequelize-typescript;BaseAssociation;sequelize-typescript/associations/shared/association-service;;Member[setAssociations].Argument[1].ArrayElement", // - "sequelize-typescript;BaseAssociation;sequelize-typescript/associations/shared/base-association;BaseAssociation;", // - "sequelize-typescript;BaseAssociation;sequelize-typescript;;Member[addAssociation].Argument[1]", // - "sequelize-typescript;BaseAssociation;sequelize-typescript;;Member[getAssociations,getAssociationsByRelation].ReturnValue.ArrayElement", // - "sequelize-typescript;BaseAssociation;sequelize-typescript;;Member[setAssociations].Argument[1].ArrayElement", // - "sequelize-typescript;BaseAssociation;sequelize-typescript;BaseAssociationStatic;Instance", // - "sequelize-typescript;BaseAssociation;sequelize-typescript;BelongsToAssociation;", // - "sequelize-typescript;BaseAssociation;sequelize-typescript;BelongsToManyAssociation;", // - "sequelize-typescript;BaseAssociation;sequelize-typescript;HasAssociation;", // - "sequelize-typescript;BaseAssociationStatic;sequelize-typescript/associations/shared/base-association;;Member[BaseAssociation]", // - "sequelize-typescript;BaseAssociationStatic;sequelize-typescript/associations/shared/base-association;BaseAssociationStatic;", // - "sequelize-typescript;BaseAssociationStatic;sequelize-typescript;;Member[BaseAssociation]", // - "sequelize-typescript;BelongsToAssociation;sequelize-typescript/associations/belongs-to/belongs-to-association;BelongsToAssociation;", // - "sequelize-typescript;BelongsToAssociation;sequelize-typescript;BelongsToAssociationStatic;Instance", // - "sequelize-typescript;BelongsToAssociationStatic;sequelize-typescript/associations/belongs-to/belongs-to-association;;Member[BelongsToAssociation]", // - "sequelize-typescript;BelongsToAssociationStatic;sequelize-typescript/associations/belongs-to/belongs-to-association;BelongsToAssociationStatic;", // - "sequelize-typescript;BelongsToAssociationStatic;sequelize-typescript;;Member[BelongsToAssociation]", // - "sequelize-typescript;BelongsToManyAssociation;sequelize-typescript/associations/belongs-to-many/belongs-to-many-association;BelongsToManyAssociation;", // - "sequelize-typescript;BelongsToManyAssociation;sequelize-typescript;BelongsToManyAssociationStatic;Instance", // - "sequelize-typescript;BelongsToManyAssociationStatic;sequelize-typescript/associations/belongs-to-many/belongs-to-many-association;;Member[BelongsToManyAssociation]", // - "sequelize-typescript;BelongsToManyAssociationStatic;sequelize-typescript/associations/belongs-to-many/belongs-to-many-association;BelongsToManyAssociationStatic;", // - "sequelize-typescript;BelongsToManyAssociationStatic;sequelize-typescript;;Member[BelongsToManyAssociation]", // - "sequelize-typescript;DefaultScopeGetter;sequelize-typescript/scopes/default-scope;;Member[DefaultScope].Argument[0]", // - "sequelize-typescript;DefaultScopeGetter;sequelize-typescript/scopes/scope-options;DefaultScopeGetter;", // - "sequelize-typescript;DefaultScopeGetter;sequelize-typescript;;Member[DefaultScope].Argument[0]", // - "sequelize-typescript;DefaultScopeGetter;sequelize-typescript;ScopeOptionsGetters;Member[getDefaultScope]", // - "sequelize-typescript;HasAssociation;sequelize-typescript/associations/has/has-association;HasAssociation;", // - "sequelize-typescript;HasAssociation;sequelize-typescript;HasAssociationStatic;Instance", // - "sequelize-typescript;HasAssociationStatic;sequelize-typescript/associations/has/has-association;;Member[HasAssociation]", // - "sequelize-typescript;HasAssociationStatic;sequelize-typescript/associations/has/has-association;HasAssociationStatic;", // - "sequelize-typescript;HasAssociationStatic;sequelize-typescript;;Member[HasAssociation]", // - "sequelize-typescript;Model;sequelize-typescript/model/model/model;Model;", // - "sequelize-typescript;Model;sequelize-typescript;Model;Member[$add,$has,$remove,$set].Argument[1]", // - "sequelize-typescript;Model;sequelize-typescript;Model;Member[$add,$has,$remove,$set].Argument[1].ArrayElement", // - "sequelize-typescript;Model;sequelize-typescript;Model;Member[$create,reload].ReturnValue.Awaited", // - "sequelize-typescript;Model;sequelize-typescript;ModelStatic~;Instance", // - "sequelize-typescript;Model;sequelize-typescript;ModelStatic~;Member[initialize].ReturnValue.TypeVar[sequelize-typescript.ModelStatic.0]", // - "sequelize-typescript;Model;sequelize-typescript;ModelType;Instance", // - "sequelize-typescript;Model;sequelize-typescript;Sequelize;Member[getRepository].Argument[0].Instance", // - "sequelize-typescript;Model;sequelize-typescript;Sequelize;Member[getRepository].ReturnValue.TypeVar[sequelize-typescript.Repository.0]", // - "sequelize-typescript;ModelClassGetter;sequelize-typescript/associations/belongs-to-many/belongs-to-many;;Member[BelongsToMany].Argument[0,1]", // - "sequelize-typescript;ModelClassGetter;sequelize-typescript/associations/belongs-to/belongs-to;;Member[BelongsTo].Argument[0]", // - "sequelize-typescript;ModelClassGetter;sequelize-typescript/associations/foreign-key/foreign-key-meta;ForeignKeyMeta;Member[relatedClassGetter]", // - "sequelize-typescript;ModelClassGetter;sequelize-typescript/associations/foreign-key/foreign-key-service;;Member[addForeignKey].Argument[1]", // - "sequelize-typescript;ModelClassGetter;sequelize-typescript/associations/foreign-key/foreign-key;;Member[ForeignKey].Argument[0]", // - "sequelize-typescript;ModelClassGetter;sequelize-typescript/associations/has/has-many;;Member[HasMany].Argument[0]", // - "sequelize-typescript;ModelClassGetter;sequelize-typescript/associations/has/has-one;;Member[HasOne].Argument[0]", // - "sequelize-typescript;ModelClassGetter;sequelize-typescript/model/shared/model-class-getter;ModelClassGetter;", // - "sequelize-typescript;ModelClassGetter;sequelize-typescript;;Member[BelongsTo,ForeignKey,HasMany,HasOne].Argument[0]", // - "sequelize-typescript;ModelClassGetter;sequelize-typescript;;Member[BelongsToMany].Argument[0,1]", // - "sequelize-typescript;ModelClassGetter;sequelize-typescript;BaseAssociationStatic;Argument[0]", // - "sequelize-typescript;ModelClassGetter;sequelize-typescript;BelongsToAssociationStatic;Argument[0]", // - "sequelize-typescript;ModelClassGetter;sequelize-typescript;BelongsToManyAssociationStatic;Argument[0]", // - "sequelize-typescript;ModelClassGetter;sequelize-typescript;HasAssociationStatic;Argument[0]", // - "sequelize-typescript;ModelStatic~;sequelize-typescript/model/model/model;;Member[Model]", // - "sequelize-typescript;ModelStatic~;sequelize-typescript/model/model/model;ModelStatic~;", // - "sequelize-typescript;ModelStatic~;sequelize-typescript/model/shared/model-not-initialized-error;ModelNotInitializedErrorStatic;Argument[0]", // - "sequelize-typescript;ModelStatic~;sequelize-typescript;;Member[Model]", // - "sequelize-typescript;ModelType;sequelize-typescript/associations/foreign-key/foreign-key-service;;Member[getForeignKeyOptions].Argument[0,1]", // - "sequelize-typescript;ModelType;sequelize-typescript/model/model/model;ModelType;", // - "sequelize-typescript;ModelType;sequelize-typescript;BaseAssociation;Member[getAssociatedClass].ReturnValue", // - "sequelize-typescript;ModelType;sequelize-typescript;BaseAssociation;Member[getSequelizeOptions].Argument[0]", // - "sequelize-typescript;ModelType;sequelize-typescript;BelongsToAssociation;Member[getSequelizeOptions].Argument[0]", // - "sequelize-typescript;ModelType;sequelize-typescript;BelongsToManyAssociation;Member[getSequelizeOptions].Argument[0]", // - "sequelize-typescript;ModelType;sequelize-typescript;HasAssociation;Member[getSequelizeOptions].Argument[0]", // - "sequelize-typescript;ModelType;sequelize-typescript;ModelClassGetter;ReturnValue", // - "sequelize-typescript;ModelType;sequelize-typescript;Sequelize;Member[model].Argument[0]", // - "sequelize-typescript;ScopeOptionsGetters;sequelize-typescript/scopes/scope-options;ScopeOptionsGetters;", // - "sequelize-typescript;ScopeOptionsGetters;sequelize-typescript/scopes/scope-service;;Member[addScopeOptionsGetter,setScopeOptionsGetters].Argument[1]", // - "sequelize-typescript;ScopeOptionsGetters;sequelize-typescript/scopes/scope-service;;Member[getScopeOptionsGetters].ReturnValue", // - "sequelize-typescript;ScopeOptionsGetters;sequelize-typescript;;Member[addScopeOptionsGetter,setScopeOptionsGetters].Argument[1]", // - "sequelize-typescript;ScopeOptionsGetters;sequelize-typescript;;Member[getScopeOptionsGetters].ReturnValue", // - "sequelize-typescript;ScopesOptions;sequelize-typescript/scopes/scope-options;ScopesOptions;", // - "sequelize-typescript;ScopesOptions;sequelize-typescript/scopes/scope-service;;Member[resolveScope].Argument[2]", // - "sequelize-typescript;ScopesOptions;sequelize-typescript;;Member[resolveScope].Argument[2]", // - "sequelize-typescript;ScopesOptions;sequelize-typescript;ScopesOptionsGetter;ReturnValue.AnyMember", // - "sequelize-typescript;ScopesOptionsGetter;sequelize-typescript/scopes/scope-options;ScopesOptionsGetter;", // - "sequelize-typescript;ScopesOptionsGetter;sequelize-typescript/scopes/scopes;;Member[Scopes].Argument[0]", // - "sequelize-typescript;ScopesOptionsGetter;sequelize-typescript;;Member[Scopes].Argument[0]", // - "sequelize-typescript;ScopesOptionsGetter;sequelize-typescript;ScopeOptionsGetters;Member[getScopes]", // - "sequelize-typescript;Sequelize;sequelize-typescript/sequelize/sequelize/sequelize;Sequelize;", // - "sequelize-typescript;Sequelize;sequelize-typescript;BaseAssociation;Member[getSequelizeOptions].Argument[1]", // - "sequelize-typescript;Sequelize;sequelize-typescript;BelongsToManyAssociation;Member[getSequelizeOptions].Argument[1]", // - "sequelize-typescript;Sequelize;sequelize-typescript;SequelizeStatic;Instance", // - "sequelize-typescript;SequelizeOptions;sequelize-typescript/sequelize/sequelize/sequelize-options;SequelizeOptions;", // - "sequelize-typescript;SequelizeOptions;sequelize-typescript/sequelize/sequelize/sequelize-service;;Member[prepareArgs].ReturnValue.Member[options]", // - "sequelize-typescript;SequelizeOptions;sequelize-typescript/sequelize/sequelize/sequelize-service;;Member[prepareOptions].Argument[0]", // - "sequelize-typescript;SequelizeOptions;sequelize-typescript/sequelize/sequelize/sequelize-service;;Member[prepareOptions].ReturnValue", // - "sequelize-typescript;SequelizeOptions;sequelize-typescript;;Member[prepareArgs].ReturnValue.Member[options]", // - "sequelize-typescript;SequelizeOptions;sequelize-typescript;;Member[prepareOptions].Argument[0]", // - "sequelize-typescript;SequelizeOptions;sequelize-typescript;;Member[prepareOptions].ReturnValue", // - "sequelize-typescript;SequelizeOptions;sequelize-typescript;Sequelize;Member[options]", // - "sequelize-typescript;SequelizeOptions;sequelize-typescript;SequelizeStatic;Argument[3]", // - "sequelize-typescript;SequelizeOptions;sequelize-typescript;SequelizeStatic;WithArity[0].Argument[0]", // - "sequelize-typescript;SequelizeOptions;sequelize-typescript;SequelizeStatic;WithArity[1].Argument[0,1]", // - "sequelize-typescript;SequelizeOptions;sequelize-typescript;SequelizeStatic;WithArity[2].Argument[1,2]", // - "sequelize-typescript;SequelizeOptions;sequelize-typescript;SequelizeStatic;WithArity[3].Argument[2]", // - "sequelize-typescript;SequelizeStatic;sequelize-typescript/sequelize/sequelize/sequelize;;Member[Sequelize]", // - "sequelize-typescript;SequelizeStatic;sequelize-typescript/sequelize/sequelize/sequelize;SequelizeStatic;", // - "sequelize-typescript;SequelizeStatic;sequelize-typescript;;Member[Sequelize]", // - "sequelize;AnyFindOptions;sequelize;BelongsToManyAddAssociationMixin;Argument[1]", // - "sequelize;AnyFindOptions;sequelize;BelongsToManyAddAssociationsMixin;Argument[1]", // - "sequelize;AnyFindOptions;sequelize;BelongsToManySetAssociationsMixin;Argument[1]", // - "sequelize;AnyFindOptions;sequelize;DefineOptions;Member[defaultScope]", // - "sequelize;AnyFindOptions;sequelize;DefineScopeOptions;AnyMember", // - "sequelize;AnyFindOptions;sequelize;HasManySetAssociationsMixin;Argument[1]", // - "sequelize;AnyFindOptions;sequelize;Instance;Member[reload].Argument[0]", // - "sequelize;AnyFindOptions;sequelize;Model;Member[addScope].Argument[1]", // - "sequelize;AssociationOptionsBelongsToMany;sequelize;Associations;Member[belongsToMany].Argument[1]", // - "sequelize;Associations;sequelize;Model;", // - "sequelize;Associations;sequelize;SequelizeStaticAndInstance.Model;", // - "sequelize;BuildOptions;sequelize-typescript;ModelStatic~;Argument[1]", // - "sequelize;BuildOptions;sequelize;CreateOptions;", // - "sequelize;BuildOptions;sequelize;Model;Member[build,bulkBuild].Argument[1]", // - "sequelize;CountOptions;sequelize;Model;Member[count].Argument[0]", // - "sequelize;CreateOptions;sequelize-typescript/model/model/association/association-create-options;AssociationCreateOptions;", // - "sequelize;CreateOptions;sequelize;BelongsToCreateAssociationMixin;Argument[1]", // - "sequelize;CreateOptions;sequelize;BelongsToManyCreateAssociationMixin;Argument[1]", // - "sequelize;CreateOptions;sequelize;HasManyCreateAssociationMixin;Argument[1]", // - "sequelize;CreateOptions;sequelize;HasOneCreateAssociationMixin;Argument[1]", // - "sequelize;CreateOptions;sequelize;Model;Member[create].Argument[1]", // - "sequelize;DefineAttributeColumnOptions;sequelize;DefineAttributes;AnyMember", // - "sequelize;DefineAttributeColumnOptions;sequelize;QueryInterface;Member[addColumn,changeColumn].Argument[2]", // - "sequelize;DefineAttributeColumnReferencesOptions;sequelize;DefineAttributeColumnOptions;Member[references]", // - "sequelize;DefineAttributes;sequelize;Hooks;Member[beforeDefine].Argument[1].Argument[0]", // - "sequelize;DefineAttributes;sequelize;Hooks;Member[beforeDefine].WithArity[1].Argument[0].Argument[0]", // - "sequelize;DefineAttributes;sequelize;QueryInterface;Member[createTable].Argument[1]", // - "sequelize;DefineOptions;sequelize;Options;Member[define]", // - "sequelize;DefineOptions;sequelize;Sequelize;Member[define].Argument[2]", // - "sequelize;DefineScopeOptions;sequelize;DefineOptions;Member[scopes]", // - "sequelize;FindCreateFindOptions;sequelize;Model;Member[findCreateFind].Argument[0]", // - "sequelize;FindOptions;sequelize-typescript;AssociationCountOptions;", // - "sequelize;FindOptions;sequelize-typescript;AssociationGetOptions;", // - "sequelize;FindOptions;sequelize-typescript;DefaultScopeGetter;ReturnValue", // - "sequelize;FindOptions;sequelize-typescript;Model;Member[reload].Argument[0]", // - "sequelize;FindOptions;sequelize-typescript;ScopesOptions;", // - "sequelize;FindOptions;sequelize-typescript;ScopesOptions;ReturnValue", // - "sequelize;FindOptions;sequelize;AnyFindOptions;", // - "sequelize;FindOptions;sequelize;FindCreateFindOptions;", // - "sequelize;FindOptions;sequelize;FindOrInitializeOptions;", // - "sequelize;FindOptions;sequelize;Model;Member[all,find,findAll,findAndCount,findAndCountAll,findOne].Argument[0]", // - "sequelize;FindOptionsOrderArray;sequelize;FindOptions;Member[order]", // - "sequelize;FindOptionsOrderArray;sequelize;FindOptions;Member[order].ArrayElement", // - "sequelize;FindOrInitializeOptions;sequelize;Model;Member[findOrBuild,findOrCreate,findOrInitialize].Argument[0]", // - "sequelize;HasManyGetAssociationsMixinOptions;sequelize;HasManyGetAssociationsMixin;Argument[0]", // - "sequelize;HasManyGetAssociationsMixinOptions;sequelize;HasManyHasAssociationMixin;Argument[1]", // - "sequelize;HasManyGetAssociationsMixinOptions;sequelize;HasManyHasAssociationsMixin;Argument[1]", // - "sequelize;Hooks;sequelize;Hooks;Member[addHook,hook,removeHook].ReturnValue", // - "sequelize;Hooks;sequelize;Model;", // - "sequelize;Hooks;sequelize;Sequelize;", // - "sequelize;Hooks;sequelize;SequelizeStaticAndInstance.Model;", // - "sequelize;IncludeAssociation;sequelize;Associations;Member[belongsTo,belongsToMany,hasMany,hasOne].ReturnValue", // - "sequelize;IncludeAssociation;sequelize;IncludeOptions;Member[association]", // - "sequelize;IncludeOptions;sequelize;BuildOptions;Member[include].ArrayElement", // - "sequelize;IncludeOptions;sequelize;CountOptions;Member[include]", // - "sequelize;IncludeOptions;sequelize;CountOptions;Member[include].ArrayElement", // - "sequelize;IncludeOptions;sequelize;FindOptions;Member[include]", // - "sequelize;IncludeOptions;sequelize;FindOptions;Member[include].ArrayElement", // - "sequelize;IncludeOptions;sequelize;HasManyGetAssociationsMixinOptions;Member[include]", // - "sequelize;IncludeOptions;sequelize;IncludeOptions;Member[include]", // - "sequelize;IncludeOptions;sequelize;IncludeOptions;Member[include].ArrayElement", // - "sequelize;Instance;sequelize;Instance;Member[decrement,increment,reload,save,update,updateAttributes].ReturnValue.Awaited", // - "sequelize;Instance;sequelize;Instance;Member[equalsOneOf].Argument[0].ArrayElement", // - "sequelize;Instance;sequelize;Instance;Member[equals].Argument[0]", // - "sequelize;Instance;sequelize;Instance;Member[set,setAttributes].ReturnValue", // - "sequelize;Instance;sequelize;Model;Member[Instance,build].ReturnValue", // - "sequelize;Instance;sequelize;Model;Member[all,bulkCreate,findAll].ReturnValue.Awaited.ArrayElement", // - "sequelize;Instance;sequelize;Model;Member[bulkBuild].ReturnValue.ArrayElement", // - "sequelize;Instance;sequelize;Model;Member[create,find,findById,findByPk,findByPrimary,findOne].ReturnValue.Awaited", // - "sequelize;Instance;sequelize;Model;Member[findAndCount,findAndCountAll].ReturnValue.Awaited.Member[rows].ArrayElement", // - "sequelize;Instance;sequelize;QueryInterface;Member[delete,increment,insert,update].Argument[0]", // - "sequelize;Instance;sequelize;QueryOptions;Member[instance]", // - "sequelize;Instance;sequelize;SequelizeStaticAndInstance;Member[Instance]", // - "sequelize;Model;sequelize;AssociationOptionsBelongsToMany;Member[through]", // - "sequelize;Model;sequelize;Associations;Member[belongsTo,belongsToMany,hasMany,hasOne].Argument[0]", // - "sequelize;Model;sequelize;BuildOptions;Member[include].ArrayElement", // - "sequelize;Model;sequelize;CountOptions;Member[include]", // - "sequelize;Model;sequelize;CountOptions;Member[include].ArrayElement", // - "sequelize;Model;sequelize;DefineAttributeColumnReferencesOptions;Member[model]", // - "sequelize;Model;sequelize;FindOptions;Member[include]", // - "sequelize;Model;sequelize;FindOptions;Member[include].ArrayElement", // - "sequelize;Model;sequelize;FindOptions;Member[lock].Member[of]", // - "sequelize;Model;sequelize;FindOptionsOrderArray;ArrayElement", // - "sequelize;Model;sequelize;FindOptionsOrderArray;ArrayElement.Member[model]", // - "sequelize;Model;sequelize;Hooks;Member[afterDefine].Argument[1].Argument[0]", // - "sequelize;Model;sequelize;Hooks;Member[afterDefine].WithArity[1].Argument[0].Argument[0]", // - "sequelize;Model;sequelize;IncludeAssociation;Member[source,target]", // - "sequelize;Model;sequelize;IncludeOptions;Member[include,model]", // - "sequelize;Model;sequelize;IncludeOptions;Member[include].ArrayElement", // - "sequelize;Model;sequelize;Instance;Member[Model]", // - "sequelize;Model;sequelize;Model;Member[schema,scope,unscoped].ReturnValue", // - "sequelize;Model;sequelize;Model;Member[sync].ReturnValue.Awaited", // - "sequelize;Model;sequelize;Models;AnyMember", // - "sequelize;Model;sequelize;ModelsHashInterface;AnyMember", // - "sequelize;Model;sequelize;QueryInterface;Member[bulkDelete,rawSelect,upsert].Argument[3]", // - "sequelize;Model;sequelize;QueryInterface;Member[select].Argument[0]", // - "sequelize;Model;sequelize;QueryOptions;Member[model]", // - "sequelize;Model;sequelize;Sequelize;Member[define,import,model].ReturnValue", // - "sequelize;Model;sequelize;Sequelize;Member[import].Argument[1].ReturnValue", // - "sequelize;Model;sequelize;SequelizeStaticAndInstance;Member[Model]", // - "sequelize;Model;sequelize;ThroughOptions;Member[model]", // - "sequelize;Model;sequelize;Utils;Member[mapOptionFieldNames].Argument[1]", // - "sequelize;Model;sequelize;Utils;Member[mapValueFieldNames].Argument[2]", // - "sequelize;Models;sequelize;Model;Member[associate].Argument[0]", // - "sequelize;ModelsHashInterface;sequelize;Sequelize;Member[models]", // - "sequelize;Options;sequelize-typescript;SequelizeOptions;", // - "sequelize;Options;sequelize;Sequelize;Member[options]", // - "sequelize;Options;sequelize;SequelizeStatic;Argument[3]", // - "sequelize;Options;sequelize;SequelizeStatic;WithArity[1].Argument[0,1]", // - "sequelize;Options;sequelize;SequelizeStatic;WithArity[2].Argument[1,2]", // - "sequelize;Options;sequelize;SequelizeStatic;WithArity[3].Argument[2]", // - "sequelize;QueryInterface;sequelize;Sequelize;Member[getQueryInterface].ReturnValue", // - "sequelize;QueryOptions;sequelize;Options;Member[query]", // - "sequelize;QueryOptions;sequelize;QueryInterface;Member[bulkDelete,bulkInsert,createTable,select,setAutocommit,setIsolationLevel].Argument[2]", // - "sequelize;QueryOptions;sequelize;QueryInterface;Member[bulkUpdate,delete,insert].Argument[3]", // - "sequelize;QueryOptions;sequelize;QueryInterface;Member[commitTransaction,deferConstraints,dropTable,rawSelect,rollbackTransaction,showIndex,startTransaction].Argument[1]", // - "sequelize;QueryOptions;sequelize;QueryInterface;Member[createFunction].Argument[5]", // - "sequelize;QueryOptions;sequelize;QueryInterface;Member[dropAllEnums,dropAllTables,showAllSchemas,showAllTables].Argument[0]", // - "sequelize;QueryOptions;sequelize;QueryInterface;Member[increment,update,upsert].Argument[4]", // - "sequelize;QueryOptions;sequelize;Sequelize;Member[authenticate,validate].Argument[0]", // - "sequelize;QueryOptions;sequelize;Sequelize;Member[query].Argument[1]", // - "sequelize;Sequelize;sequelize-typescript;Sequelize;", // - "sequelize;Sequelize;sequelize;Hooks;Member[afterInit].Argument[1].Argument[0]", // - "sequelize;Sequelize;sequelize;Hooks;Member[afterInit].WithArity[1].Argument[0].Argument[0]", // - "sequelize;Sequelize;sequelize;Instance;Member[sequelize]", // - "sequelize;Sequelize;sequelize;QueryInterface;Member[sequelize]", // - "sequelize;Sequelize;sequelize;Sequelize;Member[import].Argument[1].Argument[0]", // - "sequelize;Sequelize;sequelize;SequelizeStatic;Instance", // - "sequelize;Sequelize;sequelize;SequelizeStatic;Member[useCLS].ReturnValue", // - "sequelize;SequelizeStatic;sequelize-typescript;Sequelize;", // - "sequelize;SequelizeStatic;sequelize;;", // - "sequelize;SequelizeStatic;sequelize;Sequelize;Member[Sequelize]", // - "sequelize;SequelizeStatic;sequelize;SequelizeStatic;Member[Sequelize,default]", // - "sequelize;SequelizeStaticAndInstance.Model;sequelize-typescript;Model;", // - "sequelize;SequelizeStaticAndInstance;sequelize;Sequelize;", // - "sequelize;SequelizeStaticAndInstance;sequelize;SequelizeStatic;", // - "sequelize;ThroughOptions;sequelize;AssociationOptionsBelongsToMany;Member[through]", // - "sequelize;Utils;sequelize;SequelizeStaticAndInstance;Member[Utils]", // + "sequelize-typescript.AssociationCountOptions;sequelize-typescript.Model;Member[$count].Argument[1]", // + "sequelize-typescript.AssociationCountOptions;sequelize-typescript/model/model/association/association-count-options.AssociationCountOptions;", // + "sequelize-typescript.AssociationGetOptions;sequelize-typescript.Model;Member[$get].Argument[1]", // + "sequelize-typescript.AssociationGetOptions;sequelize-typescript.Model;Member[$has].Argument[2]", // + "sequelize-typescript.AssociationGetOptions;sequelize-typescript/model/model/association/association-get-options.AssociationGetOptions;", // + "sequelize-typescript.BaseAssociation;sequelize-typescript.BaseAssociationStatic;Instance", // + "sequelize-typescript.BaseAssociation;sequelize-typescript.BelongsToAssociation;", // + "sequelize-typescript.BaseAssociation;sequelize-typescript.BelongsToManyAssociation;", // + "sequelize-typescript.BaseAssociation;sequelize-typescript.HasAssociation;", // + "sequelize-typescript.BaseAssociation;sequelize-typescript/associations/shared/association-service;Member[addAssociation].Argument[1]", // + "sequelize-typescript.BaseAssociation;sequelize-typescript/associations/shared/association-service;Member[getAssociations,getAssociationsByRelation].ReturnValue.ArrayElement", // + "sequelize-typescript.BaseAssociation;sequelize-typescript/associations/shared/association-service;Member[setAssociations].Argument[1].ArrayElement", // + "sequelize-typescript.BaseAssociation;sequelize-typescript/associations/shared/base-association.BaseAssociation;", // + "sequelize-typescript.BaseAssociation;sequelize-typescript;Member[addAssociation].Argument[1]", // + "sequelize-typescript.BaseAssociation;sequelize-typescript;Member[getAssociations,getAssociationsByRelation].ReturnValue.ArrayElement", // + "sequelize-typescript.BaseAssociation;sequelize-typescript;Member[setAssociations].Argument[1].ArrayElement", // + "sequelize-typescript.BaseAssociationStatic;sequelize-typescript/associations/shared/base-association.BaseAssociationStatic;", // + "sequelize-typescript.BaseAssociationStatic;sequelize-typescript/associations/shared/base-association;Member[BaseAssociation]", // + "sequelize-typescript.BaseAssociationStatic;sequelize-typescript;Member[BaseAssociation]", // + "sequelize-typescript.BelongsToAssociation;sequelize-typescript.BelongsToAssociationStatic;Instance", // + "sequelize-typescript.BelongsToAssociation;sequelize-typescript/associations/belongs-to/belongs-to-association.BelongsToAssociation;", // + "sequelize-typescript.BelongsToAssociationStatic;sequelize-typescript/associations/belongs-to/belongs-to-association.BelongsToAssociationStatic;", // + "sequelize-typescript.BelongsToAssociationStatic;sequelize-typescript/associations/belongs-to/belongs-to-association;Member[BelongsToAssociation]", // + "sequelize-typescript.BelongsToAssociationStatic;sequelize-typescript;Member[BelongsToAssociation]", // + "sequelize-typescript.BelongsToManyAssociation;sequelize-typescript.BelongsToManyAssociationStatic;Instance", // + "sequelize-typescript.BelongsToManyAssociation;sequelize-typescript/associations/belongs-to-many/belongs-to-many-association.BelongsToManyAssociation;", // + "sequelize-typescript.BelongsToManyAssociationStatic;sequelize-typescript/associations/belongs-to-many/belongs-to-many-association.BelongsToManyAssociationStatic;", // + "sequelize-typescript.BelongsToManyAssociationStatic;sequelize-typescript/associations/belongs-to-many/belongs-to-many-association;Member[BelongsToManyAssociation]", // + "sequelize-typescript.BelongsToManyAssociationStatic;sequelize-typescript;Member[BelongsToManyAssociation]", // + "sequelize-typescript.DefaultScopeGetter;sequelize-typescript.ScopeOptionsGetters;Member[getDefaultScope]", // + "sequelize-typescript.DefaultScopeGetter;sequelize-typescript/scopes/default-scope;Member[DefaultScope].Argument[0]", // + "sequelize-typescript.DefaultScopeGetter;sequelize-typescript/scopes/scope-options.DefaultScopeGetter;", // + "sequelize-typescript.DefaultScopeGetter;sequelize-typescript;Member[DefaultScope].Argument[0]", // + "sequelize-typescript.HasAssociation;sequelize-typescript.HasAssociationStatic;Instance", // + "sequelize-typescript.HasAssociation;sequelize-typescript/associations/has/has-association.HasAssociation;", // + "sequelize-typescript.HasAssociationStatic;sequelize-typescript/associations/has/has-association.HasAssociationStatic;", // + "sequelize-typescript.HasAssociationStatic;sequelize-typescript/associations/has/has-association;Member[HasAssociation]", // + "sequelize-typescript.HasAssociationStatic;sequelize-typescript;Member[HasAssociation]", // + "sequelize-typescript.Model;sequelize-typescript.Model;Member[$add,$has,$remove,$set].Argument[1]", // + "sequelize-typescript.Model;sequelize-typescript.Model;Member[$add,$has,$remove,$set].Argument[1].ArrayElement", // + "sequelize-typescript.Model;sequelize-typescript.Model;Member[$create,reload].ReturnValue.Awaited", // + "sequelize-typescript.Model;sequelize-typescript.ModelStatic~;Instance", // + "sequelize-typescript.Model;sequelize-typescript.ModelStatic~;Member[initialize].ReturnValue.TypeVar[sequelize-typescript.ModelStatic.0]", // + "sequelize-typescript.Model;sequelize-typescript.ModelType;Instance", // + "sequelize-typescript.Model;sequelize-typescript.Sequelize;Member[getRepository].Argument[0].Instance", // + "sequelize-typescript.Model;sequelize-typescript.Sequelize;Member[getRepository].ReturnValue.TypeVar[sequelize-typescript.Repository.0]", // + "sequelize-typescript.Model;sequelize-typescript/model/model/model.Model;", // + "sequelize-typescript.ModelClassGetter;sequelize-typescript.BaseAssociationStatic;Argument[0]", // + "sequelize-typescript.ModelClassGetter;sequelize-typescript.BelongsToAssociationStatic;Argument[0]", // + "sequelize-typescript.ModelClassGetter;sequelize-typescript.BelongsToManyAssociationStatic;Argument[0]", // + "sequelize-typescript.ModelClassGetter;sequelize-typescript.HasAssociationStatic;Argument[0]", // + "sequelize-typescript.ModelClassGetter;sequelize-typescript/associations/belongs-to-many/belongs-to-many;Member[BelongsToMany].Argument[0,1]", // + "sequelize-typescript.ModelClassGetter;sequelize-typescript/associations/belongs-to/belongs-to;Member[BelongsTo].Argument[0]", // + "sequelize-typescript.ModelClassGetter;sequelize-typescript/associations/foreign-key/foreign-key-meta.ForeignKeyMeta;Member[relatedClassGetter]", // + "sequelize-typescript.ModelClassGetter;sequelize-typescript/associations/foreign-key/foreign-key-service;Member[addForeignKey].Argument[1]", // + "sequelize-typescript.ModelClassGetter;sequelize-typescript/associations/foreign-key/foreign-key;Member[ForeignKey].Argument[0]", // + "sequelize-typescript.ModelClassGetter;sequelize-typescript/associations/has/has-many;Member[HasMany].Argument[0]", // + "sequelize-typescript.ModelClassGetter;sequelize-typescript/associations/has/has-one;Member[HasOne].Argument[0]", // + "sequelize-typescript.ModelClassGetter;sequelize-typescript/model/shared/model-class-getter.ModelClassGetter;", // + "sequelize-typescript.ModelClassGetter;sequelize-typescript;Member[BelongsTo,ForeignKey,HasMany,HasOne].Argument[0]", // + "sequelize-typescript.ModelClassGetter;sequelize-typescript;Member[BelongsToMany].Argument[0,1]", // + "sequelize-typescript.ModelStatic~;sequelize-typescript/model/model/model.ModelStatic~;", // + "sequelize-typescript.ModelStatic~;sequelize-typescript/model/model/model;Member[Model]", // + "sequelize-typescript.ModelStatic~;sequelize-typescript/model/shared/model-not-initialized-error.ModelNotInitializedErrorStatic;Argument[0]", // + "sequelize-typescript.ModelStatic~;sequelize-typescript;Member[Model]", // + "sequelize-typescript.ModelType;sequelize-typescript.BaseAssociation;Member[getAssociatedClass].ReturnValue", // + "sequelize-typescript.ModelType;sequelize-typescript.BaseAssociation;Member[getSequelizeOptions].Argument[0]", // + "sequelize-typescript.ModelType;sequelize-typescript.BelongsToAssociation;Member[getSequelizeOptions].Argument[0]", // + "sequelize-typescript.ModelType;sequelize-typescript.BelongsToManyAssociation;Member[getSequelizeOptions].Argument[0]", // + "sequelize-typescript.ModelType;sequelize-typescript.HasAssociation;Member[getSequelizeOptions].Argument[0]", // + "sequelize-typescript.ModelType;sequelize-typescript.ModelClassGetter;ReturnValue", // + "sequelize-typescript.ModelType;sequelize-typescript.Sequelize;Member[model].Argument[0]", // + "sequelize-typescript.ModelType;sequelize-typescript/associations/foreign-key/foreign-key-service;Member[getForeignKeyOptions].Argument[0,1]", // + "sequelize-typescript.ModelType;sequelize-typescript/model/model/model.ModelType;", // + "sequelize-typescript.ScopeOptionsGetters;sequelize-typescript/scopes/scope-options.ScopeOptionsGetters;", // + "sequelize-typescript.ScopeOptionsGetters;sequelize-typescript/scopes/scope-service;Member[addScopeOptionsGetter,setScopeOptionsGetters].Argument[1]", // + "sequelize-typescript.ScopeOptionsGetters;sequelize-typescript/scopes/scope-service;Member[getScopeOptionsGetters].ReturnValue", // + "sequelize-typescript.ScopeOptionsGetters;sequelize-typescript;Member[addScopeOptionsGetter,setScopeOptionsGetters].Argument[1]", // + "sequelize-typescript.ScopeOptionsGetters;sequelize-typescript;Member[getScopeOptionsGetters].ReturnValue", // + "sequelize-typescript.ScopesOptions;sequelize-typescript.ScopesOptionsGetter;ReturnValue.AnyMember", // + "sequelize-typescript.ScopesOptions;sequelize-typescript/scopes/scope-options.ScopesOptions;", // + "sequelize-typescript.ScopesOptions;sequelize-typescript/scopes/scope-service;Member[resolveScope].Argument[2]", // + "sequelize-typescript.ScopesOptions;sequelize-typescript;Member[resolveScope].Argument[2]", // + "sequelize-typescript.ScopesOptionsGetter;sequelize-typescript.ScopeOptionsGetters;Member[getScopes]", // + "sequelize-typescript.ScopesOptionsGetter;sequelize-typescript/scopes/scope-options.ScopesOptionsGetter;", // + "sequelize-typescript.ScopesOptionsGetter;sequelize-typescript/scopes/scopes;Member[Scopes].Argument[0]", // + "sequelize-typescript.ScopesOptionsGetter;sequelize-typescript;Member[Scopes].Argument[0]", // + "sequelize-typescript.Sequelize;sequelize-typescript.BaseAssociation;Member[getSequelizeOptions].Argument[1]", // + "sequelize-typescript.Sequelize;sequelize-typescript.BelongsToManyAssociation;Member[getSequelizeOptions].Argument[1]", // + "sequelize-typescript.Sequelize;sequelize-typescript.SequelizeStatic;Instance", // + "sequelize-typescript.Sequelize;sequelize-typescript/sequelize/sequelize/sequelize.Sequelize;", // + "sequelize-typescript.SequelizeOptions;sequelize-typescript.Sequelize;Member[options]", // + "sequelize-typescript.SequelizeOptions;sequelize-typescript.SequelizeStatic;Argument[3]", // + "sequelize-typescript.SequelizeOptions;sequelize-typescript.SequelizeStatic;WithArity[0].Argument[0]", // + "sequelize-typescript.SequelizeOptions;sequelize-typescript.SequelizeStatic;WithArity[1].Argument[0,1]", // + "sequelize-typescript.SequelizeOptions;sequelize-typescript.SequelizeStatic;WithArity[2].Argument[1,2]", // + "sequelize-typescript.SequelizeOptions;sequelize-typescript.SequelizeStatic;WithArity[3].Argument[2]", // + "sequelize-typescript.SequelizeOptions;sequelize-typescript/sequelize/sequelize/sequelize-options.SequelizeOptions;", // + "sequelize-typescript.SequelizeOptions;sequelize-typescript/sequelize/sequelize/sequelize-service;Member[prepareArgs].ReturnValue.Member[options]", // + "sequelize-typescript.SequelizeOptions;sequelize-typescript/sequelize/sequelize/sequelize-service;Member[prepareOptions].Argument[0]", // + "sequelize-typescript.SequelizeOptions;sequelize-typescript/sequelize/sequelize/sequelize-service;Member[prepareOptions].ReturnValue", // + "sequelize-typescript.SequelizeOptions;sequelize-typescript;Member[prepareArgs].ReturnValue.Member[options]", // + "sequelize-typescript.SequelizeOptions;sequelize-typescript;Member[prepareOptions].Argument[0]", // + "sequelize-typescript.SequelizeOptions;sequelize-typescript;Member[prepareOptions].ReturnValue", // + "sequelize-typescript.SequelizeStatic;sequelize-typescript/sequelize/sequelize/sequelize.SequelizeStatic;", // + "sequelize-typescript.SequelizeStatic;sequelize-typescript/sequelize/sequelize/sequelize;Member[Sequelize]", // + "sequelize-typescript.SequelizeStatic;sequelize-typescript;Member[Sequelize]", // + "sequelize-typescript/associations/foreign-key/foreign-key-meta.ForeignKeyMeta;sequelize-typescript/associations/foreign-key/foreign-key-service;Member[getForeignKeys].ReturnValue.ArrayElement", // + "sequelize-typescript/model/model/association/association-create-options.AssociationCreateOptions;sequelize-typescript.Model;Member[$create].Argument[2]", // + "sequelize-typescript/model/shared/model-not-initialized-error.ModelNotInitializedErrorStatic;sequelize-typescript/model/shared/model-not-initialized-error;Member[ModelNotInitializedError]", // + "sequelize.AnyFindOptions;sequelize.BelongsToManyAddAssociationMixin;Argument[1]", // + "sequelize.AnyFindOptions;sequelize.BelongsToManyAddAssociationsMixin;Argument[1]", // + "sequelize.AnyFindOptions;sequelize.BelongsToManySetAssociationsMixin;Argument[1]", // + "sequelize.AnyFindOptions;sequelize.DefineOptions;Member[defaultScope]", // + "sequelize.AnyFindOptions;sequelize.DefineScopeOptions;AnyMember", // + "sequelize.AnyFindOptions;sequelize.HasManySetAssociationsMixin;Argument[1]", // + "sequelize.AnyFindOptions;sequelize.Instance;Member[reload].Argument[0]", // + "sequelize.AnyFindOptions;sequelize.Model;Member[addScope].Argument[1]", // + "sequelize.AssociationOptionsBelongsToMany;sequelize.Associations;Member[belongsToMany].Argument[1]", // + "sequelize.Associations;sequelize.Model;", // + "sequelize.Associations;sequelize.SequelizeStaticAndInstance.Model;", // + "sequelize.BuildOptions;sequelize-typescript.ModelStatic~;Argument[1]", // + "sequelize.BuildOptions;sequelize.CreateOptions;", // + "sequelize.BuildOptions;sequelize.Model;Member[build,bulkBuild].Argument[1]", // + "sequelize.CountOptions;sequelize.Model;Member[count].Argument[0]", // + "sequelize.CreateOptions;sequelize-typescript/model/model/association/association-create-options.AssociationCreateOptions;", // + "sequelize.CreateOptions;sequelize.BelongsToCreateAssociationMixin;Argument[1]", // + "sequelize.CreateOptions;sequelize.BelongsToManyCreateAssociationMixin;Argument[1]", // + "sequelize.CreateOptions;sequelize.HasManyCreateAssociationMixin;Argument[1]", // + "sequelize.CreateOptions;sequelize.HasOneCreateAssociationMixin;Argument[1]", // + "sequelize.CreateOptions;sequelize.Model;Member[create].Argument[1]", // + "sequelize.DefineAttributeColumnOptions;sequelize.DefineAttributes;AnyMember", // + "sequelize.DefineAttributeColumnOptions;sequelize.QueryInterface;Member[addColumn,changeColumn].Argument[2]", // + "sequelize.DefineAttributeColumnReferencesOptions;sequelize.DefineAttributeColumnOptions;Member[references]", // + "sequelize.DefineAttributes;sequelize.Hooks;Member[beforeDefine].Argument[1].Argument[0]", // + "sequelize.DefineAttributes;sequelize.Hooks;Member[beforeDefine].WithArity[1].Argument[0].Argument[0]", // + "sequelize.DefineAttributes;sequelize.QueryInterface;Member[createTable].Argument[1]", // + "sequelize.DefineOptions;sequelize.Options;Member[define]", // + "sequelize.DefineOptions;sequelize.Sequelize;Member[define].Argument[2]", // + "sequelize.DefineScopeOptions;sequelize.DefineOptions;Member[scopes]", // + "sequelize.FindCreateFindOptions;sequelize.Model;Member[findCreateFind].Argument[0]", // + "sequelize.FindOptions;sequelize-typescript.AssociationCountOptions;", // + "sequelize.FindOptions;sequelize-typescript.AssociationGetOptions;", // + "sequelize.FindOptions;sequelize-typescript.DefaultScopeGetter;ReturnValue", // + "sequelize.FindOptions;sequelize-typescript.Model;Member[reload].Argument[0]", // + "sequelize.FindOptions;sequelize-typescript.ScopesOptions;", // + "sequelize.FindOptions;sequelize-typescript.ScopesOptions;ReturnValue", // + "sequelize.FindOptions;sequelize.AnyFindOptions;", // + "sequelize.FindOptions;sequelize.FindCreateFindOptions;", // + "sequelize.FindOptions;sequelize.FindOrInitializeOptions;", // + "sequelize.FindOptions;sequelize.Model;Member[all,find,findAll,findAndCount,findAndCountAll,findOne].Argument[0]", // + "sequelize.FindOptionsOrderArray;sequelize.FindOptions;Member[order]", // + "sequelize.FindOptionsOrderArray;sequelize.FindOptions;Member[order].ArrayElement", // + "sequelize.FindOrInitializeOptions;sequelize.Model;Member[findOrBuild,findOrCreate,findOrInitialize].Argument[0]", // + "sequelize.HasManyGetAssociationsMixinOptions;sequelize.HasManyGetAssociationsMixin;Argument[0]", // + "sequelize.HasManyGetAssociationsMixinOptions;sequelize.HasManyHasAssociationMixin;Argument[1]", // + "sequelize.HasManyGetAssociationsMixinOptions;sequelize.HasManyHasAssociationsMixin;Argument[1]", // + "sequelize.Hooks;sequelize.Hooks;Member[addHook,hook,removeHook].ReturnValue", // + "sequelize.Hooks;sequelize.Model;", // + "sequelize.Hooks;sequelize.Sequelize;", // + "sequelize.Hooks;sequelize.SequelizeStaticAndInstance.Model;", // + "sequelize.IncludeAssociation;sequelize.Associations;Member[belongsTo,belongsToMany,hasMany,hasOne].ReturnValue", // + "sequelize.IncludeAssociation;sequelize.IncludeOptions;Member[association]", // + "sequelize.IncludeOptions;sequelize.BuildOptions;Member[include].ArrayElement", // + "sequelize.IncludeOptions;sequelize.CountOptions;Member[include]", // + "sequelize.IncludeOptions;sequelize.CountOptions;Member[include].ArrayElement", // + "sequelize.IncludeOptions;sequelize.FindOptions;Member[include]", // + "sequelize.IncludeOptions;sequelize.FindOptions;Member[include].ArrayElement", // + "sequelize.IncludeOptions;sequelize.HasManyGetAssociationsMixinOptions;Member[include]", // + "sequelize.IncludeOptions;sequelize.IncludeOptions;Member[include]", // + "sequelize.IncludeOptions;sequelize.IncludeOptions;Member[include].ArrayElement", // + "sequelize.Instance;sequelize.Instance;Member[decrement,increment,reload,save,update,updateAttributes].ReturnValue.Awaited", // + "sequelize.Instance;sequelize.Instance;Member[equalsOneOf].Argument[0].ArrayElement", // + "sequelize.Instance;sequelize.Instance;Member[equals].Argument[0]", // + "sequelize.Instance;sequelize.Instance;Member[set,setAttributes].ReturnValue", // + "sequelize.Instance;sequelize.Model;Member[Instance,build].ReturnValue", // + "sequelize.Instance;sequelize.Model;Member[all,bulkCreate,findAll].ReturnValue.Awaited.ArrayElement", // + "sequelize.Instance;sequelize.Model;Member[bulkBuild].ReturnValue.ArrayElement", // + "sequelize.Instance;sequelize.Model;Member[create,find,findById,findByPk,findByPrimary,findOne].ReturnValue.Awaited", // + "sequelize.Instance;sequelize.Model;Member[findAndCount,findAndCountAll].ReturnValue.Awaited.Member[rows].ArrayElement", // + "sequelize.Instance;sequelize.QueryInterface;Member[delete,increment,insert,update].Argument[0]", // + "sequelize.Instance;sequelize.QueryOptions;Member[instance]", // + "sequelize.Instance;sequelize.SequelizeStaticAndInstance;Member[Instance]", // + "sequelize.Model;sequelize.AssociationOptionsBelongsToMany;Member[through]", // + "sequelize.Model;sequelize.Associations;Member[belongsTo,belongsToMany,hasMany,hasOne].Argument[0]", // + "sequelize.Model;sequelize.BuildOptions;Member[include].ArrayElement", // + "sequelize.Model;sequelize.CountOptions;Member[include]", // + "sequelize.Model;sequelize.CountOptions;Member[include].ArrayElement", // + "sequelize.Model;sequelize.DefineAttributeColumnReferencesOptions;Member[model]", // + "sequelize.Model;sequelize.FindOptions;Member[include]", // + "sequelize.Model;sequelize.FindOptions;Member[include].ArrayElement", // + "sequelize.Model;sequelize.FindOptions;Member[lock].Member[of]", // + "sequelize.Model;sequelize.FindOptionsOrderArray;ArrayElement", // + "sequelize.Model;sequelize.FindOptionsOrderArray;ArrayElement.Member[model]", // + "sequelize.Model;sequelize.Hooks;Member[afterDefine].Argument[1].Argument[0]", // + "sequelize.Model;sequelize.Hooks;Member[afterDefine].WithArity[1].Argument[0].Argument[0]", // + "sequelize.Model;sequelize.IncludeAssociation;Member[source,target]", // + "sequelize.Model;sequelize.IncludeOptions;Member[include,model]", // + "sequelize.Model;sequelize.IncludeOptions;Member[include].ArrayElement", // + "sequelize.Model;sequelize.Instance;Member[Model]", // + "sequelize.Model;sequelize.Model;Member[schema,scope,unscoped].ReturnValue", // + "sequelize.Model;sequelize.Model;Member[sync].ReturnValue.Awaited", // + "sequelize.Model;sequelize.Models;AnyMember", // + "sequelize.Model;sequelize.ModelsHashInterface;AnyMember", // + "sequelize.Model;sequelize.QueryInterface;Member[bulkDelete,rawSelect,upsert].Argument[3]", // + "sequelize.Model;sequelize.QueryInterface;Member[select].Argument[0]", // + "sequelize.Model;sequelize.QueryOptions;Member[model]", // + "sequelize.Model;sequelize.Sequelize;Member[define,import,model].ReturnValue", // + "sequelize.Model;sequelize.Sequelize;Member[import].Argument[1].ReturnValue", // + "sequelize.Model;sequelize.SequelizeStaticAndInstance;Member[Model]", // + "sequelize.Model;sequelize.ThroughOptions;Member[model]", // + "sequelize.Model;sequelize.Utils;Member[mapOptionFieldNames].Argument[1]", // + "sequelize.Model;sequelize.Utils;Member[mapValueFieldNames].Argument[2]", // + "sequelize.Models;sequelize.Model;Member[associate].Argument[0]", // + "sequelize.ModelsHashInterface;sequelize.Sequelize;Member[models]", // + "sequelize.Options;sequelize-typescript.SequelizeOptions;", // + "sequelize.Options;sequelize.Sequelize;Member[options]", // + "sequelize.Options;sequelize.SequelizeStatic;Argument[3]", // + "sequelize.Options;sequelize.SequelizeStatic;WithArity[1].Argument[0,1]", // + "sequelize.Options;sequelize.SequelizeStatic;WithArity[2].Argument[1,2]", // + "sequelize.Options;sequelize.SequelizeStatic;WithArity[3].Argument[2]", // + "sequelize.QueryInterface;sequelize.Sequelize;Member[getQueryInterface].ReturnValue", // + "sequelize.QueryOptions;sequelize.Options;Member[query]", // + "sequelize.QueryOptions;sequelize.QueryInterface;Member[bulkDelete,bulkInsert,createTable,select,setAutocommit,setIsolationLevel].Argument[2]", // + "sequelize.QueryOptions;sequelize.QueryInterface;Member[bulkUpdate,delete,insert].Argument[3]", // + "sequelize.QueryOptions;sequelize.QueryInterface;Member[commitTransaction,deferConstraints,dropTable,rawSelect,rollbackTransaction,showIndex,startTransaction].Argument[1]", // + "sequelize.QueryOptions;sequelize.QueryInterface;Member[createFunction].Argument[5]", // + "sequelize.QueryOptions;sequelize.QueryInterface;Member[dropAllEnums,dropAllTables,showAllSchemas,showAllTables].Argument[0]", // + "sequelize.QueryOptions;sequelize.QueryInterface;Member[increment,update,upsert].Argument[4]", // + "sequelize.QueryOptions;sequelize.Sequelize;Member[authenticate,validate].Argument[0]", // + "sequelize.QueryOptions;sequelize.Sequelize;Member[query].Argument[1]", // + "sequelize.Sequelize;sequelize-typescript.Sequelize;", // + "sequelize.Sequelize;sequelize.Hooks;Member[afterInit].Argument[1].Argument[0]", // + "sequelize.Sequelize;sequelize.Hooks;Member[afterInit].WithArity[1].Argument[0].Argument[0]", // + "sequelize.Sequelize;sequelize.Instance;Member[sequelize]", // + "sequelize.Sequelize;sequelize.QueryInterface;Member[sequelize]", // + "sequelize.Sequelize;sequelize.Sequelize;Member[import].Argument[1].Argument[0]", // + "sequelize.Sequelize;sequelize.SequelizeStatic;Instance", // + "sequelize.Sequelize;sequelize.SequelizeStatic;Member[useCLS].ReturnValue", // + "sequelize.SequelizeStatic;sequelize-typescript.Sequelize;", // + "sequelize.SequelizeStatic;sequelize.Sequelize;Member[Sequelize]", // + "sequelize.SequelizeStatic;sequelize.SequelizeStatic;Member[Sequelize,default]", // + "sequelize.SequelizeStatic;sequelize;", // + "sequelize.SequelizeStaticAndInstance.Model;sequelize-typescript.Model;", // + "sequelize.SequelizeStaticAndInstance;sequelize.Sequelize;", // + "sequelize.SequelizeStaticAndInstance;sequelize.SequelizeStatic;", // + "sequelize.ThroughOptions;sequelize.AssociationOptionsBelongsToMany;Member[through]", // + "sequelize.Utils;sequelize.SequelizeStaticAndInstance;Member[Utils]", // ] } } @@ -277,11 +277,11 @@ private class Summaries extends ModelInput::SummaryModelCsv { override predicate row(string row) { row = [ - "sequelize-typescript;Model;;;Member[reload].ReturnValue.Awaited;type", // - "sequelize;Instance;;;Member[decrement,increment,reload,save,update,updateAttributes].ReturnValue.Awaited;type", // - "sequelize;Instance;;;Member[set,setAttributes].ReturnValue;type", // - "sequelize;Model;;;Member[schema,scope,unscoped].ReturnValue;type", // - "sequelize;Model;;;Member[sync].ReturnValue.Awaited;type", // + "sequelize-typescript.Model;;;Member[reload].ReturnValue.Awaited;type", // + "sequelize.Instance;;;Member[decrement,increment,reload,save,update,updateAttributes].ReturnValue.Awaited;type", // + "sequelize.Instance;;;Member[set,setAttributes].ReturnValue;type", // + "sequelize.Model;;;Member[schema,scope,unscoped].ReturnValue;type", // + "sequelize.Model;;;Member[sync].ReturnValue.Awaited;type", // ] } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/sequelize/model.json b/javascript/ql/lib/semmle/javascript/frameworks/sequelize/model.json index 8d6c473de29..88568283605 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/sequelize/model.json +++ b/javascript/ql/lib/semmle/javascript/frameworks/sequelize/model.json @@ -12,279 +12,279 @@ }, "language": "javascript", "replaceTypeParameters": [ - "sequelize;Model;TInstance;sequelize;Instance" + "sequelize.Model;TInstance;sequelize.Instance" ], "model": { "sinks": [ - "sequelize;;Argument[0..].Member[password];credentials[password]", - "sequelize;;Argument[0..].Member[username];credentials[username]", - "sequelize;;Argument[1];credentials[username]", - "sequelize;;Argument[2];credentials[password]", - "sequelize;Sequelize;Member[query].Argument[0].Member[query];sql-injection", - "sequelize;Sequelize;Member[query].Argument[0];sql-injection", - "sequelize;SequelizeStaticAndInstance;Member[asIs,literal].Argument[0];sql-injection" + "sequelize.Sequelize;Member[query].Argument[0].Member[query];sql-injection", + "sequelize.Sequelize;Member[query].Argument[0];sql-injection", + "sequelize.SequelizeStaticAndInstance;Member[asIs,literal].Argument[0];sql-injection", + "sequelize;Argument[0..].Member[password];credentials[password]", + "sequelize;Argument[0..].Member[username];credentials[username]", + "sequelize;Argument[1];credentials[username]", + "sequelize;Argument[2];credentials[password]" ], "typeDefinitions": [ - "sequelize;Sequelize;sequelize-typescript;Sequelize;" + "sequelize.Sequelize;sequelize-typescript.Sequelize;" ] }, "generatedModel": { "//": "Autogenerated section. Manual edits in here will be lost.", "typeDefinitions": [ - "sequelize-typescript/associations/foreign-key/foreign-key-meta;ForeignKeyMeta;sequelize-typescript/associations/foreign-key/foreign-key-service;;Member[getForeignKeys].ReturnValue.ArrayElement", - "sequelize-typescript/model/model/association/association-create-options;AssociationCreateOptions;sequelize-typescript;Model;Member[$create].Argument[2]", - "sequelize-typescript/model/shared/model-not-initialized-error;ModelNotInitializedErrorStatic;sequelize-typescript/model/shared/model-not-initialized-error;;Member[ModelNotInitializedError]", - "sequelize-typescript;AssociationCountOptions;sequelize-typescript/model/model/association/association-count-options;AssociationCountOptions;", - "sequelize-typescript;AssociationCountOptions;sequelize-typescript;Model;Member[$count].Argument[1]", - "sequelize-typescript;AssociationGetOptions;sequelize-typescript/model/model/association/association-get-options;AssociationGetOptions;", - "sequelize-typescript;AssociationGetOptions;sequelize-typescript;Model;Member[$get].Argument[1]", - "sequelize-typescript;AssociationGetOptions;sequelize-typescript;Model;Member[$has].Argument[2]", - "sequelize-typescript;BaseAssociation;sequelize-typescript/associations/shared/association-service;;Member[addAssociation].Argument[1]", - "sequelize-typescript;BaseAssociation;sequelize-typescript/associations/shared/association-service;;Member[getAssociations,getAssociationsByRelation].ReturnValue.ArrayElement", - "sequelize-typescript;BaseAssociation;sequelize-typescript/associations/shared/association-service;;Member[setAssociations].Argument[1].ArrayElement", - "sequelize-typescript;BaseAssociation;sequelize-typescript/associations/shared/base-association;BaseAssociation;", - "sequelize-typescript;BaseAssociation;sequelize-typescript;;Member[addAssociation].Argument[1]", - "sequelize-typescript;BaseAssociation;sequelize-typescript;;Member[getAssociations,getAssociationsByRelation].ReturnValue.ArrayElement", - "sequelize-typescript;BaseAssociation;sequelize-typescript;;Member[setAssociations].Argument[1].ArrayElement", - "sequelize-typescript;BaseAssociation;sequelize-typescript;BaseAssociationStatic;Instance", - "sequelize-typescript;BaseAssociation;sequelize-typescript;BelongsToAssociation;", - "sequelize-typescript;BaseAssociation;sequelize-typescript;BelongsToManyAssociation;", - "sequelize-typescript;BaseAssociation;sequelize-typescript;HasAssociation;", - "sequelize-typescript;BaseAssociationStatic;sequelize-typescript/associations/shared/base-association;;Member[BaseAssociation]", - "sequelize-typescript;BaseAssociationStatic;sequelize-typescript/associations/shared/base-association;BaseAssociationStatic;", - "sequelize-typescript;BaseAssociationStatic;sequelize-typescript;;Member[BaseAssociation]", - "sequelize-typescript;BelongsToAssociation;sequelize-typescript/associations/belongs-to/belongs-to-association;BelongsToAssociation;", - "sequelize-typescript;BelongsToAssociation;sequelize-typescript;BelongsToAssociationStatic;Instance", - "sequelize-typescript;BelongsToAssociationStatic;sequelize-typescript/associations/belongs-to/belongs-to-association;;Member[BelongsToAssociation]", - "sequelize-typescript;BelongsToAssociationStatic;sequelize-typescript/associations/belongs-to/belongs-to-association;BelongsToAssociationStatic;", - "sequelize-typescript;BelongsToAssociationStatic;sequelize-typescript;;Member[BelongsToAssociation]", - "sequelize-typescript;BelongsToManyAssociation;sequelize-typescript/associations/belongs-to-many/belongs-to-many-association;BelongsToManyAssociation;", - "sequelize-typescript;BelongsToManyAssociation;sequelize-typescript;BelongsToManyAssociationStatic;Instance", - "sequelize-typescript;BelongsToManyAssociationStatic;sequelize-typescript/associations/belongs-to-many/belongs-to-many-association;;Member[BelongsToManyAssociation]", - "sequelize-typescript;BelongsToManyAssociationStatic;sequelize-typescript/associations/belongs-to-many/belongs-to-many-association;BelongsToManyAssociationStatic;", - "sequelize-typescript;BelongsToManyAssociationStatic;sequelize-typescript;;Member[BelongsToManyAssociation]", - "sequelize-typescript;DefaultScopeGetter;sequelize-typescript/scopes/default-scope;;Member[DefaultScope].Argument[0]", - "sequelize-typescript;DefaultScopeGetter;sequelize-typescript/scopes/scope-options;DefaultScopeGetter;", - "sequelize-typescript;DefaultScopeGetter;sequelize-typescript;;Member[DefaultScope].Argument[0]", - "sequelize-typescript;DefaultScopeGetter;sequelize-typescript;ScopeOptionsGetters;Member[getDefaultScope]", - "sequelize-typescript;HasAssociation;sequelize-typescript/associations/has/has-association;HasAssociation;", - "sequelize-typescript;HasAssociation;sequelize-typescript;HasAssociationStatic;Instance", - "sequelize-typescript;HasAssociationStatic;sequelize-typescript/associations/has/has-association;;Member[HasAssociation]", - "sequelize-typescript;HasAssociationStatic;sequelize-typescript/associations/has/has-association;HasAssociationStatic;", - "sequelize-typescript;HasAssociationStatic;sequelize-typescript;;Member[HasAssociation]", - "sequelize-typescript;Model;sequelize-typescript/model/model/model;Model;", - "sequelize-typescript;Model;sequelize-typescript;Model;Member[$add,$has,$remove,$set].Argument[1]", - "sequelize-typescript;Model;sequelize-typescript;Model;Member[$add,$has,$remove,$set].Argument[1].ArrayElement", - "sequelize-typescript;Model;sequelize-typescript;Model;Member[$create,reload].ReturnValue.Awaited", - "sequelize-typescript;Model;sequelize-typescript;ModelStatic~;Instance", - "sequelize-typescript;Model;sequelize-typescript;ModelStatic~;Member[initialize].ReturnValue.TypeVar[sequelize-typescript.ModelStatic.0]", - "sequelize-typescript;Model;sequelize-typescript;ModelType;Instance", - "sequelize-typescript;Model;sequelize-typescript;Sequelize;Member[getRepository].Argument[0].Instance", - "sequelize-typescript;Model;sequelize-typescript;Sequelize;Member[getRepository].ReturnValue.TypeVar[sequelize-typescript.Repository.0]", - "sequelize-typescript;ModelClassGetter;sequelize-typescript/associations/belongs-to-many/belongs-to-many;;Member[BelongsToMany].Argument[0,1]", - "sequelize-typescript;ModelClassGetter;sequelize-typescript/associations/belongs-to/belongs-to;;Member[BelongsTo].Argument[0]", - "sequelize-typescript;ModelClassGetter;sequelize-typescript/associations/foreign-key/foreign-key-meta;ForeignKeyMeta;Member[relatedClassGetter]", - "sequelize-typescript;ModelClassGetter;sequelize-typescript/associations/foreign-key/foreign-key-service;;Member[addForeignKey].Argument[1]", - "sequelize-typescript;ModelClassGetter;sequelize-typescript/associations/foreign-key/foreign-key;;Member[ForeignKey].Argument[0]", - "sequelize-typescript;ModelClassGetter;sequelize-typescript/associations/has/has-many;;Member[HasMany].Argument[0]", - "sequelize-typescript;ModelClassGetter;sequelize-typescript/associations/has/has-one;;Member[HasOne].Argument[0]", - "sequelize-typescript;ModelClassGetter;sequelize-typescript/model/shared/model-class-getter;ModelClassGetter;", - "sequelize-typescript;ModelClassGetter;sequelize-typescript;;Member[BelongsTo,ForeignKey,HasMany,HasOne].Argument[0]", - "sequelize-typescript;ModelClassGetter;sequelize-typescript;;Member[BelongsToMany].Argument[0,1]", - "sequelize-typescript;ModelClassGetter;sequelize-typescript;BaseAssociationStatic;Argument[0]", - "sequelize-typescript;ModelClassGetter;sequelize-typescript;BelongsToAssociationStatic;Argument[0]", - "sequelize-typescript;ModelClassGetter;sequelize-typescript;BelongsToManyAssociationStatic;Argument[0]", - "sequelize-typescript;ModelClassGetter;sequelize-typescript;HasAssociationStatic;Argument[0]", - "sequelize-typescript;ModelStatic~;sequelize-typescript/model/model/model;;Member[Model]", - "sequelize-typescript;ModelStatic~;sequelize-typescript/model/model/model;ModelStatic~;", - "sequelize-typescript;ModelStatic~;sequelize-typescript/model/shared/model-not-initialized-error;ModelNotInitializedErrorStatic;Argument[0]", - "sequelize-typescript;ModelStatic~;sequelize-typescript;;Member[Model]", - "sequelize-typescript;ModelType;sequelize-typescript/associations/foreign-key/foreign-key-service;;Member[getForeignKeyOptions].Argument[0,1]", - "sequelize-typescript;ModelType;sequelize-typescript/model/model/model;ModelType;", - "sequelize-typescript;ModelType;sequelize-typescript;BaseAssociation;Member[getAssociatedClass].ReturnValue", - "sequelize-typescript;ModelType;sequelize-typescript;BaseAssociation;Member[getSequelizeOptions].Argument[0]", - "sequelize-typescript;ModelType;sequelize-typescript;BelongsToAssociation;Member[getSequelizeOptions].Argument[0]", - "sequelize-typescript;ModelType;sequelize-typescript;BelongsToManyAssociation;Member[getSequelizeOptions].Argument[0]", - "sequelize-typescript;ModelType;sequelize-typescript;HasAssociation;Member[getSequelizeOptions].Argument[0]", - "sequelize-typescript;ModelType;sequelize-typescript;ModelClassGetter;ReturnValue", - "sequelize-typescript;ModelType;sequelize-typescript;Sequelize;Member[model].Argument[0]", - "sequelize-typescript;ScopeOptionsGetters;sequelize-typescript/scopes/scope-options;ScopeOptionsGetters;", - "sequelize-typescript;ScopeOptionsGetters;sequelize-typescript/scopes/scope-service;;Member[addScopeOptionsGetter,setScopeOptionsGetters].Argument[1]", - "sequelize-typescript;ScopeOptionsGetters;sequelize-typescript/scopes/scope-service;;Member[getScopeOptionsGetters].ReturnValue", - "sequelize-typescript;ScopeOptionsGetters;sequelize-typescript;;Member[addScopeOptionsGetter,setScopeOptionsGetters].Argument[1]", - "sequelize-typescript;ScopeOptionsGetters;sequelize-typescript;;Member[getScopeOptionsGetters].ReturnValue", - "sequelize-typescript;ScopesOptions;sequelize-typescript/scopes/scope-options;ScopesOptions;", - "sequelize-typescript;ScopesOptions;sequelize-typescript/scopes/scope-service;;Member[resolveScope].Argument[2]", - "sequelize-typescript;ScopesOptions;sequelize-typescript;;Member[resolveScope].Argument[2]", - "sequelize-typescript;ScopesOptions;sequelize-typescript;ScopesOptionsGetter;ReturnValue.AnyMember", - "sequelize-typescript;ScopesOptionsGetter;sequelize-typescript/scopes/scope-options;ScopesOptionsGetter;", - "sequelize-typescript;ScopesOptionsGetter;sequelize-typescript/scopes/scopes;;Member[Scopes].Argument[0]", - "sequelize-typescript;ScopesOptionsGetter;sequelize-typescript;;Member[Scopes].Argument[0]", - "sequelize-typescript;ScopesOptionsGetter;sequelize-typescript;ScopeOptionsGetters;Member[getScopes]", - "sequelize-typescript;Sequelize;sequelize-typescript/sequelize/sequelize/sequelize;Sequelize;", - "sequelize-typescript;Sequelize;sequelize-typescript;BaseAssociation;Member[getSequelizeOptions].Argument[1]", - "sequelize-typescript;Sequelize;sequelize-typescript;BelongsToManyAssociation;Member[getSequelizeOptions].Argument[1]", - "sequelize-typescript;Sequelize;sequelize-typescript;SequelizeStatic;Instance", - "sequelize-typescript;SequelizeOptions;sequelize-typescript/sequelize/sequelize/sequelize-options;SequelizeOptions;", - "sequelize-typescript;SequelizeOptions;sequelize-typescript/sequelize/sequelize/sequelize-service;;Member[prepareArgs].ReturnValue.Member[options]", - "sequelize-typescript;SequelizeOptions;sequelize-typescript/sequelize/sequelize/sequelize-service;;Member[prepareOptions].Argument[0]", - "sequelize-typescript;SequelizeOptions;sequelize-typescript/sequelize/sequelize/sequelize-service;;Member[prepareOptions].ReturnValue", - "sequelize-typescript;SequelizeOptions;sequelize-typescript;;Member[prepareArgs].ReturnValue.Member[options]", - "sequelize-typescript;SequelizeOptions;sequelize-typescript;;Member[prepareOptions].Argument[0]", - "sequelize-typescript;SequelizeOptions;sequelize-typescript;;Member[prepareOptions].ReturnValue", - "sequelize-typescript;SequelizeOptions;sequelize-typescript;Sequelize;Member[options]", - "sequelize-typescript;SequelizeOptions;sequelize-typescript;SequelizeStatic;Argument[3]", - "sequelize-typescript;SequelizeOptions;sequelize-typescript;SequelizeStatic;WithArity[0].Argument[0]", - "sequelize-typescript;SequelizeOptions;sequelize-typescript;SequelizeStatic;WithArity[1].Argument[0,1]", - "sequelize-typescript;SequelizeOptions;sequelize-typescript;SequelizeStatic;WithArity[2].Argument[1,2]", - "sequelize-typescript;SequelizeOptions;sequelize-typescript;SequelizeStatic;WithArity[3].Argument[2]", - "sequelize-typescript;SequelizeStatic;sequelize-typescript/sequelize/sequelize/sequelize;;Member[Sequelize]", - "sequelize-typescript;SequelizeStatic;sequelize-typescript/sequelize/sequelize/sequelize;SequelizeStatic;", - "sequelize-typescript;SequelizeStatic;sequelize-typescript;;Member[Sequelize]", - "sequelize;AnyFindOptions;sequelize;BelongsToManyAddAssociationMixin;Argument[1]", - "sequelize;AnyFindOptions;sequelize;BelongsToManyAddAssociationsMixin;Argument[1]", - "sequelize;AnyFindOptions;sequelize;BelongsToManySetAssociationsMixin;Argument[1]", - "sequelize;AnyFindOptions;sequelize;DefineOptions;Member[defaultScope]", - "sequelize;AnyFindOptions;sequelize;DefineScopeOptions;AnyMember", - "sequelize;AnyFindOptions;sequelize;HasManySetAssociationsMixin;Argument[1]", - "sequelize;AnyFindOptions;sequelize;Instance;Member[reload].Argument[0]", - "sequelize;AnyFindOptions;sequelize;Model;Member[addScope].Argument[1]", - "sequelize;AssociationOptionsBelongsToMany;sequelize;Associations;Member[belongsToMany].Argument[1]", - "sequelize;Associations;sequelize;Model;", - "sequelize;Associations;sequelize;SequelizeStaticAndInstance.Model;", - "sequelize;BuildOptions;sequelize-typescript;ModelStatic~;Argument[1]", - "sequelize;BuildOptions;sequelize;CreateOptions;", - "sequelize;BuildOptions;sequelize;Model;Member[build,bulkBuild].Argument[1]", - "sequelize;CountOptions;sequelize;Model;Member[count].Argument[0]", - "sequelize;CreateOptions;sequelize-typescript/model/model/association/association-create-options;AssociationCreateOptions;", - "sequelize;CreateOptions;sequelize;BelongsToCreateAssociationMixin;Argument[1]", - "sequelize;CreateOptions;sequelize;BelongsToManyCreateAssociationMixin;Argument[1]", - "sequelize;CreateOptions;sequelize;HasManyCreateAssociationMixin;Argument[1]", - "sequelize;CreateOptions;sequelize;HasOneCreateAssociationMixin;Argument[1]", - "sequelize;CreateOptions;sequelize;Model;Member[create].Argument[1]", - "sequelize;DefineAttributeColumnOptions;sequelize;DefineAttributes;AnyMember", - "sequelize;DefineAttributeColumnOptions;sequelize;QueryInterface;Member[addColumn,changeColumn].Argument[2]", - "sequelize;DefineAttributeColumnReferencesOptions;sequelize;DefineAttributeColumnOptions;Member[references]", - "sequelize;DefineAttributes;sequelize;Hooks;Member[beforeDefine].Argument[1].Argument[0]", - "sequelize;DefineAttributes;sequelize;Hooks;Member[beforeDefine].WithArity[1].Argument[0].Argument[0]", - "sequelize;DefineAttributes;sequelize;QueryInterface;Member[createTable].Argument[1]", - "sequelize;DefineOptions;sequelize;Options;Member[define]", - "sequelize;DefineOptions;sequelize;Sequelize;Member[define].Argument[2]", - "sequelize;DefineScopeOptions;sequelize;DefineOptions;Member[scopes]", - "sequelize;FindCreateFindOptions;sequelize;Model;Member[findCreateFind].Argument[0]", - "sequelize;FindOptions;sequelize-typescript;AssociationCountOptions;", - "sequelize;FindOptions;sequelize-typescript;AssociationGetOptions;", - "sequelize;FindOptions;sequelize-typescript;DefaultScopeGetter;ReturnValue", - "sequelize;FindOptions;sequelize-typescript;Model;Member[reload].Argument[0]", - "sequelize;FindOptions;sequelize-typescript;ScopesOptions;", - "sequelize;FindOptions;sequelize-typescript;ScopesOptions;ReturnValue", - "sequelize;FindOptions;sequelize;AnyFindOptions;", - "sequelize;FindOptions;sequelize;FindCreateFindOptions;", - "sequelize;FindOptions;sequelize;FindOrInitializeOptions;", - "sequelize;FindOptions;sequelize;Model;Member[all,find,findAll,findAndCount,findAndCountAll,findOne].Argument[0]", - "sequelize;FindOptionsOrderArray;sequelize;FindOptions;Member[order]", - "sequelize;FindOptionsOrderArray;sequelize;FindOptions;Member[order].ArrayElement", - "sequelize;FindOrInitializeOptions;sequelize;Model;Member[findOrBuild,findOrCreate,findOrInitialize].Argument[0]", - "sequelize;HasManyGetAssociationsMixinOptions;sequelize;HasManyGetAssociationsMixin;Argument[0]", - "sequelize;HasManyGetAssociationsMixinOptions;sequelize;HasManyHasAssociationMixin;Argument[1]", - "sequelize;HasManyGetAssociationsMixinOptions;sequelize;HasManyHasAssociationsMixin;Argument[1]", - "sequelize;Hooks;sequelize;Hooks;Member[addHook,hook,removeHook].ReturnValue", - "sequelize;Hooks;sequelize;Model;", - "sequelize;Hooks;sequelize;Sequelize;", - "sequelize;Hooks;sequelize;SequelizeStaticAndInstance.Model;", - "sequelize;IncludeAssociation;sequelize;Associations;Member[belongsTo,belongsToMany,hasMany,hasOne].ReturnValue", - "sequelize;IncludeAssociation;sequelize;IncludeOptions;Member[association]", - "sequelize;IncludeOptions;sequelize;BuildOptions;Member[include].ArrayElement", - "sequelize;IncludeOptions;sequelize;CountOptions;Member[include]", - "sequelize;IncludeOptions;sequelize;CountOptions;Member[include].ArrayElement", - "sequelize;IncludeOptions;sequelize;FindOptions;Member[include]", - "sequelize;IncludeOptions;sequelize;FindOptions;Member[include].ArrayElement", - "sequelize;IncludeOptions;sequelize;HasManyGetAssociationsMixinOptions;Member[include]", - "sequelize;IncludeOptions;sequelize;IncludeOptions;Member[include]", - "sequelize;IncludeOptions;sequelize;IncludeOptions;Member[include].ArrayElement", - "sequelize;Instance;sequelize;Instance;Member[decrement,increment,reload,save,update,updateAttributes].ReturnValue.Awaited", - "sequelize;Instance;sequelize;Instance;Member[equalsOneOf].Argument[0].ArrayElement", - "sequelize;Instance;sequelize;Instance;Member[equals].Argument[0]", - "sequelize;Instance;sequelize;Instance;Member[set,setAttributes].ReturnValue", - "sequelize;Instance;sequelize;Model;Member[Instance,build].ReturnValue", - "sequelize;Instance;sequelize;Model;Member[all,bulkCreate,findAll].ReturnValue.Awaited.ArrayElement", - "sequelize;Instance;sequelize;Model;Member[bulkBuild].ReturnValue.ArrayElement", - "sequelize;Instance;sequelize;Model;Member[create,find,findById,findByPk,findByPrimary,findOne].ReturnValue.Awaited", - "sequelize;Instance;sequelize;Model;Member[findAndCount,findAndCountAll].ReturnValue.Awaited.Member[rows].ArrayElement", - "sequelize;Instance;sequelize;QueryInterface;Member[delete,increment,insert,update].Argument[0]", - "sequelize;Instance;sequelize;QueryOptions;Member[instance]", - "sequelize;Instance;sequelize;SequelizeStaticAndInstance;Member[Instance]", - "sequelize;Model;sequelize;AssociationOptionsBelongsToMany;Member[through]", - "sequelize;Model;sequelize;Associations;Member[belongsTo,belongsToMany,hasMany,hasOne].Argument[0]", - "sequelize;Model;sequelize;BuildOptions;Member[include].ArrayElement", - "sequelize;Model;sequelize;CountOptions;Member[include]", - "sequelize;Model;sequelize;CountOptions;Member[include].ArrayElement", - "sequelize;Model;sequelize;DefineAttributeColumnReferencesOptions;Member[model]", - "sequelize;Model;sequelize;FindOptions;Member[include]", - "sequelize;Model;sequelize;FindOptions;Member[include].ArrayElement", - "sequelize;Model;sequelize;FindOptions;Member[lock].Member[of]", - "sequelize;Model;sequelize;FindOptionsOrderArray;ArrayElement", - "sequelize;Model;sequelize;FindOptionsOrderArray;ArrayElement.Member[model]", - "sequelize;Model;sequelize;Hooks;Member[afterDefine].Argument[1].Argument[0]", - "sequelize;Model;sequelize;Hooks;Member[afterDefine].WithArity[1].Argument[0].Argument[0]", - "sequelize;Model;sequelize;IncludeAssociation;Member[source,target]", - "sequelize;Model;sequelize;IncludeOptions;Member[include,model]", - "sequelize;Model;sequelize;IncludeOptions;Member[include].ArrayElement", - "sequelize;Model;sequelize;Instance;Member[Model]", - "sequelize;Model;sequelize;Model;Member[schema,scope,unscoped].ReturnValue", - "sequelize;Model;sequelize;Model;Member[sync].ReturnValue.Awaited", - "sequelize;Model;sequelize;Models;AnyMember", - "sequelize;Model;sequelize;ModelsHashInterface;AnyMember", - "sequelize;Model;sequelize;QueryInterface;Member[bulkDelete,rawSelect,upsert].Argument[3]", - "sequelize;Model;sequelize;QueryInterface;Member[select].Argument[0]", - "sequelize;Model;sequelize;QueryOptions;Member[model]", - "sequelize;Model;sequelize;Sequelize;Member[define,import,model].ReturnValue", - "sequelize;Model;sequelize;Sequelize;Member[import].Argument[1].ReturnValue", - "sequelize;Model;sequelize;SequelizeStaticAndInstance;Member[Model]", - "sequelize;Model;sequelize;ThroughOptions;Member[model]", - "sequelize;Model;sequelize;Utils;Member[mapOptionFieldNames].Argument[1]", - "sequelize;Model;sequelize;Utils;Member[mapValueFieldNames].Argument[2]", - "sequelize;Models;sequelize;Model;Member[associate].Argument[0]", - "sequelize;ModelsHashInterface;sequelize;Sequelize;Member[models]", - "sequelize;Options;sequelize-typescript;SequelizeOptions;", - "sequelize;Options;sequelize;Sequelize;Member[options]", - "sequelize;Options;sequelize;SequelizeStatic;Argument[3]", - "sequelize;Options;sequelize;SequelizeStatic;WithArity[1].Argument[0,1]", - "sequelize;Options;sequelize;SequelizeStatic;WithArity[2].Argument[1,2]", - "sequelize;Options;sequelize;SequelizeStatic;WithArity[3].Argument[2]", - "sequelize;QueryInterface;sequelize;Sequelize;Member[getQueryInterface].ReturnValue", - "sequelize;QueryOptions;sequelize;Options;Member[query]", - "sequelize;QueryOptions;sequelize;QueryInterface;Member[bulkDelete,bulkInsert,createTable,select,setAutocommit,setIsolationLevel].Argument[2]", - "sequelize;QueryOptions;sequelize;QueryInterface;Member[bulkUpdate,delete,insert].Argument[3]", - "sequelize;QueryOptions;sequelize;QueryInterface;Member[commitTransaction,deferConstraints,dropTable,rawSelect,rollbackTransaction,showIndex,startTransaction].Argument[1]", - "sequelize;QueryOptions;sequelize;QueryInterface;Member[createFunction].Argument[5]", - "sequelize;QueryOptions;sequelize;QueryInterface;Member[dropAllEnums,dropAllTables,showAllSchemas,showAllTables].Argument[0]", - "sequelize;QueryOptions;sequelize;QueryInterface;Member[increment,update,upsert].Argument[4]", - "sequelize;QueryOptions;sequelize;Sequelize;Member[authenticate,validate].Argument[0]", - "sequelize;QueryOptions;sequelize;Sequelize;Member[query].Argument[1]", - "sequelize;Sequelize;sequelize;Hooks;Member[afterInit].Argument[1].Argument[0]", - "sequelize;Sequelize;sequelize;Hooks;Member[afterInit].WithArity[1].Argument[0].Argument[0]", - "sequelize;Sequelize;sequelize;Instance;Member[sequelize]", - "sequelize;Sequelize;sequelize;QueryInterface;Member[sequelize]", - "sequelize;Sequelize;sequelize;Sequelize;Member[import].Argument[1].Argument[0]", - "sequelize;Sequelize;sequelize;SequelizeStatic;Instance", - "sequelize;Sequelize;sequelize;SequelizeStatic;Member[useCLS].ReturnValue", - "sequelize;SequelizeStatic;sequelize-typescript;Sequelize;", - "sequelize;SequelizeStatic;sequelize;;", - "sequelize;SequelizeStatic;sequelize;Sequelize;Member[Sequelize]", - "sequelize;SequelizeStatic;sequelize;SequelizeStatic;Member[Sequelize,default]", - "sequelize;SequelizeStaticAndInstance.Model;sequelize-typescript;Model;", - "sequelize;SequelizeStaticAndInstance;sequelize;Sequelize;", - "sequelize;SequelizeStaticAndInstance;sequelize;SequelizeStatic;", - "sequelize;ThroughOptions;sequelize;AssociationOptionsBelongsToMany;Member[through]", - "sequelize;Utils;sequelize;SequelizeStaticAndInstance;Member[Utils]" + "sequelize-typescript.AssociationCountOptions;sequelize-typescript.Model;Member[$count].Argument[1]", + "sequelize-typescript.AssociationCountOptions;sequelize-typescript/model/model/association/association-count-options.AssociationCountOptions;", + "sequelize-typescript.AssociationGetOptions;sequelize-typescript.Model;Member[$get].Argument[1]", + "sequelize-typescript.AssociationGetOptions;sequelize-typescript.Model;Member[$has].Argument[2]", + "sequelize-typescript.AssociationGetOptions;sequelize-typescript/model/model/association/association-get-options.AssociationGetOptions;", + "sequelize-typescript.BaseAssociation;sequelize-typescript.BaseAssociationStatic;Instance", + "sequelize-typescript.BaseAssociation;sequelize-typescript.BelongsToAssociation;", + "sequelize-typescript.BaseAssociation;sequelize-typescript.BelongsToManyAssociation;", + "sequelize-typescript.BaseAssociation;sequelize-typescript.HasAssociation;", + "sequelize-typescript.BaseAssociation;sequelize-typescript/associations/shared/association-service;Member[addAssociation].Argument[1]", + "sequelize-typescript.BaseAssociation;sequelize-typescript/associations/shared/association-service;Member[getAssociations,getAssociationsByRelation].ReturnValue.ArrayElement", + "sequelize-typescript.BaseAssociation;sequelize-typescript/associations/shared/association-service;Member[setAssociations].Argument[1].ArrayElement", + "sequelize-typescript.BaseAssociation;sequelize-typescript/associations/shared/base-association.BaseAssociation;", + "sequelize-typescript.BaseAssociation;sequelize-typescript;Member[addAssociation].Argument[1]", + "sequelize-typescript.BaseAssociation;sequelize-typescript;Member[getAssociations,getAssociationsByRelation].ReturnValue.ArrayElement", + "sequelize-typescript.BaseAssociation;sequelize-typescript;Member[setAssociations].Argument[1].ArrayElement", + "sequelize-typescript.BaseAssociationStatic;sequelize-typescript/associations/shared/base-association.BaseAssociationStatic;", + "sequelize-typescript.BaseAssociationStatic;sequelize-typescript/associations/shared/base-association;Member[BaseAssociation]", + "sequelize-typescript.BaseAssociationStatic;sequelize-typescript;Member[BaseAssociation]", + "sequelize-typescript.BelongsToAssociation;sequelize-typescript.BelongsToAssociationStatic;Instance", + "sequelize-typescript.BelongsToAssociation;sequelize-typescript/associations/belongs-to/belongs-to-association.BelongsToAssociation;", + "sequelize-typescript.BelongsToAssociationStatic;sequelize-typescript/associations/belongs-to/belongs-to-association.BelongsToAssociationStatic;", + "sequelize-typescript.BelongsToAssociationStatic;sequelize-typescript/associations/belongs-to/belongs-to-association;Member[BelongsToAssociation]", + "sequelize-typescript.BelongsToAssociationStatic;sequelize-typescript;Member[BelongsToAssociation]", + "sequelize-typescript.BelongsToManyAssociation;sequelize-typescript.BelongsToManyAssociationStatic;Instance", + "sequelize-typescript.BelongsToManyAssociation;sequelize-typescript/associations/belongs-to-many/belongs-to-many-association.BelongsToManyAssociation;", + "sequelize-typescript.BelongsToManyAssociationStatic;sequelize-typescript/associations/belongs-to-many/belongs-to-many-association.BelongsToManyAssociationStatic;", + "sequelize-typescript.BelongsToManyAssociationStatic;sequelize-typescript/associations/belongs-to-many/belongs-to-many-association;Member[BelongsToManyAssociation]", + "sequelize-typescript.BelongsToManyAssociationStatic;sequelize-typescript;Member[BelongsToManyAssociation]", + "sequelize-typescript.DefaultScopeGetter;sequelize-typescript.ScopeOptionsGetters;Member[getDefaultScope]", + "sequelize-typescript.DefaultScopeGetter;sequelize-typescript/scopes/default-scope;Member[DefaultScope].Argument[0]", + "sequelize-typescript.DefaultScopeGetter;sequelize-typescript/scopes/scope-options.DefaultScopeGetter;", + "sequelize-typescript.DefaultScopeGetter;sequelize-typescript;Member[DefaultScope].Argument[0]", + "sequelize-typescript.HasAssociation;sequelize-typescript.HasAssociationStatic;Instance", + "sequelize-typescript.HasAssociation;sequelize-typescript/associations/has/has-association.HasAssociation;", + "sequelize-typescript.HasAssociationStatic;sequelize-typescript/associations/has/has-association.HasAssociationStatic;", + "sequelize-typescript.HasAssociationStatic;sequelize-typescript/associations/has/has-association;Member[HasAssociation]", + "sequelize-typescript.HasAssociationStatic;sequelize-typescript;Member[HasAssociation]", + "sequelize-typescript.Model;sequelize-typescript.Model;Member[$add,$has,$remove,$set].Argument[1]", + "sequelize-typescript.Model;sequelize-typescript.Model;Member[$add,$has,$remove,$set].Argument[1].ArrayElement", + "sequelize-typescript.Model;sequelize-typescript.Model;Member[$create,reload].ReturnValue.Awaited", + "sequelize-typescript.Model;sequelize-typescript.ModelStatic~;Instance", + "sequelize-typescript.Model;sequelize-typescript.ModelStatic~;Member[initialize].ReturnValue.TypeVar[sequelize-typescript.ModelStatic.0]", + "sequelize-typescript.Model;sequelize-typescript.ModelType;Instance", + "sequelize-typescript.Model;sequelize-typescript.Sequelize;Member[getRepository].Argument[0].Instance", + "sequelize-typescript.Model;sequelize-typescript.Sequelize;Member[getRepository].ReturnValue.TypeVar[sequelize-typescript.Repository.0]", + "sequelize-typescript.Model;sequelize-typescript/model/model/model.Model;", + "sequelize-typescript.ModelClassGetter;sequelize-typescript.BaseAssociationStatic;Argument[0]", + "sequelize-typescript.ModelClassGetter;sequelize-typescript.BelongsToAssociationStatic;Argument[0]", + "sequelize-typescript.ModelClassGetter;sequelize-typescript.BelongsToManyAssociationStatic;Argument[0]", + "sequelize-typescript.ModelClassGetter;sequelize-typescript.HasAssociationStatic;Argument[0]", + "sequelize-typescript.ModelClassGetter;sequelize-typescript/associations/belongs-to-many/belongs-to-many;Member[BelongsToMany].Argument[0,1]", + "sequelize-typescript.ModelClassGetter;sequelize-typescript/associations/belongs-to/belongs-to;Member[BelongsTo].Argument[0]", + "sequelize-typescript.ModelClassGetter;sequelize-typescript/associations/foreign-key/foreign-key-meta.ForeignKeyMeta;Member[relatedClassGetter]", + "sequelize-typescript.ModelClassGetter;sequelize-typescript/associations/foreign-key/foreign-key-service;Member[addForeignKey].Argument[1]", + "sequelize-typescript.ModelClassGetter;sequelize-typescript/associations/foreign-key/foreign-key;Member[ForeignKey].Argument[0]", + "sequelize-typescript.ModelClassGetter;sequelize-typescript/associations/has/has-many;Member[HasMany].Argument[0]", + "sequelize-typescript.ModelClassGetter;sequelize-typescript/associations/has/has-one;Member[HasOne].Argument[0]", + "sequelize-typescript.ModelClassGetter;sequelize-typescript/model/shared/model-class-getter.ModelClassGetter;", + "sequelize-typescript.ModelClassGetter;sequelize-typescript;Member[BelongsTo,ForeignKey,HasMany,HasOne].Argument[0]", + "sequelize-typescript.ModelClassGetter;sequelize-typescript;Member[BelongsToMany].Argument[0,1]", + "sequelize-typescript.ModelStatic~;sequelize-typescript/model/model/model.ModelStatic~;", + "sequelize-typescript.ModelStatic~;sequelize-typescript/model/model/model;Member[Model]", + "sequelize-typescript.ModelStatic~;sequelize-typescript/model/shared/model-not-initialized-error.ModelNotInitializedErrorStatic;Argument[0]", + "sequelize-typescript.ModelStatic~;sequelize-typescript;Member[Model]", + "sequelize-typescript.ModelType;sequelize-typescript.BaseAssociation;Member[getAssociatedClass].ReturnValue", + "sequelize-typescript.ModelType;sequelize-typescript.BaseAssociation;Member[getSequelizeOptions].Argument[0]", + "sequelize-typescript.ModelType;sequelize-typescript.BelongsToAssociation;Member[getSequelizeOptions].Argument[0]", + "sequelize-typescript.ModelType;sequelize-typescript.BelongsToManyAssociation;Member[getSequelizeOptions].Argument[0]", + "sequelize-typescript.ModelType;sequelize-typescript.HasAssociation;Member[getSequelizeOptions].Argument[0]", + "sequelize-typescript.ModelType;sequelize-typescript.ModelClassGetter;ReturnValue", + "sequelize-typescript.ModelType;sequelize-typescript.Sequelize;Member[model].Argument[0]", + "sequelize-typescript.ModelType;sequelize-typescript/associations/foreign-key/foreign-key-service;Member[getForeignKeyOptions].Argument[0,1]", + "sequelize-typescript.ModelType;sequelize-typescript/model/model/model.ModelType;", + "sequelize-typescript.ScopeOptionsGetters;sequelize-typescript/scopes/scope-options.ScopeOptionsGetters;", + "sequelize-typescript.ScopeOptionsGetters;sequelize-typescript/scopes/scope-service;Member[addScopeOptionsGetter,setScopeOptionsGetters].Argument[1]", + "sequelize-typescript.ScopeOptionsGetters;sequelize-typescript/scopes/scope-service;Member[getScopeOptionsGetters].ReturnValue", + "sequelize-typescript.ScopeOptionsGetters;sequelize-typescript;Member[addScopeOptionsGetter,setScopeOptionsGetters].Argument[1]", + "sequelize-typescript.ScopeOptionsGetters;sequelize-typescript;Member[getScopeOptionsGetters].ReturnValue", + "sequelize-typescript.ScopesOptions;sequelize-typescript.ScopesOptionsGetter;ReturnValue.AnyMember", + "sequelize-typescript.ScopesOptions;sequelize-typescript/scopes/scope-options.ScopesOptions;", + "sequelize-typescript.ScopesOptions;sequelize-typescript/scopes/scope-service;Member[resolveScope].Argument[2]", + "sequelize-typescript.ScopesOptions;sequelize-typescript;Member[resolveScope].Argument[2]", + "sequelize-typescript.ScopesOptionsGetter;sequelize-typescript.ScopeOptionsGetters;Member[getScopes]", + "sequelize-typescript.ScopesOptionsGetter;sequelize-typescript/scopes/scope-options.ScopesOptionsGetter;", + "sequelize-typescript.ScopesOptionsGetter;sequelize-typescript/scopes/scopes;Member[Scopes].Argument[0]", + "sequelize-typescript.ScopesOptionsGetter;sequelize-typescript;Member[Scopes].Argument[0]", + "sequelize-typescript.Sequelize;sequelize-typescript.BaseAssociation;Member[getSequelizeOptions].Argument[1]", + "sequelize-typescript.Sequelize;sequelize-typescript.BelongsToManyAssociation;Member[getSequelizeOptions].Argument[1]", + "sequelize-typescript.Sequelize;sequelize-typescript.SequelizeStatic;Instance", + "sequelize-typescript.Sequelize;sequelize-typescript/sequelize/sequelize/sequelize.Sequelize;", + "sequelize-typescript.SequelizeOptions;sequelize-typescript.Sequelize;Member[options]", + "sequelize-typescript.SequelizeOptions;sequelize-typescript.SequelizeStatic;Argument[3]", + "sequelize-typescript.SequelizeOptions;sequelize-typescript.SequelizeStatic;WithArity[0].Argument[0]", + "sequelize-typescript.SequelizeOptions;sequelize-typescript.SequelizeStatic;WithArity[1].Argument[0,1]", + "sequelize-typescript.SequelizeOptions;sequelize-typescript.SequelizeStatic;WithArity[2].Argument[1,2]", + "sequelize-typescript.SequelizeOptions;sequelize-typescript.SequelizeStatic;WithArity[3].Argument[2]", + "sequelize-typescript.SequelizeOptions;sequelize-typescript/sequelize/sequelize/sequelize-options.SequelizeOptions;", + "sequelize-typescript.SequelizeOptions;sequelize-typescript/sequelize/sequelize/sequelize-service;Member[prepareArgs].ReturnValue.Member[options]", + "sequelize-typescript.SequelizeOptions;sequelize-typescript/sequelize/sequelize/sequelize-service;Member[prepareOptions].Argument[0]", + "sequelize-typescript.SequelizeOptions;sequelize-typescript/sequelize/sequelize/sequelize-service;Member[prepareOptions].ReturnValue", + "sequelize-typescript.SequelizeOptions;sequelize-typescript;Member[prepareArgs].ReturnValue.Member[options]", + "sequelize-typescript.SequelizeOptions;sequelize-typescript;Member[prepareOptions].Argument[0]", + "sequelize-typescript.SequelizeOptions;sequelize-typescript;Member[prepareOptions].ReturnValue", + "sequelize-typescript.SequelizeStatic;sequelize-typescript/sequelize/sequelize/sequelize.SequelizeStatic;", + "sequelize-typescript.SequelizeStatic;sequelize-typescript/sequelize/sequelize/sequelize;Member[Sequelize]", + "sequelize-typescript.SequelizeStatic;sequelize-typescript;Member[Sequelize]", + "sequelize-typescript/associations/foreign-key/foreign-key-meta.ForeignKeyMeta;sequelize-typescript/associations/foreign-key/foreign-key-service;Member[getForeignKeys].ReturnValue.ArrayElement", + "sequelize-typescript/model/model/association/association-create-options.AssociationCreateOptions;sequelize-typescript.Model;Member[$create].Argument[2]", + "sequelize-typescript/model/shared/model-not-initialized-error.ModelNotInitializedErrorStatic;sequelize-typescript/model/shared/model-not-initialized-error;Member[ModelNotInitializedError]", + "sequelize.AnyFindOptions;sequelize.BelongsToManyAddAssociationMixin;Argument[1]", + "sequelize.AnyFindOptions;sequelize.BelongsToManyAddAssociationsMixin;Argument[1]", + "sequelize.AnyFindOptions;sequelize.BelongsToManySetAssociationsMixin;Argument[1]", + "sequelize.AnyFindOptions;sequelize.DefineOptions;Member[defaultScope]", + "sequelize.AnyFindOptions;sequelize.DefineScopeOptions;AnyMember", + "sequelize.AnyFindOptions;sequelize.HasManySetAssociationsMixin;Argument[1]", + "sequelize.AnyFindOptions;sequelize.Instance;Member[reload].Argument[0]", + "sequelize.AnyFindOptions;sequelize.Model;Member[addScope].Argument[1]", + "sequelize.AssociationOptionsBelongsToMany;sequelize.Associations;Member[belongsToMany].Argument[1]", + "sequelize.Associations;sequelize.Model;", + "sequelize.Associations;sequelize.SequelizeStaticAndInstance.Model;", + "sequelize.BuildOptions;sequelize-typescript.ModelStatic~;Argument[1]", + "sequelize.BuildOptions;sequelize.CreateOptions;", + "sequelize.BuildOptions;sequelize.Model;Member[build,bulkBuild].Argument[1]", + "sequelize.CountOptions;sequelize.Model;Member[count].Argument[0]", + "sequelize.CreateOptions;sequelize-typescript/model/model/association/association-create-options.AssociationCreateOptions;", + "sequelize.CreateOptions;sequelize.BelongsToCreateAssociationMixin;Argument[1]", + "sequelize.CreateOptions;sequelize.BelongsToManyCreateAssociationMixin;Argument[1]", + "sequelize.CreateOptions;sequelize.HasManyCreateAssociationMixin;Argument[1]", + "sequelize.CreateOptions;sequelize.HasOneCreateAssociationMixin;Argument[1]", + "sequelize.CreateOptions;sequelize.Model;Member[create].Argument[1]", + "sequelize.DefineAttributeColumnOptions;sequelize.DefineAttributes;AnyMember", + "sequelize.DefineAttributeColumnOptions;sequelize.QueryInterface;Member[addColumn,changeColumn].Argument[2]", + "sequelize.DefineAttributeColumnReferencesOptions;sequelize.DefineAttributeColumnOptions;Member[references]", + "sequelize.DefineAttributes;sequelize.Hooks;Member[beforeDefine].Argument[1].Argument[0]", + "sequelize.DefineAttributes;sequelize.Hooks;Member[beforeDefine].WithArity[1].Argument[0].Argument[0]", + "sequelize.DefineAttributes;sequelize.QueryInterface;Member[createTable].Argument[1]", + "sequelize.DefineOptions;sequelize.Options;Member[define]", + "sequelize.DefineOptions;sequelize.Sequelize;Member[define].Argument[2]", + "sequelize.DefineScopeOptions;sequelize.DefineOptions;Member[scopes]", + "sequelize.FindCreateFindOptions;sequelize.Model;Member[findCreateFind].Argument[0]", + "sequelize.FindOptions;sequelize-typescript.AssociationCountOptions;", + "sequelize.FindOptions;sequelize-typescript.AssociationGetOptions;", + "sequelize.FindOptions;sequelize-typescript.DefaultScopeGetter;ReturnValue", + "sequelize.FindOptions;sequelize-typescript.Model;Member[reload].Argument[0]", + "sequelize.FindOptions;sequelize-typescript.ScopesOptions;", + "sequelize.FindOptions;sequelize-typescript.ScopesOptions;ReturnValue", + "sequelize.FindOptions;sequelize.AnyFindOptions;", + "sequelize.FindOptions;sequelize.FindCreateFindOptions;", + "sequelize.FindOptions;sequelize.FindOrInitializeOptions;", + "sequelize.FindOptions;sequelize.Model;Member[all,find,findAll,findAndCount,findAndCountAll,findOne].Argument[0]", + "sequelize.FindOptionsOrderArray;sequelize.FindOptions;Member[order]", + "sequelize.FindOptionsOrderArray;sequelize.FindOptions;Member[order].ArrayElement", + "sequelize.FindOrInitializeOptions;sequelize.Model;Member[findOrBuild,findOrCreate,findOrInitialize].Argument[0]", + "sequelize.HasManyGetAssociationsMixinOptions;sequelize.HasManyGetAssociationsMixin;Argument[0]", + "sequelize.HasManyGetAssociationsMixinOptions;sequelize.HasManyHasAssociationMixin;Argument[1]", + "sequelize.HasManyGetAssociationsMixinOptions;sequelize.HasManyHasAssociationsMixin;Argument[1]", + "sequelize.Hooks;sequelize.Hooks;Member[addHook,hook,removeHook].ReturnValue", + "sequelize.Hooks;sequelize.Model;", + "sequelize.Hooks;sequelize.Sequelize;", + "sequelize.Hooks;sequelize.SequelizeStaticAndInstance.Model;", + "sequelize.IncludeAssociation;sequelize.Associations;Member[belongsTo,belongsToMany,hasMany,hasOne].ReturnValue", + "sequelize.IncludeAssociation;sequelize.IncludeOptions;Member[association]", + "sequelize.IncludeOptions;sequelize.BuildOptions;Member[include].ArrayElement", + "sequelize.IncludeOptions;sequelize.CountOptions;Member[include]", + "sequelize.IncludeOptions;sequelize.CountOptions;Member[include].ArrayElement", + "sequelize.IncludeOptions;sequelize.FindOptions;Member[include]", + "sequelize.IncludeOptions;sequelize.FindOptions;Member[include].ArrayElement", + "sequelize.IncludeOptions;sequelize.HasManyGetAssociationsMixinOptions;Member[include]", + "sequelize.IncludeOptions;sequelize.IncludeOptions;Member[include]", + "sequelize.IncludeOptions;sequelize.IncludeOptions;Member[include].ArrayElement", + "sequelize.Instance;sequelize.Instance;Member[decrement,increment,reload,save,update,updateAttributes].ReturnValue.Awaited", + "sequelize.Instance;sequelize.Instance;Member[equalsOneOf].Argument[0].ArrayElement", + "sequelize.Instance;sequelize.Instance;Member[equals].Argument[0]", + "sequelize.Instance;sequelize.Instance;Member[set,setAttributes].ReturnValue", + "sequelize.Instance;sequelize.Model;Member[Instance,build].ReturnValue", + "sequelize.Instance;sequelize.Model;Member[all,bulkCreate,findAll].ReturnValue.Awaited.ArrayElement", + "sequelize.Instance;sequelize.Model;Member[bulkBuild].ReturnValue.ArrayElement", + "sequelize.Instance;sequelize.Model;Member[create,find,findById,findByPk,findByPrimary,findOne].ReturnValue.Awaited", + "sequelize.Instance;sequelize.Model;Member[findAndCount,findAndCountAll].ReturnValue.Awaited.Member[rows].ArrayElement", + "sequelize.Instance;sequelize.QueryInterface;Member[delete,increment,insert,update].Argument[0]", + "sequelize.Instance;sequelize.QueryOptions;Member[instance]", + "sequelize.Instance;sequelize.SequelizeStaticAndInstance;Member[Instance]", + "sequelize.Model;sequelize.AssociationOptionsBelongsToMany;Member[through]", + "sequelize.Model;sequelize.Associations;Member[belongsTo,belongsToMany,hasMany,hasOne].Argument[0]", + "sequelize.Model;sequelize.BuildOptions;Member[include].ArrayElement", + "sequelize.Model;sequelize.CountOptions;Member[include]", + "sequelize.Model;sequelize.CountOptions;Member[include].ArrayElement", + "sequelize.Model;sequelize.DefineAttributeColumnReferencesOptions;Member[model]", + "sequelize.Model;sequelize.FindOptions;Member[include]", + "sequelize.Model;sequelize.FindOptions;Member[include].ArrayElement", + "sequelize.Model;sequelize.FindOptions;Member[lock].Member[of]", + "sequelize.Model;sequelize.FindOptionsOrderArray;ArrayElement", + "sequelize.Model;sequelize.FindOptionsOrderArray;ArrayElement.Member[model]", + "sequelize.Model;sequelize.Hooks;Member[afterDefine].Argument[1].Argument[0]", + "sequelize.Model;sequelize.Hooks;Member[afterDefine].WithArity[1].Argument[0].Argument[0]", + "sequelize.Model;sequelize.IncludeAssociation;Member[source,target]", + "sequelize.Model;sequelize.IncludeOptions;Member[include,model]", + "sequelize.Model;sequelize.IncludeOptions;Member[include].ArrayElement", + "sequelize.Model;sequelize.Instance;Member[Model]", + "sequelize.Model;sequelize.Model;Member[schema,scope,unscoped].ReturnValue", + "sequelize.Model;sequelize.Model;Member[sync].ReturnValue.Awaited", + "sequelize.Model;sequelize.Models;AnyMember", + "sequelize.Model;sequelize.ModelsHashInterface;AnyMember", + "sequelize.Model;sequelize.QueryInterface;Member[bulkDelete,rawSelect,upsert].Argument[3]", + "sequelize.Model;sequelize.QueryInterface;Member[select].Argument[0]", + "sequelize.Model;sequelize.QueryOptions;Member[model]", + "sequelize.Model;sequelize.Sequelize;Member[define,import,model].ReturnValue", + "sequelize.Model;sequelize.Sequelize;Member[import].Argument[1].ReturnValue", + "sequelize.Model;sequelize.SequelizeStaticAndInstance;Member[Model]", + "sequelize.Model;sequelize.ThroughOptions;Member[model]", + "sequelize.Model;sequelize.Utils;Member[mapOptionFieldNames].Argument[1]", + "sequelize.Model;sequelize.Utils;Member[mapValueFieldNames].Argument[2]", + "sequelize.Models;sequelize.Model;Member[associate].Argument[0]", + "sequelize.ModelsHashInterface;sequelize.Sequelize;Member[models]", + "sequelize.Options;sequelize-typescript.SequelizeOptions;", + "sequelize.Options;sequelize.Sequelize;Member[options]", + "sequelize.Options;sequelize.SequelizeStatic;Argument[3]", + "sequelize.Options;sequelize.SequelizeStatic;WithArity[1].Argument[0,1]", + "sequelize.Options;sequelize.SequelizeStatic;WithArity[2].Argument[1,2]", + "sequelize.Options;sequelize.SequelizeStatic;WithArity[3].Argument[2]", + "sequelize.QueryInterface;sequelize.Sequelize;Member[getQueryInterface].ReturnValue", + "sequelize.QueryOptions;sequelize.Options;Member[query]", + "sequelize.QueryOptions;sequelize.QueryInterface;Member[bulkDelete,bulkInsert,createTable,select,setAutocommit,setIsolationLevel].Argument[2]", + "sequelize.QueryOptions;sequelize.QueryInterface;Member[bulkUpdate,delete,insert].Argument[3]", + "sequelize.QueryOptions;sequelize.QueryInterface;Member[commitTransaction,deferConstraints,dropTable,rawSelect,rollbackTransaction,showIndex,startTransaction].Argument[1]", + "sequelize.QueryOptions;sequelize.QueryInterface;Member[createFunction].Argument[5]", + "sequelize.QueryOptions;sequelize.QueryInterface;Member[dropAllEnums,dropAllTables,showAllSchemas,showAllTables].Argument[0]", + "sequelize.QueryOptions;sequelize.QueryInterface;Member[increment,update,upsert].Argument[4]", + "sequelize.QueryOptions;sequelize.Sequelize;Member[authenticate,validate].Argument[0]", + "sequelize.QueryOptions;sequelize.Sequelize;Member[query].Argument[1]", + "sequelize.Sequelize;sequelize.Hooks;Member[afterInit].Argument[1].Argument[0]", + "sequelize.Sequelize;sequelize.Hooks;Member[afterInit].WithArity[1].Argument[0].Argument[0]", + "sequelize.Sequelize;sequelize.Instance;Member[sequelize]", + "sequelize.Sequelize;sequelize.QueryInterface;Member[sequelize]", + "sequelize.Sequelize;sequelize.Sequelize;Member[import].Argument[1].Argument[0]", + "sequelize.Sequelize;sequelize.SequelizeStatic;Instance", + "sequelize.Sequelize;sequelize.SequelizeStatic;Member[useCLS].ReturnValue", + "sequelize.SequelizeStatic;sequelize-typescript.Sequelize;", + "sequelize.SequelizeStatic;sequelize.Sequelize;Member[Sequelize]", + "sequelize.SequelizeStatic;sequelize.SequelizeStatic;Member[Sequelize,default]", + "sequelize.SequelizeStatic;sequelize;", + "sequelize.SequelizeStaticAndInstance.Model;sequelize-typescript.Model;", + "sequelize.SequelizeStaticAndInstance;sequelize.Sequelize;", + "sequelize.SequelizeStaticAndInstance;sequelize.SequelizeStatic;", + "sequelize.ThroughOptions;sequelize.AssociationOptionsBelongsToMany;Member[through]", + "sequelize.Utils;sequelize.SequelizeStaticAndInstance;Member[Utils]" ], "summaries": [ - "sequelize-typescript;Model;;;Member[reload].ReturnValue.Awaited;type", - "sequelize;Instance;;;Member[decrement,increment,reload,save,update,updateAttributes].ReturnValue.Awaited;type", - "sequelize;Instance;;;Member[set,setAttributes].ReturnValue;type", - "sequelize;Model;;;Member[schema,scope,unscoped].ReturnValue;type", - "sequelize;Model;;;Member[sync].ReturnValue.Awaited;type" + "sequelize-typescript.Model;;;Member[reload].ReturnValue.Awaited;type", + "sequelize.Instance;;;Member[decrement,increment,reload,save,update,updateAttributes].ReturnValue.Awaited;type", + "sequelize.Instance;;;Member[set,setAttributes].ReturnValue;type", + "sequelize.Model;;;Member[schema,scope,unscoped].ReturnValue;type", + "sequelize.Model;;;Member[sync].ReturnValue.Awaited;type" ], "typeVariables": [ "sequelize-typescript.ModelStatic.0;Instance", diff --git a/javascript/ql/lib/semmle/javascript/frameworks/spanner/Model.qll b/javascript/ql/lib/semmle/javascript/frameworks/spanner/Model.qll index f99266b6e54..630fa5ea8c9 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/spanner/Model.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/spanner/Model.qll @@ -6,180 +6,180 @@ private class Types extends ModelInput::TypeModelCsv { override predicate row(string row) { row = [ - "@google-cloud/spanner/batch-transaction;BatchTransaction;@google-cloud/spanner/batch-transaction;BatchTransactionStatic;Instance", // - "@google-cloud/spanner/batch-transaction;BatchTransaction;@google-cloud/spanner/database;CreateBatchTransactionCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0]", // - "@google-cloud/spanner/batch-transaction;BatchTransaction;@google-cloud/spanner;Database;Member[batchTransaction].ReturnValue", // - "@google-cloud/spanner/batch-transaction;BatchTransactionStatic;@google-cloud/spanner/batch-transaction;;Member[BatchTransaction]", // - "@google-cloud/spanner/batch-transaction;TransactionIdentifier;@google-cloud/spanner/batch-transaction;BatchTransaction;Member[identifier].ReturnValue", // - "@google-cloud/spanner/batch-transaction;TransactionIdentifier;@google-cloud/spanner;Database;Member[batchTransaction].Argument[0]", // - "@google-cloud/spanner/database;BatchCreateSessionsCallback;@google-cloud/spanner;Database;Member[batchCreateSessions].Argument[1]", // - "@google-cloud/spanner/database;CreateBatchTransactionCallback;@google-cloud/spanner;Database;Member[createBatchTransaction].Argument[1]", // - "@google-cloud/spanner/database;CreateBatchTransactionCallback;@google-cloud/spanner;Database;Member[createBatchTransaction].WithArity[1].Argument[0]", // - "@google-cloud/spanner/database;CreateSessionCallback;@google-cloud/spanner;Database;Member[createSession].Argument[1]", // - "@google-cloud/spanner/database;CreateSessionCallback;@google-cloud/spanner;Database;Member[createSession].WithArity[1].Argument[0]", // - "@google-cloud/spanner/database;DatabaseCallback;@google-cloud/spanner;Database;Member[get].Argument[1]", // - "@google-cloud/spanner/database;DatabaseCallback;@google-cloud/spanner;Database;Member[get].WithArity[1].Argument[0]", // - "@google-cloud/spanner/database;GetSessionsCallback;@google-cloud/spanner;Database;Member[getSessions].Argument[1]", // - "@google-cloud/spanner/database;GetSessionsCallback;@google-cloud/spanner;Database;Member[getSessions].WithArity[1].Argument[0]", // - "@google-cloud/spanner/database;GetSnapshotCallback;@google-cloud/spanner;Database;Member[getSnapshot].Argument[1]", // - "@google-cloud/spanner/database;GetSnapshotCallback;@google-cloud/spanner;Database;Member[getSnapshot].WithArity[1].Argument[0]", // - "@google-cloud/spanner/database;GetTransactionCallback;@google-cloud/spanner;Database;Member[getTransaction].Argument[0]", // - "@google-cloud/spanner/database;PoolRequestCallback;@google-cloud/spanner;Database;Member[makePooledRequest_].Argument[1]", // - "@google-cloud/spanner/database;RestoreDatabaseCallback;@google-cloud/spanner;Database;Member[restore].Argument[1,2]", // - "@google-cloud/spanner/database;SessionPoolConstructor;@google-cloud/spanner;DatabaseStatic;Argument[2]", // - "@google-cloud/spanner/database;SessionPoolConstructor;@google-cloud/spanner;Instance;Member[database].Argument[1]", // - "@google-cloud/spanner/instance;CreateDatabaseCallback;@google-cloud/spanner;Instance;Member[createDatabase].Argument[2]", // - "@google-cloud/spanner/instance;CreateDatabaseCallback;@google-cloud/spanner;Instance;Member[createDatabase].WithArity[2].Argument[1]", // - "@google-cloud/spanner/instance;CreateDatabaseOptions;@google-cloud/spanner;Instance;Member[createDatabase].WithArity[1,2,3].Argument[1]", // - "@google-cloud/spanner/instance;CreateInstanceCallback;@google-cloud/spanner;Spanner;Member[createInstance].Argument[2]", // - "@google-cloud/spanner/instance;GetDatabasesCallback;@google-cloud/spanner;Instance;Member[getDatabases].Argument[1]", // - "@google-cloud/spanner/instance;GetDatabasesCallback;@google-cloud/spanner;Instance;Member[getDatabases].WithArity[1].Argument[0]", // - "@google-cloud/spanner/instance;GetInstanceCallback;@google-cloud/spanner;Instance;Member[get].Argument[1]", // - "@google-cloud/spanner/instance;GetInstanceCallback;@google-cloud/spanner;Instance;Member[get].WithArity[1].Argument[0]", // - "@google-cloud/spanner/session-pool;GetReadSessionCallback;@google-cloud/spanner/session-pool;SessionPoolInterface;Member[getReadSession].Argument[0]", // - "@google-cloud/spanner/session-pool;GetReadSessionCallback;@google-cloud/spanner;SessionPool;Member[getReadSession].Argument[0]", // - "@google-cloud/spanner/session-pool;GetWriteSessionCallback;@google-cloud/spanner/session-pool;SessionPoolInterface;Member[getWriteSession].Argument[0]", // - "@google-cloud/spanner/session-pool;GetWriteSessionCallback;@google-cloud/spanner;SessionPool;Member[getWriteSession].Argument[0]", // - "@google-cloud/spanner/session-pool;SessionPoolInterface;@google-cloud/spanner/database;SessionPoolConstructor;Instance", // - "@google-cloud/spanner/session-pool;SessionPoolInterface;@google-cloud/spanner;Database;Member[pool_]", // - "@google-cloud/spanner/session-pool;SessionPoolInterface;@google-cloud/spanner;SessionPool;", // - "@google-cloud/spanner/table;CreateTableCallback;@google-cloud/spanner;Database;Member[createTable].Argument[2]", // - "@google-cloud/spanner/table;CreateTableCallback;@google-cloud/spanner;Database;Member[createTable].WithArity[2].Argument[1]", // - "@google-cloud/spanner/table;CreateTableCallback;@google-cloud/spanner;Table;Member[create].Argument[2]", // - "@google-cloud/spanner/table;CreateTableCallback;@google-cloud/spanner;Table;Member[create].WithArity[2].Argument[1]", // - "@google-cloud/spanner/transaction-runner;AsyncRunTransactionCallback;@google-cloud/spanner/transaction-runner;AsyncTransactionRunnerStatic;Argument[2]", // - "@google-cloud/spanner/transaction-runner;AsyncRunTransactionCallback;@google-cloud/spanner;Database;Member[runTransactionAsync].Argument[1]", // - "@google-cloud/spanner/transaction-runner;AsyncRunTransactionCallback;@google-cloud/spanner;Database;Member[runTransactionAsync].WithArity[1].Argument[0]", // - "@google-cloud/spanner/transaction-runner;AsyncTransactionRunner;@google-cloud/spanner/transaction-runner;AsyncTransactionRunnerStatic;Instance", // - "@google-cloud/spanner/transaction-runner;AsyncTransactionRunnerStatic;@google-cloud/spanner/transaction-runner;;Member[AsyncTransactionRunner]", // - "@google-cloud/spanner/transaction-runner;RunTransactionCallback;@google-cloud/spanner/transaction-runner;TransactionRunnerStatic;Argument[2]", // - "@google-cloud/spanner/transaction-runner;RunTransactionCallback;@google-cloud/spanner;Database;Member[runTransaction].Argument[1]", // - "@google-cloud/spanner/transaction-runner;RunTransactionCallback;@google-cloud/spanner;Database;Member[runTransaction].WithArity[1].Argument[0]", // - "@google-cloud/spanner/transaction-runner;Runner;@google-cloud/spanner/transaction-runner;AsyncTransactionRunner;", // - "@google-cloud/spanner/transaction-runner;Runner;@google-cloud/spanner/transaction-runner;RunnerStatic;Instance", // - "@google-cloud/spanner/transaction-runner;Runner;@google-cloud/spanner/transaction-runner;TransactionRunner;", // - "@google-cloud/spanner/transaction-runner;RunnerStatic;@google-cloud/spanner/transaction-runner;;Member[Runner]", // - "@google-cloud/spanner/transaction-runner;TransactionRunner;@google-cloud/spanner/transaction-runner;TransactionRunnerStatic;Instance", // - "@google-cloud/spanner/transaction-runner;TransactionRunnerStatic;@google-cloud/spanner/transaction-runner;;Member[TransactionRunner]", // - "@google-cloud/spanner/transaction;Dml;@google-cloud/spanner/transaction;DmlStatic;Instance", // - "@google-cloud/spanner/transaction;Dml;@google-cloud/spanner;PartitionedDml;", // - "@google-cloud/spanner/transaction;Dml;@google-cloud/spanner;Transaction;", // - "@google-cloud/spanner/transaction;DmlStatic;@google-cloud/spanner/transaction;;Member[Dml]", // - "@google-cloud/spanner;BackupStatic;@google-cloud/spanner/backup;;Member[Backup]", // - "@google-cloud/spanner;BackupStatic;@google-cloud/spanner/backup;BackupStatic;", // - "@google-cloud/spanner;BackupStatic;@google-cloud/spanner;;Member[Backup]", // - "@google-cloud/spanner;BatchTransaction;@google-cloud/spanner/batch-transaction;BatchTransaction;", // - "@google-cloud/spanner;Database;@google-cloud/spanner/database;Database;", // - "@google-cloud/spanner;Database;@google-cloud/spanner/database;DatabaseCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0]", // - "@google-cloud/spanner;Database;@google-cloud/spanner/database;RestoreDatabaseCallback;TypeVar[@google-cloud/spanner/common.LongRunningCallback.0]", // - "@google-cloud/spanner;Database;@google-cloud/spanner/database;SessionPoolConstructor;Argument[0]", // - "@google-cloud/spanner;Database;@google-cloud/spanner/instance;CreateDatabaseCallback;TypeVar[@google-cloud/spanner/common.LongRunningCallback.0]", // - "@google-cloud/spanner;Database;@google-cloud/spanner/instance;GetDatabasesCallback;TypeVar[@google-cloud/spanner/common.RequestCallback.0]", // - "@google-cloud/spanner;Database;@google-cloud/spanner;DatabaseStatic;Instance", // - "@google-cloud/spanner;Database;@google-cloud/spanner;Instance;Member[database].ReturnValue", // - "@google-cloud/spanner;Database;@google-cloud/spanner;SessionPool;Member[database]", // - "@google-cloud/spanner;Database;@google-cloud/spanner;SessionPoolStatic;Argument[0]", // - "@google-cloud/spanner;Database;@google-cloud/spanner;SessionStatic;Argument[0]", // - "@google-cloud/spanner;Database;@google-cloud/spanner;Table;Member[database]", // - "@google-cloud/spanner;Database;@google-cloud/spanner;TableStatic;Argument[0]", // - "@google-cloud/spanner;DatabaseStatic;@google-cloud/spanner/database;;Member[Database]", // - "@google-cloud/spanner;DatabaseStatic;@google-cloud/spanner/database;DatabaseStatic;", // - "@google-cloud/spanner;DatabaseStatic;@google-cloud/spanner;;Member[Database]", // - "@google-cloud/spanner;GetInstancesCallback;@google-cloud/spanner/build/src;GetInstancesCallback;", // - "@google-cloud/spanner;GetInstancesCallback;@google-cloud/spanner;Spanner;Member[getInstances].Argument[1]", // - "@google-cloud/spanner;GetInstancesCallback;@google-cloud/spanner;Spanner;Member[getInstances].WithArity[1].Argument[0]", // - "@google-cloud/spanner;Instance;@google-cloud/spanner/instance;CreateInstanceCallback;TypeVar[@google-cloud/spanner/common.LongRunningCallback.0]", // - "@google-cloud/spanner;Instance;@google-cloud/spanner/instance;GetInstanceCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0]", // - "@google-cloud/spanner;Instance;@google-cloud/spanner/instance;Instance;", // - "@google-cloud/spanner;Instance;@google-cloud/spanner;BackupStatic;Argument[0]", // - "@google-cloud/spanner;Instance;@google-cloud/spanner;DatabaseStatic;Argument[0]", // - "@google-cloud/spanner;Instance;@google-cloud/spanner;GetInstancesCallback;TypeVar[@google-cloud/spanner/common.PagedCallback.0]", // - "@google-cloud/spanner;Instance;@google-cloud/spanner;InstanceStatic;Instance", // - "@google-cloud/spanner;Instance;@google-cloud/spanner;Spanner;Member[instance].ReturnValue", // - "@google-cloud/spanner;InstanceStatic;@google-cloud/spanner/instance;;Member[Instance]", // - "@google-cloud/spanner;InstanceStatic;@google-cloud/spanner/instance;InstanceStatic;", // - "@google-cloud/spanner;InstanceStatic;@google-cloud/spanner;;Member[Instance]", // - "@google-cloud/spanner;PartitionedDml;@google-cloud/spanner/transaction;PartitionedDml;", // - "@google-cloud/spanner;PartitionedDml;@google-cloud/spanner;PartitionedDmlStatic;Instance", // - "@google-cloud/spanner;PartitionedDml;@google-cloud/spanner;Session;Member[partitionedDml].ReturnValue", // - "@google-cloud/spanner;PartitionedDmlStatic;@google-cloud/spanner/transaction;;Member[PartitionedDml]", // - "@google-cloud/spanner;PartitionedDmlStatic;@google-cloud/spanner/transaction;PartitionedDmlStatic;", // - "@google-cloud/spanner;PartitionedDmlStatic;@google-cloud/spanner;;Member[PartitionedDml]", // - "@google-cloud/spanner;Session;@google-cloud/spanner/batch-transaction;TransactionIdentifier;Member[session]", // - "@google-cloud/spanner;Session;@google-cloud/spanner/database;BatchCreateSessionsCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0].ArrayElement", // - "@google-cloud/spanner;Session;@google-cloud/spanner/database;CreateSessionCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0]", // - "@google-cloud/spanner;Session;@google-cloud/spanner/database;GetSessionsCallback;TypeVar[@google-cloud/spanner/common.RequestCallback.0]", // - "@google-cloud/spanner;Session;@google-cloud/spanner/database;PoolRequestCallback;TypeVar[@google-cloud/spanner/common.RequestCallback.0]", // - "@google-cloud/spanner;Session;@google-cloud/spanner/session-pool;GetReadSessionCallback;TypeVar[@google-cloud/spanner/common.NormalCallback.0]", // - "@google-cloud/spanner;Session;@google-cloud/spanner/session-pool;GetWriteSessionCallback;Argument[1]", // - "@google-cloud/spanner;Session;@google-cloud/spanner/session-pool;SessionPoolInterface;Member[release].Argument[0]", // - "@google-cloud/spanner;Session;@google-cloud/spanner/session;Session;", // - "@google-cloud/spanner;Session;@google-cloud/spanner/transaction-runner;Runner;Member[session]", // - "@google-cloud/spanner;Session;@google-cloud/spanner;Database;Member[_runPartitionedUpdate].Argument[0]", // - "@google-cloud/spanner;Session;@google-cloud/spanner;Database;Member[makePooledRequest_].WithArity[1].ReturnValue.Awaited", // - "@google-cloud/spanner;Session;@google-cloud/spanner;Database;Member[session].ReturnValue", // - "@google-cloud/spanner;Session;@google-cloud/spanner;SessionPool;Member[_acquire,_getSession].ReturnValue.Awaited", // - "@google-cloud/spanner;Session;@google-cloud/spanner;SessionPool;Member[_borrow,_destroy,_isValidSession,_ping,_prepareTransaction,_release,release].Argument[0]", // - "@google-cloud/spanner;Session;@google-cloud/spanner;SessionPool;Member[_borrowFrom,_borrowNextAvailableSession].ReturnValue", // - "@google-cloud/spanner;Session;@google-cloud/spanner;SessionPool;Member[_getIdleSessions].ReturnValue.ArrayElement", // - "@google-cloud/spanner;Session;@google-cloud/spanner;SessionStatic;Instance", // - "@google-cloud/spanner;Session;@google-cloud/spanner;Snapshot;Member[session]", // - "@google-cloud/spanner;SessionPool;@google-cloud/spanner/instance;CreateDatabaseOptions;Member[poolCtor]", // - "@google-cloud/spanner;SessionPool;@google-cloud/spanner/session-pool;SessionPool;", // - "@google-cloud/spanner;SessionPool;@google-cloud/spanner;SessionPoolStatic;Instance", // - "@google-cloud/spanner;SessionPoolStatic;@google-cloud/spanner/session-pool;;Member[SessionPool]", // - "@google-cloud/spanner;SessionPoolStatic;@google-cloud/spanner/session-pool;SessionPoolStatic;", // - "@google-cloud/spanner;SessionPoolStatic;@google-cloud/spanner;;Member[SessionPool]", // - "@google-cloud/spanner;SessionStatic;@google-cloud/spanner/session;;Member[Session]", // - "@google-cloud/spanner;SessionStatic;@google-cloud/spanner/session;SessionStatic;", // - "@google-cloud/spanner;SessionStatic;@google-cloud/spanner;;Member[Session]", // - "@google-cloud/spanner;Snapshot;@google-cloud/spanner/batch-transaction;BatchTransaction;", // - "@google-cloud/spanner;Snapshot;@google-cloud/spanner/database;GetSnapshotCallback;TypeVar[@google-cloud/spanner/common.NormalCallback.0]", // - "@google-cloud/spanner;Snapshot;@google-cloud/spanner/transaction;Dml;", // - "@google-cloud/spanner;Snapshot;@google-cloud/spanner/transaction;Snapshot;", // - "@google-cloud/spanner;Snapshot;@google-cloud/spanner;Session;Member[snapshot].ReturnValue", // - "@google-cloud/spanner;Snapshot;@google-cloud/spanner;SnapshotStatic;Instance", // - "@google-cloud/spanner;SnapshotStatic;@google-cloud/spanner/transaction;;Member[Snapshot]", // - "@google-cloud/spanner;SnapshotStatic;@google-cloud/spanner/transaction;SnapshotStatic;", // - "@google-cloud/spanner;SnapshotStatic;@google-cloud/spanner;;Member[Snapshot]", // - "@google-cloud/spanner;Spanner;@google-cloud/spanner;InstanceStatic;Argument[0]", // - "@google-cloud/spanner;Spanner;@google-cloud/spanner;SpannerStatic;Instance", // - "@google-cloud/spanner;SpannerStatic;@google-cloud/spanner;;Member[Spanner]", // - "@google-cloud/spanner;Table;@google-cloud/spanner/table;CreateTableCallback;TypeVar[@google-cloud/spanner/common.LongRunningCallback.0]", // - "@google-cloud/spanner;Table;@google-cloud/spanner/table;Table;", // - "@google-cloud/spanner;Table;@google-cloud/spanner;Database;Member[table].ReturnValue", // - "@google-cloud/spanner;Table;@google-cloud/spanner;TableStatic;Instance", // - "@google-cloud/spanner;TableStatic;@google-cloud/spanner/table;;Member[Table]", // - "@google-cloud/spanner;TableStatic;@google-cloud/spanner/table;TableStatic;", // - "@google-cloud/spanner;TableStatic;@google-cloud/spanner;;Member[Table]", // - "@google-cloud/spanner;Transaction;@google-cloud/spanner/database;GetTransactionCallback;TypeVar[@google-cloud/spanner/common.NormalCallback.0]", // - "@google-cloud/spanner;Transaction;@google-cloud/spanner/session-pool;GetWriteSessionCallback;Argument[2]", // - "@google-cloud/spanner;Transaction;@google-cloud/spanner/transaction-runner;AsyncRunTransactionCallback;Argument[0]", // - "@google-cloud/spanner;Transaction;@google-cloud/spanner/transaction-runner;RunTransactionCallback;TypeVar[@google-cloud/spanner/common.NormalCallback.0]", // - "@google-cloud/spanner;Transaction;@google-cloud/spanner/transaction-runner;Runner;Member[getTransaction].ReturnValue.Awaited", // - "@google-cloud/spanner;Transaction;@google-cloud/spanner/transaction-runner;Runner;Member[transaction]", // - "@google-cloud/spanner;Transaction;@google-cloud/spanner/transaction;Transaction;", // - "@google-cloud/spanner;Transaction;@google-cloud/spanner;Session;Member[transaction].ReturnValue", // - "@google-cloud/spanner;Transaction;@google-cloud/spanner;Session;Member[txn]", // - "@google-cloud/spanner;Transaction;@google-cloud/spanner;TransactionStatic;Instance", // - "@google-cloud/spanner;TransactionStatic;@google-cloud/spanner/transaction;;Member[Transaction]", // - "@google-cloud/spanner;TransactionStatic;@google-cloud/spanner/transaction;TransactionStatic;", // - "@google-cloud/spanner;TransactionStatic;@google-cloud/spanner;;Member[Transaction]", // - "@google-cloud/spanner;v1.SpannerClient;@google-cloud/spanner/v1/spanner_client;SpannerClient;", // - "@google-cloud/spanner;v1.SpannerClient;@google-cloud/spanner;v1.SpannerClientStatic;Instance", // - "@google-cloud/spanner;v1.SpannerClientStatic;@google-cloud/spanner/v1/spanner_client;;Member[SpannerClient]", // - "@google-cloud/spanner;v1.SpannerClientStatic;@google-cloud/spanner/v1/spanner_client;SpannerClientStatic;", // - "@google-cloud/spanner;v1.SpannerClientStatic;@google-cloud/spanner;;Member[v1].Member[SpannerClient]", // - "@google-cloud/spanner;~SpannerObject;@google-cloud/spanner;Database;", // - "@google-cloud/spanner;~SpannerObject;@google-cloud/spanner;Snapshot;", // - "@google-cloud/spanner;~SpannerObject;@google-cloud/spanner;Transaction;", // - "@google-cloud/spanner;~SpannerObject;@google-cloud/spanner;v1.SpannerClient;", // - "@google-cloud/spanner;~SqlExecutorDirect;@google-cloud/spanner;BatchTransaction;Member[createQueryPartitions]", // - "@google-cloud/spanner;~SqlExecutorDirect;@google-cloud/spanner;Database;Member[run,runPartitionedUpdate,runStream]", // - "@google-cloud/spanner;~SqlExecutorDirect;@google-cloud/spanner;PartitionedDml;Member[runUpdate]", // - "@google-cloud/spanner;~SqlExecutorDirect;@google-cloud/spanner;Snapshot;Member[run,runStream]", // - "@google-cloud/spanner;~SqlExecutorDirect;@google-cloud/spanner;Transaction;Member[run,runStream,runUpdate]", // - "@google-cloud/spanner;~SqlExecutorDirect;@google-cloud/spanner;v1.SpannerClient;Member[executeSql,executeStreamingSql,partitionQuery]", // + "@google-cloud/spanner.BackupStatic;@google-cloud/spanner/backup.BackupStatic;", // + "@google-cloud/spanner.BackupStatic;@google-cloud/spanner/backup;Member[Backup]", // + "@google-cloud/spanner.BackupStatic;@google-cloud/spanner;Member[Backup]", // + "@google-cloud/spanner.BatchTransaction;@google-cloud/spanner/batch-transaction.BatchTransaction;", // + "@google-cloud/spanner.Database;@google-cloud/spanner.DatabaseStatic;Instance", // + "@google-cloud/spanner.Database;@google-cloud/spanner.Instance;Member[database].ReturnValue", // + "@google-cloud/spanner.Database;@google-cloud/spanner.SessionPool;Member[database]", // + "@google-cloud/spanner.Database;@google-cloud/spanner.SessionPoolStatic;Argument[0]", // + "@google-cloud/spanner.Database;@google-cloud/spanner.SessionStatic;Argument[0]", // + "@google-cloud/spanner.Database;@google-cloud/spanner.Table;Member[database]", // + "@google-cloud/spanner.Database;@google-cloud/spanner.TableStatic;Argument[0]", // + "@google-cloud/spanner.Database;@google-cloud/spanner/database.Database;", // + "@google-cloud/spanner.Database;@google-cloud/spanner/database.DatabaseCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0]", // + "@google-cloud/spanner.Database;@google-cloud/spanner/database.RestoreDatabaseCallback;TypeVar[@google-cloud/spanner/common.LongRunningCallback.0]", // + "@google-cloud/spanner.Database;@google-cloud/spanner/database.SessionPoolConstructor;Argument[0]", // + "@google-cloud/spanner.Database;@google-cloud/spanner/instance.CreateDatabaseCallback;TypeVar[@google-cloud/spanner/common.LongRunningCallback.0]", // + "@google-cloud/spanner.Database;@google-cloud/spanner/instance.GetDatabasesCallback;TypeVar[@google-cloud/spanner/common.RequestCallback.0]", // + "@google-cloud/spanner.DatabaseStatic;@google-cloud/spanner/database.DatabaseStatic;", // + "@google-cloud/spanner.DatabaseStatic;@google-cloud/spanner/database;Member[Database]", // + "@google-cloud/spanner.DatabaseStatic;@google-cloud/spanner;Member[Database]", // + "@google-cloud/spanner.GetInstancesCallback;@google-cloud/spanner.Spanner;Member[getInstances].Argument[1]", // + "@google-cloud/spanner.GetInstancesCallback;@google-cloud/spanner.Spanner;Member[getInstances].WithArity[1].Argument[0]", // + "@google-cloud/spanner.GetInstancesCallback;@google-cloud/spanner/build/src.GetInstancesCallback;", // + "@google-cloud/spanner.Instance;@google-cloud/spanner.BackupStatic;Argument[0]", // + "@google-cloud/spanner.Instance;@google-cloud/spanner.DatabaseStatic;Argument[0]", // + "@google-cloud/spanner.Instance;@google-cloud/spanner.GetInstancesCallback;TypeVar[@google-cloud/spanner/common.PagedCallback.0]", // + "@google-cloud/spanner.Instance;@google-cloud/spanner.InstanceStatic;Instance", // + "@google-cloud/spanner.Instance;@google-cloud/spanner.Spanner;Member[instance].ReturnValue", // + "@google-cloud/spanner.Instance;@google-cloud/spanner/instance.CreateInstanceCallback;TypeVar[@google-cloud/spanner/common.LongRunningCallback.0]", // + "@google-cloud/spanner.Instance;@google-cloud/spanner/instance.GetInstanceCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0]", // + "@google-cloud/spanner.Instance;@google-cloud/spanner/instance.Instance;", // + "@google-cloud/spanner.InstanceStatic;@google-cloud/spanner/instance.InstanceStatic;", // + "@google-cloud/spanner.InstanceStatic;@google-cloud/spanner/instance;Member[Instance]", // + "@google-cloud/spanner.InstanceStatic;@google-cloud/spanner;Member[Instance]", // + "@google-cloud/spanner.PartitionedDml;@google-cloud/spanner.PartitionedDmlStatic;Instance", // + "@google-cloud/spanner.PartitionedDml;@google-cloud/spanner.Session;Member[partitionedDml].ReturnValue", // + "@google-cloud/spanner.PartitionedDml;@google-cloud/spanner/transaction.PartitionedDml;", // + "@google-cloud/spanner.PartitionedDmlStatic;@google-cloud/spanner/transaction.PartitionedDmlStatic;", // + "@google-cloud/spanner.PartitionedDmlStatic;@google-cloud/spanner/transaction;Member[PartitionedDml]", // + "@google-cloud/spanner.PartitionedDmlStatic;@google-cloud/spanner;Member[PartitionedDml]", // + "@google-cloud/spanner.Session;@google-cloud/spanner.Database;Member[_runPartitionedUpdate].Argument[0]", // + "@google-cloud/spanner.Session;@google-cloud/spanner.Database;Member[makePooledRequest_].WithArity[1].ReturnValue.Awaited", // + "@google-cloud/spanner.Session;@google-cloud/spanner.Database;Member[session].ReturnValue", // + "@google-cloud/spanner.Session;@google-cloud/spanner.SessionPool;Member[_acquire,_getSession].ReturnValue.Awaited", // + "@google-cloud/spanner.Session;@google-cloud/spanner.SessionPool;Member[_borrow,_destroy,_isValidSession,_ping,_prepareTransaction,_release,release].Argument[0]", // + "@google-cloud/spanner.Session;@google-cloud/spanner.SessionPool;Member[_borrowFrom,_borrowNextAvailableSession].ReturnValue", // + "@google-cloud/spanner.Session;@google-cloud/spanner.SessionPool;Member[_getIdleSessions].ReturnValue.ArrayElement", // + "@google-cloud/spanner.Session;@google-cloud/spanner.SessionStatic;Instance", // + "@google-cloud/spanner.Session;@google-cloud/spanner.Snapshot;Member[session]", // + "@google-cloud/spanner.Session;@google-cloud/spanner/batch-transaction.TransactionIdentifier;Member[session]", // + "@google-cloud/spanner.Session;@google-cloud/spanner/database.BatchCreateSessionsCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0].ArrayElement", // + "@google-cloud/spanner.Session;@google-cloud/spanner/database.CreateSessionCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0]", // + "@google-cloud/spanner.Session;@google-cloud/spanner/database.GetSessionsCallback;TypeVar[@google-cloud/spanner/common.RequestCallback.0]", // + "@google-cloud/spanner.Session;@google-cloud/spanner/database.PoolRequestCallback;TypeVar[@google-cloud/spanner/common.RequestCallback.0]", // + "@google-cloud/spanner.Session;@google-cloud/spanner/session-pool.GetReadSessionCallback;TypeVar[@google-cloud/spanner/common.NormalCallback.0]", // + "@google-cloud/spanner.Session;@google-cloud/spanner/session-pool.GetWriteSessionCallback;Argument[1]", // + "@google-cloud/spanner.Session;@google-cloud/spanner/session-pool.SessionPoolInterface;Member[release].Argument[0]", // + "@google-cloud/spanner.Session;@google-cloud/spanner/session.Session;", // + "@google-cloud/spanner.Session;@google-cloud/spanner/transaction-runner.Runner;Member[session]", // + "@google-cloud/spanner.SessionPool;@google-cloud/spanner.SessionPoolStatic;Instance", // + "@google-cloud/spanner.SessionPool;@google-cloud/spanner/instance.CreateDatabaseOptions;Member[poolCtor]", // + "@google-cloud/spanner.SessionPool;@google-cloud/spanner/session-pool.SessionPool;", // + "@google-cloud/spanner.SessionPoolStatic;@google-cloud/spanner/session-pool.SessionPoolStatic;", // + "@google-cloud/spanner.SessionPoolStatic;@google-cloud/spanner/session-pool;Member[SessionPool]", // + "@google-cloud/spanner.SessionPoolStatic;@google-cloud/spanner;Member[SessionPool]", // + "@google-cloud/spanner.SessionStatic;@google-cloud/spanner/session.SessionStatic;", // + "@google-cloud/spanner.SessionStatic;@google-cloud/spanner/session;Member[Session]", // + "@google-cloud/spanner.SessionStatic;@google-cloud/spanner;Member[Session]", // + "@google-cloud/spanner.Snapshot;@google-cloud/spanner.Session;Member[snapshot].ReturnValue", // + "@google-cloud/spanner.Snapshot;@google-cloud/spanner.SnapshotStatic;Instance", // + "@google-cloud/spanner.Snapshot;@google-cloud/spanner/batch-transaction.BatchTransaction;", // + "@google-cloud/spanner.Snapshot;@google-cloud/spanner/database.GetSnapshotCallback;TypeVar[@google-cloud/spanner/common.NormalCallback.0]", // + "@google-cloud/spanner.Snapshot;@google-cloud/spanner/transaction.Dml;", // + "@google-cloud/spanner.Snapshot;@google-cloud/spanner/transaction.Snapshot;", // + "@google-cloud/spanner.SnapshotStatic;@google-cloud/spanner/transaction.SnapshotStatic;", // + "@google-cloud/spanner.SnapshotStatic;@google-cloud/spanner/transaction;Member[Snapshot]", // + "@google-cloud/spanner.SnapshotStatic;@google-cloud/spanner;Member[Snapshot]", // + "@google-cloud/spanner.Spanner;@google-cloud/spanner.InstanceStatic;Argument[0]", // + "@google-cloud/spanner.Spanner;@google-cloud/spanner.SpannerStatic;Instance", // + "@google-cloud/spanner.SpannerStatic;@google-cloud/spanner;Member[Spanner]", // + "@google-cloud/spanner.Table;@google-cloud/spanner.Database;Member[table].ReturnValue", // + "@google-cloud/spanner.Table;@google-cloud/spanner.TableStatic;Instance", // + "@google-cloud/spanner.Table;@google-cloud/spanner/table.CreateTableCallback;TypeVar[@google-cloud/spanner/common.LongRunningCallback.0]", // + "@google-cloud/spanner.Table;@google-cloud/spanner/table.Table;", // + "@google-cloud/spanner.TableStatic;@google-cloud/spanner/table.TableStatic;", // + "@google-cloud/spanner.TableStatic;@google-cloud/spanner/table;Member[Table]", // + "@google-cloud/spanner.TableStatic;@google-cloud/spanner;Member[Table]", // + "@google-cloud/spanner.Transaction;@google-cloud/spanner.Session;Member[transaction].ReturnValue", // + "@google-cloud/spanner.Transaction;@google-cloud/spanner.Session;Member[txn]", // + "@google-cloud/spanner.Transaction;@google-cloud/spanner.TransactionStatic;Instance", // + "@google-cloud/spanner.Transaction;@google-cloud/spanner/database.GetTransactionCallback;TypeVar[@google-cloud/spanner/common.NormalCallback.0]", // + "@google-cloud/spanner.Transaction;@google-cloud/spanner/session-pool.GetWriteSessionCallback;Argument[2]", // + "@google-cloud/spanner.Transaction;@google-cloud/spanner/transaction-runner.AsyncRunTransactionCallback;Argument[0]", // + "@google-cloud/spanner.Transaction;@google-cloud/spanner/transaction-runner.RunTransactionCallback;TypeVar[@google-cloud/spanner/common.NormalCallback.0]", // + "@google-cloud/spanner.Transaction;@google-cloud/spanner/transaction-runner.Runner;Member[getTransaction].ReturnValue.Awaited", // + "@google-cloud/spanner.Transaction;@google-cloud/spanner/transaction-runner.Runner;Member[transaction]", // + "@google-cloud/spanner.Transaction;@google-cloud/spanner/transaction.Transaction;", // + "@google-cloud/spanner.TransactionStatic;@google-cloud/spanner/transaction.TransactionStatic;", // + "@google-cloud/spanner.TransactionStatic;@google-cloud/spanner/transaction;Member[Transaction]", // + "@google-cloud/spanner.TransactionStatic;@google-cloud/spanner;Member[Transaction]", // + "@google-cloud/spanner.v1.SpannerClient;@google-cloud/spanner.v1.SpannerClientStatic;Instance", // + "@google-cloud/spanner.v1.SpannerClient;@google-cloud/spanner/v1/spanner_client.SpannerClient;", // + "@google-cloud/spanner.v1.SpannerClientStatic;@google-cloud/spanner/v1/spanner_client.SpannerClientStatic;", // + "@google-cloud/spanner.v1.SpannerClientStatic;@google-cloud/spanner/v1/spanner_client;Member[SpannerClient]", // + "@google-cloud/spanner.v1.SpannerClientStatic;@google-cloud/spanner;Member[v1].Member[SpannerClient]", // + "@google-cloud/spanner.~SpannerObject;@google-cloud/spanner.Database;", // + "@google-cloud/spanner.~SpannerObject;@google-cloud/spanner.Snapshot;", // + "@google-cloud/spanner.~SpannerObject;@google-cloud/spanner.Transaction;", // + "@google-cloud/spanner.~SpannerObject;@google-cloud/spanner.v1.SpannerClient;", // + "@google-cloud/spanner.~SqlExecutorDirect;@google-cloud/spanner.BatchTransaction;Member[createQueryPartitions]", // + "@google-cloud/spanner.~SqlExecutorDirect;@google-cloud/spanner.Database;Member[run,runPartitionedUpdate,runStream]", // + "@google-cloud/spanner.~SqlExecutorDirect;@google-cloud/spanner.PartitionedDml;Member[runUpdate]", // + "@google-cloud/spanner.~SqlExecutorDirect;@google-cloud/spanner.Snapshot;Member[run,runStream]", // + "@google-cloud/spanner.~SqlExecutorDirect;@google-cloud/spanner.Transaction;Member[run,runStream,runUpdate]", // + "@google-cloud/spanner.~SqlExecutorDirect;@google-cloud/spanner.v1.SpannerClient;Member[executeSql,executeStreamingSql,partitionQuery]", // + "@google-cloud/spanner/batch-transaction.BatchTransaction;@google-cloud/spanner.Database;Member[batchTransaction].ReturnValue", // + "@google-cloud/spanner/batch-transaction.BatchTransaction;@google-cloud/spanner/batch-transaction.BatchTransactionStatic;Instance", // + "@google-cloud/spanner/batch-transaction.BatchTransaction;@google-cloud/spanner/database.CreateBatchTransactionCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0]", // + "@google-cloud/spanner/batch-transaction.BatchTransactionStatic;@google-cloud/spanner/batch-transaction;Member[BatchTransaction]", // + "@google-cloud/spanner/batch-transaction.TransactionIdentifier;@google-cloud/spanner.Database;Member[batchTransaction].Argument[0]", // + "@google-cloud/spanner/batch-transaction.TransactionIdentifier;@google-cloud/spanner/batch-transaction.BatchTransaction;Member[identifier].ReturnValue", // + "@google-cloud/spanner/database.BatchCreateSessionsCallback;@google-cloud/spanner.Database;Member[batchCreateSessions].Argument[1]", // + "@google-cloud/spanner/database.CreateBatchTransactionCallback;@google-cloud/spanner.Database;Member[createBatchTransaction].Argument[1]", // + "@google-cloud/spanner/database.CreateBatchTransactionCallback;@google-cloud/spanner.Database;Member[createBatchTransaction].WithArity[1].Argument[0]", // + "@google-cloud/spanner/database.CreateSessionCallback;@google-cloud/spanner.Database;Member[createSession].Argument[1]", // + "@google-cloud/spanner/database.CreateSessionCallback;@google-cloud/spanner.Database;Member[createSession].WithArity[1].Argument[0]", // + "@google-cloud/spanner/database.DatabaseCallback;@google-cloud/spanner.Database;Member[get].Argument[1]", // + "@google-cloud/spanner/database.DatabaseCallback;@google-cloud/spanner.Database;Member[get].WithArity[1].Argument[0]", // + "@google-cloud/spanner/database.GetSessionsCallback;@google-cloud/spanner.Database;Member[getSessions].Argument[1]", // + "@google-cloud/spanner/database.GetSessionsCallback;@google-cloud/spanner.Database;Member[getSessions].WithArity[1].Argument[0]", // + "@google-cloud/spanner/database.GetSnapshotCallback;@google-cloud/spanner.Database;Member[getSnapshot].Argument[1]", // + "@google-cloud/spanner/database.GetSnapshotCallback;@google-cloud/spanner.Database;Member[getSnapshot].WithArity[1].Argument[0]", // + "@google-cloud/spanner/database.GetTransactionCallback;@google-cloud/spanner.Database;Member[getTransaction].Argument[0]", // + "@google-cloud/spanner/database.PoolRequestCallback;@google-cloud/spanner.Database;Member[makePooledRequest_].Argument[1]", // + "@google-cloud/spanner/database.RestoreDatabaseCallback;@google-cloud/spanner.Database;Member[restore].Argument[1,2]", // + "@google-cloud/spanner/database.SessionPoolConstructor;@google-cloud/spanner.DatabaseStatic;Argument[2]", // + "@google-cloud/spanner/database.SessionPoolConstructor;@google-cloud/spanner.Instance;Member[database].Argument[1]", // + "@google-cloud/spanner/instance.CreateDatabaseCallback;@google-cloud/spanner.Instance;Member[createDatabase].Argument[2]", // + "@google-cloud/spanner/instance.CreateDatabaseCallback;@google-cloud/spanner.Instance;Member[createDatabase].WithArity[2].Argument[1]", // + "@google-cloud/spanner/instance.CreateDatabaseOptions;@google-cloud/spanner.Instance;Member[createDatabase].WithArity[1,2,3].Argument[1]", // + "@google-cloud/spanner/instance.CreateInstanceCallback;@google-cloud/spanner.Spanner;Member[createInstance].Argument[2]", // + "@google-cloud/spanner/instance.GetDatabasesCallback;@google-cloud/spanner.Instance;Member[getDatabases].Argument[1]", // + "@google-cloud/spanner/instance.GetDatabasesCallback;@google-cloud/spanner.Instance;Member[getDatabases].WithArity[1].Argument[0]", // + "@google-cloud/spanner/instance.GetInstanceCallback;@google-cloud/spanner.Instance;Member[get].Argument[1]", // + "@google-cloud/spanner/instance.GetInstanceCallback;@google-cloud/spanner.Instance;Member[get].WithArity[1].Argument[0]", // + "@google-cloud/spanner/session-pool.GetReadSessionCallback;@google-cloud/spanner.SessionPool;Member[getReadSession].Argument[0]", // + "@google-cloud/spanner/session-pool.GetReadSessionCallback;@google-cloud/spanner/session-pool.SessionPoolInterface;Member[getReadSession].Argument[0]", // + "@google-cloud/spanner/session-pool.GetWriteSessionCallback;@google-cloud/spanner.SessionPool;Member[getWriteSession].Argument[0]", // + "@google-cloud/spanner/session-pool.GetWriteSessionCallback;@google-cloud/spanner/session-pool.SessionPoolInterface;Member[getWriteSession].Argument[0]", // + "@google-cloud/spanner/session-pool.SessionPoolInterface;@google-cloud/spanner.Database;Member[pool_]", // + "@google-cloud/spanner/session-pool.SessionPoolInterface;@google-cloud/spanner.SessionPool;", // + "@google-cloud/spanner/session-pool.SessionPoolInterface;@google-cloud/spanner/database.SessionPoolConstructor;Instance", // + "@google-cloud/spanner/table.CreateTableCallback;@google-cloud/spanner.Database;Member[createTable].Argument[2]", // + "@google-cloud/spanner/table.CreateTableCallback;@google-cloud/spanner.Database;Member[createTable].WithArity[2].Argument[1]", // + "@google-cloud/spanner/table.CreateTableCallback;@google-cloud/spanner.Table;Member[create].Argument[2]", // + "@google-cloud/spanner/table.CreateTableCallback;@google-cloud/spanner.Table;Member[create].WithArity[2].Argument[1]", // + "@google-cloud/spanner/transaction-runner.AsyncRunTransactionCallback;@google-cloud/spanner.Database;Member[runTransactionAsync].Argument[1]", // + "@google-cloud/spanner/transaction-runner.AsyncRunTransactionCallback;@google-cloud/spanner.Database;Member[runTransactionAsync].WithArity[1].Argument[0]", // + "@google-cloud/spanner/transaction-runner.AsyncRunTransactionCallback;@google-cloud/spanner/transaction-runner.AsyncTransactionRunnerStatic;Argument[2]", // + "@google-cloud/spanner/transaction-runner.AsyncTransactionRunner;@google-cloud/spanner/transaction-runner.AsyncTransactionRunnerStatic;Instance", // + "@google-cloud/spanner/transaction-runner.AsyncTransactionRunnerStatic;@google-cloud/spanner/transaction-runner;Member[AsyncTransactionRunner]", // + "@google-cloud/spanner/transaction-runner.RunTransactionCallback;@google-cloud/spanner.Database;Member[runTransaction].Argument[1]", // + "@google-cloud/spanner/transaction-runner.RunTransactionCallback;@google-cloud/spanner.Database;Member[runTransaction].WithArity[1].Argument[0]", // + "@google-cloud/spanner/transaction-runner.RunTransactionCallback;@google-cloud/spanner/transaction-runner.TransactionRunnerStatic;Argument[2]", // + "@google-cloud/spanner/transaction-runner.Runner;@google-cloud/spanner/transaction-runner.AsyncTransactionRunner;", // + "@google-cloud/spanner/transaction-runner.Runner;@google-cloud/spanner/transaction-runner.RunnerStatic;Instance", // + "@google-cloud/spanner/transaction-runner.Runner;@google-cloud/spanner/transaction-runner.TransactionRunner;", // + "@google-cloud/spanner/transaction-runner.RunnerStatic;@google-cloud/spanner/transaction-runner;Member[Runner]", // + "@google-cloud/spanner/transaction-runner.TransactionRunner;@google-cloud/spanner/transaction-runner.TransactionRunnerStatic;Instance", // + "@google-cloud/spanner/transaction-runner.TransactionRunnerStatic;@google-cloud/spanner/transaction-runner;Member[TransactionRunner]", // + "@google-cloud/spanner/transaction.Dml;@google-cloud/spanner.PartitionedDml;", // + "@google-cloud/spanner/transaction.Dml;@google-cloud/spanner.Transaction;", // + "@google-cloud/spanner/transaction.Dml;@google-cloud/spanner/transaction.DmlStatic;Instance", // + "@google-cloud/spanner/transaction.DmlStatic;@google-cloud/spanner/transaction;Member[Dml]", // ] } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/spanner/model.json b/javascript/ql/lib/semmle/javascript/frameworks/spanner/model.json index d2fe140f4d8..c4f583df6e4 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/spanner/model.json +++ b/javascript/ql/lib/semmle/javascript/frameworks/spanner/model.json @@ -56,186 +56,186 @@ "language": "javascript", "model": { "typeDefinitions": [ - "@google-cloud/spanner;BatchTransaction;@google-cloud/spanner/batch-transaction;BatchTransaction;", - "@google-cloud/spanner;~SpannerObject;@google-cloud/spanner;Database;", - "@google-cloud/spanner;~SpannerObject;@google-cloud/spanner;Snapshot;", - "@google-cloud/spanner;~SpannerObject;@google-cloud/spanner;Transaction;", - "@google-cloud/spanner;~SpannerObject;@google-cloud/spanner;v1.SpannerClient;", - "@google-cloud/spanner;~SqlExecutorDirect;@google-cloud/spanner;BatchTransaction;Member[createQueryPartitions]", - "@google-cloud/spanner;~SqlExecutorDirect;@google-cloud/spanner;Database;Member[run,runPartitionedUpdate,runStream]", - "@google-cloud/spanner;~SqlExecutorDirect;@google-cloud/spanner;PartitionedDml;Member[runUpdate]", - "@google-cloud/spanner;~SqlExecutorDirect;@google-cloud/spanner;Snapshot;Member[run,runStream]", - "@google-cloud/spanner;~SqlExecutorDirect;@google-cloud/spanner;Transaction;Member[run,runStream,runUpdate]", - "@google-cloud/spanner;~SqlExecutorDirect;@google-cloud/spanner;v1.SpannerClient;Member[executeSql,executeStreamingSql,partitionQuery]" + "@google-cloud/spanner.BatchTransaction;@google-cloud/spanner/batch-transaction.BatchTransaction;", + "@google-cloud/spanner.~SpannerObject;@google-cloud/spanner.Database;", + "@google-cloud/spanner.~SpannerObject;@google-cloud/spanner.Snapshot;", + "@google-cloud/spanner.~SpannerObject;@google-cloud/spanner.Transaction;", + "@google-cloud/spanner.~SpannerObject;@google-cloud/spanner.v1.SpannerClient;", + "@google-cloud/spanner.~SqlExecutorDirect;@google-cloud/spanner.BatchTransaction;Member[createQueryPartitions]", + "@google-cloud/spanner.~SqlExecutorDirect;@google-cloud/spanner.Database;Member[run,runPartitionedUpdate,runStream]", + "@google-cloud/spanner.~SqlExecutorDirect;@google-cloud/spanner.PartitionedDml;Member[runUpdate]", + "@google-cloud/spanner.~SqlExecutorDirect;@google-cloud/spanner.Snapshot;Member[run,runStream]", + "@google-cloud/spanner.~SqlExecutorDirect;@google-cloud/spanner.Transaction;Member[run,runStream,runUpdate]", + "@google-cloud/spanner.~SqlExecutorDirect;@google-cloud/spanner.v1.SpannerClient;Member[executeSql,executeStreamingSql,partitionQuery]" ], "sinks": [] }, "generatedModel": { "//": "Autogenerated section. Manual edits in here will be lost.", "typeDefinitions": [ - "@google-cloud/spanner/batch-transaction;BatchTransaction;@google-cloud/spanner/batch-transaction;BatchTransactionStatic;Instance", - "@google-cloud/spanner/batch-transaction;BatchTransaction;@google-cloud/spanner/database;CreateBatchTransactionCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0]", - "@google-cloud/spanner/batch-transaction;BatchTransaction;@google-cloud/spanner;Database;Member[batchTransaction].ReturnValue", - "@google-cloud/spanner/batch-transaction;BatchTransactionStatic;@google-cloud/spanner/batch-transaction;;Member[BatchTransaction]", - "@google-cloud/spanner/batch-transaction;TransactionIdentifier;@google-cloud/spanner/batch-transaction;BatchTransaction;Member[identifier].ReturnValue", - "@google-cloud/spanner/batch-transaction;TransactionIdentifier;@google-cloud/spanner;Database;Member[batchTransaction].Argument[0]", - "@google-cloud/spanner/database;BatchCreateSessionsCallback;@google-cloud/spanner;Database;Member[batchCreateSessions].Argument[1]", - "@google-cloud/spanner/database;CreateBatchTransactionCallback;@google-cloud/spanner;Database;Member[createBatchTransaction].Argument[1]", - "@google-cloud/spanner/database;CreateBatchTransactionCallback;@google-cloud/spanner;Database;Member[createBatchTransaction].WithArity[1].Argument[0]", - "@google-cloud/spanner/database;CreateSessionCallback;@google-cloud/spanner;Database;Member[createSession].Argument[1]", - "@google-cloud/spanner/database;CreateSessionCallback;@google-cloud/spanner;Database;Member[createSession].WithArity[1].Argument[0]", - "@google-cloud/spanner/database;DatabaseCallback;@google-cloud/spanner;Database;Member[get].Argument[1]", - "@google-cloud/spanner/database;DatabaseCallback;@google-cloud/spanner;Database;Member[get].WithArity[1].Argument[0]", - "@google-cloud/spanner/database;GetSessionsCallback;@google-cloud/spanner;Database;Member[getSessions].Argument[1]", - "@google-cloud/spanner/database;GetSessionsCallback;@google-cloud/spanner;Database;Member[getSessions].WithArity[1].Argument[0]", - "@google-cloud/spanner/database;GetSnapshotCallback;@google-cloud/spanner;Database;Member[getSnapshot].Argument[1]", - "@google-cloud/spanner/database;GetSnapshotCallback;@google-cloud/spanner;Database;Member[getSnapshot].WithArity[1].Argument[0]", - "@google-cloud/spanner/database;GetTransactionCallback;@google-cloud/spanner;Database;Member[getTransaction].Argument[0]", - "@google-cloud/spanner/database;PoolRequestCallback;@google-cloud/spanner;Database;Member[makePooledRequest_].Argument[1]", - "@google-cloud/spanner/database;RestoreDatabaseCallback;@google-cloud/spanner;Database;Member[restore].Argument[1,2]", - "@google-cloud/spanner/database;SessionPoolConstructor;@google-cloud/spanner;DatabaseStatic;Argument[2]", - "@google-cloud/spanner/database;SessionPoolConstructor;@google-cloud/spanner;Instance;Member[database].Argument[1]", - "@google-cloud/spanner/instance;CreateDatabaseCallback;@google-cloud/spanner;Instance;Member[createDatabase].Argument[2]", - "@google-cloud/spanner/instance;CreateDatabaseCallback;@google-cloud/spanner;Instance;Member[createDatabase].WithArity[2].Argument[1]", - "@google-cloud/spanner/instance;CreateDatabaseOptions;@google-cloud/spanner;Instance;Member[createDatabase].WithArity[1,2,3].Argument[1]", - "@google-cloud/spanner/instance;CreateInstanceCallback;@google-cloud/spanner;Spanner;Member[createInstance].Argument[2]", - "@google-cloud/spanner/instance;GetDatabasesCallback;@google-cloud/spanner;Instance;Member[getDatabases].Argument[1]", - "@google-cloud/spanner/instance;GetDatabasesCallback;@google-cloud/spanner;Instance;Member[getDatabases].WithArity[1].Argument[0]", - "@google-cloud/spanner/instance;GetInstanceCallback;@google-cloud/spanner;Instance;Member[get].Argument[1]", - "@google-cloud/spanner/instance;GetInstanceCallback;@google-cloud/spanner;Instance;Member[get].WithArity[1].Argument[0]", - "@google-cloud/spanner/session-pool;GetReadSessionCallback;@google-cloud/spanner/session-pool;SessionPoolInterface;Member[getReadSession].Argument[0]", - "@google-cloud/spanner/session-pool;GetReadSessionCallback;@google-cloud/spanner;SessionPool;Member[getReadSession].Argument[0]", - "@google-cloud/spanner/session-pool;GetWriteSessionCallback;@google-cloud/spanner/session-pool;SessionPoolInterface;Member[getWriteSession].Argument[0]", - "@google-cloud/spanner/session-pool;GetWriteSessionCallback;@google-cloud/spanner;SessionPool;Member[getWriteSession].Argument[0]", - "@google-cloud/spanner/session-pool;SessionPoolInterface;@google-cloud/spanner/database;SessionPoolConstructor;Instance", - "@google-cloud/spanner/session-pool;SessionPoolInterface;@google-cloud/spanner;Database;Member[pool_]", - "@google-cloud/spanner/session-pool;SessionPoolInterface;@google-cloud/spanner;SessionPool;", - "@google-cloud/spanner/table;CreateTableCallback;@google-cloud/spanner;Database;Member[createTable].Argument[2]", - "@google-cloud/spanner/table;CreateTableCallback;@google-cloud/spanner;Database;Member[createTable].WithArity[2].Argument[1]", - "@google-cloud/spanner/table;CreateTableCallback;@google-cloud/spanner;Table;Member[create].Argument[2]", - "@google-cloud/spanner/table;CreateTableCallback;@google-cloud/spanner;Table;Member[create].WithArity[2].Argument[1]", - "@google-cloud/spanner/transaction-runner;AsyncRunTransactionCallback;@google-cloud/spanner/transaction-runner;AsyncTransactionRunnerStatic;Argument[2]", - "@google-cloud/spanner/transaction-runner;AsyncRunTransactionCallback;@google-cloud/spanner;Database;Member[runTransactionAsync].Argument[1]", - "@google-cloud/spanner/transaction-runner;AsyncRunTransactionCallback;@google-cloud/spanner;Database;Member[runTransactionAsync].WithArity[1].Argument[0]", - "@google-cloud/spanner/transaction-runner;AsyncTransactionRunner;@google-cloud/spanner/transaction-runner;AsyncTransactionRunnerStatic;Instance", - "@google-cloud/spanner/transaction-runner;AsyncTransactionRunnerStatic;@google-cloud/spanner/transaction-runner;;Member[AsyncTransactionRunner]", - "@google-cloud/spanner/transaction-runner;RunTransactionCallback;@google-cloud/spanner/transaction-runner;TransactionRunnerStatic;Argument[2]", - "@google-cloud/spanner/transaction-runner;RunTransactionCallback;@google-cloud/spanner;Database;Member[runTransaction].Argument[1]", - "@google-cloud/spanner/transaction-runner;RunTransactionCallback;@google-cloud/spanner;Database;Member[runTransaction].WithArity[1].Argument[0]", - "@google-cloud/spanner/transaction-runner;Runner;@google-cloud/spanner/transaction-runner;AsyncTransactionRunner;", - "@google-cloud/spanner/transaction-runner;Runner;@google-cloud/spanner/transaction-runner;RunnerStatic;Instance", - "@google-cloud/spanner/transaction-runner;Runner;@google-cloud/spanner/transaction-runner;TransactionRunner;", - "@google-cloud/spanner/transaction-runner;RunnerStatic;@google-cloud/spanner/transaction-runner;;Member[Runner]", - "@google-cloud/spanner/transaction-runner;TransactionRunner;@google-cloud/spanner/transaction-runner;TransactionRunnerStatic;Instance", - "@google-cloud/spanner/transaction-runner;TransactionRunnerStatic;@google-cloud/spanner/transaction-runner;;Member[TransactionRunner]", - "@google-cloud/spanner/transaction;Dml;@google-cloud/spanner/transaction;DmlStatic;Instance", - "@google-cloud/spanner/transaction;Dml;@google-cloud/spanner;PartitionedDml;", - "@google-cloud/spanner/transaction;Dml;@google-cloud/spanner;Transaction;", - "@google-cloud/spanner/transaction;DmlStatic;@google-cloud/spanner/transaction;;Member[Dml]", - "@google-cloud/spanner;BackupStatic;@google-cloud/spanner/backup;;Member[Backup]", - "@google-cloud/spanner;BackupStatic;@google-cloud/spanner/backup;BackupStatic;", - "@google-cloud/spanner;BackupStatic;@google-cloud/spanner;;Member[Backup]", - "@google-cloud/spanner;Database;@google-cloud/spanner/database;Database;", - "@google-cloud/spanner;Database;@google-cloud/spanner/database;DatabaseCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0]", - "@google-cloud/spanner;Database;@google-cloud/spanner/database;RestoreDatabaseCallback;TypeVar[@google-cloud/spanner/common.LongRunningCallback.0]", - "@google-cloud/spanner;Database;@google-cloud/spanner/database;SessionPoolConstructor;Argument[0]", - "@google-cloud/spanner;Database;@google-cloud/spanner/instance;CreateDatabaseCallback;TypeVar[@google-cloud/spanner/common.LongRunningCallback.0]", - "@google-cloud/spanner;Database;@google-cloud/spanner/instance;GetDatabasesCallback;TypeVar[@google-cloud/spanner/common.RequestCallback.0]", - "@google-cloud/spanner;Database;@google-cloud/spanner;DatabaseStatic;Instance", - "@google-cloud/spanner;Database;@google-cloud/spanner;Instance;Member[database].ReturnValue", - "@google-cloud/spanner;Database;@google-cloud/spanner;SessionPool;Member[database]", - "@google-cloud/spanner;Database;@google-cloud/spanner;SessionPoolStatic;Argument[0]", - "@google-cloud/spanner;Database;@google-cloud/spanner;SessionStatic;Argument[0]", - "@google-cloud/spanner;Database;@google-cloud/spanner;Table;Member[database]", - "@google-cloud/spanner;Database;@google-cloud/spanner;TableStatic;Argument[0]", - "@google-cloud/spanner;DatabaseStatic;@google-cloud/spanner/database;;Member[Database]", - "@google-cloud/spanner;DatabaseStatic;@google-cloud/spanner/database;DatabaseStatic;", - "@google-cloud/spanner;DatabaseStatic;@google-cloud/spanner;;Member[Database]", - "@google-cloud/spanner;GetInstancesCallback;@google-cloud/spanner/build/src;GetInstancesCallback;", - "@google-cloud/spanner;GetInstancesCallback;@google-cloud/spanner;Spanner;Member[getInstances].Argument[1]", - "@google-cloud/spanner;GetInstancesCallback;@google-cloud/spanner;Spanner;Member[getInstances].WithArity[1].Argument[0]", - "@google-cloud/spanner;Instance;@google-cloud/spanner/instance;CreateInstanceCallback;TypeVar[@google-cloud/spanner/common.LongRunningCallback.0]", - "@google-cloud/spanner;Instance;@google-cloud/spanner/instance;GetInstanceCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0]", - "@google-cloud/spanner;Instance;@google-cloud/spanner/instance;Instance;", - "@google-cloud/spanner;Instance;@google-cloud/spanner;BackupStatic;Argument[0]", - "@google-cloud/spanner;Instance;@google-cloud/spanner;DatabaseStatic;Argument[0]", - "@google-cloud/spanner;Instance;@google-cloud/spanner;GetInstancesCallback;TypeVar[@google-cloud/spanner/common.PagedCallback.0]", - "@google-cloud/spanner;Instance;@google-cloud/spanner;InstanceStatic;Instance", - "@google-cloud/spanner;Instance;@google-cloud/spanner;Spanner;Member[instance].ReturnValue", - "@google-cloud/spanner;InstanceStatic;@google-cloud/spanner/instance;;Member[Instance]", - "@google-cloud/spanner;InstanceStatic;@google-cloud/spanner/instance;InstanceStatic;", - "@google-cloud/spanner;InstanceStatic;@google-cloud/spanner;;Member[Instance]", - "@google-cloud/spanner;PartitionedDml;@google-cloud/spanner/transaction;PartitionedDml;", - "@google-cloud/spanner;PartitionedDml;@google-cloud/spanner;PartitionedDmlStatic;Instance", - "@google-cloud/spanner;PartitionedDml;@google-cloud/spanner;Session;Member[partitionedDml].ReturnValue", - "@google-cloud/spanner;PartitionedDmlStatic;@google-cloud/spanner/transaction;;Member[PartitionedDml]", - "@google-cloud/spanner;PartitionedDmlStatic;@google-cloud/spanner/transaction;PartitionedDmlStatic;", - "@google-cloud/spanner;PartitionedDmlStatic;@google-cloud/spanner;;Member[PartitionedDml]", - "@google-cloud/spanner;Session;@google-cloud/spanner/batch-transaction;TransactionIdentifier;Member[session]", - "@google-cloud/spanner;Session;@google-cloud/spanner/database;BatchCreateSessionsCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0].ArrayElement", - "@google-cloud/spanner;Session;@google-cloud/spanner/database;CreateSessionCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0]", - "@google-cloud/spanner;Session;@google-cloud/spanner/database;GetSessionsCallback;TypeVar[@google-cloud/spanner/common.RequestCallback.0]", - "@google-cloud/spanner;Session;@google-cloud/spanner/database;PoolRequestCallback;TypeVar[@google-cloud/spanner/common.RequestCallback.0]", - "@google-cloud/spanner;Session;@google-cloud/spanner/session-pool;GetReadSessionCallback;TypeVar[@google-cloud/spanner/common.NormalCallback.0]", - "@google-cloud/spanner;Session;@google-cloud/spanner/session-pool;GetWriteSessionCallback;Argument[1]", - "@google-cloud/spanner;Session;@google-cloud/spanner/session-pool;SessionPoolInterface;Member[release].Argument[0]", - "@google-cloud/spanner;Session;@google-cloud/spanner/session;Session;", - "@google-cloud/spanner;Session;@google-cloud/spanner/transaction-runner;Runner;Member[session]", - "@google-cloud/spanner;Session;@google-cloud/spanner;Database;Member[_runPartitionedUpdate].Argument[0]", - "@google-cloud/spanner;Session;@google-cloud/spanner;Database;Member[makePooledRequest_].WithArity[1].ReturnValue.Awaited", - "@google-cloud/spanner;Session;@google-cloud/spanner;Database;Member[session].ReturnValue", - "@google-cloud/spanner;Session;@google-cloud/spanner;SessionPool;Member[_acquire,_getSession].ReturnValue.Awaited", - "@google-cloud/spanner;Session;@google-cloud/spanner;SessionPool;Member[_borrow,_destroy,_isValidSession,_ping,_prepareTransaction,_release,release].Argument[0]", - "@google-cloud/spanner;Session;@google-cloud/spanner;SessionPool;Member[_borrowFrom,_borrowNextAvailableSession].ReturnValue", - "@google-cloud/spanner;Session;@google-cloud/spanner;SessionPool;Member[_getIdleSessions].ReturnValue.ArrayElement", - "@google-cloud/spanner;Session;@google-cloud/spanner;SessionStatic;Instance", - "@google-cloud/spanner;Session;@google-cloud/spanner;Snapshot;Member[session]", - "@google-cloud/spanner;SessionPool;@google-cloud/spanner/instance;CreateDatabaseOptions;Member[poolCtor]", - "@google-cloud/spanner;SessionPool;@google-cloud/spanner/session-pool;SessionPool;", - "@google-cloud/spanner;SessionPool;@google-cloud/spanner;SessionPoolStatic;Instance", - "@google-cloud/spanner;SessionPoolStatic;@google-cloud/spanner/session-pool;;Member[SessionPool]", - "@google-cloud/spanner;SessionPoolStatic;@google-cloud/spanner/session-pool;SessionPoolStatic;", - "@google-cloud/spanner;SessionPoolStatic;@google-cloud/spanner;;Member[SessionPool]", - "@google-cloud/spanner;SessionStatic;@google-cloud/spanner/session;;Member[Session]", - "@google-cloud/spanner;SessionStatic;@google-cloud/spanner/session;SessionStatic;", - "@google-cloud/spanner;SessionStatic;@google-cloud/spanner;;Member[Session]", - "@google-cloud/spanner;Snapshot;@google-cloud/spanner/batch-transaction;BatchTransaction;", - "@google-cloud/spanner;Snapshot;@google-cloud/spanner/database;GetSnapshotCallback;TypeVar[@google-cloud/spanner/common.NormalCallback.0]", - "@google-cloud/spanner;Snapshot;@google-cloud/spanner/transaction;Dml;", - "@google-cloud/spanner;Snapshot;@google-cloud/spanner/transaction;Snapshot;", - "@google-cloud/spanner;Snapshot;@google-cloud/spanner;Session;Member[snapshot].ReturnValue", - "@google-cloud/spanner;Snapshot;@google-cloud/spanner;SnapshotStatic;Instance", - "@google-cloud/spanner;SnapshotStatic;@google-cloud/spanner/transaction;;Member[Snapshot]", - "@google-cloud/spanner;SnapshotStatic;@google-cloud/spanner/transaction;SnapshotStatic;", - "@google-cloud/spanner;SnapshotStatic;@google-cloud/spanner;;Member[Snapshot]", - "@google-cloud/spanner;Spanner;@google-cloud/spanner;InstanceStatic;Argument[0]", - "@google-cloud/spanner;Spanner;@google-cloud/spanner;SpannerStatic;Instance", - "@google-cloud/spanner;SpannerStatic;@google-cloud/spanner;;Member[Spanner]", - "@google-cloud/spanner;Table;@google-cloud/spanner/table;CreateTableCallback;TypeVar[@google-cloud/spanner/common.LongRunningCallback.0]", - "@google-cloud/spanner;Table;@google-cloud/spanner/table;Table;", - "@google-cloud/spanner;Table;@google-cloud/spanner;Database;Member[table].ReturnValue", - "@google-cloud/spanner;Table;@google-cloud/spanner;TableStatic;Instance", - "@google-cloud/spanner;TableStatic;@google-cloud/spanner/table;;Member[Table]", - "@google-cloud/spanner;TableStatic;@google-cloud/spanner/table;TableStatic;", - "@google-cloud/spanner;TableStatic;@google-cloud/spanner;;Member[Table]", - "@google-cloud/spanner;Transaction;@google-cloud/spanner/database;GetTransactionCallback;TypeVar[@google-cloud/spanner/common.NormalCallback.0]", - "@google-cloud/spanner;Transaction;@google-cloud/spanner/session-pool;GetWriteSessionCallback;Argument[2]", - "@google-cloud/spanner;Transaction;@google-cloud/spanner/transaction-runner;AsyncRunTransactionCallback;Argument[0]", - "@google-cloud/spanner;Transaction;@google-cloud/spanner/transaction-runner;RunTransactionCallback;TypeVar[@google-cloud/spanner/common.NormalCallback.0]", - "@google-cloud/spanner;Transaction;@google-cloud/spanner/transaction-runner;Runner;Member[getTransaction].ReturnValue.Awaited", - "@google-cloud/spanner;Transaction;@google-cloud/spanner/transaction-runner;Runner;Member[transaction]", - "@google-cloud/spanner;Transaction;@google-cloud/spanner/transaction;Transaction;", - "@google-cloud/spanner;Transaction;@google-cloud/spanner;Session;Member[transaction].ReturnValue", - "@google-cloud/spanner;Transaction;@google-cloud/spanner;Session;Member[txn]", - "@google-cloud/spanner;Transaction;@google-cloud/spanner;TransactionStatic;Instance", - "@google-cloud/spanner;TransactionStatic;@google-cloud/spanner/transaction;;Member[Transaction]", - "@google-cloud/spanner;TransactionStatic;@google-cloud/spanner/transaction;TransactionStatic;", - "@google-cloud/spanner;TransactionStatic;@google-cloud/spanner;;Member[Transaction]", - "@google-cloud/spanner;v1.SpannerClient;@google-cloud/spanner/v1/spanner_client;SpannerClient;", - "@google-cloud/spanner;v1.SpannerClient;@google-cloud/spanner;v1.SpannerClientStatic;Instance", - "@google-cloud/spanner;v1.SpannerClientStatic;@google-cloud/spanner/v1/spanner_client;;Member[SpannerClient]", - "@google-cloud/spanner;v1.SpannerClientStatic;@google-cloud/spanner/v1/spanner_client;SpannerClientStatic;", - "@google-cloud/spanner;v1.SpannerClientStatic;@google-cloud/spanner;;Member[v1].Member[SpannerClient]" + "@google-cloud/spanner.BackupStatic;@google-cloud/spanner/backup.BackupStatic;", + "@google-cloud/spanner.BackupStatic;@google-cloud/spanner/backup;Member[Backup]", + "@google-cloud/spanner.BackupStatic;@google-cloud/spanner;Member[Backup]", + "@google-cloud/spanner.Database;@google-cloud/spanner.DatabaseStatic;Instance", + "@google-cloud/spanner.Database;@google-cloud/spanner.Instance;Member[database].ReturnValue", + "@google-cloud/spanner.Database;@google-cloud/spanner.SessionPool;Member[database]", + "@google-cloud/spanner.Database;@google-cloud/spanner.SessionPoolStatic;Argument[0]", + "@google-cloud/spanner.Database;@google-cloud/spanner.SessionStatic;Argument[0]", + "@google-cloud/spanner.Database;@google-cloud/spanner.Table;Member[database]", + "@google-cloud/spanner.Database;@google-cloud/spanner.TableStatic;Argument[0]", + "@google-cloud/spanner.Database;@google-cloud/spanner/database.Database;", + "@google-cloud/spanner.Database;@google-cloud/spanner/database.DatabaseCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0]", + "@google-cloud/spanner.Database;@google-cloud/spanner/database.RestoreDatabaseCallback;TypeVar[@google-cloud/spanner/common.LongRunningCallback.0]", + "@google-cloud/spanner.Database;@google-cloud/spanner/database.SessionPoolConstructor;Argument[0]", + "@google-cloud/spanner.Database;@google-cloud/spanner/instance.CreateDatabaseCallback;TypeVar[@google-cloud/spanner/common.LongRunningCallback.0]", + "@google-cloud/spanner.Database;@google-cloud/spanner/instance.GetDatabasesCallback;TypeVar[@google-cloud/spanner/common.RequestCallback.0]", + "@google-cloud/spanner.DatabaseStatic;@google-cloud/spanner/database.DatabaseStatic;", + "@google-cloud/spanner.DatabaseStatic;@google-cloud/spanner/database;Member[Database]", + "@google-cloud/spanner.DatabaseStatic;@google-cloud/spanner;Member[Database]", + "@google-cloud/spanner.GetInstancesCallback;@google-cloud/spanner.Spanner;Member[getInstances].Argument[1]", + "@google-cloud/spanner.GetInstancesCallback;@google-cloud/spanner.Spanner;Member[getInstances].WithArity[1].Argument[0]", + "@google-cloud/spanner.GetInstancesCallback;@google-cloud/spanner/build/src.GetInstancesCallback;", + "@google-cloud/spanner.Instance;@google-cloud/spanner.BackupStatic;Argument[0]", + "@google-cloud/spanner.Instance;@google-cloud/spanner.DatabaseStatic;Argument[0]", + "@google-cloud/spanner.Instance;@google-cloud/spanner.GetInstancesCallback;TypeVar[@google-cloud/spanner/common.PagedCallback.0]", + "@google-cloud/spanner.Instance;@google-cloud/spanner.InstanceStatic;Instance", + "@google-cloud/spanner.Instance;@google-cloud/spanner.Spanner;Member[instance].ReturnValue", + "@google-cloud/spanner.Instance;@google-cloud/spanner/instance.CreateInstanceCallback;TypeVar[@google-cloud/spanner/common.LongRunningCallback.0]", + "@google-cloud/spanner.Instance;@google-cloud/spanner/instance.GetInstanceCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0]", + "@google-cloud/spanner.Instance;@google-cloud/spanner/instance.Instance;", + "@google-cloud/spanner.InstanceStatic;@google-cloud/spanner/instance.InstanceStatic;", + "@google-cloud/spanner.InstanceStatic;@google-cloud/spanner/instance;Member[Instance]", + "@google-cloud/spanner.InstanceStatic;@google-cloud/spanner;Member[Instance]", + "@google-cloud/spanner.PartitionedDml;@google-cloud/spanner.PartitionedDmlStatic;Instance", + "@google-cloud/spanner.PartitionedDml;@google-cloud/spanner.Session;Member[partitionedDml].ReturnValue", + "@google-cloud/spanner.PartitionedDml;@google-cloud/spanner/transaction.PartitionedDml;", + "@google-cloud/spanner.PartitionedDmlStatic;@google-cloud/spanner/transaction.PartitionedDmlStatic;", + "@google-cloud/spanner.PartitionedDmlStatic;@google-cloud/spanner/transaction;Member[PartitionedDml]", + "@google-cloud/spanner.PartitionedDmlStatic;@google-cloud/spanner;Member[PartitionedDml]", + "@google-cloud/spanner.Session;@google-cloud/spanner.Database;Member[_runPartitionedUpdate].Argument[0]", + "@google-cloud/spanner.Session;@google-cloud/spanner.Database;Member[makePooledRequest_].WithArity[1].ReturnValue.Awaited", + "@google-cloud/spanner.Session;@google-cloud/spanner.Database;Member[session].ReturnValue", + "@google-cloud/spanner.Session;@google-cloud/spanner.SessionPool;Member[_acquire,_getSession].ReturnValue.Awaited", + "@google-cloud/spanner.Session;@google-cloud/spanner.SessionPool;Member[_borrow,_destroy,_isValidSession,_ping,_prepareTransaction,_release,release].Argument[0]", + "@google-cloud/spanner.Session;@google-cloud/spanner.SessionPool;Member[_borrowFrom,_borrowNextAvailableSession].ReturnValue", + "@google-cloud/spanner.Session;@google-cloud/spanner.SessionPool;Member[_getIdleSessions].ReturnValue.ArrayElement", + "@google-cloud/spanner.Session;@google-cloud/spanner.SessionStatic;Instance", + "@google-cloud/spanner.Session;@google-cloud/spanner.Snapshot;Member[session]", + "@google-cloud/spanner.Session;@google-cloud/spanner/batch-transaction.TransactionIdentifier;Member[session]", + "@google-cloud/spanner.Session;@google-cloud/spanner/database.BatchCreateSessionsCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0].ArrayElement", + "@google-cloud/spanner.Session;@google-cloud/spanner/database.CreateSessionCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0]", + "@google-cloud/spanner.Session;@google-cloud/spanner/database.GetSessionsCallback;TypeVar[@google-cloud/spanner/common.RequestCallback.0]", + "@google-cloud/spanner.Session;@google-cloud/spanner/database.PoolRequestCallback;TypeVar[@google-cloud/spanner/common.RequestCallback.0]", + "@google-cloud/spanner.Session;@google-cloud/spanner/session-pool.GetReadSessionCallback;TypeVar[@google-cloud/spanner/common.NormalCallback.0]", + "@google-cloud/spanner.Session;@google-cloud/spanner/session-pool.GetWriteSessionCallback;Argument[1]", + "@google-cloud/spanner.Session;@google-cloud/spanner/session-pool.SessionPoolInterface;Member[release].Argument[0]", + "@google-cloud/spanner.Session;@google-cloud/spanner/session.Session;", + "@google-cloud/spanner.Session;@google-cloud/spanner/transaction-runner.Runner;Member[session]", + "@google-cloud/spanner.SessionPool;@google-cloud/spanner.SessionPoolStatic;Instance", + "@google-cloud/spanner.SessionPool;@google-cloud/spanner/instance.CreateDatabaseOptions;Member[poolCtor]", + "@google-cloud/spanner.SessionPool;@google-cloud/spanner/session-pool.SessionPool;", + "@google-cloud/spanner.SessionPoolStatic;@google-cloud/spanner/session-pool.SessionPoolStatic;", + "@google-cloud/spanner.SessionPoolStatic;@google-cloud/spanner/session-pool;Member[SessionPool]", + "@google-cloud/spanner.SessionPoolStatic;@google-cloud/spanner;Member[SessionPool]", + "@google-cloud/spanner.SessionStatic;@google-cloud/spanner/session.SessionStatic;", + "@google-cloud/spanner.SessionStatic;@google-cloud/spanner/session;Member[Session]", + "@google-cloud/spanner.SessionStatic;@google-cloud/spanner;Member[Session]", + "@google-cloud/spanner.Snapshot;@google-cloud/spanner.Session;Member[snapshot].ReturnValue", + "@google-cloud/spanner.Snapshot;@google-cloud/spanner.SnapshotStatic;Instance", + "@google-cloud/spanner.Snapshot;@google-cloud/spanner/batch-transaction.BatchTransaction;", + "@google-cloud/spanner.Snapshot;@google-cloud/spanner/database.GetSnapshotCallback;TypeVar[@google-cloud/spanner/common.NormalCallback.0]", + "@google-cloud/spanner.Snapshot;@google-cloud/spanner/transaction.Dml;", + "@google-cloud/spanner.Snapshot;@google-cloud/spanner/transaction.Snapshot;", + "@google-cloud/spanner.SnapshotStatic;@google-cloud/spanner/transaction.SnapshotStatic;", + "@google-cloud/spanner.SnapshotStatic;@google-cloud/spanner/transaction;Member[Snapshot]", + "@google-cloud/spanner.SnapshotStatic;@google-cloud/spanner;Member[Snapshot]", + "@google-cloud/spanner.Spanner;@google-cloud/spanner.InstanceStatic;Argument[0]", + "@google-cloud/spanner.Spanner;@google-cloud/spanner.SpannerStatic;Instance", + "@google-cloud/spanner.SpannerStatic;@google-cloud/spanner;Member[Spanner]", + "@google-cloud/spanner.Table;@google-cloud/spanner.Database;Member[table].ReturnValue", + "@google-cloud/spanner.Table;@google-cloud/spanner.TableStatic;Instance", + "@google-cloud/spanner.Table;@google-cloud/spanner/table.CreateTableCallback;TypeVar[@google-cloud/spanner/common.LongRunningCallback.0]", + "@google-cloud/spanner.Table;@google-cloud/spanner/table.Table;", + "@google-cloud/spanner.TableStatic;@google-cloud/spanner/table.TableStatic;", + "@google-cloud/spanner.TableStatic;@google-cloud/spanner/table;Member[Table]", + "@google-cloud/spanner.TableStatic;@google-cloud/spanner;Member[Table]", + "@google-cloud/spanner.Transaction;@google-cloud/spanner.Session;Member[transaction].ReturnValue", + "@google-cloud/spanner.Transaction;@google-cloud/spanner.Session;Member[txn]", + "@google-cloud/spanner.Transaction;@google-cloud/spanner.TransactionStatic;Instance", + "@google-cloud/spanner.Transaction;@google-cloud/spanner/database.GetTransactionCallback;TypeVar[@google-cloud/spanner/common.NormalCallback.0]", + "@google-cloud/spanner.Transaction;@google-cloud/spanner/session-pool.GetWriteSessionCallback;Argument[2]", + "@google-cloud/spanner.Transaction;@google-cloud/spanner/transaction-runner.AsyncRunTransactionCallback;Argument[0]", + "@google-cloud/spanner.Transaction;@google-cloud/spanner/transaction-runner.RunTransactionCallback;TypeVar[@google-cloud/spanner/common.NormalCallback.0]", + "@google-cloud/spanner.Transaction;@google-cloud/spanner/transaction-runner.Runner;Member[getTransaction].ReturnValue.Awaited", + "@google-cloud/spanner.Transaction;@google-cloud/spanner/transaction-runner.Runner;Member[transaction]", + "@google-cloud/spanner.Transaction;@google-cloud/spanner/transaction.Transaction;", + "@google-cloud/spanner.TransactionStatic;@google-cloud/spanner/transaction.TransactionStatic;", + "@google-cloud/spanner.TransactionStatic;@google-cloud/spanner/transaction;Member[Transaction]", + "@google-cloud/spanner.TransactionStatic;@google-cloud/spanner;Member[Transaction]", + "@google-cloud/spanner.v1.SpannerClient;@google-cloud/spanner.v1.SpannerClientStatic;Instance", + "@google-cloud/spanner.v1.SpannerClient;@google-cloud/spanner/v1/spanner_client.SpannerClient;", + "@google-cloud/spanner.v1.SpannerClientStatic;@google-cloud/spanner/v1/spanner_client.SpannerClientStatic;", + "@google-cloud/spanner.v1.SpannerClientStatic;@google-cloud/spanner/v1/spanner_client;Member[SpannerClient]", + "@google-cloud/spanner.v1.SpannerClientStatic;@google-cloud/spanner;Member[v1].Member[SpannerClient]", + "@google-cloud/spanner/batch-transaction.BatchTransaction;@google-cloud/spanner.Database;Member[batchTransaction].ReturnValue", + "@google-cloud/spanner/batch-transaction.BatchTransaction;@google-cloud/spanner/batch-transaction.BatchTransactionStatic;Instance", + "@google-cloud/spanner/batch-transaction.BatchTransaction;@google-cloud/spanner/database.CreateBatchTransactionCallback;TypeVar[@google-cloud/spanner/common.ResourceCallback.0]", + "@google-cloud/spanner/batch-transaction.BatchTransactionStatic;@google-cloud/spanner/batch-transaction;Member[BatchTransaction]", + "@google-cloud/spanner/batch-transaction.TransactionIdentifier;@google-cloud/spanner.Database;Member[batchTransaction].Argument[0]", + "@google-cloud/spanner/batch-transaction.TransactionIdentifier;@google-cloud/spanner/batch-transaction.BatchTransaction;Member[identifier].ReturnValue", + "@google-cloud/spanner/database.BatchCreateSessionsCallback;@google-cloud/spanner.Database;Member[batchCreateSessions].Argument[1]", + "@google-cloud/spanner/database.CreateBatchTransactionCallback;@google-cloud/spanner.Database;Member[createBatchTransaction].Argument[1]", + "@google-cloud/spanner/database.CreateBatchTransactionCallback;@google-cloud/spanner.Database;Member[createBatchTransaction].WithArity[1].Argument[0]", + "@google-cloud/spanner/database.CreateSessionCallback;@google-cloud/spanner.Database;Member[createSession].Argument[1]", + "@google-cloud/spanner/database.CreateSessionCallback;@google-cloud/spanner.Database;Member[createSession].WithArity[1].Argument[0]", + "@google-cloud/spanner/database.DatabaseCallback;@google-cloud/spanner.Database;Member[get].Argument[1]", + "@google-cloud/spanner/database.DatabaseCallback;@google-cloud/spanner.Database;Member[get].WithArity[1].Argument[0]", + "@google-cloud/spanner/database.GetSessionsCallback;@google-cloud/spanner.Database;Member[getSessions].Argument[1]", + "@google-cloud/spanner/database.GetSessionsCallback;@google-cloud/spanner.Database;Member[getSessions].WithArity[1].Argument[0]", + "@google-cloud/spanner/database.GetSnapshotCallback;@google-cloud/spanner.Database;Member[getSnapshot].Argument[1]", + "@google-cloud/spanner/database.GetSnapshotCallback;@google-cloud/spanner.Database;Member[getSnapshot].WithArity[1].Argument[0]", + "@google-cloud/spanner/database.GetTransactionCallback;@google-cloud/spanner.Database;Member[getTransaction].Argument[0]", + "@google-cloud/spanner/database.PoolRequestCallback;@google-cloud/spanner.Database;Member[makePooledRequest_].Argument[1]", + "@google-cloud/spanner/database.RestoreDatabaseCallback;@google-cloud/spanner.Database;Member[restore].Argument[1,2]", + "@google-cloud/spanner/database.SessionPoolConstructor;@google-cloud/spanner.DatabaseStatic;Argument[2]", + "@google-cloud/spanner/database.SessionPoolConstructor;@google-cloud/spanner.Instance;Member[database].Argument[1]", + "@google-cloud/spanner/instance.CreateDatabaseCallback;@google-cloud/spanner.Instance;Member[createDatabase].Argument[2]", + "@google-cloud/spanner/instance.CreateDatabaseCallback;@google-cloud/spanner.Instance;Member[createDatabase].WithArity[2].Argument[1]", + "@google-cloud/spanner/instance.CreateDatabaseOptions;@google-cloud/spanner.Instance;Member[createDatabase].WithArity[1,2,3].Argument[1]", + "@google-cloud/spanner/instance.CreateInstanceCallback;@google-cloud/spanner.Spanner;Member[createInstance].Argument[2]", + "@google-cloud/spanner/instance.GetDatabasesCallback;@google-cloud/spanner.Instance;Member[getDatabases].Argument[1]", + "@google-cloud/spanner/instance.GetDatabasesCallback;@google-cloud/spanner.Instance;Member[getDatabases].WithArity[1].Argument[0]", + "@google-cloud/spanner/instance.GetInstanceCallback;@google-cloud/spanner.Instance;Member[get].Argument[1]", + "@google-cloud/spanner/instance.GetInstanceCallback;@google-cloud/spanner.Instance;Member[get].WithArity[1].Argument[0]", + "@google-cloud/spanner/session-pool.GetReadSessionCallback;@google-cloud/spanner.SessionPool;Member[getReadSession].Argument[0]", + "@google-cloud/spanner/session-pool.GetReadSessionCallback;@google-cloud/spanner/session-pool.SessionPoolInterface;Member[getReadSession].Argument[0]", + "@google-cloud/spanner/session-pool.GetWriteSessionCallback;@google-cloud/spanner.SessionPool;Member[getWriteSession].Argument[0]", + "@google-cloud/spanner/session-pool.GetWriteSessionCallback;@google-cloud/spanner/session-pool.SessionPoolInterface;Member[getWriteSession].Argument[0]", + "@google-cloud/spanner/session-pool.SessionPoolInterface;@google-cloud/spanner.Database;Member[pool_]", + "@google-cloud/spanner/session-pool.SessionPoolInterface;@google-cloud/spanner.SessionPool;", + "@google-cloud/spanner/session-pool.SessionPoolInterface;@google-cloud/spanner/database.SessionPoolConstructor;Instance", + "@google-cloud/spanner/table.CreateTableCallback;@google-cloud/spanner.Database;Member[createTable].Argument[2]", + "@google-cloud/spanner/table.CreateTableCallback;@google-cloud/spanner.Database;Member[createTable].WithArity[2].Argument[1]", + "@google-cloud/spanner/table.CreateTableCallback;@google-cloud/spanner.Table;Member[create].Argument[2]", + "@google-cloud/spanner/table.CreateTableCallback;@google-cloud/spanner.Table;Member[create].WithArity[2].Argument[1]", + "@google-cloud/spanner/transaction-runner.AsyncRunTransactionCallback;@google-cloud/spanner.Database;Member[runTransactionAsync].Argument[1]", + "@google-cloud/spanner/transaction-runner.AsyncRunTransactionCallback;@google-cloud/spanner.Database;Member[runTransactionAsync].WithArity[1].Argument[0]", + "@google-cloud/spanner/transaction-runner.AsyncRunTransactionCallback;@google-cloud/spanner/transaction-runner.AsyncTransactionRunnerStatic;Argument[2]", + "@google-cloud/spanner/transaction-runner.AsyncTransactionRunner;@google-cloud/spanner/transaction-runner.AsyncTransactionRunnerStatic;Instance", + "@google-cloud/spanner/transaction-runner.AsyncTransactionRunnerStatic;@google-cloud/spanner/transaction-runner;Member[AsyncTransactionRunner]", + "@google-cloud/spanner/transaction-runner.RunTransactionCallback;@google-cloud/spanner.Database;Member[runTransaction].Argument[1]", + "@google-cloud/spanner/transaction-runner.RunTransactionCallback;@google-cloud/spanner.Database;Member[runTransaction].WithArity[1].Argument[0]", + "@google-cloud/spanner/transaction-runner.RunTransactionCallback;@google-cloud/spanner/transaction-runner.TransactionRunnerStatic;Argument[2]", + "@google-cloud/spanner/transaction-runner.Runner;@google-cloud/spanner/transaction-runner.AsyncTransactionRunner;", + "@google-cloud/spanner/transaction-runner.Runner;@google-cloud/spanner/transaction-runner.RunnerStatic;Instance", + "@google-cloud/spanner/transaction-runner.Runner;@google-cloud/spanner/transaction-runner.TransactionRunner;", + "@google-cloud/spanner/transaction-runner.RunnerStatic;@google-cloud/spanner/transaction-runner;Member[Runner]", + "@google-cloud/spanner/transaction-runner.TransactionRunner;@google-cloud/spanner/transaction-runner.TransactionRunnerStatic;Instance", + "@google-cloud/spanner/transaction-runner.TransactionRunnerStatic;@google-cloud/spanner/transaction-runner;Member[TransactionRunner]", + "@google-cloud/spanner/transaction.Dml;@google-cloud/spanner.PartitionedDml;", + "@google-cloud/spanner/transaction.Dml;@google-cloud/spanner.Transaction;", + "@google-cloud/spanner/transaction.Dml;@google-cloud/spanner/transaction.DmlStatic;Instance", + "@google-cloud/spanner/transaction.DmlStatic;@google-cloud/spanner/transaction;Member[Dml]" ], "summaries": [], "typeVariables": [ diff --git a/javascript/ql/lib/semmle/javascript/frameworks/sqlite3/Model.qll b/javascript/ql/lib/semmle/javascript/frameworks/sqlite3/Model.qll index 727408e7569..86bc0efd72b 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/sqlite3/Model.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/sqlite3/Model.qll @@ -6,21 +6,21 @@ private class Types extends ModelInput::TypeModelCsv { override predicate row(string row) { row = [ - "sqlite3;Database;sqlite3;;Member[cached].Member[Database].ReturnValue", // - "sqlite3;Database;sqlite3;Database;Member[addListener,all,each,exec,get,on,once,prependListener,prependOnceListener,run].ReturnValue", // - "sqlite3;Database;sqlite3;DatabaseStatic;Instance", // - "sqlite3;Database;sqlite3;Statement;Member[finalize].ReturnValue", // - "sqlite3;DatabaseStatic;sqlite3;;Member[Database]", // - "sqlite3;DatabaseStatic;sqlite3;sqlite3;Member[Database]", // - "sqlite3;RunResult;sqlite3;sqlite3;Member[RunResult]", // - "sqlite3;Statement;sqlite3;Database;Member[prepare].ReturnValue", // - "sqlite3;Statement;sqlite3;RunResult;", // - "sqlite3;Statement;sqlite3;Statement;Member[all,bind,each,get,reset,run].ReturnValue", // - "sqlite3;Statement;sqlite3;StatementStatic;Instance", // - "sqlite3;StatementStatic;sqlite3;;Member[Statement]", // - "sqlite3;StatementStatic;sqlite3;sqlite3;Member[Statement]", // - "sqlite3;sqlite3;sqlite3;;Member[verbose].ReturnValue", // - "sqlite3;sqlite3;sqlite3;sqlite3;Member[verbose].ReturnValue", // + "sqlite3.Database;sqlite3.Database;Member[addListener,all,each,exec,get,on,once,prependListener,prependOnceListener,run].ReturnValue", // + "sqlite3.Database;sqlite3.DatabaseStatic;Instance", // + "sqlite3.Database;sqlite3.Statement;Member[finalize].ReturnValue", // + "sqlite3.Database;sqlite3;Member[cached].Member[Database].ReturnValue", // + "sqlite3.DatabaseStatic;sqlite3.sqlite3;Member[Database]", // + "sqlite3.DatabaseStatic;sqlite3;Member[Database]", // + "sqlite3.RunResult;sqlite3.sqlite3;Member[RunResult]", // + "sqlite3.Statement;sqlite3.Database;Member[prepare].ReturnValue", // + "sqlite3.Statement;sqlite3.RunResult;", // + "sqlite3.Statement;sqlite3.Statement;Member[all,bind,each,get,reset,run].ReturnValue", // + "sqlite3.Statement;sqlite3.StatementStatic;Instance", // + "sqlite3.StatementStatic;sqlite3.sqlite3;Member[Statement]", // + "sqlite3.StatementStatic;sqlite3;Member[Statement]", // + "sqlite3.sqlite3;sqlite3.sqlite3;Member[verbose].ReturnValue", // + "sqlite3.sqlite3;sqlite3;Member[verbose].ReturnValue", // ] } } @@ -29,9 +29,9 @@ private class Summaries extends ModelInput::SummaryModelCsv { override predicate row(string row) { row = [ - "sqlite3;Database;;;Member[addListener,all,each,exec,get,on,once,prependListener,prependOnceListener,run].ReturnValue;type", // - "sqlite3;Statement;;;Member[all,bind,each,get,reset,run].ReturnValue;type", // - "sqlite3;sqlite3;;;Member[verbose].ReturnValue;type", // + "sqlite3.Database;;;Member[addListener,all,each,exec,get,on,once,prependListener,prependOnceListener,run].ReturnValue;type", // + "sqlite3.Statement;;;Member[all,bind,each,get,reset,run].ReturnValue;type", // + "sqlite3.sqlite3;;;Member[verbose].ReturnValue;type", // ] } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/sqlite3/model.json b/javascript/ql/lib/semmle/javascript/frameworks/sqlite3/model.json index 2cc41498ead..2d9a919bd1f 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/sqlite3/model.json +++ b/javascript/ql/lib/semmle/javascript/frameworks/sqlite3/model.json @@ -8,7 +8,7 @@ "language": "javascript", "usedTypes": { "sources": [ - "sqlite3;Database" + "sqlite3.Database" ] }, "model": { @@ -17,26 +17,26 @@ "generatedModel": { "//": "Autogenerated section. Manual edits in here will be lost.", "typeDefinitions": [ - "sqlite3;Database;sqlite3;;Member[cached].Member[Database].ReturnValue", - "sqlite3;Database;sqlite3;Database;Member[addListener,all,each,exec,get,on,once,prependListener,prependOnceListener,run].ReturnValue", - "sqlite3;Database;sqlite3;DatabaseStatic;Instance", - "sqlite3;Database;sqlite3;Statement;Member[finalize].ReturnValue", - "sqlite3;DatabaseStatic;sqlite3;;Member[Database]", - "sqlite3;DatabaseStatic;sqlite3;sqlite3;Member[Database]", - "sqlite3;RunResult;sqlite3;sqlite3;Member[RunResult]", - "sqlite3;Statement;sqlite3;Database;Member[prepare].ReturnValue", - "sqlite3;Statement;sqlite3;RunResult;", - "sqlite3;Statement;sqlite3;Statement;Member[all,bind,each,get,reset,run].ReturnValue", - "sqlite3;Statement;sqlite3;StatementStatic;Instance", - "sqlite3;StatementStatic;sqlite3;;Member[Statement]", - "sqlite3;StatementStatic;sqlite3;sqlite3;Member[Statement]", - "sqlite3;sqlite3;sqlite3;;Member[verbose].ReturnValue", - "sqlite3;sqlite3;sqlite3;sqlite3;Member[verbose].ReturnValue" + "sqlite3.Database;sqlite3.Database;Member[addListener,all,each,exec,get,on,once,prependListener,prependOnceListener,run].ReturnValue", + "sqlite3.Database;sqlite3.DatabaseStatic;Instance", + "sqlite3.Database;sqlite3.Statement;Member[finalize].ReturnValue", + "sqlite3.Database;sqlite3;Member[cached].Member[Database].ReturnValue", + "sqlite3.DatabaseStatic;sqlite3.sqlite3;Member[Database]", + "sqlite3.DatabaseStatic;sqlite3;Member[Database]", + "sqlite3.RunResult;sqlite3.sqlite3;Member[RunResult]", + "sqlite3.Statement;sqlite3.Database;Member[prepare].ReturnValue", + "sqlite3.Statement;sqlite3.RunResult;", + "sqlite3.Statement;sqlite3.Statement;Member[all,bind,each,get,reset,run].ReturnValue", + "sqlite3.Statement;sqlite3.StatementStatic;Instance", + "sqlite3.StatementStatic;sqlite3.sqlite3;Member[Statement]", + "sqlite3.StatementStatic;sqlite3;Member[Statement]", + "sqlite3.sqlite3;sqlite3.sqlite3;Member[verbose].ReturnValue", + "sqlite3.sqlite3;sqlite3;Member[verbose].ReturnValue" ], "summaries": [ - "sqlite3;Database;;;Member[addListener,all,each,exec,get,on,once,prependListener,prependOnceListener,run].ReturnValue;type", - "sqlite3;Statement;;;Member[all,bind,each,get,reset,run].ReturnValue;type", - "sqlite3;sqlite3;;;Member[verbose].ReturnValue;type" + "sqlite3.Database;;;Member[addListener,all,each,exec,get,on,once,prependListener,prependOnceListener,run].ReturnValue;type", + "sqlite3.Statement;;;Member[all,bind,each,get,reset,run].ReturnValue;type", + "sqlite3.sqlite3;;;Member[verbose].ReturnValue;type" ], "typeVariables": [] } diff --git a/javascript/ql/test/ApiGraphs/typed/NodeOfType.expected b/javascript/ql/test/ApiGraphs/typed/NodeOfType.expected index 0f237bfe6f2..da535a9c14c 100644 --- a/javascript/ql/test/ApiGraphs/typed/NodeOfType.expected +++ b/javascript/ql/test/ApiGraphs/typed/NodeOfType.expected @@ -24,7 +24,12 @@ getANodeOfType | puppeteer | | index.ts:26:8:26:21 | * as puppeteer | | puppeteer | Browser | index.ts:30:22:30:33 | this.browser | getANodeOfTypeRaw +| body-parser | | index.ts:4:20:4:41 | require ... arser") | +| express | | index.ts:3:17:3:34 | require("express") | +| mongodb | | index.ts:1:8:1:19 | * as mongodb | | mongodb | Collection | index.ts:14:3:14:17 | getCollection() | +| mongoose | | index.ts:17:8:17:20 | * as mongoose | | mongoose | Model | index.ts:22:3:22:20 | getMongooseModel() | | mongoose | Query | index.ts:23:3:23:20 | getMongooseQuery() | +| puppeteer | | index.ts:26:8:26:21 | * as puppeteer | | puppeteer | Browser | index.ts:30:22:30:33 | this.browser | diff --git a/javascript/ql/test/library-tests/frameworks/data/test.expected b/javascript/ql/test/library-tests/frameworks/data/test.expected index 138547cc7ff..39439f64629 100644 --- a/javascript/ql/test/library-tests/frameworks/data/test.expected +++ b/javascript/ql/test/library-tests/frameworks/data/test.expected @@ -147,3 +147,4 @@ syntaxErrors | Member[foo]Member[bar] | | Member[foo]] | | Member[foo]].Member[bar] | +warning diff --git a/javascript/ql/test/library-tests/frameworks/data/test.ql b/javascript/ql/test/library-tests/frameworks/data/test.ql index 053e41e22ff..c5e3ce9ea8c 100644 --- a/javascript/ql/test/library-tests/frameworks/data/test.ql +++ b/javascript/ql/test/library-tests/frameworks/data/test.ql @@ -4,17 +4,17 @@ import semmle.javascript.frameworks.data.internal.AccessPathSyntax as AccessPath class Steps extends ModelInput::SummaryModelCsv { override predicate row(string row) { - // package;type;path;input;output;kind + // type;path;input;output;kind row = [ - "testlib;;Member[preserveTaint];Argument[0];ReturnValue;taint", - "testlib;;Member[taintIntoCallback];Argument[0];Argument[1..2].Parameter[0];taint", - "testlib;;Member[taintIntoCallbackThis];Argument[0];Argument[1..2].Parameter[this];taint", - "testlib;;Member[preserveArgZeroAndTwo];Argument[0,2];ReturnValue;taint", - "testlib;;Member[preserveAllButFirstArgument];Argument[1..];ReturnValue;taint", - "testlib;;Member[preserveAllIfCall].Call;Argument[0..];ReturnValue;taint", - "testlib;;Member[getSource].ReturnValue.Member[continue];Argument[this];ReturnValue;taint", - "testlib;~HasThisFlow;;;Member[getThis].ReturnValue;type", + "testlib;Member[preserveTaint];Argument[0];ReturnValue;taint", + "testlib;Member[taintIntoCallback];Argument[0];Argument[1..2].Parameter[0];taint", + "testlib;Member[taintIntoCallbackThis];Argument[0];Argument[1..2].Parameter[this];taint", + "testlib;Member[preserveArgZeroAndTwo];Argument[0,2];ReturnValue;taint", + "testlib;Member[preserveAllButFirstArgument];Argument[1..];ReturnValue;taint", + "testlib;Member[preserveAllIfCall].Call;Argument[0..];ReturnValue;taint", + "testlib;Member[getSource].ReturnValue.Member[continue];Argument[this];ReturnValue;taint", + "testlib.~HasThisFlow;;;Member[getThis].ReturnValue;type", ] } } @@ -23,37 +23,37 @@ class TypeDefs extends ModelInput::TypeModelCsv { override predicate row(string row) { row = [ - "testlib;~HasThisFlow;testlib;;Member[typevar]", - "testlib;~HasThisFlow;testlib;~HasThisFlow;Member[left,right,x]", + "testlib.~HasThisFlow;testlib;Member[typevar]", + "testlib.~HasThisFlow;testlib.~HasThisFlow;Member[left,right,x]", ] } } class Sinks extends ModelInput::SinkModelCsv { override predicate row(string row) { - // package;type;path;kind + // type;path;kind row = [ - "testlib;;Member[mySink].Argument[0];test-sink", - "testlib;;Member[mySinkIfCall].Call.Argument[0];test-sink", - "testlib;;Member[mySinkIfNew].NewCall.Argument[0];test-sink", - "testlib;;Member[mySinkLast].Argument[N-1];test-sink", - "testlib;;Member[mySinkSecondLast].Argument[N-2];test-sink", - "testlib;;Member[mySinkTwoLast].Argument[N-1,N-2];test-sink", - "testlib;;Member[mySinkTwoLastRange].Argument[N-2..N-1];test-sink", - "testlib;;Member[mySinkExceptLast].Argument[0..N-2];test-sink", - "testlib;;Member[mySinkIfArityTwo].WithArity[2].Argument[0];test-sink", - "testlib;;Member[sink1, sink2, sink3 ].Argument[0];test-sink", - "testlib;;Member[ClassDecorator].DecoratedClass.Instance.Member[returnValueIsSink].ReturnValue;test-sink", - "testlib;;Member[FieldDecoratorSink].DecoratedMember;test-sink", - "testlib;;Member[MethodDecorator].DecoratedMember.ReturnValue;test-sink", - "testlib;;Member[MethodDecoratorWithArgs].ReturnValue.DecoratedMember.ReturnValue;test-sink", - "testlib;;Member[ParamDecoratorSink].DecoratedParameter;test-sink", - "testlib;;AnyMember.Member[memberSink].Argument[0];test-sink", - "testlib;;Member[overloadedSink].WithStringArgument[0=danger].Argument[1];test-sink", - "testlib;;Member[typevar].TypeVar[ABC].Member[mySink].Argument[0];test-sink", - "testlib;;Member[typevar].TypeVar[ABC].TypeVar[ABC].Member[mySink].Argument[1];test-sink", - "testlib;;Member[typevar].TypeVar[LeftRight].Member[mySink].Argument[0];test-sink", + "testlib;Member[mySink].Argument[0];test-sink", + "testlib;Member[mySinkIfCall].Call.Argument[0];test-sink", + "testlib;Member[mySinkIfNew].NewCall.Argument[0];test-sink", + "testlib;Member[mySinkLast].Argument[N-1];test-sink", + "testlib;Member[mySinkSecondLast].Argument[N-2];test-sink", + "testlib;Member[mySinkTwoLast].Argument[N-1,N-2];test-sink", + "testlib;Member[mySinkTwoLastRange].Argument[N-2..N-1];test-sink", + "testlib;Member[mySinkExceptLast].Argument[0..N-2];test-sink", + "testlib;Member[mySinkIfArityTwo].WithArity[2].Argument[0];test-sink", + "testlib;Member[sink1, sink2, sink3 ].Argument[0];test-sink", + "testlib;Member[ClassDecorator].DecoratedClass.Instance.Member[returnValueIsSink].ReturnValue;test-sink", + "testlib;Member[FieldDecoratorSink].DecoratedMember;test-sink", + "testlib;Member[MethodDecorator].DecoratedMember.ReturnValue;test-sink", + "testlib;Member[MethodDecoratorWithArgs].ReturnValue.DecoratedMember.ReturnValue;test-sink", + "testlib;Member[ParamDecoratorSink].DecoratedParameter;test-sink", + "testlib;AnyMember.Member[memberSink].Argument[0];test-sink", + "testlib;Member[overloadedSink].WithStringArgument[0=danger].Argument[1];test-sink", + "testlib;Member[typevar].TypeVar[ABC].Member[mySink].Argument[0];test-sink", + "testlib;Member[typevar].TypeVar[ABC].TypeVar[ABC].Member[mySink].Argument[1];test-sink", + "testlib;Member[typevar].TypeVar[LeftRight].Member[mySink].Argument[0];test-sink", ] } } @@ -73,12 +73,12 @@ class Sources extends ModelInput::SourceModelCsv { override predicate row(string row) { row = [ - "testlib;;Member[getSource].ReturnValue;test-source", - "testlib;;Member[ClassDecorator].DecoratedClass.Instance.Member[inputIsSource].Parameter[0];test-source", - "testlib;;Member[FieldDecoratorSource].DecoratedMember;test-source", - "testlib;;Member[ParamDecoratorSource].DecoratedParameter;test-source", - "testlib;;Member[MethodDecorator].DecoratedMember.Parameter[0];test-source", - "testlib;;Member[MethodDecoratorWithArgs].ReturnValue.DecoratedMember.Parameter[0];test-source", + "testlib;Member[getSource].ReturnValue;test-source", + "testlib;Member[ClassDecorator].DecoratedClass.Instance.Member[inputIsSource].Parameter[0];test-source", + "testlib;Member[FieldDecoratorSource].DecoratedMember;test-source", + "testlib;Member[ParamDecoratorSource].DecoratedParameter;test-source", + "testlib;Member[MethodDecorator].DecoratedMember.Parameter[0];test-source", + "testlib;Member[MethodDecoratorWithArgs].ReturnValue.DecoratedMember.Parameter[0];test-source", ] } } @@ -111,15 +111,20 @@ class SyntaxErrorTest extends ModelInput::SinkModelCsv { override predicate row(string row) { row = [ - "testlib;;Member[foo],Member[bar];test-sink", "testlib;;Member[foo] Member[bar];test-sink", - "testlib;;Member[foo]. Member[bar];test-sink", - "testlib;;Member[foo], Member[bar];test-sink", - "testlib;;Member[foo]..Member[bar];test-sink", - "testlib;;Member[foo] .Member[bar];test-sink", "testlib;;Member[foo]Member[bar];test-sink", - "testlib;;Member[foo;test-sink", "testlib;;Member[foo]];test-sink", - "testlib;;Member[foo]].Member[bar];test-sink" + "testlib;Member[foo],Member[bar];test-sink", // + "testlib;Member[foo] Member[bar];test-sink", // + "testlib;Member[foo]. Member[bar];test-sink", // + "testlib;Member[foo], Member[bar];test-sink", // + "testlib;Member[foo]..Member[bar];test-sink", // + "testlib;Member[foo] .Member[bar];test-sink", // + "testlib;Member[foo]Member[bar];test-sink", // + "testlib;Member[foo;test-sink", // + "testlib;Member[foo]];test-sink", // + "testlib;Member[foo]].Member[bar];test-sink" ] } } query predicate syntaxErrors(AccessPathSyntax::AccessPath path) { path.hasSyntaxError() } + +query predicate warning = ModelOutput::getAWarning/0; diff --git a/javascript/ql/test/library-tests/frameworks/data/warnings.expected b/javascript/ql/test/library-tests/frameworks/data/warnings.expected index 7ba231c9627..cfb4265b2c8 100644 --- a/javascript/ql/test/library-tests/frameworks/data/warnings.expected +++ b/javascript/ql/test/library-tests/frameworks/data/warnings.expected @@ -1,5 +1,5 @@ -| CSV type row should have 5 columns but has 2: test;TooFewColumns | -| CSV type row should have 5 columns but has 8: test;TooManyColumns;;;Member[Foo].Instance;too;many;columns | +| CSV type row should have 3 columns but has 1: test.TooFewColumns | +| CSV type row should have 3 columns but has 6: test.TooManyColumns;;Member[Foo].Instance;too;many;columns | | Invalid argument '0-1' in token 'Argument[0-1]' in access path: Method[foo].Argument[0-1] | | Invalid argument '*' in token 'Argument[*]' in access path: Method[foo].Argument[*] | | Invalid token 'Argument' is missing its arguments, in access path: Method[foo].Argument | diff --git a/javascript/ql/test/library-tests/frameworks/data/warnings.ql b/javascript/ql/test/library-tests/frameworks/data/warnings.ql index 9ae05b8dcc0..94e6f74aae7 100644 --- a/javascript/ql/test/library-tests/frameworks/data/warnings.ql +++ b/javascript/ql/test/library-tests/frameworks/data/warnings.ql @@ -6,13 +6,13 @@ private class InvalidTypeModel extends ModelInput::TypeModelCsv { override predicate row(string row) { row = [ - "test;TooManyColumns;;;Member[Foo].Instance;too;many;columns", // - "test;TooFewColumns", // - "test;X;test;Y;Method[foo].Arg[0]", // - "test;X;test;Y;Method[foo].Argument[0-1]", // - "test;X;test;Y;Method[foo].Argument[*]", // - "test;X;test;Y;Method[foo].Argument", // - "test;X;test;Y;Method[foo].Member", // + "test.TooManyColumns;;Member[Foo].Instance;too;many;columns", // + "test.TooFewColumns", // + "test.X;test.Y;Method[foo].Arg[0]", // + "test.X;test.Y;Method[foo].Argument[0-1]", // + "test.X;test.Y;Method[foo].Argument[*]", // + "test.X;test.Y;Method[foo].Argument", // + "test.X;test.Y;Method[foo].Member", // ] } } From 22316ee4fe0159413b6b99ccb7a8b5d799137efa Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 11 Nov 2022 16:42:51 +0100 Subject: [PATCH 467/796] Ruby: merge package/type columns --- .../dataflow/internal/DataFlowPrivate.qll | 2 +- .../codeql/ruby/frameworks/ActionDispatch.qll | 19 +- .../codeql/ruby/frameworks/ActiveStorage.qll | 18 +- .../codeql/ruby/frameworks/ActiveSupport.qll | 14 +- .../codeql/ruby/frameworks/core/Regexp.qll | 2 +- .../ruby/frameworks/data/ModelsAsData.qll | 11 +- .../data/internal/ApiGraphModels.qll | 312 ++++++++---------- .../data/internal/ApiGraphModelsSpecific.qll | 115 +++++-- .../ruby/frameworks/stdlib/Pathname.qll | 52 ++- .../dataflow/local/TaintStep.expected | 22 -- .../dataflow/summaries/Summaries.expected | 4 +- .../dataflow/summaries/Summaries.ql | 94 +++--- .../frameworks/ActionDispatch.ql | 4 +- .../frameworks/pathname/Pathname.expected | 24 +- 14 files changed, 341 insertions(+), 352 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index 8c9c8242c71..205f75ab535 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -474,7 +474,7 @@ private module Cached { // external model data. This, unfortunately, does not included any field names used // in models defined in QL code. exists(string input, string output | - ModelOutput::relevantSummaryModel(_, _, _, input, output, _) + ModelOutput::relevantSummaryModel(_, _, input, output, _) | name = [input, output].regexpFind("(?<=(^|\\.)Field\\[)[^\\]]+(?=\\])", _, _).trim() ) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActionDispatch.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActionDispatch.qll index e9ff9d5c86a..cc898abe034 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActionDispatch.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActionDispatch.qll @@ -21,23 +21,21 @@ module ActionDispatch { */ private class MimeTypeTypeSummary extends ModelInput::TypeModelCsv { override predicate row(string row) { - // package1;type1;package2;type2;path + // type1;type2;path row = [ // Mime[type] : Mime::Type (omitted) // Method names with brackets like [] cannot be represented in MaD. // Mime.fetch(type) : Mime::Type - "actiondispatch;Mime::Type;;;Member[Mime].Method[fetch].ReturnValue", - // Mime::Type.new(str) : Mime::Type - "actiondispatch;Mime::Type;;;Member[Mime].Member[Type].Instance", + "Mime::Type;Mime!;Method[fetch].ReturnValue", // Mime::Type.lookup(str) : Mime::Type - "actiondispatch;Mime::Type;;;Member[Mime].Member[Type].Method[lookup].ReturnValue", + "Mime::Type;Mime::Type!;Method[lookup].ReturnValue", // Mime::Type.lookup_by_extension(str) : Mime::Type - "actiondispatch;Mime::Type;;;Member[Mime].Member[Type].Method[lookup_by_extension].ReturnValue", + "Mime::Type;Mime::Type!;Method[lookup_by_extension].ReturnValue", // Mime::Type.register(str) : Mime::Type - "actiondispatch;Mime::Type;;;Member[Mime].Member[Type].Method[register].ReturnValue", + "Mime::Type;Mime::Type!;Method[register].ReturnValue", // Mime::Type.register_alias(str) : Mime::Type - "actiondispatch;Mime::Type;;;Member[Mime].Member[Type].Method[register_alias].ReturnValue", + "Mime::Type;Mime::Type!;Method[register_alias].ReturnValue", ] } } @@ -48,10 +46,7 @@ module ActionDispatch { */ class MimeTypeMatchRegExpInterpretation extends RE::RegExpInterpretation::Range { MimeTypeMatchRegExpInterpretation() { - this = - ModelOutput::getATypeNode("actiondispatch", "Mime::Type") - .getAMethodCall(["match?", "=~"]) - .getArgument(0) + this = ModelOutput::getATypeNode("Mime::Type").getAMethodCall(["match?", "=~"]).getArgument(0) } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveStorage.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveStorage.qll index 389ac9ee64d..9fe157842d7 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveStorage.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveStorage.qll @@ -31,8 +31,8 @@ module ActiveStorage { override predicate row(string row) { row = [ - "activestorage;;Member[ActiveStorage].Member[Filename].Method[new];Argument[0];ReturnValue;taint", - "activestorage;;Member[ActiveStorage].Member[Filename].Instance.Method[sanitized];Argument[self];ReturnValue;taint", + "ActiveStorage::Filename!;Method[new];Argument[0];ReturnValue;taint", + "ActiveStorage::Filename;Method[sanitized];Argument[self];ReturnValue;taint", ] } } @@ -45,25 +45,23 @@ module ActiveStorage { // package1;type1;package2;type2;path row = [ - // ActiveStorage::Blob.new : Blob - "activestorage;Blob;activestorage;;Member[ActiveStorage].Member[Blob].Instance", // ActiveStorage::Blob.create_and_upload! : Blob - "activestorage;Blob;activestorage;;Member[ActiveStorage].Member[Blob].Method[create_and_upload!].ReturnValue", + "ActiveStorage::Blob;ActiveStorage::Blob!;Method[create_and_upload!].ReturnValue", // ActiveStorage::Blob.create_before_direct_upload! : Blob - "activestorage;Blob;activestorage;;Member[ActiveStorage].Member[Blob].Method[create_before_direct_upload!].ReturnValue", + "ActiveStorage::Blob;ActiveStorage::Blob!;Method[create_before_direct_upload!].ReturnValue", // ActiveStorage::Blob.compose(blobs : [Blob]) : Blob - "activestorage;Blob;activestorage;;Member[ActiveStorage].Member[Blob].Method[compose].ReturnValue", + "ActiveStorage::Blob;ActiveStorage::Blob!;Method[compose].ReturnValue", // gives error: Invalid name 'Element' in access path - // "activestorage;Blob;activestorage;;Member[ActiveStorage].Member[Blob].Method[compose].Argument[0].Element[any]", + // "ActiveStorage::Blob;ActiveStorage::Blob!;Method[compose].Argument[0].Element[any]", // ActiveStorage::Blob.find_signed(!) : Blob - "activestorage;Blob;activestorage;;Member[ActiveStorage].Member[Blob].Method[find_signed,find_signed!].ReturnValue", + "ActiveStorage::Blob;ActiveStorage::Blob!;Method[find_signed,find_signed!].ReturnValue", ] } } private class BlobInstance extends DataFlow::Node { BlobInstance() { - this = ModelOutput::getATypeNode("activestorage", "Blob").getAValueReachableFromSource() + this = ModelOutput::getATypeNode("ActiveStorage::Blob").getAValueReachableFromSource() or // ActiveStorage::Attachment#blob : Blob exists(DataFlow::CallNode call | diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll index 7d3286a0a74..bb08594c227 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll @@ -317,9 +317,9 @@ module ActiveSupport { */ private class PathnameTypeSummary extends ModelInput::TypeModelCsv { override predicate row(string row) { - // package1;type1;package2;type2;path + // type1;type2;path // Pathname#existence : Pathname - row = ";Pathname;;Pathname;Method[existence].ReturnValue" + row = "Pathname;Pathname;Method[existence].ReturnValue" } } @@ -327,7 +327,7 @@ module ActiveSupport { private class PathnameTaintSummary extends ModelInput::SummaryModelCsv { override predicate row(string row) { // Pathname#existence - row = ";Pathname;Method[existence];Argument[self];ReturnValue;taint" + row = "Pathname;Method[existence];Argument[self];ReturnValue;taint" } } @@ -345,12 +345,12 @@ module ActiveSupport { row = [ // SafeBuffer.new(x) does not sanitize x - "activesupport;;Member[ActionView].Member[SafeBuffer].Method[new];Argument[0];ReturnValue;taint", + "ActionView::SafeBuffer!;Method[new];Argument[0];ReturnValue;taint", // SafeBuffer#safe_concat(x) does not sanitize x - "activesupport;;Member[ActionView].Member[SafeBuffer].Instance.Method[safe_concat];Argument[0];ReturnValue;taint", - "activesupport;;Member[ActionView].Member[SafeBuffer].Instance.Method[safe_concat];Argument[0];Argument[self];taint", + "ActionView::SafeBuffer;Method[safe_concat];Argument[0];ReturnValue;taint", + "ActionView::SafeBuffer;Method[safe_concat];Argument[0];Argument[self];taint", // These methods preserve taint in self - "activesupport;;Member[ActionView].Member[SafeBuffer].Instance.Method[concat,insert,prepend,to_s,to_param];Argument[self];ReturnValue;taint", + "ActionView::SafeBuffer;Method[concat,insert,prepend,to_s,to_param];Argument[self];ReturnValue;taint", ] } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/Regexp.qll b/ruby/ql/lib/codeql/ruby/frameworks/core/Regexp.qll index cea79f19cf1..581c0d581c9 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/core/Regexp.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/core/Regexp.qll @@ -13,7 +13,7 @@ module Regexp { /** A flow summary for `Regexp.escape` and its alias, `Regexp.quote`. */ class RegexpEscapeSummary extends ModelInput::SummaryModelCsv { override predicate row(string row) { - row = ";;Member[Regexp].Method[escape,quote];Argument[0];ReturnValue;taint" + row = "Regexp!;Method[escape,quote];Argument[0];ReturnValue;taint" } } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/ModelsAsData.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/ModelsAsData.qll index 8302a2c4300..2e3fa21a45b 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/ModelsAsData.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/ModelsAsData.qll @@ -33,26 +33,23 @@ private class RemoteFlowSourceFromCsv extends RemoteFlowSource::Range { } private class SummarizedCallableFromModel extends SummarizedCallable { - string package; string type; string path; SummarizedCallableFromModel() { - ModelOutput::relevantSummaryModel(package, type, path, _, _, _) and - this = package + ";" + type + ";" + path + ModelOutput::relevantSummaryModel(type, path, _, _, _) and + this = type + ";" + path } override Call getACall() { exists(API::MethodAccessNode base | - ModelOutput::resolvedSummaryBase(package, type, path, base) and + ModelOutput::resolvedSummaryBase(type, path, base) and result = base.getCallNode().asExpr().getExpr() ) } override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { - exists(string kind | - ModelOutput::relevantSummaryModel(package, type, path, input, output, kind) - | + exists(string kind | ModelOutput::relevantSummaryModel(type, path, input, output, kind) | kind = "value" and preservesValue = true or diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll index 9b2428f3413..0e744ba801a 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll @@ -5,23 +5,20 @@ * * The CSV specification has the following columns: * - Sources: - * `package; type; path; kind` + * `type; path; kind` * - Sinks: - * `package; type; path; kind` + * `type; path; kind` * - Summaries: - * `package; type; path; input; output; kind` + * `type; path; input; output; kind` * - Types: - * `package1; type1; package2; type2; path` + * `type1; type2; path` * * The interpretation of a row is similar to API-graphs with a left-to-right * reading. - * 1. The `package` column selects a package name, as it would be referenced in the source code, - * such as an NPM package, PIP package, or Ruby gem. (See `ModelsAsData.qll` for language-specific details). - * It may also be a synthetic package used for a type definition (see type definitions below). - * 2. The `type` column selects all instances of a named type originating from that package, - * or the empty string if referring to the package itself. + * 1. The `type` column selects all instances of a named type. The syntax of this column is language-specific. + * The language defines some type names that the analysis knows how to identify without models. * It can also be a synthetic type name defined by a type definition (see type definitions below). - * 3. The `path` column is a `.`-separated list of "access path tokens" to resolve, starting at the node selected by `package` and `type`. + * 2. The `path` column is a `.`-separated list of "access path tokens" to resolve, starting at the node selected by `type`. * * Every language supports the following tokens: * - Argument[n]: the n-th argument to a call. May be a range of form `x..y` (inclusive) and/or a comma-separated list. @@ -42,10 +39,10 @@ * * For the time being, please consult `ApiGraphModelsSpecific.qll` to see which language-specific tokens are currently supported. * - * 4. The `input` and `output` columns specify how data enters and leaves the element selected by the - * first `(package, type, path)` tuple. Both strings are `.`-separated access paths + * 3. The `input` and `output` columns specify how data enters and leaves the element selected by the + * first `(type, path)` tuple. Both strings are `.`-separated access paths * of the same syntax as the `path` column. - * 5. The `kind` column is a tag that can be referenced from QL to determine to + * 4. The `kind` column is a tag that can be referenced from QL to determine to * which classes the interpreted elements should be added. For example, for * sources `"remote"` indicates a default remote flow source, and for summaries * `"taint"` indicates a default additional taint step and `"value"` indicates a @@ -53,17 +50,17 @@ * * ### Types * - * A type row of form `package1; type1; package2; type2; path` indicates that `package2; type2; path` - * should be seen as an instance of the type `package1; type1`. + * A type row of form `type1; type2; path` indicates that `type2; path` + * should be seen as an instance of the type `type1`. * - * A `(package,type)` pair may refer to a static type or a synthetic type name used internally in the model. + * A type may refer to a static type or a synthetic type name used internally in the model. * Synthetic type names can be used to reuse intermediate sub-paths, when there are multiple ways to access the same * element. - * See `ModelsAsData.qll` for the language-specific interpretation of packages and static type names. + * See `ModelsAsData.qll` for the language-specific interpretation of type names. * - * By convention, if one wants to avoid clashes with static types from the package, the type name - * should be prefixed with a tilde character (`~`). For example, `(foo, ~Bar)` can be used to indicate that - * the type is related to the `foo` package but is not intended to match a static type. + * By convention, if one wants to avoid clashes with static types, the type name + * should be prefixed with a tilde character (`~`). For example, `~Bar` can be used to indicate that + * the type is not intended to match a static type. */ private import ApiGraphModelsSpecific as Specific @@ -89,9 +86,9 @@ module ModelInput { * * A row of form * ``` - * package;type;path;kind + * type;path;kind * ``` - * indicates that the value at `(package, type, path)` should be seen as a flow + * indicates that the value at `(type, path)` should be seen as a flow * source of the given `kind`. * * The kind `remote` represents a general remote flow source. @@ -110,9 +107,9 @@ module ModelInput { * * A row of form * ``` - * package;type;path;kind + * type;path;kind * ``` - * indicates that the value at `(package, type, path)` should be seen as a sink + * indicates that the value at `(type, path)` should be seen as a sink * of the given `kind`. */ abstract predicate row(string row); @@ -129,9 +126,9 @@ module ModelInput { * * A row of form * ``` - * package;type;path;input;output;kind + * type;path;input;output;kind * ``` - * indicates that for each call to `(package, type, path)`, the value referred to by `input` + * indicates that for each call to `(type, path)`, the value referred to by `input` * can flow to the value referred to by `output`. * * `kind` should be either `value` or `taint`, for value-preserving or taint-preserving steps, @@ -151,9 +148,9 @@ module ModelInput { * * A row of form, * ``` - * package1;type1;package2;type2;path + * type1;type2;path * ``` - * indicates that `(package2, type2, path)` should be seen as an instance of `(package1, type1)`. + * indicates that `(type2, path)` should be seen as an instance of `type1`. */ abstract predicate row(string row); } @@ -163,28 +160,28 @@ module ModelInput { */ class TypeModel extends Unit { /** - * Gets a data-flow node that is a source of the type `package;type`. + * Gets a data-flow node that is a source of the given `type`. * * This must not depend on API graphs, but ensures that an API node is generated for * the source. */ - DataFlow::Node getASource(string package, string type) { none() } + DataFlow::Node getASource(string type) { none() } /** - * Gets a data-flow node that is a sink of the type `package;type`, + * Gets a data-flow node that is a sink of the given `type`, * usually because it is an argument passed to a parameter of that type. * * This must not depend on API graphs, but ensures that an API node is generated for * the sink. */ - DataFlow::Node getASink(string package, string type) { none() } + DataFlow::Node getASink(string type) { none() } /** - * Gets an API node that is a source or sink of the type `package;type`. + * Gets an API node that is a source or sink of the given `type`. * * Unlike `getASource` and `getASink`, this may depend on API graphs. */ - API::Node getAnApiNode(string package, string type) { none() } + API::Node getAnApiNode(string type) { none() } } /** @@ -209,7 +206,7 @@ private import ModelInput /** * An empty class, except in specific tests. * - * If this is non-empty, all models are parsed even if the package is not + * If this is non-empty, all models are parsed even if the type name is not * considered relevant for the current database. */ abstract class TestAllModels extends Unit { } @@ -232,53 +229,44 @@ private predicate typeModel(string row) { any(TypeModelCsv s).row(inversePad(row private predicate typeVariableModel(string row) { any(TypeVariableModelCsv s).row(inversePad(row)) } /** Holds if a source model exists for the given parameters. */ -predicate sourceModel(string package, string type, string path, string kind) { +predicate sourceModel(string type, string path, string kind) { exists(string row | sourceModel(row) and - row.splitAt(";", 0) = package and - row.splitAt(";", 1) = type and - row.splitAt(";", 2) = path and - row.splitAt(";", 3) = kind + row.splitAt(";", 0) = type and + row.splitAt(";", 1) = path and + row.splitAt(";", 2) = kind ) } /** Holds if a sink model exists for the given parameters. */ -private predicate sinkModel(string package, string type, string path, string kind) { +private predicate sinkModel(string type, string path, string kind) { exists(string row | sinkModel(row) and - row.splitAt(";", 0) = package and - row.splitAt(";", 1) = type and - row.splitAt(";", 2) = path and - row.splitAt(";", 3) = kind + row.splitAt(";", 0) = type and + row.splitAt(";", 1) = path and + row.splitAt(";", 2) = kind ) } /** Holds if a summary model `row` exists for the given parameters. */ -private predicate summaryModel( - string package, string type, string path, string input, string output, string kind -) { +private predicate summaryModel(string type, string path, string input, string output, string kind) { exists(string row | summaryModel(row) and - row.splitAt(";", 0) = package and - row.splitAt(";", 1) = type and - row.splitAt(";", 2) = path and - row.splitAt(";", 3) = input and - row.splitAt(";", 4) = output and - row.splitAt(";", 5) = kind + row.splitAt(";", 0) = type and + row.splitAt(";", 1) = path and + row.splitAt(";", 2) = input and + row.splitAt(";", 3) = output and + row.splitAt(";", 4) = kind ) } /** Holds if a type model exists for the given parameters. */ -private predicate typeModel( - string package1, string type1, string package2, string type2, string path -) { +private predicate typeModel(string type1, string type2, string path) { exists(string row | typeModel(row) and - row.splitAt(";", 0) = package1 and - row.splitAt(";", 1) = type1 and - row.splitAt(";", 2) = package2 and - row.splitAt(";", 3) = type2 and - row.splitAt(";", 4) = path + row.splitAt(";", 0) = type1 and + row.splitAt(";", 1) = type2 and + row.splitAt(";", 2) = path ) } @@ -292,61 +280,50 @@ private predicate typeVariableModel(string name, string path) { } /** - * Gets a package that should be seen as an alias for the given other `package`, - * or the `package` itself. + * Holds if CSV rows involving `type` might be relevant for the analysis of this database. */ -bindingset[package] -bindingset[result] -string getAPackageAlias(string package) { - typeModel(package, "", result, "", "") - or - result = package -} - -/** - * Holds if CSV rows involving `package` might be relevant for the analysis of this database. - */ -private predicate isRelevantPackage(string package) { +predicate isRelevantType(string type) { ( - sourceModel(package, _, _, _) or - sinkModel(package, _, _, _) or - summaryModel(package, _, _, _, _, _) or - typeModel(_, _, package, _, _) + sourceModel(type, _, _) or + sinkModel(type, _, _) or + summaryModel(type, _, _, _, _) or + typeModel(_, type, _) ) and ( - Specific::isPackageUsed(package) + Specific::isTypeUsed(type) or exists(TestAllModels t) ) or - exists(string other | - isRelevantPackage(other) and - typeModel(package, _, other, _, _) + exists(string other | isRelevantType(other) | + typeModel(type, other, _) + or + Specific::hasImplicitTypeModel(type, other) ) } /** - * Holds if `package,type,path` is used in some CSV row. + * Holds if `type,path` is used in some CSV row. */ pragma[nomagic] -predicate isRelevantFullPath(string package, string type, string path) { - isRelevantPackage(package) and +predicate isRelevantFullPath(string type, string path) { + isRelevantType(type) and ( - sourceModel(package, type, path, _) or - sinkModel(package, type, path, _) or - summaryModel(package, type, path, _, _, _) or - typeModel(_, _, package, type, path) + sourceModel(type, path, _) or + sinkModel(type, path, _) or + summaryModel(type, path, _, _, _) or + typeModel(_, type, path) ) } /** A string from a CSV row that should be parsed as an access path. */ private class AccessPathRange extends AccessPath::Range { AccessPathRange() { - isRelevantFullPath(_, _, this) + isRelevantFullPath(_, this) or - exists(string package | isRelevantPackage(package) | - summaryModel(package, _, _, this, _, _) or - summaryModel(package, _, _, _, this, _) + exists(string type | isRelevantType(type) | + summaryModel(type, _, this, _, _) or + summaryModel(type, _, _, this, _) ) or typeVariableModel(_, this) @@ -400,83 +377,73 @@ private predicate invocationMatchesCallSiteFilter(Specific::InvokeNode invoke, A } private class TypeModelUseEntry extends API::EntryPoint { - private string package; private string type; TypeModelUseEntry() { - exists(any(TypeModel tm).getASource(package, type)) and - this = "TypeModelUseEntry;" + package + ";" + type + exists(any(TypeModel tm).getASource(type)) and + this = "TypeModelUseEntry;" + type } - override DataFlow::LocalSourceNode getASource() { - result = any(TypeModel tm).getASource(package, type) - } + override DataFlow::LocalSourceNode getASource() { result = any(TypeModel tm).getASource(type) } - API::Node getNodeForType(string package_, string type_) { - package = package_ and type = type_ and result = this.getANode() - } + API::Node getNodeForType(string type_) { type = type_ and result = this.getANode() } } private class TypeModelDefEntry extends API::EntryPoint { - private string package; private string type; TypeModelDefEntry() { - exists(any(TypeModel tm).getASink(package, type)) and - this = "TypeModelDefEntry;" + package + ";" + type + exists(any(TypeModel tm).getASink(type)) and + this = "TypeModelDefEntry;" + type } - override DataFlow::Node getASink() { result = any(TypeModel tm).getASink(package, type) } + override DataFlow::Node getASink() { result = any(TypeModel tm).getASink(type) } - API::Node getNodeForType(string package_, string type_) { - package = package_ and type = type_ and result = this.getANode() - } + API::Node getNodeForType(string type_) { type = type_ and result = this.getANode() } } /** - * Gets an API node identified by the given `(package,type)` pair. + * Gets an API node identified by the given `type`. */ pragma[nomagic] -private API::Node getNodeFromType(string package, string type) { - exists(string package2, string type2, AccessPath path2 | - typeModel(package, type, package2, type2, path2) and - result = getNodeFromPath(package2, type2, path2) +private API::Node getNodeFromType(string type) { + exists(string type2, AccessPath path2 | + typeModel(type, type2, path2) and + result = getNodeFromPath(type2, path2) ) or - result = any(TypeModelUseEntry e).getNodeForType(package, type) + result = any(TypeModelUseEntry e).getNodeForType(type) or - result = any(TypeModelDefEntry e).getNodeForType(package, type) + result = any(TypeModelDefEntry e).getNodeForType(type) or - result = any(TypeModel t).getAnApiNode(package, type) + result = any(TypeModel t).getAnApiNode(type) or - result = Specific::getExtraNodeFromType(package, type) + result = Specific::getExtraNodeFromType(type) } /** - * Gets the API node identified by the first `n` tokens of `path` in the given `(package, type, path)` tuple. + * Gets the API node identified by the first `n` tokens of `path` in the given `(type, path)` tuple. */ pragma[nomagic] -private API::Node getNodeFromPath(string package, string type, AccessPath path, int n) { - isRelevantFullPath(package, type, path) and +private API::Node getNodeFromPath(string type, AccessPath path, int n) { + isRelevantFullPath(type, path) and ( n = 0 and - result = getNodeFromType(package, type) + result = getNodeFromType(type) or - result = Specific::getExtraNodeFromPath(package, type, path, n) + result = Specific::getExtraNodeFromPath(type, path, n) ) or - result = getSuccessorFromNode(getNodeFromPath(package, type, path, n - 1), path.getToken(n - 1)) + result = getSuccessorFromNode(getNodeFromPath(type, path, n - 1), path.getToken(n - 1)) or // Similar to the other recursive case, but where the path may have stepped through one or more call-site filters - result = - getSuccessorFromInvoke(getInvocationFromPath(package, type, path, n - 1), path.getToken(n - 1)) + result = getSuccessorFromInvoke(getInvocationFromPath(type, path, n - 1), path.getToken(n - 1)) or // Apply a subpath - result = - getNodeFromSubPath(getNodeFromPath(package, type, path, n - 1), getSubPathAt(path, n - 1)) + result = getNodeFromSubPath(getNodeFromPath(type, path, n - 1), getSubPathAt(path, n - 1)) or // Apply a type step - typeStep(getNodeFromPath(package, type, path, n), result) + typeStep(getNodeFromPath(type, path, n), result) } /** @@ -496,15 +463,15 @@ private AccessPath getSubPathAt(AccessPath path, int n) { pragma[nomagic] private API::Node getNodeFromSubPath(API::Node base, AccessPath subPath, int n) { exists(AccessPath path, int k | - base = [getNodeFromPath(_, _, path, k), getNodeFromSubPath(_, path, k)] and + base = [getNodeFromPath(_, path, k), getNodeFromSubPath(_, path, k)] and subPath = getSubPathAt(path, k) and result = base and n = 0 ) or - exists(string package, string type, AccessPath basePath | - typeStepModel(package, type, basePath, subPath) and - base = getNodeFromPath(package, type, basePath) and + exists(string type, AccessPath basePath | + typeStepModel(type, basePath, subPath) and + base = getNodeFromPath(type, basePath) and result = base and n = 0 ) @@ -543,42 +510,40 @@ private API::Node getNodeFromSubPath(API::Node base, AccessPath subPath) { result = getNodeFromSubPath(base, subPath, subPath.getNumToken()) } -/** Gets the node identified by the given `(package, type, path)` tuple. */ -private API::Node getNodeFromPath(string package, string type, AccessPath path) { - result = getNodeFromPath(package, type, path, path.getNumToken()) +/** Gets the node identified by the given `(type, path)` tuple. */ +private API::Node getNodeFromPath(string type, AccessPath path) { + result = getNodeFromPath(type, path, path.getNumToken()) } pragma[nomagic] -private predicate typeStepModel(string package, string type, AccessPath basePath, AccessPath output) { - summaryModel(package, type, basePath, "", output, "type") +private predicate typeStepModel(string type, AccessPath basePath, AccessPath output) { + summaryModel(type, basePath, "", output, "type") } pragma[nomagic] private predicate typeStep(API::Node pred, API::Node succ) { - exists(string package, string type, AccessPath basePath, AccessPath output | - typeStepModel(package, type, basePath, output) and - pred = getNodeFromPath(package, type, basePath) and + exists(string type, AccessPath basePath, AccessPath output | + typeStepModel(type, basePath, output) and + pred = getNodeFromPath(type, basePath) and succ = getNodeFromSubPath(pred, output) ) } /** - * Gets an invocation identified by the given `(package, type, path)` tuple. + * Gets an invocation identified by the given `(type, path)` tuple. * * Unlike `getNodeFromPath`, the `path` may end with one or more call-site filters. */ -private Specific::InvokeNode getInvocationFromPath( - string package, string type, AccessPath path, int n -) { - result = Specific::getAnInvocationOf(getNodeFromPath(package, type, path, n)) +private Specific::InvokeNode getInvocationFromPath(string type, AccessPath path, int n) { + result = Specific::getAnInvocationOf(getNodeFromPath(type, path, n)) or - result = getInvocationFromPath(package, type, path, n - 1) and + result = getInvocationFromPath(type, path, n - 1) and invocationMatchesCallSiteFilter(result, path.getToken(n - 1)) } -/** Gets an invocation identified by the given `(package, type, path)` tuple. */ -private Specific::InvokeNode getInvocationFromPath(string package, string type, AccessPath path) { - result = getInvocationFromPath(package, type, path, path.getNumToken()) +/** Gets an invocation identified by the given `(type, path)` tuple. */ +private Specific::InvokeNode getInvocationFromPath(string type, AccessPath path) { + result = getInvocationFromPath(type, path, path.getNumToken()) } /** @@ -631,9 +596,9 @@ module ModelOutput { */ cached API::Node getASourceNode(string kind) { - exists(string package, string type, string path | - sourceModel(package, type, path, kind) and - result = getNodeFromPath(package, type, path) + exists(string type, string path | + sourceModel(type, path, kind) and + result = getNodeFromPath(type, path) ) } @@ -642,9 +607,9 @@ module ModelOutput { */ cached API::Node getASinkNode(string kind) { - exists(string package, string type, string path | - sinkModel(package, type, path, kind) and - result = getNodeFromPath(package, type, path) + exists(string type, string path | + sinkModel(type, path, kind) and + result = getNodeFromPath(type, path) ) } @@ -653,32 +618,31 @@ module ModelOutput { */ cached predicate relevantSummaryModel( - string package, string type, string path, string input, string output, string kind + string type, string path, string input, string output, string kind ) { - isRelevantPackage(package) and - summaryModel(package, type, path, input, output, kind) + isRelevantType(type) and + summaryModel(type, path, input, output, kind) } /** - * Holds if a `baseNode` is an invocation identified by the `package,type,path` part of a summary row. + * Holds if a `baseNode` is an invocation identified by the `type,path` part of a summary row. */ cached - predicate resolvedSummaryBase( - string package, string type, string path, Specific::InvokeNode baseNode - ) { - summaryModel(package, type, path, _, _, _) and - baseNode = getInvocationFromPath(package, type, path) + predicate resolvedSummaryBase(string type, string path, Specific::InvokeNode baseNode) { + summaryModel(type, path, _, _, _) and + baseNode = getInvocationFromPath(type, path) } /** - * Holds if `node` is seen as an instance of `(package,type)` due to a type definition + * Holds if `node` is seen as an instance of `type` due to a type definition * contributed by a CSV model. */ cached - API::Node getATypeNode(string package, string type) { result = getNodeFromType(package, type) } + API::Node getATypeNode(string type) { result = getNodeFromType(type) } } import Cached + import Specific::ModelOutputSpecific /** * Gets an error message relating to an invalid CSV row in a model. @@ -686,13 +650,13 @@ module ModelOutput { string getAWarning() { // Check number of columns exists(string row, string kind, int expectedArity, int actualArity | - any(SourceModelCsv csv).row(row) and kind = "source" and expectedArity = 4 + any(SourceModelCsv csv).row(row) and kind = "source" and expectedArity = 3 or - any(SinkModelCsv csv).row(row) and kind = "sink" and expectedArity = 4 + any(SinkModelCsv csv).row(row) and kind = "sink" and expectedArity = 3 or - any(SummaryModelCsv csv).row(row) and kind = "summary" and expectedArity = 6 + any(SummaryModelCsv csv).row(row) and kind = "summary" and expectedArity = 5 or - any(TypeModelCsv csv).row(row) and kind = "type" and expectedArity = 5 + any(TypeModelCsv csv).row(row) and kind = "type" and expectedArity = 3 or any(TypeVariableModelCsv csv).row(row) and kind = "type-variable" and expectedArity = 2 | @@ -705,7 +669,7 @@ module ModelOutput { or // Check names and arguments of access path tokens exists(AccessPath path, AccessPathToken token | - (isRelevantFullPath(_, _, path) or typeVariableModel(_, path)) and + (isRelevantFullPath(_, path) or typeVariableModel(_, path)) and token = path.getToken(_) | not isValidTokenNameInIdentifyingAccessPath(token.getName()) and diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModelsSpecific.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModelsSpecific.qll index 03390a6c34e..500197f2f89 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModelsSpecific.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModelsSpecific.qll @@ -34,30 +34,73 @@ private import codeql.ruby.dataflow.internal.FlowSummaryImplSpecific as FlowSumm private import codeql.ruby.dataflow.internal.FlowSummaryImpl::Public private import codeql.ruby.dataflow.internal.DataFlowDispatch as DataFlowDispatch -/** - * Holds if models describing `package` may be relevant for the analysis of this database. - * - * In the context of Ruby, this is the name of a Ruby gem. - */ -bindingset[package] -predicate isPackageUsed(string package) { - // For now everything is modeled as an access path starting at any top-level, so the package name has no effect. - // - // We allow an arbitrary package name so that the model can record the name of the package in case it's needed in the future. - // - // In principle we should consider a package to be "used" if there is a transitive dependency on it, but we can only - // reliably see the direct dependencies. - // - // In practice, packages try to use unique top-level module names, which mitigates the precision loss of not checking - // the package name. - any() +pragma[nomagic] +private predicate isUsedTopLevelConstant(string name) { + exists(ConstantAccess access | + access.getName() = name and + not exists(access.getScopeExpr()) + ) } -/** Gets a Ruby-specific interpretation of the `(package, type, path)` tuple after resolving the first `n` access path tokens. */ -bindingset[package, type, path] -API::Node getExtraNodeFromPath(string package, string type, AccessPath path, int n) { - // A row of form `;any;Method[foo]` should match any method named `foo`. - exists(package) and +bindingset[rawType] +predicate isTypeUsed(string rawType) { + exists(string consts | + parseType(rawType, consts, _) and + isUsedTopLevelConstant(consts.splitAt("::", 0)) + ) + or + rawType = ["", "any"] +} + +bindingset[rawType] +private predicate parseType(string rawType, string consts, string suffix) { + exists(string regexp | + regexp = "([^!]+)(!|)" and + consts = rawType.regexpCapture(regexp, 1) and + suffix = rawType.regexpCapture(regexp, 2) + ) +} + +/** + * Holds if `type` can be obtained from an instance of `otherType` due to + * language semantics modeled by `getExtraNodeFromType`. + */ +bindingset[otherType] +predicate hasImplicitTypeModel(string type, string otherType) { + // A::B! can be used to obtain A::B + parseType(otherType, type, _) +} + +private predicate parseRelevantType(string rawType, string consts, string suffix) { + isRelevantType(rawType) and + parseType(rawType, consts, suffix) +} + +pragma[nomagic] +private string getConstComponent(string consts, int n) { + parseRelevantType(_, consts, _) and + result = consts.splitAt("::", n) +} + +private int getNumConstComponents(string consts) { + result = strictcount(int n | exists(getConstComponent(consts, n))) +} + +private DataFlow::ConstRef getConstantFromConstPath(string consts, int n) { + n = 1 and + result = DataFlow::getConstant(getConstComponent(consts, 0)) + or + result = getConstantFromConstPath(consts, n - 1).getConstant(getConstComponent(consts, n - 1)) +} + +private DataFlow::ConstRef getConstantFromConstPath(string consts) { + result = getConstantFromConstPath(consts, getNumConstComponents(consts)) +} + +/** Gets a Ruby-specific interpretation of the `(type, path)` tuple after resolving the first `n` access path tokens. */ +bindingset[type, path] +API::Node getExtraNodeFromPath(string type, AccessPath path, int n) { + // A row of form `any;Method[foo]` should match any method named `foo`. type = "any" and n = 1 and exists(EntryPointFromAnyType entry | @@ -66,9 +109,27 @@ API::Node getExtraNodeFromPath(string package, string type, AccessPath path, int ) } -/** Gets a Ruby-specific interpretation of the `(package, type)` tuple. */ -API::Node getExtraNodeFromType(string package, string type) { - isRelevantFullPath(package, type, _) and // Allow any package name, see `isPackageUsed`. +/** Gets a Ruby-specific interpretation of the given `type`. */ +API::Node getExtraNodeFromType(string type) { + exists(string consts, string suffix, DataFlow::ConstRef constRef | + parseRelevantType(type, consts, suffix) and + constRef = getConstantFromConstPath(consts) + | + suffix = "!" and + ( + result.asSource() = constRef + or + result.asSource() = constRef.getADescendentModule().getAnOwnModuleSelf() + ) + or + suffix = "" and + ( + result.asSource() = constRef.getAMethodCall("new") + or + result.asSource() = constRef.getADescendentModule().getAnInstanceSelf() + ) + ) + or type = "" and result = API::root() } @@ -78,7 +139,7 @@ API::Node getExtraNodeFromType(string package, string type) { * matching anywhere, and the path begins with `Method[methodName]`. */ private predicate methodMatchedByName(AccessPath path, string methodName) { - isRelevantFullPath(_, "any", path) and + isRelevantFullPath("any", path) and exists(AccessPathToken token | token = path.getToken(0) and token.getName() = "Method" and @@ -190,3 +251,5 @@ predicate isExtraValidTokenArgumentInIdentifyingAccessPath(string name, string a argument.regexpMatch("\\w+:") // keyword argument ) } + +module ModelOutputSpecific { } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll index 85db78252c8..0ef535d3aa7 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll @@ -123,33 +123,31 @@ module Pathname { */ private class PathnameTypeSummary extends ModelInput::TypeModelCsv { override predicate row(string row) { - // package1;type1;package2;type2;path + // type1;type2;path row = [ - // Pathname.new : Pathname - ";Pathname;;;Member[Pathname].Instance", // Pathname#+(path) : Pathname - ";Pathname;;Pathname;Method[+].ReturnValue", + "Pathname;Pathname;Method[+].ReturnValue", // Pathname#/(path) : Pathname - ";Pathname;;Pathname;Method[/].ReturnValue", + "Pathname;Pathname;Method[/].ReturnValue", // Pathname#basename(path) : Pathname - ";Pathname;;Pathname;Method[basename].ReturnValue", + "Pathname;Pathname;Method[basename].ReturnValue", // Pathname#cleanpath(path) : Pathname - ";Pathname;;Pathname;Method[cleanpath].ReturnValue", + "Pathname;Pathname;Method[cleanpath].ReturnValue", // Pathname#expand_path(path) : Pathname - ";Pathname;;Pathname;Method[expand_path].ReturnValue", + "Pathname;Pathname;Method[expand_path].ReturnValue", // Pathname#join(path) : Pathname - ";Pathname;;Pathname;Method[join].ReturnValue", + "Pathname;Pathname;Method[join].ReturnValue", // Pathname#realpath(path) : Pathname - ";Pathname;;Pathname;Method[realpath].ReturnValue", + "Pathname;Pathname;Method[realpath].ReturnValue", // Pathname#relative_path_from(path) : Pathname - ";Pathname;;Pathname;Method[relative_path_from].ReturnValue", + "Pathname;Pathname;Method[relative_path_from].ReturnValue", // Pathname#sub(path) : Pathname - ";Pathname;;Pathname;Method[sub].ReturnValue", + "Pathname;Pathname;Method[sub].ReturnValue", // Pathname#sub_ext(path) : Pathname - ";Pathname;;Pathname;Method[sub_ext].ReturnValue", + "Pathname;Pathname;Method[sub_ext].ReturnValue", // Pathname#to_path(path) : Pathname - ";Pathname;;Pathname;Method[to_path].ReturnValue", + "Pathname;Pathname;Method[to_path].ReturnValue", ] } } @@ -160,31 +158,31 @@ module Pathname { row = [ // Pathname.new(path) - ";;Member[Pathname].Method[new];Argument[0];ReturnValue;taint", + "Pathname!;Method[new];Argument[0];ReturnValue;taint", // Pathname#dirname - ";Pathname;Method[dirname];Argument[self];ReturnValue;taint", + "Pathname;Method[dirname];Argument[self];ReturnValue;taint", // Pathname#each_filename - ";Pathname;Method[each_filename];Argument[self];Argument[block].Parameter[0];taint", + "Pathname;Method[each_filename];Argument[self];Argument[block].Parameter[0];taint", // Pathname#expand_path - ";Pathname;Method[expand_path];Argument[self];ReturnValue;taint", + "Pathname;Method[expand_path];Argument[self];ReturnValue;taint", // Pathname#join - ";Pathname;Method[join];Argument[self,any];ReturnValue;taint", + "Pathname;Method[join];Argument[self,any];ReturnValue;taint", // Pathname#parent - ";Pathname;Method[parent];Argument[self];ReturnValue;taint", + "Pathname;Method[parent];Argument[self];ReturnValue;taint", // Pathname#realpath - ";Pathname;Method[realpath];Argument[self];ReturnValue;taint", + "Pathname;Method[realpath];Argument[self];ReturnValue;taint", // Pathname#relative_path_from - ";Pathname;Method[relative_path_from];Argument[self];ReturnValue;taint", + "Pathname;Method[relative_path_from];Argument[self];ReturnValue;taint", // Pathname#to_path - ";Pathname;Method[to_path];Argument[self];ReturnValue;taint", + "Pathname;Method[to_path];Argument[self];ReturnValue;taint", // Pathname#basename - ";Pathname;Method[basename];Argument[self];ReturnValue;taint", + "Pathname;Method[basename];Argument[self];ReturnValue;taint", // Pathname#cleanpath - ";Pathname;Method[cleanpath];Argument[self];ReturnValue;taint", + "Pathname;Method[cleanpath];Argument[self];ReturnValue;taint", // Pathname#sub - ";Pathname;Method[sub];Argument[self];ReturnValue;taint", + "Pathname;Method[sub];Argument[self];ReturnValue;taint", // Pathname#sub_ext - ";Pathname;Method[sub_ext];Argument[self];ReturnValue;taint", + "Pathname;Method[sub_ext];Argument[self];ReturnValue;taint", ] } } diff --git a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected index f1b8eb2da26..34947d0005d 100644 --- a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected +++ b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected @@ -1,9 +1,6 @@ | file://:0:0:0:0 | [summary] read: argument position 0.any element in Hash[] | file://:0:0:0:0 | [summary] read: argument position 0.any element.element 1 or unknown in Hash[] | -| file://:0:0:0:0 | parameter any of ;Pathname;Method[join] | file://:0:0:0:0 | [summary] to write: return (return) in ;Pathname;Method[join] | | file://:0:0:0:0 | parameter position 0 of & | file://:0:0:0:0 | [summary] read: argument position 0.any element in & | | file://:0:0:0:0 | parameter position 0 of + | file://:0:0:0:0 | [summary] read: argument position 0.any element in + | -| file://:0:0:0:0 | parameter position 0 of ;;Member[Pathname].Method[new] | file://:0:0:0:0 | [summary] to write: return (return) in ;;Member[Pathname].Method[new] | -| file://:0:0:0:0 | parameter position 0 of ;;Member[Regexp].Method[escape,quote] | file://:0:0:0:0 | [summary] to write: return (return) in ;;Member[Regexp].Method[escape,quote] | | file://:0:0:0:0 | parameter position 0 of ActionController::Parameters#merge | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge | | file://:0:0:0:0 | parameter position 0 of ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: argument self in ActionController::Parameters#merge! | | file://:0:0:0:0 | parameter position 0 of ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge! | @@ -17,27 +14,10 @@ | file://:0:0:0:0 | parameter position 0 of Hash[] | file://:0:0:0:0 | [summary] read: argument position 0.any element in Hash[] | | file://:0:0:0:0 | parameter position 0 of String.try_convert | file://:0:0:0:0 | [summary] to write: return (return) in String.try_convert | | file://:0:0:0:0 | parameter position 0 of \| | file://:0:0:0:0 | [summary] read: argument position 0.any element in \| | -| file://:0:0:0:0 | parameter position 0 of activestorage;;Member[ActiveStorage].Member[Filename].Method[new] | file://:0:0:0:0 | [summary] to write: return (return) in activestorage;;Member[ActiveStorage].Member[Filename].Method[new] | -| file://:0:0:0:0 | parameter position 0 of activesupport;;Member[ActionView].Member[SafeBuffer].Instance.Method[safe_concat] | file://:0:0:0:0 | [summary] to write: argument self in activesupport;;Member[ActionView].Member[SafeBuffer].Instance.Method[safe_concat] | -| file://:0:0:0:0 | parameter position 0 of activesupport;;Member[ActionView].Member[SafeBuffer].Instance.Method[safe_concat] | file://:0:0:0:0 | [summary] to write: return (return) in activesupport;;Member[ActionView].Member[SafeBuffer].Instance.Method[safe_concat] | -| file://:0:0:0:0 | parameter position 0 of activesupport;;Member[ActionView].Member[SafeBuffer].Method[new] | file://:0:0:0:0 | [summary] to write: return (return) in activesupport;;Member[ActionView].Member[SafeBuffer].Method[new] | | file://:0:0:0:0 | parameter position 0.. of File.join | file://:0:0:0:0 | [summary] to write: return (return) in File.join | | file://:0:0:0:0 | parameter self of & | file://:0:0:0:0 | [summary] read: argument self.any element in & | | file://:0:0:0:0 | parameter self of * | file://:0:0:0:0 | [summary] read: argument self.any element in * | | file://:0:0:0:0 | parameter self of - | file://:0:0:0:0 | [summary] read: argument self.any element in - | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[basename] | file://:0:0:0:0 | [summary] to write: return (return) in ;Pathname;Method[basename] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[cleanpath] | file://:0:0:0:0 | [summary] to write: return (return) in ;Pathname;Method[cleanpath] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[dirname] | file://:0:0:0:0 | [summary] to write: return (return) in ;Pathname;Method[dirname] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[each_filename] | file://:0:0:0:0 | [summary] to write: argument block.parameter position 0 in ;Pathname;Method[each_filename] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[existence] | file://:0:0:0:0 | [summary] to write: return (return) in ;Pathname;Method[existence] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[expand_path] | file://:0:0:0:0 | [summary] to write: return (return) in ;Pathname;Method[expand_path] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[join] | file://:0:0:0:0 | [summary] to write: return (return) in ;Pathname;Method[join] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[parent] | file://:0:0:0:0 | [summary] to write: return (return) in ;Pathname;Method[parent] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[realpath] | file://:0:0:0:0 | [summary] to write: return (return) in ;Pathname;Method[realpath] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[relative_path_from] | file://:0:0:0:0 | [summary] to write: return (return) in ;Pathname;Method[relative_path_from] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[sub] | file://:0:0:0:0 | [summary] to write: return (return) in ;Pathname;Method[sub] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[sub_ext] | file://:0:0:0:0 | [summary] to write: return (return) in ;Pathname;Method[sub_ext] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[to_path] | file://:0:0:0:0 | [summary] to write: return (return) in ;Pathname;Method[to_path] | | file://:0:0:0:0 | parameter self of ActionController::Parameters# | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters# | | file://:0:0:0:0 | parameter self of ActionController::Parameters#merge | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge | | file://:0:0:0:0 | parameter self of ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: argument self in ActionController::Parameters#merge! | @@ -45,8 +25,6 @@ | file://:0:0:0:0 | parameter self of ActiveSupportStringTransform | file://:0:0:0:0 | [summary] to write: return (return) in ActiveSupportStringTransform | | file://:0:0:0:0 | parameter self of [] | file://:0:0:0:0 | [summary] to write: return (return) in [] | | file://:0:0:0:0 | parameter self of \| | file://:0:0:0:0 | [summary] read: argument self.any element in \| | -| file://:0:0:0:0 | parameter self of activestorage;;Member[ActiveStorage].Member[Filename].Instance.Method[sanitized] | file://:0:0:0:0 | [summary] to write: return (return) in activestorage;;Member[ActiveStorage].Member[Filename].Instance.Method[sanitized] | -| file://:0:0:0:0 | parameter self of activesupport;;Member[ActionView].Member[SafeBuffer].Instance.Method[concat,insert,prepend,to_s,to_param] | file://:0:0:0:0 | [summary] to write: return (return) in activesupport;;Member[ActionView].Member[SafeBuffer].Instance.Method[concat,insert,prepend,to_s,to_param] | | file://:0:0:0:0 | parameter self of each(0) | file://:0:0:0:0 | [summary] read: argument self.any element in each(0) | | local_dataflow.rb:1:1:7:3 | self (foo) | local_dataflow.rb:3:8:3:10 | self | | local_dataflow.rb:1:1:7:3 | self in foo | local_dataflow.rb:1:1:7:3 | self (foo) | diff --git a/ruby/ql/test/library-tests/dataflow/summaries/Summaries.expected b/ruby/ql/test/library-tests/dataflow/summaries/Summaries.expected index 055faee45c6..f916520c8ce 100644 --- a/ruby/ql/test/library-tests/dataflow/summaries/Summaries.expected +++ b/ruby/ql/test/library-tests/dataflow/summaries/Summaries.expected @@ -534,8 +534,8 @@ invalidSpecComponent | summaries.rb:150:39:150:45 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:150:39:150:45 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : | | summaries.rb:150:39:150:45 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:150:39:150:45 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : | warning -| CSV type row should have 5 columns but has 2: test;TooFewColumns | -| CSV type row should have 5 columns but has 8: test;TooManyColumns;;;Member[Foo].Instance;too;many;columns | +| CSV type row should have 3 columns but has 1: TooFewColumns | +| CSV type row should have 3 columns but has 6: TooManyColumns;;Member[Foo].Instance;too;many;columns | | Invalid argument '0-1' in token 'Argument[0-1]' in access path: Method[foo].Argument[0-1] | | Invalid argument '*' in token 'Argument[*]' in access path: Method[foo].Argument[*] | | Invalid token 'Argument' is missing its arguments, in access path: Method[foo].Argument | diff --git a/ruby/ql/test/library-tests/dataflow/summaries/Summaries.ql b/ruby/ql/test/library-tests/dataflow/summaries/Summaries.ql index 416a8635deb..b59862d0e5a 100644 --- a/ruby/ql/test/library-tests/dataflow/summaries/Summaries.ql +++ b/ruby/ql/test/library-tests/dataflow/summaries/Summaries.ql @@ -67,32 +67,32 @@ private class StepsFromModel extends ModelInput::SummaryModelCsv { override predicate row(string row) { row = [ - ";any;Method[set_value];Argument[0];Argument[self].Field[@value];value", - ";any;Method[get_value];Argument[self].Field[@value];ReturnValue;value", - ";;Member[Foo].Method[firstArg];Argument[0];ReturnValue;taint", - ";;Member[Foo].Method[secondArg];Argument[1];ReturnValue;taint", - ";;Member[Foo].Method[onlyWithoutBlock].WithoutBlock;Argument[0];ReturnValue;taint", - ";;Member[Foo].Method[onlyWithBlock].WithBlock;Argument[0];ReturnValue;taint", - ";;Member[Foo].Method[blockArg].Argument[block].Parameter[0].Method[preserveTaint];Argument[0];ReturnValue;taint", - ";;Member[Foo].Method[namedArg];Argument[foo:];ReturnValue;taint", - ";;Member[Foo].Method[anyArg];Argument[any];ReturnValue;taint", - ";;Member[Foo].Method[anyNamedArg];Argument[any-named];ReturnValue;taint", - ";;Member[Foo].Method[anyPositionFromOne];Argument[1..];ReturnValue;taint", - ";;Member[Foo].Method[intoNamedCallback];Argument[0];Argument[foo:].Parameter[0];taint", - ";;Member[Foo].Method[intoNamedParameter];Argument[0];Argument[0].Parameter[foo:];taint", - ";;Member[Foo].Method[startInNamedCallback].Argument[foo:].Parameter[0].Method[preserveTaint];Argument[0];ReturnValue;taint", - ";;Member[Foo].Method[startInNamedParameter].Argument[0].Parameter[foo:].Method[preserveTaint];Argument[0];ReturnValue;taint", - ";;Member[Foo].Instance.Method[flowToAnyArg];Argument[0];Argument[any];taint", - ";;Member[Foo].Instance.Method[flowToSelf];Argument[0];Argument[self];taint", - ";any;Method[matchedByName];Argument[0];ReturnValue;taint", - ";any;Method[matchedByNameRcv];Argument[self];ReturnValue;taint", - ";any;Method[withElementOne];Argument[self].WithElement[1];ReturnValue;value", - ";any;Method[withExactlyElementOne];Argument[self].WithElement[1!];ReturnValue;value", - ";any;Method[withoutElementOne];Argument[self].WithoutElement[1];Argument[self];value", - ";any;Method[withoutExactlyElementOne];Argument[self].WithoutElement[1!];Argument[self];value", - ";any;Method[readElementOne];Argument[self].Element[1];ReturnValue;value", - ";any;Method[readExactlyElementOne];Argument[self].Element[1!];ReturnValue;value", - ";any;Method[withoutElementOneAndTwo];Argument[self].WithoutElement[1].WithoutElement[2].WithElement[any];Argument[self];value", + "any;Method[set_value];Argument[0];Argument[self].Field[@value];value", + "any;Method[get_value];Argument[self].Field[@value];ReturnValue;value", + "Foo!;Method[firstArg];Argument[0];ReturnValue;taint", + "Foo!;Method[secondArg];Argument[1];ReturnValue;taint", + "Foo!;Method[onlyWithoutBlock].WithoutBlock;Argument[0];ReturnValue;taint", + "Foo!;Method[onlyWithBlock].WithBlock;Argument[0];ReturnValue;taint", + "Foo!;Method[blockArg].Argument[block].Parameter[0].Method[preserveTaint];Argument[0];ReturnValue;taint", + "Foo!;Method[namedArg];Argument[foo:];ReturnValue;taint", + "Foo!;Method[anyArg];Argument[any];ReturnValue;taint", + "Foo!;Method[anyNamedArg];Argument[any-named];ReturnValue;taint", + "Foo!;Method[anyPositionFromOne];Argument[1..];ReturnValue;taint", + "Foo!;Method[intoNamedCallback];Argument[0];Argument[foo:].Parameter[0];taint", + "Foo!;Method[intoNamedParameter];Argument[0];Argument[0].Parameter[foo:];taint", + "Foo!;Method[startInNamedCallback].Argument[foo:].Parameter[0].Method[preserveTaint];Argument[0];ReturnValue;taint", + "Foo!;Method[startInNamedParameter].Argument[0].Parameter[foo:].Method[preserveTaint];Argument[0];ReturnValue;taint", + "Foo;Method[flowToAnyArg];Argument[0];Argument[any];taint", + "Foo;Method[flowToSelf];Argument[0];Argument[self];taint", + "any;Method[matchedByName];Argument[0];ReturnValue;taint", + "any;Method[matchedByNameRcv];Argument[self];ReturnValue;taint", + "any;Method[withElementOne];Argument[self].WithElement[1];ReturnValue;value", + "any;Method[withExactlyElementOne];Argument[self].WithElement[1!];ReturnValue;value", + "any;Method[withoutElementOne];Argument[self].WithoutElement[1];Argument[self];value", + "any;Method[withoutExactlyElementOne];Argument[self].WithoutElement[1!];Argument[self];value", + "any;Method[readElementOne];Argument[self].Element[1];ReturnValue;value", + "any;Method[readExactlyElementOne];Argument[self].Element[1!];ReturnValue;value", + "any;Method[withoutElementOneAndTwo];Argument[self].WithoutElement[1].WithoutElement[2].WithElement[any];Argument[self];value", ] } } @@ -101,23 +101,21 @@ private class TypeFromModel extends ModelInput::TypeModelCsv { override predicate row(string row) { row = [ - "test;FooOrBar;;;Member[Foo].Instance", // - "test;FooOrBar;;;Member[Bar].Instance", // - "test;FooOrBar;test;FooOrBar;Method[next].ReturnValue", + "~FooOrBar;Foo;", // + "~FooOrBar;Bar;", // + "~FooOrBar;~FooOrBar;Method[next].ReturnValue", ] } } private class TypeFromCodeQL extends ModelInput::TypeModel { - override DataFlow::Node getASource(string package, string type) { - package = "test" and - type = "FooOrBar" and + override DataFlow::Node getASource(string type) { + type = "~FooOrBar" and result.getConstantValue().getString() = "magic_string" } - override API::Node getAnApiNode(string package, string type) { - package = "test" and - type = "FooOrBar" and + override API::Node getAnApiNode(string type) { + type = "~FooOrBar" and result = API::getTopLevelMember("Alias").getMember(["Foo", "Bar"]) } } @@ -126,13 +124,13 @@ private class InvalidTypeModel extends ModelInput::TypeModelCsv { override predicate row(string row) { row = [ - "test;TooManyColumns;;;Member[Foo].Instance;too;many;columns", // - "test;TooFewColumns", // - "test;X;test;Y;Method[foo].Arg[0]", // - "test;X;test;Y;Method[foo].Argument[0-1]", // - "test;X;test;Y;Method[foo].Argument[*]", // - "test;X;test;Y;Method[foo].Argument", // - "test;X;test;Y;Method[foo].Member", // + "TooManyColumns;;Member[Foo].Instance;too;many;columns", // + "TooFewColumns", // + "Foo;Foo;Method[foo].Arg[0]", // + "Foo;Foo;Method[foo].Argument[0-1]", // + "Foo;Foo;Method[foo].Argument[*]", // + "Foo;Foo;Method[foo].Argument", // + "Foo;Foo;Method[foo].Member", // ] } } @@ -141,12 +139,12 @@ private class SinkFromModel extends ModelInput::SinkModelCsv { override predicate row(string row) { row = [ - "test;FooOrBar;Method[method].Argument[0];test-sink", // - ";;Member[Foo].Method[sinkAnyArg].Argument[any];test-sink", // - ";;Member[Foo].Method[sinkAnyNamedArg].Argument[any-named];test-sink", // - ";;Member[Foo].Method[getSinks].ReturnValue.Element[any].Method[mySink].Argument[0];test-sink", // - ";;Member[Foo].Method[arraySink].Argument[0].Element[any];test-sink", // - ";;Member[Foo].Method[secondArrayElementIsSink].Argument[0].Element[1];test-sink", // + "~FooOrBar;Method[method].Argument[0];test-sink", // + "Foo!;Method[sinkAnyArg].Argument[any];test-sink", // + "Foo!;Method[sinkAnyNamedArg].Argument[any-named];test-sink", // + "Foo!;Method[getSinks].ReturnValue.Element[any].Method[mySink].Argument[0];test-sink", // + "Foo!;Method[arraySink].Argument[0].Element[any];test-sink", // + "Foo!;Method[secondArrayElementIsSink].Argument[0].Element[1];test-sink", // ] } } diff --git a/ruby/ql/test/library-tests/frameworks/ActionDispatch.ql b/ruby/ql/test/library-tests/frameworks/ActionDispatch.ql index 5f25c62f32e..5b1275595ea 100644 --- a/ruby/ql/test/library-tests/frameworks/ActionDispatch.ql +++ b/ruby/ql/test/library-tests/frameworks/ActionDispatch.ql @@ -29,9 +29,7 @@ query predicate underscore(string input, string output) { ] } -query predicate mimeTypeInstances(API::Node n) { - n = ModelOutput::getATypeNode("actiondispatch", "Mime::Type") -} +query predicate mimeTypeInstances(API::Node n) { n = ModelOutput::getATypeNode("Mime::Type") } query predicate mimeTypeMatchRegExpInterpretations( ActionDispatch::MimeTypeMatchRegExpInterpretation s diff --git a/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected index e56238cf023..c760575bf2e 100644 --- a/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected +++ b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected @@ -59,12 +59,12 @@ pathnameInstances | Pathname.rb:42:1:42:3 | p01 | | file://:0:0:0:0 | parameter position 0 of + | | file://:0:0:0:0 | parameter self of + | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[cleanpath] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[expand_path] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[realpath] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[relative_path_from] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[sub_ext] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[to_path] | +| file://:0:0:0:0 | parameter self of Pathname;Method[cleanpath] | +| file://:0:0:0:0 | parameter self of Pathname;Method[expand_path] | +| file://:0:0:0:0 | parameter self of Pathname;Method[realpath] | +| file://:0:0:0:0 | parameter self of Pathname;Method[relative_path_from] | +| file://:0:0:0:0 | parameter self of Pathname;Method[sub_ext] | +| file://:0:0:0:0 | parameter self of Pathname;Method[to_path] | | file://:0:0:0:0 | parameter self of sub | | file://:0:0:0:0 | parameter self of to_s | fileSystemAccesses @@ -135,12 +135,12 @@ fileNameSources | Pathname.rb:42:1:42:3 | p01 | | file://:0:0:0:0 | parameter position 0 of + | | file://:0:0:0:0 | parameter self of + | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[cleanpath] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[expand_path] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[realpath] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[relative_path_from] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[sub_ext] | -| file://:0:0:0:0 | parameter self of ;Pathname;Method[to_path] | +| file://:0:0:0:0 | parameter self of Pathname;Method[cleanpath] | +| file://:0:0:0:0 | parameter self of Pathname;Method[expand_path] | +| file://:0:0:0:0 | parameter self of Pathname;Method[realpath] | +| file://:0:0:0:0 | parameter self of Pathname;Method[relative_path_from] | +| file://:0:0:0:0 | parameter self of Pathname;Method[sub_ext] | +| file://:0:0:0:0 | parameter self of Pathname;Method[to_path] | | file://:0:0:0:0 | parameter self of sub | | file://:0:0:0:0 | parameter self of to_s | fileSystemReadAccesses From 1c910550e6c3da3095796dfbf53c03b83a9288e4 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 14 Nov 2022 14:23:39 +0100 Subject: [PATCH 468/796] Python: merge package/type columns --- .../lib/semmle/python/frameworks/Asyncpg.qll | 23 +- .../data/internal/ApiGraphModels.qll | 312 ++++++++---------- .../data/internal/ApiGraphModelsSpecific.qll | 40 +-- .../library-tests/frameworks/data/test.ql | 91 ++--- .../frameworks/data/warnings.expected | 4 +- .../library-tests/frameworks/data/warnings.ql | 14 +- 6 files changed, 227 insertions(+), 257 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/Asyncpg.qll b/python/ql/lib/semmle/python/frameworks/Asyncpg.qll index ca28dca550f..7ded3730788 100644 --- a/python/ql/lib/semmle/python/frameworks/Asyncpg.qll +++ b/python/ql/lib/semmle/python/frameworks/Asyncpg.qll @@ -17,14 +17,15 @@ private module Asyncpg { row = [ // a `ConnectionPool` that is created when the result of `asyncpg.create_pool()` is awaited. - "asyncpg;ConnectionPool;asyncpg;;Member[create_pool].ReturnValue.Awaited", + "asyncpg.ConnectionPool;asyncpg;Member[create_pool].ReturnValue.Awaited", // a `Connection` that is created when // * - the result of `asyncpg.connect()` is awaited. // * - the result of calling `acquire` on a `ConnectionPool` is awaited. - "asyncpg;Connection;asyncpg;;Member[connect].ReturnValue.Awaited", - "asyncpg;Connection;asyncpg;ConnectionPool;Member[acquire].ReturnValue.Awaited", + "asyncpg.Connection;asyncpg;Member[connect].ReturnValue.Awaited", + "asyncpg.Connection;asyncpg.ConnectionPool;Member[acquire].ReturnValue.Awaited", // Creating an internal `~Connection` type that contains both `Connection` and `ConnectionPool`. - "asyncpg;~Connection;asyncpg;Connection;", "asyncpg;~Connection;asyncpg;ConnectionPool;" + "asyncpg.~Connection;asyncpg.Connection;", // + "asyncpg.~Connection;asyncpg.ConnectionPool;" ] } } @@ -35,13 +36,13 @@ private module Asyncpg { row = [ // `Connection`s and `ConnectionPool`s provide some methods that execute SQL. - "asyncpg;~Connection;Member[copy_from_query,execute,fetch,fetchrow,fetchval].Argument[0,query:];sql-injection", - "asyncpg;~Connection;Member[executemany].Argument[0,command:];sql-injection", + "asyncpg.~Connection;Member[copy_from_query,execute,fetch,fetchrow,fetchval].Argument[0,query:];sql-injection", + "asyncpg.~Connection;Member[executemany].Argument[0,command:];sql-injection", // A model of `Connection` and `ConnectionPool`, which provide some methods that access the file system. - "asyncpg;~Connection;Member[copy_from_query,copy_from_table].Argument[output:];path-injection", - "asyncpg;~Connection;Member[copy_to_table].Argument[source:];path-injection", + "asyncpg.~Connection;Member[copy_from_query,copy_from_table].Argument[output:];path-injection", + "asyncpg.~Connection;Member[copy_to_table].Argument[source:];path-injection", // the `PreparedStatement` class in `asyncpg`. - "asyncpg;Connection;Member[prepare].Argument[0,query:];sql-injection", + "asyncpg.Connection;Member[prepare].Argument[0,query:];sql-injection", ] } } @@ -58,7 +59,7 @@ private module Asyncpg { module Cursor { class CursorConstruction extends SqlConstruction::Range, API::CallNode { CursorConstruction() { - this = ModelOutput::getATypeNode("asyncpg", "Connection").getMember("cursor").getACall() + this = ModelOutput::getATypeNode("asyncpg.Connection").getMember("cursor").getACall() } override DataFlow::Node getSql() { result = this.getParameter(0, "query").asSink() } @@ -76,7 +77,7 @@ private module Asyncpg { or exists(API::CallNode prepareCall | prepareCall = - ModelOutput::getATypeNode("asyncpg", "Connection").getMember("prepare").getACall() + ModelOutput::getATypeNode("asyncpg.Connection").getMember("prepare").getACall() | sql = prepareCall.getParameter(0, "query").asSink() and this = diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll index 9b2428f3413..0e744ba801a 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll @@ -5,23 +5,20 @@ * * The CSV specification has the following columns: * - Sources: - * `package; type; path; kind` + * `type; path; kind` * - Sinks: - * `package; type; path; kind` + * `type; path; kind` * - Summaries: - * `package; type; path; input; output; kind` + * `type; path; input; output; kind` * - Types: - * `package1; type1; package2; type2; path` + * `type1; type2; path` * * The interpretation of a row is similar to API-graphs with a left-to-right * reading. - * 1. The `package` column selects a package name, as it would be referenced in the source code, - * such as an NPM package, PIP package, or Ruby gem. (See `ModelsAsData.qll` for language-specific details). - * It may also be a synthetic package used for a type definition (see type definitions below). - * 2. The `type` column selects all instances of a named type originating from that package, - * or the empty string if referring to the package itself. + * 1. The `type` column selects all instances of a named type. The syntax of this column is language-specific. + * The language defines some type names that the analysis knows how to identify without models. * It can also be a synthetic type name defined by a type definition (see type definitions below). - * 3. The `path` column is a `.`-separated list of "access path tokens" to resolve, starting at the node selected by `package` and `type`. + * 2. The `path` column is a `.`-separated list of "access path tokens" to resolve, starting at the node selected by `type`. * * Every language supports the following tokens: * - Argument[n]: the n-th argument to a call. May be a range of form `x..y` (inclusive) and/or a comma-separated list. @@ -42,10 +39,10 @@ * * For the time being, please consult `ApiGraphModelsSpecific.qll` to see which language-specific tokens are currently supported. * - * 4. The `input` and `output` columns specify how data enters and leaves the element selected by the - * first `(package, type, path)` tuple. Both strings are `.`-separated access paths + * 3. The `input` and `output` columns specify how data enters and leaves the element selected by the + * first `(type, path)` tuple. Both strings are `.`-separated access paths * of the same syntax as the `path` column. - * 5. The `kind` column is a tag that can be referenced from QL to determine to + * 4. The `kind` column is a tag that can be referenced from QL to determine to * which classes the interpreted elements should be added. For example, for * sources `"remote"` indicates a default remote flow source, and for summaries * `"taint"` indicates a default additional taint step and `"value"` indicates a @@ -53,17 +50,17 @@ * * ### Types * - * A type row of form `package1; type1; package2; type2; path` indicates that `package2; type2; path` - * should be seen as an instance of the type `package1; type1`. + * A type row of form `type1; type2; path` indicates that `type2; path` + * should be seen as an instance of the type `type1`. * - * A `(package,type)` pair may refer to a static type or a synthetic type name used internally in the model. + * A type may refer to a static type or a synthetic type name used internally in the model. * Synthetic type names can be used to reuse intermediate sub-paths, when there are multiple ways to access the same * element. - * See `ModelsAsData.qll` for the language-specific interpretation of packages and static type names. + * See `ModelsAsData.qll` for the language-specific interpretation of type names. * - * By convention, if one wants to avoid clashes with static types from the package, the type name - * should be prefixed with a tilde character (`~`). For example, `(foo, ~Bar)` can be used to indicate that - * the type is related to the `foo` package but is not intended to match a static type. + * By convention, if one wants to avoid clashes with static types, the type name + * should be prefixed with a tilde character (`~`). For example, `~Bar` can be used to indicate that + * the type is not intended to match a static type. */ private import ApiGraphModelsSpecific as Specific @@ -89,9 +86,9 @@ module ModelInput { * * A row of form * ``` - * package;type;path;kind + * type;path;kind * ``` - * indicates that the value at `(package, type, path)` should be seen as a flow + * indicates that the value at `(type, path)` should be seen as a flow * source of the given `kind`. * * The kind `remote` represents a general remote flow source. @@ -110,9 +107,9 @@ module ModelInput { * * A row of form * ``` - * package;type;path;kind + * type;path;kind * ``` - * indicates that the value at `(package, type, path)` should be seen as a sink + * indicates that the value at `(type, path)` should be seen as a sink * of the given `kind`. */ abstract predicate row(string row); @@ -129,9 +126,9 @@ module ModelInput { * * A row of form * ``` - * package;type;path;input;output;kind + * type;path;input;output;kind * ``` - * indicates that for each call to `(package, type, path)`, the value referred to by `input` + * indicates that for each call to `(type, path)`, the value referred to by `input` * can flow to the value referred to by `output`. * * `kind` should be either `value` or `taint`, for value-preserving or taint-preserving steps, @@ -151,9 +148,9 @@ module ModelInput { * * A row of form, * ``` - * package1;type1;package2;type2;path + * type1;type2;path * ``` - * indicates that `(package2, type2, path)` should be seen as an instance of `(package1, type1)`. + * indicates that `(type2, path)` should be seen as an instance of `type1`. */ abstract predicate row(string row); } @@ -163,28 +160,28 @@ module ModelInput { */ class TypeModel extends Unit { /** - * Gets a data-flow node that is a source of the type `package;type`. + * Gets a data-flow node that is a source of the given `type`. * * This must not depend on API graphs, but ensures that an API node is generated for * the source. */ - DataFlow::Node getASource(string package, string type) { none() } + DataFlow::Node getASource(string type) { none() } /** - * Gets a data-flow node that is a sink of the type `package;type`, + * Gets a data-flow node that is a sink of the given `type`, * usually because it is an argument passed to a parameter of that type. * * This must not depend on API graphs, but ensures that an API node is generated for * the sink. */ - DataFlow::Node getASink(string package, string type) { none() } + DataFlow::Node getASink(string type) { none() } /** - * Gets an API node that is a source or sink of the type `package;type`. + * Gets an API node that is a source or sink of the given `type`. * * Unlike `getASource` and `getASink`, this may depend on API graphs. */ - API::Node getAnApiNode(string package, string type) { none() } + API::Node getAnApiNode(string type) { none() } } /** @@ -209,7 +206,7 @@ private import ModelInput /** * An empty class, except in specific tests. * - * If this is non-empty, all models are parsed even if the package is not + * If this is non-empty, all models are parsed even if the type name is not * considered relevant for the current database. */ abstract class TestAllModels extends Unit { } @@ -232,53 +229,44 @@ private predicate typeModel(string row) { any(TypeModelCsv s).row(inversePad(row private predicate typeVariableModel(string row) { any(TypeVariableModelCsv s).row(inversePad(row)) } /** Holds if a source model exists for the given parameters. */ -predicate sourceModel(string package, string type, string path, string kind) { +predicate sourceModel(string type, string path, string kind) { exists(string row | sourceModel(row) and - row.splitAt(";", 0) = package and - row.splitAt(";", 1) = type and - row.splitAt(";", 2) = path and - row.splitAt(";", 3) = kind + row.splitAt(";", 0) = type and + row.splitAt(";", 1) = path and + row.splitAt(";", 2) = kind ) } /** Holds if a sink model exists for the given parameters. */ -private predicate sinkModel(string package, string type, string path, string kind) { +private predicate sinkModel(string type, string path, string kind) { exists(string row | sinkModel(row) and - row.splitAt(";", 0) = package and - row.splitAt(";", 1) = type and - row.splitAt(";", 2) = path and - row.splitAt(";", 3) = kind + row.splitAt(";", 0) = type and + row.splitAt(";", 1) = path and + row.splitAt(";", 2) = kind ) } /** Holds if a summary model `row` exists for the given parameters. */ -private predicate summaryModel( - string package, string type, string path, string input, string output, string kind -) { +private predicate summaryModel(string type, string path, string input, string output, string kind) { exists(string row | summaryModel(row) and - row.splitAt(";", 0) = package and - row.splitAt(";", 1) = type and - row.splitAt(";", 2) = path and - row.splitAt(";", 3) = input and - row.splitAt(";", 4) = output and - row.splitAt(";", 5) = kind + row.splitAt(";", 0) = type and + row.splitAt(";", 1) = path and + row.splitAt(";", 2) = input and + row.splitAt(";", 3) = output and + row.splitAt(";", 4) = kind ) } /** Holds if a type model exists for the given parameters. */ -private predicate typeModel( - string package1, string type1, string package2, string type2, string path -) { +private predicate typeModel(string type1, string type2, string path) { exists(string row | typeModel(row) and - row.splitAt(";", 0) = package1 and - row.splitAt(";", 1) = type1 and - row.splitAt(";", 2) = package2 and - row.splitAt(";", 3) = type2 and - row.splitAt(";", 4) = path + row.splitAt(";", 0) = type1 and + row.splitAt(";", 1) = type2 and + row.splitAt(";", 2) = path ) } @@ -292,61 +280,50 @@ private predicate typeVariableModel(string name, string path) { } /** - * Gets a package that should be seen as an alias for the given other `package`, - * or the `package` itself. + * Holds if CSV rows involving `type` might be relevant for the analysis of this database. */ -bindingset[package] -bindingset[result] -string getAPackageAlias(string package) { - typeModel(package, "", result, "", "") - or - result = package -} - -/** - * Holds if CSV rows involving `package` might be relevant for the analysis of this database. - */ -private predicate isRelevantPackage(string package) { +predicate isRelevantType(string type) { ( - sourceModel(package, _, _, _) or - sinkModel(package, _, _, _) or - summaryModel(package, _, _, _, _, _) or - typeModel(_, _, package, _, _) + sourceModel(type, _, _) or + sinkModel(type, _, _) or + summaryModel(type, _, _, _, _) or + typeModel(_, type, _) ) and ( - Specific::isPackageUsed(package) + Specific::isTypeUsed(type) or exists(TestAllModels t) ) or - exists(string other | - isRelevantPackage(other) and - typeModel(package, _, other, _, _) + exists(string other | isRelevantType(other) | + typeModel(type, other, _) + or + Specific::hasImplicitTypeModel(type, other) ) } /** - * Holds if `package,type,path` is used in some CSV row. + * Holds if `type,path` is used in some CSV row. */ pragma[nomagic] -predicate isRelevantFullPath(string package, string type, string path) { - isRelevantPackage(package) and +predicate isRelevantFullPath(string type, string path) { + isRelevantType(type) and ( - sourceModel(package, type, path, _) or - sinkModel(package, type, path, _) or - summaryModel(package, type, path, _, _, _) or - typeModel(_, _, package, type, path) + sourceModel(type, path, _) or + sinkModel(type, path, _) or + summaryModel(type, path, _, _, _) or + typeModel(_, type, path) ) } /** A string from a CSV row that should be parsed as an access path. */ private class AccessPathRange extends AccessPath::Range { AccessPathRange() { - isRelevantFullPath(_, _, this) + isRelevantFullPath(_, this) or - exists(string package | isRelevantPackage(package) | - summaryModel(package, _, _, this, _, _) or - summaryModel(package, _, _, _, this, _) + exists(string type | isRelevantType(type) | + summaryModel(type, _, this, _, _) or + summaryModel(type, _, _, this, _) ) or typeVariableModel(_, this) @@ -400,83 +377,73 @@ private predicate invocationMatchesCallSiteFilter(Specific::InvokeNode invoke, A } private class TypeModelUseEntry extends API::EntryPoint { - private string package; private string type; TypeModelUseEntry() { - exists(any(TypeModel tm).getASource(package, type)) and - this = "TypeModelUseEntry;" + package + ";" + type + exists(any(TypeModel tm).getASource(type)) and + this = "TypeModelUseEntry;" + type } - override DataFlow::LocalSourceNode getASource() { - result = any(TypeModel tm).getASource(package, type) - } + override DataFlow::LocalSourceNode getASource() { result = any(TypeModel tm).getASource(type) } - API::Node getNodeForType(string package_, string type_) { - package = package_ and type = type_ and result = this.getANode() - } + API::Node getNodeForType(string type_) { type = type_ and result = this.getANode() } } private class TypeModelDefEntry extends API::EntryPoint { - private string package; private string type; TypeModelDefEntry() { - exists(any(TypeModel tm).getASink(package, type)) and - this = "TypeModelDefEntry;" + package + ";" + type + exists(any(TypeModel tm).getASink(type)) and + this = "TypeModelDefEntry;" + type } - override DataFlow::Node getASink() { result = any(TypeModel tm).getASink(package, type) } + override DataFlow::Node getASink() { result = any(TypeModel tm).getASink(type) } - API::Node getNodeForType(string package_, string type_) { - package = package_ and type = type_ and result = this.getANode() - } + API::Node getNodeForType(string type_) { type = type_ and result = this.getANode() } } /** - * Gets an API node identified by the given `(package,type)` pair. + * Gets an API node identified by the given `type`. */ pragma[nomagic] -private API::Node getNodeFromType(string package, string type) { - exists(string package2, string type2, AccessPath path2 | - typeModel(package, type, package2, type2, path2) and - result = getNodeFromPath(package2, type2, path2) +private API::Node getNodeFromType(string type) { + exists(string type2, AccessPath path2 | + typeModel(type, type2, path2) and + result = getNodeFromPath(type2, path2) ) or - result = any(TypeModelUseEntry e).getNodeForType(package, type) + result = any(TypeModelUseEntry e).getNodeForType(type) or - result = any(TypeModelDefEntry e).getNodeForType(package, type) + result = any(TypeModelDefEntry e).getNodeForType(type) or - result = any(TypeModel t).getAnApiNode(package, type) + result = any(TypeModel t).getAnApiNode(type) or - result = Specific::getExtraNodeFromType(package, type) + result = Specific::getExtraNodeFromType(type) } /** - * Gets the API node identified by the first `n` tokens of `path` in the given `(package, type, path)` tuple. + * Gets the API node identified by the first `n` tokens of `path` in the given `(type, path)` tuple. */ pragma[nomagic] -private API::Node getNodeFromPath(string package, string type, AccessPath path, int n) { - isRelevantFullPath(package, type, path) and +private API::Node getNodeFromPath(string type, AccessPath path, int n) { + isRelevantFullPath(type, path) and ( n = 0 and - result = getNodeFromType(package, type) + result = getNodeFromType(type) or - result = Specific::getExtraNodeFromPath(package, type, path, n) + result = Specific::getExtraNodeFromPath(type, path, n) ) or - result = getSuccessorFromNode(getNodeFromPath(package, type, path, n - 1), path.getToken(n - 1)) + result = getSuccessorFromNode(getNodeFromPath(type, path, n - 1), path.getToken(n - 1)) or // Similar to the other recursive case, but where the path may have stepped through one or more call-site filters - result = - getSuccessorFromInvoke(getInvocationFromPath(package, type, path, n - 1), path.getToken(n - 1)) + result = getSuccessorFromInvoke(getInvocationFromPath(type, path, n - 1), path.getToken(n - 1)) or // Apply a subpath - result = - getNodeFromSubPath(getNodeFromPath(package, type, path, n - 1), getSubPathAt(path, n - 1)) + result = getNodeFromSubPath(getNodeFromPath(type, path, n - 1), getSubPathAt(path, n - 1)) or // Apply a type step - typeStep(getNodeFromPath(package, type, path, n), result) + typeStep(getNodeFromPath(type, path, n), result) } /** @@ -496,15 +463,15 @@ private AccessPath getSubPathAt(AccessPath path, int n) { pragma[nomagic] private API::Node getNodeFromSubPath(API::Node base, AccessPath subPath, int n) { exists(AccessPath path, int k | - base = [getNodeFromPath(_, _, path, k), getNodeFromSubPath(_, path, k)] and + base = [getNodeFromPath(_, path, k), getNodeFromSubPath(_, path, k)] and subPath = getSubPathAt(path, k) and result = base and n = 0 ) or - exists(string package, string type, AccessPath basePath | - typeStepModel(package, type, basePath, subPath) and - base = getNodeFromPath(package, type, basePath) and + exists(string type, AccessPath basePath | + typeStepModel(type, basePath, subPath) and + base = getNodeFromPath(type, basePath) and result = base and n = 0 ) @@ -543,42 +510,40 @@ private API::Node getNodeFromSubPath(API::Node base, AccessPath subPath) { result = getNodeFromSubPath(base, subPath, subPath.getNumToken()) } -/** Gets the node identified by the given `(package, type, path)` tuple. */ -private API::Node getNodeFromPath(string package, string type, AccessPath path) { - result = getNodeFromPath(package, type, path, path.getNumToken()) +/** Gets the node identified by the given `(type, path)` tuple. */ +private API::Node getNodeFromPath(string type, AccessPath path) { + result = getNodeFromPath(type, path, path.getNumToken()) } pragma[nomagic] -private predicate typeStepModel(string package, string type, AccessPath basePath, AccessPath output) { - summaryModel(package, type, basePath, "", output, "type") +private predicate typeStepModel(string type, AccessPath basePath, AccessPath output) { + summaryModel(type, basePath, "", output, "type") } pragma[nomagic] private predicate typeStep(API::Node pred, API::Node succ) { - exists(string package, string type, AccessPath basePath, AccessPath output | - typeStepModel(package, type, basePath, output) and - pred = getNodeFromPath(package, type, basePath) and + exists(string type, AccessPath basePath, AccessPath output | + typeStepModel(type, basePath, output) and + pred = getNodeFromPath(type, basePath) and succ = getNodeFromSubPath(pred, output) ) } /** - * Gets an invocation identified by the given `(package, type, path)` tuple. + * Gets an invocation identified by the given `(type, path)` tuple. * * Unlike `getNodeFromPath`, the `path` may end with one or more call-site filters. */ -private Specific::InvokeNode getInvocationFromPath( - string package, string type, AccessPath path, int n -) { - result = Specific::getAnInvocationOf(getNodeFromPath(package, type, path, n)) +private Specific::InvokeNode getInvocationFromPath(string type, AccessPath path, int n) { + result = Specific::getAnInvocationOf(getNodeFromPath(type, path, n)) or - result = getInvocationFromPath(package, type, path, n - 1) and + result = getInvocationFromPath(type, path, n - 1) and invocationMatchesCallSiteFilter(result, path.getToken(n - 1)) } -/** Gets an invocation identified by the given `(package, type, path)` tuple. */ -private Specific::InvokeNode getInvocationFromPath(string package, string type, AccessPath path) { - result = getInvocationFromPath(package, type, path, path.getNumToken()) +/** Gets an invocation identified by the given `(type, path)` tuple. */ +private Specific::InvokeNode getInvocationFromPath(string type, AccessPath path) { + result = getInvocationFromPath(type, path, path.getNumToken()) } /** @@ -631,9 +596,9 @@ module ModelOutput { */ cached API::Node getASourceNode(string kind) { - exists(string package, string type, string path | - sourceModel(package, type, path, kind) and - result = getNodeFromPath(package, type, path) + exists(string type, string path | + sourceModel(type, path, kind) and + result = getNodeFromPath(type, path) ) } @@ -642,9 +607,9 @@ module ModelOutput { */ cached API::Node getASinkNode(string kind) { - exists(string package, string type, string path | - sinkModel(package, type, path, kind) and - result = getNodeFromPath(package, type, path) + exists(string type, string path | + sinkModel(type, path, kind) and + result = getNodeFromPath(type, path) ) } @@ -653,32 +618,31 @@ module ModelOutput { */ cached predicate relevantSummaryModel( - string package, string type, string path, string input, string output, string kind + string type, string path, string input, string output, string kind ) { - isRelevantPackage(package) and - summaryModel(package, type, path, input, output, kind) + isRelevantType(type) and + summaryModel(type, path, input, output, kind) } /** - * Holds if a `baseNode` is an invocation identified by the `package,type,path` part of a summary row. + * Holds if a `baseNode` is an invocation identified by the `type,path` part of a summary row. */ cached - predicate resolvedSummaryBase( - string package, string type, string path, Specific::InvokeNode baseNode - ) { - summaryModel(package, type, path, _, _, _) and - baseNode = getInvocationFromPath(package, type, path) + predicate resolvedSummaryBase(string type, string path, Specific::InvokeNode baseNode) { + summaryModel(type, path, _, _, _) and + baseNode = getInvocationFromPath(type, path) } /** - * Holds if `node` is seen as an instance of `(package,type)` due to a type definition + * Holds if `node` is seen as an instance of `type` due to a type definition * contributed by a CSV model. */ cached - API::Node getATypeNode(string package, string type) { result = getNodeFromType(package, type) } + API::Node getATypeNode(string type) { result = getNodeFromType(type) } } import Cached + import Specific::ModelOutputSpecific /** * Gets an error message relating to an invalid CSV row in a model. @@ -686,13 +650,13 @@ module ModelOutput { string getAWarning() { // Check number of columns exists(string row, string kind, int expectedArity, int actualArity | - any(SourceModelCsv csv).row(row) and kind = "source" and expectedArity = 4 + any(SourceModelCsv csv).row(row) and kind = "source" and expectedArity = 3 or - any(SinkModelCsv csv).row(row) and kind = "sink" and expectedArity = 4 + any(SinkModelCsv csv).row(row) and kind = "sink" and expectedArity = 3 or - any(SummaryModelCsv csv).row(row) and kind = "summary" and expectedArity = 6 + any(SummaryModelCsv csv).row(row) and kind = "summary" and expectedArity = 5 or - any(TypeModelCsv csv).row(row) and kind = "type" and expectedArity = 5 + any(TypeModelCsv csv).row(row) and kind = "type" and expectedArity = 3 or any(TypeVariableModelCsv csv).row(row) and kind = "type-variable" and expectedArity = 2 | @@ -705,7 +669,7 @@ module ModelOutput { or // Check names and arguments of access path tokens exists(AccessPath path, AccessPathToken token | - (isRelevantFullPath(_, _, path) or typeVariableModel(_, path)) and + (isRelevantFullPath(_, path) or typeVariableModel(_, path)) and token = path.getToken(_) | not isValidTokenNameInIdentifyingAccessPath(token.getName()) and diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModelsSpecific.qll b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModelsSpecific.qll index 2f53c4fdeea..eb23efe4aff 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModelsSpecific.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModelsSpecific.qll @@ -31,19 +31,22 @@ import semmle.python.dataflow.new.DataFlow::DataFlow as DataFlow private import AccessPathSyntax /** - * Holds if models describing `package` may be relevant for the analysis of this database. + * Holds if models describing `type` may be relevant for the analysis of this database. */ -predicate isPackageUsed(string package) { API::moduleImportExists(package) } +predicate isTypeUsed(string type) { API::moduleImportExists(type) } -/** Gets a Python-specific interpretation of the `(package, type, path)` tuple after resolving the first `n` access path tokens. */ -bindingset[package, type, path] -API::Node getExtraNodeFromPath(string package, string type, AccessPath path, int n) { none() } +/** + * Holds if `type` can be obtained from an instance of `otherType` due to + * language semantics modeled by `getExtraNodeFromType`. + */ +predicate hasImplicitTypeModel(string type, string otherType) { none() } -/** Gets a Python-specific interpretation of the `(package, type)` tuple. */ -API::Node getExtraNodeFromType(string package, string type) { - type = "" and - result = API::moduleImport(package) -} +/** Gets a Python-specific interpretation of the `(type, path)` tuple after resolving the first `n` access path tokens. */ +bindingset[type, path] +API::Node getExtraNodeFromPath(string type, AccessPath path, int n) { none() } + +/** Gets a Python-specific interpretation of the given `type`. */ +API::Node getExtraNodeFromType(string type) { result = API::moduleImport(type) } /** * Gets a Python-specific API graph successor of `node` reachable by resolving `token`. @@ -121,9 +124,9 @@ predicate invocationMatchesExtraCallSiteFilter(API::CallNode invoke, AccessPathT */ pragma[nomagic] private predicate relevantInputOutputPath(API::CallNode base, AccessPath inputOrOutput) { - exists(string package, string type, string input, string output, string path | - ModelOutput::relevantSummaryModel(package, type, path, input, output, _) and - ModelOutput::resolvedSummaryBase(package, type, path, base) and + exists(string type, string input, string output, string path | + ModelOutput::relevantSummaryModel(type, path, input, output, _) and + ModelOutput::resolvedSummaryBase(type, path, base) and inputOrOutput = [input, output] ) } @@ -153,12 +156,9 @@ private API::Node getNodeFromInputOutputPath(API::CallNode baseNode, AccessPath * Holds if a CSV summary contributed the step `pred -> succ` of the given `kind`. */ predicate summaryStep(API::Node pred, API::Node succ, string kind) { - exists( - string package, string type, string path, API::CallNode base, AccessPath input, - AccessPath output - | - ModelOutput::relevantSummaryModel(package, type, path, input, output, kind) and - ModelOutput::resolvedSummaryBase(package, type, path, base) and + exists(string type, string path, API::CallNode base, AccessPath input, AccessPath output | + ModelOutput::relevantSummaryModel(type, path, input, output, kind) and + ModelOutput::resolvedSummaryBase(type, path, base) and pred = getNodeFromInputOutputPath(base, input) and succ = getNodeFromInputOutputPath(base, output) ) @@ -201,3 +201,5 @@ predicate isExtraValidTokenArgumentInIdentifyingAccessPath(string name, string a argument.regexpMatch("\\w+:") // keyword argument ) } + +module ModelOutputSpecific { } diff --git a/python/ql/test/library-tests/frameworks/data/test.ql b/python/ql/test/library-tests/frameworks/data/test.ql index 00411a5f95f..6c7639dc0c3 100644 --- a/python/ql/test/library-tests/frameworks/data/test.ql +++ b/python/ql/test/library-tests/frameworks/data/test.ql @@ -7,78 +7,78 @@ private import semmle.python.ApiGraphs class Steps extends ModelInput::SummaryModelCsv { override predicate row(string row) { - // package;type;path;input;output;kind + // type;path;input;output;kind row = [ - "testlib;;Member[Steps].Member[preserveTaint].Call;Argument[0];ReturnValue;taint", - "testlib;;Member[Steps].Member[taintIntoCallback];Argument[0];Argument[1..2].Parameter[0];taint", - "testlib;;Member[Steps].Member[preserveArgZeroAndTwo];Argument[0,2];ReturnValue;taint", - "testlib;;Member[Steps].Member[preserveAllButFirstArgument].Call;Argument[1..];ReturnValue;taint", + "testlib;Member[Steps].Member[preserveTaint].Call;Argument[0];ReturnValue;taint", + "testlib;Member[Steps].Member[taintIntoCallback];Argument[0];Argument[1..2].Parameter[0];taint", + "testlib;Member[Steps].Member[preserveArgZeroAndTwo];Argument[0,2];ReturnValue;taint", + "testlib;Member[Steps].Member[preserveAllButFirstArgument].Call;Argument[1..];ReturnValue;taint", ] } } class Types extends ModelInput::TypeModelCsv { override predicate row(string row) { - // package1;type1;package2;type2;path + // type1;type2;path row = [ - "testlib;Alias;testlib;;Member[alias].ReturnValue", - "testlib;Alias;testlib;Alias;Member[chain].ReturnValue", + "testlib.Alias;testlib;Member[alias].ReturnValue", + "testlib.Alias;testlib.Alias;Member[chain].ReturnValue", ] } } class Sinks extends ModelInput::SinkModelCsv { override predicate row(string row) { - // package;type;path;kind + // type;path;kind row = [ - "testlib;;Member[mySink].Argument[0,sinkName:];test-sink", + "testlib;Member[mySink].Argument[0,sinkName:];test-sink", // testing argument syntax - "testlib;;Member[Args].Member[arg0].Argument[0];test-sink", // - "testlib;;Member[Args].Member[arg1to3].Argument[1..3];test-sink", // - "testlib;;Member[Args].Member[lastarg].Argument[N-1];test-sink", // - "testlib;;Member[Args].Member[nonFist].Argument[1..];test-sink", // + "testlib;Member[Args].Member[arg0].Argument[0];test-sink", // + "testlib;Member[Args].Member[arg1to3].Argument[1..3];test-sink", // + "testlib;Member[Args].Member[lastarg].Argument[N-1];test-sink", // + "testlib;Member[Args].Member[nonFist].Argument[1..];test-sink", // // callsite filter. - "testlib;;Member[CallFilter].Member[arityOne].WithArity[1].Argument[any];test-sink", // - "testlib;;Member[CallFilter].Member[twoOrMore].WithArity[2..].Argument[0..];test-sink", // + "testlib;Member[CallFilter].Member[arityOne].WithArity[1].Argument[any];test-sink", // + "testlib;Member[CallFilter].Member[twoOrMore].WithArity[2..].Argument[0..];test-sink", // // testing non-positional arguments - "testlib;;Member[ArgPos].Instance.Member[self_thing].Argument[self];test-sink", // + "testlib;Member[ArgPos].Instance.Member[self_thing].Argument[self];test-sink", // // any argument - "testlib;;Member[ArgPos].Member[anyParam].Argument[any];test-sink", // - "testlib;;Member[ArgPos].Member[anyNamed].Argument[any-named];test-sink", // + "testlib;Member[ArgPos].Member[anyParam].Argument[any];test-sink", // + "testlib;Member[ArgPos].Member[anyNamed].Argument[any-named];test-sink", // // testing package syntax - "foo1.bar;;Member[baz1].Argument[any];test-sink", // - "foo2;;Member[bar].Member[baz2].Argument[any];test-sink", // + "foo1.bar;Member[baz1].Argument[any];test-sink", // + "foo2;Member[bar].Member[baz2].Argument[any];test-sink", // ] } } class Sources extends ModelInput::SourceModelCsv { - // package;type;path;kind + // type;path;kind override predicate row(string row) { row = [ - "testlib;;Member[getSource].ReturnValue;test-source", // - "testlib;Alias;;test-source", + "testlib;Member[getSource].ReturnValue;test-source", // + "testlib.Alias;;test-source", // testing parameter syntax - "testlib;;Member[Callbacks].Member[first].Argument[0].Parameter[0];test-source", // - "testlib;;Member[Callbacks].Member[param1to3].Argument[0].Parameter[1..3];test-source", // - "testlib;;Member[Callbacks].Member[nonFirst].Argument[0].Parameter[1..];test-source", // + "testlib;Member[Callbacks].Member[first].Argument[0].Parameter[0];test-source", // + "testlib;Member[Callbacks].Member[param1to3].Argument[0].Parameter[1..3];test-source", // + "testlib;Member[Callbacks].Member[nonFirst].Argument[0].Parameter[1..];test-source", // // Common tokens. - "testlib;;Member[CommonTokens].Member[makePromise].ReturnValue.Awaited;test-source", // - "testlib;;Member[CommonTokens].Member[Class].Instance;test-source", // - "testlib;;Member[CommonTokens].Member[Super].Subclass.Instance;test-source", // + "testlib;Member[CommonTokens].Member[makePromise].ReturnValue.Awaited;test-source", // + "testlib;Member[CommonTokens].Member[Class].Instance;test-source", // + "testlib;Member[CommonTokens].Member[Super].Subclass.Instance;test-source", // // method - "testlib;;Member[CommonTokens].Member[Class].Instance.Method[foo];test-source", // + "testlib;Member[CommonTokens].Member[Class].Instance.Method[foo];test-source", // // testing non-positional arguments - "testlib;;Member[ArgPos].Member[MyClass].Subclass.Member[foo].Parameter[self];test-source", // - "testlib;;Member[ArgPos].Member[MyClass].Subclass.Member[foo].Parameter[named:];test-source", // - "testlib;;Member[ArgPos].Member[MyClass].Subclass.Member[secondAndAfter].Parameter[1..];test-source", // - "testlib;;Member[ArgPos].Member[MyClass].Subclass.Member[otherSelfTest].Parameter[0];test-source", // - "testlib;;Member[ArgPos].Member[MyClass].Subclass.Member[anyParam].Parameter[any];test-source", // - "testlib;;Member[ArgPos].Member[MyClass].Subclass.Member[anyNamed].Parameter[any-named];test-source", // + "testlib;Member[ArgPos].Member[MyClass].Subclass.Member[foo].Parameter[self];test-source", // + "testlib;Member[ArgPos].Member[MyClass].Subclass.Member[foo].Parameter[named:];test-source", // + "testlib;Member[ArgPos].Member[MyClass].Subclass.Member[secondAndAfter].Parameter[1..];test-source", // + "testlib;Member[ArgPos].Member[MyClass].Subclass.Member[otherSelfTest].Parameter[0];test-source", // + "testlib;Member[ArgPos].Member[MyClass].Subclass.Member[anyParam].Parameter[any];test-source", // + "testlib;Member[ArgPos].Member[MyClass].Subclass.Member[anyNamed].Parameter[any-named];test-source", // ] } } @@ -111,13 +111,16 @@ class SyntaxErrorTest extends ModelInput::SinkModelCsv { override predicate row(string row) { row = [ - "testlib;;Member[foo],Member[bar];test-sink", "testlib;;Member[foo] Member[bar];test-sink", - "testlib;;Member[foo]. Member[bar];test-sink", - "testlib;;Member[foo], Member[bar];test-sink", - "testlib;;Member[foo]..Member[bar];test-sink", - "testlib;;Member[foo] .Member[bar];test-sink", "testlib;;Member[foo]Member[bar];test-sink", - "testlib;;Member[foo;test-sink", "testlib;;Member[foo]];test-sink", - "testlib;;Member[foo]].Member[bar];test-sink" + "testlib;Member[foo],Member[bar];test-sink", // + "testlib;Member[foo] Member[bar];test-sink", // + "testlib;Member[foo]. Member[bar];test-sink", // + "testlib;Member[foo], Member[bar];test-sink", // + "testlib;Member[foo]..Member[bar];test-sink", // + "testlib;Member[foo] .Member[bar];test-sink", // + "testlib;Member[foo]Member[bar];test-sink", // + "testlib;Member[foo;test-sink", // + "testlib;Member[foo]];test-sink", // + "testlib;Member[foo]].Member[bar];test-sink", // ] } } diff --git a/python/ql/test/library-tests/frameworks/data/warnings.expected b/python/ql/test/library-tests/frameworks/data/warnings.expected index 5cebb548358..23ce426abb9 100644 --- a/python/ql/test/library-tests/frameworks/data/warnings.expected +++ b/python/ql/test/library-tests/frameworks/data/warnings.expected @@ -1,5 +1,5 @@ -| CSV type row should have 5 columns but has 2: test;TooFewColumns | -| CSV type row should have 5 columns but has 8: test;TooManyColumns;;;Member[Foo].Instance;too;many;columns | +| CSV type row should have 3 columns but has 1: test.TooFewColumns | +| CSV type row should have 3 columns but has 6: test.TooManyColumns;;Member[Foo].Instance;too;many;columns | | Invalid argument '0-1' in token 'Argument[0-1]' in access path: Method[foo].Argument[0-1] | | Invalid argument '*' in token 'Argument[*]' in access path: Method[foo].Argument[*] | | Invalid token 'Argument' is missing its arguments, in access path: Method[foo].Argument | diff --git a/python/ql/test/library-tests/frameworks/data/warnings.ql b/python/ql/test/library-tests/frameworks/data/warnings.ql index 20b87211765..c6561797164 100644 --- a/python/ql/test/library-tests/frameworks/data/warnings.ql +++ b/python/ql/test/library-tests/frameworks/data/warnings.ql @@ -7,13 +7,13 @@ private class InvalidTypeModel extends ModelInput::TypeModelCsv { override predicate row(string row) { row = [ - "test;TooManyColumns;;;Member[Foo].Instance;too;many;columns", // - "test;TooFewColumns", // - "test;X;test;Y;Method[foo].Arg[0]", // - "test;X;test;Y;Method[foo].Argument[0-1]", // - "test;X;test;Y;Method[foo].Argument[*]", // - "test;X;test;Y;Method[foo].Argument", // - "test;X;test;Y;Method[foo].Member", // + "test.TooManyColumns;;Member[Foo].Instance;too;many;columns", // + "test.TooFewColumns", // + "test.X;test.Y;Method[foo].Arg[0]", // + "test.X;test.Y;Method[foo].Argument[0-1]", // + "test.X;test.Y;Method[foo].Argument[*]", // + "test.X;test.Y;Method[foo].Argument", // + "test.X;test.Y;Method[foo].Member", // ] } } From a55c56feed2019bec3fcc1f4fd0a00e7c1e479fa Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 23 Nov 2022 11:33:52 +0100 Subject: [PATCH 469/796] Fix typo in `codeql-workspace.yml` --- codeql-workspace.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codeql-workspace.yml b/codeql-workspace.yml index f93ed4ac5c8..3f3318d12c2 100644 --- a/codeql-workspace.yml +++ b/codeql-workspace.yml @@ -25,7 +25,7 @@ provide: - "misc/suite-helpers/qlpack.yml" - "ruby/extractor-pack/codeql-extractor.yml" - "swift/extractor-pack/codeql-extractor.yml" - - "ql/extractor-pack/codeql-extractor.ym" + - "ql/extractor-pack/codeql-extractor.yml" versionPolicies: default: From 3b698216304bad5c22df4dfffce0f0def6a8e3e7 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Wed, 23 Nov 2022 10:45:05 +0000 Subject: [PATCH 470/796] ATM: Add descriptions to ML-powered packs --- javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml | 1 + .../ql/experimental/adaptivethreatmodeling/model/qlpack.yml | 1 + .../experimental/adaptivethreatmodeling/modelbuilding/qlpack.yml | 1 + javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml | 1 + 4 files changed, 4 insertions(+) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml b/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml index fb53f54ded7..e3f7c7064d3 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml @@ -1,4 +1,5 @@ name: codeql/javascript-experimental-atm-lib +description: CodeQL libraries for the experimental ML-powered queries version: 0.4.2 extractor: javascript library: true diff --git a/javascript/ql/experimental/adaptivethreatmodeling/model/qlpack.yml b/javascript/ql/experimental/adaptivethreatmodeling/model/qlpack.yml index 40b611fc72a..e37547ed938 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/model/qlpack.yml +++ b/javascript/ql/experimental/adaptivethreatmodeling/model/qlpack.yml @@ -1,4 +1,5 @@ name: codeql/javascript-experimental-atm-model +description: Machine learning model supporting the experimental ML-powered queries version: 0.3.1 groups: - javascript diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/qlpack.yml b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/qlpack.yml index e6657138f1c..ac65fc1bb5f 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/qlpack.yml +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/qlpack.yml @@ -1,4 +1,5 @@ name: codeql/javascript-experimental-atm-model-building +description: CodeQL libraries for building machine learning models for the experimental ML-powered queries extractor: javascript library: false groups: diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml b/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml index 725beadcb0e..1378bc67041 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml @@ -1,4 +1,5 @@ name: codeql/javascript-experimental-atm-queries +description: Experimental ML-powered queries for JavaScript language: javascript version: 0.4.2 suites: codeql-suites From a1bffff0b0c30aaae3bbea21b34eea8446354a9a Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 23 Nov 2022 12:15:29 +0100 Subject: [PATCH 471/796] Swift: add downgrades script to extractor pack --- swift/BUILD.bazel | 1 + swift/downgrades/BUILD.bazel | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 swift/downgrades/BUILD.bazel diff --git a/swift/BUILD.bazel b/swift/BUILD.bazel index 446d021a6aa..4803d4b3153 100644 --- a/swift/BUILD.bazel +++ b/swift/BUILD.bazel @@ -33,6 +33,7 @@ pkg_filegroup( srcs = [ ":dbscheme_files", ":manifest", + "//swift/downgrades", "//swift/tools", ], visibility = ["//visibility:public"], diff --git a/swift/downgrades/BUILD.bazel b/swift/downgrades/BUILD.bazel new file mode 100644 index 00000000000..d76e543a6e7 --- /dev/null +++ b/swift/downgrades/BUILD.bazel @@ -0,0 +1,12 @@ +load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") + +pkg_files( + name = "downgrades", + srcs = glob( + ["**"], + exclude = ["BUILD.bazel"], + ), + prefix = "downgrades", + strip_prefix = strip_prefix.from_pkg(), + visibility = ["//swift:__pkg__"], +) From 807f87e01f0052d8e659c127621e62068e823b29 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 23 Nov 2022 12:56:32 +0100 Subject: [PATCH 472/796] Java: Adjust the prioritisation between MaD and source dispatch. --- java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll b/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll index 56385e89877..eb1878bf7e4 100644 --- a/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll +++ b/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll @@ -99,10 +99,12 @@ private module Dispatch { private predicate lowConfidenceDispatchType(SrcRefType t) { t instanceof TypeObject or - t instanceof FunctionalInterface + t instanceof Interface and not t.fromSource() or t.hasQualifiedName("java.io", "Serializable") or + t.hasQualifiedName("java.lang", "Iterable") + or t.hasQualifiedName("java.lang", "Cloneable") or t.getPackage().hasName("java.util") and t instanceof Interface From 8f3731fd42d7d0e0f1e062a34b3dc99ed4866fd7 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 23 Nov 2022 10:57:21 +0100 Subject: [PATCH 473/796] C#: Split `AutobuildOptions` into C#/C++ specific classes --- .github/workflows/csharp-qltest.yml | 1 + .../BuildScripts.cs | 6 +- .../Semmle.Autobuild.Cpp/CppAutobuilder.cs | 21 ++++- .../Semmle.Autobuild.Cpp/Program.cs | 4 +- .../BuildScripts.cs | 4 +- .../CSharpAutobuilder.cs | 27 +++++- .../Semmle.Autobuild.CSharp/DotNetRule.cs | 16 ++-- .../Semmle.Autobuild.CSharp/Program.cs | 2 +- .../StandaloneBuildRule.cs | 4 +- .../AutobuildOptions.cs | 18 ++-- .../Semmle.Autobuild.Shared/Autobuilder.cs | 85 ++++++++++++++----- .../BuildCommandAutoRule.cs | 8 +- .../BuildCommandRule.cs | 8 +- .../Semmle.Autobuild.Shared/MsBuildRule.cs | 12 +-- .../Semmle.Autobuild.Shared/Project.cs | 14 +-- .../ProjectOrSolution.cs | 4 +- .../Semmle.Autobuild.Shared/Solution.cs | 12 +-- 17 files changed, 163 insertions(+), 83 deletions(-) diff --git a/.github/workflows/csharp-qltest.yml b/.github/workflows/csharp-qltest.yml index 28b3fb7477d..531f4296a84 100644 --- a/.github/workflows/csharp-qltest.yml +++ b/.github/workflows/csharp-qltest.yml @@ -83,3 +83,4 @@ jobs: dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/csharp/extractor/Semmle.Util.Tests" dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/csharp/extractor/Semmle.Extraction.Tests" dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests" + dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests" diff --git a/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/BuildScripts.cs b/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/BuildScripts.cs index 76acba2eee4..def45890c9f 100644 --- a/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/BuildScripts.cs +++ b/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/BuildScripts.cs @@ -257,11 +257,11 @@ namespace Semmle.Autobuild.Cpp.Tests Actions.GetCurrentDirectory = cwd; Actions.IsWindows = isWindows; - var options = new AutobuildOptions(Actions, Language.Cpp); + var options = new CppAutobuildOptions(Actions); return new CppAutobuilder(Actions, options); } - void TestAutobuilderScript(Autobuilder autobuilder, int expectedOutput, int commandsRun) + void TestAutobuilderScript(CppAutobuilder autobuilder, int expectedOutput, int commandsRun) { Assert.Equal(expectedOutput, autobuilder.GetBuildScript().Run(Actions, StartCallback, EndCallback)); @@ -299,7 +299,7 @@ namespace Semmle.Autobuild.Cpp.Tests { Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test.sln -DisableParallelProcessing"] = 1; Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test.sln -DisableParallelProcessing"] = 0; - Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program Files ^(x86^)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat^"" && set Platform=&& type NUL && C:\odasa\tools\odasa index --auto msbuild C:\Project\test.sln /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"" /p:MvcBuildViews=true"] = 0; + Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program Files ^(x86^)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat^"" && set Platform=&& type NUL && msbuild C:\Project\test.sln /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"""] = 0; Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = ""; Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = 1; Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = 0; diff --git a/cpp/autobuilder/Semmle.Autobuild.Cpp/CppAutobuilder.cs b/cpp/autobuilder/Semmle.Autobuild.Cpp/CppAutobuilder.cs index 44c34656a2a..1503dedb376 100644 --- a/cpp/autobuilder/Semmle.Autobuild.Cpp/CppAutobuilder.cs +++ b/cpp/autobuilder/Semmle.Autobuild.Cpp/CppAutobuilder.cs @@ -2,9 +2,26 @@ namespace Semmle.Autobuild.Cpp { - public class CppAutobuilder : Autobuilder + ///

    + /// Encapsulates C++ build options. + /// + public class CppAutobuildOptions : AutobuildOptionsShared { - public CppAutobuilder(IBuildActions actions, AutobuildOptions options) : base(actions, options) { } + public override Language Language => Language.Cpp; + + + /// + /// Reads options from environment variables. + /// Throws ArgumentOutOfRangeException for invalid arguments. + /// + public CppAutobuildOptions(IBuildActions actions) : base(actions) + { + } + } + + public class CppAutobuilder : Autobuilder + { + public CppAutobuilder(IBuildActions actions, CppAutobuildOptions options) : base(actions, options) { } public override BuildScript GetBuildScript() { diff --git a/cpp/autobuilder/Semmle.Autobuild.Cpp/Program.cs b/cpp/autobuilder/Semmle.Autobuild.Cpp/Program.cs index 3f4627c53d5..a7556197bcd 100644 --- a/cpp/autobuilder/Semmle.Autobuild.Cpp/Program.cs +++ b/cpp/autobuilder/Semmle.Autobuild.Cpp/Program.cs @@ -11,14 +11,14 @@ namespace Semmle.Autobuild.Cpp try { var actions = SystemBuildActions.Instance; - var options = new AutobuildOptions(actions, Language.Cpp); + var options = new CppAutobuildOptions(actions); try { Console.WriteLine("CodeQL C++ autobuilder"); var builder = new CppAutobuilder(actions, options); return builder.AttemptBuild(); } - catch(InvalidEnvironmentException ex) + catch (InvalidEnvironmentException ex) { Console.WriteLine("The environment is invalid: {0}", ex.Message); } diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BuildScripts.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BuildScripts.cs index 9afe24ed72f..df362c2a129 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BuildScripts.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BuildScripts.cs @@ -403,7 +403,7 @@ namespace Semmle.Autobuild.CSharp.Tests actions.GetCurrentDirectory = cwd; actions.IsWindows = isWindows; - var options = new AutobuildOptions(actions, Language.CSharp); + var options = new CSharpAutobuildOptions(actions); return new CSharpAutobuilder(actions, options); } @@ -576,7 +576,7 @@ namespace Semmle.Autobuild.CSharp.Tests actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"] = false; } - private void TestAutobuilderScript(Autobuilder autobuilder, int expectedOutput, int commandsRun) + private void TestAutobuilderScript(CSharpAutobuilder autobuilder, int expectedOutput, int commandsRun) { Assert.Equal(expectedOutput, autobuilder.GetBuildScript().Run(actions, StartCallback, EndCallback)); diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/CSharpAutobuilder.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp/CSharpAutobuilder.cs index ff6d2c804cc..71891fa4e8b 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/CSharpAutobuilder.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/CSharpAutobuilder.cs @@ -4,9 +4,32 @@ using Semmle.Autobuild.Shared; namespace Semmle.Autobuild.CSharp { - public class CSharpAutobuilder : Autobuilder + /// + /// Encapsulates C# build options. + /// + public class CSharpAutobuildOptions : AutobuildOptionsShared { - public CSharpAutobuilder(IBuildActions actions, AutobuildOptions options) : base(actions, options) { } + private const string extractorOptionPrefix = "CODEQL_EXTRACTOR_CSHARP_OPTION_"; + + public bool Buildless { get; } + + public override Language Language => Language.CSharp; + + + /// + /// Reads options from environment variables. + /// Throws ArgumentOutOfRangeException for invalid arguments. + /// + public CSharpAutobuildOptions(IBuildActions actions) : base(actions) + { + Buildless = actions.GetEnvironmentVariable(lgtmPrefix + "BUILDLESS").AsBool("buildless", false) || + actions.GetEnvironmentVariable(extractorOptionPrefix + "BUILDLESS").AsBool("buildless", false); + } + } + + public class CSharpAutobuilder : Autobuilder + { + public CSharpAutobuilder(IBuildActions actions, CSharpAutobuildOptions options) : base(actions, options) { } public override BuildScript GetBuildScript() { diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs index 163dbfa1464..394349e2a40 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs @@ -13,9 +13,9 @@ namespace Semmle.Autobuild.CSharp /// A build rule where the build command is of the form "dotnet build". /// Currently unused because the tracer does not work with dotnet. /// - internal class DotNetRule : IBuildRule + internal class DotNetRule : IBuildRule { - public BuildScript Analyse(Autobuilder builder, bool auto) + public BuildScript Analyse(IAutobuilder builder, bool auto) { if (!builder.ProjectsOrSolutionsToBuild.Any()) return BuildScript.Failure; @@ -24,7 +24,7 @@ namespace Semmle.Autobuild.CSharp { var notDotNetProject = builder.ProjectsOrSolutionsToBuild .SelectMany(p => Enumerators.Singleton(p).Concat(p.IncludedProjects)) - .OfType() + .OfType>() .FirstOrDefault(p => !p.DotNetProject); if (notDotNetProject is not null) { @@ -56,7 +56,7 @@ namespace Semmle.Autobuild.CSharp }); } - private static BuildScript WithDotNet(Autobuilder builder, Func?, BuildScript> f) + private static BuildScript WithDotNet(IAutobuilder builder, Func?, BuildScript> f) { var installDir = builder.Actions.PathCombine(builder.Options.RootDirectory, ".dotnet"); var installScript = DownloadDotNet(builder, installDir); @@ -92,7 +92,7 @@ namespace Semmle.Autobuild.CSharp /// variables needed by the installed .NET Core (null when no variables /// are needed). /// - public static BuildScript WithDotNet(Autobuilder builder, Func?, BuildScript> f) + public static BuildScript WithDotNet(IAutobuilder builder, Func?, BuildScript> f) => WithDotNet(builder, (_1, env) => f(env)); /// @@ -100,7 +100,7 @@ namespace Semmle.Autobuild.CSharp /// .NET Core SDK. The SDK(s) will be installed at installDir /// (provided that the script succeeds). /// - private static BuildScript DownloadDotNet(Autobuilder builder, string installDir) + private static BuildScript DownloadDotNet(IAutobuilder builder, string installDir) { if (!string.IsNullOrEmpty(builder.Options.DotNetVersion)) // Specific version supplied in configuration: always use that @@ -137,7 +137,7 @@ namespace Semmle.Autobuild.CSharp /// /// See https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script. /// - private static BuildScript DownloadDotNetVersion(Autobuilder builder, string path, string version) + private static BuildScript DownloadDotNetVersion(IAutobuilder builder, string path, string version) { return BuildScript.Bind(GetInstalledSdksScript(builder.Actions), (sdks, sdksRet) => { @@ -233,7 +233,7 @@ namespace Semmle.Autobuild.CSharp /// /// Gets the `dotnet build` script. /// - private static BuildScript GetBuildScript(Autobuilder builder, string? dotNetPath, IDictionary? environment, string projOrSln) + private static BuildScript GetBuildScript(IAutobuilder builder, string? dotNetPath, IDictionary? environment, string projOrSln) { var build = new CommandBuilder(builder.Actions, null, environment); var script = build.RunCommand(DotNetCommand(builder.Actions, dotNetPath)). diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/Program.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp/Program.cs index 2233557af16..479625c76e3 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/Program.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/Program.cs @@ -11,7 +11,7 @@ namespace Semmle.Autobuild.CSharp try { var actions = SystemBuildActions.Instance; - var options = new AutobuildOptions(actions, Language.CSharp); + var options = new CSharpAutobuildOptions(actions); try { Console.WriteLine("CodeQL C# autobuilder"); diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/StandaloneBuildRule.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp/StandaloneBuildRule.cs index fa6523e37ae..207ecd70f0a 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/StandaloneBuildRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/StandaloneBuildRule.cs @@ -6,9 +6,9 @@ namespace Semmle.Autobuild.CSharp /// /// Build using standalone extraction. /// - internal class StandaloneBuildRule : IBuildRule + internal class StandaloneBuildRule : IBuildRule { - public BuildScript Analyse(Autobuilder builder, bool auto) + public BuildScript Analyse(IAutobuilder builder, bool auto) { BuildScript GetCommand(string? solution) { diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/AutobuildOptions.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/AutobuildOptions.cs index ed20bb929ff..d51612272d0 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/AutobuildOptions.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/AutobuildOptions.cs @@ -6,12 +6,12 @@ using System.Text.RegularExpressions; namespace Semmle.Autobuild.Shared { /// - /// Encapsulates build options. + /// Encapsulates build options shared between C# and C++. /// - public class AutobuildOptions + public abstract class AutobuildOptionsShared { - private const string lgtmPrefix = "LGTM_INDEX_"; - private const string extractorOptionPrefix = "CODEQL_EXTRACTOR_CSHARP_OPTION_"; + protected const string lgtmPrefix = "LGTM_INDEX_"; + public int SearchDepth { get; } = 3; public string RootDirectory { get; } @@ -25,16 +25,16 @@ namespace Semmle.Autobuild.Shared public string? BuildCommand { get; } public IEnumerable Solution { get; } public bool IgnoreErrors { get; } - public bool Buildless { get; } + public bool AllSolutions { get; } public bool NugetRestore { get; } - public Language Language { get; } + public abstract Language Language { get; } /// /// Reads options from environment variables. /// Throws ArgumentOutOfRangeException for invalid arguments. /// - public AutobuildOptions(IBuildActions actions, Language language) + public AutobuildOptionsShared(IBuildActions actions) { RootDirectory = actions.GetCurrentDirectory(); VsToolsVersion = actions.GetEnvironmentVariable(lgtmPrefix + "VSTOOLS_VERSION"); @@ -48,12 +48,8 @@ namespace Semmle.Autobuild.Shared Solution = actions.GetEnvironmentVariable(lgtmPrefix + "SOLUTION").AsListWithExpandedEnvVars(actions, Array.Empty()); IgnoreErrors = actions.GetEnvironmentVariable(lgtmPrefix + "IGNORE_ERRORS").AsBool("ignore_errors", false); - Buildless = actions.GetEnvironmentVariable(lgtmPrefix + "BUILDLESS").AsBool("buildless", false) || - actions.GetEnvironmentVariable(extractorOptionPrefix + "BUILDLESS").AsBool("buildless", false); AllSolutions = actions.GetEnvironmentVariable(lgtmPrefix + "ALL_SOLUTIONS").AsBool("all_solutions", false); NugetRestore = actions.GetEnvironmentVariable(lgtmPrefix + "NUGET_RESTORE").AsBool("nuget_restore", true); - - Language = language; } } diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/Autobuilder.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/Autobuilder.cs index d90175d245a..1ef5ebd815d 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/Autobuilder.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/Autobuilder.cs @@ -9,21 +9,21 @@ namespace Semmle.Autobuild.Shared /// /// A build rule analyses the files in "builder" and outputs a build script. /// - public interface IBuildRule + public interface IBuildRule where TAutobuildOptions : AutobuildOptionsShared { /// /// Analyse the files and produce a build script. /// /// The files and options relating to the build. /// Whether this build rule is being automatically applied. - BuildScript Analyse(Autobuilder builder, bool auto); + BuildScript Analyse(IAutobuilder builder, bool auto); } /// /// A delegate used to wrap a build script in an environment where an appropriate /// version of .NET Core is automatically installed. /// - public delegate BuildScript WithDotNet(Autobuilder builder, Func?, BuildScript> f); + public delegate BuildScript WithDotNet(IAutobuilder builder, Func?, BuildScript> f) where TAutobuildOptions : AutobuildOptionsShared; /// /// Exception indicating that environment variables are missing or invalid. @@ -33,6 +33,59 @@ namespace Semmle.Autobuild.Shared public InvalidEnvironmentException(string m) : base(m) { } } + public interface IAutobuilder where TAutobuildOptions : AutobuildOptionsShared + { + /// + /// Full file paths of files found in the project directory, as well as + /// their distance from the project root folder. The list is sorted + /// by distance in ascending order. + /// + IEnumerable<(string, int)> Paths { get; } + + /// + /// Gets all paths matching a particular filename, as well as + /// their distance from the project root folder. The list is sorted + /// by distance in ascending order. + /// + /// The filename to find. + /// Possibly empty sequence of paths with the given filename. + IEnumerable<(string, int)> GetFilename(string name) => + Paths.Where(p => Actions.GetFileName(p.Item1) == name); + + /// + /// List of project/solution files to build. + /// + IList ProjectsOrSolutionsToBuild { get; } + + /// + /// Gets the supplied build configuration. + /// + TAutobuildOptions Options { get; } + + /// + /// The set of build actions used during the autobuilder. + /// Could be real system operations, or a stub for testing. + /// + IBuildActions Actions { get; } + + /// + /// Log a given build event to the console. + /// + /// The format string. + /// Inserts to the format string. + void Log(Severity severity, string format, params object[] args); + + /// + /// Value of CODEQL_EXTRACTOR__ROOT environment variable. + /// + string? CodeQLExtractorLangRoot { get; } + + /// + /// Value of CODEQL_PLATFORM environment variable. + /// + string? CodeQlPlatform { get; } + } + /// /// Main application logic, containing all data /// gathered from the project and filesystem. @@ -40,7 +93,7 @@ namespace Semmle.Autobuild.Shared /// The overall design is intended to be extensible so that in theory, /// it should be possible to add new build rules without touching this code. /// - public abstract class Autobuilder + public abstract class Autobuilder : IAutobuilder where TAutobuildOptions : AutobuildOptionsShared { /// /// Full file paths of files found in the project directory, as well as @@ -60,16 +113,6 @@ namespace Semmle.Autobuild.Shared public IEnumerable<(string, int)> GetExtensions(params string[] extensions) => Paths.Where(p => extensions.Contains(Path.GetExtension(p.Item1))); - /// - /// Gets all paths matching a particular filename, as well as - /// their distance from the project root folder. The list is sorted - /// by distance in ascending order. - /// - /// The filename to find. - /// Possibly empty sequence of paths with the given filename. - public IEnumerable<(string, int)> GetFilename(string name) => - Paths.Where(p => Actions.GetFileName(p.Item1) == name); - /// /// Holds if a given path, relative to the root of the source directory /// was found. @@ -115,7 +158,7 @@ namespace Semmle.Autobuild.Shared /// /// Gets the supplied build configuration. /// - public AutobuildOptions Options { get; } + public TAutobuildOptions Options { get; } /// /// The set of build actions used during the autobuilder. @@ -123,7 +166,7 @@ namespace Semmle.Autobuild.Shared /// public IBuildActions Actions { get; } - private IEnumerable? FindFiles(string extension, Func create) + private IEnumerable? FindFiles(string extension, Func> create) { var matchingFiles = GetExtensions(extension) .Select(p => (ProjectOrSolution: create(p.Item1), DistanceFromRoot: p.Item2)) @@ -146,7 +189,7 @@ namespace Semmle.Autobuild.Shared /// solution file and tools. /// /// The command line options. - protected Autobuilder(IBuildActions actions, AutobuildOptions options) + protected Autobuilder(IBuildActions actions, TAutobuildOptions options) { Actions = actions; Options = options; @@ -167,7 +210,7 @@ namespace Semmle.Autobuild.Shared foreach (var solution in options.Solution) { if (actions.FileExists(solution)) - ret.Add(new Solution(this, solution, true)); + ret.Add(new Solution(this, solution, true)); else Log(Severity.Error, $"The specified project or solution file {solution} was not found"); } @@ -175,17 +218,17 @@ namespace Semmle.Autobuild.Shared } // First look for `.proj` files - ret = FindFiles(".proj", f => new Project(this, f))?.ToList(); + ret = FindFiles(".proj", f => new Project(this, f))?.ToList(); if (ret is not null) return ret; // Then look for `.sln` files - ret = FindFiles(".sln", f => new Solution(this, f, false))?.ToList(); + ret = FindFiles(".sln", f => new Solution(this, f, false))?.ToList(); if (ret is not null) return ret; // Finally look for language specific project files, e.g. `.csproj` files - ret = FindFiles(this.Options.Language.ProjectExtension, f => new Project(this, f))?.ToList(); + ret = FindFiles(this.Options.Language.ProjectExtension, f => new Project(this, f))?.ToList(); return ret ?? new List(); }); diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandAutoRule.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandAutoRule.cs index b6cb0737630..0d44f0dad4d 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandAutoRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandAutoRule.cs @@ -7,11 +7,11 @@ namespace Semmle.Autobuild.Shared /// /// Auto-detection of build scripts. /// - public class BuildCommandAutoRule : IBuildRule + public class BuildCommandAutoRule : IBuildRule { - private readonly WithDotNet withDotNet; + private readonly WithDotNet withDotNet; - public BuildCommandAutoRule(WithDotNet withDotNet) + public BuildCommandAutoRule(WithDotNet withDotNet) { this.withDotNet = withDotNet; } @@ -31,7 +31,7 @@ namespace Semmle.Autobuild.Shared "build" }; - public BuildScript Analyse(Autobuilder builder, bool auto) + public BuildScript Analyse(IAutobuilder builder, bool auto) { builder.Log(Severity.Info, "Attempting to locate build script"); diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandRule.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandRule.cs index 6db4cfa139d..54d406c9dac 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandRule.cs @@ -3,16 +3,16 @@ /// /// Execute the build_command rule. /// - public class BuildCommandRule : IBuildRule + public class BuildCommandRule : IBuildRule { - private readonly WithDotNet withDotNet; + private readonly WithDotNet withDotNet; - public BuildCommandRule(WithDotNet withDotNet) + public BuildCommandRule(WithDotNet withDotNet) { this.withDotNet = withDotNet; } - public BuildScript Analyse(Autobuilder builder, bool auto) + public BuildScript Analyse(IAutobuilder builder, bool auto) { if (builder.Options.BuildCommand is null) return BuildScript.Failure; diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/MsBuildRule.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/MsBuildRule.cs index 0afc1da098c..77f2f70f718 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/MsBuildRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/MsBuildRule.cs @@ -6,14 +6,14 @@ namespace Semmle.Autobuild.Shared /// /// A build rule using msbuild. /// - public class MsBuildRule : IBuildRule + public class MsBuildRule : IBuildRule { /// /// The name of the msbuild command. /// private const string msBuild = "msbuild"; - public BuildScript Analyse(Autobuilder builder, bool auto) + public BuildScript Analyse(IAutobuilder builder, bool auto) { if (!builder.ProjectsOrSolutionsToBuild.Any()) return BuildScript.Failure; @@ -27,8 +27,8 @@ namespace Semmle.Autobuild.Shared { var firstSolution = builder.ProjectsOrSolutionsToBuild.OfType().FirstOrDefault(); vsTools = firstSolution is not null - ? BuildTools.FindCompatibleVcVars(builder.Actions, firstSolution) - : BuildTools.VcVarsAllBatFiles(builder.Actions).OrderByDescending(b => b.ToolsVersion).FirstOrDefault(); + ? BuildTools.FindCompatibleVcVars(builder.Actions, firstSolution) + : BuildTools.VcVarsAllBatFiles(builder.Actions).OrderByDescending(b => b.ToolsVersion).FirstOrDefault(); } if (vsTools is null && builder.Actions.IsWindows()) @@ -123,7 +123,7 @@ namespace Semmle.Autobuild.Shared /// /// Returns null when no version is specified. /// - public static VcVarsBatFile? GetVcVarsBatFile(Autobuilder builder) + public static VcVarsBatFile? GetVcVarsBatFile(IAutobuilder builder) where TAutobuildOptions : AutobuildOptionsShared { VcVarsBatFile? vsTools = null; @@ -154,7 +154,7 @@ namespace Semmle.Autobuild.Shared /// /// Returns a script for downloading `nuget.exe` from nuget.org. /// - private static BuildScript DownloadNugetExe(Autobuilder builder, string path) => + private static BuildScript DownloadNugetExe(IAutobuilder builder, string path) where TAutobuildOptions : AutobuildOptionsShared => BuildScript.Create(_ => { builder.Log(Severity.Info, "Attempting to download nuget.exe"); diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/Project.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/Project.cs index bdc712d6623..71522859871 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/Project.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/Project.cs @@ -12,7 +12,7 @@ namespace Semmle.Autobuild.Shared /// C# project files come in 2 flavours, .Net core and msbuild, but they /// have the same file extension. /// - public class Project : ProjectOrSolution + public class Project : ProjectOrSolution where TAutobuildOptions : AutobuildOptionsShared { ///
    /// Holds if this project is for .Net core. @@ -23,13 +23,13 @@ namespace Semmle.Autobuild.Shared public Version ToolsVersion { get; private set; } - private readonly Lazy> includedProjectsLazy; + private readonly Lazy>> includedProjectsLazy; public override IEnumerable IncludedProjects => includedProjectsLazy.Value; - public Project(Autobuilder builder, string path) : base(builder, path) + public Project(Autobuilder builder, string path) : base(builder, path) { ToolsVersion = new Version(); - includedProjectsLazy = new Lazy>(() => new List()); + includedProjectsLazy = new Lazy>>(() => new List>()); if (!builder.Actions.FileExists(FullPath)) return; @@ -70,9 +70,9 @@ namespace Semmle.Autobuild.Shared } } - includedProjectsLazy = new Lazy>(() => + includedProjectsLazy = new Lazy>>(() => { - var ret = new List(); + var ret = new List>(); // The documentation on `.proj` files is very limited, but it appears that both // `` and `` is valid var mgr = new XmlNamespaceManager(projFile.NameTable); @@ -89,7 +89,7 @@ namespace Semmle.Autobuild.Shared } var includePath = builder.Actions.PathCombine(include.Value.Split('\\', StringSplitOptions.RemoveEmptyEntries)); - ret.Add(new Project(builder, builder.Actions.PathCombine(DirectoryName, includePath))); + ret.Add(new Project(builder, builder.Actions.PathCombine(DirectoryName, includePath))); } return ret; }); diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/ProjectOrSolution.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/ProjectOrSolution.cs index 5e4d6c05248..d0c9eeb9669 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/ProjectOrSolution.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/ProjectOrSolution.cs @@ -20,13 +20,13 @@ namespace Semmle.Autobuild.Shared IEnumerable IncludedProjects { get; } } - public abstract class ProjectOrSolution : IProjectOrSolution + public abstract class ProjectOrSolution : IProjectOrSolution where TAutobuildOptions : AutobuildOptionsShared { public string FullPath { get; } public string DirectoryName { get; } - protected ProjectOrSolution(Autobuilder builder, string path) + protected ProjectOrSolution(Autobuilder builder, string path) { FullPath = builder.Actions.GetFullPath(path); DirectoryName = builder.Actions.GetDirectoryName(path) ?? ""; diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/Solution.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/Solution.cs index 0ec54c1e02f..78929b3a93e 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/Solution.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/Solution.cs @@ -40,11 +40,11 @@ namespace Semmle.Autobuild.Shared /// /// A solution file on the filesystem, read using Microsoft.Build. /// - internal class Solution : ProjectOrSolution, ISolution + internal class Solution : ProjectOrSolution, ISolution where TAutobuildOptions : AutobuildOptionsShared { private readonly SolutionFile? solution; - private readonly IEnumerable includedProjects; + private readonly IEnumerable> includedProjects; public override IEnumerable IncludedProjects => includedProjects; @@ -57,7 +57,7 @@ namespace Semmle.Autobuild.Shared public string DefaultPlatformName => solution is null ? "" : solution.GetDefaultPlatformName(); - public Solution(Autobuilder builder, string path, bool allowProject) : base(builder, path) + public Solution(Autobuilder builder, string path, bool allowProject) : base(builder, path) { try { @@ -69,19 +69,19 @@ namespace Semmle.Autobuild.Shared // that scenario as a solution with just that one project if (allowProject) { - includedProjects = new[] { new Project(builder, path) }; + includedProjects = new[] { new Project(builder, path) }; return; } builder.Log(Severity.Info, $"Unable to read solution file {path}."); - includedProjects = Array.Empty(); + includedProjects = Array.Empty>(); return; } includedProjects = solution.ProjectsInOrder .Where(p => p.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat) .Select(p => builder.Actions.PathCombine(DirectoryName, builder.Actions.PathCombine(p.RelativePath.Split('\\', StringSplitOptions.RemoveEmptyEntries)))) - .Select(p => new Project(builder, p)) + .Select(p => new Project(builder, p)) .ToArray(); } From d401be18453679f98d03cdff77c50b9b4880ea07 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Wed, 23 Nov 2022 12:11:55 +0000 Subject: [PATCH 474/796] Java: Fix typo: ceritificate --- .../Security/CWE/CWE-299/DisabledRevocationChecking.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-299/DisabledRevocationChecking.ql b/java/ql/src/experimental/Security/CWE/CWE-299/DisabledRevocationChecking.ql index c3af26f8ff4..a6d2049bd16 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-299/DisabledRevocationChecking.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-299/DisabledRevocationChecking.ql @@ -1,5 +1,5 @@ /** - * @name Disabled ceritificate revocation checking + * @name Disabled certificate revocation checking * @description Using revoked certificates is dangerous. * Therefore, revocation status of certificates in a chain should be checked. * @kind path-problem From dcd082e955a225cf471f0aa90cf6de44453dbb05 Mon Sep 17 00:00:00 2001 From: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Date: Wed, 23 Nov 2022 12:48:47 +0000 Subject: [PATCH 475/796] Possible build fix, else needs new parameter --- docs/codeql/reusables/kotlin-java-differences.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/codeql/reusables/kotlin-java-differences.rst b/docs/codeql/reusables/kotlin-java-differences.rst index 2cefb35a6ea..3ab5b73e044 100644 --- a/docs/codeql/reusables/kotlin-java-differences.rst +++ b/docs/codeql/reusables/kotlin-java-differences.rst @@ -8,6 +8,7 @@ There are however some important cases where writing queries for Kotlin can prod Be careful when you model code elements that don’t exist in Java, such as ``NotNullExpr (expr!!)``, because they could interact in unexpected ways with common predicates. For example, ``MethodAccess.getQualifier()`` returns a ``NotNullExpr`` instead of a ``VarAccess`` in the following Kotlin code: .. code-block:: kotlin + someVar!!.someMethodCall() In that specific case, you can use the predicate `Expr.getUnderlyingExpr()`. This goes directly to the underlying `VarAccess`` to produce a more similar behavior to that in Java. From 876add521476ca15ee49768e144f73271f3a82c5 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 23 Nov 2022 13:56:03 +0100 Subject: [PATCH 476/796] Swift: reject uppercase acronyms in schema This was causing hardly debuggable errors because names are transformed to underscored lowercase names in the dbscheme and back to camelcase for trap emission classes, which is not a noop in case uppercase acronyms (like SIL or ABI) are in the name. This makes the error be surfaced early with a helpful message. --- swift/codegen/lib/schema/schema.py | 9 +++++++-- swift/codegen/test/test_schema.py | 11 +++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/swift/codegen/lib/schema/schema.py b/swift/codegen/lib/schema/schema.py index 94b4a2279ef..a2a1de0c05a 100644 --- a/swift/codegen/lib/schema/schema.py +++ b/swift/codegen/lib/schema/schema.py @@ -9,6 +9,7 @@ from enum import Enum, auto import functools import importlib.util from toposort import toposort_flatten +import inflection class Error(Exception): @@ -210,8 +211,12 @@ class _PropertyNamer(PropertyModifier): def _get_class(cls: type) -> Class: if not isinstance(cls, type): raise Error(f"Only class definitions allowed in schema, found {cls}") - if cls.__name__[0].islower(): - raise Error(f"Class name must be capitalized, found {cls.__name__}") + # we must check that going to dbscheme names and back is preserved + # In particular this will not happen if uppercase acronyms are included in the name + to_underscore_and_back = inflection.camelize(inflection.underscore(cls.__name__), uppercase_first_letter=True) + if cls.__name__ != to_underscore_and_back: + raise Error(f"Class name must be upper camel-case, without capitalized acronyms, found {cls.__name__} " + f"instead of {to_underscore_and_back}") if len({b._group for b in cls.__bases__ if hasattr(b, "_group")}) > 1: raise Error(f"Bases with mixed groups for {cls.__name__}") if any(getattr(b, "_null", False) for b in cls.__bases__): diff --git a/swift/codegen/test/test_schema.py b/swift/codegen/test/test_schema.py index 7ba84b4a292..0171087fafb 100644 --- a/swift/codegen/test/test_schema.py +++ b/swift/codegen/test/test_schema.py @@ -669,5 +669,16 @@ def test_null_class_cannot_be_defined_multiple_times(): pass +def test_uppercase_acronyms_are_rejected(): + with pytest.raises(schema.Error): + @schema.load + class data: + class Root: + pass + + class ROTFLNode(Root): + pass + + if __name__ == '__main__': sys.exit(pytest.main([__file__] + sys.argv[1:])) From 91198524cd9e0e43852477bf05bd78215c86490a Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Wed, 23 Nov 2022 14:37:45 +0100 Subject: [PATCH 477/796] Python: port `py/super-not-enclosing-class` --- .../ql/src/Expressions/CallToSuperWrongClass.ql | 17 +++++++---------- .../super/CallToSuperWrongClass.expected | 2 +- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/python/ql/src/Expressions/CallToSuperWrongClass.ql b/python/ql/src/Expressions/CallToSuperWrongClass.ql index 4098653d7f8..1424fa8f434 100644 --- a/python/ql/src/Expressions/CallToSuperWrongClass.ql +++ b/python/ql/src/Expressions/CallToSuperWrongClass.ql @@ -13,17 +13,14 @@ */ import python +import semmle.python.dataflow.new.DataFlow -from CallNode call_to_super, string name +from DataFlow::CallCfgNode call_to_super, string name where - exists(GlobalVariable gv, ControlFlowNode cn | - call_to_super = ClassValue::super_().getACall() and - gv.getId() = "super" and - cn = call_to_super.getArg(0) and - name = call_to_super.getScope().getScope().(Class).getName() and - exists(ClassValue other | - cn.pointsTo(other) and - not other.getScope().getName() = name - ) + call_to_super.getFunction().getALocalSource().asExpr().(Name).getId() = "super" and + name = call_to_super.getScope().getScope().(Class).getName() and + exists(DataFlow::Node arg | + arg = call_to_super.getArg(0) and + not arg.getALocalSource().asExpr().(Name).getId() = name ) select call_to_super.getNode(), "First argument to super() should be " + name + "." diff --git a/python/ql/test/query-tests/Expressions/super/CallToSuperWrongClass.expected b/python/ql/test/query-tests/Expressions/super/CallToSuperWrongClass.expected index 66508e08d70..859e4624a01 100644 --- a/python/ql/test/query-tests/Expressions/super/CallToSuperWrongClass.expected +++ b/python/ql/test/query-tests/Expressions/super/CallToSuperWrongClass.expected @@ -1 +1 @@ -| test.py:10:9:10:27 | super() | First argument to super() should be NotMyDict. | +| test.py:10:9:10:27 | ControlFlowNode for super() | First argument to super() should be NotMyDict. | From 2eb6b1adb34679be3dc4c0822ebf10460369624b Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 23 Nov 2022 14:38:12 +0100 Subject: [PATCH 478/796] JS: fix two typos --- .../security/dataflow/SecondOrderCommandInjectionQuery.qll | 2 +- .../ql/src/experimental/Security/CWE-340/TokenBuiltFromUUID.ql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionQuery.qll index eb3fac4e860..fc10cd30c71 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionQuery.qll @@ -12,7 +12,7 @@ import SecondOrderCommandInjectionCustomizations::SecondOrderCommandInjection private import semmle.javascript.security.TaintedObject /** - * A taint-tracking configuration for reasoning about command-injection vulnerabilities. + * A taint-tracking configuration for reasoning about second order command-injection vulnerabilities. */ class Configuration extends TaintTracking::Configuration { Configuration() { this = "SecondOrderCommandInjection" } diff --git a/javascript/ql/src/experimental/Security/CWE-340/TokenBuiltFromUUID.ql b/javascript/ql/src/experimental/Security/CWE-340/TokenBuiltFromUUID.ql index 4d4471e9a55..2c3b5a59eee 100644 --- a/javascript/ql/src/experimental/Security/CWE-340/TokenBuiltFromUUID.ql +++ b/javascript/ql/src/experimental/Security/CWE-340/TokenBuiltFromUUID.ql @@ -6,7 +6,7 @@ * @precision medium * @problem.severity error * @security-severity 5 - * @id py/predictable-token + * @id js/predictable-token * @tags security * external/cwe/cwe-340 */ From 5a51d718c643044e037854ea9736861748340dd9 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 23 Nov 2022 14:44:03 +0100 Subject: [PATCH 479/796] Update some comments referring to the package column --- javascript/ql/lib/semmle/javascript/frameworks/SQL.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/SQL.qll b/javascript/ql/lib/semmle/javascript/frameworks/SQL.qll index 80694f0c723..2eace281e84 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/SQL.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/SQL.qll @@ -365,7 +365,7 @@ private module Sequelize { private module SpannerCsv { class SpannerSinks extends ModelInput::SinkModelCsv { override predicate row(string row) { - // package; type; path; kind + // type; path; kind row = [ "@google-cloud/spanner.~SqlExecutorDirect;Argument[0];sql-injection", From 19b5f64a11a8fc08f1152439ed33d76e96ebb59a Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 23 Nov 2022 14:58:17 +0100 Subject: [PATCH 480/796] use `instanceof` instead of `extends` on `DataFlow::CallNode` in some case --- .../codeql/ruby/frameworks/ActiveStorage.qll | 4 +-- .../lib/codeql/ruby/frameworks/PosixSpawn.qll | 8 +++--- .../lib/codeql/ruby/frameworks/Railties.qll | 8 +++--- .../ql/lib/codeql/ruby/frameworks/core/IO.qll | 6 ++--- .../codeql/ruby/frameworks/stdlib/Open3.qll | 25 +++++++------------ 5 files changed, 22 insertions(+), 29 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveStorage.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveStorage.qll index 389ac9ee64d..4393f4c2bdb 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveStorage.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveStorage.qll @@ -168,7 +168,7 @@ module ActiveStorage { * A call on an ActiveStorage object that results in an image transformation. * Arguments to these calls may be executed as system commands. */ - private class ImageProcessingCall extends DataFlow::CallNode, SystemCommandExecution::Range { + private class ImageProcessingCall extends SystemCommandExecution::Range instanceof DataFlow::CallNode { ImageProcessingCall() { this.getReceiver() instanceof BlobInstance and this.getMethodName() = ["variant", "preview", "representation"] @@ -209,7 +209,7 @@ module ActiveStorage { this = API::getTopLevelMember("ActiveStorage").getAMethodCall("video_preview_arguments=") } - override DataFlow::Node getAnArgument() { result = this.getArgument(0) } + override DataFlow::Node getAnArgument() { result = super.getArgument(0) } } /** diff --git a/ruby/ql/lib/codeql/ruby/frameworks/PosixSpawn.qll b/ruby/ql/lib/codeql/ruby/frameworks/PosixSpawn.qll index 6c4d2ab1a47..92b6eb0fe71 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/PosixSpawn.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/PosixSpawn.qll @@ -20,7 +20,7 @@ module PosixSpawn { /** * A call to `POSIX::Spawn::Child.new` or `POSIX::Spawn::Child.build`. */ - class ChildCall extends SystemCommandExecution::Range, DataFlow::CallNode { + class ChildCall extends SystemCommandExecution::Range instanceof DataFlow::CallNode { ChildCall() { this = [ @@ -30,7 +30,7 @@ module PosixSpawn { } override DataFlow::Node getAnArgument() { - result = this.getArgument(_) and not result.asExpr() instanceof ExprNodes::PairCfgNode + result = super.getArgument(_) and not result.asExpr() instanceof ExprNodes::PairCfgNode } override predicate isShellInterpreted(DataFlow::Node arg) { none() } @@ -39,7 +39,7 @@ module PosixSpawn { /** * A call to `POSIX::Spawn.spawn` or a related method. */ - class SystemCall extends SystemCommandExecution::Range, DataFlow::CallNode { + class SystemCall extends SystemCommandExecution::Range instanceof DataFlow::CallNode { SystemCall() { this = posixSpawnModule() @@ -71,7 +71,7 @@ module PosixSpawn { } private predicate argument(DataFlow::Node arg) { - arg = this.getArgument(_) and + arg = super.getArgument(_) and not arg.asExpr() instanceof ExprNodes::HashLiteralCfgNode and not arg.asExpr() instanceof ExprNodes::ArrayLiteralCfgNode and not arg.asExpr() instanceof ExprNodes::PairCfgNode diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Railties.qll b/ruby/ql/lib/codeql/ruby/frameworks/Railties.qll index fdcd3a0e1a8..509f72cafb9 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Railties.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Railties.qll @@ -27,12 +27,12 @@ module Railties { * A call to `Rails::Generators::Actions#execute_command`. * This method concatenates its first and second arguments and executes the result as a shell command. */ - private class ExecuteCommandCall extends SystemCommandExecution::Range, DataFlow::CallNode { + private class ExecuteCommandCall extends SystemCommandExecution::Range instanceof DataFlow::CallNode { ExecuteCommandCall() { this = generatorsActionsClass().getAnInstanceSelf().getAMethodCall("execute_command") } - override DataFlow::Node getAnArgument() { result = this.getArgument([0, 1]) } + override DataFlow::Node getAnArgument() { result = super.getArgument([0, 1]) } override predicate isShellInterpreted(DataFlow::Node arg) { arg = this.getAnArgument() } } @@ -40,7 +40,7 @@ module Railties { /** * A call to a method in `Rails::Generators::Actions` which delegates to `execute_command`. */ - private class ExecuteCommandWrapperCall extends SystemCommandExecution::Range, DataFlow::CallNode { + private class ExecuteCommandWrapperCall extends SystemCommandExecution::Range instanceof DataFlow::CallNode { ExecuteCommandWrapperCall() { this = generatorsActionsClass() @@ -48,7 +48,7 @@ module Railties { .getAMethodCall(["rake", "rails_command", "git"]) } - override DataFlow::Node getAnArgument() { result = this.getArgument(0) } + override DataFlow::Node getAnArgument() { result = super.getArgument(0) } override predicate isShellInterpreted(DataFlow::Node arg) { arg = this.getAnArgument() } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/IO.qll b/ruby/ql/lib/codeql/ruby/frameworks/core/IO.qll index 0828a6dcea7..e751e882ddb 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/core/IO.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/core/IO.qll @@ -114,7 +114,7 @@ module IO { * ``` * Ruby documentation: https://docs.ruby-lang.org/en/3.1/IO.html#method-c-popen */ - class POpenCall extends SystemCommandExecution::Range, DataFlow::CallNode { + class POpenCall extends SystemCommandExecution::Range instanceof DataFlow::CallNode { POpenCall() { this = API::getTopLevelMember("IO").getAMethodCall("popen") } override DataFlow::Node getAnArgument() { this.argument(result, _) } @@ -131,7 +131,7 @@ module IO { not n instanceof ExprNodes::ArrayLiteralCfgNode and ( // IO.popen({var: "a"}, "cmd", {some: :opt}) - arg = this.getArgument([0, 1]) and + arg = super.getArgument([0, 1]) and // We over-approximate by assuming a subshell if the argument isn't an array or "-". // This increases the sensitivity of the CommandInjection query at the risk of some FPs. if n.getConstantValue().getString() = "-" then shell = false else shell = true @@ -139,7 +139,7 @@ module IO { // IO.popen([{var: "b"}, "cmd", "arg1", "arg2", {some: :opt}]) // IO.popen({var: "a"}, ["cmd", "arg1", "arg2", {some: :opt}]) shell = false and - exists(ExprNodes::ArrayLiteralCfgNode arr | this.getArgument([0, 1]).asExpr() = arr | + exists(ExprNodes::ArrayLiteralCfgNode arr | super.getArgument([0, 1]).asExpr() = arr | n = arr.getAnArgument() or // IO.popen([{var: "b"}, ["cmd", "argv0"], "arg1", "arg2", {some: :opt}]) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Open3.qll b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Open3.qll index 3272056b4f1..fb081d5113e 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Open3.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Open3.qll @@ -2,11 +2,13 @@ * Provides modeling for the `Open3` library. */ +private import ruby private import codeql.ruby.AST private import codeql.ruby.DataFlow private import codeql.ruby.ApiGraphs private import codeql.ruby.frameworks.Stdlib private import codeql.ruby.Concepts +private import codeql.ruby.frameworks.core.Kernel /** * Provides modeling for the `Open3` library. @@ -17,23 +19,19 @@ module Open3 { * These methods take the same argument forms as `Kernel.system`. * See `KernelSystemCall` for details. */ - class Open3Call extends SystemCommandExecution::Range { - MethodCall methodCall; - + class Open3Call extends SystemCommandExecution::Range instanceof DataFlow::CallNode { Open3Call() { - this.asExpr().getExpr() = methodCall and this = API::getTopLevelMember("Open3") .getAMethodCall(["popen3", "popen2", "popen2e", "capture3", "capture2", "capture2e"]) } - override DataFlow::Node getAnArgument() { - result.asExpr().getExpr() = methodCall.getAnArgument() - } + override DataFlow::Node getAnArgument() { result = super.getArgument(_) } override predicate isShellInterpreted(DataFlow::Node arg) { // These Open3 methods invoke a subshell if you provide a single string as argument - methodCall.getNumberOfArguments() = 1 and arg.asExpr().getExpr() = methodCall.getAnArgument() + super.getNumberOfArguments() = 1 and + arg = this.getAnArgument() } } @@ -47,11 +45,8 @@ module Open3 { * Open3.pipeline([{}, "cat", "foo.txt"], "tail") * Open3.pipeline([["cat", "cat"], "foo.txt"], "tail") */ - class Open3PipelineCall extends SystemCommandExecution::Range { - MethodCall methodCall; - + class Open3PipelineCall extends SystemCommandExecution::Range instanceof DataFlow::CallNode { Open3PipelineCall() { - this.asExpr().getExpr() = methodCall and this = API::getTopLevelMember("Open3") .getAMethodCall([ @@ -59,14 +54,12 @@ module Open3 { ]) } - override DataFlow::Node getAnArgument() { - result.asExpr().getExpr() = methodCall.getAnArgument() - } + override DataFlow::Node getAnArgument() { result = super.getArgument(_) } override predicate isShellInterpreted(DataFlow::Node arg) { // A command in the pipeline is executed in a subshell if it is given as a single string argument. arg.asExpr().getExpr() instanceof StringlikeLiteral and - arg.asExpr().getExpr() = methodCall.getAnArgument() + arg = this.getAnArgument() } } } From abf0c0f296b7c62d171311738b246f457c8ba983 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 23 Nov 2022 15:01:56 +0100 Subject: [PATCH 481/796] Python: update more comments referring to the package column --- python/ql/lib/semmle/python/frameworks/Asyncpg.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/Asyncpg.qll b/python/ql/lib/semmle/python/frameworks/Asyncpg.qll index 7ded3730788..259699eeb0e 100644 --- a/python/ql/lib/semmle/python/frameworks/Asyncpg.qll +++ b/python/ql/lib/semmle/python/frameworks/Asyncpg.qll @@ -13,7 +13,7 @@ private import semmle.python.frameworks.data.ModelsAsData private module Asyncpg { class AsyncpgModel extends ModelInput::TypeModelCsv { override predicate row(string row) { - // package1;type1;package2;type2;path + // type1;type2;path row = [ // a `ConnectionPool` that is created when the result of `asyncpg.create_pool()` is awaited. @@ -31,7 +31,7 @@ private module Asyncpg { } class AsyncpgSink extends ModelInput::SinkModelCsv { - // package;type;path;kind + // type;path;kind override predicate row(string row) { row = [ From 311614c5e6c250efaa165eb84fb20be665a65227 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 23 Nov 2022 14:08:15 +0100 Subject: [PATCH 482/796] C#: Remove imports of ExternalFlow.qll. --- .../semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll | 1 - csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll | 1 - csharp/ql/lib/semmle/code/csharp/frameworks/JsonNET.qll | 1 - csharp/ql/lib/semmle/code/csharp/frameworks/ServiceStack.qll | 1 - csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll | 1 - csharp/ql/lib/semmle/code/csharp/frameworks/System.qll | 1 - csharp/ql/lib/semmle/code/csharp/frameworks/system/CodeDom.qll | 1 - .../ql/lib/semmle/code/csharp/frameworks/system/Collections.qll | 1 - csharp/ql/lib/semmle/code/csharp/frameworks/system/Data.qll | 1 - .../ql/lib/semmle/code/csharp/frameworks/system/Diagnostics.qll | 1 - csharp/ql/lib/semmle/code/csharp/frameworks/system/IO.qll | 1 - csharp/ql/lib/semmle/code/csharp/frameworks/system/Linq.qll | 1 - csharp/ql/lib/semmle/code/csharp/frameworks/system/Net.qll | 1 - csharp/ql/lib/semmle/code/csharp/frameworks/system/Security.qll | 1 - csharp/ql/lib/semmle/code/csharp/frameworks/system/Text.qll | 1 - csharp/ql/lib/semmle/code/csharp/frameworks/system/Web.qll | 1 - csharp/ql/lib/semmle/code/csharp/frameworks/system/Xml.qll | 1 - .../semmle/code/csharp/frameworks/system/collections/Generic.qll | 1 - .../code/csharp/frameworks/system/collections/Specialized.qll | 1 - .../ql/lib/semmle/code/csharp/frameworks/system/data/Common.qll | 1 - .../lib/semmle/code/csharp/frameworks/system/io/Compression.qll | 1 - csharp/ql/lib/semmle/code/csharp/frameworks/system/net/Mail.qll | 1 - .../code/csharp/frameworks/system/runtime/CompilerServices.qll | 1 - .../code/csharp/frameworks/system/security/Cryptography.qll | 1 - .../frameworks/system/security/cryptography/X509Certificates.qll | 1 - .../code/csharp/frameworks/system/text/RegularExpressions.qll | 1 - .../lib/semmle/code/csharp/frameworks/system/threading/Tasks.qll | 1 - .../semmle/code/csharp/frameworks/system/web/ui/WebControls.qll | 1 - .../src/utils/model-generator/CaptureTypeBasedSummaryModels.ql | 1 - 29 files changed, 29 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll index 594cbe20865..a6142ce11ee 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll @@ -6,7 +6,6 @@ private import DataFlowPublic private import DataFlowPrivate private import FlowSummaryImpl as FlowSummaryImpl private import semmle.code.csharp.dataflow.FlowSummary as FlowSummary -private import semmle.code.csharp.dataflow.ExternalFlow private import semmle.code.csharp.dispatch.Dispatch private import semmle.code.csharp.dispatch.RuntimeCallable private import semmle.code.csharp.frameworks.system.Collections diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll index 4c4b4e7bd1d..946ba0b9e2d 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll @@ -9,7 +9,6 @@ private import semmle.code.csharp.frameworks.system.data.Entity private import semmle.code.csharp.frameworks.system.collections.Generic private import semmle.code.csharp.frameworks.Sql private import semmle.code.csharp.dataflow.FlowSummary -private import semmle.code.csharp.dataflow.ExternalFlow private import semmle.code.csharp.dataflow.internal.DataFlowPrivate as DataFlowPrivate /** diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/JsonNET.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/JsonNET.qll index 73a506bc555..bbadee3d5c9 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/JsonNET.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/JsonNET.qll @@ -3,7 +3,6 @@ */ import csharp -private import semmle.code.csharp.dataflow.ExternalFlow /** Definitions relating to the `Json.NET` package. */ module JsonNET { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/ServiceStack.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/ServiceStack.qll index ba3248fea95..27021573f38 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/ServiceStack.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/ServiceStack.qll @@ -6,7 +6,6 @@ */ import csharp -private import semmle.code.csharp.dataflow.ExternalFlow /** A class representing a Service */ private class ServiceClass extends Class { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll index 258b7b3f794..3d643934b5f 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll @@ -7,7 +7,6 @@ private import semmle.code.csharp.frameworks.EntityFramework private import semmle.code.csharp.frameworks.NHibernate private import semmle.code.csharp.frameworks.Dapper private import semmle.code.csharp.dataflow.DataFlow4 -private import semmle.code.csharp.dataflow.ExternalFlow /** An expression containing a SQL command. */ abstract class SqlExpr extends Expr { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/System.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/System.qll index bf291f90879..479b78b0567 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/System.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/System.qll @@ -2,7 +2,6 @@ import csharp private import system.Reflection -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System` namespace. */ class SystemNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/CodeDom.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/CodeDom.qll index b7edb8e18dc..400e9954866 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/CodeDom.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/CodeDom.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.System -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.CodeDome` namespace. */ class SystemCodeDomNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Collections.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Collections.qll index 227fe34e3ca..1a35b7a807d 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Collections.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Collections.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.System -private import semmle.code.csharp.dataflow.ExternalFlow private import semmle.code.csharp.dataflow.FlowSummary /** The `System.Collections` namespace. */ diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Data.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Data.qll index a95ae099295..f0e9fe29e96 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Data.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Data.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.System -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Data` namespace. */ class SystemDataNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Diagnostics.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Diagnostics.qll index 0b85d2ac24a..81a620c9e7c 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Diagnostics.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Diagnostics.qll @@ -2,7 +2,6 @@ import semmle.code.csharp.Type private import semmle.code.csharp.frameworks.System -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Diagnostics` namespace. */ class SystemDiagnosticsNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/IO.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/IO.qll index 5ceb73d4b64..9756bf9c982 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/IO.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/IO.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.System -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.IO` namespace. */ class SystemIONamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Linq.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Linq.qll index 31b23334eaf..49076215471 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Linq.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Linq.qll @@ -4,7 +4,6 @@ private import csharp as CSharp private import semmle.code.csharp.frameworks.System as System -private import semmle.code.csharp.dataflow.ExternalFlow as ExternalFlow /** Definitions relating to the `System.Linq` namespace. */ module SystemLinq { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Net.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Net.qll index 1fbc46dbc9c..7c0aee741db 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Net.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Net.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.System -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Net` namespace. */ class SystemNetNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Security.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Security.qll index f8501eb82e9..02325e19383 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Security.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Security.qll @@ -1,7 +1,6 @@ /** Provides classes related to the namespace `System.Security`. */ import csharp -private import semmle.code.csharp.dataflow.ExternalFlow private import semmle.code.csharp.frameworks.System /** The `System.Security` namespace. */ diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Text.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Text.qll index c81b28e29fe..fb4c37489af 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Text.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Text.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.System -private import semmle.code.csharp.dataflow.ExternalFlow private import semmle.code.csharp.dataflow.FlowSummary /** The `System.Text` namespace. */ diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Web.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Web.qll index 6680e22b796..8552c028c89 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Web.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Web.qll @@ -3,7 +3,6 @@ import csharp private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.frameworks.system.collections.Specialized -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Web` namespace. */ class SystemWebNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Xml.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Xml.qll index d6fd132ee6b..df6827660a0 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Xml.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Xml.qll @@ -3,7 +3,6 @@ import csharp private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.dataflow.DataFlow3 -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Xml` namespace. */ class SystemXmlNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Generic.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Generic.qll index a7ab58da4f1..260fe6d0318 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Generic.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Generic.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.system.Collections -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Collections.Generic` namespace. */ class SystemCollectionsGenericNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Specialized.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Specialized.qll index 4ffb7b5aa0c..2ddac761c4b 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Specialized.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Specialized.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.system.Collections -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Collections.Specialized` namespace. */ class SystemCollectionsSpecializedNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/Common.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/Common.qll index 06a98d59f49..22c80fd4de6 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/Common.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/Common.qll @@ -4,7 +4,6 @@ private import csharp as CSharp private import semmle.code.csharp.frameworks.system.Data as Data -private import semmle.code.csharp.dataflow.ExternalFlow as ExternalFlow /** Definitions relating to the `System.Data.Common` namespace. */ module SystemDataCommon { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/io/Compression.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/io/Compression.qll index d5c58f13128..b1b777b0f69 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/io/Compression.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/io/Compression.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.system.IO -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.IO.Compression` namespace. */ class SystemIOCompressionNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/net/Mail.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/net/Mail.qll index 104ea2424dd..631a09058a3 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/net/Mail.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/net/Mail.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.system.Net -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Net.Mail` namespace. */ class SystemNetMailNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/runtime/CompilerServices.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/runtime/CompilerServices.qll index e4426a81d14..9ae5ec90b24 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/runtime/CompilerServices.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/runtime/CompilerServices.qll @@ -3,7 +3,6 @@ import csharp private import semmle.code.csharp.frameworks.system.Runtime private import semmle.code.csharp.dataflow.internal.DataFlowPrivate -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Runtime.CompilerServices` namespace. */ class SystemRuntimeCompilerServicesNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/Cryptography.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/Cryptography.qll index f922fb00669..40c07eef121 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/Cryptography.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/Cryptography.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.system.Security -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Security.Cryptography` namespace. */ class SystemSecurityCryptographyNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/cryptography/X509Certificates.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/cryptography/X509Certificates.qll index 0bd6461a6cd..54cc8d11864 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/cryptography/X509Certificates.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/cryptography/X509Certificates.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.system.security.Cryptography -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Security.Cryptography.X509Certificates` namespace. */ class SystemSecurityCryptographyX509CertificatesNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/text/RegularExpressions.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/text/RegularExpressions.qll index 6319ef6e894..531fa6ef721 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/text/RegularExpressions.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/text/RegularExpressions.qll @@ -4,7 +4,6 @@ import default import semmle.code.csharp.frameworks.system.Text -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Text.RegularExpressions` namespace. */ class SystemTextRegularExpressionsNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/threading/Tasks.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/threading/Tasks.qll index 7c0f1d2a885..acfc4edddd7 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/threading/Tasks.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/threading/Tasks.qll @@ -3,7 +3,6 @@ import csharp private import semmle.code.csharp.frameworks.system.Threading private import semmle.code.csharp.dataflow.internal.DataFlowPrivate -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Threading.Tasks` namespace. */ class SystemThreadingTasksNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/web/ui/WebControls.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/web/ui/WebControls.qll index 09d5e08d371..a059d5b3c7c 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/web/ui/WebControls.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/web/ui/WebControls.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.system.web.UI -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Web.UI.WebControls` namespace. */ class SystemWebUIWebControlsNamespace extends Namespace { diff --git a/csharp/ql/src/utils/model-generator/CaptureTypeBasedSummaryModels.ql b/csharp/ql/src/utils/model-generator/CaptureTypeBasedSummaryModels.ql index 7cd23988321..f15a786f53f 100644 --- a/csharp/ql/src/utils/model-generator/CaptureTypeBasedSummaryModels.ql +++ b/csharp/ql/src/utils/model-generator/CaptureTypeBasedSummaryModels.ql @@ -6,7 +6,6 @@ * @tags model-generator */ -import semmle.code.csharp.dataflow.ExternalFlow import utils.modelgenerator.internal.CaptureTypeBasedSummaryModels from TypeBasedFlowTargetApi api, string flow From 33216f3867c74f0d7f444dfd7b30b60ed2ffb658 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 23 Nov 2022 15:22:19 +0100 Subject: [PATCH 483/796] cleanup imports --- ruby/ql/lib/codeql/ruby/frameworks/stdlib/Open3.qll | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Open3.qll b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Open3.qll index fb081d5113e..e65f3005503 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Open3.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Open3.qll @@ -3,12 +3,8 @@ */ private import ruby -private import codeql.ruby.AST -private import codeql.ruby.DataFlow private import codeql.ruby.ApiGraphs -private import codeql.ruby.frameworks.Stdlib private import codeql.ruby.Concepts -private import codeql.ruby.frameworks.core.Kernel /** * Provides modeling for the `Open3` library. @@ -58,7 +54,7 @@ module Open3 { override predicate isShellInterpreted(DataFlow::Node arg) { // A command in the pipeline is executed in a subshell if it is given as a single string argument. - arg.asExpr().getExpr() instanceof StringlikeLiteral and + arg.asExpr().getExpr() instanceof Ast::StringlikeLiteral and arg = this.getAnArgument() } } From ef837f72e47b0a13a643c19a76a9498c369df843 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 23 Nov 2022 14:57:08 +0000 Subject: [PATCH 484/796] Swift: Test .expected changes resulting from merge. --- .../Security/CWE-094/UnsafeJsEval.expected | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected index 4e04cad1468..6f146b41df8 100644 --- a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected +++ b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected @@ -1,9 +1,11 @@ edges | UnsafeJsEval.swift:124:21:124:42 | string : | UnsafeJsEval.swift:124:70:124:70 | string : | +| UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | | UnsafeJsEval.swift:165:10:165:37 | try ... : | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | | UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:165:10:165:37 | try ... : | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | UnsafeJsEval.swift:205:7:205:7 | remoteString : | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | +| UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | UnsafeJsEval.swift:211:24:211:37 | .utf8 : | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | | UnsafeJsEval.swift:204:7:204:66 | try! ... : | UnsafeJsEval.swift:265:13:265:13 | string : | | UnsafeJsEval.swift:204:7:204:66 | try! ... : | UnsafeJsEval.swift:268:13:268:13 | string : | @@ -24,6 +26,10 @@ edges | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:279:13:279:13 | string : | | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:285:13:285:13 | string : | | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:299:13:299:13 | string : | +| UnsafeJsEval.swift:211:19:211:41 | call to init(_:) : | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | +| UnsafeJsEval.swift:211:24:211:37 | .utf8 : | UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in init(_:) : | +| UnsafeJsEval.swift:211:24:211:37 | .utf8 : | UnsafeJsEval.swift:211:19:211:41 | call to init(_:) : | +| UnsafeJsEval.swift:211:24:211:37 | .utf8 : | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:265:13:265:13 | string : | | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:268:13:268:13 | string : | | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:276:13:276:13 | string : | @@ -53,6 +59,7 @@ edges nodes | UnsafeJsEval.swift:124:21:124:42 | string : | semmle.label | string : | | UnsafeJsEval.swift:124:70:124:70 | string : | semmle.label | string : | +| UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in init(_:) : | semmle.label | [summary param] 0 in init(_:) : | | UnsafeJsEval.swift:165:10:165:37 | try ... : | semmle.label | try ... : | | UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | semmle.label | call to init(contentsOf:) : | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | semmle.label | call to getRemoteData() : | @@ -60,6 +67,8 @@ nodes | UnsafeJsEval.swift:204:12:204:66 | call to init(contentsOf:) : | semmle.label | call to init(contentsOf:) : | | UnsafeJsEval.swift:205:7:205:7 | remoteString : | semmle.label | remoteString : | | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | semmle.label | ... .+(_:_:) ... : | +| UnsafeJsEval.swift:211:19:211:41 | call to init(_:) : | semmle.label | call to init(_:) : | +| UnsafeJsEval.swift:211:24:211:37 | .utf8 : | semmle.label | .utf8 : | | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | semmle.label | call to init(decoding:as:) : | | UnsafeJsEval.swift:265:13:265:13 | string : | semmle.label | string : | | UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | semmle.label | call to init(source:injectionTime:forMainFrameOnly:) | @@ -81,7 +90,9 @@ nodes | UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) : | semmle.label | call to JSStringRetain(_:) : | | UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) : | semmle.label | call to JSStringCreateWithUTF8CString(_:) : | | UnsafeJsEval.swift:305:17:305:17 | jsstr | semmle.label | jsstr | +| file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | semmle.label | [summary] to write: return (return) in init(_:) : | subpaths +| UnsafeJsEval.swift:211:24:211:37 | .utf8 : | UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | UnsafeJsEval.swift:211:19:211:41 | call to init(_:) : | | UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) : | UnsafeJsEval.swift:124:21:124:42 | string : | UnsafeJsEval.swift:124:70:124:70 | string : | UnsafeJsEval.swift:287:16:287:98 | call to JSStringRetain(_:) : | | UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) : | UnsafeJsEval.swift:124:21:124:42 | string : | UnsafeJsEval.swift:124:70:124:70 | string : | UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) : | #select From 3c3442d8f0327673024fd3c5c4449d23637f0310 Mon Sep 17 00:00:00 2001 From: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Date: Wed, 23 Nov 2022 15:09:58 +0000 Subject: [PATCH 485/796] Update docs/codeql/reusables/kotlin-java-differences.rst Co-authored-by: Felicity Chapman --- docs/codeql/reusables/kotlin-java-differences.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/reusables/kotlin-java-differences.rst b/docs/codeql/reusables/kotlin-java-differences.rst index 3ab5b73e044..2523a7e8bda 100644 --- a/docs/codeql/reusables/kotlin-java-differences.rst +++ b/docs/codeql/reusables/kotlin-java-differences.rst @@ -1,7 +1,7 @@ Writing CodeQL queries for Kotlin versus Java analysis ------------------------------------------------------ -Generally you use the same classes to write queries for Kotlin and for Java. You use the same libraries such as DataFlow, TaintTracking, or SSA, and the same classes such as `MethodAccess` or `Class` for both languages. When you want to access Kotlin-specific elements (such as a ``WhenExpr``) you’ll need to use Kotlin-specific CodeQL classes. +Generally you use the same classes to write queries for Kotlin and for Java. You use the same libraries such as DataFlow, TaintTracking, or SSA, and the same classes such as ``MethodAccess`` or ``Class`` for both languages. When you want to access Kotlin-specific elements (such as a ``WhenExpr``) you’ll need to use Kotlin-specific CodeQL classes. There are however some important cases where writing queries for Kotlin can produce surprising results compared to writing queries for Java, as CodeQL works with the JVM bytecode representation of the Kotlin source code. From 72999c7af123a3df7c2aacba01b2ab566626e302 Mon Sep 17 00:00:00 2001 From: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Date: Wed, 23 Nov 2022 15:10:14 +0000 Subject: [PATCH 486/796] Update docs/codeql/reusables/kotlin-java-differences.rst Co-authored-by: Felicity Chapman --- docs/codeql/reusables/kotlin-java-differences.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/reusables/kotlin-java-differences.rst b/docs/codeql/reusables/kotlin-java-differences.rst index 2523a7e8bda..16fdc129d75 100644 --- a/docs/codeql/reusables/kotlin-java-differences.rst +++ b/docs/codeql/reusables/kotlin-java-differences.rst @@ -11,7 +11,7 @@ Be careful when you model code elements that don’t exist in Java, such as ``No someVar!!.someMethodCall() -In that specific case, you can use the predicate `Expr.getUnderlyingExpr()`. This goes directly to the underlying `VarAccess`` to produce a more similar behavior to that in Java. +In that specific case, you can use the predicate ``Expr.getUnderlyingExpr()``. This goes directly to the underlying ``VarAccess`` to produce a more similar behavior to that in Java. Nullable elements (`?`) can also produce unexpected behavior. To avoid a `NullPointerException`, Kotlin may inline calls like `expr.toString()` to `String.valueOf(expr)` when `expr` is nullable. Make sure that you write CodeQL around the extracted code, and do not directly modify the source code in the codebase. From f9215ec5ca4765d64df13ff56892825f0aff4db3 Mon Sep 17 00:00:00 2001 From: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Date: Wed, 23 Nov 2022 15:10:24 +0000 Subject: [PATCH 487/796] Update docs/codeql/reusables/kotlin-java-differences.rst Co-authored-by: Felicity Chapman --- docs/codeql/reusables/kotlin-java-differences.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/codeql/reusables/kotlin-java-differences.rst b/docs/codeql/reusables/kotlin-java-differences.rst index 16fdc129d75..b2b74d2d41a 100644 --- a/docs/codeql/reusables/kotlin-java-differences.rst +++ b/docs/codeql/reusables/kotlin-java-differences.rst @@ -13,8 +13,8 @@ Be careful when you model code elements that don’t exist in Java, such as ``No In that specific case, you can use the predicate ``Expr.getUnderlyingExpr()``. This goes directly to the underlying ``VarAccess`` to produce a more similar behavior to that in Java. -Nullable elements (`?`) can also produce unexpected behavior. To avoid a `NullPointerException`, Kotlin may inline calls like `expr.toString()` to `String.valueOf(expr)` when `expr` is nullable. Make sure that you write CodeQL around the extracted code, and do not directly modify the source code in the codebase. +Nullable elements (``?``) can also produce unexpected behavior. To avoid a ``NullPointerException``, Kotlin may inline calls like ``expr.toString()`` to ``String.valueOf(expr)`` when ``expr`` is nullable. Make sure that you write CodeQL around the extracted code, and do not directly modify the source code in the codebase. -Another example is that if-else expressions are translated into `WhenExprs` in CodeQL, instead of the more typical `IfStmt` in Java. +Another example is that if-else expressions in Kotlin are translated into ``WhenExprs`` in CodeQL, instead of the more typical ``IfStmt`` seen in Java. In general, you can debug these issues with the AST (you can use the ``CodeQL: View AST`` command from Visual Studio Code’s CodeQL extension, or run the ``PrintAst.ql`` query) and see exactly what CodeQL is extracting from your code. \ No newline at end of file From ee0811df268254af508a1d152090f0dcfc3fd2ae Mon Sep 17 00:00:00 2001 From: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Date: Wed, 23 Nov 2022 15:13:40 +0000 Subject: [PATCH 488/796] Update docs/codeql/codeql-language-guides/codeql-for-java.rst --- docs/codeql/codeql-language-guides/codeql-for-java.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/codeql-for-java.rst b/docs/codeql/codeql-language-guides/codeql-for-java.rst index 536dfbc294e..a27328b052c 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-java.rst @@ -7,7 +7,6 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat .. include:: ../reusables/kotlin-beta-note.rst -.. include:: ../reusables/kotlin-java-differences.rst .. pull-quote:: Enabling Kotlin support From 9ee36215bd95510d8c50064746788f164ed916e5 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Wed, 23 Nov 2022 15:14:46 +0000 Subject: [PATCH 489/796] Java: Fix basic query in docs --- .../basic-query-for-java-code.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst b/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst index bc721ce9371..0545efa738c 100644 --- a/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst +++ b/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst @@ -37,7 +37,7 @@ Running the query import java - from IfStmt ifstmt, Block block + from IfStmt ifstmt, BlockStmt block where ifstmt.getThen() = block and block.getNumStmt() = 0 select ifstmt, "This 'if' statement is redundant." @@ -59,7 +59,7 @@ Running the query The query will take a few moments to return results. When the query completes, the results are displayed below the project name. The query results are listed in two columns, corresponding to the two expressions in the ``select`` clause of the query. The first column corresponds to the expression ``ifstmt`` and is linked to the location in the source code of the project where ``ifstmt`` occurs. The second column is the alert message. - ➤ `Example query results `__ + ➤ `Example query results `__ .. pull-quote:: @@ -81,10 +81,10 @@ After the initial ``import`` statement, this simple query comprises three parts +===============================================================+===================================================================================================================+========================================================================================================================+ | ``import java`` | Imports the standard CodeQL libraries for Java. | Every query begins with one or more ``import`` statements. | +---------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+ -| ``from IfStmt ifstmt, Block block`` | Defines the variables for the query. | We use: | +| ``from IfStmt ifstmt, BlockStmt block`` | Defines the variables for the query. | We use: | | | Declarations are of the form: | | | | `` `` | - an ``IfStmt`` variable for ``if`` statements | -| | | - a ``Block`` variable for the then block | +| | | - a ``BlockStmt`` variable for the ``then`` block | +---------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+ | ``where ifstmt.getThen() = block and block.getNumStmt() = 0`` | Defines a condition on the variables. | ``ifstmt.getThen() = block`` relates the two variables. The block must be the ``then`` branch of the ``if`` statement. | | | | | @@ -138,7 +138,7 @@ To exclude ``if`` statements that have an ``else`` branch: There are now fewer results because ``if`` statements with an ``else`` branch are no longer included. -➤ `See this in the query console `__ +➤ `See this in the query console `__ Further reading --------------- From 950c4c811c4fac720d4716d4610a9506bd540f0d Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Wed, 23 Nov 2022 15:15:28 +0000 Subject: [PATCH 490/796] Java/Kotlin: Make the basic query in docs work for both languages --- .../basic-query-for-java-code.rst | 110 ++++++++++-------- 1 file changed, 62 insertions(+), 48 deletions(-) diff --git a/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst b/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst index 0545efa738c..23d655b791b 100644 --- a/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst +++ b/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst @@ -1,18 +1,33 @@ .. _basic-query-for-java-code: -Basic query for Java code -========================= +Basic query for Java and Kotlin code +==================================== Learn to write and run a simple CodeQL query using LGTM. About the query --------------- -The query we're going to run performs a basic search of the code for ``if`` statements that are redundant, in the sense that they have an empty then branch. For example, code such as: +The query we're going to run searches for inefficient tests for empty strings. For example, Java code such as: .. code-block:: java - if (error) { } + public class TestJava { + void myJavaFun(String s) { + boolean b = s.equals(""); + } + } + +or Kotlin code such as: + +.. code-block:: kotlin + + void myKotlinFun(s: String) { + var b = s.equals("") + } + +In either case, replacing ``s.equals("")`` with ``s.isEmpty()`` +would be more efficient. Running the query ----------------- @@ -37,10 +52,13 @@ Running the query import java - from IfStmt ifstmt, BlockStmt block - where ifstmt.getThen() = block and - block.getNumStmt() = 0 - select ifstmt, "This 'if' statement is redundant." + from MethodAccess ma + where + ma.getMethod().hasName("equals") and + ma.getArgument(0).(StringLiteral).getValue() = "" + select ma, "This comparison to empty string is inefficient, use isEmpty() instead." + + Note that CodeQL treats Java and Kotlin as part of the same language, so even though this query starts with ``import java``, it will work for both Java and Kotlin code. LGTM checks whether your query compiles and, if all is well, the **Run** button changes to green to indicate that you can go ahead and run the query. @@ -57,9 +75,9 @@ Running the query Your query is always run against the most recently analyzed commit to the selected project. - The query will take a few moments to return results. When the query completes, the results are displayed below the project name. The query results are listed in two columns, corresponding to the two expressions in the ``select`` clause of the query. The first column corresponds to the expression ``ifstmt`` and is linked to the location in the source code of the project where ``ifstmt`` occurs. The second column is the alert message. + The query will take a few moments to return results. When the query completes, the results are displayed below the project name. The query results are listed in two columns, corresponding to the two expressions in the ``select`` clause of the query. The first column corresponds to the expression ``ma`` and is linked to the location in the source code of the project where ``ma`` occurs. The second column is the alert message. - ➤ `Example query results `__ + ➤ `Example query results `__ .. pull-quote:: @@ -67,34 +85,33 @@ Running the query An ellipsis (…) at the bottom of the table indicates that the entire list is not displayed—click it to show more results. -#. If any matching code is found, click a link in the ``ifstmt`` column to view the ``if`` statement in the code viewer. +#. If any matching code is found, click a link in the ``ma`` column to view the ``.equals`` expression in the code viewer. - The matching ``if`` statement is highlighted with a yellow background in the code viewer. If any code in the file also matches a query from the standard query library for that language, you will see a red alert message at the appropriate point within the code. + The matching ``.equals`` expression is highlighted with a yellow background in the code viewer. If any code in the file also matches a query from the standard query library for that language, you will see a red alert message at the appropriate point within the code. About the query structure ~~~~~~~~~~~~~~~~~~~~~~~~~ After the initial ``import`` statement, this simple query comprises three parts that serve similar purposes to the FROM, WHERE, and SELECT parts of an SQL query. -+---------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+ -| Query part | Purpose | Details | -+===============================================================+===================================================================================================================+========================================================================================================================+ -| ``import java`` | Imports the standard CodeQL libraries for Java. | Every query begins with one or more ``import`` statements. | -+---------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+ -| ``from IfStmt ifstmt, BlockStmt block`` | Defines the variables for the query. | We use: | -| | Declarations are of the form: | | -| | `` `` | - an ``IfStmt`` variable for ``if`` statements | -| | | - a ``BlockStmt`` variable for the ``then`` block | -+---------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+ -| ``where ifstmt.getThen() = block and block.getNumStmt() = 0`` | Defines a condition on the variables. | ``ifstmt.getThen() = block`` relates the two variables. The block must be the ``then`` branch of the ``if`` statement. | -| | | | -| | | ``block.getNumStmt() = 0`` states that the block must be empty (that is, it contains no statements). | -+---------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+ -| ``select ifstmt, "This 'if' statement is redundant."`` | Defines what to report for each match. | Reports the resulting ``if`` statement with a string that explains the problem. | -| | | | -| | ``select`` statements for queries that are used to find instances of poor coding practice are always in the form: | | -| | ``select , ""`` | | -+---------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+ ++--------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+ +| Query part | Purpose | Details | ++==================================================================================================+===================================================================================================================+===================================================================================================+ +| ``import java`` | Imports the standard CodeQL libraries for Java. | Every query begins with one or more ``import`` statements. | ++--------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+ +| ``from MethodAccess ma`` | Defines the variables for the query. | We use: | +| | Declarations are of the form: | | +| | `` `` | - a ``MethodAccess`` variable for call expressions | ++--------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+ +| ``where ma.getMethod().hasName("equals") and ma.getArgument(0).(StringLiteral).getValue() = ""`` | Defines a condition on the variables. | ``ma.getMethod().hasName("equals")`` restricts ``ma`` to only calls to methods call ``equals``. | +| | | | +| | | ``ma.getArgument(0).(StringLiteral).getValue() = ""`` says the argument must be literal ``""``. | ++--------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+ +| ``select ma, "This comparison to empty string is inefficient, use isEmpty() instead."`` | Defines what to report for each match. | Reports the resulting ``.equals`` expression with a string that explains the problem. | +| | | | +| | ``select`` statements for queries that are used to find instances of poor coding practice are always in the form: | | +| | ``select , ""`` | | ++--------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+ Extend the query ---------------- @@ -104,41 +121,38 @@ Query writing is an inherently iterative process. You write a simple query and t Remove false positive results ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Browsing the results of our basic query shows that it could be improved. Among the results you are likely to find examples of ``if`` statements with an ``else`` branch, where an empty ``then`` branch does serve a purpose. For example: +Browsing the results of our basic query shows that it could be improved. For example, you may find results for code like: .. code-block:: java - if (...) { - ... - } else if ("-verbose".equals(option)) { - // nothing to do - handled earlier - } else { - error("unrecognized option"); - } + public class TestJava { + void myJavaFun(Object o) { + boolean b = o.equals(""); + } + } -In this case, identifying the ``if`` statement with the empty ``then`` branch as redundant is a false positive. One solution to this is to modify the query to ignore empty ``then`` branches if the ``if`` statement has an ``else`` branch. - -To exclude ``if`` statements that have an ``else`` branch: +In this case, it is not possible to simply use ``o.isEmpty()`` instead, as ``o`` has type ``Object`` rather than ``String``. One solution to this is to modify the query to only return results where the expression being tested has type ``String``: #. Extend the where clause to include the following extra condition: .. code-block:: ql - and not exists(ifstmt.getElse()) + ma.getQualifier().getType() instanceof TypeString The ``where`` clause is now: .. code-block:: ql - where ifstmt.getThen() = block and - block.getNumStmt() = 0 and - not exists(ifstmt.getElse()) + where + ma.getQualifier().getType() instanceof TypeString and + ma.getMethod().hasName("equals") and + ma.getArgument(0).(StringLiteral).getValue() = "" #. Click **Run**. - There are now fewer results because ``if`` statements with an ``else`` branch are no longer included. + There are now fewer results because ``.equals`` expressions with different types are no longer included. -➤ `See this in the query console `__ +➤ `See this in the query console `__ Further reading --------------- From 582cfb93304783fa472e69cd56cf420ec1e50bc3 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 23 Nov 2022 16:20:36 +0100 Subject: [PATCH 491/796] C#: Remove the frameworks module in ExternalFlow as MaD models are no longer inlined in the code. --- .../code/csharp/dataflow/ExternalFlow.qll | 37 ------------------- 1 file changed, 37 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index 874bd51a9f3..f72fa288919 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -90,43 +90,6 @@ private import internal.FlowSummaryImpl::Public private import internal.FlowSummaryImpl::Private::External private import internal.FlowSummaryImplSpecific -/** - * A module importing the frameworks that provide external flow data, - * ensuring that they are visible to the taint tracking / data flow library. - */ -private module Frameworks { - private import semmle.code.csharp.frameworks.EntityFramework - private import semmle.code.csharp.frameworks.JsonNET - private import semmle.code.csharp.frameworks.ServiceStack - private import semmle.code.csharp.frameworks.Sql - private import semmle.code.csharp.frameworks.System - private import semmle.code.csharp.frameworks.system.CodeDom - private import semmle.code.csharp.frameworks.system.Collections - private import semmle.code.csharp.frameworks.system.collections.Generic - private import semmle.code.csharp.frameworks.system.collections.Specialized - private import semmle.code.csharp.frameworks.system.Data - private import semmle.code.csharp.frameworks.system.data.Common - private import semmle.code.csharp.frameworks.system.Diagnostics - private import semmle.code.csharp.frameworks.system.Linq - private import semmle.code.csharp.frameworks.system.Net - private import semmle.code.csharp.frameworks.system.net.Mail - private import semmle.code.csharp.frameworks.system.IO - private import semmle.code.csharp.frameworks.system.io.Compression - private import semmle.code.csharp.frameworks.system.runtime.CompilerServices - private import semmle.code.csharp.frameworks.system.Security - private import semmle.code.csharp.frameworks.system.security.Cryptography - private import semmle.code.csharp.frameworks.system.security.cryptography.X509Certificates - private import semmle.code.csharp.frameworks.system.Text - private import semmle.code.csharp.frameworks.system.text.RegularExpressions - private import semmle.code.csharp.frameworks.system.threading.Tasks - private import semmle.code.csharp.frameworks.system.Web - private import semmle.code.csharp.frameworks.system.web.ui.WebControls - private import semmle.code.csharp.frameworks.system.Xml - private import semmle.code.csharp.security.dataflow.flowsinks.Html - private import semmle.code.csharp.security.dataflow.flowsources.Local - private import semmle.code.csharp.security.dataflow.XSSSinks -} - /** * DEPRECATED: Define source models as data extensions instead. * From 277b5b483d7fcea8bbfd0b49300745a265c872a8 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Wed, 23 Nov 2022 15:51:40 +0000 Subject: [PATCH 492/796] Java/Kotlin docs: Tweak text --- .../codeql/codeql-language-guides/basic-query-for-java-code.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst b/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst index 23d655b791b..90954ad0e2c 100644 --- a/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst +++ b/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst @@ -97,7 +97,7 @@ After the initial ``import`` statement, this simple query comprises three parts +--------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+ | Query part | Purpose | Details | +==================================================================================================+===================================================================================================================+===================================================================================================+ -| ``import java`` | Imports the standard CodeQL libraries for Java. | Every query begins with one or more ``import`` statements. | +| ``import java`` | Imports the standard CodeQL libraries for Java and Kotlin. | Every query begins with one or more ``import`` statements. | +--------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+ | ``from MethodAccess ma`` | Defines the variables for the query. | We use: | | | Declarations are of the form: | | From 2684b3f396ffd83859a69df955f7a02cb9656f7b Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 23 Nov 2022 16:59:40 +0100 Subject: [PATCH 493/796] C#: Make bi-directional import of Servicestack remote flow source definitions. --- .../code/csharp/security/dataflow/flowsources/Remote.qll | 7 +++++++ 1 file changed, 7 insertions(+) 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 293d15b7461..a71edbc0681 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 @@ -19,6 +19,13 @@ abstract class RemoteFlowSource extends DataFlow::Node { abstract string getSourceType(); } +/** + * A module for importing frameworks that defines remote flow sources. + */ +private module RemoteFlowSources { + private import semmle.code.csharp.frameworks.ServiceStack +} + /** A data flow source of remote user input (ASP.NET). */ abstract class AspNetRemoteFlowSource extends RemoteFlowSource { } From 357c823b92b9f2dc7d2f16db1f523c1f269bdd53 Mon Sep 17 00:00:00 2001 From: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Date: Wed, 23 Nov 2022 16:59:52 +0000 Subject: [PATCH 494/796] Changes after feedback --- docs/codeql/codeql-language-guides/codeql-for-java.rst | 2 +- docs/codeql/reusables/kotlin-java-differences.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/codeql/codeql-language-guides/codeql-for-java.rst b/docs/codeql/codeql-language-guides/codeql-for-java.rst index a27328b052c..392ef19c8b2 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-java.rst @@ -10,7 +10,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat .. pull-quote:: Enabling Kotlin support - To enable Kotlin support, you should enable ``java`` as a language. + CodeQL treats Java and Kotlin as parts of the same language, so to enable Kotlin support you should enable ``java`` as a language. .. toctree:: :hidden: diff --git a/docs/codeql/reusables/kotlin-java-differences.rst b/docs/codeql/reusables/kotlin-java-differences.rst index b2b74d2d41a..07cb95203c2 100644 --- a/docs/codeql/reusables/kotlin-java-differences.rst +++ b/docs/codeql/reusables/kotlin-java-differences.rst @@ -13,7 +13,7 @@ Be careful when you model code elements that don’t exist in Java, such as ``No In that specific case, you can use the predicate ``Expr.getUnderlyingExpr()``. This goes directly to the underlying ``VarAccess`` to produce a more similar behavior to that in Java. -Nullable elements (``?``) can also produce unexpected behavior. To avoid a ``NullPointerException``, Kotlin may inline calls like ``expr.toString()`` to ``String.valueOf(expr)`` when ``expr`` is nullable. Make sure that you write CodeQL around the extracted code, and do not directly modify the source code in the codebase. +Nullable elements (`?`) can also produce unexpected behavior. To avoid a `NullPointerException`, Kotlin may inline calls like `expr.toString()` to `String.valueOf(expr)` when `expr` is nullable. Make sure that you write CodeQL around the extracted code, which may not exactly match the code as written in the codebase. Another example is that if-else expressions in Kotlin are translated into ``WhenExprs`` in CodeQL, instead of the more typical ``IfStmt`` seen in Java. From 03b8e649f1528905ed1709ce4581e9368337cccf Mon Sep 17 00:00:00 2001 From: tiferet Date: Wed, 23 Nov 2022 10:46:27 -0800 Subject: [PATCH 495/796] Filter endpoints by confidence Select endpoints to score at inference time base purely on their confidence level, and not on whether they fit the historical definition of endpoint filters. --- .../adaptivethreatmodeling/ATMConfig.qll | 21 +++++++++++-------- .../EndpointCharacteristics.qll | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index bce5a3172d6..8eceff9e362 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -80,15 +80,18 @@ abstract class AtmConfig extends string { // characteristics that are specific to this sink type. // TODO: Experiment with excluding all endpoints that have a medium- or high-confidence characteristic that implies // they're not sinks for this sink type (or not sinks for any sink type), not just the EndpointFilterCharacteristics. - exists(EndpointCharacteristics::StandardEndpointFilterCharacteristic standardFilter | - standardFilter.getEndpoints(candidateSink) and - result = standardFilter - ) - or - exists(EndpointCharacteristics::EndpointFilterCharacteristic specificFilter | - specificFilter.getEndpoints(candidateSink) and - specificFilter.getImplications(this.getASinkEndpointType(), false, _) and - result = specificFilter + exists(EndpointCharacteristics::EndpointCharacteristic filter, float confidence | + filter.getEndpoints(candidateSink) and + confidence >= filter.mediumConfidence() and + confidence < filter.highConfidence() and + ( + // Exclude endpoints that have a characteristic that implies they're not sinks for _any_ sink type. + filter.getImplications(any(NegativeType negative), true, confidence) + or + // Exclude endpoints that have a characteristic that implies they're not sinks for _this particular_ sink type. + filter.getImplications(this.getASinkEndpointType(), false, confidence) + ) and + result = filter ) } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index 1b305fa0b11..7bd615df139 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -462,7 +462,7 @@ abstract class EndpointFilterCharacteristic extends EndpointCharacteristic { * An EndpointFilterCharacteristic that indicates that an endpoint is unlikely to be a sink of any type. * Replaces https://github.com/github/codeql/blob/387e57546bf7352f7c1cfe781daa1a3799b7063e/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll#LL15C24-L15C24 */ -abstract class StandardEndpointFilterCharacteristic extends EndpointFilterCharacteristic { +abstract private class StandardEndpointFilterCharacteristic extends EndpointFilterCharacteristic { bindingset[this] StandardEndpointFilterCharacteristic() { any() } From 5b8b9044a527bd9f11eece8713aae15743a2d6b4 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Wed, 23 Nov 2022 18:47:53 +0000 Subject: [PATCH 496/796] Kotlin: Remove an unused argument --- java/kotlin-extractor/src/main/kotlin/LinesOfCode.kt | 2 +- .../src/main/kotlin/comments/CommentExtractor.kt | 2 +- .../src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt | 4 +--- .../src/main/kotlin/utils/versions/v_1_5_20/Psi2Ir.kt | 5 ++--- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/LinesOfCode.kt b/java/kotlin-extractor/src/main/kotlin/LinesOfCode.kt index 45e23498e9d..27b62c86109 100644 --- a/java/kotlin-extractor/src/main/kotlin/LinesOfCode.kt +++ b/java/kotlin-extractor/src/main/kotlin/LinesOfCode.kt @@ -16,7 +16,7 @@ class LinesOfCode( val tw: FileTrapWriter, val file: IrFile ) { - val psi2Ir = getPsi2Ir(logger).also { + val psi2Ir = getPsi2Ir().also { if (it == null) { logger.warn("Lines of code will not be populated as Kotlin version is too old (${KotlinCompilerVersion.getVersion()})") } diff --git a/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt b/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt index 310eb3e18b0..ad4aaf60936 100644 --- a/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt @@ -25,7 +25,7 @@ class CommentExtractor(private val fileExtractor: KotlinFileExtractor, private v private val logger = fileExtractor.logger fun extract() { - val psi2Ir = getPsi2Ir(logger) + val psi2Ir = getPsi2Ir() if (psi2Ir == null) { logger.warn("Comments will not be extracted as Kotlin version is too old (${KotlinCompilerVersion.getVersion()})") return diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt index 2990acfc98f..80120107478 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt @@ -1,5 +1,3 @@ package com.github.codeql.utils.versions -import com.github.codeql.FileLogger - -fun getPsi2Ir(@Suppress("UNUSED_PARAMETER") logger: FileLogger): Psi2IrFacade? = null +fun getPsi2Ir(): Psi2IrFacade? = null diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_20/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_20/Psi2Ir.kt index 024710bc4b8..73987106c55 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_20/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_20/Psi2Ir.kt @@ -1,6 +1,5 @@ package com.github.codeql.utils.versions -import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager import org.jetbrains.kotlin.backend.jvm.ir.getKtFile @@ -8,9 +7,9 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -fun getPsi2Ir(logger: FileLogger): Psi2IrFacade? = Psi2Ir(logger) +fun getPsi2Ir(): Psi2IrFacade? = Psi2Ir() -private class Psi2Ir(private val logger: FileLogger): Psi2IrFacade { +private class Psi2Ir(): Psi2IrFacade { override fun getKtFile(irFile: IrFile): KtFile? { return irFile.getKtFile() } From 95f35196e4d7c6f1e080edb40fa7f05cb58aebc9 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 23 Nov 2022 20:45:51 +0100 Subject: [PATCH 497/796] add missing additional keywords --- .../semmle/code/java/regex/RegexTreeView.qll | 16 ++++++++-------- python/ql/lib/semmle/python/RegexTreeView.qll | 12 ++++++------ .../lib/codeql/ruby/regexp/RegExpTreeView.qll | 18 +++++++++--------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll b/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll index 2eecff1e627..1b01be0377b 100644 --- a/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll +++ b/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll @@ -615,7 +615,7 @@ module Impl implements RegexTreeViewSig { * \p{Digit} * \p{IsLowerCase} */ - class RegExpNamedProperty extends RegExpCharacterClassEscape { + additional class RegExpNamedProperty extends RegExpCharacterClassEscape { boolean inverted; string name; @@ -745,7 +745,7 @@ module Impl implements RegexTreeViewSig { * \t * ``` */ - class RegExpNormalChar extends RegExpTerm, TRegExpNormalChar { + additional class RegExpNormalChar extends RegExpTerm, TRegExpNormalChar { RegExpNormalChar() { this = TRegExpNormalChar(re, start, end) } /** @@ -770,7 +770,7 @@ module Impl implements RegexTreeViewSig { * \Qabc\E * ``` */ - class RegExpQuote extends RegExpTerm, TRegExpQuote { + additional class RegExpQuote extends RegExpTerm, TRegExpQuote { string value; RegExpQuote() { @@ -880,7 +880,7 @@ module Impl implements RegexTreeViewSig { * . * ``` */ - class RegExpSpecialChar extends RegExpTerm, TRegExpSpecialChar { + additional class RegExpSpecialChar extends RegExpTerm, TRegExpSpecialChar { string char; RegExpSpecialChar() { @@ -956,7 +956,7 @@ module Impl implements RegexTreeViewSig { * (?=\w) * ``` */ - class RegExpZeroWidthMatch extends RegExpGroup { + additional class RegExpZeroWidthMatch extends RegExpGroup { RegExpZeroWidthMatch() { re.zeroWidthMatch(start, end) } override RegExpTerm getChild(int i) { none() } @@ -1023,7 +1023,7 @@ module Impl implements RegexTreeViewSig { * (?!\n) * ``` */ - class RegExpNegativeLookahead extends RegExpLookahead { + additional class RegExpNegativeLookahead extends RegExpLookahead { RegExpNegativeLookahead() { re.negativeLookaheadAssertionGroup(start, end) } override string getPrimaryQLClass() { result = "RegExpNegativeLookahead" } @@ -1065,7 +1065,7 @@ module Impl implements RegexTreeViewSig { * (? Date: Mon, 21 Nov 2022 17:26:16 +0000 Subject: [PATCH 498/796] Kotlin build system: Refactor jar-finder We were globbing with a * in the filename, but that is not necessary. --- java/kotlin-extractor/build.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/java/kotlin-extractor/build.py b/java/kotlin-extractor/build.py index 05cb1204d86..f31484bdec3 100755 --- a/java/kotlin-extractor/build.py +++ b/java/kotlin-extractor/build.py @@ -147,18 +147,17 @@ def get_gradle_lib_folder(): return gradle_home + '/lib' -def find_jar(path, pattern): - result = glob.glob(path + '/' + pattern + '*.jar') - if len(result) == 0: - raise Exception('Cannot find jar file %s under path %s' % - (pattern, path)) - return result +def find_jar(path, base): + fn = path + '/' + base + '.jar' + if not os.path.isfile(fn): + raise Exception('Cannot find jar file at %s' % fn) + return fn -def patterns_to_classpath(path, patterns): +def bases_to_classpath(path, bases): result = [] - for pattern in patterns: - result += find_jar(path, pattern) + for base in bases: + result.append(find_jar(path, base)) return os.path.pathsep.join(result) @@ -174,8 +173,8 @@ def transform_to_embeddable(srcs): def compile(jars, java_jars, dependency_folder, transform_to_embeddable, output, build_dir, current_version): - classpath = patterns_to_classpath(dependency_folder, jars) - java_classpath = patterns_to_classpath(dependency_folder, java_jars) + classpath = bases_to_classpath(dependency_folder, jars) + java_classpath = bases_to_classpath(dependency_folder, java_jars) tmp_src_dir = build_dir + '/temp_src' From 57f689401efbda3ec02b9d9487467fe4b820d042 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Thu, 24 Nov 2022 17:33:57 +1300 Subject: [PATCH 499/796] Ruby: SplatExprCfgNode extends UnaryOperationCfgNode --- ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll b/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll index 5007acf4e31..c8ca8ff12e6 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll @@ -900,20 +900,17 @@ module ExprNodes { final override RelationalOperation getExpr() { result = super.getExpr() } } - private class SplatExprChildMapping extends ExprChildMapping, SplatExpr { + private class SplatExprChildMapping extends OperationExprChildMapping, SplatExpr { override predicate relevantChild(AstNode n) { n = this.getOperand() } } /** A control-flow node that wraps a `SplatExpr` AST expression. */ - class SplatExprCfgNode extends ExprCfgNode { + class SplatExprCfgNode extends UnaryOperationCfgNode { override string getAPrimaryQlClass() { result = "SplatExprCfgNode" } override SplatExprChildMapping e; final override SplatExpr getExpr() { result = super.getExpr() } - - /** Gets the operand of this splat expression. */ - final ExprCfgNode getOperand() { e.hasCfgChild(e.getOperand(), this, result) } } /** A control-flow node that wraps an `ElementReference` AST expression. */ From 4e4ee32dbcfbf65cc298bdf2184e91cc56579f52 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 24 Nov 2022 10:48:29 +0100 Subject: [PATCH 500/796] Data flow: Join on one more column in `flowThroughIntoCall` --- .../codeql/ruby/dataflow/internal/DataFlowImpl.qll | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index a52ad110662..bfdb6c9c9a3 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -1502,10 +1502,13 @@ private module MkStage { private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p.asNode(), pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** From 2ac06b8db941f978e323bc1dafe48aecce43d2e4 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Thu, 24 Nov 2022 10:50:39 +0100 Subject: [PATCH 501/796] Turns out lambda flow is already supported --- .../swift/frameworks/StandardLibrary/NSData.qll | 3 +-- .../test/library-tests/dataflow/taint/Taint.expected | 12 ++++++++++++ .../dataflow/taint/TaintInline.expected | 1 + .../test/library-tests/dataflow/taint/nsdata.swift | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/NSData.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/NSData.qll index 4fd8cba33fc..bad20ece437 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/NSData.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/NSData.qll @@ -45,8 +45,7 @@ private class NsDataSummaries extends SummaryModelCsv { ";NSData;true;base64EncodedString(options:);;;Argument[-1];ReturnValue;taint", ";NSData;true;base64Encoding();;;Argument[-1];ReturnValue;taint", ";NSData;true;dataWithContentsOfMappedFile(_:);;;Argument[0];ReturnValue;taint", - // TODO: Needs block flow - // ";NSData;true;enumerateBytes(_:);;;Argument[-1];Argument[0].Parameter[0];taint" + ";NSData;true;enumerateBytes(_:);;;Argument[-1];Argument[0].Parameter[0];taint", ";NSData;true;getBytes(_:);;;Argument[-1];Argument[0];taint", ";NSData;true;getBytes(_:length:);;;Argument[-1];Argument[0];taint", ";NSData;true;getBytes(_:range:);;;Argument[-1];Argument[0];taint", diff --git a/swift/ql/test/library-tests/dataflow/taint/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/Taint.expected index 16e2f0bec8d..38c3a209deb 100644 --- a/swift/ql/test/library-tests/dataflow/taint/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/Taint.expected @@ -1,4 +1,5 @@ edges +| file://:0:0:0:0 | [summary] to write: argument 0.parameter 0 in enumerateBytes(_:) : | nsdata.swift:110:9:110:9 | bytes : | | file://:0:0:0:0 | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : | url.swift:120:61:120:61 | data : | | nsdata.swift:22:9:22:9 | self : | file://:0:0:0:0 | .bytes : | | nsdata.swift:23:9:23:9 | self : | file://:0:0:0:0 | .description : | @@ -19,6 +20,7 @@ edges | nsdata.swift:38:5:38:96 | [summary param] this in base64EncodedString(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedString(options:) : | | nsdata.swift:39:5:39:49 | [summary param] this in base64Encoding() : | file://:0:0:0:0 | [summary] to write: return (return) in base64Encoding() : | | nsdata.swift:40:5:40:82 | [summary param] 0 in dataWithContentsOfMappedFile(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in dataWithContentsOfMappedFile(_:) : | +| nsdata.swift:41:5:41:104 | [summary param] this in enumerateBytes(_:) : | file://:0:0:0:0 | [summary] to write: argument 0.parameter 0 in enumerateBytes(_:) : | | nsdata.swift:42:5:42:55 | [summary param] this in getBytes(_:) : | file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:) : | | nsdata.swift:43:5:43:68 | [summary param] this in getBytes(_:length:) : | file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:length:) : | | nsdata.swift:44:5:44:71 | [summary param] this in getBytes(_:range:) : | file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:range:) : | @@ -82,6 +84,9 @@ edges | nsdata.swift:106:15:106:70 | call to dataWithContentsOfMappedFile(_:) : | nsdata.swift:106:15:106:71 | ...! | | nsdata.swift:106:51:106:58 | call to source() : | nsdata.swift:40:5:40:82 | [summary param] 0 in dataWithContentsOfMappedFile(_:) : | | nsdata.swift:106:51:106:58 | call to source() : | nsdata.swift:106:15:106:70 | call to dataWithContentsOfMappedFile(_:) : | +| nsdata.swift:108:27:108:34 | call to source() : | nsdata.swift:109:5:109:5 | nsDataTainted17 : | +| nsdata.swift:109:5:109:5 | nsDataTainted17 : | nsdata.swift:41:5:41:104 | [summary param] this in enumerateBytes(_:) : | +| nsdata.swift:110:9:110:9 | bytes : | nsdata.swift:110:45:110:45 | bytes | | nsdata.swift:113:27:113:34 | call to source() : | nsdata.swift:115:5:115:5 | nsDataTainted18 : | | nsdata.swift:115:5:115:5 | nsDataTainted18 : | nsdata.swift:42:5:42:55 | [summary param] this in getBytes(_:) : | | nsdata.swift:115:5:115:5 | nsDataTainted18 : | nsdata.swift:115:30:115:30 | [post] bufferTainted18 : | @@ -382,6 +387,7 @@ nodes | file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:) : | semmle.label | [summary] to write: argument 0 in getBytes(_:) : | | file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:length:) : | semmle.label | [summary] to write: argument 0 in getBytes(_:length:) : | | file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:range:) : | semmle.label | [summary] to write: argument 0 in getBytes(_:range:) : | +| file://:0:0:0:0 | [summary] to write: argument 0.parameter 0 in enumerateBytes(_:) : | semmle.label | [summary] to write: argument 0.parameter 0 in enumerateBytes(_:) : | | file://:0:0:0:0 | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : | semmle.label | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : | | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | semmle.label | [summary] to write: argument this in append(_:) : | | file://:0:0:0:0 | [summary] to write: argument this in append(_:length:) : | semmle.label | [summary] to write: argument this in append(_:length:) : | @@ -459,6 +465,7 @@ nodes | nsdata.swift:38:5:38:96 | [summary param] this in base64EncodedString(options:) : | semmle.label | [summary param] this in base64EncodedString(options:) : | | nsdata.swift:39:5:39:49 | [summary param] this in base64Encoding() : | semmle.label | [summary param] this in base64Encoding() : | | nsdata.swift:40:5:40:82 | [summary param] 0 in dataWithContentsOfMappedFile(_:) : | semmle.label | [summary param] 0 in dataWithContentsOfMappedFile(_:) : | +| nsdata.swift:41:5:41:104 | [summary param] this in enumerateBytes(_:) : | semmle.label | [summary param] this in enumerateBytes(_:) : | | nsdata.swift:42:5:42:55 | [summary param] this in getBytes(_:) : | semmle.label | [summary param] this in getBytes(_:) : | | nsdata.swift:43:5:43:68 | [summary param] this in getBytes(_:length:) : | semmle.label | [summary param] this in getBytes(_:length:) : | | nsdata.swift:44:5:44:71 | [summary param] this in getBytes(_:range:) : | semmle.label | [summary param] this in getBytes(_:range:) : | @@ -520,6 +527,10 @@ nodes | nsdata.swift:106:15:106:70 | call to dataWithContentsOfMappedFile(_:) : | semmle.label | call to dataWithContentsOfMappedFile(_:) : | | nsdata.swift:106:15:106:71 | ...! | semmle.label | ...! | | nsdata.swift:106:51:106:58 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:108:27:108:34 | call to source() : | semmle.label | call to source() : | +| nsdata.swift:109:5:109:5 | nsDataTainted17 : | semmle.label | nsDataTainted17 : | +| nsdata.swift:110:9:110:9 | bytes : | semmle.label | bytes : | +| nsdata.swift:110:45:110:45 | bytes | semmle.label | bytes | | nsdata.swift:113:27:113:34 | call to source() : | semmle.label | call to source() : | | nsdata.swift:115:5:115:5 | nsDataTainted18 : | semmle.label | nsDataTainted18 : | | nsdata.swift:115:30:115:30 | [post] bufferTainted18 : | semmle.label | [post] bufferTainted18 : | @@ -873,6 +884,7 @@ subpaths | nsdata.swift:101:15:101:62 | call to base64EncodedString(options:) | nsdata.swift:99:27:99:34 | call to source() : | nsdata.swift:101:15:101:62 | call to base64EncodedString(options:) | result | | nsdata.swift:104:15:104:46 | call to base64Encoding() | nsdata.swift:103:27:103:34 | call to source() : | nsdata.swift:104:15:104:46 | call to base64Encoding() | result | | nsdata.swift:106:15:106:71 | ...! | nsdata.swift:106:51:106:58 | call to source() : | nsdata.swift:106:15:106:71 | ...! | result | +| nsdata.swift:110:45:110:45 | bytes | nsdata.swift:108:27:108:34 | call to source() : | nsdata.swift:110:45:110:45 | bytes | result | | nsdata.swift:116:15:116:15 | bufferTainted18 | nsdata.swift:113:27:113:34 | call to source() : | nsdata.swift:116:15:116:15 | bufferTainted18 | result | | nsdata.swift:121:15:121:15 | bufferTainted19 | nsdata.swift:118:27:118:34 | call to source() : | nsdata.swift:121:15:121:15 | bufferTainted19 | result | | nsdata.swift:126:15:126:15 | bufferTainted20 | nsdata.swift:123:27:123:34 | call to source() : | nsdata.swift:126:15:126:15 | bufferTainted20 | result | diff --git a/swift/ql/test/library-tests/dataflow/taint/TaintInline.expected b/swift/ql/test/library-tests/dataflow/taint/TaintInline.expected index e69de29bb2d..24bd1bc7451 100644 --- a/swift/ql/test/library-tests/dataflow/taint/TaintInline.expected +++ b/swift/ql/test/library-tests/dataflow/taint/TaintInline.expected @@ -0,0 +1 @@ +| nsdata.swift:110:45:110:45 | bytes | Unexpected result: tainted=108 | diff --git a/swift/ql/test/library-tests/dataflow/taint/nsdata.swift b/swift/ql/test/library-tests/dataflow/taint/nsdata.swift index f6d82ede499..e737bb108d9 100644 --- a/swift/ql/test/library-tests/dataflow/taint/nsdata.swift +++ b/swift/ql/test/library-tests/dataflow/taint/nsdata.swift @@ -107,7 +107,7 @@ func test() { // ";NSData;true;enumerateBytes(_:);;;Argument[-1];Argument[0].Parameter[0];taint" let nsDataTainted17 = source() as! NSData nsDataTainted17.enumerateBytes { - bytes, byteRange, stop in sink(arg: bytes) // $ MISSING: tainted=108 + bytes, byteRange, stop in sink(arg: bytes) // tainted=108 } // ";NSData;true;getBytes(_:);;;Argument[-1];Argument[0];taint", let nsDataTainted18 = source() as! NSData From c9a600d4960ac561e8b976cab6d36be56f7c55a3 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 24 Nov 2022 10:29:20 +0100 Subject: [PATCH 502/796] Ruby: cache the compiled extractor, because that's way smaller than the cargo cache --- .github/workflows/ruby-build.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index cbe7f32fb17..f561af9c13b 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -48,7 +48,19 @@ jobs: run: | brew install gnu-tar echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH + - name: Cache entire extractor + uses: actions/cache@v3 + id: cache-extractor + with: + path: | + ruby/target/release/ruby-autobuilder + ruby/target/release/ruby-autobuilder.exe + ruby/target/release/ruby-extractor + ruby/target/release/ruby-extractor.exe + ruby/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll + key: ${{ runner.os }}-ruby-extractor-${{ hashFiles('ruby/rust-toolchain.toml', 'ruby/**/Cargo.lock') }}--${{ hashFiles('ruby/**/*.rs') }} - uses: actions/cache@v3 + if: steps.cache-extractor.outputs.cache-hit != 'true' with: path: | ~/.cargo/registry @@ -56,15 +68,19 @@ jobs: ruby/target key: ${{ runner.os }}-ruby-rust-cargo-${{ hashFiles('ruby/rust-toolchain.toml', 'ruby/**/Cargo.lock') }} - name: Check formatting + if: steps.cache-extractor.outputs.cache-hit != 'true' run: cargo fmt --all -- --check - name: Build + if: steps.cache-extractor.outputs.cache-hit != 'true' run: cargo build --verbose - name: Run tests + if: steps.cache-extractor.outputs.cache-hit != 'true' run: cargo test --verbose - name: Release build + if: steps.cache-extractor.outputs.cache-hit != 'true' run: cargo build --release - name: Generate dbscheme - if: ${{ matrix.os == 'ubuntu-latest' }} + if: ${{ matrix.os == 'ubuntu-latest' && steps.cache-extractor.outputs.cache-hit != 'true'}} run: target/release/ruby-generator --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll - uses: actions/upload-artifact@v3 if: ${{ matrix.os == 'ubuntu-latest' }} From 443d0f50c1354951c46ef5cfb1cba70150d3e682 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Thu, 24 Nov 2022 11:10:07 +0100 Subject: [PATCH 503/796] Apply suggestions from code review --- .../Security/CWE/CWE-089/MyBatisCommonLib.qll | 2 +- .../CWE-089/src/main/MybatisSqlInjection.java | 12 ++++++------ .../CWE-089/src/main/MybatisSqlInjectionService.java | 8 ++++---- .../CWE-089/src/main/SqlInjectionMapper.java | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll b/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll index 8399efcc229..4d3d77d8b65 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll @@ -135,7 +135,7 @@ predicate isMybatisXmlOrAnnotationSqlInjection( "%}") and annotation.getType() instanceof TypeParam and ma.getAnArgument() = node.asExpr() and - annotation.getTarget() = ma.getMethod().getParameter(node.asExpr().getIndex()) + annotation.getTarget() = ma.getMethod().getParameter(node.asExpr().(Argument).getParameterPos()) ) or // MyBatis default parameter sql injection vulnerabilities.the default parameter form of the method is arg[0...n] or param[1...n]. diff --git a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjection.java b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjection.java index 5aa6876e00c..a751d2ebb1c 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjection.java +++ b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjection.java @@ -90,13 +90,13 @@ public class MybatisSqlInjection { mybatisSqlInjectionService.badInsert(name); } - @GetMapping(value = "kkbad1") - public void kkbad1(@RequestParam String name, @RequestParam Integer age) { - mybatisSqlInjectionService.kkbad1(name, age); + @GetMapping(value = "good2") + public void good2(@RequestParam String name, @RequestParam Integer age) { + mybatisSqlInjectionService.good2(name, age); } - @GetMapping(value = "kkbad2") - public void kkbad2(@RequestParam String age) { - mybatisSqlInjectionService.kkbad2(age); + @GetMapping(value = "good3") + public void good3(@RequestParam String age) { + mybatisSqlInjectionService.good3(age); } } diff --git a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjectionService.java b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjectionService.java index 28b9bebc1f4..c8e1ce9c3cb 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjectionService.java +++ b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjectionService.java @@ -73,11 +73,11 @@ public class MybatisSqlInjectionService { sqlInjectionMapper.badInsert(input); } - public void kkbad1(String name, Integer age){ - sqlInjectionMapper.kkbad1(name, age); + public void good2(String name, Integer age){ + sqlInjectionMapper.good2(name, age); } - public void kkbad2(String age){ - sqlInjectionMapper.kkbad2(age); + public void good3(String age){ + sqlInjectionMapper.good3(age); } } diff --git a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.java b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.java index 50801558eb8..a39b26a3aea 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.java +++ b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.java @@ -61,9 +61,9 @@ public interface SqlInjectionMapper { void badInsert(String input); @Select("select * from user_info where name = #{name} and age = ${age}") - String kkbad1(@Param("name") String name, Integer age); + String good2(@Param("name") String name, Integer age); @Select("select * from user_info where age = #{age}") - String kkbad2(@Param("age") String age); + String good3(@Param("age") String age); } From 42259ef8d1ad5f5e2ee663d65384f6430b96d24e Mon Sep 17 00:00:00 2001 From: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Date: Thu, 24 Nov 2022 10:10:42 +0000 Subject: [PATCH 504/796] Update docs/codeql/reusables/kotlin-java-differences.rst --- docs/codeql/reusables/kotlin-java-differences.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/reusables/kotlin-java-differences.rst b/docs/codeql/reusables/kotlin-java-differences.rst index 07cb95203c2..40e18b60484 100644 --- a/docs/codeql/reusables/kotlin-java-differences.rst +++ b/docs/codeql/reusables/kotlin-java-differences.rst @@ -13,7 +13,7 @@ Be careful when you model code elements that don’t exist in Java, such as ``No In that specific case, you can use the predicate ``Expr.getUnderlyingExpr()``. This goes directly to the underlying ``VarAccess`` to produce a more similar behavior to that in Java. -Nullable elements (`?`) can also produce unexpected behavior. To avoid a `NullPointerException`, Kotlin may inline calls like `expr.toString()` to `String.valueOf(expr)` when `expr` is nullable. Make sure that you write CodeQL around the extracted code, which may not exactly match the code as written in the codebase. +Nullable elements (``?``) can also produce unexpected behavior. To avoid a ``NullPointerException``, Kotlin may inline calls like ``expr.toString()`` to ``String.valueOf(expr)`` when ``expr`` is nullable. Make sure that you write CodeQL around the extracted code, which may not exactly match the code as written in the codebase. Another example is that if-else expressions in Kotlin are translated into ``WhenExprs`` in CodeQL, instead of the more typical ``IfStmt`` seen in Java. From 17218fa663373a2d327309204e765d2e10cd1f0a Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Thu, 24 Nov 2022 11:14:16 +0100 Subject: [PATCH 505/796] Formatting --- .../src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll b/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll index 4d3d77d8b65..0d13340b55d 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll @@ -135,7 +135,8 @@ predicate isMybatisXmlOrAnnotationSqlInjection( "%}") and annotation.getType() instanceof TypeParam and ma.getAnArgument() = node.asExpr() and - annotation.getTarget() = ma.getMethod().getParameter(node.asExpr().(Argument).getParameterPos()) + annotation.getTarget() = + ma.getMethod().getParameter(node.asExpr().(Argument).getParameterPos()) ) or // MyBatis default parameter sql injection vulnerabilities.the default parameter form of the method is arg[0...n] or param[1...n]. From 4f8ef13cd8014a1203ec15b9a924f03977b89253 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Thu, 24 Nov 2022 12:13:46 +0100 Subject: [PATCH 506/796] Fix expectation in NSData tests --- swift/ql/test/library-tests/dataflow/taint/TaintInline.expected | 1 - swift/ql/test/library-tests/dataflow/taint/nsdata.swift | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/swift/ql/test/library-tests/dataflow/taint/TaintInline.expected b/swift/ql/test/library-tests/dataflow/taint/TaintInline.expected index 24bd1bc7451..e69de29bb2d 100644 --- a/swift/ql/test/library-tests/dataflow/taint/TaintInline.expected +++ b/swift/ql/test/library-tests/dataflow/taint/TaintInline.expected @@ -1 +0,0 @@ -| nsdata.swift:110:45:110:45 | bytes | Unexpected result: tainted=108 | diff --git a/swift/ql/test/library-tests/dataflow/taint/nsdata.swift b/swift/ql/test/library-tests/dataflow/taint/nsdata.swift index e737bb108d9..f49dce6679a 100644 --- a/swift/ql/test/library-tests/dataflow/taint/nsdata.swift +++ b/swift/ql/test/library-tests/dataflow/taint/nsdata.swift @@ -107,7 +107,7 @@ func test() { // ";NSData;true;enumerateBytes(_:);;;Argument[-1];Argument[0].Parameter[0];taint" let nsDataTainted17 = source() as! NSData nsDataTainted17.enumerateBytes { - bytes, byteRange, stop in sink(arg: bytes) // tainted=108 + bytes, byteRange, stop in sink(arg: bytes) // $ tainted=108 } // ";NSData;true;getBytes(_:);;;Argument[-1];Argument[0];taint", let nsDataTainted18 = source() as! NSData From c6835cd2704cdaa0b4b30e2c6b3c44d28b720daf Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 24 Nov 2022 11:16:56 +0000 Subject: [PATCH 507/796] Swift: Update .generated.list. --- swift/ql/.generated.list | 1 - 1 file changed, 1 deletion(-) diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index fd75bc1ade4..a62640aace8 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -184,7 +184,6 @@ ql/lib/codeql/swift/elements/expr/OverloadedDeclRefExprConstructor.qll 2cf79b483 ql/lib/codeql/swift/elements/expr/ParenExprConstructor.qll 6baaa592db57870f5ecd9be632bd3f653c44d72581efd41e8a837916e1590f9e 6f28988d04b2cb69ddcb63fba9ae3166b527803a61c250f97e48ff39a28379f6 ql/lib/codeql/swift/elements/expr/PointerToPointerExpr.qll 921645a373443d050dbc29b9f6bc4a734163c75aeffce453a4f8334b34077d30 54089de77845f6b0e623c537bc25a010ecf1b5c7630b1b4060d2b378abc07f4e ql/lib/codeql/swift/elements/expr/PointerToPointerExprConstructor.qll 95cc8003b9a3b2101afb8f110ec4cbd29e380fc048ee080f5047bcf0e14a06c7 114d487a1bb2cd33b27a9c3a47ad1d7254766e169512642f8b09b9c32cf3dc86 -ql/lib/codeql/swift/elements/expr/PostfixUnaryExpr.qll a67abdf379f04f1aeee0795cd3ebeb28ed8dfe0efad15b128d44cc9e30b32cbd cbb2b2d54c8e316dc71388ea4ff6bb5d0a6204b4e9d9ce2888e1877a54e85e8f ql/lib/codeql/swift/elements/expr/PostfixUnaryExprConstructor.qll c26326e2703b9a8b077ea9f132ae86a76b4010a108b8dcde29864f4206096231 70e45fbe365b63226d0132158cdd453e2e00d740a31c1fb0f7bfb3b2dedfd928 ql/lib/codeql/swift/elements/expr/PrefixUnaryExprConstructor.qll 6d4c915baf460691cc22681154b1129852c26f1bd9fe3e27b4e162f819d934f5 7971698433bc03dbff2fec34426a96a969fab1a5a575aaf91f10044819e16f6d ql/lib/codeql/swift/elements/expr/PropertyWrapperValuePlaceholderExpr.qll 35a61a7f68e71165690127b445fff39780028cb6be5e7b5eadaafa8aeb6b2321 f9e32f65e6d453d3fa857a4d3ca19700be1f8ea2f3d13534656bc21a2fc5f0b0 From 4bbc1dc7346507147e77eee576f458c6e8ca29bd Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Thu, 24 Nov 2022 12:34:48 +0100 Subject: [PATCH 508/796] Update test expectations --- .../MyBatisAnnotationSqlInjection.expected | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MyBatisAnnotationSqlInjection.expected b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MyBatisAnnotationSqlInjection.expected index 481c8307ac3..1aedc93eb9a 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MyBatisAnnotationSqlInjection.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MyBatisAnnotationSqlInjection.expected @@ -1,30 +1,30 @@ edges | MybatisSqlInjection.java:62:19:62:43 | name : String | MybatisSqlInjection.java:63:35:63:38 | name : String | | MybatisSqlInjection.java:63:35:63:38 | name : String | MybatisSqlInjectionService.java:48:19:48:29 | name : String | -| MybatisSqlInjection.java:94:21:94:45 | name : String | MybatisSqlInjection.java:95:37:95:40 | name : String | -| MybatisSqlInjection.java:95:37:95:40 | name : String | MybatisSqlInjectionService.java:76:21:76:31 | name : String | -| MybatisSqlInjection.java:99:21:99:44 | age : String | MybatisSqlInjection.java:100:37:100:39 | age : String | -| MybatisSqlInjection.java:100:37:100:39 | age : String | MybatisSqlInjectionService.java:80:21:80:30 | age : String | +| MybatisSqlInjection.java:94:20:94:44 | name : String | MybatisSqlInjection.java:95:36:95:39 | name : String | +| MybatisSqlInjection.java:95:36:95:39 | name : String | MybatisSqlInjectionService.java:76:20:76:30 | name : String | +| MybatisSqlInjection.java:99:20:99:43 | age : String | MybatisSqlInjection.java:100:36:100:38 | age : String | +| MybatisSqlInjection.java:100:36:100:38 | age : String | MybatisSqlInjectionService.java:80:20:80:29 | age : String | | MybatisSqlInjectionService.java:48:19:48:29 | name : String | MybatisSqlInjectionService.java:50:23:50:26 | name : String | | MybatisSqlInjectionService.java:50:3:50:9 | hashMap [post update] [] : String | MybatisSqlInjectionService.java:51:27:51:33 | hashMap | | MybatisSqlInjectionService.java:50:23:50:26 | name : String | MybatisSqlInjectionService.java:50:3:50:9 | hashMap [post update] [] : String | -| MybatisSqlInjectionService.java:76:21:76:31 | name : String | MybatisSqlInjectionService.java:77:29:77:32 | name | -| MybatisSqlInjectionService.java:80:21:80:30 | age : String | MybatisSqlInjectionService.java:81:29:81:31 | age | +| MybatisSqlInjectionService.java:76:20:76:30 | name : String | MybatisSqlInjectionService.java:77:28:77:31 | name | +| MybatisSqlInjectionService.java:80:20:80:29 | age : String | MybatisSqlInjectionService.java:81:28:81:30 | age | nodes | MybatisSqlInjection.java:62:19:62:43 | name : String | semmle.label | name : String | | MybatisSqlInjection.java:63:35:63:38 | name : String | semmle.label | name : String | -| MybatisSqlInjection.java:94:21:94:45 | name : String | semmle.label | name : String | -| MybatisSqlInjection.java:95:37:95:40 | name : String | semmle.label | name : String | -| MybatisSqlInjection.java:99:21:99:44 | age : String | semmle.label | age : String | -| MybatisSqlInjection.java:100:37:100:39 | age : String | semmle.label | age : String | +| MybatisSqlInjection.java:94:20:94:44 | name : String | semmle.label | name : String | +| MybatisSqlInjection.java:95:36:95:39 | name : String | semmle.label | name : String | +| MybatisSqlInjection.java:99:20:99:43 | age : String | semmle.label | age : String | +| MybatisSqlInjection.java:100:36:100:38 | age : String | semmle.label | age : String | | MybatisSqlInjectionService.java:48:19:48:29 | name : String | semmle.label | name : String | | MybatisSqlInjectionService.java:50:3:50:9 | hashMap [post update] [] : String | semmle.label | hashMap [post update] [] : String | | MybatisSqlInjectionService.java:50:23:50:26 | name : String | semmle.label | name : String | | MybatisSqlInjectionService.java:51:27:51:33 | hashMap | semmle.label | hashMap | -| MybatisSqlInjectionService.java:76:21:76:31 | name : String | semmle.label | name : String | -| MybatisSqlInjectionService.java:77:29:77:32 | name | semmle.label | name | -| MybatisSqlInjectionService.java:80:21:80:30 | age : String | semmle.label | age : String | -| MybatisSqlInjectionService.java:81:29:81:31 | age | semmle.label | age | +| MybatisSqlInjectionService.java:76:20:76:30 | name : String | semmle.label | name : String | +| MybatisSqlInjectionService.java:77:28:77:31 | name | semmle.label | name | +| MybatisSqlInjectionService.java:80:20:80:29 | age : String | semmle.label | age : String | +| MybatisSqlInjectionService.java:81:28:81:30 | age | semmle.label | age | subpaths #select | MybatisSqlInjectionService.java:51:27:51:33 | hashMap | MybatisSqlInjection.java:62:19:62:43 | name : String | MybatisSqlInjectionService.java:51:27:51:33 | hashMap | MyBatis annotation SQL injection might include code from $@ to $@. | MybatisSqlInjection.java:62:19:62:43 | name | this user input | SqlInjectionMapper.java:33:2:33:54 | Select | this SQL operation | From 22841276502dbe6bac77a618775153833f542d8e Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Tue, 15 Nov 2022 13:18:40 +0100 Subject: [PATCH 509/796] Add MaD rows for the Data class --- .../swift/frameworks/StandardLibrary/Data.qll | 45 +++- .../library-tests/dataflow/taint/data.swift | 240 ++++++++++++++++-- .../library-tests/dataflow/taint/string.swift | 24 ++ 3 files changed, 291 insertions(+), 18 deletions(-) diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Data.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Data.qll index 740fc8874b6..0e27c0824dc 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Data.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Data.qll @@ -1,6 +1,47 @@ import swift private import codeql.swift.dataflow.ExternalFlow -private class DataSummaries extends SummaryModelCsv { - override predicate row(string row) { row = ";Data;true;init(_:);;;Argument[0];ReturnValue;taint" } +private class DataSources extends SourceModelCsv { + override predicate row(string row) { + row = ";Data;true;init(contentsOf:options:);;;ReturnValue;remote" + } +} + +private class DataSummaries extends SummaryModelCsv { + override predicate row(string row) { + row = + [ + ";Data;true;init(_:);;;Argument[0];ReturnValue;taint", + ";Data;true;init(base64Encoded:options:);;;Argument[0];ReturnValue;taint", + ";Data;true;init(buffer:);;;Argument[0];ReturnValue;taint", + ";Data;true;init(bytes:count:);;;Argument[0];ReturnValue;taint", + ";Data;true;init(contentsOf:options:);;;Argument[0];ReturnValue;taint", + ";Data;true;init(bytesNoCopy:count:deallocator:);;;Argument[0];ReturnValue;taint", + ";Data;true;init(referencing:);;;Argument[0];ReturnValue;taint", + ";Data;true;append(_:);;;Argument[0];Argument[-1];taint", + ";Data;true;append(_:count:);;;Argument[0];Argument[-1];taint", + ";Data;true;append(contentsOf:);;;Argument[0];Argument[-1];taint", + ";Data;true;base64EncodedData(options:);;;Argument[-1];ReturnValue;taint", + ";Data;true;base64EncodedString(options:);;;Argument[-1];ReturnValue;taint", + ";Data;true;compactMap(_:);;;Argument[-1];ReturnValue;taint", + ";Data;true;copyBytes(to:);;;Argument[-1];Argument[0];taint", + ";Data;true;copyBytes(to:count:);;;Argument[-1];Argument[0];taint", + ";Data;true;copyBytes(to:from:);;;Argument[-1];Argument[0];taint", + ";Data;true;flatMap(_:);;;Argument[-1];ReturnValue;taint", + ";Data;true;insert(_:at:);;;Argument[0];Argument[-1];taint", + ";Data;true;insert(contentsOf:at:);;;Argument[0];Argument[-1];taint", + ";Data;true;map(_:);;;Argument[-1];ReturnValue;taint", + ";Data;true;reduce(into:_:);;;Argument[-1];ReturnValue;taint", + ";Data;true;replace(_:with:maxReplacements:);;;Argument[1];Argument[-1];taint", + ";Data;true;replaceSubrange(_:with:);;;Argument[1];Argument[-1];taint", + ";Data;true;replaceSubrange(_:with:count:);;;Argument[1];Argument[-1];taint", + ";Data;true;replacing(_:with:maxReplacements:);;;Argument[1];Argument[-1];taint", + ";Data;true;replacing(_:with:subrange:maxReplacements:);;;Argument[1];Argument[-1];taint", + ";Data;true;shuffled();;;Argument[-1];ReturnValue;taint", + ";Data;true;shuffled(using:);;;Argument[-1];ReturnValue;taint", + ";Data;true;sorted(using:);;;Argument[-1];ReturnValue;taint", + ";Data;true;trimmingPrefix(_:);;;Argument[-1];ReturnValue;taint", + ";Data;true;trimmingPrefix(while:);;;Argument[-1];ReturnValue;taint" + ] + } } diff --git a/swift/ql/test/library-tests/dataflow/taint/data.swift b/swift/ql/test/library-tests/dataflow/taint/data.swift index d7ebe600f8a..ba53694cf98 100644 --- a/swift/ql/test/library-tests/dataflow/taint/data.swift +++ b/swift/ql/test/library-tests/dataflow/taint/data.swift @@ -1,33 +1,241 @@ +// --- stubs --- +struct URL {} -class Data +class NSData {} + +protocol SortComparator { + associatedtype Compared +} +struct Data { + struct Base64EncodingOptions : OptionSet { let rawValue: Int } + struct Base64DecodingOptions : OptionSet { let rawValue: Int } + enum Deallocator { case none } + struct ReadingOptions : OptionSet { let rawValue: Int } + typealias Index = Int init(_ elements: S) {} + init(base64Encoded: Data, options: Data.Base64DecodingOptions) {} + init(buffer: UnsafeBufferPointer) {} + init(buffer: UnsafeMutablePointer) {} + init(bytes: UnsafeRawPointer, count: Int) {} + init(bytesNoCopy: UnsafeRawPointer, count: Int, deallocator: Data.Deallocator) {} + init(contentsOf: URL, options: ReadingOptions) {} + init(referencing: NSData) {} + func append(_: Data) {} + func append(_: UInt8) {} + func append(_: UnsafeBufferPointer) {} + func append(_: UnsafePointer, count: Int) {} + func append(contentsOf: [UInt8]) {} + func append(contentsOf: S) {} + func base64EncodedData(options: Data.Base64EncodingOptions) -> Data { return Data("") } + func base64EncodedString(options: Data.Base64EncodingOptions) -> String { return "" } + func compactMap(_: (UInt8) -> ElementOfResult) -> [ElementOfResult] { return [] } + func copyBytes(to: UnsafeMutableRawBufferPointer) {} + func copyBytes(to: UnsafeMutablePointer, count: Int) {} + func copyBytes(to: UnsafeMutablePointer, from: Range) {} + func flatMap(_: (UInt8) -> SegmentOfResult) -> [SegmentOfResult.Element] where SegmentOfResult : Sequence { return [] } + func flatMap(_: (UInt8) -> ElementOfResult?) -> [ElementOfResult] { return [] } + func insert(_: UInt8, at: Int) {} + func insert(contentsOf: C, at: Int) where C : Collection, UInt8 == C.Element {} + func map(_: (UInt8) -> T) -> [T] { return [] } + func reduce(into initialResult: Result, _: (inout Result, UInt8) -> ()) -> Result { return initialResult } + func replace(_: C, with: Replacement, maxReplacements: Int) where C : Collection, Replacement : Collection, UInt8 == C.Element, C.Element == Replacement.Element {} + func replaceSubrange(_: Range, with: Data) {} + func replaceSubrange(_: Range, with: ByteCollection) where ByteCollection : Collection, ByteCollection.Element == UInt8 {} + func replaceSubrange(_: Range, with: UnsafeBufferPointer) {} + func replaceSubrange(_: Range, with: UnsafeRawPointer, count: Int) {} + func replaceSubrange(_: R, with: C) where C : Collection, R : RangeExpression, UInt8 == C.Element, Int == R.Bound {} + func replacing(_: C, with: Replacement, maxReplacements: Int = .max) -> Data where C : Collection, Replacement : Collection, UInt8 == C.Element, C.Element == Replacement.Element { return Data("") } + func replacing(_: C, with: Replacement, subrange: Range, maxReplacements: Int = .max) -> Data where C : Collection, Replacement : Collection, UInt8 == C.Element, C.Element == Replacement.Element { return Data("") } + func shuffled() -> [UInt8] { return [] } + func shuffled(using: inout T) -> [UInt8] { return [] } + func sorted(using: Comparator) -> [UInt8] where Comparator : SortComparator, UInt8 == Comparator.Compared { return [] } + func trimmingPrefix(_ prefix: Prefix) -> Data where Prefix : Sequence, UInt8 == Prefix.Element { return Data("") } + func trimmingPrefix(while: (UInt8) -> Bool) -> Data { return Data("") } } -extension String { - struct Encoding { - static let utf8 = Encoding() - } +// --- tests --- - init?(data: Data, encoding: Encoding) { self.init() } +class UInt8SortCompartor : SortComparator { + typealias Compared = UInt8 } -func source() -> String { return "" } -func sink(arg: Data) {} -func sink2(arg: String) {} +func source() -> Any { return "" } +func sink(arg: Any) {} +func rng() -> RandomNumberGenerator? { return nil } +func cmp() -> UInt8SortCompartor? { return nil } func taintThroughData() { + // ";Data;true;init(_:);;;Argument[0];ReturnValue;taint", let dataClean = Data("123456".utf8) - let dataTainted = Data(source().utf8) + let dataTainted = Data((source() as! String).utf8) let dataTainted2 = Data(dataTainted) sink(arg: dataClean) - sink(arg: dataTainted) // $ MISSING: tainted=13 - sink(arg: dataTainted2) // $ MISSING: tainted=13 + sink(arg: dataTainted) // $ MISSING: tainted=71 + sink(arg: dataTainted2) // $ MISSING: tainted=71 - let stringClean = String(data: dataClean, encoding: String.Encoding.utf8) - let stringTainted = String(data: dataTainted, encoding: String.Encoding.utf8) + // ";Data;true;init(base64Encoded:options:);;;Argument[0];ReturnValue;taint", + let dataTainted3 = Data(base64Encoded: source() as! Data, options: []) + sink(arg: dataTainted3) // $ tainted=79 + + // ";Data;true;init(buffer:);;;Argument[0];ReturnValue;taint", + let dataTainted4 = Data(buffer: source() as! UnsafeBufferPointer) + sink(arg: dataTainted4) // $ tainted=83 + let dataTainted5 = Data(buffer: source() as! UnsafeMutablePointer) + sink(arg: dataTainted5) // $ tainted=85 + + // ";Data;true;init(bytes:count:);;;Argument[0];ReturnValue;taint", + let dataTainted6 = Data(bytes: source() as! UnsafeRawPointer, count: 0) + sink(arg: dataTainted6) // $ tainted=89 + + // ";Data;true;init(bytesNoCopy:count:deallocator:);;;Argument[0];ReturnValue;taint", + let dataTainted7 = Data(bytesNoCopy: source() as! UnsafeRawPointer, count: 0, deallocator: Data.Deallocator.none) + sink(arg: dataTainted7) // $ tainted=93 + + // ";Data;true;init(contentsOf:options:);;;Argument[0];ReturnValue;taint", + let dataTainted8 = Data(contentsOf: source() as! URL, options: []) + sink(arg: dataTainted8) // $ tainted=97 + + // ";Data;true;init(referencing:);;;Argument[0];ReturnValue;taint", + let dataTainted9 = Data(referencing: source() as! NSData) + sink(arg: dataTainted9) // $ tainted=101 + + // ";Data;true;append(_:);;;Argument[0];Argument[-1];taint", + let dataTainted10 = Data("") + dataTainted10.append(source() as! Data) + sink(arg: dataTainted10) // $ tainted=106 + + let dataTainted11 = Data("") + dataTainted11.append(source() as! UInt8) + sink(arg: dataTainted11) // $ tainted=110 + + let dataTainted12 = Data("") + dataTainted12.append(source() as! UnsafeBufferPointer) + sink(arg: dataTainted12) // $ tainted=114 + + // ";Data;true;append(_:count:);;;Argument[0];Argument[-1];taint", + let dataTainted13 = Data("") + dataTainted13.append(source() as! UnsafePointer, count: 0) + sink(arg: dataTainted13) // $ tainted=119 + + // ";Data;true;append(contentsOf:);;;Argument[0];Argument[-1];taint", + let dataTainted14 = Data("") + dataTainted14.append(contentsOf: source() as! [UInt8]) + sink(arg: dataTainted14) // $ tainted=124 + + // ";Data;true;base64EncodedData(options:);;;Argument[-1];ReturnValue;taint", + let dataTainted15 = source() as! Data + sink(arg: dataTainted15.base64EncodedData(options: [])) // $ tainted=128 + + // ";Data;true;base64EncodedString(options:);;;Argument[-1];ReturnValue;taint", + let dataTainted16 = source() as! Data + sink(arg: dataTainted16.base64EncodedString(options: [])) // $ tainted=132 + + // ";Data;true;compactMap(_:);;;Argument[-1];ReturnValue;taint", + let dataTainted17 = source() as! Data + let compactMapped: [Int] = dataTainted17.compactMap { str in Int(str) } + sink(arg: compactMapped) // $ tainted=136 + + // ";Data;true;copyBytes(to:);;;Argument[-1];Argument[0];taint", + let dataTainted18 = source() as! Data + let pointerTainted18 = UnsafeMutableRawBufferPointer.allocate(byteCount: 0, alignment: 0) + dataTainted18.copyBytes(to: pointerTainted18) + sink(arg: pointerTainted18) // $ tainted=141 + + // ";Data;true;copyBytes(to:count:);;;Argument[-1];Argument[0];taint", + let dataTainted19 = source() as! Data + let pointerTainted19 = UnsafeMutablePointer.allocate(capacity: 0) + dataTainted19.copyBytes(to: pointerTainted19, count: 0) + sink(arg: pointerTainted19) // $ MISSING: tainted=147 + + // ";Data;true;copyBytes(to:from:);;;Argument[-1];Argument[0];taint", + let dataTainted20 = source() as! Data + let pointerTainted20 = UnsafeMutablePointer.allocate(capacity: 0) + dataTainted20.copyBytes(to: pointerTainted20, from: 0..<1) + sink(arg: pointerTainted20) // $ MISSING: tainted=153 + + // ";Data;true;flatMap(_:);;;Argument[-1];ReturnValue;taint", + let dataTainted21 = source() as! Data + let flatMapped = dataTainted21.flatMap { Array(repeating: $0, count: 0) } + sink(arg: flatMapped) // $ tainted=159 + + let dataTainted22 = source() as! Data + let flatMapped2 = dataTainted22.flatMap { str in Int(str) } + sink(arg: flatMapped2) // $ tainted=163 + + // ";Data;true;insert(_:at:);;;Argument[0];Argument[-1];taint", + let dataTainted23 = Data("") + dataTainted23.insert(source() as! UInt8, at: 0) + sink(arg: dataTainted23) // $ tainted=169 + + // ";Data;true;insert(contentsOf:at:);;;Argument[0];Argument[-1];taint", + let dataTainted24 = Data("") + dataTainted24.insert(contentsOf: source() as! [UInt8], at: 0) + sink(arg: dataTainted24) // $ tainted=174 + + // ";Data;true;map(_:);;;Argument[-1];ReturnValue;taint", + let dataTainted25 = source() as! Data + let mapped = dataTainted25.map { $0 } + sink(arg: mapped) // $ tainted=178 + + // ";Data;true;reduce(into:_:);;;Argument[-1];ReturnValue;taint", + let dataTainted26 = source() as! Data + let reduced = dataTainted26.reduce(into: [:]) { c, i in c[i, default: 0] += 1 } + sink(arg: reduced) // $ tainted=183 + + // ";Data;true;replace(_:with:maxReplacements:);;;Argument[1];Argument[-1];taint", + let dataTainted27 = Data("") + dataTainted27.replace([0], with: source() as! [UInt8], maxReplacements: .max) + sink(arg: dataTainted27) // $ tainted=189 + + // ";Data;true;replaceSubrange(_:with:);;;Argument[1];Argument[-1];taint", + let dataTainted28 = Data("") + dataTainted28.replaceSubrange(1..<3, with: source() as! Data) + sink(arg: dataTainted28) // $ tainted=194 + + let dataTainted29 = Data("") + dataTainted29.replaceSubrange(1..<3, with: source() as! [UInt8]) + sink(arg: dataTainted29) // $ tainted=198 + + let dataTainted30 = Data("") + dataTainted30.replaceSubrange(1..<3, with: source() as! UnsafeBufferPointer) + sink(arg: dataTainted30) // $ tainted=202 + + // ";Data;true;replaceSubrange(_:with:count:);;;Argument[1];Argument[-1];taint", + let dataTainted31 = Data("") + dataTainted31.replaceSubrange(1..<3, with: source() as! UnsafeRawPointer, count: 0) + sink(arg: dataTainted31) // $ tainted=207 + + // ";Data;true;replacing(_:with:maxReplacements:);;;Argument[1];Argument[-1];taint", + let dataTainted32 = Data("") + dataTainted32.replacing([0], with: source() as! [UInt8], maxReplacements: 0) + sink(arg: dataTainted32) // $ tainted=212 + + // ";Data;true;replacing(_:with:subrange:maxReplacements:);;;Argument[1];Argument[-1];taint", + let dataTainted33 = Data("") + dataTainted33.replacing([0], with: source() as! [UInt8], subrange: 1..<3, maxReplacements: 0) + sink(arg: dataTainted33) // $ tainted=217 + + // ";Data;true;shuffled();;;Argument[-1];ReturnValue;taint", + let dataTainted34 = source() as! Data + sink(arg: dataTainted34.shuffled()) // $ tainted=221 + + // ";Data;true;shuffled(using:);;;Argument[-1];ReturnValue;taint", + let dataTainted35 = source() as! Data + var rng = rng()! + sink(arg: dataTainted35.shuffled(using: &rng)) // $ tainted=225 + + // ";Data;true;sorted(using:);;;Argument[-1];ReturnValue;taint", + let dataTainted36 = source() as! Data + sink(arg: dataTainted36.sorted(using: cmp()!)) // $ tainted=230 + + // ";Data;true;trimmingPrefix(_:);;;Argument[-1];ReturnValue;taint", + let dataTainted37 = source() as! Data + sink(arg: dataTainted37.trimmingPrefix([0])) // $ tainted=234 + + // ";Data;true;trimmingPrefix(while:);;;Argument[-1];ReturnValue;taint" + let dataTainted38 = source() as! Data + sink(arg: dataTainted38.trimmingPrefix { _ in false }) // $ tainted=238 - sink2(arg: stringClean!) // $ MISSING: tainted=13 - sink2(arg: stringTainted!) // $ MISSING: tainted=13 } diff --git a/swift/ql/test/library-tests/dataflow/taint/string.swift b/swift/ql/test/library-tests/dataflow/taint/string.swift index 6f5e5876a65..5b54a8dc444 100644 --- a/swift/ql/test/library-tests/dataflow/taint/string.swift +++ b/swift/ql/test/library-tests/dataflow/taint/string.swift @@ -87,3 +87,27 @@ func taintThroughStringOperations() { sink(arg: clean.debugDescription) sink(arg: tainted.debugDescription) // $ MISSING: tainted=74 } + +class Data +{ + init(_ elements: S) {} +} + +extension String { + struct Encoding { + static let utf8 = Encoding() + } + + init?(data: Data, encoding: Encoding) { self.init() } +} + + +func source3() -> Data { return Data("") } + +func taintThroughData() { + let stringClean = String(data: Data(""), encoding: String.Encoding.utf8) + let stringTainted = String(data: source3(), encoding: String.Encoding.utf8) + + sink(arg: stringClean!) + sink(arg: stringTainted!) // $ MISSING: tainted=100 +} From d6b14a13952337702f5c2c631fdf7699daa43d2c Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Mon, 21 Nov 2022 15:45:31 +0100 Subject: [PATCH 510/796] Update test expectations --- .../dataflow/taint/LocalTaint.expected | 1 + .../dataflow/taint/Taint.expected | 403 ++++++++++++++++++ 2 files changed, 404 insertions(+) diff --git a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected index e2c893738d3..9e3f081261c 100644 --- a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected @@ -1,6 +1,7 @@ | nsdata.swift:139:15:139:15 | nsDataTainted24 | nsdata.swift:139:15:139:31 | .bytes | | nsdata.swift:140:15:140:15 | nsDataTainted24 | nsdata.swift:140:15:140:31 | .description | | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 | nsmutabledata.swift:49:15:49:37 | .mutableBytes | +| data.swift:184:58:184:58 | &... | data.swift:184:58:184:73 | ...[...] | | string.swift:7:13:7:13 | | string.swift:7:13:7:13 | [post] | | string.swift:7:13:7:13 | | string.swift:7:14:7:14 | [post] &... | | string.swift:7:13:7:13 | TapExpr | string.swift:7:13:7:13 | "..." | diff --git a/swift/ql/test/library-tests/dataflow/taint/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/Taint.expected index 38c3a209deb..9430f377bef 100644 --- a/swift/ql/test/library-tests/dataflow/taint/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/Taint.expected @@ -1,5 +1,146 @@ edges | file://:0:0:0:0 | [summary] to write: argument 0.parameter 0 in enumerateBytes(_:) : | nsdata.swift:110:9:110:9 | bytes : | +| data.swift:17:2:17:66 | [summary param] 0 in init(base64Encoded:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | +| data.swift:18:2:18:61 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | +| data.swift:19:2:19:62 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | +| data.swift:20:2:20:45 | [summary param] 0 in init(bytes:count:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytes:count:) : | +| data.swift:21:2:21:82 | [summary param] 0 in init(bytesNoCopy:count:deallocator:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:count:deallocator:) : | +| data.swift:22:2:22:50 | [summary param] 0 in init(contentsOf:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOf:options:) : | +| data.swift:23:2:23:29 | [summary param] 0 in init(referencing:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(referencing:) : | +| data.swift:24:2:24:24 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | +| data.swift:25:2:25:25 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | +| data.swift:26:2:26:63 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | +| data.swift:27:2:27:52 | [summary param] 0 in append(_:count:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:count:) : | +| data.swift:28:2:28:36 | [summary param] 0 in append(contentsOf:) : | file://:0:0:0:0 | [summary] to write: argument this in append(contentsOf:) : | +| data.swift:30:2:30:88 | [summary param] this in base64EncodedData(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedData(options:) : | +| data.swift:31:2:31:86 | [summary param] this in base64EncodedString(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedString(options:) : | +| data.swift:32:2:32:99 | [summary param] this in compactMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in compactMap(_:) : | +| data.swift:33:2:33:53 | [summary param] this in copyBytes(to:) : | file://:0:0:0:0 | [summary] to write: argument 0 in copyBytes(to:) : | +| data.swift:36:2:36:137 | [summary param] this in flatMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | +| data.swift:37:2:37:97 | [summary param] this in flatMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | +| data.swift:38:2:38:34 | [summary param] 0 in insert(_:at:) : | file://:0:0:0:0 | [summary] to write: argument this in insert(_:at:) : | +| data.swift:39:2:39:83 | [summary param] 0 in insert(contentsOf:at:) : | file://:0:0:0:0 | [summary] to write: argument this in insert(contentsOf:at:) : | +| data.swift:40:2:40:50 | [summary param] this in map(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in map(_:) : | +| data.swift:41:2:41:115 | [summary param] this in reduce(into:_:) : | file://:0:0:0:0 | [summary] to write: return (return) in reduce(into:_:) : | +| data.swift:42:2:42:180 | [summary param] 1 in replace(_:with:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replace(_:with:maxReplacements:) : | +| data.swift:43:2:43:58 | [summary param] 1 in replaceSubrange(_:with:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | +| data.swift:44:2:44:151 | [summary param] 1 in replaceSubrange(_:with:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | +| data.swift:46:2:46:82 | [summary param] 1 in replaceSubrange(_:with:count:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:count:) : | +| data.swift:48:2:48:214 | [summary param] 1 in replacing(_:with:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replacing(_:with:maxReplacements:) : | +| data.swift:49:2:49:236 | [summary param] 1 in replacing(_:with:subrange:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replacing(_:with:subrange:maxReplacements:) : | +| data.swift:50:2:50:41 | [summary param] this in shuffled() : | file://:0:0:0:0 | [summary] to write: return (return) in shuffled() : | +| data.swift:51:2:51:58 | [summary param] this in shuffled(using:) : | file://:0:0:0:0 | [summary] to write: return (return) in shuffled(using:) : | +| data.swift:52:2:52:132 | [summary param] this in sorted(using:) : | file://:0:0:0:0 | [summary] to write: return (return) in sorted(using:) : | +| data.swift:53:2:53:123 | [summary param] this in trimmingPrefix(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(_:) : | +| data.swift:54:2:54:72 | [summary param] this in trimmingPrefix(while:) : | file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(while:) : | +| data.swift:79:21:79:71 | call to init(base64Encoded:options:) : | data.swift:80:12:80:12 | dataTainted3 | +| data.swift:79:41:79:48 | call to source() : | data.swift:17:2:17:66 | [summary param] 0 in init(base64Encoded:options:) : | +| data.swift:79:41:79:48 | call to source() : | data.swift:79:21:79:71 | call to init(base64Encoded:options:) : | +| data.swift:83:21:83:73 | call to init(buffer:) : | data.swift:84:12:84:12 | dataTainted4 | +| data.swift:83:34:83:41 | call to source() : | data.swift:18:2:18:61 | [summary param] 0 in init(buffer:) : | +| data.swift:83:34:83:41 | call to source() : | data.swift:83:21:83:73 | call to init(buffer:) : | +| data.swift:85:21:85:74 | call to init(buffer:) : | data.swift:86:12:86:12 | dataTainted5 | +| data.swift:85:34:85:41 | call to source() : | data.swift:19:2:19:62 | [summary param] 0 in init(buffer:) : | +| data.swift:85:34:85:41 | call to source() : | data.swift:85:21:85:74 | call to init(buffer:) : | +| data.swift:89:21:89:72 | call to init(bytes:count:) : | data.swift:90:12:90:12 | dataTainted6 | +| data.swift:89:33:89:40 | call to source() : | data.swift:20:2:20:45 | [summary param] 0 in init(bytes:count:) : | +| data.swift:89:33:89:40 | call to source() : | data.swift:89:21:89:72 | call to init(bytes:count:) : | +| data.swift:93:21:93:114 | call to init(bytesNoCopy:count:deallocator:) : | data.swift:94:12:94:12 | dataTainted7 | +| data.swift:93:39:93:46 | call to source() : | data.swift:21:2:21:82 | [summary param] 0 in init(bytesNoCopy:count:deallocator:) : | +| data.swift:93:39:93:46 | call to source() : | data.swift:93:21:93:114 | call to init(bytesNoCopy:count:deallocator:) : | +| data.swift:97:21:97:67 | call to init(contentsOf:options:) : | data.swift:98:12:98:12 | dataTainted8 | +| data.swift:97:38:97:45 | call to source() : | data.swift:22:2:22:50 | [summary param] 0 in init(contentsOf:options:) : | +| data.swift:97:38:97:45 | call to source() : | data.swift:97:21:97:67 | call to init(contentsOf:options:) : | +| data.swift:101:21:101:58 | call to init(referencing:) : | data.swift:102:12:102:12 | dataTainted9 | +| data.swift:101:39:101:46 | call to source() : | data.swift:23:2:23:29 | [summary param] 0 in init(referencing:) : | +| data.swift:101:39:101:46 | call to source() : | data.swift:101:21:101:58 | call to init(referencing:) : | +| data.swift:106:2:106:2 | [post] dataTainted10 : | data.swift:107:12:107:12 | dataTainted10 | +| data.swift:106:23:106:30 | call to source() : | data.swift:24:2:24:24 | [summary param] 0 in append(_:) : | +| data.swift:106:23:106:30 | call to source() : | data.swift:106:2:106:2 | [post] dataTainted10 : | +| data.swift:110:2:110:2 | [post] dataTainted11 : | data.swift:111:12:111:12 | dataTainted11 | +| data.swift:110:23:110:30 | call to source() : | data.swift:25:2:25:25 | [summary param] 0 in append(_:) : | +| data.swift:110:23:110:30 | call to source() : | data.swift:110:2:110:2 | [post] dataTainted11 : | +| data.swift:114:2:114:2 | [post] dataTainted12 : | data.swift:115:12:115:12 | dataTainted12 | +| data.swift:114:23:114:30 | call to source() : | data.swift:26:2:26:63 | [summary param] 0 in append(_:) : | +| data.swift:114:23:114:30 | call to source() : | data.swift:114:2:114:2 | [post] dataTainted12 : | +| data.swift:119:2:119:2 | [post] dataTainted13 : | data.swift:120:12:120:12 | dataTainted13 | +| data.swift:119:23:119:30 | call to source() : | data.swift:27:2:27:52 | [summary param] 0 in append(_:count:) : | +| data.swift:119:23:119:30 | call to source() : | data.swift:119:2:119:2 | [post] dataTainted13 : | +| data.swift:124:2:124:2 | [post] dataTainted14 : | data.swift:125:12:125:12 | dataTainted14 | +| data.swift:124:35:124:42 | call to source() : | data.swift:28:2:28:36 | [summary param] 0 in append(contentsOf:) : | +| data.swift:124:35:124:42 | call to source() : | data.swift:124:2:124:2 | [post] dataTainted14 : | +| data.swift:128:22:128:29 | call to source() : | data.swift:129:12:129:12 | dataTainted15 : | +| data.swift:129:12:129:12 | dataTainted15 : | data.swift:30:2:30:88 | [summary param] this in base64EncodedData(options:) : | +| data.swift:129:12:129:12 | dataTainted15 : | data.swift:129:12:129:55 | call to base64EncodedData(options:) | +| data.swift:132:22:132:29 | call to source() : | data.swift:133:12:133:12 | dataTainted16 : | +| data.swift:133:12:133:12 | dataTainted16 : | data.swift:31:2:31:86 | [summary param] this in base64EncodedString(options:) : | +| data.swift:133:12:133:12 | dataTainted16 : | data.swift:133:12:133:57 | call to base64EncodedString(options:) | +| data.swift:136:22:136:29 | call to source() : | data.swift:137:29:137:29 | dataTainted17 : | +| data.swift:137:29:137:29 | dataTainted17 : | data.swift:32:2:32:99 | [summary param] this in compactMap(_:) : | +| data.swift:137:29:137:29 | dataTainted17 : | data.swift:137:29:137:72 | call to compactMap(_:) : | +| data.swift:137:29:137:72 | call to compactMap(_:) : | data.swift:138:12:138:12 | compactMapped | +| data.swift:141:22:141:29 | call to source() : | data.swift:143:2:143:2 | dataTainted18 : | +| data.swift:143:2:143:2 | dataTainted18 : | data.swift:33:2:33:53 | [summary param] this in copyBytes(to:) : | +| data.swift:143:2:143:2 | dataTainted18 : | data.swift:143:30:143:30 | [post] pointerTainted18 : | +| data.swift:143:30:143:30 | [post] pointerTainted18 : | data.swift:144:12:144:12 | pointerTainted18 | +| data.swift:159:22:159:29 | call to source() : | data.swift:160:19:160:19 | dataTainted21 : | +| data.swift:160:19:160:19 | dataTainted21 : | data.swift:36:2:36:137 | [summary param] this in flatMap(_:) : | +| data.swift:160:19:160:19 | dataTainted21 : | data.swift:160:19:160:74 | call to flatMap(_:) : | +| data.swift:160:19:160:74 | call to flatMap(_:) : | data.swift:161:12:161:12 | flatMapped | +| data.swift:163:22:163:29 | call to source() : | data.swift:164:20:164:20 | dataTainted22 : | +| data.swift:164:20:164:20 | dataTainted22 : | data.swift:37:2:37:97 | [summary param] this in flatMap(_:) : | +| data.swift:164:20:164:20 | dataTainted22 : | data.swift:164:20:164:60 | call to flatMap(_:) : | +| data.swift:164:20:164:60 | call to flatMap(_:) : | data.swift:165:12:165:12 | flatMapped2 | +| data.swift:169:2:169:2 | [post] dataTainted23 : | data.swift:170:12:170:12 | dataTainted23 | +| data.swift:169:23:169:30 | call to source() : | data.swift:38:2:38:34 | [summary param] 0 in insert(_:at:) : | +| data.swift:169:23:169:30 | call to source() : | data.swift:169:2:169:2 | [post] dataTainted23 : | +| data.swift:174:2:174:2 | [post] dataTainted24 : | data.swift:175:12:175:12 | dataTainted24 | +| data.swift:174:35:174:42 | call to source() : | data.swift:39:2:39:83 | [summary param] 0 in insert(contentsOf:at:) : | +| data.swift:174:35:174:42 | call to source() : | data.swift:174:2:174:2 | [post] dataTainted24 : | +| data.swift:178:22:178:29 | call to source() : | data.swift:179:15:179:15 | dataTainted25 : | +| data.swift:179:15:179:15 | dataTainted25 : | data.swift:40:2:40:50 | [summary param] this in map(_:) : | +| data.swift:179:15:179:15 | dataTainted25 : | data.swift:179:15:179:38 | call to map(_:) : | +| data.swift:179:15:179:38 | call to map(_:) : | data.swift:180:12:180:12 | mapped | +| data.swift:183:22:183:29 | call to source() : | data.swift:184:16:184:16 | dataTainted26 : | +| data.swift:184:16:184:16 | dataTainted26 : | data.swift:41:2:41:115 | [summary param] this in reduce(into:_:) : | +| data.swift:184:16:184:16 | dataTainted26 : | data.swift:184:16:184:80 | call to reduce(into:_:) : | +| data.swift:184:16:184:80 | call to reduce(into:_:) : | data.swift:185:12:185:12 | reduced | +| data.swift:189:2:189:2 | [post] dataTainted27 : | data.swift:190:12:190:12 | dataTainted27 | +| data.swift:189:35:189:42 | call to source() : | data.swift:42:2:42:180 | [summary param] 1 in replace(_:with:maxReplacements:) : | +| data.swift:189:35:189:42 | call to source() : | data.swift:189:2:189:2 | [post] dataTainted27 : | +| data.swift:194:2:194:2 | [post] dataTainted28 : | data.swift:195:12:195:12 | dataTainted28 | +| data.swift:194:45:194:52 | call to source() : | data.swift:43:2:43:58 | [summary param] 1 in replaceSubrange(_:with:) : | +| data.swift:194:45:194:52 | call to source() : | data.swift:194:2:194:2 | [post] dataTainted28 : | +| data.swift:198:2:198:2 | [post] dataTainted29 : | data.swift:199:12:199:12 | dataTainted29 | +| data.swift:198:45:198:52 | call to source() : | data.swift:44:2:44:151 | [summary param] 1 in replaceSubrange(_:with:) : | +| data.swift:198:45:198:52 | call to source() : | data.swift:198:2:198:2 | [post] dataTainted29 : | +| data.swift:202:2:202:2 | [post] dataTainted30 : | data.swift:203:12:203:12 | dataTainted30 | +| data.swift:202:45:202:52 | call to source() : | data.swift:44:2:44:151 | [summary param] 1 in replaceSubrange(_:with:) : | +| data.swift:202:45:202:52 | call to source() : | data.swift:202:2:202:2 | [post] dataTainted30 : | +| data.swift:207:2:207:2 | [post] dataTainted31 : | data.swift:208:12:208:12 | dataTainted31 | +| data.swift:207:45:207:52 | call to source() : | data.swift:46:2:46:82 | [summary param] 1 in replaceSubrange(_:with:count:) : | +| data.swift:207:45:207:52 | call to source() : | data.swift:207:2:207:2 | [post] dataTainted31 : | +| data.swift:212:2:212:2 | [post] dataTainted32 : | data.swift:213:12:213:12 | dataTainted32 | +| data.swift:212:37:212:44 | call to source() : | data.swift:48:2:48:214 | [summary param] 1 in replacing(_:with:maxReplacements:) : | +| data.swift:212:37:212:44 | call to source() : | data.swift:212:2:212:2 | [post] dataTainted32 : | +| data.swift:217:2:217:2 | [post] dataTainted33 : | data.swift:218:12:218:12 | dataTainted33 | +| data.swift:217:37:217:44 | call to source() : | data.swift:49:2:49:236 | [summary param] 1 in replacing(_:with:subrange:maxReplacements:) : | +| data.swift:217:37:217:44 | call to source() : | data.swift:217:2:217:2 | [post] dataTainted33 : | +| data.swift:221:22:221:29 | call to source() : | data.swift:222:12:222:12 | dataTainted34 : | +| data.swift:222:12:222:12 | dataTainted34 : | data.swift:50:2:50:41 | [summary param] this in shuffled() : | +| data.swift:222:12:222:12 | dataTainted34 : | data.swift:222:12:222:35 | call to shuffled() | +| data.swift:225:22:225:29 | call to source() : | data.swift:227:12:227:12 | dataTainted35 : | +| data.swift:227:12:227:12 | dataTainted35 : | data.swift:51:2:51:58 | [summary param] this in shuffled(using:) : | +| data.swift:227:12:227:12 | dataTainted35 : | data.swift:227:12:227:46 | call to shuffled(using:) | +| data.swift:230:22:230:29 | call to source() : | data.swift:231:12:231:12 | dataTainted36 : | +| data.swift:231:12:231:12 | dataTainted36 : | data.swift:52:2:52:132 | [summary param] this in sorted(using:) : | +| data.swift:231:12:231:12 | dataTainted36 : | data.swift:231:12:231:46 | call to sorted(using:) | +| data.swift:234:22:234:29 | call to source() : | data.swift:235:12:235:12 | dataTainted37 : | +| data.swift:235:12:235:12 | dataTainted37 : | data.swift:53:2:53:123 | [summary param] this in trimmingPrefix(_:) : | +| data.swift:235:12:235:12 | dataTainted37 : | data.swift:235:12:235:44 | call to trimmingPrefix(_:) | +| data.swift:238:22:238:29 | call to source() : | data.swift:239:12:239:12 | dataTainted38 : | +| data.swift:239:12:239:12 | dataTainted38 : | data.swift:54:2:54:72 | [summary param] this in trimmingPrefix(while:) : | +| data.swift:239:12:239:12 | dataTainted38 : | data.swift:239:12:239:54 | call to trimmingPrefix(while:) | | file://:0:0:0:0 | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : | url.swift:120:61:120:61 | data : | | nsdata.swift:22:9:22:9 | self : | file://:0:0:0:0 | .bytes : | | nsdata.swift:23:9:23:9 | self : | file://:0:0:0:0 | .description : | @@ -381,6 +522,7 @@ edges | webview.swift:97:17:97:17 | s : | webview.swift:44:5:44:48 | [summary param] 0 in setValue(_:forProperty:) : | | webview.swift:97:17:97:17 | s : | webview.swift:97:5:97:5 | [post] v3 : | nodes +<<<<<<< HEAD | file://:0:0:0:0 | .bytes : | semmle.label | .bytes : | | file://:0:0:0:0 | .description : | semmle.label | .description : | | file://:0:0:0:0 | .mutableBytes : | semmle.label | .mutableBytes : | @@ -395,11 +537,171 @@ nodes | file://:0:0:0:0 | [summary] to write: argument this in replaceBytes(in:withBytes:) : | semmle.label | [summary] to write: argument this in replaceBytes(in:withBytes:) : | | file://:0:0:0:0 | [summary] to write: argument this in replaceBytes(in:withBytes:length:) : | semmle.label | [summary] to write: argument this in replaceBytes(in:withBytes:length:) : | | file://:0:0:0:0 | [summary] to write: argument this in setData(_:) : | semmle.label | [summary] to write: argument this in setData(_:) : | +======= +| data.swift:17:2:17:66 | [summary param] 0 in init(base64Encoded:options:) : | semmle.label | [summary param] 0 in init(base64Encoded:options:) : | +| data.swift:18:2:18:61 | [summary param] 0 in init(buffer:) : | semmle.label | [summary param] 0 in init(buffer:) : | +| data.swift:19:2:19:62 | [summary param] 0 in init(buffer:) : | semmle.label | [summary param] 0 in init(buffer:) : | +| data.swift:20:2:20:45 | [summary param] 0 in init(bytes:count:) : | semmle.label | [summary param] 0 in init(bytes:count:) : | +| data.swift:21:2:21:82 | [summary param] 0 in init(bytesNoCopy:count:deallocator:) : | semmle.label | [summary param] 0 in init(bytesNoCopy:count:deallocator:) : | +| data.swift:22:2:22:50 | [summary param] 0 in init(contentsOf:options:) : | semmle.label | [summary param] 0 in init(contentsOf:options:) : | +| data.swift:23:2:23:29 | [summary param] 0 in init(referencing:) : | semmle.label | [summary param] 0 in init(referencing:) : | +| data.swift:24:2:24:24 | [summary param] 0 in append(_:) : | semmle.label | [summary param] 0 in append(_:) : | +| data.swift:25:2:25:25 | [summary param] 0 in append(_:) : | semmle.label | [summary param] 0 in append(_:) : | +| data.swift:26:2:26:63 | [summary param] 0 in append(_:) : | semmle.label | [summary param] 0 in append(_:) : | +| data.swift:27:2:27:52 | [summary param] 0 in append(_:count:) : | semmle.label | [summary param] 0 in append(_:count:) : | +| data.swift:28:2:28:36 | [summary param] 0 in append(contentsOf:) : | semmle.label | [summary param] 0 in append(contentsOf:) : | +| data.swift:30:2:30:88 | [summary param] this in base64EncodedData(options:) : | semmle.label | [summary param] this in base64EncodedData(options:) : | +| data.swift:31:2:31:86 | [summary param] this in base64EncodedString(options:) : | semmle.label | [summary param] this in base64EncodedString(options:) : | +| data.swift:32:2:32:99 | [summary param] this in compactMap(_:) : | semmle.label | [summary param] this in compactMap(_:) : | +| data.swift:33:2:33:53 | [summary param] this in copyBytes(to:) : | semmle.label | [summary param] this in copyBytes(to:) : | +| data.swift:36:2:36:137 | [summary param] this in flatMap(_:) : | semmle.label | [summary param] this in flatMap(_:) : | +| data.swift:37:2:37:97 | [summary param] this in flatMap(_:) : | semmle.label | [summary param] this in flatMap(_:) : | +| data.swift:38:2:38:34 | [summary param] 0 in insert(_:at:) : | semmle.label | [summary param] 0 in insert(_:at:) : | +| data.swift:39:2:39:83 | [summary param] 0 in insert(contentsOf:at:) : | semmle.label | [summary param] 0 in insert(contentsOf:at:) : | +| data.swift:40:2:40:50 | [summary param] this in map(_:) : | semmle.label | [summary param] this in map(_:) : | +| data.swift:41:2:41:115 | [summary param] this in reduce(into:_:) : | semmle.label | [summary param] this in reduce(into:_:) : | +| data.swift:42:2:42:180 | [summary param] 1 in replace(_:with:maxReplacements:) : | semmle.label | [summary param] 1 in replace(_:with:maxReplacements:) : | +| data.swift:43:2:43:58 | [summary param] 1 in replaceSubrange(_:with:) : | semmle.label | [summary param] 1 in replaceSubrange(_:with:) : | +| data.swift:44:2:44:151 | [summary param] 1 in replaceSubrange(_:with:) : | semmle.label | [summary param] 1 in replaceSubrange(_:with:) : | +| data.swift:46:2:46:82 | [summary param] 1 in replaceSubrange(_:with:count:) : | semmle.label | [summary param] 1 in replaceSubrange(_:with:count:) : | +| data.swift:48:2:48:214 | [summary param] 1 in replacing(_:with:maxReplacements:) : | semmle.label | [summary param] 1 in replacing(_:with:maxReplacements:) : | +| data.swift:49:2:49:236 | [summary param] 1 in replacing(_:with:subrange:maxReplacements:) : | semmle.label | [summary param] 1 in replacing(_:with:subrange:maxReplacements:) : | +| data.swift:50:2:50:41 | [summary param] this in shuffled() : | semmle.label | [summary param] this in shuffled() : | +| data.swift:51:2:51:58 | [summary param] this in shuffled(using:) : | semmle.label | [summary param] this in shuffled(using:) : | +| data.swift:52:2:52:132 | [summary param] this in sorted(using:) : | semmle.label | [summary param] this in sorted(using:) : | +| data.swift:53:2:53:123 | [summary param] this in trimmingPrefix(_:) : | semmle.label | [summary param] this in trimmingPrefix(_:) : | +| data.swift:54:2:54:72 | [summary param] this in trimmingPrefix(while:) : | semmle.label | [summary param] this in trimmingPrefix(while:) : | +| data.swift:79:21:79:71 | call to init(base64Encoded:options:) : | semmle.label | call to init(base64Encoded:options:) : | +| data.swift:79:41:79:48 | call to source() : | semmle.label | call to source() : | +| data.swift:80:12:80:12 | dataTainted3 | semmle.label | dataTainted3 | +| data.swift:83:21:83:73 | call to init(buffer:) : | semmle.label | call to init(buffer:) : | +| data.swift:83:34:83:41 | call to source() : | semmle.label | call to source() : | +| data.swift:84:12:84:12 | dataTainted4 | semmle.label | dataTainted4 | +| data.swift:85:21:85:74 | call to init(buffer:) : | semmle.label | call to init(buffer:) : | +| data.swift:85:34:85:41 | call to source() : | semmle.label | call to source() : | +| data.swift:86:12:86:12 | dataTainted5 | semmle.label | dataTainted5 | +| data.swift:89:21:89:72 | call to init(bytes:count:) : | semmle.label | call to init(bytes:count:) : | +| data.swift:89:33:89:40 | call to source() : | semmle.label | call to source() : | +| data.swift:90:12:90:12 | dataTainted6 | semmle.label | dataTainted6 | +| data.swift:93:21:93:114 | call to init(bytesNoCopy:count:deallocator:) : | semmle.label | call to init(bytesNoCopy:count:deallocator:) : | +| data.swift:93:39:93:46 | call to source() : | semmle.label | call to source() : | +| data.swift:94:12:94:12 | dataTainted7 | semmle.label | dataTainted7 | +| data.swift:97:21:97:67 | call to init(contentsOf:options:) : | semmle.label | call to init(contentsOf:options:) : | +| data.swift:97:38:97:45 | call to source() : | semmle.label | call to source() : | +| data.swift:98:12:98:12 | dataTainted8 | semmle.label | dataTainted8 | +| data.swift:101:21:101:58 | call to init(referencing:) : | semmle.label | call to init(referencing:) : | +| data.swift:101:39:101:46 | call to source() : | semmle.label | call to source() : | +| data.swift:102:12:102:12 | dataTainted9 | semmle.label | dataTainted9 | +| data.swift:106:2:106:2 | [post] dataTainted10 : | semmle.label | [post] dataTainted10 : | +| data.swift:106:23:106:30 | call to source() : | semmle.label | call to source() : | +| data.swift:107:12:107:12 | dataTainted10 | semmle.label | dataTainted10 | +| data.swift:110:2:110:2 | [post] dataTainted11 : | semmle.label | [post] dataTainted11 : | +| data.swift:110:23:110:30 | call to source() : | semmle.label | call to source() : | +| data.swift:111:12:111:12 | dataTainted11 | semmle.label | dataTainted11 | +| data.swift:114:2:114:2 | [post] dataTainted12 : | semmle.label | [post] dataTainted12 : | +| data.swift:114:23:114:30 | call to source() : | semmle.label | call to source() : | +| data.swift:115:12:115:12 | dataTainted12 | semmle.label | dataTainted12 | +| data.swift:119:2:119:2 | [post] dataTainted13 : | semmle.label | [post] dataTainted13 : | +| data.swift:119:23:119:30 | call to source() : | semmle.label | call to source() : | +| data.swift:120:12:120:12 | dataTainted13 | semmle.label | dataTainted13 | +| data.swift:124:2:124:2 | [post] dataTainted14 : | semmle.label | [post] dataTainted14 : | +| data.swift:124:35:124:42 | call to source() : | semmle.label | call to source() : | +| data.swift:125:12:125:12 | dataTainted14 | semmle.label | dataTainted14 | +| data.swift:128:22:128:29 | call to source() : | semmle.label | call to source() : | +| data.swift:129:12:129:12 | dataTainted15 : | semmle.label | dataTainted15 : | +| data.swift:129:12:129:55 | call to base64EncodedData(options:) | semmle.label | call to base64EncodedData(options:) | +| data.swift:132:22:132:29 | call to source() : | semmle.label | call to source() : | +| data.swift:133:12:133:12 | dataTainted16 : | semmle.label | dataTainted16 : | +| data.swift:133:12:133:57 | call to base64EncodedString(options:) | semmle.label | call to base64EncodedString(options:) | +| data.swift:136:22:136:29 | call to source() : | semmle.label | call to source() : | +| data.swift:137:29:137:29 | dataTainted17 : | semmle.label | dataTainted17 : | +| data.swift:137:29:137:72 | call to compactMap(_:) : | semmle.label | call to compactMap(_:) : | +| data.swift:138:12:138:12 | compactMapped | semmle.label | compactMapped | +| data.swift:141:22:141:29 | call to source() : | semmle.label | call to source() : | +| data.swift:143:2:143:2 | dataTainted18 : | semmle.label | dataTainted18 : | +| data.swift:143:30:143:30 | [post] pointerTainted18 : | semmle.label | [post] pointerTainted18 : | +| data.swift:144:12:144:12 | pointerTainted18 | semmle.label | pointerTainted18 | +| data.swift:159:22:159:29 | call to source() : | semmle.label | call to source() : | +| data.swift:160:19:160:19 | dataTainted21 : | semmle.label | dataTainted21 : | +| data.swift:160:19:160:74 | call to flatMap(_:) : | semmle.label | call to flatMap(_:) : | +| data.swift:161:12:161:12 | flatMapped | semmle.label | flatMapped | +| data.swift:163:22:163:29 | call to source() : | semmle.label | call to source() : | +| data.swift:164:20:164:20 | dataTainted22 : | semmle.label | dataTainted22 : | +| data.swift:164:20:164:60 | call to flatMap(_:) : | semmle.label | call to flatMap(_:) : | +| data.swift:165:12:165:12 | flatMapped2 | semmle.label | flatMapped2 | +| data.swift:169:2:169:2 | [post] dataTainted23 : | semmle.label | [post] dataTainted23 : | +| data.swift:169:23:169:30 | call to source() : | semmle.label | call to source() : | +| data.swift:170:12:170:12 | dataTainted23 | semmle.label | dataTainted23 | +| data.swift:174:2:174:2 | [post] dataTainted24 : | semmle.label | [post] dataTainted24 : | +| data.swift:174:35:174:42 | call to source() : | semmle.label | call to source() : | +| data.swift:175:12:175:12 | dataTainted24 | semmle.label | dataTainted24 | +| data.swift:178:22:178:29 | call to source() : | semmle.label | call to source() : | +| data.swift:179:15:179:15 | dataTainted25 : | semmle.label | dataTainted25 : | +| data.swift:179:15:179:38 | call to map(_:) : | semmle.label | call to map(_:) : | +| data.swift:180:12:180:12 | mapped | semmle.label | mapped | +| data.swift:183:22:183:29 | call to source() : | semmle.label | call to source() : | +| data.swift:184:16:184:16 | dataTainted26 : | semmle.label | dataTainted26 : | +| data.swift:184:16:184:80 | call to reduce(into:_:) : | semmle.label | call to reduce(into:_:) : | +| data.swift:185:12:185:12 | reduced | semmle.label | reduced | +| data.swift:189:2:189:2 | [post] dataTainted27 : | semmle.label | [post] dataTainted27 : | +| data.swift:189:35:189:42 | call to source() : | semmle.label | call to source() : | +| data.swift:190:12:190:12 | dataTainted27 | semmle.label | dataTainted27 | +| data.swift:194:2:194:2 | [post] dataTainted28 : | semmle.label | [post] dataTainted28 : | +| data.swift:194:45:194:52 | call to source() : | semmle.label | call to source() : | +| data.swift:195:12:195:12 | dataTainted28 | semmle.label | dataTainted28 | +| data.swift:198:2:198:2 | [post] dataTainted29 : | semmle.label | [post] dataTainted29 : | +| data.swift:198:45:198:52 | call to source() : | semmle.label | call to source() : | +| data.swift:199:12:199:12 | dataTainted29 | semmle.label | dataTainted29 | +| data.swift:202:2:202:2 | [post] dataTainted30 : | semmle.label | [post] dataTainted30 : | +| data.swift:202:45:202:52 | call to source() : | semmle.label | call to source() : | +| data.swift:203:12:203:12 | dataTainted30 | semmle.label | dataTainted30 | +| data.swift:207:2:207:2 | [post] dataTainted31 : | semmle.label | [post] dataTainted31 : | +| data.swift:207:45:207:52 | call to source() : | semmle.label | call to source() : | +| data.swift:208:12:208:12 | dataTainted31 | semmle.label | dataTainted31 | +| data.swift:212:2:212:2 | [post] dataTainted32 : | semmle.label | [post] dataTainted32 : | +| data.swift:212:37:212:44 | call to source() : | semmle.label | call to source() : | +| data.swift:213:12:213:12 | dataTainted32 | semmle.label | dataTainted32 | +| data.swift:217:2:217:2 | [post] dataTainted33 : | semmle.label | [post] dataTainted33 : | +| data.swift:217:37:217:44 | call to source() : | semmle.label | call to source() : | +| data.swift:218:12:218:12 | dataTainted33 | semmle.label | dataTainted33 | +| data.swift:221:22:221:29 | call to source() : | semmle.label | call to source() : | +| data.swift:222:12:222:12 | dataTainted34 : | semmle.label | dataTainted34 : | +| data.swift:222:12:222:35 | call to shuffled() | semmle.label | call to shuffled() | +| data.swift:225:22:225:29 | call to source() : | semmle.label | call to source() : | +| data.swift:227:12:227:12 | dataTainted35 : | semmle.label | dataTainted35 : | +| data.swift:227:12:227:46 | call to shuffled(using:) | semmle.label | call to shuffled(using:) | +| data.swift:230:22:230:29 | call to source() : | semmle.label | call to source() : | +| data.swift:231:12:231:12 | dataTainted36 : | semmle.label | dataTainted36 : | +| data.swift:231:12:231:46 | call to sorted(using:) | semmle.label | call to sorted(using:) | +| data.swift:234:22:234:29 | call to source() : | semmle.label | call to source() : | +| data.swift:235:12:235:12 | dataTainted37 : | semmle.label | dataTainted37 : | +| data.swift:235:12:235:44 | call to trimmingPrefix(_:) | semmle.label | call to trimmingPrefix(_:) | +| data.swift:238:22:238:29 | call to source() : | semmle.label | call to source() : | +| data.swift:239:12:239:12 | dataTainted38 : | semmle.label | dataTainted38 : | +| data.swift:239:12:239:54 | call to trimmingPrefix(while:) | semmle.label | call to trimmingPrefix(while:) | +| file://:0:0:0:0 | [summary] to write: argument 0 in copyBytes(to:) : | semmle.label | [summary] to write: argument 0 in copyBytes(to:) : | +| file://:0:0:0:0 | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : | semmle.label | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : | +| file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | semmle.label | [summary] to write: argument this in append(_:) : | +| file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | semmle.label | [summary] to write: argument this in append(_:) : | +| file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | semmle.label | [summary] to write: argument this in append(_:) : | +| file://:0:0:0:0 | [summary] to write: argument this in append(_:count:) : | semmle.label | [summary] to write: argument this in append(_:count:) : | +| file://:0:0:0:0 | [summary] to write: argument this in append(contentsOf:) : | semmle.label | [summary] to write: argument this in append(contentsOf:) : | +| file://:0:0:0:0 | [summary] to write: argument this in defineProperty(_:descriptor:) : | semmle.label | [summary] to write: argument this in defineProperty(_:descriptor:) : | +| file://:0:0:0:0 | [summary] to write: argument this in insert(_:at:) : | semmle.label | [summary] to write: argument this in insert(_:at:) : | +| file://:0:0:0:0 | [summary] to write: argument this in insert(contentsOf:at:) : | semmle.label | [summary] to write: argument this in insert(contentsOf:at:) : | +| file://:0:0:0:0 | [summary] to write: argument this in replace(_:with:maxReplacements:) : | semmle.label | [summary] to write: argument this in replace(_:with:maxReplacements:) : | +| file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | semmle.label | [summary] to write: argument this in replaceSubrange(_:with:) : | +| file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | semmle.label | [summary] to write: argument this in replaceSubrange(_:with:) : | +| file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:count:) : | semmle.label | [summary] to write: argument this in replaceSubrange(_:with:count:) : | +| file://:0:0:0:0 | [summary] to write: argument this in replacing(_:with:maxReplacements:) : | semmle.label | [summary] to write: argument this in replacing(_:with:maxReplacements:) : | +| file://:0:0:0:0 | [summary] to write: argument this in replacing(_:with:subrange:maxReplacements:) : | semmle.label | [summary] to write: argument this in replacing(_:with:subrange:maxReplacements:) : | +>>>>>>> 7ef2618758 (Update test expectations) | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:at:) : | semmle.label | [summary] to write: argument this in setValue(_:at:) : | | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:forProperty:) : | semmle.label | [summary] to write: argument this in setValue(_:forProperty:) : | | file://:0:0:0:0 | [summary] to write: return (return) in atIndex(_:) : | semmle.label | [summary] to write: return (return) in atIndex(_:) : | | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedData(options:) : | semmle.label | [summary] to write: return (return) in base64EncodedData(options:) : | | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedString(options:) : | semmle.label | [summary] to write: return (return) in base64EncodedString(options:) : | +<<<<<<< HEAD | file://:0:0:0:0 | [summary] to write: return (return) in base64Encoding() : | semmle.label | [summary] to write: return (return) in base64Encoding() : | | file://:0:0:0:0 | [summary] to write: return (return) in compressed(using:) : | semmle.label | [summary] to write: return (return) in compressed(using:) : | | file://:0:0:0:0 | [summary] to write: return (return) in dataWithContentsOfMappedFile(_:) : | semmle.label | [summary] to write: return (return) in dataWithContentsOfMappedFile(_:) : | @@ -419,18 +721,40 @@ nodes | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOfFile:options:) : | semmle.label | [summary] to write: return (return) in init(contentsOfFile:options:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOfMappedFile:) : | semmle.label | [summary] to write: return (return) in init(contentsOfMappedFile:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(data:) : | semmle.label | [summary] to write: return (return) in init(data:) : | +======= +| file://:0:0:0:0 | [summary] to write: return (return) in compactMap(_:) : | semmle.label | [summary] to write: return (return) in compactMap(_:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | semmle.label | [summary] to write: return (return) in flatMap(_:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | semmle.label | [summary] to write: return (return) in flatMap(_:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in forProperty(_:) : | semmle.label | [summary] to write: return (return) in forProperty(_:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | semmle.label | [summary] to write: return (return) in init(base64Encoded:options:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(bool:in:) : | semmle.label | [summary] to write: return (return) in init(bool:in:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | semmle.label | [summary] to write: return (return) in init(buffer:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | semmle.label | [summary] to write: return (return) in init(buffer:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(bytes:count:) : | semmle.label | [summary] to write: return (return) in init(bytes:count:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:count:deallocator:) : | semmle.label | [summary] to write: return (return) in init(bytesNoCopy:count:deallocator:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOf:options:) : | semmle.label | [summary] to write: return (return) in init(contentsOf:options:) : | +>>>>>>> 7ef2618758 (Update test expectations) | file://:0:0:0:0 | [summary] to write: return (return) in init(double:in:) : | semmle.label | [summary] to write: return (return) in init(double:in:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(int32:in:) : | semmle.label | [summary] to write: return (return) in init(int32:in:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(object:in:) : | semmle.label | [summary] to write: return (return) in init(object:in:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(point:in:) : | semmle.label | [summary] to write: return (return) in init(point:in:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(range:in:) : | semmle.label | [summary] to write: return (return) in init(range:in:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(rect:in:) : | semmle.label | [summary] to write: return (return) in init(rect:in:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(referencing:) : | semmle.label | [summary] to write: return (return) in init(referencing:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(size:in:) : | semmle.label | [summary] to write: return (return) in init(size:in:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | semmle.label | [summary] to write: return (return) in init(string:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | semmle.label | [summary] to write: return (return) in init(string:relativeTo:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | semmle.label | [summary] to write: return (return) in init(string:relativeTo:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(uInt32:in:) : | semmle.label | [summary] to write: return (return) in init(uInt32:in:) : | +<<<<<<< HEAD | file://:0:0:0:0 | [summary] to write: return (return) in subdata(with:) : | semmle.label | [summary] to write: return (return) in subdata(with:) : | +======= +| file://:0:0:0:0 | [summary] to write: return (return) in map(_:) : | semmle.label | [summary] to write: return (return) in map(_:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in reduce(into:_:) : | semmle.label | [summary] to write: return (return) in reduce(into:_:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in shuffled() : | semmle.label | [summary] to write: return (return) in shuffled() : | +| file://:0:0:0:0 | [summary] to write: return (return) in shuffled(using:) : | semmle.label | [summary] to write: return (return) in shuffled(using:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in sorted(using:) : | semmle.label | [summary] to write: return (return) in sorted(using:) : | +>>>>>>> 7ef2618758 (Update test expectations) | file://:0:0:0:0 | [summary] to write: return (return) in toArray() : | semmle.label | [summary] to write: return (return) in toArray() : | | file://:0:0:0:0 | [summary] to write: return (return) in toBool() : | semmle.label | [summary] to write: return (return) in toBool() : | | file://:0:0:0:0 | [summary] to write: return (return) in toDate() : | semmle.label | [summary] to write: return (return) in toDate() : | @@ -446,6 +770,7 @@ nodes | file://:0:0:0:0 | [summary] to write: return (return) in toSize() : | semmle.label | [summary] to write: return (return) in toSize() : | | file://:0:0:0:0 | [summary] to write: return (return) in toString() : | semmle.label | [summary] to write: return (return) in toString() : | | file://:0:0:0:0 | [summary] to write: return (return) in toUInt32() : | semmle.label | [summary] to write: return (return) in toUInt32() : | +<<<<<<< HEAD | nsdata.swift:22:9:22:9 | self : | semmle.label | self : | | nsdata.swift:23:9:23:9 | self : | semmle.label | self : | | nsdata.swift:24:5:24:50 | [summary param] 0 in init(bytes:length:) : | semmle.label | [summary param] 0 in init(bytes:length:) : | @@ -581,6 +906,10 @@ nodes | nsmutabledata.swift:48:33:48:40 | call to source() : | semmle.label | call to source() : | | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 : | semmle.label | nsMutableDataTainted6 : | | nsmutabledata.swift:49:15:49:37 | .mutableBytes | semmle.label | .mutableBytes | +======= +| file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(_:) : | semmle.label | [summary] to write: return (return) in trimmingPrefix(_:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(while:) : | semmle.label | [summary] to write: return (return) in trimmingPrefix(while:) : | +>>>>>>> 7ef2618758 (Update test expectations) | string.swift:5:11:5:18 | call to source() : | semmle.label | call to source() : | | string.swift:7:13:7:13 | "..." | semmle.label | "..." | | string.swift:9:13:9:13 | "..." | semmle.label | "..." | @@ -782,6 +1111,7 @@ nodes | webview.swift:97:17:97:17 | s : | semmle.label | s : | | webview.swift:98:10:98:10 | v3 | semmle.label | v3 | subpaths +<<<<<<< HEAD | nsdata.swift:57:40:57:47 | call to source() : | nsdata.swift:24:5:24:50 | [summary param] 0 in init(bytes:length:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytes:length:) : | nsdata.swift:57:26:57:80 | call to init(bytes:length:) : | | nsdata.swift:60:46:60:53 | call to source() : | nsdata.swift:25:5:25:68 | [summary param] 0 in init(bytesNoCopy:length:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:length:) : | nsdata.swift:60:26:60:93 | call to init(bytesNoCopy:length:) : | | nsdata.swift:63:46:63:53 | call to source() : | nsdata.swift:26:5:26:130 | [summary param] 0 in init(bytesNoCopy:length:deallocator:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:length:deallocator:) : | nsdata.swift:63:26:63:111 | call to init(bytesNoCopy:length:deallocator:) : | @@ -815,6 +1145,42 @@ subpaths | nsmutabledata.swift:40:66:40:73 | call to source() : | nsmutabledata.swift:17:5:17:121 | [summary param] 1 in replaceBytes(in:withBytes:length:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceBytes(in:withBytes:length:) : | nsmutabledata.swift:40:5:40:5 | [post] nsMutableDataTainted4 : | | nsmutabledata.swift:44:35:44:42 | call to source() : | nsmutabledata.swift:18:5:18:33 | [summary param] 0 in setData(_:) : | file://:0:0:0:0 | [summary] to write: argument this in setData(_:) : | nsmutabledata.swift:44:5:44:5 | [post] nsMutableDataTainted5 : | | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 : | nsmutabledata.swift:13:9:13:9 | self : | file://:0:0:0:0 | .mutableBytes : | nsmutabledata.swift:49:15:49:37 | .mutableBytes | +======= +| data.swift:79:41:79:48 | call to source() : | data.swift:17:2:17:66 | [summary param] 0 in init(base64Encoded:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | data.swift:79:21:79:71 | call to init(base64Encoded:options:) : | +| data.swift:83:34:83:41 | call to source() : | data.swift:18:2:18:61 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | data.swift:83:21:83:73 | call to init(buffer:) : | +| data.swift:85:34:85:41 | call to source() : | data.swift:19:2:19:62 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | data.swift:85:21:85:74 | call to init(buffer:) : | +| data.swift:89:33:89:40 | call to source() : | data.swift:20:2:20:45 | [summary param] 0 in init(bytes:count:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytes:count:) : | data.swift:89:21:89:72 | call to init(bytes:count:) : | +| data.swift:93:39:93:46 | call to source() : | data.swift:21:2:21:82 | [summary param] 0 in init(bytesNoCopy:count:deallocator:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:count:deallocator:) : | data.swift:93:21:93:114 | call to init(bytesNoCopy:count:deallocator:) : | +| data.swift:97:38:97:45 | call to source() : | data.swift:22:2:22:50 | [summary param] 0 in init(contentsOf:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOf:options:) : | data.swift:97:21:97:67 | call to init(contentsOf:options:) : | +| data.swift:101:39:101:46 | call to source() : | data.swift:23:2:23:29 | [summary param] 0 in init(referencing:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(referencing:) : | data.swift:101:21:101:58 | call to init(referencing:) : | +| data.swift:106:23:106:30 | call to source() : | data.swift:24:2:24:24 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | data.swift:106:2:106:2 | [post] dataTainted10 : | +| data.swift:110:23:110:30 | call to source() : | data.swift:25:2:25:25 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | data.swift:110:2:110:2 | [post] dataTainted11 : | +| data.swift:114:23:114:30 | call to source() : | data.swift:26:2:26:63 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | data.swift:114:2:114:2 | [post] dataTainted12 : | +| data.swift:119:23:119:30 | call to source() : | data.swift:27:2:27:52 | [summary param] 0 in append(_:count:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:count:) : | data.swift:119:2:119:2 | [post] dataTainted13 : | +| data.swift:124:35:124:42 | call to source() : | data.swift:28:2:28:36 | [summary param] 0 in append(contentsOf:) : | file://:0:0:0:0 | [summary] to write: argument this in append(contentsOf:) : | data.swift:124:2:124:2 | [post] dataTainted14 : | +| data.swift:129:12:129:12 | dataTainted15 : | data.swift:30:2:30:88 | [summary param] this in base64EncodedData(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedData(options:) : | data.swift:129:12:129:55 | call to base64EncodedData(options:) | +| data.swift:133:12:133:12 | dataTainted16 : | data.swift:31:2:31:86 | [summary param] this in base64EncodedString(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedString(options:) : | data.swift:133:12:133:57 | call to base64EncodedString(options:) | +| data.swift:137:29:137:29 | dataTainted17 : | data.swift:32:2:32:99 | [summary param] this in compactMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in compactMap(_:) : | data.swift:137:29:137:72 | call to compactMap(_:) : | +| data.swift:143:2:143:2 | dataTainted18 : | data.swift:33:2:33:53 | [summary param] this in copyBytes(to:) : | file://:0:0:0:0 | [summary] to write: argument 0 in copyBytes(to:) : | data.swift:143:30:143:30 | [post] pointerTainted18 : | +| data.swift:160:19:160:19 | dataTainted21 : | data.swift:36:2:36:137 | [summary param] this in flatMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | data.swift:160:19:160:74 | call to flatMap(_:) : | +| data.swift:164:20:164:20 | dataTainted22 : | data.swift:37:2:37:97 | [summary param] this in flatMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | data.swift:164:20:164:60 | call to flatMap(_:) : | +| data.swift:169:23:169:30 | call to source() : | data.swift:38:2:38:34 | [summary param] 0 in insert(_:at:) : | file://:0:0:0:0 | [summary] to write: argument this in insert(_:at:) : | data.swift:169:2:169:2 | [post] dataTainted23 : | +| data.swift:174:35:174:42 | call to source() : | data.swift:39:2:39:83 | [summary param] 0 in insert(contentsOf:at:) : | file://:0:0:0:0 | [summary] to write: argument this in insert(contentsOf:at:) : | data.swift:174:2:174:2 | [post] dataTainted24 : | +| data.swift:179:15:179:15 | dataTainted25 : | data.swift:40:2:40:50 | [summary param] this in map(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in map(_:) : | data.swift:179:15:179:38 | call to map(_:) : | +| data.swift:184:16:184:16 | dataTainted26 : | data.swift:41:2:41:115 | [summary param] this in reduce(into:_:) : | file://:0:0:0:0 | [summary] to write: return (return) in reduce(into:_:) : | data.swift:184:16:184:80 | call to reduce(into:_:) : | +| data.swift:189:35:189:42 | call to source() : | data.swift:42:2:42:180 | [summary param] 1 in replace(_:with:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replace(_:with:maxReplacements:) : | data.swift:189:2:189:2 | [post] dataTainted27 : | +| data.swift:194:45:194:52 | call to source() : | data.swift:43:2:43:58 | [summary param] 1 in replaceSubrange(_:with:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | data.swift:194:2:194:2 | [post] dataTainted28 : | +| data.swift:198:45:198:52 | call to source() : | data.swift:44:2:44:151 | [summary param] 1 in replaceSubrange(_:with:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | data.swift:198:2:198:2 | [post] dataTainted29 : | +| data.swift:202:45:202:52 | call to source() : | data.swift:44:2:44:151 | [summary param] 1 in replaceSubrange(_:with:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | data.swift:202:2:202:2 | [post] dataTainted30 : | +| data.swift:207:45:207:52 | call to source() : | data.swift:46:2:46:82 | [summary param] 1 in replaceSubrange(_:with:count:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:count:) : | data.swift:207:2:207:2 | [post] dataTainted31 : | +| data.swift:212:37:212:44 | call to source() : | data.swift:48:2:48:214 | [summary param] 1 in replacing(_:with:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replacing(_:with:maxReplacements:) : | data.swift:212:2:212:2 | [post] dataTainted32 : | +| data.swift:217:37:217:44 | call to source() : | data.swift:49:2:49:236 | [summary param] 1 in replacing(_:with:subrange:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replacing(_:with:subrange:maxReplacements:) : | data.swift:217:2:217:2 | [post] dataTainted33 : | +| data.swift:222:12:222:12 | dataTainted34 : | data.swift:50:2:50:41 | [summary param] this in shuffled() : | file://:0:0:0:0 | [summary] to write: return (return) in shuffled() : | data.swift:222:12:222:35 | call to shuffled() | +| data.swift:227:12:227:12 | dataTainted35 : | data.swift:51:2:51:58 | [summary param] this in shuffled(using:) : | file://:0:0:0:0 | [summary] to write: return (return) in shuffled(using:) : | data.swift:227:12:227:46 | call to shuffled(using:) | +| data.swift:231:12:231:12 | dataTainted36 : | data.swift:52:2:52:132 | [summary param] this in sorted(using:) : | file://:0:0:0:0 | [summary] to write: return (return) in sorted(using:) : | data.swift:231:12:231:46 | call to sorted(using:) | +| data.swift:235:12:235:12 | dataTainted37 : | data.swift:53:2:53:123 | [summary param] this in trimmingPrefix(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(_:) : | data.swift:235:12:235:44 | call to trimmingPrefix(_:) | +| data.swift:239:12:239:12 | dataTainted38 : | data.swift:54:2:54:72 | [summary param] this in trimmingPrefix(while:) : | file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(while:) : | data.swift:239:12:239:54 | call to trimmingPrefix(while:) | +>>>>>>> 7ef2618758 (Update test expectations) | url.swift:59:31:59:31 | tainted : | url.swift:8:2:8:25 | [summary param] 0 in init(string:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | url.swift:59:19:59:38 | call to init(string:) : | | url.swift:83:24:83:24 | tainted : | url.swift:9:2:9:43 | [summary param] 0 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | url.swift:83:12:83:48 | call to init(string:relativeTo:) : | | url.swift:86:43:86:43 | urlTainted : | url.swift:9:2:9:43 | [summary param] 1 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | url.swift:86:12:86:53 | call to init(string:relativeTo:) : | @@ -865,6 +1231,7 @@ subpaths | webview.swift:93:17:93:17 | s : | webview.swift:43:5:43:38 | [summary param] 0 in setValue(_:at:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:at:) : | webview.swift:93:5:93:5 | [post] v2 : | | webview.swift:97:17:97:17 | s : | webview.swift:44:5:44:48 | [summary param] 0 in setValue(_:forProperty:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:forProperty:) : | webview.swift:97:5:97:5 | [post] v3 : | #select +<<<<<<< HEAD | nsdata.swift:58:15:58:15 | nsDataTainted1 | nsdata.swift:57:40:57:47 | call to source() : | nsdata.swift:58:15:58:15 | nsDataTainted1 | result | | nsdata.swift:61:15:61:15 | nsDataTainted2 | nsdata.swift:60:46:60:53 | call to source() : | nsdata.swift:61:15:61:15 | nsDataTainted2 | result | | nsdata.swift:64:15:64:15 | nsDataTainted3 | nsdata.swift:63:46:63:53 | call to source() : | nsdata.swift:64:15:64:15 | nsDataTainted3 | result | @@ -899,6 +1266,42 @@ subpaths | nsmutabledata.swift:41:15:41:15 | nsMutableDataTainted4 | nsmutabledata.swift:40:66:40:73 | call to source() : | nsmutabledata.swift:41:15:41:15 | nsMutableDataTainted4 | result | | nsmutabledata.swift:45:15:45:15 | nsMutableDataTainted5 | nsmutabledata.swift:44:35:44:42 | call to source() : | nsmutabledata.swift:45:15:45:15 | nsMutableDataTainted5 | result | | nsmutabledata.swift:49:15:49:37 | .mutableBytes | nsmutabledata.swift:48:33:48:40 | call to source() : | nsmutabledata.swift:49:15:49:37 | .mutableBytes | result | +======= +| data.swift:80:12:80:12 | dataTainted3 | data.swift:79:41:79:48 | call to source() : | data.swift:80:12:80:12 | dataTainted3 | result | +| data.swift:84:12:84:12 | dataTainted4 | data.swift:83:34:83:41 | call to source() : | data.swift:84:12:84:12 | dataTainted4 | result | +| data.swift:86:12:86:12 | dataTainted5 | data.swift:85:34:85:41 | call to source() : | data.swift:86:12:86:12 | dataTainted5 | result | +| data.swift:90:12:90:12 | dataTainted6 | data.swift:89:33:89:40 | call to source() : | data.swift:90:12:90:12 | dataTainted6 | result | +| data.swift:94:12:94:12 | dataTainted7 | data.swift:93:39:93:46 | call to source() : | data.swift:94:12:94:12 | dataTainted7 | result | +| data.swift:98:12:98:12 | dataTainted8 | data.swift:97:38:97:45 | call to source() : | data.swift:98:12:98:12 | dataTainted8 | result | +| data.swift:102:12:102:12 | dataTainted9 | data.swift:101:39:101:46 | call to source() : | data.swift:102:12:102:12 | dataTainted9 | result | +| data.swift:107:12:107:12 | dataTainted10 | data.swift:106:23:106:30 | call to source() : | data.swift:107:12:107:12 | dataTainted10 | result | +| data.swift:111:12:111:12 | dataTainted11 | data.swift:110:23:110:30 | call to source() : | data.swift:111:12:111:12 | dataTainted11 | result | +| data.swift:115:12:115:12 | dataTainted12 | data.swift:114:23:114:30 | call to source() : | data.swift:115:12:115:12 | dataTainted12 | result | +| data.swift:120:12:120:12 | dataTainted13 | data.swift:119:23:119:30 | call to source() : | data.swift:120:12:120:12 | dataTainted13 | result | +| data.swift:125:12:125:12 | dataTainted14 | data.swift:124:35:124:42 | call to source() : | data.swift:125:12:125:12 | dataTainted14 | result | +| data.swift:129:12:129:55 | call to base64EncodedData(options:) | data.swift:128:22:128:29 | call to source() : | data.swift:129:12:129:55 | call to base64EncodedData(options:) | result | +| data.swift:133:12:133:57 | call to base64EncodedString(options:) | data.swift:132:22:132:29 | call to source() : | data.swift:133:12:133:57 | call to base64EncodedString(options:) | result | +| data.swift:138:12:138:12 | compactMapped | data.swift:136:22:136:29 | call to source() : | data.swift:138:12:138:12 | compactMapped | result | +| data.swift:144:12:144:12 | pointerTainted18 | data.swift:141:22:141:29 | call to source() : | data.swift:144:12:144:12 | pointerTainted18 | result | +| data.swift:161:12:161:12 | flatMapped | data.swift:159:22:159:29 | call to source() : | data.swift:161:12:161:12 | flatMapped | result | +| data.swift:165:12:165:12 | flatMapped2 | data.swift:163:22:163:29 | call to source() : | data.swift:165:12:165:12 | flatMapped2 | result | +| data.swift:170:12:170:12 | dataTainted23 | data.swift:169:23:169:30 | call to source() : | data.swift:170:12:170:12 | dataTainted23 | result | +| data.swift:175:12:175:12 | dataTainted24 | data.swift:174:35:174:42 | call to source() : | data.swift:175:12:175:12 | dataTainted24 | result | +| data.swift:180:12:180:12 | mapped | data.swift:178:22:178:29 | call to source() : | data.swift:180:12:180:12 | mapped | result | +| data.swift:185:12:185:12 | reduced | data.swift:183:22:183:29 | call to source() : | data.swift:185:12:185:12 | reduced | result | +| data.swift:190:12:190:12 | dataTainted27 | data.swift:189:35:189:42 | call to source() : | data.swift:190:12:190:12 | dataTainted27 | result | +| data.swift:195:12:195:12 | dataTainted28 | data.swift:194:45:194:52 | call to source() : | data.swift:195:12:195:12 | dataTainted28 | result | +| data.swift:199:12:199:12 | dataTainted29 | data.swift:198:45:198:52 | call to source() : | data.swift:199:12:199:12 | dataTainted29 | result | +| data.swift:203:12:203:12 | dataTainted30 | data.swift:202:45:202:52 | call to source() : | data.swift:203:12:203:12 | dataTainted30 | result | +| data.swift:208:12:208:12 | dataTainted31 | data.swift:207:45:207:52 | call to source() : | data.swift:208:12:208:12 | dataTainted31 | result | +| data.swift:213:12:213:12 | dataTainted32 | data.swift:212:37:212:44 | call to source() : | data.swift:213:12:213:12 | dataTainted32 | result | +| data.swift:218:12:218:12 | dataTainted33 | data.swift:217:37:217:44 | call to source() : | data.swift:218:12:218:12 | dataTainted33 | result | +| data.swift:222:12:222:35 | call to shuffled() | data.swift:221:22:221:29 | call to source() : | data.swift:222:12:222:35 | call to shuffled() | result | +| data.swift:227:12:227:46 | call to shuffled(using:) | data.swift:225:22:225:29 | call to source() : | data.swift:227:12:227:46 | call to shuffled(using:) | result | +| data.swift:231:12:231:46 | call to sorted(using:) | data.swift:230:22:230:29 | call to source() : | data.swift:231:12:231:46 | call to sorted(using:) | result | +| data.swift:235:12:235:44 | call to trimmingPrefix(_:) | data.swift:234:22:234:29 | call to source() : | data.swift:235:12:235:44 | call to trimmingPrefix(_:) | result | +| data.swift:239:12:239:54 | call to trimmingPrefix(while:) | data.swift:238:22:238:29 | call to source() : | data.swift:239:12:239:54 | call to trimmingPrefix(while:) | result | +>>>>>>> 7ef2618758 (Update test expectations) | string.swift:7:13:7:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:7:13:7:13 | "..." | result | | string.swift:9:13:9:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:9:13:9:13 | "..." | result | | string.swift:11:13:11:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:11:13:11:13 | "..." | result | From 6a8b9fde788225afe8c9f70adf919893dfbca231 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Mon, 21 Nov 2022 16:16:58 +0100 Subject: [PATCH 511/796] Add data flowsources test --- .../dataflow/flowsources/FlowSources.expected | 2 ++ .../dataflow/flowsources/data.swift | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 swift/ql/test/library-tests/dataflow/flowsources/data.swift diff --git a/swift/ql/test/library-tests/dataflow/flowsources/FlowSources.expected b/swift/ql/test/library-tests/dataflow/flowsources/FlowSources.expected index 01c18633b5d..9aeb5661a9e 100644 --- a/swift/ql/test/library-tests/dataflow/flowsources/FlowSources.expected +++ b/swift/ql/test/library-tests/dataflow/flowsources/FlowSources.expected @@ -7,6 +7,8 @@ | nsdata.swift:18:17:18:40 | call to init(contentsOf:) | external | | nsdata.swift:19:17:19:17 | call to init(contentsOf:options:) | external | | nsdata.swift:19:17:19:53 | call to init(contentsOf:options:) | external | +| data.swift:18:20:18:20 | call to init(contentsOf:options:) | external | +| data.swift:18:20:18:54 | call to init(contentsOf:options:) | external | | string.swift:56:21:56:21 | call to init(contentsOf:) | external | | string.swift:56:21:56:44 | call to init(contentsOf:) | external | | string.swift:57:21:57:21 | call to init(contentsOf:encoding:) | external | diff --git a/swift/ql/test/library-tests/dataflow/flowsources/data.swift b/swift/ql/test/library-tests/dataflow/flowsources/data.swift new file mode 100644 index 00000000000..eef374b62a9 --- /dev/null +++ b/swift/ql/test/library-tests/dataflow/flowsources/data.swift @@ -0,0 +1,19 @@ +// --- stubs --- + +struct URL +{ + init?(string: String) {} +} + + +struct Data { + struct ReadingOptions : OptionSet { let rawValue: Int } + init(contentsOf: URL, options: ReadingOptions) {} +} + +// --- tests --- + +func testData() { + let url = URL(string: "http://example.com/") + let data = try Data(contentsOf: url!, options: []) // SOURCE +} From 25354d2dd888108c00c22b3b7a9ee2f9f548cacf Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Wed, 23 Nov 2022 12:18:32 +0100 Subject: [PATCH 512/796] Apply code review suggestions --- .../swift/frameworks/StandardLibrary/Data.qll | 6 +- .../library-tests/dataflow/taint/data.swift | 126 ++++++++++-------- 2 files changed, 79 insertions(+), 53 deletions(-) diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Data.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Data.qll index 0e27c0824dc..420a5ebeb52 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Data.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Data.qll @@ -37,9 +37,13 @@ private class DataSummaries extends SummaryModelCsv { ";Data;true;replaceSubrange(_:with:count:);;;Argument[1];Argument[-1];taint", ";Data;true;replacing(_:with:maxReplacements:);;;Argument[1];Argument[-1];taint", ";Data;true;replacing(_:with:subrange:maxReplacements:);;;Argument[1];Argument[-1];taint", + // TODO: this should be implemented by a model of BidirectionalCollection + // ";Data;true;reversed();;;Argument[-1];ReturnValue;taint", + ";Data;true;sorted();;;Argument[-1];ReturnValue;taint", + ";Data;true;sorted(by:);;;Argument[-1];ReturnValue;taint", + ";Data;true;sorted(using:);;;Argument[-1];ReturnValue;taint", ";Data;true;shuffled();;;Argument[-1];ReturnValue;taint", ";Data;true;shuffled(using:);;;Argument[-1];ReturnValue;taint", - ";Data;true;sorted(using:);;;Argument[-1];ReturnValue;taint", ";Data;true;trimmingPrefix(_:);;;Argument[-1];ReturnValue;taint", ";Data;true;trimmingPrefix(while:);;;Argument[-1];ReturnValue;taint" ] diff --git a/swift/ql/test/library-tests/dataflow/taint/data.swift b/swift/ql/test/library-tests/dataflow/taint/data.swift index ba53694cf98..2fdc4e1c949 100644 --- a/swift/ql/test/library-tests/dataflow/taint/data.swift +++ b/swift/ql/test/library-tests/dataflow/taint/data.swift @@ -6,13 +6,21 @@ class NSData {} protocol SortComparator { associatedtype Compared } -struct Data + +struct Data : BidirectionalCollection { struct Base64EncodingOptions : OptionSet { let rawValue: Int } struct Base64DecodingOptions : OptionSet { let rawValue: Int } - enum Deallocator { case none } struct ReadingOptions : OptionSet { let rawValue: Int } + enum Deallocator { case none } typealias Index = Int + typealias Element = UInt8 + var startIndex: Self.Index { get { return 0 } } + var endIndex: Self.Index { get { return 0 } } + func index(after: Self.Index) -> Self.Index { return 0 } + func index(before: Self.Index) -> Self.Index { return 0 } + subscript(position: Self.Index) -> Self.Element { get { return 0 } } + init(_ elements: S) {} init(base64Encoded: Data, options: Data.Base64DecodingOptions) {} init(buffer: UnsafeBufferPointer) {} @@ -47,9 +55,11 @@ struct Data func replaceSubrange(_: R, with: C) where C : Collection, R : RangeExpression, UInt8 == C.Element, Int == R.Bound {} func replacing(_: C, with: Replacement, maxReplacements: Int = .max) -> Data where C : Collection, Replacement : Collection, UInt8 == C.Element, C.Element == Replacement.Element { return Data("") } func replacing(_: C, with: Replacement, subrange: Range, maxReplacements: Int = .max) -> Data where C : Collection, Replacement : Collection, UInt8 == C.Element, C.Element == Replacement.Element { return Data("") } + func sorted() -> [UInt8] { return [] } + func sorted(by: (UInt8, UInt8) throws -> Bool) rethrows -> [UInt8] { return [] } + func sorted(using: Comparator) -> [UInt8] where Comparator : SortComparator, UInt8 == Comparator.Compared { return [] } func shuffled() -> [UInt8] { return [] } func shuffled(using: inout T) -> [UInt8] { return [] } - func sorted(using: Comparator) -> [UInt8] where Comparator : SortComparator, UInt8 == Comparator.Compared { return [] } func trimmingPrefix(_ prefix: Prefix) -> Data where Prefix : Sequence, UInt8 == Prefix.Element { return Data("") } func trimmingPrefix(while: (UInt8) -> Bool) -> Data { return Data("") } } @@ -72,170 +82,182 @@ func taintThroughData() { let dataTainted2 = Data(dataTainted) sink(arg: dataClean) - sink(arg: dataTainted) // $ MISSING: tainted=71 - sink(arg: dataTainted2) // $ MISSING: tainted=71 + sink(arg: dataTainted) // $ MISSING: tainted=81 + sink(arg: dataTainted2) // $ MISSING: tainted=81 // ";Data;true;init(base64Encoded:options:);;;Argument[0];ReturnValue;taint", let dataTainted3 = Data(base64Encoded: source() as! Data, options: []) - sink(arg: dataTainted3) // $ tainted=79 + sink(arg: dataTainted3) // $ tainted=89 // ";Data;true;init(buffer:);;;Argument[0];ReturnValue;taint", let dataTainted4 = Data(buffer: source() as! UnsafeBufferPointer) - sink(arg: dataTainted4) // $ tainted=83 + sink(arg: dataTainted4) // $ tainted=93 let dataTainted5 = Data(buffer: source() as! UnsafeMutablePointer) - sink(arg: dataTainted5) // $ tainted=85 + sink(arg: dataTainted5) // $ tainted=95 // ";Data;true;init(bytes:count:);;;Argument[0];ReturnValue;taint", let dataTainted6 = Data(bytes: source() as! UnsafeRawPointer, count: 0) - sink(arg: dataTainted6) // $ tainted=89 + sink(arg: dataTainted6) // $ tainted=99 // ";Data;true;init(bytesNoCopy:count:deallocator:);;;Argument[0];ReturnValue;taint", let dataTainted7 = Data(bytesNoCopy: source() as! UnsafeRawPointer, count: 0, deallocator: Data.Deallocator.none) - sink(arg: dataTainted7) // $ tainted=93 + sink(arg: dataTainted7) // $ tainted=103 // ";Data;true;init(contentsOf:options:);;;Argument[0];ReturnValue;taint", - let dataTainted8 = Data(contentsOf: source() as! URL, options: []) - sink(arg: dataTainted8) // $ tainted=97 + let urlTainted8 = source() as! URL + let dataTainted8 = Data(contentsOf: urlTainted8, options: []) + sink(arg: dataTainted8) // $ tainted=107 // ";Data;true;init(referencing:);;;Argument[0];ReturnValue;taint", let dataTainted9 = Data(referencing: source() as! NSData) - sink(arg: dataTainted9) // $ tainted=101 + sink(arg: dataTainted9) // $ tainted=112 // ";Data;true;append(_:);;;Argument[0];Argument[-1];taint", let dataTainted10 = Data("") dataTainted10.append(source() as! Data) - sink(arg: dataTainted10) // $ tainted=106 + sink(arg: dataTainted10) // $ tainted=117 let dataTainted11 = Data("") dataTainted11.append(source() as! UInt8) - sink(arg: dataTainted11) // $ tainted=110 + sink(arg: dataTainted11) // $ tainted=121 let dataTainted12 = Data("") dataTainted12.append(source() as! UnsafeBufferPointer) - sink(arg: dataTainted12) // $ tainted=114 + sink(arg: dataTainted12) // $ tainted=125 // ";Data;true;append(_:count:);;;Argument[0];Argument[-1];taint", let dataTainted13 = Data("") dataTainted13.append(source() as! UnsafePointer, count: 0) - sink(arg: dataTainted13) // $ tainted=119 + sink(arg: dataTainted13) // $ tainted=130 // ";Data;true;append(contentsOf:);;;Argument[0];Argument[-1];taint", let dataTainted14 = Data("") dataTainted14.append(contentsOf: source() as! [UInt8]) - sink(arg: dataTainted14) // $ tainted=124 + sink(arg: dataTainted14) // $ tainted=135 // ";Data;true;base64EncodedData(options:);;;Argument[-1];ReturnValue;taint", let dataTainted15 = source() as! Data - sink(arg: dataTainted15.base64EncodedData(options: [])) // $ tainted=128 + sink(arg: dataTainted15.base64EncodedData(options: [])) // $ tainted=139 // ";Data;true;base64EncodedString(options:);;;Argument[-1];ReturnValue;taint", let dataTainted16 = source() as! Data - sink(arg: dataTainted16.base64EncodedString(options: [])) // $ tainted=132 + sink(arg: dataTainted16.base64EncodedString(options: [])) // $ tainted=143 // ";Data;true;compactMap(_:);;;Argument[-1];ReturnValue;taint", let dataTainted17 = source() as! Data let compactMapped: [Int] = dataTainted17.compactMap { str in Int(str) } - sink(arg: compactMapped) // $ tainted=136 + sink(arg: compactMapped) // $ tainted=147 // ";Data;true;copyBytes(to:);;;Argument[-1];Argument[0];taint", let dataTainted18 = source() as! Data let pointerTainted18 = UnsafeMutableRawBufferPointer.allocate(byteCount: 0, alignment: 0) dataTainted18.copyBytes(to: pointerTainted18) - sink(arg: pointerTainted18) // $ tainted=141 + sink(arg: pointerTainted18) // $ tainted=152 // ";Data;true;copyBytes(to:count:);;;Argument[-1];Argument[0];taint", let dataTainted19 = source() as! Data let pointerTainted19 = UnsafeMutablePointer.allocate(capacity: 0) dataTainted19.copyBytes(to: pointerTainted19, count: 0) - sink(arg: pointerTainted19) // $ MISSING: tainted=147 + sink(arg: pointerTainted19) // $ MISSING: tainted=158 // ";Data;true;copyBytes(to:from:);;;Argument[-1];Argument[0];taint", let dataTainted20 = source() as! Data let pointerTainted20 = UnsafeMutablePointer.allocate(capacity: 0) dataTainted20.copyBytes(to: pointerTainted20, from: 0..<1) - sink(arg: pointerTainted20) // $ MISSING: tainted=153 + sink(arg: pointerTainted20) // $ MISSING: tainted=164 // ";Data;true;flatMap(_:);;;Argument[-1];ReturnValue;taint", let dataTainted21 = source() as! Data let flatMapped = dataTainted21.flatMap { Array(repeating: $0, count: 0) } - sink(arg: flatMapped) // $ tainted=159 + sink(arg: flatMapped) // $ tainted=170 let dataTainted22 = source() as! Data let flatMapped2 = dataTainted22.flatMap { str in Int(str) } - sink(arg: flatMapped2) // $ tainted=163 + sink(arg: flatMapped2) // $ tainted=174 // ";Data;true;insert(_:at:);;;Argument[0];Argument[-1];taint", let dataTainted23 = Data("") dataTainted23.insert(source() as! UInt8, at: 0) - sink(arg: dataTainted23) // $ tainted=169 + sink(arg: dataTainted23) // $ tainted=180 // ";Data;true;insert(contentsOf:at:);;;Argument[0];Argument[-1];taint", let dataTainted24 = Data("") dataTainted24.insert(contentsOf: source() as! [UInt8], at: 0) - sink(arg: dataTainted24) // $ tainted=174 + sink(arg: dataTainted24) // $ tainted=185 // ";Data;true;map(_:);;;Argument[-1];ReturnValue;taint", let dataTainted25 = source() as! Data let mapped = dataTainted25.map { $0 } - sink(arg: mapped) // $ tainted=178 + sink(arg: mapped) // $ tainted=189 // ";Data;true;reduce(into:_:);;;Argument[-1];ReturnValue;taint", let dataTainted26 = source() as! Data let reduced = dataTainted26.reduce(into: [:]) { c, i in c[i, default: 0] += 1 } - sink(arg: reduced) // $ tainted=183 + sink(arg: reduced) // $ tainted=194 // ";Data;true;replace(_:with:maxReplacements:);;;Argument[1];Argument[-1];taint", let dataTainted27 = Data("") dataTainted27.replace([0], with: source() as! [UInt8], maxReplacements: .max) - sink(arg: dataTainted27) // $ tainted=189 + sink(arg: dataTainted27) // $ tainted=200 // ";Data;true;replaceSubrange(_:with:);;;Argument[1];Argument[-1];taint", let dataTainted28 = Data("") dataTainted28.replaceSubrange(1..<3, with: source() as! Data) - sink(arg: dataTainted28) // $ tainted=194 + sink(arg: dataTainted28) // $ tainted=205 let dataTainted29 = Data("") dataTainted29.replaceSubrange(1..<3, with: source() as! [UInt8]) - sink(arg: dataTainted29) // $ tainted=198 + sink(arg: dataTainted29) // $ tainted=209 let dataTainted30 = Data("") dataTainted30.replaceSubrange(1..<3, with: source() as! UnsafeBufferPointer) - sink(arg: dataTainted30) // $ tainted=202 + sink(arg: dataTainted30) // $ tainted=213 // ";Data;true;replaceSubrange(_:with:count:);;;Argument[1];Argument[-1];taint", let dataTainted31 = Data("") dataTainted31.replaceSubrange(1..<3, with: source() as! UnsafeRawPointer, count: 0) - sink(arg: dataTainted31) // $ tainted=207 + sink(arg: dataTainted31) // $ tainted=218 // ";Data;true;replacing(_:with:maxReplacements:);;;Argument[1];Argument[-1];taint", let dataTainted32 = Data("") - dataTainted32.replacing([0], with: source() as! [UInt8], maxReplacements: 0) - sink(arg: dataTainted32) // $ tainted=212 + let _ = dataTainted32.replacing([0], with: source() as! [UInt8], maxReplacements: 0) + sink(arg: dataTainted32) // $ tainted=223 // ";Data;true;replacing(_:with:subrange:maxReplacements:);;;Argument[1];Argument[-1];taint", let dataTainted33 = Data("") - dataTainted33.replacing([0], with: source() as! [UInt8], subrange: 1..<3, maxReplacements: 0) - sink(arg: dataTainted33) // $ tainted=217 + let _ = dataTainted33.replacing([0], with: source() as! [UInt8], subrange: 1..<3, maxReplacements: 0) + sink(arg: dataTainted33) // $ tainted=228 - // ";Data;true;shuffled();;;Argument[-1];ReturnValue;taint", + // ";Data;true;reversed();;;Argument[-1];ReturnValue;taint", let dataTainted34 = source() as! Data - sink(arg: dataTainted34.shuffled()) // $ tainted=221 - - // ";Data;true;shuffled(using:);;;Argument[-1];ReturnValue;taint", + sink(arg: dataTainted34.reversed()) // $ MISSING: tainted=232 // Needs models for BidirectionalCollection + + // ";Data;true;sorted();;;Argument[-1];ReturnValue;taint", let dataTainted35 = source() as! Data - var rng = rng()! - sink(arg: dataTainted35.shuffled(using: &rng)) // $ tainted=225 + sink(arg: dataTainted35.sorted()) // $ tainted=236 + + // ";Data;true;sorted(by:);;;Argument[-1];ReturnValue;taint", + let dataTainted36 = source() as! Data + sink(arg: dataTainted36.sorted{ _,_ in return false }) // $ tainted=240 // ";Data;true;sorted(using:);;;Argument[-1];ReturnValue;taint", - let dataTainted36 = source() as! Data - sink(arg: dataTainted36.sorted(using: cmp()!)) // $ tainted=230 + let dataTainted37 = source() as! Data + sink(arg: dataTainted37.sorted(using: cmp()!)) // $ tainted=244 + + // ";Data;true;shuffled();;;Argument[-1];ReturnValue;taint", + let dataTainted38 = source() as! Data + sink(arg: dataTainted38.shuffled()) // $ tainted=248 + + // ";Data;true;shuffled(using:);;;Argument[-1];ReturnValue;taint", + let dataTainted39 = source() as! Data + var rng = rng()! + sink(arg: dataTainted39.shuffled(using: &rng)) // $ tainted=252 // ";Data;true;trimmingPrefix(_:);;;Argument[-1];ReturnValue;taint", - let dataTainted37 = source() as! Data - sink(arg: dataTainted37.trimmingPrefix([0])) // $ tainted=234 + let dataTainted40 = source() as! Data + sink(arg: dataTainted40.trimmingPrefix([0])) // $ tainted=257 // ";Data;true;trimmingPrefix(while:);;;Argument[-1];ReturnValue;taint" - let dataTainted38 = source() as! Data - sink(arg: dataTainted38.trimmingPrefix { _ in false }) // $ tainted=238 - + let dataTainted41 = source() as! Data + sink(arg: dataTainted41.trimmingPrefix { _ in false }) // $ tainted=261 } From e67b72d954b9eb05a57b1916319bef7a06073cbb Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Wed, 23 Nov 2022 12:45:49 +0100 Subject: [PATCH 513/796] Update test expectations --- .../dataflow/taint/LocalTaint.expected | 2 +- .../dataflow/taint/Taint.expected | 782 +++++++++--------- 2 files changed, 394 insertions(+), 390 deletions(-) diff --git a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected index 9e3f081261c..8ba56979b65 100644 --- a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected @@ -1,7 +1,7 @@ +| data.swift:195:58:195:58 | &... | data.swift:195:58:195:73 | ...[...] | | nsdata.swift:139:15:139:15 | nsDataTainted24 | nsdata.swift:139:15:139:31 | .bytes | | nsdata.swift:140:15:140:15 | nsDataTainted24 | nsdata.swift:140:15:140:31 | .description | | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 | nsmutabledata.swift:49:15:49:37 | .mutableBytes | -| data.swift:184:58:184:58 | &... | data.swift:184:58:184:73 | ...[...] | | string.swift:7:13:7:13 | | string.swift:7:13:7:13 | [post] | | string.swift:7:13:7:13 | | string.swift:7:14:7:14 | [post] &... | | string.swift:7:13:7:13 | TapExpr | string.swift:7:13:7:13 | "..." | diff --git a/swift/ql/test/library-tests/dataflow/taint/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/Taint.expected index 9430f377bef..37d4e5dda85 100644 --- a/swift/ql/test/library-tests/dataflow/taint/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/Taint.expected @@ -1,146 +1,155 @@ edges +| data.swift:25:2:25:66 | [summary param] 0 in init(base64Encoded:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | +| data.swift:26:2:26:61 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | +| data.swift:27:2:27:62 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | +| data.swift:28:2:28:45 | [summary param] 0 in init(bytes:count:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytes:count:) : | +| data.swift:29:2:29:82 | [summary param] 0 in init(bytesNoCopy:count:deallocator:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:count:deallocator:) : | +| data.swift:30:2:30:50 | [summary param] 0 in init(contentsOf:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOf:options:) : | +| data.swift:31:2:31:29 | [summary param] 0 in init(referencing:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(referencing:) : | +| data.swift:32:2:32:24 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | +| data.swift:33:2:33:25 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | +| data.swift:34:2:34:63 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | +| data.swift:35:2:35:52 | [summary param] 0 in append(_:count:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:count:) : | +| data.swift:36:2:36:36 | [summary param] 0 in append(contentsOf:) : | file://:0:0:0:0 | [summary] to write: argument this in append(contentsOf:) : | +| data.swift:38:2:38:88 | [summary param] this in base64EncodedData(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedData(options:) : | +| data.swift:39:2:39:86 | [summary param] this in base64EncodedString(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedString(options:) : | +| data.swift:40:2:40:99 | [summary param] this in compactMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in compactMap(_:) : | +| data.swift:41:2:41:53 | [summary param] this in copyBytes(to:) : | file://:0:0:0:0 | [summary] to write: argument 0 in copyBytes(to:) : | +| data.swift:44:2:44:137 | [summary param] this in flatMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | +| data.swift:45:2:45:97 | [summary param] this in flatMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | +| data.swift:46:2:46:34 | [summary param] 0 in insert(_:at:) : | file://:0:0:0:0 | [summary] to write: argument this in insert(_:at:) : | +| data.swift:47:2:47:83 | [summary param] 0 in insert(contentsOf:at:) : | file://:0:0:0:0 | [summary] to write: argument this in insert(contentsOf:at:) : | +| data.swift:48:2:48:50 | [summary param] this in map(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in map(_:) : | +| data.swift:49:2:49:115 | [summary param] this in reduce(into:_:) : | file://:0:0:0:0 | [summary] to write: return (return) in reduce(into:_:) : | +| data.swift:50:2:50:180 | [summary param] 1 in replace(_:with:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replace(_:with:maxReplacements:) : | +| data.swift:51:2:51:58 | [summary param] 1 in replaceSubrange(_:with:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | +| data.swift:52:2:52:151 | [summary param] 1 in replaceSubrange(_:with:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | +| data.swift:54:2:54:82 | [summary param] 1 in replaceSubrange(_:with:count:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:count:) : | +| data.swift:56:2:56:214 | [summary param] 1 in replacing(_:with:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replacing(_:with:maxReplacements:) : | +| data.swift:57:2:57:236 | [summary param] 1 in replacing(_:with:subrange:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replacing(_:with:subrange:maxReplacements:) : | +| data.swift:58:2:58:39 | [summary param] this in sorted() : | file://:0:0:0:0 | [summary] to write: return (return) in sorted() : | +| data.swift:59:2:59:81 | [summary param] this in sorted(by:) : | file://:0:0:0:0 | [summary] to write: return (return) in sorted(by:) : | +| data.swift:60:2:60:132 | [summary param] this in sorted(using:) : | file://:0:0:0:0 | [summary] to write: return (return) in sorted(using:) : | +| data.swift:61:2:61:41 | [summary param] this in shuffled() : | file://:0:0:0:0 | [summary] to write: return (return) in shuffled() : | +| data.swift:62:2:62:58 | [summary param] this in shuffled(using:) : | file://:0:0:0:0 | [summary] to write: return (return) in shuffled(using:) : | +| data.swift:63:2:63:123 | [summary param] this in trimmingPrefix(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(_:) : | +| data.swift:64:2:64:72 | [summary param] this in trimmingPrefix(while:) : | file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(while:) : | +| data.swift:89:21:89:71 | call to init(base64Encoded:options:) : | data.swift:90:12:90:12 | dataTainted3 | +| data.swift:89:41:89:48 | call to source() : | data.swift:25:2:25:66 | [summary param] 0 in init(base64Encoded:options:) : | +| data.swift:89:41:89:48 | call to source() : | data.swift:89:21:89:71 | call to init(base64Encoded:options:) : | +| data.swift:93:21:93:73 | call to init(buffer:) : | data.swift:94:12:94:12 | dataTainted4 | +| data.swift:93:34:93:41 | call to source() : | data.swift:26:2:26:61 | [summary param] 0 in init(buffer:) : | +| data.swift:93:34:93:41 | call to source() : | data.swift:93:21:93:73 | call to init(buffer:) : | +| data.swift:95:21:95:74 | call to init(buffer:) : | data.swift:96:12:96:12 | dataTainted5 | +| data.swift:95:34:95:41 | call to source() : | data.swift:27:2:27:62 | [summary param] 0 in init(buffer:) : | +| data.swift:95:34:95:41 | call to source() : | data.swift:95:21:95:74 | call to init(buffer:) : | +| data.swift:99:21:99:72 | call to init(bytes:count:) : | data.swift:100:12:100:12 | dataTainted6 | +| data.swift:99:33:99:40 | call to source() : | data.swift:28:2:28:45 | [summary param] 0 in init(bytes:count:) : | +| data.swift:99:33:99:40 | call to source() : | data.swift:99:21:99:72 | call to init(bytes:count:) : | +| data.swift:103:21:103:114 | call to init(bytesNoCopy:count:deallocator:) : | data.swift:104:12:104:12 | dataTainted7 | +| data.swift:103:39:103:46 | call to source() : | data.swift:29:2:29:82 | [summary param] 0 in init(bytesNoCopy:count:deallocator:) : | +| data.swift:103:39:103:46 | call to source() : | data.swift:103:21:103:114 | call to init(bytesNoCopy:count:deallocator:) : | +| data.swift:107:20:107:27 | call to source() : | data.swift:108:38:108:38 | urlTainted8 : | +| data.swift:108:21:108:62 | call to init(contentsOf:options:) : | data.swift:109:12:109:12 | dataTainted8 | +| data.swift:108:38:108:38 | urlTainted8 : | data.swift:30:2:30:50 | [summary param] 0 in init(contentsOf:options:) : | +| data.swift:108:38:108:38 | urlTainted8 : | data.swift:108:21:108:62 | call to init(contentsOf:options:) : | +| data.swift:112:21:112:58 | call to init(referencing:) : | data.swift:113:12:113:12 | dataTainted9 | +| data.swift:112:39:112:46 | call to source() : | data.swift:31:2:31:29 | [summary param] 0 in init(referencing:) : | +| data.swift:112:39:112:46 | call to source() : | data.swift:112:21:112:58 | call to init(referencing:) : | +| data.swift:117:2:117:2 | [post] dataTainted10 : | data.swift:118:12:118:12 | dataTainted10 | +| data.swift:117:23:117:30 | call to source() : | data.swift:32:2:32:24 | [summary param] 0 in append(_:) : | +| data.swift:117:23:117:30 | call to source() : | data.swift:117:2:117:2 | [post] dataTainted10 : | +| data.swift:121:2:121:2 | [post] dataTainted11 : | data.swift:122:12:122:12 | dataTainted11 | +| data.swift:121:23:121:30 | call to source() : | data.swift:33:2:33:25 | [summary param] 0 in append(_:) : | +| data.swift:121:23:121:30 | call to source() : | data.swift:121:2:121:2 | [post] dataTainted11 : | +| data.swift:125:2:125:2 | [post] dataTainted12 : | data.swift:126:12:126:12 | dataTainted12 | +| data.swift:125:23:125:30 | call to source() : | data.swift:34:2:34:63 | [summary param] 0 in append(_:) : | +| data.swift:125:23:125:30 | call to source() : | data.swift:125:2:125:2 | [post] dataTainted12 : | +| data.swift:130:2:130:2 | [post] dataTainted13 : | data.swift:131:12:131:12 | dataTainted13 | +| data.swift:130:23:130:30 | call to source() : | data.swift:35:2:35:52 | [summary param] 0 in append(_:count:) : | +| data.swift:130:23:130:30 | call to source() : | data.swift:130:2:130:2 | [post] dataTainted13 : | +| data.swift:135:2:135:2 | [post] dataTainted14 : | data.swift:136:12:136:12 | dataTainted14 | +| data.swift:135:35:135:42 | call to source() : | data.swift:36:2:36:36 | [summary param] 0 in append(contentsOf:) : | +| data.swift:135:35:135:42 | call to source() : | data.swift:135:2:135:2 | [post] dataTainted14 : | +| data.swift:139:22:139:29 | call to source() : | data.swift:140:12:140:12 | dataTainted15 : | +| data.swift:140:12:140:12 | dataTainted15 : | data.swift:38:2:38:88 | [summary param] this in base64EncodedData(options:) : | +| data.swift:140:12:140:12 | dataTainted15 : | data.swift:140:12:140:55 | call to base64EncodedData(options:) | +| data.swift:143:22:143:29 | call to source() : | data.swift:144:12:144:12 | dataTainted16 : | +| data.swift:144:12:144:12 | dataTainted16 : | data.swift:39:2:39:86 | [summary param] this in base64EncodedString(options:) : | +| data.swift:144:12:144:12 | dataTainted16 : | data.swift:144:12:144:57 | call to base64EncodedString(options:) | +| data.swift:147:22:147:29 | call to source() : | data.swift:148:29:148:29 | dataTainted17 : | +| data.swift:148:29:148:29 | dataTainted17 : | data.swift:40:2:40:99 | [summary param] this in compactMap(_:) : | +| data.swift:148:29:148:29 | dataTainted17 : | data.swift:148:29:148:72 | call to compactMap(_:) : | +| data.swift:148:29:148:72 | call to compactMap(_:) : | data.swift:149:12:149:12 | compactMapped | +| data.swift:152:22:152:29 | call to source() : | data.swift:154:2:154:2 | dataTainted18 : | +| data.swift:154:2:154:2 | dataTainted18 : | data.swift:41:2:41:53 | [summary param] this in copyBytes(to:) : | +| data.swift:154:2:154:2 | dataTainted18 : | data.swift:154:30:154:30 | [post] pointerTainted18 : | +| data.swift:154:30:154:30 | [post] pointerTainted18 : | data.swift:155:12:155:12 | pointerTainted18 | +| data.swift:170:22:170:29 | call to source() : | data.swift:171:19:171:19 | dataTainted21 : | +| data.swift:171:19:171:19 | dataTainted21 : | data.swift:44:2:44:137 | [summary param] this in flatMap(_:) : | +| data.swift:171:19:171:19 | dataTainted21 : | data.swift:171:19:171:74 | call to flatMap(_:) : | +| data.swift:171:19:171:74 | call to flatMap(_:) : | data.swift:172:12:172:12 | flatMapped | +| data.swift:174:22:174:29 | call to source() : | data.swift:175:20:175:20 | dataTainted22 : | +| data.swift:175:20:175:20 | dataTainted22 : | data.swift:45:2:45:97 | [summary param] this in flatMap(_:) : | +| data.swift:175:20:175:20 | dataTainted22 : | data.swift:175:20:175:60 | call to flatMap(_:) : | +| data.swift:175:20:175:60 | call to flatMap(_:) : | data.swift:176:12:176:12 | flatMapped2 | +| data.swift:180:2:180:2 | [post] dataTainted23 : | data.swift:181:12:181:12 | dataTainted23 | +| data.swift:180:23:180:30 | call to source() : | data.swift:46:2:46:34 | [summary param] 0 in insert(_:at:) : | +| data.swift:180:23:180:30 | call to source() : | data.swift:180:2:180:2 | [post] dataTainted23 : | +| data.swift:185:2:185:2 | [post] dataTainted24 : | data.swift:186:12:186:12 | dataTainted24 | +| data.swift:185:35:185:42 | call to source() : | data.swift:47:2:47:83 | [summary param] 0 in insert(contentsOf:at:) : | +| data.swift:185:35:185:42 | call to source() : | data.swift:185:2:185:2 | [post] dataTainted24 : | +| data.swift:189:22:189:29 | call to source() : | data.swift:190:15:190:15 | dataTainted25 : | +| data.swift:190:15:190:15 | dataTainted25 : | data.swift:48:2:48:50 | [summary param] this in map(_:) : | +| data.swift:190:15:190:15 | dataTainted25 : | data.swift:190:15:190:38 | call to map(_:) : | +| data.swift:190:15:190:38 | call to map(_:) : | data.swift:191:12:191:12 | mapped | +| data.swift:194:22:194:29 | call to source() : | data.swift:195:16:195:16 | dataTainted26 : | +| data.swift:195:16:195:16 | dataTainted26 : | data.swift:49:2:49:115 | [summary param] this in reduce(into:_:) : | +| data.swift:195:16:195:16 | dataTainted26 : | data.swift:195:16:195:80 | call to reduce(into:_:) : | +| data.swift:195:16:195:80 | call to reduce(into:_:) : | data.swift:196:12:196:12 | reduced | +| data.swift:200:2:200:2 | [post] dataTainted27 : | data.swift:201:12:201:12 | dataTainted27 | +| data.swift:200:35:200:42 | call to source() : | data.swift:50:2:50:180 | [summary param] 1 in replace(_:with:maxReplacements:) : | +| data.swift:200:35:200:42 | call to source() : | data.swift:200:2:200:2 | [post] dataTainted27 : | +| data.swift:205:2:205:2 | [post] dataTainted28 : | data.swift:206:12:206:12 | dataTainted28 | +| data.swift:205:45:205:52 | call to source() : | data.swift:51:2:51:58 | [summary param] 1 in replaceSubrange(_:with:) : | +| data.swift:205:45:205:52 | call to source() : | data.swift:205:2:205:2 | [post] dataTainted28 : | +| data.swift:209:2:209:2 | [post] dataTainted29 : | data.swift:210:12:210:12 | dataTainted29 | +| data.swift:209:45:209:52 | call to source() : | data.swift:52:2:52:151 | [summary param] 1 in replaceSubrange(_:with:) : | +| data.swift:209:45:209:52 | call to source() : | data.swift:209:2:209:2 | [post] dataTainted29 : | +| data.swift:213:2:213:2 | [post] dataTainted30 : | data.swift:214:12:214:12 | dataTainted30 | +| data.swift:213:45:213:52 | call to source() : | data.swift:52:2:52:151 | [summary param] 1 in replaceSubrange(_:with:) : | +| data.swift:213:45:213:52 | call to source() : | data.swift:213:2:213:2 | [post] dataTainted30 : | +| data.swift:218:2:218:2 | [post] dataTainted31 : | data.swift:219:12:219:12 | dataTainted31 | +| data.swift:218:45:218:52 | call to source() : | data.swift:54:2:54:82 | [summary param] 1 in replaceSubrange(_:with:count:) : | +| data.swift:218:45:218:52 | call to source() : | data.swift:218:2:218:2 | [post] dataTainted31 : | +| data.swift:223:10:223:10 | [post] dataTainted32 : | data.swift:224:12:224:12 | dataTainted32 | +| data.swift:223:45:223:52 | call to source() : | data.swift:56:2:56:214 | [summary param] 1 in replacing(_:with:maxReplacements:) : | +| data.swift:223:45:223:52 | call to source() : | data.swift:223:10:223:10 | [post] dataTainted32 : | +| data.swift:228:10:228:10 | [post] dataTainted33 : | data.swift:229:12:229:12 | dataTainted33 | +| data.swift:228:45:228:52 | call to source() : | data.swift:57:2:57:236 | [summary param] 1 in replacing(_:with:subrange:maxReplacements:) : | +| data.swift:228:45:228:52 | call to source() : | data.swift:228:10:228:10 | [post] dataTainted33 : | +| data.swift:236:22:236:29 | call to source() : | data.swift:237:12:237:12 | dataTainted35 : | +| data.swift:237:12:237:12 | dataTainted35 : | data.swift:58:2:58:39 | [summary param] this in sorted() : | +| data.swift:237:12:237:12 | dataTainted35 : | data.swift:237:12:237:33 | call to sorted() | +| data.swift:240:22:240:29 | call to source() : | data.swift:241:12:241:12 | dataTainted36 : | +| data.swift:241:12:241:12 | dataTainted36 : | data.swift:59:2:59:81 | [summary param] this in sorted(by:) : | +| data.swift:241:12:241:12 | dataTainted36 : | data.swift:241:12:241:54 | call to sorted(by:) | +| data.swift:244:22:244:29 | call to source() : | data.swift:245:12:245:12 | dataTainted37 : | +| data.swift:245:12:245:12 | dataTainted37 : | data.swift:60:2:60:132 | [summary param] this in sorted(using:) : | +| data.swift:245:12:245:12 | dataTainted37 : | data.swift:245:12:245:46 | call to sorted(using:) | +| data.swift:248:22:248:29 | call to source() : | data.swift:249:12:249:12 | dataTainted38 : | +| data.swift:249:12:249:12 | dataTainted38 : | data.swift:61:2:61:41 | [summary param] this in shuffled() : | +| data.swift:249:12:249:12 | dataTainted38 : | data.swift:249:12:249:35 | call to shuffled() | +| data.swift:252:22:252:29 | call to source() : | data.swift:254:12:254:12 | dataTainted39 : | +| data.swift:254:12:254:12 | dataTainted39 : | data.swift:62:2:62:58 | [summary param] this in shuffled(using:) : | +| data.swift:254:12:254:12 | dataTainted39 : | data.swift:254:12:254:46 | call to shuffled(using:) | +| data.swift:257:22:257:29 | call to source() : | data.swift:258:12:258:12 | dataTainted40 : | +| data.swift:258:12:258:12 | dataTainted40 : | data.swift:63:2:63:123 | [summary param] this in trimmingPrefix(_:) : | +| data.swift:258:12:258:12 | dataTainted40 : | data.swift:258:12:258:44 | call to trimmingPrefix(_:) | +| data.swift:261:22:261:29 | call to source() : | data.swift:262:12:262:12 | dataTainted41 : | +| data.swift:262:12:262:12 | dataTainted41 : | data.swift:64:2:64:72 | [summary param] this in trimmingPrefix(while:) : | +| data.swift:262:12:262:12 | dataTainted41 : | data.swift:262:12:262:54 | call to trimmingPrefix(while:) | | file://:0:0:0:0 | [summary] to write: argument 0.parameter 0 in enumerateBytes(_:) : | nsdata.swift:110:9:110:9 | bytes : | -| data.swift:17:2:17:66 | [summary param] 0 in init(base64Encoded:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | -| data.swift:18:2:18:61 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | -| data.swift:19:2:19:62 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | -| data.swift:20:2:20:45 | [summary param] 0 in init(bytes:count:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytes:count:) : | -| data.swift:21:2:21:82 | [summary param] 0 in init(bytesNoCopy:count:deallocator:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:count:deallocator:) : | -| data.swift:22:2:22:50 | [summary param] 0 in init(contentsOf:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOf:options:) : | -| data.swift:23:2:23:29 | [summary param] 0 in init(referencing:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(referencing:) : | -| data.swift:24:2:24:24 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | -| data.swift:25:2:25:25 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | -| data.swift:26:2:26:63 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | -| data.swift:27:2:27:52 | [summary param] 0 in append(_:count:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:count:) : | -| data.swift:28:2:28:36 | [summary param] 0 in append(contentsOf:) : | file://:0:0:0:0 | [summary] to write: argument this in append(contentsOf:) : | -| data.swift:30:2:30:88 | [summary param] this in base64EncodedData(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedData(options:) : | -| data.swift:31:2:31:86 | [summary param] this in base64EncodedString(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedString(options:) : | -| data.swift:32:2:32:99 | [summary param] this in compactMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in compactMap(_:) : | -| data.swift:33:2:33:53 | [summary param] this in copyBytes(to:) : | file://:0:0:0:0 | [summary] to write: argument 0 in copyBytes(to:) : | -| data.swift:36:2:36:137 | [summary param] this in flatMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | -| data.swift:37:2:37:97 | [summary param] this in flatMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | -| data.swift:38:2:38:34 | [summary param] 0 in insert(_:at:) : | file://:0:0:0:0 | [summary] to write: argument this in insert(_:at:) : | -| data.swift:39:2:39:83 | [summary param] 0 in insert(contentsOf:at:) : | file://:0:0:0:0 | [summary] to write: argument this in insert(contentsOf:at:) : | -| data.swift:40:2:40:50 | [summary param] this in map(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in map(_:) : | -| data.swift:41:2:41:115 | [summary param] this in reduce(into:_:) : | file://:0:0:0:0 | [summary] to write: return (return) in reduce(into:_:) : | -| data.swift:42:2:42:180 | [summary param] 1 in replace(_:with:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replace(_:with:maxReplacements:) : | -| data.swift:43:2:43:58 | [summary param] 1 in replaceSubrange(_:with:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | -| data.swift:44:2:44:151 | [summary param] 1 in replaceSubrange(_:with:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | -| data.swift:46:2:46:82 | [summary param] 1 in replaceSubrange(_:with:count:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:count:) : | -| data.swift:48:2:48:214 | [summary param] 1 in replacing(_:with:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replacing(_:with:maxReplacements:) : | -| data.swift:49:2:49:236 | [summary param] 1 in replacing(_:with:subrange:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replacing(_:with:subrange:maxReplacements:) : | -| data.swift:50:2:50:41 | [summary param] this in shuffled() : | file://:0:0:0:0 | [summary] to write: return (return) in shuffled() : | -| data.swift:51:2:51:58 | [summary param] this in shuffled(using:) : | file://:0:0:0:0 | [summary] to write: return (return) in shuffled(using:) : | -| data.swift:52:2:52:132 | [summary param] this in sorted(using:) : | file://:0:0:0:0 | [summary] to write: return (return) in sorted(using:) : | -| data.swift:53:2:53:123 | [summary param] this in trimmingPrefix(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(_:) : | -| data.swift:54:2:54:72 | [summary param] this in trimmingPrefix(while:) : | file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(while:) : | -| data.swift:79:21:79:71 | call to init(base64Encoded:options:) : | data.swift:80:12:80:12 | dataTainted3 | -| data.swift:79:41:79:48 | call to source() : | data.swift:17:2:17:66 | [summary param] 0 in init(base64Encoded:options:) : | -| data.swift:79:41:79:48 | call to source() : | data.swift:79:21:79:71 | call to init(base64Encoded:options:) : | -| data.swift:83:21:83:73 | call to init(buffer:) : | data.swift:84:12:84:12 | dataTainted4 | -| data.swift:83:34:83:41 | call to source() : | data.swift:18:2:18:61 | [summary param] 0 in init(buffer:) : | -| data.swift:83:34:83:41 | call to source() : | data.swift:83:21:83:73 | call to init(buffer:) : | -| data.swift:85:21:85:74 | call to init(buffer:) : | data.swift:86:12:86:12 | dataTainted5 | -| data.swift:85:34:85:41 | call to source() : | data.swift:19:2:19:62 | [summary param] 0 in init(buffer:) : | -| data.swift:85:34:85:41 | call to source() : | data.swift:85:21:85:74 | call to init(buffer:) : | -| data.swift:89:21:89:72 | call to init(bytes:count:) : | data.swift:90:12:90:12 | dataTainted6 | -| data.swift:89:33:89:40 | call to source() : | data.swift:20:2:20:45 | [summary param] 0 in init(bytes:count:) : | -| data.swift:89:33:89:40 | call to source() : | data.swift:89:21:89:72 | call to init(bytes:count:) : | -| data.swift:93:21:93:114 | call to init(bytesNoCopy:count:deallocator:) : | data.swift:94:12:94:12 | dataTainted7 | -| data.swift:93:39:93:46 | call to source() : | data.swift:21:2:21:82 | [summary param] 0 in init(bytesNoCopy:count:deallocator:) : | -| data.swift:93:39:93:46 | call to source() : | data.swift:93:21:93:114 | call to init(bytesNoCopy:count:deallocator:) : | -| data.swift:97:21:97:67 | call to init(contentsOf:options:) : | data.swift:98:12:98:12 | dataTainted8 | -| data.swift:97:38:97:45 | call to source() : | data.swift:22:2:22:50 | [summary param] 0 in init(contentsOf:options:) : | -| data.swift:97:38:97:45 | call to source() : | data.swift:97:21:97:67 | call to init(contentsOf:options:) : | -| data.swift:101:21:101:58 | call to init(referencing:) : | data.swift:102:12:102:12 | dataTainted9 | -| data.swift:101:39:101:46 | call to source() : | data.swift:23:2:23:29 | [summary param] 0 in init(referencing:) : | -| data.swift:101:39:101:46 | call to source() : | data.swift:101:21:101:58 | call to init(referencing:) : | -| data.swift:106:2:106:2 | [post] dataTainted10 : | data.swift:107:12:107:12 | dataTainted10 | -| data.swift:106:23:106:30 | call to source() : | data.swift:24:2:24:24 | [summary param] 0 in append(_:) : | -| data.swift:106:23:106:30 | call to source() : | data.swift:106:2:106:2 | [post] dataTainted10 : | -| data.swift:110:2:110:2 | [post] dataTainted11 : | data.swift:111:12:111:12 | dataTainted11 | -| data.swift:110:23:110:30 | call to source() : | data.swift:25:2:25:25 | [summary param] 0 in append(_:) : | -| data.swift:110:23:110:30 | call to source() : | data.swift:110:2:110:2 | [post] dataTainted11 : | -| data.swift:114:2:114:2 | [post] dataTainted12 : | data.swift:115:12:115:12 | dataTainted12 | -| data.swift:114:23:114:30 | call to source() : | data.swift:26:2:26:63 | [summary param] 0 in append(_:) : | -| data.swift:114:23:114:30 | call to source() : | data.swift:114:2:114:2 | [post] dataTainted12 : | -| data.swift:119:2:119:2 | [post] dataTainted13 : | data.swift:120:12:120:12 | dataTainted13 | -| data.swift:119:23:119:30 | call to source() : | data.swift:27:2:27:52 | [summary param] 0 in append(_:count:) : | -| data.swift:119:23:119:30 | call to source() : | data.swift:119:2:119:2 | [post] dataTainted13 : | -| data.swift:124:2:124:2 | [post] dataTainted14 : | data.swift:125:12:125:12 | dataTainted14 | -| data.swift:124:35:124:42 | call to source() : | data.swift:28:2:28:36 | [summary param] 0 in append(contentsOf:) : | -| data.swift:124:35:124:42 | call to source() : | data.swift:124:2:124:2 | [post] dataTainted14 : | -| data.swift:128:22:128:29 | call to source() : | data.swift:129:12:129:12 | dataTainted15 : | -| data.swift:129:12:129:12 | dataTainted15 : | data.swift:30:2:30:88 | [summary param] this in base64EncodedData(options:) : | -| data.swift:129:12:129:12 | dataTainted15 : | data.swift:129:12:129:55 | call to base64EncodedData(options:) | -| data.swift:132:22:132:29 | call to source() : | data.swift:133:12:133:12 | dataTainted16 : | -| data.swift:133:12:133:12 | dataTainted16 : | data.swift:31:2:31:86 | [summary param] this in base64EncodedString(options:) : | -| data.swift:133:12:133:12 | dataTainted16 : | data.swift:133:12:133:57 | call to base64EncodedString(options:) | -| data.swift:136:22:136:29 | call to source() : | data.swift:137:29:137:29 | dataTainted17 : | -| data.swift:137:29:137:29 | dataTainted17 : | data.swift:32:2:32:99 | [summary param] this in compactMap(_:) : | -| data.swift:137:29:137:29 | dataTainted17 : | data.swift:137:29:137:72 | call to compactMap(_:) : | -| data.swift:137:29:137:72 | call to compactMap(_:) : | data.swift:138:12:138:12 | compactMapped | -| data.swift:141:22:141:29 | call to source() : | data.swift:143:2:143:2 | dataTainted18 : | -| data.swift:143:2:143:2 | dataTainted18 : | data.swift:33:2:33:53 | [summary param] this in copyBytes(to:) : | -| data.swift:143:2:143:2 | dataTainted18 : | data.swift:143:30:143:30 | [post] pointerTainted18 : | -| data.swift:143:30:143:30 | [post] pointerTainted18 : | data.swift:144:12:144:12 | pointerTainted18 | -| data.swift:159:22:159:29 | call to source() : | data.swift:160:19:160:19 | dataTainted21 : | -| data.swift:160:19:160:19 | dataTainted21 : | data.swift:36:2:36:137 | [summary param] this in flatMap(_:) : | -| data.swift:160:19:160:19 | dataTainted21 : | data.swift:160:19:160:74 | call to flatMap(_:) : | -| data.swift:160:19:160:74 | call to flatMap(_:) : | data.swift:161:12:161:12 | flatMapped | -| data.swift:163:22:163:29 | call to source() : | data.swift:164:20:164:20 | dataTainted22 : | -| data.swift:164:20:164:20 | dataTainted22 : | data.swift:37:2:37:97 | [summary param] this in flatMap(_:) : | -| data.swift:164:20:164:20 | dataTainted22 : | data.swift:164:20:164:60 | call to flatMap(_:) : | -| data.swift:164:20:164:60 | call to flatMap(_:) : | data.swift:165:12:165:12 | flatMapped2 | -| data.swift:169:2:169:2 | [post] dataTainted23 : | data.swift:170:12:170:12 | dataTainted23 | -| data.swift:169:23:169:30 | call to source() : | data.swift:38:2:38:34 | [summary param] 0 in insert(_:at:) : | -| data.swift:169:23:169:30 | call to source() : | data.swift:169:2:169:2 | [post] dataTainted23 : | -| data.swift:174:2:174:2 | [post] dataTainted24 : | data.swift:175:12:175:12 | dataTainted24 | -| data.swift:174:35:174:42 | call to source() : | data.swift:39:2:39:83 | [summary param] 0 in insert(contentsOf:at:) : | -| data.swift:174:35:174:42 | call to source() : | data.swift:174:2:174:2 | [post] dataTainted24 : | -| data.swift:178:22:178:29 | call to source() : | data.swift:179:15:179:15 | dataTainted25 : | -| data.swift:179:15:179:15 | dataTainted25 : | data.swift:40:2:40:50 | [summary param] this in map(_:) : | -| data.swift:179:15:179:15 | dataTainted25 : | data.swift:179:15:179:38 | call to map(_:) : | -| data.swift:179:15:179:38 | call to map(_:) : | data.swift:180:12:180:12 | mapped | -| data.swift:183:22:183:29 | call to source() : | data.swift:184:16:184:16 | dataTainted26 : | -| data.swift:184:16:184:16 | dataTainted26 : | data.swift:41:2:41:115 | [summary param] this in reduce(into:_:) : | -| data.swift:184:16:184:16 | dataTainted26 : | data.swift:184:16:184:80 | call to reduce(into:_:) : | -| data.swift:184:16:184:80 | call to reduce(into:_:) : | data.swift:185:12:185:12 | reduced | -| data.swift:189:2:189:2 | [post] dataTainted27 : | data.swift:190:12:190:12 | dataTainted27 | -| data.swift:189:35:189:42 | call to source() : | data.swift:42:2:42:180 | [summary param] 1 in replace(_:with:maxReplacements:) : | -| data.swift:189:35:189:42 | call to source() : | data.swift:189:2:189:2 | [post] dataTainted27 : | -| data.swift:194:2:194:2 | [post] dataTainted28 : | data.swift:195:12:195:12 | dataTainted28 | -| data.swift:194:45:194:52 | call to source() : | data.swift:43:2:43:58 | [summary param] 1 in replaceSubrange(_:with:) : | -| data.swift:194:45:194:52 | call to source() : | data.swift:194:2:194:2 | [post] dataTainted28 : | -| data.swift:198:2:198:2 | [post] dataTainted29 : | data.swift:199:12:199:12 | dataTainted29 | -| data.swift:198:45:198:52 | call to source() : | data.swift:44:2:44:151 | [summary param] 1 in replaceSubrange(_:with:) : | -| data.swift:198:45:198:52 | call to source() : | data.swift:198:2:198:2 | [post] dataTainted29 : | -| data.swift:202:2:202:2 | [post] dataTainted30 : | data.swift:203:12:203:12 | dataTainted30 | -| data.swift:202:45:202:52 | call to source() : | data.swift:44:2:44:151 | [summary param] 1 in replaceSubrange(_:with:) : | -| data.swift:202:45:202:52 | call to source() : | data.swift:202:2:202:2 | [post] dataTainted30 : | -| data.swift:207:2:207:2 | [post] dataTainted31 : | data.swift:208:12:208:12 | dataTainted31 | -| data.swift:207:45:207:52 | call to source() : | data.swift:46:2:46:82 | [summary param] 1 in replaceSubrange(_:with:count:) : | -| data.swift:207:45:207:52 | call to source() : | data.swift:207:2:207:2 | [post] dataTainted31 : | -| data.swift:212:2:212:2 | [post] dataTainted32 : | data.swift:213:12:213:12 | dataTainted32 | -| data.swift:212:37:212:44 | call to source() : | data.swift:48:2:48:214 | [summary param] 1 in replacing(_:with:maxReplacements:) : | -| data.swift:212:37:212:44 | call to source() : | data.swift:212:2:212:2 | [post] dataTainted32 : | -| data.swift:217:2:217:2 | [post] dataTainted33 : | data.swift:218:12:218:12 | dataTainted33 | -| data.swift:217:37:217:44 | call to source() : | data.swift:49:2:49:236 | [summary param] 1 in replacing(_:with:subrange:maxReplacements:) : | -| data.swift:217:37:217:44 | call to source() : | data.swift:217:2:217:2 | [post] dataTainted33 : | -| data.swift:221:22:221:29 | call to source() : | data.swift:222:12:222:12 | dataTainted34 : | -| data.swift:222:12:222:12 | dataTainted34 : | data.swift:50:2:50:41 | [summary param] this in shuffled() : | -| data.swift:222:12:222:12 | dataTainted34 : | data.swift:222:12:222:35 | call to shuffled() | -| data.swift:225:22:225:29 | call to source() : | data.swift:227:12:227:12 | dataTainted35 : | -| data.swift:227:12:227:12 | dataTainted35 : | data.swift:51:2:51:58 | [summary param] this in shuffled(using:) : | -| data.swift:227:12:227:12 | dataTainted35 : | data.swift:227:12:227:46 | call to shuffled(using:) | -| data.swift:230:22:230:29 | call to source() : | data.swift:231:12:231:12 | dataTainted36 : | -| data.swift:231:12:231:12 | dataTainted36 : | data.swift:52:2:52:132 | [summary param] this in sorted(using:) : | -| data.swift:231:12:231:12 | dataTainted36 : | data.swift:231:12:231:46 | call to sorted(using:) | -| data.swift:234:22:234:29 | call to source() : | data.swift:235:12:235:12 | dataTainted37 : | -| data.swift:235:12:235:12 | dataTainted37 : | data.swift:53:2:53:123 | [summary param] this in trimmingPrefix(_:) : | -| data.swift:235:12:235:12 | dataTainted37 : | data.swift:235:12:235:44 | call to trimmingPrefix(_:) | -| data.swift:238:22:238:29 | call to source() : | data.swift:239:12:239:12 | dataTainted38 : | -| data.swift:239:12:239:12 | dataTainted38 : | data.swift:54:2:54:72 | [summary param] this in trimmingPrefix(while:) : | -| data.swift:239:12:239:12 | dataTainted38 : | data.swift:239:12:239:54 | call to trimmingPrefix(while:) | | file://:0:0:0:0 | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : | url.swift:120:61:120:61 | data : | | nsdata.swift:22:9:22:9 | self : | file://:0:0:0:0 | .bytes : | | nsdata.swift:23:9:23:9 | self : | file://:0:0:0:0 | .description : | @@ -522,218 +531,219 @@ edges | webview.swift:97:17:97:17 | s : | webview.swift:44:5:44:48 | [summary param] 0 in setValue(_:forProperty:) : | | webview.swift:97:17:97:17 | s : | webview.swift:97:5:97:5 | [post] v3 : | nodes -<<<<<<< HEAD +| data.swift:25:2:25:66 | [summary param] 0 in init(base64Encoded:options:) : | semmle.label | [summary param] 0 in init(base64Encoded:options:) : | +| data.swift:26:2:26:61 | [summary param] 0 in init(buffer:) : | semmle.label | [summary param] 0 in init(buffer:) : | +| data.swift:27:2:27:62 | [summary param] 0 in init(buffer:) : | semmle.label | [summary param] 0 in init(buffer:) : | +| data.swift:28:2:28:45 | [summary param] 0 in init(bytes:count:) : | semmle.label | [summary param] 0 in init(bytes:count:) : | +| data.swift:29:2:29:82 | [summary param] 0 in init(bytesNoCopy:count:deallocator:) : | semmle.label | [summary param] 0 in init(bytesNoCopy:count:deallocator:) : | +| data.swift:30:2:30:50 | [summary param] 0 in init(contentsOf:options:) : | semmle.label | [summary param] 0 in init(contentsOf:options:) : | +| data.swift:31:2:31:29 | [summary param] 0 in init(referencing:) : | semmle.label | [summary param] 0 in init(referencing:) : | +| data.swift:32:2:32:24 | [summary param] 0 in append(_:) : | semmle.label | [summary param] 0 in append(_:) : | +| data.swift:33:2:33:25 | [summary param] 0 in append(_:) : | semmle.label | [summary param] 0 in append(_:) : | +| data.swift:34:2:34:63 | [summary param] 0 in append(_:) : | semmle.label | [summary param] 0 in append(_:) : | +| data.swift:35:2:35:52 | [summary param] 0 in append(_:count:) : | semmle.label | [summary param] 0 in append(_:count:) : | +| data.swift:36:2:36:36 | [summary param] 0 in append(contentsOf:) : | semmle.label | [summary param] 0 in append(contentsOf:) : | +| data.swift:38:2:38:88 | [summary param] this in base64EncodedData(options:) : | semmle.label | [summary param] this in base64EncodedData(options:) : | +| data.swift:39:2:39:86 | [summary param] this in base64EncodedString(options:) : | semmle.label | [summary param] this in base64EncodedString(options:) : | +| data.swift:40:2:40:99 | [summary param] this in compactMap(_:) : | semmle.label | [summary param] this in compactMap(_:) : | +| data.swift:41:2:41:53 | [summary param] this in copyBytes(to:) : | semmle.label | [summary param] this in copyBytes(to:) : | +| data.swift:44:2:44:137 | [summary param] this in flatMap(_:) : | semmle.label | [summary param] this in flatMap(_:) : | +| data.swift:45:2:45:97 | [summary param] this in flatMap(_:) : | semmle.label | [summary param] this in flatMap(_:) : | +| data.swift:46:2:46:34 | [summary param] 0 in insert(_:at:) : | semmle.label | [summary param] 0 in insert(_:at:) : | +| data.swift:47:2:47:83 | [summary param] 0 in insert(contentsOf:at:) : | semmle.label | [summary param] 0 in insert(contentsOf:at:) : | +| data.swift:48:2:48:50 | [summary param] this in map(_:) : | semmle.label | [summary param] this in map(_:) : | +| data.swift:49:2:49:115 | [summary param] this in reduce(into:_:) : | semmle.label | [summary param] this in reduce(into:_:) : | +| data.swift:50:2:50:180 | [summary param] 1 in replace(_:with:maxReplacements:) : | semmle.label | [summary param] 1 in replace(_:with:maxReplacements:) : | +| data.swift:51:2:51:58 | [summary param] 1 in replaceSubrange(_:with:) : | semmle.label | [summary param] 1 in replaceSubrange(_:with:) : | +| data.swift:52:2:52:151 | [summary param] 1 in replaceSubrange(_:with:) : | semmle.label | [summary param] 1 in replaceSubrange(_:with:) : | +| data.swift:54:2:54:82 | [summary param] 1 in replaceSubrange(_:with:count:) : | semmle.label | [summary param] 1 in replaceSubrange(_:with:count:) : | +| data.swift:56:2:56:214 | [summary param] 1 in replacing(_:with:maxReplacements:) : | semmle.label | [summary param] 1 in replacing(_:with:maxReplacements:) : | +| data.swift:57:2:57:236 | [summary param] 1 in replacing(_:with:subrange:maxReplacements:) : | semmle.label | [summary param] 1 in replacing(_:with:subrange:maxReplacements:) : | +| data.swift:58:2:58:39 | [summary param] this in sorted() : | semmle.label | [summary param] this in sorted() : | +| data.swift:59:2:59:81 | [summary param] this in sorted(by:) : | semmle.label | [summary param] this in sorted(by:) : | +| data.swift:60:2:60:132 | [summary param] this in sorted(using:) : | semmle.label | [summary param] this in sorted(using:) : | +| data.swift:61:2:61:41 | [summary param] this in shuffled() : | semmle.label | [summary param] this in shuffled() : | +| data.swift:62:2:62:58 | [summary param] this in shuffled(using:) : | semmle.label | [summary param] this in shuffled(using:) : | +| data.swift:63:2:63:123 | [summary param] this in trimmingPrefix(_:) : | semmle.label | [summary param] this in trimmingPrefix(_:) : | +| data.swift:64:2:64:72 | [summary param] this in trimmingPrefix(while:) : | semmle.label | [summary param] this in trimmingPrefix(while:) : | +| data.swift:89:21:89:71 | call to init(base64Encoded:options:) : | semmle.label | call to init(base64Encoded:options:) : | +| data.swift:89:41:89:48 | call to source() : | semmle.label | call to source() : | +| data.swift:90:12:90:12 | dataTainted3 | semmle.label | dataTainted3 | +| data.swift:93:21:93:73 | call to init(buffer:) : | semmle.label | call to init(buffer:) : | +| data.swift:93:34:93:41 | call to source() : | semmle.label | call to source() : | +| data.swift:94:12:94:12 | dataTainted4 | semmle.label | dataTainted4 | +| data.swift:95:21:95:74 | call to init(buffer:) : | semmle.label | call to init(buffer:) : | +| data.swift:95:34:95:41 | call to source() : | semmle.label | call to source() : | +| data.swift:96:12:96:12 | dataTainted5 | semmle.label | dataTainted5 | +| data.swift:99:21:99:72 | call to init(bytes:count:) : | semmle.label | call to init(bytes:count:) : | +| data.swift:99:33:99:40 | call to source() : | semmle.label | call to source() : | +| data.swift:100:12:100:12 | dataTainted6 | semmle.label | dataTainted6 | +| data.swift:103:21:103:114 | call to init(bytesNoCopy:count:deallocator:) : | semmle.label | call to init(bytesNoCopy:count:deallocator:) : | +| data.swift:103:39:103:46 | call to source() : | semmle.label | call to source() : | +| data.swift:104:12:104:12 | dataTainted7 | semmle.label | dataTainted7 | +| data.swift:107:20:107:27 | call to source() : | semmle.label | call to source() : | +| data.swift:108:21:108:62 | call to init(contentsOf:options:) : | semmle.label | call to init(contentsOf:options:) : | +| data.swift:108:38:108:38 | urlTainted8 : | semmle.label | urlTainted8 : | +| data.swift:109:12:109:12 | dataTainted8 | semmle.label | dataTainted8 | +| data.swift:112:21:112:58 | call to init(referencing:) : | semmle.label | call to init(referencing:) : | +| data.swift:112:39:112:46 | call to source() : | semmle.label | call to source() : | +| data.swift:113:12:113:12 | dataTainted9 | semmle.label | dataTainted9 | +| data.swift:117:2:117:2 | [post] dataTainted10 : | semmle.label | [post] dataTainted10 : | +| data.swift:117:23:117:30 | call to source() : | semmle.label | call to source() : | +| data.swift:118:12:118:12 | dataTainted10 | semmle.label | dataTainted10 | +| data.swift:121:2:121:2 | [post] dataTainted11 : | semmle.label | [post] dataTainted11 : | +| data.swift:121:23:121:30 | call to source() : | semmle.label | call to source() : | +| data.swift:122:12:122:12 | dataTainted11 | semmle.label | dataTainted11 | +| data.swift:125:2:125:2 | [post] dataTainted12 : | semmle.label | [post] dataTainted12 : | +| data.swift:125:23:125:30 | call to source() : | semmle.label | call to source() : | +| data.swift:126:12:126:12 | dataTainted12 | semmle.label | dataTainted12 | +| data.swift:130:2:130:2 | [post] dataTainted13 : | semmle.label | [post] dataTainted13 : | +| data.swift:130:23:130:30 | call to source() : | semmle.label | call to source() : | +| data.swift:131:12:131:12 | dataTainted13 | semmle.label | dataTainted13 | +| data.swift:135:2:135:2 | [post] dataTainted14 : | semmle.label | [post] dataTainted14 : | +| data.swift:135:35:135:42 | call to source() : | semmle.label | call to source() : | +| data.swift:136:12:136:12 | dataTainted14 | semmle.label | dataTainted14 | +| data.swift:139:22:139:29 | call to source() : | semmle.label | call to source() : | +| data.swift:140:12:140:12 | dataTainted15 : | semmle.label | dataTainted15 : | +| data.swift:140:12:140:55 | call to base64EncodedData(options:) | semmle.label | call to base64EncodedData(options:) | +| data.swift:143:22:143:29 | call to source() : | semmle.label | call to source() : | +| data.swift:144:12:144:12 | dataTainted16 : | semmle.label | dataTainted16 : | +| data.swift:144:12:144:57 | call to base64EncodedString(options:) | semmle.label | call to base64EncodedString(options:) | +| data.swift:147:22:147:29 | call to source() : | semmle.label | call to source() : | +| data.swift:148:29:148:29 | dataTainted17 : | semmle.label | dataTainted17 : | +| data.swift:148:29:148:72 | call to compactMap(_:) : | semmle.label | call to compactMap(_:) : | +| data.swift:149:12:149:12 | compactMapped | semmle.label | compactMapped | +| data.swift:152:22:152:29 | call to source() : | semmle.label | call to source() : | +| data.swift:154:2:154:2 | dataTainted18 : | semmle.label | dataTainted18 : | +| data.swift:154:30:154:30 | [post] pointerTainted18 : | semmle.label | [post] pointerTainted18 : | +| data.swift:155:12:155:12 | pointerTainted18 | semmle.label | pointerTainted18 | +| data.swift:170:22:170:29 | call to source() : | semmle.label | call to source() : | +| data.swift:171:19:171:19 | dataTainted21 : | semmle.label | dataTainted21 : | +| data.swift:171:19:171:74 | call to flatMap(_:) : | semmle.label | call to flatMap(_:) : | +| data.swift:172:12:172:12 | flatMapped | semmle.label | flatMapped | +| data.swift:174:22:174:29 | call to source() : | semmle.label | call to source() : | +| data.swift:175:20:175:20 | dataTainted22 : | semmle.label | dataTainted22 : | +| data.swift:175:20:175:60 | call to flatMap(_:) : | semmle.label | call to flatMap(_:) : | +| data.swift:176:12:176:12 | flatMapped2 | semmle.label | flatMapped2 | +| data.swift:180:2:180:2 | [post] dataTainted23 : | semmle.label | [post] dataTainted23 : | +| data.swift:180:23:180:30 | call to source() : | semmle.label | call to source() : | +| data.swift:181:12:181:12 | dataTainted23 | semmle.label | dataTainted23 | +| data.swift:185:2:185:2 | [post] dataTainted24 : | semmle.label | [post] dataTainted24 : | +| data.swift:185:35:185:42 | call to source() : | semmle.label | call to source() : | +| data.swift:186:12:186:12 | dataTainted24 | semmle.label | dataTainted24 | +| data.swift:189:22:189:29 | call to source() : | semmle.label | call to source() : | +| data.swift:190:15:190:15 | dataTainted25 : | semmle.label | dataTainted25 : | +| data.swift:190:15:190:38 | call to map(_:) : | semmle.label | call to map(_:) : | +| data.swift:191:12:191:12 | mapped | semmle.label | mapped | +| data.swift:194:22:194:29 | call to source() : | semmle.label | call to source() : | +| data.swift:195:16:195:16 | dataTainted26 : | semmle.label | dataTainted26 : | +| data.swift:195:16:195:80 | call to reduce(into:_:) : | semmle.label | call to reduce(into:_:) : | +| data.swift:196:12:196:12 | reduced | semmle.label | reduced | +| data.swift:200:2:200:2 | [post] dataTainted27 : | semmle.label | [post] dataTainted27 : | +| data.swift:200:35:200:42 | call to source() : | semmle.label | call to source() : | +| data.swift:201:12:201:12 | dataTainted27 | semmle.label | dataTainted27 | +| data.swift:205:2:205:2 | [post] dataTainted28 : | semmle.label | [post] dataTainted28 : | +| data.swift:205:45:205:52 | call to source() : | semmle.label | call to source() : | +| data.swift:206:12:206:12 | dataTainted28 | semmle.label | dataTainted28 | +| data.swift:209:2:209:2 | [post] dataTainted29 : | semmle.label | [post] dataTainted29 : | +| data.swift:209:45:209:52 | call to source() : | semmle.label | call to source() : | +| data.swift:210:12:210:12 | dataTainted29 | semmle.label | dataTainted29 | +| data.swift:213:2:213:2 | [post] dataTainted30 : | semmle.label | [post] dataTainted30 : | +| data.swift:213:45:213:52 | call to source() : | semmle.label | call to source() : | +| data.swift:214:12:214:12 | dataTainted30 | semmle.label | dataTainted30 | +| data.swift:218:2:218:2 | [post] dataTainted31 : | semmle.label | [post] dataTainted31 : | +| data.swift:218:45:218:52 | call to source() : | semmle.label | call to source() : | +| data.swift:219:12:219:12 | dataTainted31 | semmle.label | dataTainted31 | +| data.swift:223:10:223:10 | [post] dataTainted32 : | semmle.label | [post] dataTainted32 : | +| data.swift:223:45:223:52 | call to source() : | semmle.label | call to source() : | +| data.swift:224:12:224:12 | dataTainted32 | semmle.label | dataTainted32 | +| data.swift:228:10:228:10 | [post] dataTainted33 : | semmle.label | [post] dataTainted33 : | +| data.swift:228:45:228:52 | call to source() : | semmle.label | call to source() : | +| data.swift:229:12:229:12 | dataTainted33 | semmle.label | dataTainted33 | +| data.swift:236:22:236:29 | call to source() : | semmle.label | call to source() : | +| data.swift:237:12:237:12 | dataTainted35 : | semmle.label | dataTainted35 : | +| data.swift:237:12:237:33 | call to sorted() | semmle.label | call to sorted() | +| data.swift:240:22:240:29 | call to source() : | semmle.label | call to source() : | +| data.swift:241:12:241:12 | dataTainted36 : | semmle.label | dataTainted36 : | +| data.swift:241:12:241:54 | call to sorted(by:) | semmle.label | call to sorted(by:) | +| data.swift:244:22:244:29 | call to source() : | semmle.label | call to source() : | +| data.swift:245:12:245:12 | dataTainted37 : | semmle.label | dataTainted37 : | +| data.swift:245:12:245:46 | call to sorted(using:) | semmle.label | call to sorted(using:) | +| data.swift:248:22:248:29 | call to source() : | semmle.label | call to source() : | +| data.swift:249:12:249:12 | dataTainted38 : | semmle.label | dataTainted38 : | +| data.swift:249:12:249:35 | call to shuffled() | semmle.label | call to shuffled() | +| data.swift:252:22:252:29 | call to source() : | semmle.label | call to source() : | +| data.swift:254:12:254:12 | dataTainted39 : | semmle.label | dataTainted39 : | +| data.swift:254:12:254:46 | call to shuffled(using:) | semmle.label | call to shuffled(using:) | +| data.swift:257:22:257:29 | call to source() : | semmle.label | call to source() : | +| data.swift:258:12:258:12 | dataTainted40 : | semmle.label | dataTainted40 : | +| data.swift:258:12:258:44 | call to trimmingPrefix(_:) | semmle.label | call to trimmingPrefix(_:) | +| data.swift:261:22:261:29 | call to source() : | semmle.label | call to source() : | +| data.swift:262:12:262:12 | dataTainted41 : | semmle.label | dataTainted41 : | +| data.swift:262:12:262:54 | call to trimmingPrefix(while:) | semmle.label | call to trimmingPrefix(while:) | | file://:0:0:0:0 | .bytes : | semmle.label | .bytes : | | file://:0:0:0:0 | .description : | semmle.label | .description : | | file://:0:0:0:0 | .mutableBytes : | semmle.label | .mutableBytes : | +| file://:0:0:0:0 | [summary] to write: argument 0 in copyBytes(to:) : | semmle.label | [summary] to write: argument 0 in copyBytes(to:) : | | file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:) : | semmle.label | [summary] to write: argument 0 in getBytes(_:) : | | file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:length:) : | semmle.label | [summary] to write: argument 0 in getBytes(_:length:) : | | file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:range:) : | semmle.label | [summary] to write: argument 0 in getBytes(_:range:) : | | file://:0:0:0:0 | [summary] to write: argument 0.parameter 0 in enumerateBytes(_:) : | semmle.label | [summary] to write: argument 0.parameter 0 in enumerateBytes(_:) : | | file://:0:0:0:0 | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : | semmle.label | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : | | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | semmle.label | [summary] to write: argument this in append(_:) : | -| file://:0:0:0:0 | [summary] to write: argument this in append(_:length:) : | semmle.label | [summary] to write: argument this in append(_:length:) : | -| file://:0:0:0:0 | [summary] to write: argument this in defineProperty(_:descriptor:) : | semmle.label | [summary] to write: argument this in defineProperty(_:descriptor:) : | -| file://:0:0:0:0 | [summary] to write: argument this in replaceBytes(in:withBytes:) : | semmle.label | [summary] to write: argument this in replaceBytes(in:withBytes:) : | -| file://:0:0:0:0 | [summary] to write: argument this in replaceBytes(in:withBytes:length:) : | semmle.label | [summary] to write: argument this in replaceBytes(in:withBytes:length:) : | -| file://:0:0:0:0 | [summary] to write: argument this in setData(_:) : | semmle.label | [summary] to write: argument this in setData(_:) : | -======= -| data.swift:17:2:17:66 | [summary param] 0 in init(base64Encoded:options:) : | semmle.label | [summary param] 0 in init(base64Encoded:options:) : | -| data.swift:18:2:18:61 | [summary param] 0 in init(buffer:) : | semmle.label | [summary param] 0 in init(buffer:) : | -| data.swift:19:2:19:62 | [summary param] 0 in init(buffer:) : | semmle.label | [summary param] 0 in init(buffer:) : | -| data.swift:20:2:20:45 | [summary param] 0 in init(bytes:count:) : | semmle.label | [summary param] 0 in init(bytes:count:) : | -| data.swift:21:2:21:82 | [summary param] 0 in init(bytesNoCopy:count:deallocator:) : | semmle.label | [summary param] 0 in init(bytesNoCopy:count:deallocator:) : | -| data.swift:22:2:22:50 | [summary param] 0 in init(contentsOf:options:) : | semmle.label | [summary param] 0 in init(contentsOf:options:) : | -| data.swift:23:2:23:29 | [summary param] 0 in init(referencing:) : | semmle.label | [summary param] 0 in init(referencing:) : | -| data.swift:24:2:24:24 | [summary param] 0 in append(_:) : | semmle.label | [summary param] 0 in append(_:) : | -| data.swift:25:2:25:25 | [summary param] 0 in append(_:) : | semmle.label | [summary param] 0 in append(_:) : | -| data.swift:26:2:26:63 | [summary param] 0 in append(_:) : | semmle.label | [summary param] 0 in append(_:) : | -| data.swift:27:2:27:52 | [summary param] 0 in append(_:count:) : | semmle.label | [summary param] 0 in append(_:count:) : | -| data.swift:28:2:28:36 | [summary param] 0 in append(contentsOf:) : | semmle.label | [summary param] 0 in append(contentsOf:) : | -| data.swift:30:2:30:88 | [summary param] this in base64EncodedData(options:) : | semmle.label | [summary param] this in base64EncodedData(options:) : | -| data.swift:31:2:31:86 | [summary param] this in base64EncodedString(options:) : | semmle.label | [summary param] this in base64EncodedString(options:) : | -| data.swift:32:2:32:99 | [summary param] this in compactMap(_:) : | semmle.label | [summary param] this in compactMap(_:) : | -| data.swift:33:2:33:53 | [summary param] this in copyBytes(to:) : | semmle.label | [summary param] this in copyBytes(to:) : | -| data.swift:36:2:36:137 | [summary param] this in flatMap(_:) : | semmle.label | [summary param] this in flatMap(_:) : | -| data.swift:37:2:37:97 | [summary param] this in flatMap(_:) : | semmle.label | [summary param] this in flatMap(_:) : | -| data.swift:38:2:38:34 | [summary param] 0 in insert(_:at:) : | semmle.label | [summary param] 0 in insert(_:at:) : | -| data.swift:39:2:39:83 | [summary param] 0 in insert(contentsOf:at:) : | semmle.label | [summary param] 0 in insert(contentsOf:at:) : | -| data.swift:40:2:40:50 | [summary param] this in map(_:) : | semmle.label | [summary param] this in map(_:) : | -| data.swift:41:2:41:115 | [summary param] this in reduce(into:_:) : | semmle.label | [summary param] this in reduce(into:_:) : | -| data.swift:42:2:42:180 | [summary param] 1 in replace(_:with:maxReplacements:) : | semmle.label | [summary param] 1 in replace(_:with:maxReplacements:) : | -| data.swift:43:2:43:58 | [summary param] 1 in replaceSubrange(_:with:) : | semmle.label | [summary param] 1 in replaceSubrange(_:with:) : | -| data.swift:44:2:44:151 | [summary param] 1 in replaceSubrange(_:with:) : | semmle.label | [summary param] 1 in replaceSubrange(_:with:) : | -| data.swift:46:2:46:82 | [summary param] 1 in replaceSubrange(_:with:count:) : | semmle.label | [summary param] 1 in replaceSubrange(_:with:count:) : | -| data.swift:48:2:48:214 | [summary param] 1 in replacing(_:with:maxReplacements:) : | semmle.label | [summary param] 1 in replacing(_:with:maxReplacements:) : | -| data.swift:49:2:49:236 | [summary param] 1 in replacing(_:with:subrange:maxReplacements:) : | semmle.label | [summary param] 1 in replacing(_:with:subrange:maxReplacements:) : | -| data.swift:50:2:50:41 | [summary param] this in shuffled() : | semmle.label | [summary param] this in shuffled() : | -| data.swift:51:2:51:58 | [summary param] this in shuffled(using:) : | semmle.label | [summary param] this in shuffled(using:) : | -| data.swift:52:2:52:132 | [summary param] this in sorted(using:) : | semmle.label | [summary param] this in sorted(using:) : | -| data.swift:53:2:53:123 | [summary param] this in trimmingPrefix(_:) : | semmle.label | [summary param] this in trimmingPrefix(_:) : | -| data.swift:54:2:54:72 | [summary param] this in trimmingPrefix(while:) : | semmle.label | [summary param] this in trimmingPrefix(while:) : | -| data.swift:79:21:79:71 | call to init(base64Encoded:options:) : | semmle.label | call to init(base64Encoded:options:) : | -| data.swift:79:41:79:48 | call to source() : | semmle.label | call to source() : | -| data.swift:80:12:80:12 | dataTainted3 | semmle.label | dataTainted3 | -| data.swift:83:21:83:73 | call to init(buffer:) : | semmle.label | call to init(buffer:) : | -| data.swift:83:34:83:41 | call to source() : | semmle.label | call to source() : | -| data.swift:84:12:84:12 | dataTainted4 | semmle.label | dataTainted4 | -| data.swift:85:21:85:74 | call to init(buffer:) : | semmle.label | call to init(buffer:) : | -| data.swift:85:34:85:41 | call to source() : | semmle.label | call to source() : | -| data.swift:86:12:86:12 | dataTainted5 | semmle.label | dataTainted5 | -| data.swift:89:21:89:72 | call to init(bytes:count:) : | semmle.label | call to init(bytes:count:) : | -| data.swift:89:33:89:40 | call to source() : | semmle.label | call to source() : | -| data.swift:90:12:90:12 | dataTainted6 | semmle.label | dataTainted6 | -| data.swift:93:21:93:114 | call to init(bytesNoCopy:count:deallocator:) : | semmle.label | call to init(bytesNoCopy:count:deallocator:) : | -| data.swift:93:39:93:46 | call to source() : | semmle.label | call to source() : | -| data.swift:94:12:94:12 | dataTainted7 | semmle.label | dataTainted7 | -| data.swift:97:21:97:67 | call to init(contentsOf:options:) : | semmle.label | call to init(contentsOf:options:) : | -| data.swift:97:38:97:45 | call to source() : | semmle.label | call to source() : | -| data.swift:98:12:98:12 | dataTainted8 | semmle.label | dataTainted8 | -| data.swift:101:21:101:58 | call to init(referencing:) : | semmle.label | call to init(referencing:) : | -| data.swift:101:39:101:46 | call to source() : | semmle.label | call to source() : | -| data.swift:102:12:102:12 | dataTainted9 | semmle.label | dataTainted9 | -| data.swift:106:2:106:2 | [post] dataTainted10 : | semmle.label | [post] dataTainted10 : | -| data.swift:106:23:106:30 | call to source() : | semmle.label | call to source() : | -| data.swift:107:12:107:12 | dataTainted10 | semmle.label | dataTainted10 | -| data.swift:110:2:110:2 | [post] dataTainted11 : | semmle.label | [post] dataTainted11 : | -| data.swift:110:23:110:30 | call to source() : | semmle.label | call to source() : | -| data.swift:111:12:111:12 | dataTainted11 | semmle.label | dataTainted11 | -| data.swift:114:2:114:2 | [post] dataTainted12 : | semmle.label | [post] dataTainted12 : | -| data.swift:114:23:114:30 | call to source() : | semmle.label | call to source() : | -| data.swift:115:12:115:12 | dataTainted12 | semmle.label | dataTainted12 | -| data.swift:119:2:119:2 | [post] dataTainted13 : | semmle.label | [post] dataTainted13 : | -| data.swift:119:23:119:30 | call to source() : | semmle.label | call to source() : | -| data.swift:120:12:120:12 | dataTainted13 | semmle.label | dataTainted13 | -| data.swift:124:2:124:2 | [post] dataTainted14 : | semmle.label | [post] dataTainted14 : | -| data.swift:124:35:124:42 | call to source() : | semmle.label | call to source() : | -| data.swift:125:12:125:12 | dataTainted14 | semmle.label | dataTainted14 | -| data.swift:128:22:128:29 | call to source() : | semmle.label | call to source() : | -| data.swift:129:12:129:12 | dataTainted15 : | semmle.label | dataTainted15 : | -| data.swift:129:12:129:55 | call to base64EncodedData(options:) | semmle.label | call to base64EncodedData(options:) | -| data.swift:132:22:132:29 | call to source() : | semmle.label | call to source() : | -| data.swift:133:12:133:12 | dataTainted16 : | semmle.label | dataTainted16 : | -| data.swift:133:12:133:57 | call to base64EncodedString(options:) | semmle.label | call to base64EncodedString(options:) | -| data.swift:136:22:136:29 | call to source() : | semmle.label | call to source() : | -| data.swift:137:29:137:29 | dataTainted17 : | semmle.label | dataTainted17 : | -| data.swift:137:29:137:72 | call to compactMap(_:) : | semmle.label | call to compactMap(_:) : | -| data.swift:138:12:138:12 | compactMapped | semmle.label | compactMapped | -| data.swift:141:22:141:29 | call to source() : | semmle.label | call to source() : | -| data.swift:143:2:143:2 | dataTainted18 : | semmle.label | dataTainted18 : | -| data.swift:143:30:143:30 | [post] pointerTainted18 : | semmle.label | [post] pointerTainted18 : | -| data.swift:144:12:144:12 | pointerTainted18 | semmle.label | pointerTainted18 | -| data.swift:159:22:159:29 | call to source() : | semmle.label | call to source() : | -| data.swift:160:19:160:19 | dataTainted21 : | semmle.label | dataTainted21 : | -| data.swift:160:19:160:74 | call to flatMap(_:) : | semmle.label | call to flatMap(_:) : | -| data.swift:161:12:161:12 | flatMapped | semmle.label | flatMapped | -| data.swift:163:22:163:29 | call to source() : | semmle.label | call to source() : | -| data.swift:164:20:164:20 | dataTainted22 : | semmle.label | dataTainted22 : | -| data.swift:164:20:164:60 | call to flatMap(_:) : | semmle.label | call to flatMap(_:) : | -| data.swift:165:12:165:12 | flatMapped2 | semmle.label | flatMapped2 | -| data.swift:169:2:169:2 | [post] dataTainted23 : | semmle.label | [post] dataTainted23 : | -| data.swift:169:23:169:30 | call to source() : | semmle.label | call to source() : | -| data.swift:170:12:170:12 | dataTainted23 | semmle.label | dataTainted23 | -| data.swift:174:2:174:2 | [post] dataTainted24 : | semmle.label | [post] dataTainted24 : | -| data.swift:174:35:174:42 | call to source() : | semmle.label | call to source() : | -| data.swift:175:12:175:12 | dataTainted24 | semmle.label | dataTainted24 | -| data.swift:178:22:178:29 | call to source() : | semmle.label | call to source() : | -| data.swift:179:15:179:15 | dataTainted25 : | semmle.label | dataTainted25 : | -| data.swift:179:15:179:38 | call to map(_:) : | semmle.label | call to map(_:) : | -| data.swift:180:12:180:12 | mapped | semmle.label | mapped | -| data.swift:183:22:183:29 | call to source() : | semmle.label | call to source() : | -| data.swift:184:16:184:16 | dataTainted26 : | semmle.label | dataTainted26 : | -| data.swift:184:16:184:80 | call to reduce(into:_:) : | semmle.label | call to reduce(into:_:) : | -| data.swift:185:12:185:12 | reduced | semmle.label | reduced | -| data.swift:189:2:189:2 | [post] dataTainted27 : | semmle.label | [post] dataTainted27 : | -| data.swift:189:35:189:42 | call to source() : | semmle.label | call to source() : | -| data.swift:190:12:190:12 | dataTainted27 | semmle.label | dataTainted27 | -| data.swift:194:2:194:2 | [post] dataTainted28 : | semmle.label | [post] dataTainted28 : | -| data.swift:194:45:194:52 | call to source() : | semmle.label | call to source() : | -| data.swift:195:12:195:12 | dataTainted28 | semmle.label | dataTainted28 | -| data.swift:198:2:198:2 | [post] dataTainted29 : | semmle.label | [post] dataTainted29 : | -| data.swift:198:45:198:52 | call to source() : | semmle.label | call to source() : | -| data.swift:199:12:199:12 | dataTainted29 | semmle.label | dataTainted29 | -| data.swift:202:2:202:2 | [post] dataTainted30 : | semmle.label | [post] dataTainted30 : | -| data.swift:202:45:202:52 | call to source() : | semmle.label | call to source() : | -| data.swift:203:12:203:12 | dataTainted30 | semmle.label | dataTainted30 | -| data.swift:207:2:207:2 | [post] dataTainted31 : | semmle.label | [post] dataTainted31 : | -| data.swift:207:45:207:52 | call to source() : | semmle.label | call to source() : | -| data.swift:208:12:208:12 | dataTainted31 | semmle.label | dataTainted31 | -| data.swift:212:2:212:2 | [post] dataTainted32 : | semmle.label | [post] dataTainted32 : | -| data.swift:212:37:212:44 | call to source() : | semmle.label | call to source() : | -| data.swift:213:12:213:12 | dataTainted32 | semmle.label | dataTainted32 | -| data.swift:217:2:217:2 | [post] dataTainted33 : | semmle.label | [post] dataTainted33 : | -| data.swift:217:37:217:44 | call to source() : | semmle.label | call to source() : | -| data.swift:218:12:218:12 | dataTainted33 | semmle.label | dataTainted33 | -| data.swift:221:22:221:29 | call to source() : | semmle.label | call to source() : | -| data.swift:222:12:222:12 | dataTainted34 : | semmle.label | dataTainted34 : | -| data.swift:222:12:222:35 | call to shuffled() | semmle.label | call to shuffled() | -| data.swift:225:22:225:29 | call to source() : | semmle.label | call to source() : | -| data.swift:227:12:227:12 | dataTainted35 : | semmle.label | dataTainted35 : | -| data.swift:227:12:227:46 | call to shuffled(using:) | semmle.label | call to shuffled(using:) | -| data.swift:230:22:230:29 | call to source() : | semmle.label | call to source() : | -| data.swift:231:12:231:12 | dataTainted36 : | semmle.label | dataTainted36 : | -| data.swift:231:12:231:46 | call to sorted(using:) | semmle.label | call to sorted(using:) | -| data.swift:234:22:234:29 | call to source() : | semmle.label | call to source() : | -| data.swift:235:12:235:12 | dataTainted37 : | semmle.label | dataTainted37 : | -| data.swift:235:12:235:44 | call to trimmingPrefix(_:) | semmle.label | call to trimmingPrefix(_:) | -| data.swift:238:22:238:29 | call to source() : | semmle.label | call to source() : | -| data.swift:239:12:239:12 | dataTainted38 : | semmle.label | dataTainted38 : | -| data.swift:239:12:239:54 | call to trimmingPrefix(while:) | semmle.label | call to trimmingPrefix(while:) | -| file://:0:0:0:0 | [summary] to write: argument 0 in copyBytes(to:) : | semmle.label | [summary] to write: argument 0 in copyBytes(to:) : | -| file://:0:0:0:0 | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : | semmle.label | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : | | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | semmle.label | [summary] to write: argument this in append(_:) : | | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | semmle.label | [summary] to write: argument this in append(_:) : | | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | semmle.label | [summary] to write: argument this in append(_:) : | | file://:0:0:0:0 | [summary] to write: argument this in append(_:count:) : | semmle.label | [summary] to write: argument this in append(_:count:) : | +| file://:0:0:0:0 | [summary] to write: argument this in append(_:length:) : | semmle.label | [summary] to write: argument this in append(_:length:) : | | file://:0:0:0:0 | [summary] to write: argument this in append(contentsOf:) : | semmle.label | [summary] to write: argument this in append(contentsOf:) : | | file://:0:0:0:0 | [summary] to write: argument this in defineProperty(_:descriptor:) : | semmle.label | [summary] to write: argument this in defineProperty(_:descriptor:) : | | file://:0:0:0:0 | [summary] to write: argument this in insert(_:at:) : | semmle.label | [summary] to write: argument this in insert(_:at:) : | | file://:0:0:0:0 | [summary] to write: argument this in insert(contentsOf:at:) : | semmle.label | [summary] to write: argument this in insert(contentsOf:at:) : | | file://:0:0:0:0 | [summary] to write: argument this in replace(_:with:maxReplacements:) : | semmle.label | [summary] to write: argument this in replace(_:with:maxReplacements:) : | +| file://:0:0:0:0 | [summary] to write: argument this in replaceBytes(in:withBytes:) : | semmle.label | [summary] to write: argument this in replaceBytes(in:withBytes:) : | +| file://:0:0:0:0 | [summary] to write: argument this in replaceBytes(in:withBytes:length:) : | semmle.label | [summary] to write: argument this in replaceBytes(in:withBytes:length:) : | | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | semmle.label | [summary] to write: argument this in replaceSubrange(_:with:) : | | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | semmle.label | [summary] to write: argument this in replaceSubrange(_:with:) : | | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:count:) : | semmle.label | [summary] to write: argument this in replaceSubrange(_:with:count:) : | | file://:0:0:0:0 | [summary] to write: argument this in replacing(_:with:maxReplacements:) : | semmle.label | [summary] to write: argument this in replacing(_:with:maxReplacements:) : | | file://:0:0:0:0 | [summary] to write: argument this in replacing(_:with:subrange:maxReplacements:) : | semmle.label | [summary] to write: argument this in replacing(_:with:subrange:maxReplacements:) : | ->>>>>>> 7ef2618758 (Update test expectations) +| file://:0:0:0:0 | [summary] to write: argument this in setData(_:) : | semmle.label | [summary] to write: argument this in setData(_:) : | | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:at:) : | semmle.label | [summary] to write: argument this in setValue(_:at:) : | | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:forProperty:) : | semmle.label | [summary] to write: argument this in setValue(_:forProperty:) : | | file://:0:0:0:0 | [summary] to write: return (return) in atIndex(_:) : | semmle.label | [summary] to write: return (return) in atIndex(_:) : | | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedData(options:) : | semmle.label | [summary] to write: return (return) in base64EncodedData(options:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedData(options:) : | semmle.label | [summary] to write: return (return) in base64EncodedData(options:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedString(options:) : | semmle.label | [summary] to write: return (return) in base64EncodedString(options:) : | | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedString(options:) : | semmle.label | [summary] to write: return (return) in base64EncodedString(options:) : | -<<<<<<< HEAD | file://:0:0:0:0 | [summary] to write: return (return) in base64Encoding() : | semmle.label | [summary] to write: return (return) in base64Encoding() : | +| file://:0:0:0:0 | [summary] to write: return (return) in compactMap(_:) : | semmle.label | [summary] to write: return (return) in compactMap(_:) : | | file://:0:0:0:0 | [summary] to write: return (return) in compressed(using:) : | semmle.label | [summary] to write: return (return) in compressed(using:) : | | file://:0:0:0:0 | [summary] to write: return (return) in dataWithContentsOfMappedFile(_:) : | semmle.label | [summary] to write: return (return) in dataWithContentsOfMappedFile(_:) : | | file://:0:0:0:0 | [summary] to write: return (return) in decompressed(using:) : | semmle.label | [summary] to write: return (return) in decompressed(using:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | semmle.label | [summary] to write: return (return) in flatMap(_:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | semmle.label | [summary] to write: return (return) in flatMap(_:) : | | file://:0:0:0:0 | [summary] to write: return (return) in forProperty(_:) : | semmle.label | [summary] to write: return (return) in forProperty(_:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | semmle.label | [summary] to write: return (return) in init(base64Encoded:options:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | semmle.label | [summary] to write: return (return) in init(base64Encoded:options:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | semmle.label | [summary] to write: return (return) in init(base64Encoded:options:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoding:) : | semmle.label | [summary] to write: return (return) in init(base64Encoding:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(bool:in:) : | semmle.label | [summary] to write: return (return) in init(bool:in:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | semmle.label | [summary] to write: return (return) in init(buffer:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | semmle.label | [summary] to write: return (return) in init(buffer:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(bytes:count:) : | semmle.label | [summary] to write: return (return) in init(bytes:count:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(bytes:length:) : | semmle.label | [summary] to write: return (return) in init(bytes:length:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:count:deallocator:) : | semmle.label | [summary] to write: return (return) in init(bytesNoCopy:count:deallocator:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:length:) : | semmle.label | [summary] to write: return (return) in init(bytesNoCopy:length:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:length:deallocator:) : | semmle.label | [summary] to write: return (return) in init(bytesNoCopy:length:deallocator:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:length:freeWhenDone:) : | semmle.label | [summary] to write: return (return) in init(bytesNoCopy:length:freeWhenDone:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOf:) : | semmle.label | [summary] to write: return (return) in init(contentsOf:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOf:options:) : | semmle.label | [summary] to write: return (return) in init(contentsOf:options:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOf:options:) : | semmle.label | [summary] to write: return (return) in init(contentsOf:options:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOfFile:) : | semmle.label | [summary] to write: return (return) in init(contentsOfFile:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOfFile:options:) : | semmle.label | [summary] to write: return (return) in init(contentsOfFile:options:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOfMappedFile:) : | semmle.label | [summary] to write: return (return) in init(contentsOfMappedFile:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(data:) : | semmle.label | [summary] to write: return (return) in init(data:) : | -======= -| file://:0:0:0:0 | [summary] to write: return (return) in compactMap(_:) : | semmle.label | [summary] to write: return (return) in compactMap(_:) : | -| file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | semmle.label | [summary] to write: return (return) in flatMap(_:) : | -| file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | semmle.label | [summary] to write: return (return) in flatMap(_:) : | -| file://:0:0:0:0 | [summary] to write: return (return) in forProperty(_:) : | semmle.label | [summary] to write: return (return) in forProperty(_:) : | -| file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | semmle.label | [summary] to write: return (return) in init(base64Encoded:options:) : | -| file://:0:0:0:0 | [summary] to write: return (return) in init(bool:in:) : | semmle.label | [summary] to write: return (return) in init(bool:in:) : | -| file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | semmle.label | [summary] to write: return (return) in init(buffer:) : | -| file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | semmle.label | [summary] to write: return (return) in init(buffer:) : | -| file://:0:0:0:0 | [summary] to write: return (return) in init(bytes:count:) : | semmle.label | [summary] to write: return (return) in init(bytes:count:) : | -| file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:count:deallocator:) : | semmle.label | [summary] to write: return (return) in init(bytesNoCopy:count:deallocator:) : | -| file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOf:options:) : | semmle.label | [summary] to write: return (return) in init(contentsOf:options:) : | ->>>>>>> 7ef2618758 (Update test expectations) | file://:0:0:0:0 | [summary] to write: return (return) in init(double:in:) : | semmle.label | [summary] to write: return (return) in init(double:in:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(int32:in:) : | semmle.label | [summary] to write: return (return) in init(int32:in:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(object:in:) : | semmle.label | [summary] to write: return (return) in init(object:in:) : | @@ -746,15 +756,14 @@ nodes | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | semmle.label | [summary] to write: return (return) in init(string:relativeTo:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | semmle.label | [summary] to write: return (return) in init(string:relativeTo:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(uInt32:in:) : | semmle.label | [summary] to write: return (return) in init(uInt32:in:) : | -<<<<<<< HEAD -| file://:0:0:0:0 | [summary] to write: return (return) in subdata(with:) : | semmle.label | [summary] to write: return (return) in subdata(with:) : | -======= | file://:0:0:0:0 | [summary] to write: return (return) in map(_:) : | semmle.label | [summary] to write: return (return) in map(_:) : | | file://:0:0:0:0 | [summary] to write: return (return) in reduce(into:_:) : | semmle.label | [summary] to write: return (return) in reduce(into:_:) : | | file://:0:0:0:0 | [summary] to write: return (return) in shuffled() : | semmle.label | [summary] to write: return (return) in shuffled() : | | file://:0:0:0:0 | [summary] to write: return (return) in shuffled(using:) : | semmle.label | [summary] to write: return (return) in shuffled(using:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in sorted() : | semmle.label | [summary] to write: return (return) in sorted() : | +| file://:0:0:0:0 | [summary] to write: return (return) in sorted(by:) : | semmle.label | [summary] to write: return (return) in sorted(by:) : | | file://:0:0:0:0 | [summary] to write: return (return) in sorted(using:) : | semmle.label | [summary] to write: return (return) in sorted(using:) : | ->>>>>>> 7ef2618758 (Update test expectations) +| file://:0:0:0:0 | [summary] to write: return (return) in subdata(with:) : | semmle.label | [summary] to write: return (return) in subdata(with:) : | | file://:0:0:0:0 | [summary] to write: return (return) in toArray() : | semmle.label | [summary] to write: return (return) in toArray() : | | file://:0:0:0:0 | [summary] to write: return (return) in toBool() : | semmle.label | [summary] to write: return (return) in toBool() : | | file://:0:0:0:0 | [summary] to write: return (return) in toDate() : | semmle.label | [summary] to write: return (return) in toDate() : | @@ -770,7 +779,8 @@ nodes | file://:0:0:0:0 | [summary] to write: return (return) in toSize() : | semmle.label | [summary] to write: return (return) in toSize() : | | file://:0:0:0:0 | [summary] to write: return (return) in toString() : | semmle.label | [summary] to write: return (return) in toString() : | | file://:0:0:0:0 | [summary] to write: return (return) in toUInt32() : | semmle.label | [summary] to write: return (return) in toUInt32() : | -<<<<<<< HEAD +| file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(_:) : | semmle.label | [summary] to write: return (return) in trimmingPrefix(_:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(while:) : | semmle.label | [summary] to write: return (return) in trimmingPrefix(while:) : | | nsdata.swift:22:9:22:9 | self : | semmle.label | self : | | nsdata.swift:23:9:23:9 | self : | semmle.label | self : | | nsdata.swift:24:5:24:50 | [summary param] 0 in init(bytes:length:) : | semmle.label | [summary param] 0 in init(bytes:length:) : | @@ -906,10 +916,6 @@ nodes | nsmutabledata.swift:48:33:48:40 | call to source() : | semmle.label | call to source() : | | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 : | semmle.label | nsMutableDataTainted6 : | | nsmutabledata.swift:49:15:49:37 | .mutableBytes | semmle.label | .mutableBytes | -======= -| file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(_:) : | semmle.label | [summary] to write: return (return) in trimmingPrefix(_:) : | -| file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(while:) : | semmle.label | [summary] to write: return (return) in trimmingPrefix(while:) : | ->>>>>>> 7ef2618758 (Update test expectations) | string.swift:5:11:5:18 | call to source() : | semmle.label | call to source() : | | string.swift:7:13:7:13 | "..." | semmle.label | "..." | | string.swift:9:13:9:13 | "..." | semmle.label | "..." | @@ -1111,7 +1117,42 @@ nodes | webview.swift:97:17:97:17 | s : | semmle.label | s : | | webview.swift:98:10:98:10 | v3 | semmle.label | v3 | subpaths -<<<<<<< HEAD +| data.swift:89:41:89:48 | call to source() : | data.swift:25:2:25:66 | [summary param] 0 in init(base64Encoded:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | data.swift:89:21:89:71 | call to init(base64Encoded:options:) : | +| data.swift:93:34:93:41 | call to source() : | data.swift:26:2:26:61 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | data.swift:93:21:93:73 | call to init(buffer:) : | +| data.swift:95:34:95:41 | call to source() : | data.swift:27:2:27:62 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | data.swift:95:21:95:74 | call to init(buffer:) : | +| data.swift:99:33:99:40 | call to source() : | data.swift:28:2:28:45 | [summary param] 0 in init(bytes:count:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytes:count:) : | data.swift:99:21:99:72 | call to init(bytes:count:) : | +| data.swift:103:39:103:46 | call to source() : | data.swift:29:2:29:82 | [summary param] 0 in init(bytesNoCopy:count:deallocator:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:count:deallocator:) : | data.swift:103:21:103:114 | call to init(bytesNoCopy:count:deallocator:) : | +| data.swift:108:38:108:38 | urlTainted8 : | data.swift:30:2:30:50 | [summary param] 0 in init(contentsOf:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOf:options:) : | data.swift:108:21:108:62 | call to init(contentsOf:options:) : | +| data.swift:112:39:112:46 | call to source() : | data.swift:31:2:31:29 | [summary param] 0 in init(referencing:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(referencing:) : | data.swift:112:21:112:58 | call to init(referencing:) : | +| data.swift:117:23:117:30 | call to source() : | data.swift:32:2:32:24 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | data.swift:117:2:117:2 | [post] dataTainted10 : | +| data.swift:121:23:121:30 | call to source() : | data.swift:33:2:33:25 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | data.swift:121:2:121:2 | [post] dataTainted11 : | +| data.swift:125:23:125:30 | call to source() : | data.swift:34:2:34:63 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | data.swift:125:2:125:2 | [post] dataTainted12 : | +| data.swift:130:23:130:30 | call to source() : | data.swift:35:2:35:52 | [summary param] 0 in append(_:count:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:count:) : | data.swift:130:2:130:2 | [post] dataTainted13 : | +| data.swift:135:35:135:42 | call to source() : | data.swift:36:2:36:36 | [summary param] 0 in append(contentsOf:) : | file://:0:0:0:0 | [summary] to write: argument this in append(contentsOf:) : | data.swift:135:2:135:2 | [post] dataTainted14 : | +| data.swift:140:12:140:12 | dataTainted15 : | data.swift:38:2:38:88 | [summary param] this in base64EncodedData(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedData(options:) : | data.swift:140:12:140:55 | call to base64EncodedData(options:) | +| data.swift:144:12:144:12 | dataTainted16 : | data.swift:39:2:39:86 | [summary param] this in base64EncodedString(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedString(options:) : | data.swift:144:12:144:57 | call to base64EncodedString(options:) | +| data.swift:148:29:148:29 | dataTainted17 : | data.swift:40:2:40:99 | [summary param] this in compactMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in compactMap(_:) : | data.swift:148:29:148:72 | call to compactMap(_:) : | +| data.swift:154:2:154:2 | dataTainted18 : | data.swift:41:2:41:53 | [summary param] this in copyBytes(to:) : | file://:0:0:0:0 | [summary] to write: argument 0 in copyBytes(to:) : | data.swift:154:30:154:30 | [post] pointerTainted18 : | +| data.swift:171:19:171:19 | dataTainted21 : | data.swift:44:2:44:137 | [summary param] this in flatMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | data.swift:171:19:171:74 | call to flatMap(_:) : | +| data.swift:175:20:175:20 | dataTainted22 : | data.swift:45:2:45:97 | [summary param] this in flatMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | data.swift:175:20:175:60 | call to flatMap(_:) : | +| data.swift:180:23:180:30 | call to source() : | data.swift:46:2:46:34 | [summary param] 0 in insert(_:at:) : | file://:0:0:0:0 | [summary] to write: argument this in insert(_:at:) : | data.swift:180:2:180:2 | [post] dataTainted23 : | +| data.swift:185:35:185:42 | call to source() : | data.swift:47:2:47:83 | [summary param] 0 in insert(contentsOf:at:) : | file://:0:0:0:0 | [summary] to write: argument this in insert(contentsOf:at:) : | data.swift:185:2:185:2 | [post] dataTainted24 : | +| data.swift:190:15:190:15 | dataTainted25 : | data.swift:48:2:48:50 | [summary param] this in map(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in map(_:) : | data.swift:190:15:190:38 | call to map(_:) : | +| data.swift:195:16:195:16 | dataTainted26 : | data.swift:49:2:49:115 | [summary param] this in reduce(into:_:) : | file://:0:0:0:0 | [summary] to write: return (return) in reduce(into:_:) : | data.swift:195:16:195:80 | call to reduce(into:_:) : | +| data.swift:200:35:200:42 | call to source() : | data.swift:50:2:50:180 | [summary param] 1 in replace(_:with:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replace(_:with:maxReplacements:) : | data.swift:200:2:200:2 | [post] dataTainted27 : | +| data.swift:205:45:205:52 | call to source() : | data.swift:51:2:51:58 | [summary param] 1 in replaceSubrange(_:with:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | data.swift:205:2:205:2 | [post] dataTainted28 : | +| data.swift:209:45:209:52 | call to source() : | data.swift:52:2:52:151 | [summary param] 1 in replaceSubrange(_:with:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | data.swift:209:2:209:2 | [post] dataTainted29 : | +| data.swift:213:45:213:52 | call to source() : | data.swift:52:2:52:151 | [summary param] 1 in replaceSubrange(_:with:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | data.swift:213:2:213:2 | [post] dataTainted30 : | +| data.swift:218:45:218:52 | call to source() : | data.swift:54:2:54:82 | [summary param] 1 in replaceSubrange(_:with:count:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:count:) : | data.swift:218:2:218:2 | [post] dataTainted31 : | +| data.swift:223:45:223:52 | call to source() : | data.swift:56:2:56:214 | [summary param] 1 in replacing(_:with:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replacing(_:with:maxReplacements:) : | data.swift:223:10:223:10 | [post] dataTainted32 : | +| data.swift:228:45:228:52 | call to source() : | data.swift:57:2:57:236 | [summary param] 1 in replacing(_:with:subrange:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replacing(_:with:subrange:maxReplacements:) : | data.swift:228:10:228:10 | [post] dataTainted33 : | +| data.swift:237:12:237:12 | dataTainted35 : | data.swift:58:2:58:39 | [summary param] this in sorted() : | file://:0:0:0:0 | [summary] to write: return (return) in sorted() : | data.swift:237:12:237:33 | call to sorted() | +| data.swift:241:12:241:12 | dataTainted36 : | data.swift:59:2:59:81 | [summary param] this in sorted(by:) : | file://:0:0:0:0 | [summary] to write: return (return) in sorted(by:) : | data.swift:241:12:241:54 | call to sorted(by:) | +| data.swift:245:12:245:12 | dataTainted37 : | data.swift:60:2:60:132 | [summary param] this in sorted(using:) : | file://:0:0:0:0 | [summary] to write: return (return) in sorted(using:) : | data.swift:245:12:245:46 | call to sorted(using:) | +| data.swift:249:12:249:12 | dataTainted38 : | data.swift:61:2:61:41 | [summary param] this in shuffled() : | file://:0:0:0:0 | [summary] to write: return (return) in shuffled() : | data.swift:249:12:249:35 | call to shuffled() | +| data.swift:254:12:254:12 | dataTainted39 : | data.swift:62:2:62:58 | [summary param] this in shuffled(using:) : | file://:0:0:0:0 | [summary] to write: return (return) in shuffled(using:) : | data.swift:254:12:254:46 | call to shuffled(using:) | +| data.swift:258:12:258:12 | dataTainted40 : | data.swift:63:2:63:123 | [summary param] this in trimmingPrefix(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(_:) : | data.swift:258:12:258:44 | call to trimmingPrefix(_:) | +| data.swift:262:12:262:12 | dataTainted41 : | data.swift:64:2:64:72 | [summary param] this in trimmingPrefix(while:) : | file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(while:) : | data.swift:262:12:262:54 | call to trimmingPrefix(while:) | | nsdata.swift:57:40:57:47 | call to source() : | nsdata.swift:24:5:24:50 | [summary param] 0 in init(bytes:length:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytes:length:) : | nsdata.swift:57:26:57:80 | call to init(bytes:length:) : | | nsdata.swift:60:46:60:53 | call to source() : | nsdata.swift:25:5:25:68 | [summary param] 0 in init(bytesNoCopy:length:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:length:) : | nsdata.swift:60:26:60:93 | call to init(bytesNoCopy:length:) : | | nsdata.swift:63:46:63:53 | call to source() : | nsdata.swift:26:5:26:130 | [summary param] 0 in init(bytesNoCopy:length:deallocator:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:length:deallocator:) : | nsdata.swift:63:26:63:111 | call to init(bytesNoCopy:length:deallocator:) : | @@ -1145,42 +1186,6 @@ subpaths | nsmutabledata.swift:40:66:40:73 | call to source() : | nsmutabledata.swift:17:5:17:121 | [summary param] 1 in replaceBytes(in:withBytes:length:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceBytes(in:withBytes:length:) : | nsmutabledata.swift:40:5:40:5 | [post] nsMutableDataTainted4 : | | nsmutabledata.swift:44:35:44:42 | call to source() : | nsmutabledata.swift:18:5:18:33 | [summary param] 0 in setData(_:) : | file://:0:0:0:0 | [summary] to write: argument this in setData(_:) : | nsmutabledata.swift:44:5:44:5 | [post] nsMutableDataTainted5 : | | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 : | nsmutabledata.swift:13:9:13:9 | self : | file://:0:0:0:0 | .mutableBytes : | nsmutabledata.swift:49:15:49:37 | .mutableBytes | -======= -| data.swift:79:41:79:48 | call to source() : | data.swift:17:2:17:66 | [summary param] 0 in init(base64Encoded:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | data.swift:79:21:79:71 | call to init(base64Encoded:options:) : | -| data.swift:83:34:83:41 | call to source() : | data.swift:18:2:18:61 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | data.swift:83:21:83:73 | call to init(buffer:) : | -| data.swift:85:34:85:41 | call to source() : | data.swift:19:2:19:62 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | data.swift:85:21:85:74 | call to init(buffer:) : | -| data.swift:89:33:89:40 | call to source() : | data.swift:20:2:20:45 | [summary param] 0 in init(bytes:count:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytes:count:) : | data.swift:89:21:89:72 | call to init(bytes:count:) : | -| data.swift:93:39:93:46 | call to source() : | data.swift:21:2:21:82 | [summary param] 0 in init(bytesNoCopy:count:deallocator:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bytesNoCopy:count:deallocator:) : | data.swift:93:21:93:114 | call to init(bytesNoCopy:count:deallocator:) : | -| data.swift:97:38:97:45 | call to source() : | data.swift:22:2:22:50 | [summary param] 0 in init(contentsOf:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(contentsOf:options:) : | data.swift:97:21:97:67 | call to init(contentsOf:options:) : | -| data.swift:101:39:101:46 | call to source() : | data.swift:23:2:23:29 | [summary param] 0 in init(referencing:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(referencing:) : | data.swift:101:21:101:58 | call to init(referencing:) : | -| data.swift:106:23:106:30 | call to source() : | data.swift:24:2:24:24 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | data.swift:106:2:106:2 | [post] dataTainted10 : | -| data.swift:110:23:110:30 | call to source() : | data.swift:25:2:25:25 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | data.swift:110:2:110:2 | [post] dataTainted11 : | -| data.swift:114:23:114:30 | call to source() : | data.swift:26:2:26:63 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | data.swift:114:2:114:2 | [post] dataTainted12 : | -| data.swift:119:23:119:30 | call to source() : | data.swift:27:2:27:52 | [summary param] 0 in append(_:count:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:count:) : | data.swift:119:2:119:2 | [post] dataTainted13 : | -| data.swift:124:35:124:42 | call to source() : | data.swift:28:2:28:36 | [summary param] 0 in append(contentsOf:) : | file://:0:0:0:0 | [summary] to write: argument this in append(contentsOf:) : | data.swift:124:2:124:2 | [post] dataTainted14 : | -| data.swift:129:12:129:12 | dataTainted15 : | data.swift:30:2:30:88 | [summary param] this in base64EncodedData(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedData(options:) : | data.swift:129:12:129:55 | call to base64EncodedData(options:) | -| data.swift:133:12:133:12 | dataTainted16 : | data.swift:31:2:31:86 | [summary param] this in base64EncodedString(options:) : | file://:0:0:0:0 | [summary] to write: return (return) in base64EncodedString(options:) : | data.swift:133:12:133:57 | call to base64EncodedString(options:) | -| data.swift:137:29:137:29 | dataTainted17 : | data.swift:32:2:32:99 | [summary param] this in compactMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in compactMap(_:) : | data.swift:137:29:137:72 | call to compactMap(_:) : | -| data.swift:143:2:143:2 | dataTainted18 : | data.swift:33:2:33:53 | [summary param] this in copyBytes(to:) : | file://:0:0:0:0 | [summary] to write: argument 0 in copyBytes(to:) : | data.swift:143:30:143:30 | [post] pointerTainted18 : | -| data.swift:160:19:160:19 | dataTainted21 : | data.swift:36:2:36:137 | [summary param] this in flatMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | data.swift:160:19:160:74 | call to flatMap(_:) : | -| data.swift:164:20:164:20 | dataTainted22 : | data.swift:37:2:37:97 | [summary param] this in flatMap(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | data.swift:164:20:164:60 | call to flatMap(_:) : | -| data.swift:169:23:169:30 | call to source() : | data.swift:38:2:38:34 | [summary param] 0 in insert(_:at:) : | file://:0:0:0:0 | [summary] to write: argument this in insert(_:at:) : | data.swift:169:2:169:2 | [post] dataTainted23 : | -| data.swift:174:35:174:42 | call to source() : | data.swift:39:2:39:83 | [summary param] 0 in insert(contentsOf:at:) : | file://:0:0:0:0 | [summary] to write: argument this in insert(contentsOf:at:) : | data.swift:174:2:174:2 | [post] dataTainted24 : | -| data.swift:179:15:179:15 | dataTainted25 : | data.swift:40:2:40:50 | [summary param] this in map(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in map(_:) : | data.swift:179:15:179:38 | call to map(_:) : | -| data.swift:184:16:184:16 | dataTainted26 : | data.swift:41:2:41:115 | [summary param] this in reduce(into:_:) : | file://:0:0:0:0 | [summary] to write: return (return) in reduce(into:_:) : | data.swift:184:16:184:80 | call to reduce(into:_:) : | -| data.swift:189:35:189:42 | call to source() : | data.swift:42:2:42:180 | [summary param] 1 in replace(_:with:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replace(_:with:maxReplacements:) : | data.swift:189:2:189:2 | [post] dataTainted27 : | -| data.swift:194:45:194:52 | call to source() : | data.swift:43:2:43:58 | [summary param] 1 in replaceSubrange(_:with:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | data.swift:194:2:194:2 | [post] dataTainted28 : | -| data.swift:198:45:198:52 | call to source() : | data.swift:44:2:44:151 | [summary param] 1 in replaceSubrange(_:with:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | data.swift:198:2:198:2 | [post] dataTainted29 : | -| data.swift:202:45:202:52 | call to source() : | data.swift:44:2:44:151 | [summary param] 1 in replaceSubrange(_:with:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:) : | data.swift:202:2:202:2 | [post] dataTainted30 : | -| data.swift:207:45:207:52 | call to source() : | data.swift:46:2:46:82 | [summary param] 1 in replaceSubrange(_:with:count:) : | file://:0:0:0:0 | [summary] to write: argument this in replaceSubrange(_:with:count:) : | data.swift:207:2:207:2 | [post] dataTainted31 : | -| data.swift:212:37:212:44 | call to source() : | data.swift:48:2:48:214 | [summary param] 1 in replacing(_:with:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replacing(_:with:maxReplacements:) : | data.swift:212:2:212:2 | [post] dataTainted32 : | -| data.swift:217:37:217:44 | call to source() : | data.swift:49:2:49:236 | [summary param] 1 in replacing(_:with:subrange:maxReplacements:) : | file://:0:0:0:0 | [summary] to write: argument this in replacing(_:with:subrange:maxReplacements:) : | data.swift:217:2:217:2 | [post] dataTainted33 : | -| data.swift:222:12:222:12 | dataTainted34 : | data.swift:50:2:50:41 | [summary param] this in shuffled() : | file://:0:0:0:0 | [summary] to write: return (return) in shuffled() : | data.swift:222:12:222:35 | call to shuffled() | -| data.swift:227:12:227:12 | dataTainted35 : | data.swift:51:2:51:58 | [summary param] this in shuffled(using:) : | file://:0:0:0:0 | [summary] to write: return (return) in shuffled(using:) : | data.swift:227:12:227:46 | call to shuffled(using:) | -| data.swift:231:12:231:12 | dataTainted36 : | data.swift:52:2:52:132 | [summary param] this in sorted(using:) : | file://:0:0:0:0 | [summary] to write: return (return) in sorted(using:) : | data.swift:231:12:231:46 | call to sorted(using:) | -| data.swift:235:12:235:12 | dataTainted37 : | data.swift:53:2:53:123 | [summary param] this in trimmingPrefix(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(_:) : | data.swift:235:12:235:44 | call to trimmingPrefix(_:) | -| data.swift:239:12:239:12 | dataTainted38 : | data.swift:54:2:54:72 | [summary param] this in trimmingPrefix(while:) : | file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(while:) : | data.swift:239:12:239:54 | call to trimmingPrefix(while:) | ->>>>>>> 7ef2618758 (Update test expectations) | url.swift:59:31:59:31 | tainted : | url.swift:8:2:8:25 | [summary param] 0 in init(string:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | url.swift:59:19:59:38 | call to init(string:) : | | url.swift:83:24:83:24 | tainted : | url.swift:9:2:9:43 | [summary param] 0 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | url.swift:83:12:83:48 | call to init(string:relativeTo:) : | | url.swift:86:43:86:43 | urlTainted : | url.swift:9:2:9:43 | [summary param] 1 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | url.swift:86:12:86:53 | call to init(string:relativeTo:) : | @@ -1231,7 +1236,42 @@ subpaths | webview.swift:93:17:93:17 | s : | webview.swift:43:5:43:38 | [summary param] 0 in setValue(_:at:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:at:) : | webview.swift:93:5:93:5 | [post] v2 : | | webview.swift:97:17:97:17 | s : | webview.swift:44:5:44:48 | [summary param] 0 in setValue(_:forProperty:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:forProperty:) : | webview.swift:97:5:97:5 | [post] v3 : | #select -<<<<<<< HEAD +| data.swift:90:12:90:12 | dataTainted3 | data.swift:89:41:89:48 | call to source() : | data.swift:90:12:90:12 | dataTainted3 | result | +| data.swift:94:12:94:12 | dataTainted4 | data.swift:93:34:93:41 | call to source() : | data.swift:94:12:94:12 | dataTainted4 | result | +| data.swift:96:12:96:12 | dataTainted5 | data.swift:95:34:95:41 | call to source() : | data.swift:96:12:96:12 | dataTainted5 | result | +| data.swift:100:12:100:12 | dataTainted6 | data.swift:99:33:99:40 | call to source() : | data.swift:100:12:100:12 | dataTainted6 | result | +| data.swift:104:12:104:12 | dataTainted7 | data.swift:103:39:103:46 | call to source() : | data.swift:104:12:104:12 | dataTainted7 | result | +| data.swift:109:12:109:12 | dataTainted8 | data.swift:107:20:107:27 | call to source() : | data.swift:109:12:109:12 | dataTainted8 | result | +| data.swift:113:12:113:12 | dataTainted9 | data.swift:112:39:112:46 | call to source() : | data.swift:113:12:113:12 | dataTainted9 | result | +| data.swift:118:12:118:12 | dataTainted10 | data.swift:117:23:117:30 | call to source() : | data.swift:118:12:118:12 | dataTainted10 | result | +| data.swift:122:12:122:12 | dataTainted11 | data.swift:121:23:121:30 | call to source() : | data.swift:122:12:122:12 | dataTainted11 | result | +| data.swift:126:12:126:12 | dataTainted12 | data.swift:125:23:125:30 | call to source() : | data.swift:126:12:126:12 | dataTainted12 | result | +| data.swift:131:12:131:12 | dataTainted13 | data.swift:130:23:130:30 | call to source() : | data.swift:131:12:131:12 | dataTainted13 | result | +| data.swift:136:12:136:12 | dataTainted14 | data.swift:135:35:135:42 | call to source() : | data.swift:136:12:136:12 | dataTainted14 | result | +| data.swift:140:12:140:55 | call to base64EncodedData(options:) | data.swift:139:22:139:29 | call to source() : | data.swift:140:12:140:55 | call to base64EncodedData(options:) | result | +| data.swift:144:12:144:57 | call to base64EncodedString(options:) | data.swift:143:22:143:29 | call to source() : | data.swift:144:12:144:57 | call to base64EncodedString(options:) | result | +| data.swift:149:12:149:12 | compactMapped | data.swift:147:22:147:29 | call to source() : | data.swift:149:12:149:12 | compactMapped | result | +| data.swift:155:12:155:12 | pointerTainted18 | data.swift:152:22:152:29 | call to source() : | data.swift:155:12:155:12 | pointerTainted18 | result | +| data.swift:172:12:172:12 | flatMapped | data.swift:170:22:170:29 | call to source() : | data.swift:172:12:172:12 | flatMapped | result | +| data.swift:176:12:176:12 | flatMapped2 | data.swift:174:22:174:29 | call to source() : | data.swift:176:12:176:12 | flatMapped2 | result | +| data.swift:181:12:181:12 | dataTainted23 | data.swift:180:23:180:30 | call to source() : | data.swift:181:12:181:12 | dataTainted23 | result | +| data.swift:186:12:186:12 | dataTainted24 | data.swift:185:35:185:42 | call to source() : | data.swift:186:12:186:12 | dataTainted24 | result | +| data.swift:191:12:191:12 | mapped | data.swift:189:22:189:29 | call to source() : | data.swift:191:12:191:12 | mapped | result | +| data.swift:196:12:196:12 | reduced | data.swift:194:22:194:29 | call to source() : | data.swift:196:12:196:12 | reduced | result | +| data.swift:201:12:201:12 | dataTainted27 | data.swift:200:35:200:42 | call to source() : | data.swift:201:12:201:12 | dataTainted27 | result | +| data.swift:206:12:206:12 | dataTainted28 | data.swift:205:45:205:52 | call to source() : | data.swift:206:12:206:12 | dataTainted28 | result | +| data.swift:210:12:210:12 | dataTainted29 | data.swift:209:45:209:52 | call to source() : | data.swift:210:12:210:12 | dataTainted29 | result | +| data.swift:214:12:214:12 | dataTainted30 | data.swift:213:45:213:52 | call to source() : | data.swift:214:12:214:12 | dataTainted30 | result | +| data.swift:219:12:219:12 | dataTainted31 | data.swift:218:45:218:52 | call to source() : | data.swift:219:12:219:12 | dataTainted31 | result | +| data.swift:224:12:224:12 | dataTainted32 | data.swift:223:45:223:52 | call to source() : | data.swift:224:12:224:12 | dataTainted32 | result | +| data.swift:229:12:229:12 | dataTainted33 | data.swift:228:45:228:52 | call to source() : | data.swift:229:12:229:12 | dataTainted33 | result | +| data.swift:237:12:237:33 | call to sorted() | data.swift:236:22:236:29 | call to source() : | data.swift:237:12:237:33 | call to sorted() | result | +| data.swift:241:12:241:54 | call to sorted(by:) | data.swift:240:22:240:29 | call to source() : | data.swift:241:12:241:54 | call to sorted(by:) | result | +| data.swift:245:12:245:46 | call to sorted(using:) | data.swift:244:22:244:29 | call to source() : | data.swift:245:12:245:46 | call to sorted(using:) | result | +| data.swift:249:12:249:35 | call to shuffled() | data.swift:248:22:248:29 | call to source() : | data.swift:249:12:249:35 | call to shuffled() | result | +| data.swift:254:12:254:46 | call to shuffled(using:) | data.swift:252:22:252:29 | call to source() : | data.swift:254:12:254:46 | call to shuffled(using:) | result | +| data.swift:258:12:258:44 | call to trimmingPrefix(_:) | data.swift:257:22:257:29 | call to source() : | data.swift:258:12:258:44 | call to trimmingPrefix(_:) | result | +| data.swift:262:12:262:54 | call to trimmingPrefix(while:) | data.swift:261:22:261:29 | call to source() : | data.swift:262:12:262:54 | call to trimmingPrefix(while:) | result | | nsdata.swift:58:15:58:15 | nsDataTainted1 | nsdata.swift:57:40:57:47 | call to source() : | nsdata.swift:58:15:58:15 | nsDataTainted1 | result | | nsdata.swift:61:15:61:15 | nsDataTainted2 | nsdata.swift:60:46:60:53 | call to source() : | nsdata.swift:61:15:61:15 | nsDataTainted2 | result | | nsdata.swift:64:15:64:15 | nsDataTainted3 | nsdata.swift:63:46:63:53 | call to source() : | nsdata.swift:64:15:64:15 | nsDataTainted3 | result | @@ -1266,42 +1306,6 @@ subpaths | nsmutabledata.swift:41:15:41:15 | nsMutableDataTainted4 | nsmutabledata.swift:40:66:40:73 | call to source() : | nsmutabledata.swift:41:15:41:15 | nsMutableDataTainted4 | result | | nsmutabledata.swift:45:15:45:15 | nsMutableDataTainted5 | nsmutabledata.swift:44:35:44:42 | call to source() : | nsmutabledata.swift:45:15:45:15 | nsMutableDataTainted5 | result | | nsmutabledata.swift:49:15:49:37 | .mutableBytes | nsmutabledata.swift:48:33:48:40 | call to source() : | nsmutabledata.swift:49:15:49:37 | .mutableBytes | result | -======= -| data.swift:80:12:80:12 | dataTainted3 | data.swift:79:41:79:48 | call to source() : | data.swift:80:12:80:12 | dataTainted3 | result | -| data.swift:84:12:84:12 | dataTainted4 | data.swift:83:34:83:41 | call to source() : | data.swift:84:12:84:12 | dataTainted4 | result | -| data.swift:86:12:86:12 | dataTainted5 | data.swift:85:34:85:41 | call to source() : | data.swift:86:12:86:12 | dataTainted5 | result | -| data.swift:90:12:90:12 | dataTainted6 | data.swift:89:33:89:40 | call to source() : | data.swift:90:12:90:12 | dataTainted6 | result | -| data.swift:94:12:94:12 | dataTainted7 | data.swift:93:39:93:46 | call to source() : | data.swift:94:12:94:12 | dataTainted7 | result | -| data.swift:98:12:98:12 | dataTainted8 | data.swift:97:38:97:45 | call to source() : | data.swift:98:12:98:12 | dataTainted8 | result | -| data.swift:102:12:102:12 | dataTainted9 | data.swift:101:39:101:46 | call to source() : | data.swift:102:12:102:12 | dataTainted9 | result | -| data.swift:107:12:107:12 | dataTainted10 | data.swift:106:23:106:30 | call to source() : | data.swift:107:12:107:12 | dataTainted10 | result | -| data.swift:111:12:111:12 | dataTainted11 | data.swift:110:23:110:30 | call to source() : | data.swift:111:12:111:12 | dataTainted11 | result | -| data.swift:115:12:115:12 | dataTainted12 | data.swift:114:23:114:30 | call to source() : | data.swift:115:12:115:12 | dataTainted12 | result | -| data.swift:120:12:120:12 | dataTainted13 | data.swift:119:23:119:30 | call to source() : | data.swift:120:12:120:12 | dataTainted13 | result | -| data.swift:125:12:125:12 | dataTainted14 | data.swift:124:35:124:42 | call to source() : | data.swift:125:12:125:12 | dataTainted14 | result | -| data.swift:129:12:129:55 | call to base64EncodedData(options:) | data.swift:128:22:128:29 | call to source() : | data.swift:129:12:129:55 | call to base64EncodedData(options:) | result | -| data.swift:133:12:133:57 | call to base64EncodedString(options:) | data.swift:132:22:132:29 | call to source() : | data.swift:133:12:133:57 | call to base64EncodedString(options:) | result | -| data.swift:138:12:138:12 | compactMapped | data.swift:136:22:136:29 | call to source() : | data.swift:138:12:138:12 | compactMapped | result | -| data.swift:144:12:144:12 | pointerTainted18 | data.swift:141:22:141:29 | call to source() : | data.swift:144:12:144:12 | pointerTainted18 | result | -| data.swift:161:12:161:12 | flatMapped | data.swift:159:22:159:29 | call to source() : | data.swift:161:12:161:12 | flatMapped | result | -| data.swift:165:12:165:12 | flatMapped2 | data.swift:163:22:163:29 | call to source() : | data.swift:165:12:165:12 | flatMapped2 | result | -| data.swift:170:12:170:12 | dataTainted23 | data.swift:169:23:169:30 | call to source() : | data.swift:170:12:170:12 | dataTainted23 | result | -| data.swift:175:12:175:12 | dataTainted24 | data.swift:174:35:174:42 | call to source() : | data.swift:175:12:175:12 | dataTainted24 | result | -| data.swift:180:12:180:12 | mapped | data.swift:178:22:178:29 | call to source() : | data.swift:180:12:180:12 | mapped | result | -| data.swift:185:12:185:12 | reduced | data.swift:183:22:183:29 | call to source() : | data.swift:185:12:185:12 | reduced | result | -| data.swift:190:12:190:12 | dataTainted27 | data.swift:189:35:189:42 | call to source() : | data.swift:190:12:190:12 | dataTainted27 | result | -| data.swift:195:12:195:12 | dataTainted28 | data.swift:194:45:194:52 | call to source() : | data.swift:195:12:195:12 | dataTainted28 | result | -| data.swift:199:12:199:12 | dataTainted29 | data.swift:198:45:198:52 | call to source() : | data.swift:199:12:199:12 | dataTainted29 | result | -| data.swift:203:12:203:12 | dataTainted30 | data.swift:202:45:202:52 | call to source() : | data.swift:203:12:203:12 | dataTainted30 | result | -| data.swift:208:12:208:12 | dataTainted31 | data.swift:207:45:207:52 | call to source() : | data.swift:208:12:208:12 | dataTainted31 | result | -| data.swift:213:12:213:12 | dataTainted32 | data.swift:212:37:212:44 | call to source() : | data.swift:213:12:213:12 | dataTainted32 | result | -| data.swift:218:12:218:12 | dataTainted33 | data.swift:217:37:217:44 | call to source() : | data.swift:218:12:218:12 | dataTainted33 | result | -| data.swift:222:12:222:35 | call to shuffled() | data.swift:221:22:221:29 | call to source() : | data.swift:222:12:222:35 | call to shuffled() | result | -| data.swift:227:12:227:46 | call to shuffled(using:) | data.swift:225:22:225:29 | call to source() : | data.swift:227:12:227:46 | call to shuffled(using:) | result | -| data.swift:231:12:231:46 | call to sorted(using:) | data.swift:230:22:230:29 | call to source() : | data.swift:231:12:231:46 | call to sorted(using:) | result | -| data.swift:235:12:235:44 | call to trimmingPrefix(_:) | data.swift:234:22:234:29 | call to source() : | data.swift:235:12:235:44 | call to trimmingPrefix(_:) | result | -| data.swift:239:12:239:54 | call to trimmingPrefix(while:) | data.swift:238:22:238:29 | call to source() : | data.swift:239:12:239:54 | call to trimmingPrefix(while:) | result | ->>>>>>> 7ef2618758 (Update test expectations) | string.swift:7:13:7:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:7:13:7:13 | "..." | result | | string.swift:9:13:9:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:9:13:9:13 | "..." | result | | string.swift:11:13:11:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:11:13:11:13 | "..." | result | From fc7c66dab20bf4165cba5a279b61e39123dd46c1 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Thu, 24 Nov 2022 12:04:08 +0100 Subject: [PATCH 514/796] Remove now unnecessary additional taint step in UnsafeJsEval --- swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql | 4 ---- .../test/query-tests/Security/CWE-094/UnsafeJsEval.expected | 2 -- 2 files changed, 6 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql index cd96709b6f6..e5764416d27 100644 --- a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql +++ b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql @@ -108,10 +108,6 @@ class UnsafeJsEvalConfig extends TaintTracking::Configuration { ]) ).getArgument(0) or - arg = - any(CallExpr ce | ce.getStaticTarget().(MethodDecl).hasQualifiedName("Data", "init(_:)")) - .getArgument(0) - or arg = any(CallExpr ce | ce.getStaticTarget().(MethodDecl).hasQualifiedName("String", "init(decoding:as:)") diff --git a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected index 6f146b41df8..e6b4fb45005 100644 --- a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected +++ b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected @@ -6,7 +6,6 @@ edges | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | UnsafeJsEval.swift:205:7:205:7 | remoteString : | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | UnsafeJsEval.swift:211:24:211:37 | .utf8 : | -| UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | | UnsafeJsEval.swift:204:7:204:66 | try! ... : | UnsafeJsEval.swift:265:13:265:13 | string : | | UnsafeJsEval.swift:204:7:204:66 | try! ... : | UnsafeJsEval.swift:268:13:268:13 | string : | | UnsafeJsEval.swift:204:7:204:66 | try! ... : | UnsafeJsEval.swift:276:13:276:13 | string : | @@ -29,7 +28,6 @@ edges | UnsafeJsEval.swift:211:19:211:41 | call to init(_:) : | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | | UnsafeJsEval.swift:211:24:211:37 | .utf8 : | UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in init(_:) : | | UnsafeJsEval.swift:211:24:211:37 | .utf8 : | UnsafeJsEval.swift:211:19:211:41 | call to init(_:) : | -| UnsafeJsEval.swift:211:24:211:37 | .utf8 : | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:265:13:265:13 | string : | | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:268:13:268:13 | string : | | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:276:13:276:13 | string : | From e4e5291511fa7832b58dd051f432a6362d0236c9 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Thu, 24 Nov 2022 13:03:12 +0100 Subject: [PATCH 515/796] Fix more test expectations after rebase --- .../library-tests/dataflow/flowsources/FlowSources.expected | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swift/ql/test/library-tests/dataflow/flowsources/FlowSources.expected b/swift/ql/test/library-tests/dataflow/flowsources/FlowSources.expected index 9aeb5661a9e..078385e1e00 100644 --- a/swift/ql/test/library-tests/dataflow/flowsources/FlowSources.expected +++ b/swift/ql/test/library-tests/dataflow/flowsources/FlowSources.expected @@ -3,12 +3,12 @@ | customurlschemes.swift:38:52:38:62 | url | external | | customurlschemes.swift:43:9:43:28 | ...[...] | Remote URL in UIApplicationDelegate.application.launchOptions | | customurlschemes.swift:48:9:48:28 | ...[...] | Remote URL in UIApplicationDelegate.application.launchOptions | +| data.swift:18:20:18:20 | call to init(contentsOf:options:) | external | +| data.swift:18:20:18:54 | call to init(contentsOf:options:) | external | | nsdata.swift:18:17:18:17 | call to init(contentsOf:) | external | | nsdata.swift:18:17:18:40 | call to init(contentsOf:) | external | | nsdata.swift:19:17:19:17 | call to init(contentsOf:options:) | external | | nsdata.swift:19:17:19:53 | call to init(contentsOf:options:) | external | -| data.swift:18:20:18:20 | call to init(contentsOf:options:) | external | -| data.swift:18:20:18:54 | call to init(contentsOf:options:) | external | | string.swift:56:21:56:21 | call to init(contentsOf:) | external | | string.swift:56:21:56:44 | call to init(contentsOf:) | external | | string.swift:57:21:57:21 | call to init(contentsOf:encoding:) | external | From 1c407a28cd427dbab1642707bfae3e08011462da Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Thu, 24 Nov 2022 14:00:05 +0000 Subject: [PATCH 516/796] Apply suggestions from code review Co-authored-by: Harry Maclean --- .../queries/security/cwe-209/StackTraceExposure.qhelp | 2 +- .../security/cwe-209/examples/StackTraceExposure.rb | 6 +++--- .../security/cwe-209/StackTraceExposure.expected | 10 +++++----- .../query-tests/security/cwe-209/StackTraceExposure.rb | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ruby/ql/src/queries/security/cwe-209/StackTraceExposure.qhelp b/ruby/ql/src/queries/security/cwe-209/StackTraceExposure.qhelp index 916f6cfcbeb..793138256ff 100644 --- a/ruby/ql/src/queries/security/cwe-209/StackTraceExposure.qhelp +++ b/ruby/ql/src/queries/security/cwe-209/StackTraceExposure.qhelp @@ -33,7 +33,7 @@ Either suppress the stack trace entirely, or log it only on the server.

    In the following example, an exception is handled in two different ways. In the -first version, labeled BAD, the exception is exposted to the remote user by +first version, labeled BAD, the exception is exposed to the remote user by rendering it as an HTTP response. As such, the user is able to see a detailed stack trace, which may contain sensitive information. In the second version, the error message is logged only on the server, and a generic error message is diff --git a/ruby/ql/src/queries/security/cwe-209/examples/StackTraceExposure.rb b/ruby/ql/src/queries/security/cwe-209/examples/StackTraceExposure.rb index 591be56014f..86cd38f5c30 100644 --- a/ruby/ql/src/queries/security/cwe-209/examples/StackTraceExposure.rb +++ b/ruby/ql/src/queries/security/cwe-209/examples/StackTraceExposure.rb @@ -4,15 +4,15 @@ class UsersController < ApplicationController do_computation() rescue => e # BAD - render e.backtrace, content_type: "text/plain" + render body: e.backtrace, content_type: "text/plain" end def update_good(id) do_computation() rescue => e # GOOD - log e.backtrace - redner "Computation failed", content_type: "text/plain" + logger.error e.backtrace + render body: "Computation failed", content_type: "text/plain" end end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected index 7a0e35973be..da66e5e4dc1 100644 --- a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected +++ b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected @@ -1,10 +1,10 @@ edges -| StackTraceExposure.rb:11:10:11:17 | call to caller : | StackTraceExposure.rb:12:12:12:13 | bt | +| StackTraceExposure.rb:11:10:11:17 | call to caller : | StackTraceExposure.rb:12:18:12:19 | bt | nodes -| StackTraceExposure.rb:6:12:6:22 | call to backtrace | semmle.label | call to backtrace | +| StackTraceExposure.rb:6:18:6:28 | call to backtrace | semmle.label | call to backtrace | | StackTraceExposure.rb:11:10:11:17 | call to caller : | semmle.label | call to caller : | -| StackTraceExposure.rb:12:12:12:13 | bt | semmle.label | bt | +| StackTraceExposure.rb:12:18:12:19 | bt | semmle.label | bt | subpaths #select -| StackTraceExposure.rb:6:12:6:22 | call to backtrace | StackTraceExposure.rb:6:12:6:22 | call to backtrace | StackTraceExposure.rb:6:12:6:22 | call to backtrace | $@ can be exposed to an external user. | StackTraceExposure.rb:6:12:6:22 | call to backtrace | Error information | -| StackTraceExposure.rb:12:12:12:13 | bt | StackTraceExposure.rb:11:10:11:17 | call to caller : | StackTraceExposure.rb:12:12:12:13 | bt | $@ can be exposed to an external user. | StackTraceExposure.rb:11:10:11:17 | call to caller | Error information | +| StackTraceExposure.rb:6:18:6:28 | call to backtrace | StackTraceExposure.rb:6:18:6:28 | call to backtrace | StackTraceExposure.rb:6:18:6:28 | call to backtrace | $@ can be exposed to an external user. | StackTraceExposure.rb:6:18:6:28 | call to backtrace | Error information | +| StackTraceExposure.rb:12:18:12:19 | bt | StackTraceExposure.rb:11:10:11:17 | call to caller : | StackTraceExposure.rb:12:18:12:19 | bt | $@ can be exposed to an external user. | StackTraceExposure.rb:11:10:11:17 | call to caller | Error information | diff --git a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.rb b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.rb index a9faa66af02..6091984df1a 100644 --- a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.rb +++ b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.rb @@ -3,13 +3,13 @@ class FooController < ApplicationController def show something_that_might_fail() rescue => e - render e.backtrace, content_type: "text/plain" + render body: e.backtrace, content_type: "text/plain" end def show2 bt = caller() - render bt, content_type: "text/plain" + render body: bt, content_type: "text/plain" end end From 50b10be2db43bdb5db827e64c271a8e3154af84d Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Thu, 24 Nov 2022 14:08:34 +0000 Subject: [PATCH 517/796] Ruby: StackTraceExposure: add test for a specific rescue type --- .../security/cwe-209/StackTraceExposure.expected | 2 ++ .../test/query-tests/security/cwe-209/StackTraceExposure.rb | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected index da66e5e4dc1..0dba484c65a 100644 --- a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected +++ b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected @@ -4,7 +4,9 @@ nodes | StackTraceExposure.rb:6:18:6:28 | call to backtrace | semmle.label | call to backtrace | | StackTraceExposure.rb:11:10:11:17 | call to caller : | semmle.label | call to caller : | | StackTraceExposure.rb:12:18:12:19 | bt | semmle.label | bt | +| StackTraceExposure.rb:18:18:18:28 | call to backtrace | semmle.label | call to backtrace | subpaths #select | StackTraceExposure.rb:6:18:6:28 | call to backtrace | StackTraceExposure.rb:6:18:6:28 | call to backtrace | StackTraceExposure.rb:6:18:6:28 | call to backtrace | $@ can be exposed to an external user. | StackTraceExposure.rb:6:18:6:28 | call to backtrace | Error information | | StackTraceExposure.rb:12:18:12:19 | bt | StackTraceExposure.rb:11:10:11:17 | call to caller : | StackTraceExposure.rb:12:18:12:19 | bt | $@ can be exposed to an external user. | StackTraceExposure.rb:11:10:11:17 | call to caller | Error information | +| StackTraceExposure.rb:18:18:18:28 | call to backtrace | StackTraceExposure.rb:18:18:18:28 | call to backtrace | StackTraceExposure.rb:18:18:18:28 | call to backtrace | $@ can be exposed to an external user. | StackTraceExposure.rb:18:18:18:28 | call to backtrace | Error information | diff --git a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.rb b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.rb index 6091984df1a..dcdf5c1f22c 100644 --- a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.rb +++ b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.rb @@ -12,4 +12,10 @@ class FooController < ApplicationController render body: bt, content_type: "text/plain" end + def show3 + not_a_method() + rescue NoMethodError => e + render body: e.backtrace, content_type: "text/plain" + end + end From 8d96bfe973e3d3387918e8799019cee96c440ba5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 24 Nov 2022 14:18:13 +0000 Subject: [PATCH 518/796] JS: Bump patch version of ML-powered library and query packs --- .../ql/experimental/adaptivethreatmodeling/lib/qlpack.yml | 2 +- .../ql/experimental/adaptivethreatmodeling/src/qlpack.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml b/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml index e0571f38255..fb53f54ded7 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-experimental-atm-lib -version: 0.4.1 +version: 0.4.2 extractor: javascript library: true groups: diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml b/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml index cab87ce0e33..725beadcb0e 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml @@ -1,6 +1,6 @@ name: codeql/javascript-experimental-atm-queries language: javascript -version: 0.4.1 +version: 0.4.2 suites: codeql-suites defaultSuiteFile: codeql-suites/javascript-atm-code-scanning.qls groups: From 78d49e44b1292319713b3b10e3c9b706aab67e63 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 24 Nov 2022 14:22:14 +0000 Subject: [PATCH 519/796] JS: Bump version of ML-powered library and query packs to 0.4.3 --- .../ql/experimental/adaptivethreatmodeling/lib/qlpack.yml | 2 +- .../ql/experimental/adaptivethreatmodeling/src/qlpack.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml b/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml index fb53f54ded7..22249f4b960 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-experimental-atm-lib -version: 0.4.2 +version: 0.4.3 extractor: javascript library: true groups: diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml b/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml index 725beadcb0e..875283e0b63 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml @@ -1,6 +1,6 @@ name: codeql/javascript-experimental-atm-queries language: javascript -version: 0.4.2 +version: 0.4.3 suites: codeql-suites defaultSuiteFile: codeql-suites/javascript-atm-code-scanning.qls groups: From 893c8763bb2076ba890eeffec694f63896a08bcf Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Thu, 24 Nov 2022 15:01:10 +0000 Subject: [PATCH 520/796] Ruby: model ActiveSupport json_escape flow --- .../lib/codeql/ruby/frameworks/ActiveSupport.qll | 14 ++++++++++++++ .../active_support/ActiveSupportDataFlow.expected | 7 +++++++ .../frameworks/active_support/active_support.rb | 6 ++++++ 3 files changed, 27 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll index 7d3286a0a74..5cea6497c5f 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll @@ -312,6 +312,20 @@ module ActiveSupport { } } + module Erb { + module Util { + private class JsonEscapeSummary extends SimpleSummarizedCallable { + JsonEscapeSummary() { this = "json_escape" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[0]" and + output = "ReturnValue" and + preservesValue = false + } + } + } + } + /** * Type summaries for extensions to the `Pathname` module. */ diff --git a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected index 11b6b46ee3e..2ea08b4c384 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected +++ b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected @@ -186,6 +186,9 @@ edges | active_support.rb:290:7:290:16 | call to source : | active_support.rb:291:8:291:8 | x : | | active_support.rb:291:8:291:8 | x : | active_support.rb:291:8:291:17 | call to deep_dup | | active_support.rb:291:8:291:8 | x : | active_support.rb:291:8:291:17 | call to deep_dup | +| active_support.rb:303:7:303:16 | call to source : | active_support.rb:304:19:304:19 | a : | +| active_support.rb:304:7:304:19 | call to json_escape : | active_support.rb:305:8:305:8 | b | +| active_support.rb:304:19:304:19 | a : | active_support.rb:304:7:304:19 | call to json_escape : | | hash_extensions.rb:2:14:2:24 | call to source : | hash_extensions.rb:3:9:3:9 | h [element :a] : | | hash_extensions.rb:2:14:2:24 | call to source : | hash_extensions.rb:3:9:3:9 | h [element :a] : | | hash_extensions.rb:3:9:3:9 | h [element :a] : | hash_extensions.rb:3:9:3:24 | call to stringify_keys [element] : | @@ -532,6 +535,10 @@ nodes | active_support.rb:291:8:291:8 | x : | semmle.label | x : | | active_support.rb:291:8:291:17 | call to deep_dup | semmle.label | call to deep_dup | | active_support.rb:291:8:291:17 | call to deep_dup | semmle.label | call to deep_dup | +| active_support.rb:303:7:303:16 | call to source : | semmle.label | call to source : | +| active_support.rb:304:7:304:19 | call to json_escape : | semmle.label | call to json_escape : | +| active_support.rb:304:19:304:19 | a : | semmle.label | a : | +| active_support.rb:305:8:305:8 | b | semmle.label | b | | hash_extensions.rb:2:14:2:24 | call to source : | semmle.label | call to source : | | hash_extensions.rb:2:14:2:24 | call to source : | semmle.label | call to source : | | hash_extensions.rb:3:9:3:9 | h [element :a] : | semmle.label | h [element :a] : | diff --git a/ruby/ql/test/library-tests/frameworks/active_support/active_support.rb b/ruby/ql/test/library-tests/frameworks/active_support/active_support.rb index fe0256080d1..c2dfb8b421d 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/active_support.rb +++ b/ruby/ql/test/library-tests/frameworks/active_support/active_support.rb @@ -298,3 +298,9 @@ def m_try(method) x.try!(:upcase).try!(:downcase) x.try!(method) end + +def m_json_escape + a = source "a" + b = json_escape a + sink b # $hasTaintFlow=a +end From e6446e501c603e5a6c8abdcd6f596db809b517df Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Thu, 24 Nov 2022 15:37:03 +0000 Subject: [PATCH 521/796] Ruby: fix docs failure --- ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll index 5cea6497c5f..3e90875206c 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll @@ -312,7 +312,13 @@ module ActiveSupport { } } + /** + * `ActiveSupport::ERB` + */ module Erb { + /** + * `ActiveSupport::ERB::Util` + */ module Util { private class JsonEscapeSummary extends SimpleSummarizedCallable { JsonEscapeSummary() { this = "json_escape" } From e24e3bf13f002ad35c36262106e82cd229d18360 Mon Sep 17 00:00:00 2001 From: alexet Date: Thu, 24 Nov 2022 16:43:57 +0000 Subject: [PATCH 522/796] Java: Add new Mockito runner class location. --- java/ql/lib/semmle/code/java/frameworks/Mockito.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/Mockito.qll b/java/ql/lib/semmle/code/java/frameworks/Mockito.qll index af161760063..9622d7e50ba 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Mockito.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Mockito.qll @@ -53,9 +53,11 @@ class MockitoInitedTest extends Class { MockitoInitedTest() { // Tests run with the Mockito runner. exists(RunWithAnnotation a | a = this.getAnAncestor().getAnAnnotation() | + a.getRunner().(RefType).hasQualifiedName("org.mockito.junit", "MockitoJUnitRunner") + or + // Deprecated styles. a.getRunner().(RefType).hasQualifiedName("org.mockito.runners", "MockitoJUnitRunner") or - // Deprecated style. a.getRunner().(RefType).hasQualifiedName("org.mockito.runners", "MockitoJUnit44Runner") ) or From 6897fb46cb92c6e69b2f0a281c567e7d097df908 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Thu, 24 Nov 2022 17:41:04 +1300 Subject: [PATCH 523/796] Ruby: Clean up WhenClause CFG --- .../ruby/controlflow/internal/ControlFlowGraphImpl.qll | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll index a8bd2e3feac..ba77d6beaba 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll @@ -1399,7 +1399,9 @@ module Trees { } private class WhenTree extends ControlFlowTree, WhenClause { - final override predicate propagatesAbnormal(AstNode child) { child = this.getAPattern() } + final override predicate propagatesAbnormal(AstNode child) { + child = [this.getAPattern(), this.getBody()] + } final Expr getLastPattern() { exists(int i | @@ -1415,8 +1417,7 @@ module Trees { c.isValidFor(this) and c.(ConditionalCompletion).getValue() = false or - last(this.getBody(), last, c) and - c instanceof NormalCompletion + last(this.getBody(), last, c) } final override predicate succ(AstNode pred, AstNode succ, Completion c) { From 2822c94aa795373371b51f3d900a9ac1cc5aa897 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Thu, 24 Nov 2022 17:48:41 +1300 Subject: [PATCH 524/796] Ruby: Minor refactor of barrier guard code --- .../codeql/ruby/dataflow/BarrierGuards.qll | 59 ++++++++++--------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll index f1f8d2c5b46..f586c7d74cc 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll @@ -31,15 +31,15 @@ private predicate stringConstCompare(CfgNodes::AstCfgNode guard, CfgNode testedN or stringConstCaseCompare(guard, testedNode, branch) or - exists(Ssa::Definition def, CfgNodes::ExprNodes::BinaryOperationCfgNode g | + exists(CfgNodes::ExprNodes::BinaryOperationCfgNode g | g = guard and - stringConstCompareOr(guard, def, branch) and + stringConstCompareOr(guard, branch) and stringConstCompare(g.getLeftOperand(), testedNode, _) ) } /** - * Holds if `guard` is an `or` expression whose operands are string comparison guards that test `def`. + * Holds if `guard` is an `or` expression whose operands are string comparison guards. * For example: * * ```rb @@ -47,12 +47,12 @@ private predicate stringConstCompare(CfgNodes::AstCfgNode guard, CfgNode testedN * ``` */ private predicate stringConstCompareOr( - CfgNodes::ExprNodes::BinaryOperationCfgNode guard, Ssa::Definition def, boolean branch + CfgNodes::ExprNodes::BinaryOperationCfgNode guard, boolean branch ) { guard.getExpr() instanceof LogicalOrExpr and branch = true and forall(CfgNode innerGuard | innerGuard = guard.getAnOperand() | - stringConstCompare(innerGuard, def.getARead(), branch) + stringConstCompare(innerGuard, any(Ssa::Definition def).getARead(), branch) ) } @@ -190,34 +190,35 @@ private predicate stringConstCaseCompare( exists(CfgNodes::ExprNodes::CaseExprCfgNode case | case.getValue() = testedNode and ( - exists(CfgNodes::ExprNodes::WhenClauseCfgNode branchNode | - guard = branchNode and - branchNode = case.getBranch(_) and - // For simplicity, consider patterns that contain only string literals or arrays of string literals - forall(ExprCfgNode pattern | pattern = branchNode.getPattern(_) | - // when "foo" - // when "foo", "bar" - pattern instanceof ExprNodes::StringLiteralCfgNode - or - exists(CfgNodes::ExprNodes::SplatExprCfgNode splat | splat = pattern | - // when *["foo", "bar"] - forex(ExprCfgNode elem | - elem = splat.getOperand().(ExprNodes::ArrayLiteralCfgNode).getAnArgument() - | - elem instanceof ExprNodes::StringLiteralCfgNode - ) + guard = + any(CfgNodes::ExprNodes::WhenClauseCfgNode branchNode | + branchNode = case.getBranch(_) and + // For simplicity, consider patterns that contain only string literals or arrays of string literals + forall(ExprCfgNode pattern | pattern = branchNode.getPattern(_) | + // when "foo" + // when "foo", "bar" + pattern instanceof ExprNodes::StringLiteralCfgNode or - // when *some_var - // when *SOME_CONST - exists(ExprNodes::ArrayLiteralCfgNode arr | - isArrayConstant(splat.getOperand(), arr) and - forall(ExprCfgNode elem | elem = arr.getAnArgument() | - elem instanceof ExprNodes::StringLiteralCfgNode + pattern = + any(CfgNodes::ExprNodes::SplatExprCfgNode splat | + // when *["foo", "bar"] + forex(ExprCfgNode elem | + elem = splat.getOperand().(ExprNodes::ArrayLiteralCfgNode).getAnArgument() + | + elem instanceof ExprNodes::StringLiteralCfgNode + ) + or + // when *some_var + // when *SOME_CONST + exists(ExprNodes::ArrayLiteralCfgNode arr | + isArrayConstant(splat.getOperand(), arr) and + forall(ExprCfgNode elem | elem = arr.getAnArgument() | + elem instanceof ExprNodes::StringLiteralCfgNode + ) + ) ) - ) ) ) - ) or // in "foo" exists( From d804acdef7466d04832285c65afc2ef70fe7dcd6 Mon Sep 17 00:00:00 2001 From: yoff Date: Fri, 25 Nov 2022 08:50:37 +0100 Subject: [PATCH 525/796] Apply suggestions from code review Co-authored-by: Taus --- python/ql/src/Expressions/CallToSuperWrongClass.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/src/Expressions/CallToSuperWrongClass.ql b/python/ql/src/Expressions/CallToSuperWrongClass.ql index 1424fa8f434..c54674602cc 100644 --- a/python/ql/src/Expressions/CallToSuperWrongClass.ql +++ b/python/ql/src/Expressions/CallToSuperWrongClass.ql @@ -17,10 +17,10 @@ import semmle.python.dataflow.new.DataFlow from DataFlow::CallCfgNode call_to_super, string name where - call_to_super.getFunction().getALocalSource().asExpr().(Name).getId() = "super" and + call_to_super = API::builtin("super").getACall() and name = call_to_super.getScope().getScope().(Class).getName() and exists(DataFlow::Node arg | arg = call_to_super.getArg(0) and - not arg.getALocalSource().asExpr().(Name).getId() = name + arg.getALocalSource().asExpr().(Name).getId() != name ) select call_to_super.getNode(), "First argument to super() should be " + name + "." From 77d98b217ea671e0b94aa973f9ed3672cf4718d4 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Fri, 25 Nov 2022 08:52:35 +0100 Subject: [PATCH 526/796] Python: add import --- python/ql/src/Expressions/CallToSuperWrongClass.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/python/ql/src/Expressions/CallToSuperWrongClass.ql b/python/ql/src/Expressions/CallToSuperWrongClass.ql index c54674602cc..af5c33ef13a 100644 --- a/python/ql/src/Expressions/CallToSuperWrongClass.ql +++ b/python/ql/src/Expressions/CallToSuperWrongClass.ql @@ -14,6 +14,7 @@ import python import semmle.python.dataflow.new.DataFlow +import semmle.python.ApiGraphs from DataFlow::CallCfgNode call_to_super, string name where From 8df7d465cb772181df4562edff65a71464d710e7 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 22 Nov 2022 10:51:02 +0100 Subject: [PATCH 527/796] Swift: cache more aggressively in CI * the QL compilation cache action is used for ql and integration tests * all caches (Bazel and QL) are populated on push --- .github/workflows/swift.yml | 62 +++++++------------ .../actions/run-integration-tests/action.yml | 6 +- swift/actions/run-ql-tests/action.yml | 7 ++- swift/integration-tests/runner.py | 3 + 4 files changed, 37 insertions(+), 41 deletions(-) diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index 99579421adf..2baae15f270 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -8,42 +8,30 @@ on: - "*.bazel*" - .github/workflows/swift.yml - .github/actions/fetch-codeql/action.yml + - .github/actions/cache-query-compilation/action.yml - codeql-workspace.yml - .pre-commit-config.yaml - "!**/*.md" - "!**/*.qhelp" branches: - main + - rc/* + push: + paths: + - "swift/**" + - "misc/bazel/**" + - "*.bazel*" + - .github/workflows/swift.yml + - .github/actions/fetch-codeql/action.yml + - .github/actions/cache-query-compilation/action.yml + - codeql-workspace.yml + - "!**/*.md" + - "!**/*.qhelp" + branches: + - main + - rc/* jobs: - changes: - runs-on: ubuntu-latest - outputs: - codegen: ${{ steps.filter.outputs.codegen }} - ql: ${{ steps.filter.outputs.ql }} - steps: - - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 - id: filter - with: - filters: | - codegen: - - '.github/workflows/swift.yml' - - "misc/bazel/**" - - "*.bazel*" - - 'swift/actions/setup-env/**' - - '.pre-commit-config.yaml' - - 'swift/codegen/**' - - 'swift/schema.py' - - 'swift/**/*.dbscheme' - - 'swift/ql/lib/codeql/swift/elements.qll' - - 'swift/ql/lib/codeql/swift/elements/**' - - 'swift/ql/lib/codeql/swift/generated/**' - - 'swift/ql/test/extractor-tests/generated/**' - - 'swift/ql/.generated.list' - ql: - - 'github/workflows/swift.yml' - - 'swift/**/*.ql' - - 'swift/**/*.qll' # not using a matrix as you cannot depend on a specific job in a matrix, and we want to start linux checks # without waiting for the macOS build build-and-test-macos: @@ -54,7 +42,7 @@ jobs: - uses: ./swift/actions/run-quick-tests - uses: ./swift/actions/print-unextracted build-and-test-linux: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest-xl steps: - uses: actions/checkout@v3 - uses: ./swift/actions/create-extractor-pack @@ -62,38 +50,33 @@ jobs: - uses: ./swift/actions/print-unextracted qltests-linux: needs: build-and-test-linux - runs-on: ubuntu-latest + runs-on: ubuntu-latest-xl steps: - uses: actions/checkout@v3 - uses: ./swift/actions/run-ql-tests qltests-macos: + if : ${{ github.event_name == 'pull_request' }} needs: build-and-test-macos runs-on: macos-12-xl - strategy: - fail-fast: false - matrix: - slice: ["1/2", "2/2"] steps: - uses: actions/checkout@v3 - uses: ./swift/actions/run-ql-tests - with: - flags: --slice ${{ matrix.slice }} integration-tests-linux: needs: build-and-test-linux - runs-on: ubuntu-latest + runs-on: ubuntu-latest-xl steps: - uses: actions/checkout@v3 - uses: ./swift/actions/run-integration-tests integration-tests-macos: + if : ${{ github.event_name == 'pull_request' }} needs: build-and-test-macos runs-on: macos-12-xl steps: - uses: actions/checkout@v3 - uses: ./swift/actions/run-integration-tests codegen: + if : ${{ github.event_name == 'pull_request' }} runs-on: ubuntu-latest - needs: changes - if: ${{ needs.changes.outputs.codegen == 'true' }} steps: - uses: actions/checkout@v3 - uses: ./swift/actions/setup-env @@ -114,6 +97,7 @@ jobs: name: swift-generated-cpp-files path: generated-cpp-files/** database-upgrade-scripts: + if : ${{ github.event_name == 'pull_request' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/swift/actions/run-integration-tests/action.yml b/swift/actions/run-integration-tests/action.yml index 9325fb8b11d..6e190693a55 100644 --- a/swift/actions/run-integration-tests/action.yml +++ b/swift/actions/run-integration-tests/action.yml @@ -17,7 +17,11 @@ runs: with: swift-version: "${{steps.get_swift_version.outputs.version}}" - uses: ./.github/actions/fetch-codeql + - id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: swift-qltest - name: Run integration tests shell: bash run: | - python swift/integration-tests/runner.py + python swift/integration-tests/runner.py --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" diff --git a/swift/actions/run-ql-tests/action.yml b/swift/actions/run-ql-tests/action.yml index 86af7ba12c3..3694459082b 100644 --- a/swift/actions/run-ql-tests/action.yml +++ b/swift/actions/run-ql-tests/action.yml @@ -10,18 +10,23 @@ runs: steps: - uses: ./swift/actions/share-extractor-pack - uses: ./.github/actions/fetch-codeql + - id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: swift-qltest - name: Run QL tests shell: bash run: | codeql test run \ --threads=0 \ - --ram 5000 \ + --ram 52000 \ --search-path "${{ github.workspace }}/swift/extractor-pack" \ --check-databases \ --check-unused-labels \ --check-repeated-labels \ --check-redefined-labels \ --check-use-before-definition \ + --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" \ ${{ inputs.flags }} \ swift/ql/test env: diff --git a/swift/integration-tests/runner.py b/swift/integration-tests/runner.py index b0b2ecd92b0..ec6f9215709 100755 --- a/swift/integration-tests/runner.py +++ b/swift/integration-tests/runner.py @@ -25,6 +25,7 @@ def options(): p.add_argument("--check-databases", action="store_true") p.add_argument("--learn", action="store_true") p.add_argument("--threads", "-j", type=int, default=0) + p.add_argument("--compilation-cache") return p.parse_args() @@ -65,6 +66,8 @@ def main(opts): cmd.append("--no-check-databases") if opts.learn: cmd.append("--learn") + if opts.compilation_cache: + cmd.append(f'--compilation-cache="{opts.compilation_cache}"') cmd.extend(str(t.parent) for t in succesful_db_creation) ql_test_success = subprocess.run(cmd).returncode == 0 From 4607f5990e2df174f4bfb423c3f28dab613c2ee9 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 25 Nov 2022 10:19:04 +0100 Subject: [PATCH 528/796] C++: Add more tests that exercise the default taint barrier implementation --- .../CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp | 11 ++++++++++- .../Security/CWE/CWE-190/semmle/tainted/test.c | 7 +++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp index b11a136ed24..b1245c6ae89 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp @@ -332,4 +332,13 @@ void ptr_diff_case() { char* admin_begin_pos = strstr(user, "ADMIN"); int offset = admin_begin_pos ? user - admin_begin_pos : 0; malloc(offset); // GOOD -} \ No newline at end of file +} + +void equality_barrier() { + int size1 = atoi(getenv("USER")); + int size2 = atoi(getenv("USER")); + + if (size1 == size2) { + int* a = (int*)malloc(size1 * sizeof(int)); // GOOD + } +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/test.c b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/test.c index 6999795b004..29ab7cc8f25 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/test.c +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/test.c @@ -95,5 +95,12 @@ int main(int argc, char** argv) { } } + // GOOD: check the user input first + int maxConnections3 = atoi(argv[1]); + int maxConnections4 = atoi(argv[1]); + if (maxConnections3 == maxConnections4) { + startServer(maxConnections3 * 1000); + } + return 0; } From ebdea243b2c911311e82f7c429a2ed560d53af92 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 25 Nov 2022 09:46:07 +0000 Subject: [PATCH 529/796] Make qldoc clearer about behaviour of override --- go/ql/lib/semmle/go/Scopes.qll | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/go/ql/lib/semmle/go/Scopes.qll b/go/ql/lib/semmle/go/Scopes.qll index b14d558fabb..385b52028d9 100644 --- a/go/ql/lib/semmle/go/Scopes.qll +++ b/go/ql/lib/semmle/go/Scopes.qll @@ -95,7 +95,12 @@ class Entity extends @object { /** Gets the package in which this entity is declared, if any. */ Package getPackage() { result.getScope() = this.getScope() } - /** Holds if this entity is declared in a package with path `pkg` and has the given `name`. */ + /** + * Holds if this entity is declared in a package with path `pkg` and has the given `name`. + * + * Note that for methods `pkg` is the package path followed by `.` followed + * by the name of the receiver type, for example `io.Writer`. + */ predicate hasQualifiedName(string pkg, string name) { pkg = this.getPackage().getPath() and name = this.getName() From 8ec681e61cb39c9085a06aa3b67c4815b450ebfb Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 21 Nov 2022 16:15:56 +0000 Subject: [PATCH 530/796] Kotlin: bump default CI version to 1.7.20 A bunch of test expectations change because https://github.com/JetBrains/kotlin/commit/7f531d842685fff42dbd66d7bcaa7bc58b7d8610 means that we now see (a) local variable declarations with source locations covering only their identifier, not the whole statement, and (b) more SYNTHETIC_OFFSET values for the parts of a destructuring assignment or initialiser, which show up as file.kt:0:0:0:0 in DbLocation form. --- java/kotlin-extractor/gradle.properties | 2 +- .../kotlin_plugin_versions.py | 4 +- .../allOverriddenIncludingSelf.kt | 0 ...rameterDeclarationWithWrappedDescriptor.kt | 0 .../controlflow/basic/bbStmts.expected | 32 +- .../basic/bbStrictDominance.expected | 4 +- .../controlflow/basic/bbSuccessor.expected | 8 +- .../controlflow/basic/getASuccessor.expected | 54 +-- .../basic/strictDominance.expected | 312 +++++++------- .../basic/strictPostDominance.expected | 72 ++-- .../kotlin/library-tests/exprs/exprs.expected | 382 +++++++++--------- .../library-tests/methods/exprs.expected | 2 +- .../modifiers/modifiers.expected | 2 +- .../reflection/reflection.expected | 44 +- .../library-tests/stmts/PrintAst.expected | 6 +- .../kotlin/library-tests/stmts/exprs.expected | 12 +- .../kotlin/library-tests/stmts/stmts.expected | 20 +- 17 files changed, 478 insertions(+), 478 deletions(-) rename java/kotlin-extractor/src/main/kotlin/utils/versions/{v_1_7_20-Beta => v_1_7_20}/allOverriddenIncludingSelf.kt (100%) rename java/kotlin-extractor/src/main/kotlin/utils/versions/{v_1_7_20-Beta => v_1_7_20}/createImplicitParameterDeclarationWithWrappedDescriptor.kt (100%) diff --git a/java/kotlin-extractor/gradle.properties b/java/kotlin-extractor/gradle.properties index 16f621c2d74..f9cd575cdd3 100644 --- a/java/kotlin-extractor/gradle.properties +++ b/java/kotlin-extractor/gradle.properties @@ -1,5 +1,5 @@ kotlin.code.style=official -kotlinVersion=1.7.0 +kotlinVersion=1.7.21 GROUP=com.github.codeql VERSION_NAME=0.0.1 diff --git a/java/kotlin-extractor/kotlin_plugin_versions.py b/java/kotlin-extractor/kotlin_plugin_versions.py index 04107005f8d..99691b89fd2 100755 --- a/java/kotlin-extractor/kotlin_plugin_versions.py +++ b/java/kotlin-extractor/kotlin_plugin_versions.py @@ -22,10 +22,10 @@ def version_string_to_tuple(version): return tuple([int(m.group(i)) for i in range(1, 4)] + [m.group(4)]) # Version number used by CI. It needs to be one of the versions in many_versions. -ci_version = '1.7.0' +ci_version = '1.7.20' # Version numbers in the list need to be in semantically increasing order -many_versions = [ '1.4.32', '1.5.0', '1.5.10', '1.5.20', '1.5.30', '1.6.0', '1.6.20', '1.7.0', '1.7.20-Beta' ] +many_versions = [ '1.4.32', '1.5.0', '1.5.10', '1.5.20', '1.5.30', '1.6.0', '1.6.20', '1.7.0', '1.7.20' ] many_versions_tuples = [version_string_to_tuple(v) for v in many_versions] diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20-Beta/allOverriddenIncludingSelf.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20/allOverriddenIncludingSelf.kt similarity index 100% rename from java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20-Beta/allOverriddenIncludingSelf.kt rename to java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20/allOverriddenIncludingSelf.kt diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20-Beta/createImplicitParameterDeclarationWithWrappedDescriptor.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20/createImplicitParameterDeclarationWithWrappedDescriptor.kt similarity index 100% rename from java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20-Beta/createImplicitParameterDeclarationWithWrappedDescriptor.kt rename to java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20/createImplicitParameterDeclarationWithWrappedDescriptor.kt diff --git a/java/ql/test/kotlin/library-tests/controlflow/basic/bbStmts.expected b/java/ql/test/kotlin/library-tests/controlflow/basic/bbStmts.expected index b3f3c19341f..767e68d2f75 100644 --- a/java/ql/test/kotlin/library-tests/controlflow/basic/bbStmts.expected +++ b/java/ql/test/kotlin/library-tests/controlflow/basic/bbStmts.expected @@ -4,18 +4,18 @@ | Test.kt:3:1:80:1 | { ... } | 3 | Test.kt:3:8:80:1 | Test | | Test.kt:4:2:79:2 | test | 0 | Test.kt:4:2:79:2 | test | | Test.kt:4:13:79:2 | { ... } | 0 | Test.kt:4:13:79:2 | { ... } | -| Test.kt:4:13:79:2 | { ... } | 1 | Test.kt:5:3:5:16 | var ...; | +| Test.kt:4:13:79:2 | { ... } | 1 | Test.kt:5:7:5:7 | var ...; | | Test.kt:4:13:79:2 | { ... } | 2 | Test.kt:5:16:5:16 | 0 | -| Test.kt:4:13:79:2 | { ... } | 3 | Test.kt:5:3:5:16 | x | -| Test.kt:4:13:79:2 | { ... } | 4 | Test.kt:6:3:6:18 | var ...; | +| Test.kt:4:13:79:2 | { ... } | 3 | Test.kt:5:7:5:7 | x | +| Test.kt:4:13:79:2 | { ... } | 4 | Test.kt:6:7:6:7 | var ...; | | Test.kt:4:13:79:2 | { ... } | 5 | Test.kt:6:17:6:18 | 50 | -| Test.kt:4:13:79:2 | { ... } | 6 | Test.kt:6:3:6:18 | y | -| Test.kt:4:13:79:2 | { ... } | 7 | Test.kt:7:3:7:16 | var ...; | +| Test.kt:4:13:79:2 | { ... } | 6 | Test.kt:6:7:6:7 | y | +| Test.kt:4:13:79:2 | { ... } | 7 | Test.kt:7:7:7:7 | var ...; | | Test.kt:4:13:79:2 | { ... } | 8 | Test.kt:7:16:7:16 | 0 | -| Test.kt:4:13:79:2 | { ... } | 9 | Test.kt:7:3:7:16 | z | -| Test.kt:4:13:79:2 | { ... } | 10 | Test.kt:8:3:8:16 | var ...; | +| Test.kt:4:13:79:2 | { ... } | 9 | Test.kt:7:7:7:7 | z | +| Test.kt:4:13:79:2 | { ... } | 10 | Test.kt:8:7:8:7 | var ...; | | Test.kt:4:13:79:2 | { ... } | 11 | Test.kt:8:16:8:16 | 0 | -| Test.kt:4:13:79:2 | { ... } | 12 | Test.kt:8:3:8:16 | w | +| Test.kt:4:13:79:2 | { ... } | 12 | Test.kt:8:7:8:7 | w | | Test.kt:4:13:79:2 | { ... } | 13 | Test.kt:11:3:16:3 | ; | | Test.kt:4:13:79:2 | { ... } | 14 | Test.kt:11:3:16:3 | when ... | | Test.kt:4:13:79:2 | { ... } | 15 | Test.kt:11:3:16:3 | ... -> ... | @@ -106,12 +106,12 @@ | Test.kt:82:21:89:1 | { ... } | 0 | Test.kt:82:21:89:1 | { ... } | | Test.kt:82:21:89:1 | { ... } | 1 | Test.kt:83:2:88:2 | try ... | | Test.kt:82:21:89:1 | { ... } | 2 | Test.kt:83:6:86:2 | { ... } | -| Test.kt:82:21:89:1 | { ... } | 3 | Test.kt:84:3:84:18 | var ...; | +| Test.kt:82:21:89:1 | { ... } | 3 | Test.kt:84:7:84:7 | var ...; | | Test.kt:82:21:89:1 | { ... } | 4 | Test.kt:84:11:84:11 | o | | Test.kt:82:21:89:1 | { ... } | 5 | Test.kt:84:11:84:18 | (...)... | -| Test.kt:84:3:84:18 | x | 0 | Test.kt:84:3:84:18 | x | -| Test.kt:84:3:84:18 | x | 1 | Test.kt:85:10:85:10 | 1 | -| Test.kt:84:3:84:18 | x | 2 | Test.kt:85:3:85:10 | return ... | +| Test.kt:84:7:84:7 | x | 0 | Test.kt:84:7:84:7 | x | +| Test.kt:84:7:84:7 | x | 1 | Test.kt:85:10:85:10 | 1 | +| Test.kt:84:7:84:7 | x | 2 | Test.kt:85:3:85:10 | return ... | | Test.kt:86:4:88:2 | catch (...) | 0 | Test.kt:86:4:88:2 | catch (...) | | Test.kt:86:4:88:2 | catch (...) | 1 | Test.kt:86:11:86:31 | e | | Test.kt:86:4:88:2 | catch (...) | 2 | Test.kt:86:34:88:2 | { ... } | @@ -121,12 +121,12 @@ | Test.kt:91:22:98:1 | { ... } | 0 | Test.kt:91:22:98:1 | { ... } | | Test.kt:91:22:98:1 | { ... } | 1 | Test.kt:92:2:97:2 | try ... | | Test.kt:91:22:98:1 | { ... } | 2 | Test.kt:92:6:95:2 | { ... } | -| Test.kt:91:22:98:1 | { ... } | 3 | Test.kt:93:3:93:13 | var ...; | +| Test.kt:91:22:98:1 | { ... } | 3 | Test.kt:93:7:93:7 | var ...; | | Test.kt:91:22:98:1 | { ... } | 4 | Test.kt:93:11:93:11 | o | | Test.kt:91:22:98:1 | { ... } | 5 | Test.kt:93:12:93:13 | ...!! | -| Test.kt:93:3:93:13 | x | 0 | Test.kt:93:3:93:13 | x | -| Test.kt:93:3:93:13 | x | 1 | Test.kt:94:10:94:10 | 1 | -| Test.kt:93:3:93:13 | x | 2 | Test.kt:94:3:94:10 | return ... | +| Test.kt:93:7:93:7 | x | 0 | Test.kt:93:7:93:7 | x | +| Test.kt:93:7:93:7 | x | 1 | Test.kt:94:10:94:10 | 1 | +| Test.kt:93:7:93:7 | x | 2 | Test.kt:94:3:94:10 | return ... | | Test.kt:95:4:97:2 | catch (...) | 0 | Test.kt:95:4:97:2 | catch (...) | | Test.kt:95:4:97:2 | catch (...) | 1 | Test.kt:95:11:95:33 | e | | Test.kt:95:4:97:2 | catch (...) | 2 | Test.kt:95:36:97:2 | { ... } | diff --git a/java/ql/test/kotlin/library-tests/controlflow/basic/bbStrictDominance.expected b/java/ql/test/kotlin/library-tests/controlflow/basic/bbStrictDominance.expected index bea96c9445f..90c7d07b8c3 100644 --- a/java/ql/test/kotlin/library-tests/controlflow/basic/bbStrictDominance.expected +++ b/java/ql/test/kotlin/library-tests/controlflow/basic/bbStrictDominance.expected @@ -28,10 +28,10 @@ | Test.kt:38:9:38:9 | x | Test.kt:38:16:41:3 | { ... } | | Test.kt:38:9:38:9 | x | Test.kt:43:3:43:3 | ; | | Test.kt:82:21:89:1 | { ... } | Test.kt:82:1:89:1 | t1 | -| Test.kt:82:21:89:1 | { ... } | Test.kt:84:3:84:18 | x | +| Test.kt:82:21:89:1 | { ... } | Test.kt:84:7:84:7 | x | | Test.kt:82:21:89:1 | { ... } | Test.kt:86:4:88:2 | catch (...) | | Test.kt:91:22:98:1 | { ... } | Test.kt:91:1:98:1 | t2 | -| Test.kt:91:22:98:1 | { ... } | Test.kt:93:3:93:13 | x | +| Test.kt:91:22:98:1 | { ... } | Test.kt:93:7:93:7 | x | | Test.kt:91:22:98:1 | { ... } | Test.kt:95:4:97:2 | catch (...) | | Test.kt:100:25:110:1 | { ... } | Test.kt:100:1:110:1 | fn | | Test.kt:100:25:110:1 | { ... } | Test.kt:101:22:101:22 | y | diff --git a/java/ql/test/kotlin/library-tests/controlflow/basic/bbSuccessor.expected b/java/ql/test/kotlin/library-tests/controlflow/basic/bbSuccessor.expected index 512a6907e2a..35c28b25b91 100644 --- a/java/ql/test/kotlin/library-tests/controlflow/basic/bbSuccessor.expected +++ b/java/ql/test/kotlin/library-tests/controlflow/basic/bbSuccessor.expected @@ -13,13 +13,13 @@ | Test.kt:38:9:38:9 | x | Test.kt:43:3:43:3 | ; | | Test.kt:38:16:41:3 | { ... } | Test.kt:38:9:38:9 | x | | Test.kt:43:3:43:3 | ; | Test.kt:4:2:79:2 | test | -| Test.kt:82:21:89:1 | { ... } | Test.kt:84:3:84:18 | x | +| Test.kt:82:21:89:1 | { ... } | Test.kt:84:7:84:7 | x | | Test.kt:82:21:89:1 | { ... } | Test.kt:86:4:88:2 | catch (...) | -| Test.kt:84:3:84:18 | x | Test.kt:82:1:89:1 | t1 | +| Test.kt:84:7:84:7 | x | Test.kt:82:1:89:1 | t1 | | Test.kt:86:4:88:2 | catch (...) | Test.kt:82:1:89:1 | t1 | -| Test.kt:91:22:98:1 | { ... } | Test.kt:93:3:93:13 | x | +| Test.kt:91:22:98:1 | { ... } | Test.kt:93:7:93:7 | x | | Test.kt:91:22:98:1 | { ... } | Test.kt:95:4:97:2 | catch (...) | -| Test.kt:93:3:93:13 | x | Test.kt:91:1:98:1 | t2 | +| Test.kt:93:7:93:7 | x | Test.kt:91:1:98:1 | t2 | | Test.kt:95:4:97:2 | catch (...) | Test.kt:91:1:98:1 | t2 | | Test.kt:100:25:110:1 | { ... } | Test.kt:101:22:101:22 | y | | Test.kt:100:25:110:1 | { ... } | Test.kt:105:5:109:5 | ; | diff --git a/java/ql/test/kotlin/library-tests/controlflow/basic/getASuccessor.expected b/java/ql/test/kotlin/library-tests/controlflow/basic/getASuccessor.expected index ddd54d10b7b..36544bd2d93 100644 --- a/java/ql/test/kotlin/library-tests/controlflow/basic/getASuccessor.expected +++ b/java/ql/test/kotlin/library-tests/controlflow/basic/getASuccessor.expected @@ -8,23 +8,23 @@ missingSuccessor | Test.kt:3:8:80:1 | { ... } | BlockStmt | Test.kt:3:8:80:1 | Test | Constructor | | Test.kt:4:2:79:2 | Unit | TypeAccess | file://:0:0:0:0 | | | | Test.kt:4:2:79:2 | test | Method | file://:0:0:0:0 | | | -| Test.kt:4:13:79:2 | { ... } | BlockStmt | Test.kt:5:3:5:16 | var ...; | LocalVariableDeclStmt | -| Test.kt:5:3:5:16 | int x | LocalVariableDecl | file://:0:0:0:0 | | | -| Test.kt:5:3:5:16 | var ...; | LocalVariableDeclStmt | Test.kt:5:16:5:16 | 0 | IntegerLiteral | -| Test.kt:5:3:5:16 | x | LocalVariableDeclExpr | Test.kt:6:3:6:18 | var ...; | LocalVariableDeclStmt | -| Test.kt:5:16:5:16 | 0 | IntegerLiteral | Test.kt:5:3:5:16 | x | LocalVariableDeclExpr | -| Test.kt:6:3:6:18 | long y | LocalVariableDecl | file://:0:0:0:0 | | | -| Test.kt:6:3:6:18 | var ...; | LocalVariableDeclStmt | Test.kt:6:17:6:18 | 50 | LongLiteral | -| Test.kt:6:3:6:18 | y | LocalVariableDeclExpr | Test.kt:7:3:7:16 | var ...; | LocalVariableDeclStmt | -| Test.kt:6:17:6:18 | 50 | LongLiteral | Test.kt:6:3:6:18 | y | LocalVariableDeclExpr | -| Test.kt:7:3:7:16 | int z | LocalVariableDecl | file://:0:0:0:0 | | | -| Test.kt:7:3:7:16 | var ...; | LocalVariableDeclStmt | Test.kt:7:16:7:16 | 0 | IntegerLiteral | -| Test.kt:7:3:7:16 | z | LocalVariableDeclExpr | Test.kt:8:3:8:16 | var ...; | LocalVariableDeclStmt | -| Test.kt:7:16:7:16 | 0 | IntegerLiteral | Test.kt:7:3:7:16 | z | LocalVariableDeclExpr | -| Test.kt:8:3:8:16 | int w | LocalVariableDecl | file://:0:0:0:0 | | | -| Test.kt:8:3:8:16 | var ...; | LocalVariableDeclStmt | Test.kt:8:16:8:16 | 0 | IntegerLiteral | -| Test.kt:8:3:8:16 | w | LocalVariableDeclExpr | Test.kt:11:3:16:3 | ; | ExprStmt | -| Test.kt:8:16:8:16 | 0 | IntegerLiteral | Test.kt:8:3:8:16 | w | LocalVariableDeclExpr | +| Test.kt:4:13:79:2 | { ... } | BlockStmt | Test.kt:5:7:5:7 | var ...; | LocalVariableDeclStmt | +| Test.kt:5:7:5:7 | int x | LocalVariableDecl | file://:0:0:0:0 | | | +| Test.kt:5:7:5:7 | var ...; | LocalVariableDeclStmt | Test.kt:5:16:5:16 | 0 | IntegerLiteral | +| Test.kt:5:7:5:7 | x | LocalVariableDeclExpr | Test.kt:6:7:6:7 | var ...; | LocalVariableDeclStmt | +| Test.kt:5:16:5:16 | 0 | IntegerLiteral | Test.kt:5:7:5:7 | x | LocalVariableDeclExpr | +| Test.kt:6:7:6:7 | long y | LocalVariableDecl | file://:0:0:0:0 | | | +| Test.kt:6:7:6:7 | var ...; | LocalVariableDeclStmt | Test.kt:6:17:6:18 | 50 | LongLiteral | +| Test.kt:6:7:6:7 | y | LocalVariableDeclExpr | Test.kt:7:7:7:7 | var ...; | LocalVariableDeclStmt | +| Test.kt:6:17:6:18 | 50 | LongLiteral | Test.kt:6:7:6:7 | y | LocalVariableDeclExpr | +| Test.kt:7:7:7:7 | int z | LocalVariableDecl | file://:0:0:0:0 | | | +| Test.kt:7:7:7:7 | var ...; | LocalVariableDeclStmt | Test.kt:7:16:7:16 | 0 | IntegerLiteral | +| Test.kt:7:7:7:7 | z | LocalVariableDeclExpr | Test.kt:8:7:8:7 | var ...; | LocalVariableDeclStmt | +| Test.kt:7:16:7:16 | 0 | IntegerLiteral | Test.kt:7:7:7:7 | z | LocalVariableDeclExpr | +| Test.kt:8:7:8:7 | int w | LocalVariableDecl | file://:0:0:0:0 | | | +| Test.kt:8:7:8:7 | var ...; | LocalVariableDeclStmt | Test.kt:8:16:8:16 | 0 | IntegerLiteral | +| Test.kt:8:7:8:7 | w | LocalVariableDeclExpr | Test.kt:11:3:16:3 | ; | ExprStmt | +| Test.kt:8:16:8:16 | 0 | IntegerLiteral | Test.kt:8:7:8:7 | w | LocalVariableDeclExpr | | Test.kt:11:3:16:3 | ... -> ... | WhenBranch | Test.kt:11:3:16:3 | true | BooleanLiteral | | Test.kt:11:3:16:3 | ... -> ... | WhenBranch | Test.kt:11:7:11:7 | x | VarAccess | | Test.kt:11:3:16:3 | ; | ExprStmt | Test.kt:11:3:16:3 | when ... | WhenExpr | @@ -137,12 +137,12 @@ missingSuccessor | Test.kt:82:8:82:13 | o | Parameter | file://:0:0:0:0 | | | | Test.kt:82:21:89:1 | { ... } | BlockStmt | Test.kt:83:2:88:2 | try ... | TryStmt | | Test.kt:83:2:88:2 | try ... | TryStmt | Test.kt:83:6:86:2 | { ... } | BlockStmt | -| Test.kt:83:6:86:2 | { ... } | BlockStmt | Test.kt:84:3:84:18 | var ...; | LocalVariableDeclStmt | -| Test.kt:84:3:84:18 | int x | LocalVariableDecl | file://:0:0:0:0 | | | -| Test.kt:84:3:84:18 | var ...; | LocalVariableDeclStmt | Test.kt:84:11:84:11 | o | VarAccess | -| Test.kt:84:3:84:18 | x | LocalVariableDeclExpr | Test.kt:85:10:85:10 | 1 | IntegerLiteral | +| Test.kt:83:6:86:2 | { ... } | BlockStmt | Test.kt:84:7:84:7 | var ...; | LocalVariableDeclStmt | +| Test.kt:84:7:84:7 | int x | LocalVariableDecl | file://:0:0:0:0 | | | +| Test.kt:84:7:84:7 | var ...; | LocalVariableDeclStmt | Test.kt:84:11:84:11 | o | VarAccess | +| Test.kt:84:7:84:7 | x | LocalVariableDeclExpr | Test.kt:85:10:85:10 | 1 | IntegerLiteral | | Test.kt:84:11:84:11 | o | VarAccess | Test.kt:84:11:84:18 | (...)... | CastExpr | -| Test.kt:84:11:84:18 | (...)... | CastExpr | Test.kt:84:3:84:18 | x | LocalVariableDeclExpr | +| Test.kt:84:11:84:18 | (...)... | CastExpr | Test.kt:84:7:84:7 | x | LocalVariableDeclExpr | | Test.kt:84:11:84:18 | (...)... | CastExpr | Test.kt:86:4:88:2 | catch (...) | CatchClause | | Test.kt:84:11:84:18 | int | TypeAccess | file://:0:0:0:0 | | | | Test.kt:85:3:85:10 | return ... | ReturnStmt | Test.kt:82:1:89:1 | t1 | Method | @@ -160,12 +160,12 @@ missingSuccessor | Test.kt:91:8:91:14 | o | Parameter | file://:0:0:0:0 | | | | Test.kt:91:22:98:1 | { ... } | BlockStmt | Test.kt:92:2:97:2 | try ... | TryStmt | | Test.kt:92:2:97:2 | try ... | TryStmt | Test.kt:92:6:95:2 | { ... } | BlockStmt | -| Test.kt:92:6:95:2 | { ... } | BlockStmt | Test.kt:93:3:93:13 | var ...; | LocalVariableDeclStmt | -| Test.kt:93:3:93:13 | Object x | LocalVariableDecl | file://:0:0:0:0 | | | -| Test.kt:93:3:93:13 | var ...; | LocalVariableDeclStmt | Test.kt:93:11:93:11 | o | VarAccess | -| Test.kt:93:3:93:13 | x | LocalVariableDeclExpr | Test.kt:94:10:94:10 | 1 | IntegerLiteral | +| Test.kt:92:6:95:2 | { ... } | BlockStmt | Test.kt:93:7:93:7 | var ...; | LocalVariableDeclStmt | +| Test.kt:93:7:93:7 | Object x | LocalVariableDecl | file://:0:0:0:0 | | | +| Test.kt:93:7:93:7 | var ...; | LocalVariableDeclStmt | Test.kt:93:11:93:11 | o | VarAccess | +| Test.kt:93:7:93:7 | x | LocalVariableDeclExpr | Test.kt:94:10:94:10 | 1 | IntegerLiteral | | Test.kt:93:11:93:11 | o | VarAccess | Test.kt:93:12:93:13 | ...!! | NotNullExpr | -| Test.kt:93:12:93:13 | ...!! | NotNullExpr | Test.kt:93:3:93:13 | x | LocalVariableDeclExpr | +| Test.kt:93:12:93:13 | ...!! | NotNullExpr | Test.kt:93:7:93:7 | x | LocalVariableDeclExpr | | Test.kt:93:12:93:13 | ...!! | NotNullExpr | Test.kt:95:4:97:2 | catch (...) | CatchClause | | Test.kt:94:3:94:10 | return ... | ReturnStmt | Test.kt:91:1:98:1 | t2 | Method | | Test.kt:94:10:94:10 | 1 | IntegerLiteral | Test.kt:94:3:94:10 | return ... | ReturnStmt | diff --git a/java/ql/test/kotlin/library-tests/controlflow/basic/strictDominance.expected b/java/ql/test/kotlin/library-tests/controlflow/basic/strictDominance.expected index b48a2016130..e5e94d38421 100644 --- a/java/ql/test/kotlin/library-tests/controlflow/basic/strictDominance.expected +++ b/java/ql/test/kotlin/library-tests/controlflow/basic/strictDominance.expected @@ -1,10 +1,10 @@ | Test.kt:3:1:80:1 | super(...) | Test.kt:3:8:80:1 | { ... } | | Test.kt:3:1:80:1 | { ... } | Test.kt:3:1:80:1 | super(...) | | Test.kt:3:1:80:1 | { ... } | Test.kt:3:8:80:1 | { ... } | -| Test.kt:4:13:79:2 | { ... } | Test.kt:5:3:5:16 | var ...; | -| Test.kt:4:13:79:2 | { ... } | Test.kt:6:3:6:18 | var ...; | -| Test.kt:4:13:79:2 | { ... } | Test.kt:7:3:7:16 | var ...; | -| Test.kt:4:13:79:2 | { ... } | Test.kt:8:3:8:16 | var ...; | +| Test.kt:4:13:79:2 | { ... } | Test.kt:5:7:5:7 | var ...; | +| Test.kt:4:13:79:2 | { ... } | Test.kt:6:7:6:7 | var ...; | +| Test.kt:4:13:79:2 | { ... } | Test.kt:7:7:7:7 | var ...; | +| Test.kt:4:13:79:2 | { ... } | Test.kt:8:7:8:7 | var ...; | | Test.kt:4:13:79:2 | { ... } | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:4:13:79:2 | { ... } | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:4:13:79:2 | { ... } | Test.kt:11:3:16:3 | ; | @@ -38,144 +38,144 @@ | Test.kt:4:13:79:2 | { ... } | Test.kt:73:3:73:3 | ; | | Test.kt:4:13:79:2 | { ... } | Test.kt:77:3:77:3 | ; | | Test.kt:4:13:79:2 | { ... } | Test.kt:78:3:78:8 | return ... | -| Test.kt:5:3:5:16 | var ...; | Test.kt:6:3:6:18 | var ...; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:7:3:7:16 | var ...; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:8:3:8:16 | var ...; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:11:3:16:3 | ... -> ... | -| Test.kt:5:3:5:16 | var ...; | Test.kt:11:3:16:3 | ... -> ... | -| Test.kt:5:3:5:16 | var ...; | Test.kt:11:3:16:3 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:11:14:14:3 | { ... } | -| Test.kt:5:3:5:16 | var ...; | Test.kt:12:4:12:4 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:13:4:13:4 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:14:10:16:3 | { ... } | -| Test.kt:5:3:5:16 | var ...; | Test.kt:15:4:15:4 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:18:3:18:3 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:21:3:24:9 | ... -> ... | -| Test.kt:5:3:5:16 | var ...; | Test.kt:21:3:24:9 | ... -> ... | -| Test.kt:5:3:5:16 | var ...; | Test.kt:21:3:24:9 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:22:4:22:4 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:24:4:24:9 | return ... | -| Test.kt:5:3:5:16 | var ...; | Test.kt:27:3:27:3 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:30:3:33:3 | ... -> ... | -| Test.kt:5:3:5:16 | var ...; | Test.kt:30:3:33:3 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:30:15:33:3 | { ... } | -| Test.kt:5:3:5:16 | var ...; | Test.kt:31:4:31:4 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:32:4:32:4 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:35:3:35:3 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:38:3:41:3 | while (...) | -| Test.kt:5:3:5:16 | var ...; | Test.kt:38:16:41:3 | { ... } | -| Test.kt:5:3:5:16 | var ...; | Test.kt:39:4:39:4 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:40:4:40:4 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:40:4:40:6 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:40:4:40:6 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:40:4:40:6 | var ...; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:40:4:40:6 | { ... } | -| Test.kt:5:3:5:16 | var ...; | Test.kt:43:3:43:3 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:73:3:73:3 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:77:3:77:3 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:78:3:78:8 | return ... | -| Test.kt:6:3:6:18 | var ...; | Test.kt:7:3:7:16 | var ...; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:8:3:8:16 | var ...; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:11:3:16:3 | ... -> ... | -| Test.kt:6:3:6:18 | var ...; | Test.kt:11:3:16:3 | ... -> ... | -| Test.kt:6:3:6:18 | var ...; | Test.kt:11:3:16:3 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:11:14:14:3 | { ... } | -| Test.kt:6:3:6:18 | var ...; | Test.kt:12:4:12:4 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:13:4:13:4 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:14:10:16:3 | { ... } | -| Test.kt:6:3:6:18 | var ...; | Test.kt:15:4:15:4 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:18:3:18:3 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:21:3:24:9 | ... -> ... | -| Test.kt:6:3:6:18 | var ...; | Test.kt:21:3:24:9 | ... -> ... | -| Test.kt:6:3:6:18 | var ...; | Test.kt:21:3:24:9 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:22:4:22:4 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:24:4:24:9 | return ... | -| Test.kt:6:3:6:18 | var ...; | Test.kt:27:3:27:3 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:30:3:33:3 | ... -> ... | -| Test.kt:6:3:6:18 | var ...; | Test.kt:30:3:33:3 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:30:15:33:3 | { ... } | -| Test.kt:6:3:6:18 | var ...; | Test.kt:31:4:31:4 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:32:4:32:4 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:35:3:35:3 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:38:3:41:3 | while (...) | -| Test.kt:6:3:6:18 | var ...; | Test.kt:38:16:41:3 | { ... } | -| Test.kt:6:3:6:18 | var ...; | Test.kt:39:4:39:4 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:40:4:40:4 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:40:4:40:6 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:40:4:40:6 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:40:4:40:6 | var ...; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:40:4:40:6 | { ... } | -| Test.kt:6:3:6:18 | var ...; | Test.kt:43:3:43:3 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:73:3:73:3 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:77:3:77:3 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:78:3:78:8 | return ... | -| Test.kt:7:3:7:16 | var ...; | Test.kt:8:3:8:16 | var ...; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:11:3:16:3 | ... -> ... | -| Test.kt:7:3:7:16 | var ...; | Test.kt:11:3:16:3 | ... -> ... | -| Test.kt:7:3:7:16 | var ...; | Test.kt:11:3:16:3 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:11:14:14:3 | { ... } | -| Test.kt:7:3:7:16 | var ...; | Test.kt:12:4:12:4 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:13:4:13:4 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:14:10:16:3 | { ... } | -| Test.kt:7:3:7:16 | var ...; | Test.kt:15:4:15:4 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:18:3:18:3 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:21:3:24:9 | ... -> ... | -| Test.kt:7:3:7:16 | var ...; | Test.kt:21:3:24:9 | ... -> ... | -| Test.kt:7:3:7:16 | var ...; | Test.kt:21:3:24:9 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:22:4:22:4 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:24:4:24:9 | return ... | -| Test.kt:7:3:7:16 | var ...; | Test.kt:27:3:27:3 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:30:3:33:3 | ... -> ... | -| Test.kt:7:3:7:16 | var ...; | Test.kt:30:3:33:3 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:30:15:33:3 | { ... } | -| Test.kt:7:3:7:16 | var ...; | Test.kt:31:4:31:4 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:32:4:32:4 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:35:3:35:3 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:38:3:41:3 | while (...) | -| Test.kt:7:3:7:16 | var ...; | Test.kt:38:16:41:3 | { ... } | -| Test.kt:7:3:7:16 | var ...; | Test.kt:39:4:39:4 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:40:4:40:4 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:40:4:40:6 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:40:4:40:6 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:40:4:40:6 | var ...; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:40:4:40:6 | { ... } | -| Test.kt:7:3:7:16 | var ...; | Test.kt:43:3:43:3 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:73:3:73:3 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:77:3:77:3 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:78:3:78:8 | return ... | -| Test.kt:8:3:8:16 | var ...; | Test.kt:11:3:16:3 | ... -> ... | -| Test.kt:8:3:8:16 | var ...; | Test.kt:11:3:16:3 | ... -> ... | -| Test.kt:8:3:8:16 | var ...; | Test.kt:11:3:16:3 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:11:14:14:3 | { ... } | -| Test.kt:8:3:8:16 | var ...; | Test.kt:12:4:12:4 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:13:4:13:4 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:14:10:16:3 | { ... } | -| Test.kt:8:3:8:16 | var ...; | Test.kt:15:4:15:4 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:18:3:18:3 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:21:3:24:9 | ... -> ... | -| Test.kt:8:3:8:16 | var ...; | Test.kt:21:3:24:9 | ... -> ... | -| Test.kt:8:3:8:16 | var ...; | Test.kt:21:3:24:9 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:22:4:22:4 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:24:4:24:9 | return ... | -| Test.kt:8:3:8:16 | var ...; | Test.kt:27:3:27:3 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:30:3:33:3 | ... -> ... | -| Test.kt:8:3:8:16 | var ...; | Test.kt:30:3:33:3 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:30:15:33:3 | { ... } | -| Test.kt:8:3:8:16 | var ...; | Test.kt:31:4:31:4 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:32:4:32:4 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:35:3:35:3 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:38:3:41:3 | while (...) | -| Test.kt:8:3:8:16 | var ...; | Test.kt:38:16:41:3 | { ... } | -| Test.kt:8:3:8:16 | var ...; | Test.kt:39:4:39:4 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:40:4:40:4 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:40:4:40:6 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:40:4:40:6 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:40:4:40:6 | var ...; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:40:4:40:6 | { ... } | -| Test.kt:8:3:8:16 | var ...; | Test.kt:43:3:43:3 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:73:3:73:3 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:77:3:77:3 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:78:3:78:8 | return ... | +| Test.kt:5:7:5:7 | var ...; | Test.kt:6:7:6:7 | var ...; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:7:7:7:7 | var ...; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:8:7:8:7 | var ...; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:11:3:16:3 | ... -> ... | +| Test.kt:5:7:5:7 | var ...; | Test.kt:11:3:16:3 | ... -> ... | +| Test.kt:5:7:5:7 | var ...; | Test.kt:11:3:16:3 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:11:14:14:3 | { ... } | +| Test.kt:5:7:5:7 | var ...; | Test.kt:12:4:12:4 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:13:4:13:4 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:14:10:16:3 | { ... } | +| Test.kt:5:7:5:7 | var ...; | Test.kt:15:4:15:4 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:18:3:18:3 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:21:3:24:9 | ... -> ... | +| Test.kt:5:7:5:7 | var ...; | Test.kt:21:3:24:9 | ... -> ... | +| Test.kt:5:7:5:7 | var ...; | Test.kt:21:3:24:9 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:22:4:22:4 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:24:4:24:9 | return ... | +| Test.kt:5:7:5:7 | var ...; | Test.kt:27:3:27:3 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:30:3:33:3 | ... -> ... | +| Test.kt:5:7:5:7 | var ...; | Test.kt:30:3:33:3 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:30:15:33:3 | { ... } | +| Test.kt:5:7:5:7 | var ...; | Test.kt:31:4:31:4 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:32:4:32:4 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:35:3:35:3 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:38:3:41:3 | while (...) | +| Test.kt:5:7:5:7 | var ...; | Test.kt:38:16:41:3 | { ... } | +| Test.kt:5:7:5:7 | var ...; | Test.kt:39:4:39:4 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:40:4:40:4 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:40:4:40:6 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:40:4:40:6 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:40:4:40:6 | var ...; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:40:4:40:6 | { ... } | +| Test.kt:5:7:5:7 | var ...; | Test.kt:43:3:43:3 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:73:3:73:3 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:77:3:77:3 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:78:3:78:8 | return ... | +| Test.kt:6:7:6:7 | var ...; | Test.kt:7:7:7:7 | var ...; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:8:7:8:7 | var ...; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:11:3:16:3 | ... -> ... | +| Test.kt:6:7:6:7 | var ...; | Test.kt:11:3:16:3 | ... -> ... | +| Test.kt:6:7:6:7 | var ...; | Test.kt:11:3:16:3 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:11:14:14:3 | { ... } | +| Test.kt:6:7:6:7 | var ...; | Test.kt:12:4:12:4 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:13:4:13:4 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:14:10:16:3 | { ... } | +| Test.kt:6:7:6:7 | var ...; | Test.kt:15:4:15:4 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:18:3:18:3 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:21:3:24:9 | ... -> ... | +| Test.kt:6:7:6:7 | var ...; | Test.kt:21:3:24:9 | ... -> ... | +| Test.kt:6:7:6:7 | var ...; | Test.kt:21:3:24:9 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:22:4:22:4 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:24:4:24:9 | return ... | +| Test.kt:6:7:6:7 | var ...; | Test.kt:27:3:27:3 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:30:3:33:3 | ... -> ... | +| Test.kt:6:7:6:7 | var ...; | Test.kt:30:3:33:3 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:30:15:33:3 | { ... } | +| Test.kt:6:7:6:7 | var ...; | Test.kt:31:4:31:4 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:32:4:32:4 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:35:3:35:3 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:38:3:41:3 | while (...) | +| Test.kt:6:7:6:7 | var ...; | Test.kt:38:16:41:3 | { ... } | +| Test.kt:6:7:6:7 | var ...; | Test.kt:39:4:39:4 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:40:4:40:4 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:40:4:40:6 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:40:4:40:6 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:40:4:40:6 | var ...; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:40:4:40:6 | { ... } | +| Test.kt:6:7:6:7 | var ...; | Test.kt:43:3:43:3 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:73:3:73:3 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:77:3:77:3 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:78:3:78:8 | return ... | +| Test.kt:7:7:7:7 | var ...; | Test.kt:8:7:8:7 | var ...; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:11:3:16:3 | ... -> ... | +| Test.kt:7:7:7:7 | var ...; | Test.kt:11:3:16:3 | ... -> ... | +| Test.kt:7:7:7:7 | var ...; | Test.kt:11:3:16:3 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:11:14:14:3 | { ... } | +| Test.kt:7:7:7:7 | var ...; | Test.kt:12:4:12:4 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:13:4:13:4 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:14:10:16:3 | { ... } | +| Test.kt:7:7:7:7 | var ...; | Test.kt:15:4:15:4 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:18:3:18:3 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:21:3:24:9 | ... -> ... | +| Test.kt:7:7:7:7 | var ...; | Test.kt:21:3:24:9 | ... -> ... | +| Test.kt:7:7:7:7 | var ...; | Test.kt:21:3:24:9 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:22:4:22:4 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:24:4:24:9 | return ... | +| Test.kt:7:7:7:7 | var ...; | Test.kt:27:3:27:3 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:30:3:33:3 | ... -> ... | +| Test.kt:7:7:7:7 | var ...; | Test.kt:30:3:33:3 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:30:15:33:3 | { ... } | +| Test.kt:7:7:7:7 | var ...; | Test.kt:31:4:31:4 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:32:4:32:4 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:35:3:35:3 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:38:3:41:3 | while (...) | +| Test.kt:7:7:7:7 | var ...; | Test.kt:38:16:41:3 | { ... } | +| Test.kt:7:7:7:7 | var ...; | Test.kt:39:4:39:4 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:40:4:40:4 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:40:4:40:6 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:40:4:40:6 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:40:4:40:6 | var ...; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:40:4:40:6 | { ... } | +| Test.kt:7:7:7:7 | var ...; | Test.kt:43:3:43:3 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:73:3:73:3 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:77:3:77:3 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:78:3:78:8 | return ... | +| Test.kt:8:7:8:7 | var ...; | Test.kt:11:3:16:3 | ... -> ... | +| Test.kt:8:7:8:7 | var ...; | Test.kt:11:3:16:3 | ... -> ... | +| Test.kt:8:7:8:7 | var ...; | Test.kt:11:3:16:3 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:11:14:14:3 | { ... } | +| Test.kt:8:7:8:7 | var ...; | Test.kt:12:4:12:4 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:13:4:13:4 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:14:10:16:3 | { ... } | +| Test.kt:8:7:8:7 | var ...; | Test.kt:15:4:15:4 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:18:3:18:3 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:21:3:24:9 | ... -> ... | +| Test.kt:8:7:8:7 | var ...; | Test.kt:21:3:24:9 | ... -> ... | +| Test.kt:8:7:8:7 | var ...; | Test.kt:21:3:24:9 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:22:4:22:4 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:24:4:24:9 | return ... | +| Test.kt:8:7:8:7 | var ...; | Test.kt:27:3:27:3 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:30:3:33:3 | ... -> ... | +| Test.kt:8:7:8:7 | var ...; | Test.kt:30:3:33:3 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:30:15:33:3 | { ... } | +| Test.kt:8:7:8:7 | var ...; | Test.kt:31:4:31:4 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:32:4:32:4 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:35:3:35:3 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:38:3:41:3 | while (...) | +| Test.kt:8:7:8:7 | var ...; | Test.kt:38:16:41:3 | { ... } | +| Test.kt:8:7:8:7 | var ...; | Test.kt:39:4:39:4 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:40:4:40:4 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:40:4:40:6 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:40:4:40:6 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:40:4:40:6 | var ...; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:40:4:40:6 | { ... } | +| Test.kt:8:7:8:7 | var ...; | Test.kt:43:3:43:3 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:73:3:73:3 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:77:3:77:3 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:78:3:78:8 | return ... | | Test.kt:11:3:16:3 | ... -> ... | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:11:3:16:3 | ... -> ... | Test.kt:11:14:14:3 | { ... } | | Test.kt:11:3:16:3 | ... -> ... | Test.kt:12:4:12:4 | ; | @@ -440,51 +440,51 @@ | Test.kt:77:3:77:3 | ; | Test.kt:78:3:78:8 | return ... | | Test.kt:82:21:89:1 | { ... } | Test.kt:83:2:88:2 | try ... | | Test.kt:82:21:89:1 | { ... } | Test.kt:83:6:86:2 | { ... } | -| Test.kt:82:21:89:1 | { ... } | Test.kt:84:3:84:18 | var ...; | +| Test.kt:82:21:89:1 | { ... } | Test.kt:84:7:84:7 | var ...; | | Test.kt:82:21:89:1 | { ... } | Test.kt:85:3:85:10 | return ... | | Test.kt:82:21:89:1 | { ... } | Test.kt:86:4:88:2 | catch (...) | | Test.kt:82:21:89:1 | { ... } | Test.kt:86:34:88:2 | { ... } | | Test.kt:82:21:89:1 | { ... } | Test.kt:87:3:87:10 | return ... | | Test.kt:83:2:88:2 | try ... | Test.kt:83:6:86:2 | { ... } | -| Test.kt:83:2:88:2 | try ... | Test.kt:84:3:84:18 | var ...; | +| Test.kt:83:2:88:2 | try ... | Test.kt:84:7:84:7 | var ...; | | Test.kt:83:2:88:2 | try ... | Test.kt:85:3:85:10 | return ... | | Test.kt:83:2:88:2 | try ... | Test.kt:86:4:88:2 | catch (...) | | Test.kt:83:2:88:2 | try ... | Test.kt:86:34:88:2 | { ... } | | Test.kt:83:2:88:2 | try ... | Test.kt:87:3:87:10 | return ... | -| Test.kt:83:6:86:2 | { ... } | Test.kt:84:3:84:18 | var ...; | +| Test.kt:83:6:86:2 | { ... } | Test.kt:84:7:84:7 | var ...; | | Test.kt:83:6:86:2 | { ... } | Test.kt:85:3:85:10 | return ... | | Test.kt:83:6:86:2 | { ... } | Test.kt:86:4:88:2 | catch (...) | | Test.kt:83:6:86:2 | { ... } | Test.kt:86:34:88:2 | { ... } | | Test.kt:83:6:86:2 | { ... } | Test.kt:87:3:87:10 | return ... | -| Test.kt:84:3:84:18 | var ...; | Test.kt:85:3:85:10 | return ... | -| Test.kt:84:3:84:18 | var ...; | Test.kt:86:4:88:2 | catch (...) | -| Test.kt:84:3:84:18 | var ...; | Test.kt:86:34:88:2 | { ... } | -| Test.kt:84:3:84:18 | var ...; | Test.kt:87:3:87:10 | return ... | +| Test.kt:84:7:84:7 | var ...; | Test.kt:85:3:85:10 | return ... | +| Test.kt:84:7:84:7 | var ...; | Test.kt:86:4:88:2 | catch (...) | +| Test.kt:84:7:84:7 | var ...; | Test.kt:86:34:88:2 | { ... } | +| Test.kt:84:7:84:7 | var ...; | Test.kt:87:3:87:10 | return ... | | Test.kt:86:4:88:2 | catch (...) | Test.kt:86:34:88:2 | { ... } | | Test.kt:86:4:88:2 | catch (...) | Test.kt:87:3:87:10 | return ... | | Test.kt:86:34:88:2 | { ... } | Test.kt:87:3:87:10 | return ... | | Test.kt:91:22:98:1 | { ... } | Test.kt:92:2:97:2 | try ... | | Test.kt:91:22:98:1 | { ... } | Test.kt:92:6:95:2 | { ... } | -| Test.kt:91:22:98:1 | { ... } | Test.kt:93:3:93:13 | var ...; | +| Test.kt:91:22:98:1 | { ... } | Test.kt:93:7:93:7 | var ...; | | Test.kt:91:22:98:1 | { ... } | Test.kt:94:3:94:10 | return ... | | Test.kt:91:22:98:1 | { ... } | Test.kt:95:4:97:2 | catch (...) | | Test.kt:91:22:98:1 | { ... } | Test.kt:95:36:97:2 | { ... } | | Test.kt:91:22:98:1 | { ... } | Test.kt:96:3:96:10 | return ... | | Test.kt:92:2:97:2 | try ... | Test.kt:92:6:95:2 | { ... } | -| Test.kt:92:2:97:2 | try ... | Test.kt:93:3:93:13 | var ...; | +| Test.kt:92:2:97:2 | try ... | Test.kt:93:7:93:7 | var ...; | | Test.kt:92:2:97:2 | try ... | Test.kt:94:3:94:10 | return ... | | Test.kt:92:2:97:2 | try ... | Test.kt:95:4:97:2 | catch (...) | | Test.kt:92:2:97:2 | try ... | Test.kt:95:36:97:2 | { ... } | | Test.kt:92:2:97:2 | try ... | Test.kt:96:3:96:10 | return ... | -| Test.kt:92:6:95:2 | { ... } | Test.kt:93:3:93:13 | var ...; | +| Test.kt:92:6:95:2 | { ... } | Test.kt:93:7:93:7 | var ...; | | Test.kt:92:6:95:2 | { ... } | Test.kt:94:3:94:10 | return ... | | Test.kt:92:6:95:2 | { ... } | Test.kt:95:4:97:2 | catch (...) | | Test.kt:92:6:95:2 | { ... } | Test.kt:95:36:97:2 | { ... } | | Test.kt:92:6:95:2 | { ... } | Test.kt:96:3:96:10 | return ... | -| Test.kt:93:3:93:13 | var ...; | Test.kt:94:3:94:10 | return ... | -| Test.kt:93:3:93:13 | var ...; | Test.kt:95:4:97:2 | catch (...) | -| Test.kt:93:3:93:13 | var ...; | Test.kt:95:36:97:2 | { ... } | -| Test.kt:93:3:93:13 | var ...; | Test.kt:96:3:96:10 | return ... | +| Test.kt:93:7:93:7 | var ...; | Test.kt:94:3:94:10 | return ... | +| Test.kt:93:7:93:7 | var ...; | Test.kt:95:4:97:2 | catch (...) | +| Test.kt:93:7:93:7 | var ...; | Test.kt:95:36:97:2 | { ... } | +| Test.kt:93:7:93:7 | var ...; | Test.kt:96:3:96:10 | return ... | | Test.kt:95:4:97:2 | catch (...) | Test.kt:95:36:97:2 | { ... } | | Test.kt:95:4:97:2 | catch (...) | Test.kt:96:3:96:10 | return ... | | Test.kt:95:36:97:2 | { ... } | Test.kt:96:3:96:10 | return ... | diff --git a/java/ql/test/kotlin/library-tests/controlflow/basic/strictPostDominance.expected b/java/ql/test/kotlin/library-tests/controlflow/basic/strictPostDominance.expected index c7d67d9959b..6d47a44d581 100644 --- a/java/ql/test/kotlin/library-tests/controlflow/basic/strictPostDominance.expected +++ b/java/ql/test/kotlin/library-tests/controlflow/basic/strictPostDominance.expected @@ -1,27 +1,27 @@ | Test.kt:3:1:80:1 | super(...) | Test.kt:3:1:80:1 | { ... } | | Test.kt:3:8:80:1 | { ... } | Test.kt:3:1:80:1 | super(...) | | Test.kt:3:8:80:1 | { ... } | Test.kt:3:1:80:1 | { ... } | -| Test.kt:5:3:5:16 | var ...; | Test.kt:4:13:79:2 | { ... } | -| Test.kt:6:3:6:18 | var ...; | Test.kt:4:13:79:2 | { ... } | -| Test.kt:6:3:6:18 | var ...; | Test.kt:5:3:5:16 | var ...; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:4:13:79:2 | { ... } | -| Test.kt:7:3:7:16 | var ...; | Test.kt:5:3:5:16 | var ...; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:6:3:6:18 | var ...; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:4:13:79:2 | { ... } | -| Test.kt:8:3:8:16 | var ...; | Test.kt:5:3:5:16 | var ...; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:6:3:6:18 | var ...; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:7:3:7:16 | var ...; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:4:13:79:2 | { ... } | +| Test.kt:6:7:6:7 | var ...; | Test.kt:4:13:79:2 | { ... } | +| Test.kt:6:7:6:7 | var ...; | Test.kt:5:7:5:7 | var ...; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:4:13:79:2 | { ... } | +| Test.kt:7:7:7:7 | var ...; | Test.kt:5:7:5:7 | var ...; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:6:7:6:7 | var ...; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:4:13:79:2 | { ... } | +| Test.kt:8:7:8:7 | var ...; | Test.kt:5:7:5:7 | var ...; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:6:7:6:7 | var ...; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:7:7:7:7 | var ...; | | Test.kt:11:3:16:3 | ... -> ... | Test.kt:4:13:79:2 | { ... } | -| Test.kt:11:3:16:3 | ... -> ... | Test.kt:5:3:5:16 | var ...; | -| Test.kt:11:3:16:3 | ... -> ... | Test.kt:6:3:6:18 | var ...; | -| Test.kt:11:3:16:3 | ... -> ... | Test.kt:7:3:7:16 | var ...; | -| Test.kt:11:3:16:3 | ... -> ... | Test.kt:8:3:8:16 | var ...; | +| Test.kt:11:3:16:3 | ... -> ... | Test.kt:5:7:5:7 | var ...; | +| Test.kt:11:3:16:3 | ... -> ... | Test.kt:6:7:6:7 | var ...; | +| Test.kt:11:3:16:3 | ... -> ... | Test.kt:7:7:7:7 | var ...; | +| Test.kt:11:3:16:3 | ... -> ... | Test.kt:8:7:8:7 | var ...; | | Test.kt:11:3:16:3 | ... -> ... | Test.kt:11:3:16:3 | ; | | Test.kt:11:3:16:3 | ; | Test.kt:4:13:79:2 | { ... } | -| Test.kt:11:3:16:3 | ; | Test.kt:5:3:5:16 | var ...; | -| Test.kt:11:3:16:3 | ; | Test.kt:6:3:6:18 | var ...; | -| Test.kt:11:3:16:3 | ; | Test.kt:7:3:7:16 | var ...; | -| Test.kt:11:3:16:3 | ; | Test.kt:8:3:8:16 | var ...; | +| Test.kt:11:3:16:3 | ; | Test.kt:5:7:5:7 | var ...; | +| Test.kt:11:3:16:3 | ; | Test.kt:6:7:6:7 | var ...; | +| Test.kt:11:3:16:3 | ; | Test.kt:7:7:7:7 | var ...; | +| Test.kt:11:3:16:3 | ; | Test.kt:8:7:8:7 | var ...; | | Test.kt:12:4:12:4 | ; | Test.kt:11:14:14:3 | { ... } | | Test.kt:13:4:13:4 | ; | Test.kt:11:14:14:3 | { ... } | | Test.kt:13:4:13:4 | ; | Test.kt:12:4:12:4 | ; | @@ -29,10 +29,10 @@ | Test.kt:15:4:15:4 | ; | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:15:4:15:4 | ; | Test.kt:14:10:16:3 | { ... } | | Test.kt:18:3:18:3 | ; | Test.kt:4:13:79:2 | { ... } | -| Test.kt:18:3:18:3 | ; | Test.kt:5:3:5:16 | var ...; | -| Test.kt:18:3:18:3 | ; | Test.kt:6:3:6:18 | var ...; | -| Test.kt:18:3:18:3 | ; | Test.kt:7:3:7:16 | var ...; | -| Test.kt:18:3:18:3 | ; | Test.kt:8:3:8:16 | var ...; | +| Test.kt:18:3:18:3 | ; | Test.kt:5:7:5:7 | var ...; | +| Test.kt:18:3:18:3 | ; | Test.kt:6:7:6:7 | var ...; | +| Test.kt:18:3:18:3 | ; | Test.kt:7:7:7:7 | var ...; | +| Test.kt:18:3:18:3 | ; | Test.kt:8:7:8:7 | var ...; | | Test.kt:18:3:18:3 | ; | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:18:3:18:3 | ; | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:18:3:18:3 | ; | Test.kt:11:3:16:3 | ; | @@ -42,10 +42,10 @@ | Test.kt:18:3:18:3 | ; | Test.kt:14:10:16:3 | { ... } | | Test.kt:18:3:18:3 | ; | Test.kt:15:4:15:4 | ; | | Test.kt:21:3:24:9 | ... -> ... | Test.kt:4:13:79:2 | { ... } | -| Test.kt:21:3:24:9 | ... -> ... | Test.kt:5:3:5:16 | var ...; | -| Test.kt:21:3:24:9 | ... -> ... | Test.kt:6:3:6:18 | var ...; | -| Test.kt:21:3:24:9 | ... -> ... | Test.kt:7:3:7:16 | var ...; | -| Test.kt:21:3:24:9 | ... -> ... | Test.kt:8:3:8:16 | var ...; | +| Test.kt:21:3:24:9 | ... -> ... | Test.kt:5:7:5:7 | var ...; | +| Test.kt:21:3:24:9 | ... -> ... | Test.kt:6:7:6:7 | var ...; | +| Test.kt:21:3:24:9 | ... -> ... | Test.kt:7:7:7:7 | var ...; | +| Test.kt:21:3:24:9 | ... -> ... | Test.kt:8:7:8:7 | var ...; | | Test.kt:21:3:24:9 | ... -> ... | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:21:3:24:9 | ... -> ... | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:21:3:24:9 | ... -> ... | Test.kt:11:3:16:3 | ; | @@ -57,10 +57,10 @@ | Test.kt:21:3:24:9 | ... -> ... | Test.kt:18:3:18:3 | ; | | Test.kt:21:3:24:9 | ... -> ... | Test.kt:21:3:24:9 | ; | | Test.kt:21:3:24:9 | ; | Test.kt:4:13:79:2 | { ... } | -| Test.kt:21:3:24:9 | ; | Test.kt:5:3:5:16 | var ...; | -| Test.kt:21:3:24:9 | ; | Test.kt:6:3:6:18 | var ...; | -| Test.kt:21:3:24:9 | ; | Test.kt:7:3:7:16 | var ...; | -| Test.kt:21:3:24:9 | ; | Test.kt:8:3:8:16 | var ...; | +| Test.kt:21:3:24:9 | ; | Test.kt:5:7:5:7 | var ...; | +| Test.kt:21:3:24:9 | ; | Test.kt:6:7:6:7 | var ...; | +| Test.kt:21:3:24:9 | ; | Test.kt:7:7:7:7 | var ...; | +| Test.kt:21:3:24:9 | ; | Test.kt:8:7:8:7 | var ...; | | Test.kt:21:3:24:9 | ; | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:21:3:24:9 | ; | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:21:3:24:9 | ; | Test.kt:11:3:16:3 | ; | @@ -189,18 +189,18 @@ | Test.kt:83:2:88:2 | try ... | Test.kt:82:21:89:1 | { ... } | | Test.kt:83:6:86:2 | { ... } | Test.kt:82:21:89:1 | { ... } | | Test.kt:83:6:86:2 | { ... } | Test.kt:83:2:88:2 | try ... | -| Test.kt:84:3:84:18 | var ...; | Test.kt:82:21:89:1 | { ... } | -| Test.kt:84:3:84:18 | var ...; | Test.kt:83:2:88:2 | try ... | -| Test.kt:84:3:84:18 | var ...; | Test.kt:83:6:86:2 | { ... } | +| Test.kt:84:7:84:7 | var ...; | Test.kt:82:21:89:1 | { ... } | +| Test.kt:84:7:84:7 | var ...; | Test.kt:83:2:88:2 | try ... | +| Test.kt:84:7:84:7 | var ...; | Test.kt:83:6:86:2 | { ... } | | Test.kt:86:34:88:2 | { ... } | Test.kt:86:4:88:2 | catch (...) | | Test.kt:87:3:87:10 | return ... | Test.kt:86:4:88:2 | catch (...) | | Test.kt:87:3:87:10 | return ... | Test.kt:86:34:88:2 | { ... } | | Test.kt:92:2:97:2 | try ... | Test.kt:91:22:98:1 | { ... } | | Test.kt:92:6:95:2 | { ... } | Test.kt:91:22:98:1 | { ... } | | Test.kt:92:6:95:2 | { ... } | Test.kt:92:2:97:2 | try ... | -| Test.kt:93:3:93:13 | var ...; | Test.kt:91:22:98:1 | { ... } | -| Test.kt:93:3:93:13 | var ...; | Test.kt:92:2:97:2 | try ... | -| Test.kt:93:3:93:13 | var ...; | Test.kt:92:6:95:2 | { ... } | +| Test.kt:93:7:93:7 | var ...; | Test.kt:91:22:98:1 | { ... } | +| Test.kt:93:7:93:7 | var ...; | Test.kt:92:2:97:2 | try ... | +| Test.kt:93:7:93:7 | var ...; | Test.kt:92:6:95:2 | { ... } | | Test.kt:95:36:97:2 | { ... } | Test.kt:95:4:97:2 | catch (...) | | Test.kt:96:3:96:10 | return ... | Test.kt:95:4:97:2 | catch (...) | | Test.kt:96:3:96:10 | return ... | Test.kt:95:36:97:2 | { ... } | diff --git a/java/ql/test/kotlin/library-tests/exprs/exprs.expected b/java/ql/test/kotlin/library-tests/exprs/exprs.expected index 4b8d200a1d7..5d35293eb22 100644 --- a/java/ql/test/kotlin/library-tests/exprs/exprs.expected +++ b/java/ql/test/kotlin/library-tests/exprs/exprs.expected @@ -904,468 +904,468 @@ | exprs.kt:8:32:8:41 | double | file://:0:0:0:0 | | TypeAccess | | exprs.kt:9:20:9:28 | float | file://:0:0:0:0 | | TypeAccess | | exprs.kt:9:31:9:39 | float | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:11:5:11:14 | i1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:11:9:11:10 | i1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:11:14:11:14 | 1 | exprs.kt:4:1:142:1 | topLevelMethod | IntegerLiteral | -| exprs.kt:12:5:12:18 | i2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:12:9:12:10 | i2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:12:14:12:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:12:14:12:18 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:12:18:12:18 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:13:5:13:18 | i3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:13:9:13:10 | i3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:13:14:13:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:13:14:13:18 | ... - ... | exprs.kt:4:1:142:1 | topLevelMethod | SubExpr | | exprs.kt:13:18:13:18 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:14:5:14:18 | i4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:14:9:14:10 | i4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:14:14:14:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:14:14:14:18 | ... / ... | exprs.kt:4:1:142:1 | topLevelMethod | DivExpr | | exprs.kt:14:18:14:18 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:15:5:15:18 | i5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:15:9:15:10 | i5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:15:14:15:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:15:14:15:18 | ... % ... | exprs.kt:4:1:142:1 | topLevelMethod | RemExpr | | exprs.kt:15:18:15:18 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:16:5:16:20 | i6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:16:9:16:10 | i6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:16:14:16:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:16:14:16:20 | ... << ... | exprs.kt:4:1:142:1 | topLevelMethod | LShiftExpr | | exprs.kt:16:20:16:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:17:5:17:20 | i7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:17:9:17:10 | i7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:17:14:17:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:17:14:17:20 | ... >> ... | exprs.kt:4:1:142:1 | topLevelMethod | RShiftExpr | | exprs.kt:17:20:17:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:18:5:18:21 | i8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:18:9:18:10 | i8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:18:14:18:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:18:14:18:21 | ... >>> ... | exprs.kt:4:1:142:1 | topLevelMethod | URShiftExpr | | exprs.kt:18:21:18:21 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:19:5:19:20 | i9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:19:9:19:10 | i9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:19:14:19:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:19:14:19:20 | ... & ... | exprs.kt:4:1:142:1 | topLevelMethod | AndBitwiseExpr | | exprs.kt:19:20:19:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:20:5:20:20 | i10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:20:9:20:11 | i10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:20:15:20:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:20:15:20:20 | ... \| ... | exprs.kt:4:1:142:1 | topLevelMethod | OrBitwiseExpr | | exprs.kt:20:20:20:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:21:5:21:21 | i11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:21:9:21:11 | i11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:21:15:21:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:21:15:21:21 | ... ^ ... | exprs.kt:4:1:142:1 | topLevelMethod | XorBitwiseExpr | | exprs.kt:21:21:21:21 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:22:5:22:21 | i12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:22:9:22:11 | i12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:22:15:22:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:22:15:22:21 | ~... | exprs.kt:4:1:142:1 | topLevelMethod | BitNotExpr | -| exprs.kt:23:5:23:20 | i13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:23:9:23:11 | i13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:23:15:23:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:23:15:23:20 | ... (value equals) ... | exprs.kt:4:1:142:1 | topLevelMethod | ValueEQExpr | | exprs.kt:23:20:23:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:24:5:24:20 | i14 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:24:9:24:11 | i14 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:24:15:24:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:24:15:24:20 | ... (value not-equals) ... | exprs.kt:4:1:142:1 | topLevelMethod | ValueNEExpr | | exprs.kt:24:20:24:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:25:5:25:19 | i15 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:25:9:25:11 | i15 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:25:15:25:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:25:15:25:19 | ... < ... | exprs.kt:4:1:142:1 | topLevelMethod | LTExpr | | exprs.kt:25:19:25:19 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:26:5:26:20 | i16 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:26:9:26:11 | i16 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:26:15:26:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:26:15:26:20 | ... <= ... | exprs.kt:4:1:142:1 | topLevelMethod | LEExpr | | exprs.kt:26:20:26:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:27:5:27:19 | i17 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:27:9:27:11 | i17 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:27:15:27:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:27:15:27:19 | ... > ... | exprs.kt:4:1:142:1 | topLevelMethod | GTExpr | | exprs.kt:27:19:27:19 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:28:5:28:20 | i18 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:28:9:28:11 | i18 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:28:15:28:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:28:15:28:20 | ... >= ... | exprs.kt:4:1:142:1 | topLevelMethod | GEExpr | | exprs.kt:28:20:28:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:29:5:29:21 | i19 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:29:9:29:11 | i19 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:29:15:29:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:29:15:29:21 | ... == ... | exprs.kt:4:1:142:1 | topLevelMethod | EQExpr | | exprs.kt:29:21:29:21 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:30:5:30:21 | i20 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:30:9:30:11 | i20 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:30:15:30:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:30:15:30:21 | ... != ... | exprs.kt:4:1:142:1 | topLevelMethod | NEExpr | | exprs.kt:30:21:30:21 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:31:5:31:25 | i21 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:31:9:31:11 | i21 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:31:15:31:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:31:15:31:25 | contains(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:31:20:31:20 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:31:20:31:25 | rangeTo(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:31:25:31:25 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:32:5:32:26 | i22 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:32:9:32:11 | i22 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:32:15:32:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:32:15:32:26 | !... | exprs.kt:4:1:142:1 | topLevelMethod | LogNotExpr | | exprs.kt:32:15:32:26 | contains(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:32:21:32:21 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:32:21:32:26 | rangeTo(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:32:26:32:26 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:34:5:34:17 | by1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:34:9:34:11 | by1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:34:15:34:17 | 1.0 | exprs.kt:4:1:142:1 | topLevelMethod | DoubleLiteral | -| exprs.kt:35:5:35:23 | by2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:35:9:35:11 | by2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:35:15:35:17 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:35:15:35:23 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:35:21:35:23 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:36:5:36:23 | by3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:36:9:36:11 | by3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:36:15:36:17 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:36:15:36:23 | ... - ... | exprs.kt:4:1:142:1 | topLevelMethod | SubExpr | | exprs.kt:36:21:36:23 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:37:5:37:23 | by4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:37:9:37:11 | by4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:37:15:37:17 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:37:15:37:23 | ... / ... | exprs.kt:4:1:142:1 | topLevelMethod | DivExpr | | exprs.kt:37:21:37:23 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:38:5:38:23 | by5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:38:9:38:11 | by5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:38:15:38:17 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:38:15:38:23 | ... % ... | exprs.kt:4:1:142:1 | topLevelMethod | RemExpr | | exprs.kt:38:21:38:23 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:39:5:39:24 | by6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:39:9:39:11 | by6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:39:15:39:17 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:39:15:39:17 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:39:15:39:24 | ... (value equals) ... | exprs.kt:4:1:142:1 | topLevelMethod | ValueEQExpr | | exprs.kt:39:22:39:24 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:39:22:39:24 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | -| exprs.kt:40:5:40:24 | by7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:40:9:40:11 | by7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:40:15:40:17 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:40:15:40:17 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:40:15:40:24 | ... (value not-equals) ... | exprs.kt:4:1:142:1 | topLevelMethod | ValueNEExpr | | exprs.kt:40:22:40:24 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:40:22:40:24 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | -| exprs.kt:41:5:41:23 | by8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:41:9:41:11 | by8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:41:15:41:17 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:41:15:41:17 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:41:15:41:23 | ... < ... | exprs.kt:4:1:142:1 | topLevelMethod | LTExpr | | exprs.kt:41:21:41:23 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:41:21:41:23 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | -| exprs.kt:42:5:42:24 | by9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:42:9:42:11 | by9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:42:15:42:17 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:42:15:42:17 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:42:15:42:24 | ... <= ... | exprs.kt:4:1:142:1 | topLevelMethod | LEExpr | | exprs.kt:42:22:42:24 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:42:22:42:24 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | -| exprs.kt:43:5:43:24 | by10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:43:9:43:12 | by10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:43:16:43:18 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:43:16:43:18 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:43:16:43:24 | ... > ... | exprs.kt:4:1:142:1 | topLevelMethod | GTExpr | | exprs.kt:43:22:43:24 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:43:22:43:24 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | -| exprs.kt:44:5:44:25 | by11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:44:9:44:12 | by11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:44:16:44:18 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:44:16:44:18 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:44:16:44:25 | ... >= ... | exprs.kt:4:1:142:1 | topLevelMethod | GEExpr | | exprs.kt:44:23:44:25 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:44:23:44:25 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | -| exprs.kt:45:5:45:26 | by12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:45:9:45:12 | by12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:45:16:45:18 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:45:16:45:26 | ... == ... | exprs.kt:4:1:142:1 | topLevelMethod | EQExpr | | exprs.kt:45:24:45:26 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:46:5:46:26 | by13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:46:9:46:12 | by13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:46:16:46:18 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:46:16:46:26 | ... != ... | exprs.kt:4:1:142:1 | topLevelMethod | NEExpr | | exprs.kt:46:24:46:26 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:47:5:47:25 | by14 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:47:9:47:12 | by14 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:47:16:47:18 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:47:16:47:25 | ... \| ... | exprs.kt:4:1:142:1 | topLevelMethod | OrBitwiseExpr | | exprs.kt:47:23:47:25 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:48:5:48:26 | by15 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:48:9:48:12 | by15 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:48:16:48:18 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:48:16:48:26 | ... & ... | exprs.kt:4:1:142:1 | topLevelMethod | AndBitwiseExpr | | exprs.kt:48:24:48:26 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:49:5:49:26 | by16 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:49:9:49:12 | by16 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:49:16:49:18 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:49:16:49:26 | ... ^ ... | exprs.kt:4:1:142:1 | topLevelMethod | XorBitwiseExpr | | exprs.kt:49:24:49:26 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:51:5:51:16 | s1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:51:9:51:10 | s1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:51:14:51:16 | 1.0 | exprs.kt:4:1:142:1 | topLevelMethod | DoubleLiteral | -| exprs.kt:52:5:52:20 | s2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:52:9:52:10 | s2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:52:14:52:15 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:52:14:52:20 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:52:19:52:20 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:53:5:53:20 | s3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:53:9:53:10 | s3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:53:14:53:15 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:53:14:53:20 | ... - ... | exprs.kt:4:1:142:1 | topLevelMethod | SubExpr | | exprs.kt:53:19:53:20 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:54:5:54:20 | s4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:54:9:54:10 | s4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:54:14:54:15 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:54:14:54:20 | ... / ... | exprs.kt:4:1:142:1 | topLevelMethod | DivExpr | | exprs.kt:54:19:54:20 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:55:5:55:20 | s5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:55:9:55:10 | s5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:55:14:55:15 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:55:14:55:20 | ... % ... | exprs.kt:4:1:142:1 | topLevelMethod | RemExpr | | exprs.kt:55:19:55:20 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:56:5:56:21 | s6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:56:9:56:10 | s6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:56:14:56:15 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:56:14:56:15 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:56:14:56:21 | ... (value equals) ... | exprs.kt:4:1:142:1 | topLevelMethod | ValueEQExpr | | exprs.kt:56:20:56:21 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:56:20:56:21 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:57:5:57:21 | s7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:57:9:57:10 | s7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:57:14:57:15 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:57:14:57:15 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:57:14:57:21 | ... (value not-equals) ... | exprs.kt:4:1:142:1 | topLevelMethod | ValueNEExpr | | exprs.kt:57:20:57:21 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:57:20:57:21 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:58:5:58:20 | s8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:58:9:58:10 | s8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:58:14:58:15 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:58:14:58:15 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:58:14:58:20 | ... < ... | exprs.kt:4:1:142:1 | topLevelMethod | LTExpr | | exprs.kt:58:19:58:20 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:58:19:58:20 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:59:5:59:21 | s9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:59:9:59:10 | s9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:59:14:59:15 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:59:14:59:15 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:59:14:59:21 | ... <= ... | exprs.kt:4:1:142:1 | topLevelMethod | LEExpr | | exprs.kt:59:20:59:21 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:59:20:59:21 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:60:5:60:21 | s10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:60:9:60:11 | s10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:60:15:60:16 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:60:15:60:16 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:60:15:60:21 | ... > ... | exprs.kt:4:1:142:1 | topLevelMethod | GTExpr | | exprs.kt:60:20:60:21 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:60:20:60:21 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:61:5:61:22 | s11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:61:9:61:11 | s11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:61:15:61:16 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:61:15:61:16 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:61:15:61:22 | ... >= ... | exprs.kt:4:1:142:1 | topLevelMethod | GEExpr | | exprs.kt:61:21:61:22 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:61:21:61:22 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:62:5:62:23 | s12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:62:9:62:11 | s12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:62:15:62:16 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:62:15:62:23 | ... == ... | exprs.kt:4:1:142:1 | topLevelMethod | EQExpr | | exprs.kt:62:22:62:23 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:63:5:63:23 | s13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:63:9:63:11 | s13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:63:15:63:16 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:63:15:63:23 | ... != ... | exprs.kt:4:1:142:1 | topLevelMethod | NEExpr | | exprs.kt:63:22:63:23 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:64:5:64:22 | s14 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:64:9:64:11 | s14 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:64:15:64:16 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:64:15:64:22 | ... \| ... | exprs.kt:4:1:142:1 | topLevelMethod | OrBitwiseExpr | | exprs.kt:64:21:64:22 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:65:5:65:23 | s15 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:65:9:65:11 | s15 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:65:15:65:16 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:65:15:65:23 | ... & ... | exprs.kt:4:1:142:1 | topLevelMethod | AndBitwiseExpr | | exprs.kt:65:22:65:23 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:66:5:66:23 | s16 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:66:9:66:11 | s16 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:66:15:66:16 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:66:15:66:23 | ... ^ ... | exprs.kt:4:1:142:1 | topLevelMethod | XorBitwiseExpr | | exprs.kt:66:22:66:23 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:68:5:68:16 | l1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:68:9:68:10 | l1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:68:14:68:16 | 1.0 | exprs.kt:4:1:142:1 | topLevelMethod | DoubleLiteral | -| exprs.kt:69:5:69:20 | l2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:69:9:69:10 | l2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:69:14:69:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:69:14:69:20 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:69:19:69:20 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:70:5:70:20 | l3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:70:9:70:10 | l3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:70:14:70:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:70:14:70:20 | ... - ... | exprs.kt:4:1:142:1 | topLevelMethod | SubExpr | | exprs.kt:70:19:70:20 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:71:5:71:20 | l4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:71:9:71:10 | l4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:71:14:71:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:71:14:71:20 | ... / ... | exprs.kt:4:1:142:1 | topLevelMethod | DivExpr | | exprs.kt:71:19:71:20 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:72:5:72:20 | l5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:72:9:72:10 | l5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:72:14:72:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:72:14:72:20 | ... % ... | exprs.kt:4:1:142:1 | topLevelMethod | RemExpr | | exprs.kt:72:19:72:20 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:73:5:73:21 | l6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:73:9:73:10 | l6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:73:14:73:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:73:14:73:21 | ... << ... | exprs.kt:4:1:142:1 | topLevelMethod | LShiftExpr | | exprs.kt:73:21:73:21 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:74:5:74:21 | l7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:74:9:74:10 | l7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:74:14:74:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:74:14:74:21 | ... >> ... | exprs.kt:4:1:142:1 | topLevelMethod | RShiftExpr | | exprs.kt:74:21:74:21 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:75:5:75:22 | l8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:75:9:75:10 | l8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:75:14:75:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:75:14:75:22 | ... >>> ... | exprs.kt:4:1:142:1 | topLevelMethod | URShiftExpr | | exprs.kt:75:22:75:22 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:76:5:76:22 | l9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:76:9:76:10 | l9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:76:14:76:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:76:14:76:22 | ... & ... | exprs.kt:4:1:142:1 | topLevelMethod | AndBitwiseExpr | | exprs.kt:76:21:76:22 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:77:5:77:22 | l10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:77:9:77:11 | l10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:77:15:77:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:77:15:77:22 | ... \| ... | exprs.kt:4:1:142:1 | topLevelMethod | OrBitwiseExpr | | exprs.kt:77:21:77:22 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:78:5:78:23 | l11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:78:9:78:11 | l11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:78:15:78:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:78:15:78:23 | ... ^ ... | exprs.kt:4:1:142:1 | topLevelMethod | XorBitwiseExpr | | exprs.kt:78:22:78:23 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:79:5:79:22 | l12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:79:9:79:11 | l12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:79:15:79:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:79:15:79:22 | ~... | exprs.kt:4:1:142:1 | topLevelMethod | BitNotExpr | -| exprs.kt:80:5:80:22 | l13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:80:9:80:11 | l13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:80:15:80:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:80:15:80:22 | ... (value equals) ... | exprs.kt:4:1:142:1 | topLevelMethod | ValueEQExpr | | exprs.kt:80:21:80:22 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:81:5:81:22 | l14 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:81:9:81:11 | l14 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:81:15:81:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:81:15:81:22 | ... (value not-equals) ... | exprs.kt:4:1:142:1 | topLevelMethod | ValueNEExpr | | exprs.kt:81:21:81:22 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:82:5:82:21 | l15 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:82:9:82:11 | l15 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:82:15:82:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:82:15:82:21 | ... < ... | exprs.kt:4:1:142:1 | topLevelMethod | LTExpr | | exprs.kt:82:20:82:21 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:83:5:83:22 | l16 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:83:9:83:11 | l16 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:83:15:83:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:83:15:83:22 | ... <= ... | exprs.kt:4:1:142:1 | topLevelMethod | LEExpr | | exprs.kt:83:21:83:22 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:84:5:84:21 | l17 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:84:9:84:11 | l17 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:84:15:84:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:84:15:84:21 | ... > ... | exprs.kt:4:1:142:1 | topLevelMethod | GTExpr | | exprs.kt:84:20:84:21 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:85:5:85:22 | l18 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:85:9:85:11 | l18 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:85:15:85:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:85:15:85:22 | ... >= ... | exprs.kt:4:1:142:1 | topLevelMethod | GEExpr | | exprs.kt:85:21:85:22 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:86:5:86:23 | l19 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:86:9:86:11 | l19 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:86:15:86:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:86:15:86:23 | ... == ... | exprs.kt:4:1:142:1 | topLevelMethod | EQExpr | | exprs.kt:86:22:86:23 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:87:5:87:23 | l20 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:87:9:87:11 | l20 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:87:15:87:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:87:15:87:23 | ... != ... | exprs.kt:4:1:142:1 | topLevelMethod | NEExpr | | exprs.kt:87:22:87:23 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:89:5:89:16 | d1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:89:9:89:10 | d1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:89:14:89:16 | 1.0 | exprs.kt:4:1:142:1 | topLevelMethod | DoubleLiteral | -| exprs.kt:90:5:90:20 | d2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:90:9:90:10 | d2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:90:14:90:15 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:90:14:90:20 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:90:19:90:20 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:91:5:91:20 | d3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:91:9:91:10 | d3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:91:14:91:15 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:91:14:91:20 | ... - ... | exprs.kt:4:1:142:1 | topLevelMethod | SubExpr | | exprs.kt:91:19:91:20 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:92:5:92:20 | d4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:92:9:92:10 | d4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:92:14:92:15 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:92:14:92:20 | ... / ... | exprs.kt:4:1:142:1 | topLevelMethod | DivExpr | | exprs.kt:92:19:92:20 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:93:5:93:20 | d5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:93:9:93:10 | d5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:93:14:93:15 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:93:14:93:20 | ... % ... | exprs.kt:4:1:142:1 | topLevelMethod | RemExpr | | exprs.kt:93:19:93:20 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:94:5:94:21 | d6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:94:9:94:10 | d6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:94:14:94:15 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:94:14:94:21 | ... == ... | exprs.kt:4:1:142:1 | topLevelMethod | EQExpr | | exprs.kt:94:20:94:21 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:95:5:95:21 | d7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:95:9:95:10 | d7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:95:14:95:15 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:95:14:95:21 | ... != ... | exprs.kt:4:1:142:1 | topLevelMethod | NEExpr | | exprs.kt:95:20:95:21 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:96:5:96:20 | d8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:96:9:96:10 | d8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:96:14:96:15 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:96:14:96:20 | ... < ... | exprs.kt:4:1:142:1 | topLevelMethod | LTExpr | | exprs.kt:96:19:96:20 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:97:5:97:21 | d9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:97:9:97:10 | d9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:97:14:97:15 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:97:14:97:21 | ... <= ... | exprs.kt:4:1:142:1 | topLevelMethod | LEExpr | | exprs.kt:97:20:97:21 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:98:5:98:21 | d10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:98:9:98:11 | d10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:98:15:98:16 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:98:15:98:21 | ... > ... | exprs.kt:4:1:142:1 | topLevelMethod | GTExpr | | exprs.kt:98:20:98:21 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:99:5:99:22 | d11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:99:9:99:11 | d11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:99:15:99:16 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:99:15:99:22 | ... >= ... | exprs.kt:4:1:142:1 | topLevelMethod | GEExpr | | exprs.kt:99:21:99:22 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:100:5:100:23 | d12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:100:9:100:11 | d12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:100:15:100:16 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:100:15:100:23 | ... == ... | exprs.kt:4:1:142:1 | topLevelMethod | EQExpr | | exprs.kt:100:22:100:23 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:101:5:101:23 | d13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:101:9:101:11 | d13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:101:15:101:16 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:101:15:101:23 | ... != ... | exprs.kt:4:1:142:1 | topLevelMethod | NEExpr | | exprs.kt:101:22:101:23 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:103:5:103:16 | f1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:103:9:103:10 | f1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:103:14:103:16 | 1.0 | exprs.kt:4:1:142:1 | topLevelMethod | DoubleLiteral | -| exprs.kt:104:5:104:20 | f2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:104:9:104:10 | f2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:104:14:104:15 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:104:14:104:20 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:104:19:104:20 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:105:5:105:20 | f3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:105:9:105:10 | f3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:105:14:105:15 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:105:14:105:20 | ... - ... | exprs.kt:4:1:142:1 | topLevelMethod | SubExpr | | exprs.kt:105:19:105:20 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:106:5:106:20 | f4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:106:9:106:10 | f4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:106:14:106:15 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:106:14:106:20 | ... / ... | exprs.kt:4:1:142:1 | topLevelMethod | DivExpr | | exprs.kt:106:19:106:20 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:107:5:107:20 | f5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:107:9:107:10 | f5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:107:14:107:15 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:107:14:107:20 | ... % ... | exprs.kt:4:1:142:1 | topLevelMethod | RemExpr | | exprs.kt:107:19:107:20 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:108:5:108:21 | f6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:108:9:108:10 | f6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:108:14:108:15 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:108:14:108:21 | ... == ... | exprs.kt:4:1:142:1 | topLevelMethod | EQExpr | | exprs.kt:108:20:108:21 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:109:5:109:21 | f7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:109:9:109:10 | f7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:109:14:109:15 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:109:14:109:21 | ... != ... | exprs.kt:4:1:142:1 | topLevelMethod | NEExpr | | exprs.kt:109:20:109:21 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:110:5:110:20 | f8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:110:9:110:10 | f8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:110:14:110:15 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:110:14:110:20 | ... < ... | exprs.kt:4:1:142:1 | topLevelMethod | LTExpr | | exprs.kt:110:19:110:20 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:111:5:111:21 | f9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:111:9:111:10 | f9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:111:14:111:15 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:111:14:111:21 | ... <= ... | exprs.kt:4:1:142:1 | topLevelMethod | LEExpr | | exprs.kt:111:20:111:21 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:112:5:112:21 | f10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:112:9:112:11 | f10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:112:15:112:16 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:112:15:112:21 | ... > ... | exprs.kt:4:1:142:1 | topLevelMethod | GTExpr | | exprs.kt:112:20:112:21 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:113:5:113:22 | f11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:113:9:113:11 | f11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:113:15:113:16 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:113:15:113:22 | ... >= ... | exprs.kt:4:1:142:1 | topLevelMethod | GEExpr | | exprs.kt:113:21:113:22 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:114:5:114:23 | f12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:114:9:114:11 | f12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:114:15:114:16 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:114:15:114:23 | ... == ... | exprs.kt:4:1:142:1 | topLevelMethod | EQExpr | | exprs.kt:114:22:114:23 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:115:5:115:23 | f13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:115:9:115:11 | f13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:115:15:115:16 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:115:15:115:23 | ... != ... | exprs.kt:4:1:142:1 | topLevelMethod | NEExpr | | exprs.kt:115:22:115:23 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:117:5:117:17 | b1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:117:9:117:10 | b1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:117:14:117:17 | true | exprs.kt:4:1:142:1 | topLevelMethod | BooleanLiteral | -| exprs.kt:118:5:118:18 | b2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:118:9:118:10 | b2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:118:14:118:18 | false | exprs.kt:4:1:142:1 | topLevelMethod | BooleanLiteral | -| exprs.kt:119:5:119:21 | b3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:119:9:119:10 | b3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:119:14:119:15 | b1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:119:14:119:21 | ... && ... | exprs.kt:4:1:142:1 | topLevelMethod | AndLogicalExpr | | exprs.kt:119:20:119:21 | b2 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:120:5:120:21 | b4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:120:9:120:10 | b4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:120:14:120:15 | b1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:120:14:120:21 | ... \|\| ... | exprs.kt:4:1:142:1 | topLevelMethod | OrLogicalExpr | | exprs.kt:120:20:120:21 | b2 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:121:5:121:16 | b5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:121:9:121:10 | b5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:121:14:121:16 | !... | exprs.kt:4:1:142:1 | topLevelMethod | LogNotExpr | | exprs.kt:121:15:121:16 | b1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:123:5:123:15 | c | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:123:9:123:9 | c | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:123:13:123:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | CharacterLiteral | -| exprs.kt:124:5:124:26 | str | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:124:9:124:11 | str | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:124:16:124:25 | "string lit" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | -| exprs.kt:125:5:125:38 | strWithQuote | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:125:9:125:20 | strWithQuote | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:125:25:125:37 | "string \\" lit" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | -| exprs.kt:126:5:126:22 | b6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:126:9:126:10 | b6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:126:14:126:15 | i1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:126:14:126:22 | ...instanceof... | exprs.kt:4:1:142:1 | topLevelMethod | InstanceOfExpr | | exprs.kt:126:14:126:22 | int | exprs.kt:4:1:142:1 | topLevelMethod | TypeAccess | -| exprs.kt:127:5:127:23 | b7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:127:9:127:10 | b7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:127:14:127:15 | i1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:127:14:127:23 | ... !is ... | exprs.kt:4:1:142:1 | topLevelMethod | NotInstanceOfExpr | | exprs.kt:127:14:127:23 | int | exprs.kt:4:1:142:1 | topLevelMethod | TypeAccess | -| exprs.kt:128:5:128:26 | b8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:128:9:128:10 | b8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:128:14:128:15 | b7 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:128:14:128:26 | (...)... | exprs.kt:4:1:142:1 | topLevelMethod | CastExpr | | exprs.kt:128:14:128:26 | boolean | exprs.kt:4:1:142:1 | topLevelMethod | TypeAccess | -| exprs.kt:129:5:129:35 | str1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:129:9:129:12 | str1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:129:25:129:34 | "string lit" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | -| exprs.kt:130:5:130:36 | str2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:130:9:130:12 | str2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:130:26:130:35 | "string lit" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | -| exprs.kt:131:5:131:28 | str3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:131:9:131:12 | str3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:131:25:131:28 | null | exprs.kt:4:1:142:1 | topLevelMethod | NullLiteral | -| exprs.kt:132:5:132:48 | str4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:132:9:132:12 | str4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:132:24:132:48 | "..." | exprs.kt:4:1:142:1 | topLevelMethod | StringTemplateExpr | | exprs.kt:132:25:132:28 | "foo " | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | | exprs.kt:132:30:132:33 | str1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:132:34:132:38 | " bar " | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | | exprs.kt:132:40:132:43 | str2 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:132:44:132:47 | " baz" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | -| exprs.kt:133:5:133:66 | str5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:133:9:133:12 | str5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:133:24:133:66 | "..." | exprs.kt:4:1:142:1 | topLevelMethod | StringTemplateExpr | | exprs.kt:133:25:133:28 | "foo " | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | | exprs.kt:133:31:133:34 | str1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | @@ -1377,11 +1377,11 @@ | exprs.kt:133:50:133:60 | stringPlus(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:133:57:133:60 | str1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:133:62:133:65 | " baz" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | -| exprs.kt:134:5:134:26 | str6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:134:9:134:12 | str6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:134:16:134:19 | str1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:134:16:134:26 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:134:23:134:26 | str2 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:136:5:136:21 | variable | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:136:9:136:16 | variable | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:136:20:136:21 | 10 | exprs.kt:4:1:142:1 | topLevelMethod | IntegerLiteral | | exprs.kt:137:12:137:19 | variable | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:137:12:137:23 | ... > ... | exprs.kt:4:1:142:1 | topLevelMethod | GTExpr | @@ -1400,7 +1400,7 @@ | exprs.kt:141:12:141:20 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:141:18:141:20 | 456 | exprs.kt:4:1:142:1 | topLevelMethod | IntegerLiteral | | exprs.kt:144:1:146:1 | Unit | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:145:5:145:23 | d | exprs.kt:144:1:146:1 | getClass | LocalVariableDeclExpr | +| exprs.kt:145:9:145:9 | d | exprs.kt:144:1:146:1 | getClass | LocalVariableDeclExpr | | exprs.kt:145:13:145:16 | true | exprs.kt:144:1:146:1 | getClass | BooleanLiteral | | exprs.kt:145:13:145:23 | ::class | exprs.kt:144:1:146:1 | getClass | ClassExpr | | exprs.kt:148:9:148:18 | ...=... | exprs.kt:148:1:150:1 | C | KtInitializerAssignExpr | @@ -1422,11 +1422,11 @@ | exprs.kt:157:8:157:8 | x | exprs.kt:156:1:163:1 | typeTests | VarAccess | | exprs.kt:157:8:157:21 | ...instanceof... | exprs.kt:156:1:163:1 | typeTests | InstanceOfExpr | | exprs.kt:157:8:157:21 | Subclass1 | exprs.kt:156:1:163:1 | typeTests | TypeAccess | -| exprs.kt:158:9:158:29 | x1 | exprs.kt:156:1:163:1 | typeTests | LocalVariableDeclExpr | +| exprs.kt:158:13:158:14 | x1 | exprs.kt:156:1:163:1 | typeTests | LocalVariableDeclExpr | | exprs.kt:158:29:158:29 | | exprs.kt:156:1:163:1 | typeTests | ImplicitCastExpr | | exprs.kt:158:29:158:29 | Subclass1 | exprs.kt:156:1:163:1 | typeTests | TypeAccess | | exprs.kt:158:29:158:29 | x | exprs.kt:156:1:163:1 | typeTests | VarAccess | -| exprs.kt:160:5:160:60 | y1 | exprs.kt:156:1:163:1 | typeTests | LocalVariableDeclExpr | +| exprs.kt:160:9:160:10 | y1 | exprs.kt:156:1:163:1 | typeTests | LocalVariableDeclExpr | | exprs.kt:160:25:160:60 | true | exprs.kt:156:1:163:1 | typeTests | BooleanLiteral | | exprs.kt:160:25:160:60 | when ... | exprs.kt:156:1:163:1 | typeTests | WhenExpr | | exprs.kt:160:29:160:29 | x | exprs.kt:156:1:163:1 | typeTests | VarAccess | @@ -1437,7 +1437,7 @@ | exprs.kt:160:45:160:49 | Subclass1 | exprs.kt:156:1:163:1 | typeTests | TypeAccess | | exprs.kt:160:47:160:47 | x | exprs.kt:156:1:163:1 | typeTests | VarAccess | | exprs.kt:160:58:160:58 | y | exprs.kt:156:1:163:1 | typeTests | VarAccess | -| exprs.kt:161:5:161:13 | q | exprs.kt:156:1:163:1 | typeTests | LocalVariableDeclExpr | +| exprs.kt:161:9:161:9 | q | exprs.kt:156:1:163:1 | typeTests | LocalVariableDeclExpr | | exprs.kt:161:13:161:13 | 1 | exprs.kt:156:1:163:1 | typeTests | IntegerLiteral | | exprs.kt:162:5:162:48 | true | exprs.kt:156:1:163:1 | typeTests | BooleanLiteral | | exprs.kt:162:5:162:48 | when ... | exprs.kt:156:1:163:1 | typeTests | WhenExpr | @@ -1452,18 +1452,18 @@ | exprs.kt:162:46:162:46 | 3 | exprs.kt:156:1:163:1 | typeTests | IntegerLiteral | | exprs.kt:165:1:172:1 | Unit | file://:0:0:0:0 | | TypeAccess | | exprs.kt:165:9:165:18 | Polygon | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:166:5:166:25 | r | exprs.kt:165:1:172:1 | foo | LocalVariableDeclExpr | +| exprs.kt:166:9:166:9 | r | exprs.kt:165:1:172:1 | foo | LocalVariableDeclExpr | | exprs.kt:166:13:166:13 | p | exprs.kt:165:1:172:1 | foo | VarAccess | | exprs.kt:166:13:166:25 | getBounds(...) | exprs.kt:165:1:172:1 | foo | MethodAccess | | exprs.kt:167:5:171:5 | when ... | exprs.kt:165:1:172:1 | foo | WhenExpr | | exprs.kt:167:8:167:8 | r | exprs.kt:165:1:172:1 | foo | VarAccess | | exprs.kt:167:8:167:16 | ... (value not-equals) ... | exprs.kt:165:1:172:1 | foo | ValueNEExpr | | exprs.kt:167:13:167:16 | null | exprs.kt:165:1:172:1 | foo | NullLiteral | -| exprs.kt:168:9:168:29 | r2 | exprs.kt:165:1:172:1 | foo | LocalVariableDeclExpr | +| exprs.kt:168:13:168:14 | r2 | exprs.kt:165:1:172:1 | foo | LocalVariableDeclExpr | | exprs.kt:168:29:168:29 | | exprs.kt:165:1:172:1 | foo | ImplicitNotNullExpr | | exprs.kt:168:29:168:29 | Rectangle | exprs.kt:165:1:172:1 | foo | TypeAccess | | exprs.kt:168:29:168:29 | r | exprs.kt:165:1:172:1 | foo | VarAccess | -| exprs.kt:169:9:169:30 | height | exprs.kt:165:1:172:1 | foo | LocalVariableDeclExpr | +| exprs.kt:169:13:169:18 | height | exprs.kt:165:1:172:1 | foo | LocalVariableDeclExpr | | exprs.kt:169:22:169:23 | r2 | exprs.kt:165:1:172:1 | foo | VarAccess | | exprs.kt:169:25:169:30 | r2.height | exprs.kt:165:1:172:1 | foo | VarAccess | | exprs.kt:170:9:170:10 | r2 | exprs.kt:165:1:172:1 | foo | VarAccess | @@ -1534,10 +1534,10 @@ | exprs.kt:181:5:181:18 | new Color(...) | exprs.kt:0:0:0:0 | | ClassInstanceExpr | | exprs.kt:181:10:181:17 | 255 | exprs.kt:0:0:0:0 | | IntegerLiteral | | exprs.kt:184:1:187:1 | Unit | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:185:5:185:31 | south | exprs.kt:184:1:187:1 | enums | LocalVariableDeclExpr | +| exprs.kt:185:9:185:13 | south | exprs.kt:184:1:187:1 | enums | LocalVariableDeclExpr | | exprs.kt:185:27:185:31 | Direction | exprs.kt:184:1:187:1 | enums | TypeAccess | | exprs.kt:185:27:185:31 | Direction.SOUTH | exprs.kt:184:1:187:1 | enums | VarAccess | -| exprs.kt:186:5:186:27 | green | exprs.kt:184:1:187:1 | enums | LocalVariableDeclExpr | +| exprs.kt:186:9:186:13 | green | exprs.kt:184:1:187:1 | enums | LocalVariableDeclExpr | | exprs.kt:186:23:186:27 | Color | exprs.kt:184:1:187:1 | enums | TypeAccess | | exprs.kt:186:23:186:27 | Color.GREEN | exprs.kt:184:1:187:1 | enums | VarAccess | | exprs.kt:192:5:192:14 | ...=... | exprs.kt:191:1:199:1 | Class1 | KtInitializerAssignExpr | @@ -1548,7 +1548,7 @@ | exprs.kt:192:5:192:14 | this.a1 | exprs.kt:192:5:192:14 | getA1 | VarAccess | | exprs.kt:192:14:192:14 | 1 | exprs.kt:191:1:199:1 | Class1 | IntegerLiteral | | exprs.kt:193:13:198:5 | Object | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:194:9:194:18 | a2 | exprs.kt:193:13:198:5 | getObject | LocalVariableDeclExpr | +| exprs.kt:194:13:194:14 | a2 | exprs.kt:193:13:198:5 | getObject | LocalVariableDeclExpr | | exprs.kt:194:18:194:18 | 2 | exprs.kt:193:13:198:5 | getObject | IntegerLiteral | | exprs.kt:195:16:197:9 | | exprs.kt:193:13:198:5 | getObject | StmtExpr | | exprs.kt:195:16:197:9 | Interface1 | exprs.kt:193:13:198:5 | getObject | TypeAccess | @@ -1566,47 +1566,47 @@ | exprs.kt:196:36:196:37 | a2 | exprs.kt:195:16:197:9 | | VarAccess | | exprs.kt:201:1:203:1 | Unit | file://:0:0:0:0 | | TypeAccess | | exprs.kt:201:22:201:28 | Object | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:202:5:202:20 | y | exprs.kt:201:1:203:1 | notNullAssertion | LocalVariableDeclExpr | +| exprs.kt:202:9:202:9 | y | exprs.kt:201:1:203:1 | notNullAssertion | LocalVariableDeclExpr | | exprs.kt:202:18:202:18 | x | exprs.kt:201:1:203:1 | notNullAssertion | VarAccess | | exprs.kt:202:19:202:20 | ...!! | exprs.kt:201:1:203:1 | notNullAssertion | NotNullExpr | | exprs.kt:206:5:217:5 | Unit | file://:0:0:0:0 | | TypeAccess | | exprs.kt:206:11:206:18 | Object | file://:0:0:0:0 | | TypeAccess | | exprs.kt:206:21:206:30 | String | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:208:9:208:29 | a | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:208:13:208:13 | a | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:208:17:208:18 | aa | exprs.kt:206:5:217:5 | x | VarAccess | | exprs.kt:208:17:208:29 | String | exprs.kt:206:5:217:5 | x | TypeAccess | | exprs.kt:208:17:208:29 | valueOf(...) | exprs.kt:206:5:217:5 | x | MethodAccess | -| exprs.kt:209:9:209:27 | b0 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:209:13:209:14 | b0 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:209:19:209:19 | s | exprs.kt:206:5:217:5 | x | VarAccess | | exprs.kt:209:19:209:27 | Intrinsics | exprs.kt:206:5:217:5 | x | TypeAccess | | exprs.kt:209:19:209:27 | stringPlus(...) | exprs.kt:206:5:217:5 | x | MethodAccess | | exprs.kt:209:26:209:26 | 5 | exprs.kt:206:5:217:5 | x | IntegerLiteral | -| exprs.kt:210:9:210:23 | b1 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:210:13:210:14 | b1 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:210:19:210:19 | s | exprs.kt:206:5:217:5 | x | VarAccess | | exprs.kt:210:19:210:23 | Intrinsics | exprs.kt:206:5:217:5 | x | TypeAccess | | exprs.kt:210:19:210:23 | stringPlus(...) | exprs.kt:206:5:217:5 | x | MethodAccess | | exprs.kt:210:23:210:23 | 5 | exprs.kt:206:5:217:5 | x | IntegerLiteral | -| exprs.kt:211:9:211:29 | b2 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:211:13:211:14 | b2 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:211:19:211:19 | s | exprs.kt:206:5:217:5 | x | VarAccess | | exprs.kt:211:20:211:21 | ...!! | exprs.kt:206:5:217:5 | x | NotNullExpr | | exprs.kt:211:20:211:29 | ... + ... | exprs.kt:206:5:217:5 | x | AddExpr | | exprs.kt:211:28:211:28 | 5 | exprs.kt:206:5:217:5 | x | IntegerLiteral | -| exprs.kt:212:9:212:25 | b3 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:212:13:212:14 | b3 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:212:19:212:19 | s | exprs.kt:206:5:217:5 | x | VarAccess | | exprs.kt:212:19:212:25 | ... + ... | exprs.kt:206:5:217:5 | x | AddExpr | | exprs.kt:212:20:212:21 | ...!! | exprs.kt:206:5:217:5 | x | NotNullExpr | | exprs.kt:212:25:212:25 | 5 | exprs.kt:206:5:217:5 | x | IntegerLiteral | -| exprs.kt:213:9:213:36 | c0 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:213:13:213:14 | c0 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:213:18:213:36 | Color | exprs.kt:206:5:217:5 | x | TypeAccess | | exprs.kt:213:18:213:36 | values(...) | exprs.kt:206:5:217:5 | x | MethodAccess | -| exprs.kt:214:9:214:31 | c1 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:214:13:214:14 | c1 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:214:24:214:31 | Color | exprs.kt:206:5:217:5 | x | TypeAccess | | exprs.kt:214:24:214:31 | values(...) | exprs.kt:206:5:217:5 | x | MethodAccess | -| exprs.kt:215:9:215:44 | d0 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:215:13:215:14 | d0 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:215:18:215:44 | Color | exprs.kt:206:5:217:5 | x | TypeAccess | | exprs.kt:215:18:215:44 | valueOf(...) | exprs.kt:206:5:217:5 | x | MethodAccess | | exprs.kt:215:38:215:42 | "GREEN" | exprs.kt:206:5:217:5 | x | StringLiteral | -| exprs.kt:216:9:216:39 | d1 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:216:13:216:14 | d1 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:216:24:216:39 | Color | exprs.kt:206:5:217:5 | x | TypeAccess | | exprs.kt:216:24:216:39 | valueOf(...) | exprs.kt:206:5:217:5 | x | MethodAccess | | exprs.kt:216:33:216:37 | "GREEN" | exprs.kt:206:5:217:5 | x | StringLiteral | @@ -1614,7 +1614,7 @@ | exprs.kt:221:5:221:10 | StandardKt | exprs.kt:220:1:222:1 | todo | TypeAccess | | exprs.kt:221:5:221:10 | TODO(...) | exprs.kt:220:1:222:1 | todo | MethodAccess | | exprs.kt:225:1:227:1 | Unit | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:226:5:226:29 | x | exprs.kt:225:1:227:1 | fnClassRef | LocalVariableDeclExpr | +| exprs.kt:226:9:226:9 | x | exprs.kt:225:1:227:1 | fnClassRef | LocalVariableDeclExpr | | exprs.kt:226:13:226:29 | SomeClass1 | exprs.kt:225:1:227:1 | fnClassRef | TypeAccess | | exprs.kt:226:13:226:29 | SomeClass1.class | exprs.kt:225:1:227:1 | fnClassRef | TypeLiteral | | exprs.kt:229:1:250:1 | Unit | file://:0:0:0:0 | | TypeAccess | @@ -1622,83 +1622,83 @@ | exprs.kt:229:42:229:64 | Integer | file://:0:0:0:0 | | TypeAccess | | exprs.kt:229:67:229:88 | String | file://:0:0:0:0 | | TypeAccess | | exprs.kt:229:91:229:114 | String | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:230:3:230:47 | b1 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:230:7:230:8 | b1 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:230:12:230:27 | notNullPrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:230:12:230:47 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:230:32:230:47 | notNullPrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:231:3:231:48 | b2 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:231:7:231:8 | b2 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:231:12:231:27 | notNullPrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:231:12:231:48 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:231:32:231:48 | nullablePrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:232:3:232:49 | b3 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:232:7:232:8 | b3 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:232:12:232:28 | nullablePrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:232:12:232:49 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:232:33:232:49 | nullablePrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:233:3:233:43 | b4 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:233:7:233:8 | b4 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:233:12:233:25 | notNullReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:233:12:233:43 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:233:30:233:43 | notNullReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:234:3:234:44 | b5 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:234:7:234:8 | b5 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:234:12:234:25 | notNullReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:234:12:234:44 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:234:30:234:44 | nullableReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:235:3:235:45 | b6 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:235:7:235:8 | b6 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:235:12:235:26 | nullableReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:235:12:235:45 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:235:31:235:45 | nullableReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:236:3:236:47 | b7 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:236:7:236:8 | b7 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:236:12:236:27 | notNullPrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:236:12:236:47 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:236:32:236:47 | notNullPrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:237:3:237:48 | b8 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:237:7:237:8 | b8 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:237:12:237:27 | notNullPrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:237:12:237:48 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:237:32:237:48 | nullablePrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:238:3:238:49 | b9 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:238:7:238:8 | b9 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:238:12:238:28 | nullablePrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:238:12:238:49 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:238:33:238:49 | nullablePrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:239:3:239:44 | b10 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:239:7:239:9 | b10 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:239:13:239:26 | notNullReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:239:13:239:44 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:239:31:239:44 | notNullReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:240:3:240:45 | b11 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:240:7:240:9 | b11 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:240:13:240:26 | notNullReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:240:13:240:45 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:240:31:240:45 | nullableReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:241:3:241:46 | b12 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:241:7:241:9 | b12 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:241:13:241:27 | nullableReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:241:13:241:46 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:241:32:241:46 | nullableReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:242:3:242:36 | b13 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:242:7:242:9 | b13 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:242:13:242:28 | notNullPrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:242:13:242:36 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:242:33:242:36 | null | exprs.kt:229:1:250:1 | equalityTests | NullLiteral | -| exprs.kt:243:3:243:37 | b14 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:243:7:243:9 | b14 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:243:13:243:29 | nullablePrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:243:13:243:37 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:243:34:243:37 | null | exprs.kt:229:1:250:1 | equalityTests | NullLiteral | -| exprs.kt:244:3:244:34 | b15 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:244:7:244:9 | b15 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:244:13:244:26 | notNullReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:244:13:244:34 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:244:31:244:34 | null | exprs.kt:229:1:250:1 | equalityTests | NullLiteral | -| exprs.kt:245:3:245:35 | b16 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:245:7:245:9 | b16 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:245:13:245:27 | nullableReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:245:13:245:35 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:245:32:245:35 | null | exprs.kt:229:1:250:1 | equalityTests | NullLiteral | -| exprs.kt:246:3:246:36 | b17 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:246:7:246:9 | b17 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:246:13:246:28 | notNullPrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:246:13:246:36 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:246:33:246:36 | null | exprs.kt:229:1:250:1 | equalityTests | NullLiteral | -| exprs.kt:247:3:247:37 | b18 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:247:7:247:9 | b18 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:247:13:247:29 | nullablePrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:247:13:247:37 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:247:34:247:37 | null | exprs.kt:229:1:250:1 | equalityTests | NullLiteral | -| exprs.kt:248:3:248:34 | b19 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:248:7:248:9 | b19 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:248:13:248:26 | notNullReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:248:13:248:34 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:248:31:248:34 | null | exprs.kt:229:1:250:1 | equalityTests | NullLiteral | -| exprs.kt:249:3:249:35 | b20 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:249:7:249:9 | b20 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:249:13:249:27 | nullableReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:249:13:249:35 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:249:32:249:35 | null | exprs.kt:229:1:250:1 | equalityTests | NullLiteral | @@ -1715,28 +1715,28 @@ | exprs.kt:256:30:256:39 | double | file://:0:0:0:0 | | TypeAccess | | exprs.kt:257:18:257:26 | float | file://:0:0:0:0 | | TypeAccess | | exprs.kt:257:29:257:37 | float | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:259:3:259:15 | i | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | +| exprs.kt:259:7:259:7 | i | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | | exprs.kt:259:11:259:11 | x | exprs.kt:252:1:265:1 | mulOperators | VarAccess | | exprs.kt:259:11:259:15 | ... * ... | exprs.kt:252:1:265:1 | mulOperators | MulExpr | | exprs.kt:259:15:259:15 | y | exprs.kt:252:1:265:1 | mulOperators | VarAccess | -| exprs.kt:260:3:260:19 | b | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | +| exprs.kt:260:7:260:7 | b | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | | exprs.kt:260:11:260:13 | byx | exprs.kt:252:1:265:1 | mulOperators | VarAccess | | exprs.kt:260:11:260:19 | ... * ... | exprs.kt:252:1:265:1 | mulOperators | MulExpr | | exprs.kt:260:17:260:19 | byy | exprs.kt:252:1:265:1 | mulOperators | VarAccess | -| exprs.kt:261:3:261:17 | l | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | +| exprs.kt:261:7:261:7 | l | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | | exprs.kt:261:11:261:12 | lx | exprs.kt:252:1:265:1 | mulOperators | VarAccess | | exprs.kt:261:11:261:17 | ... * ... | exprs.kt:252:1:265:1 | mulOperators | MulExpr | | exprs.kt:261:16:261:17 | ly | exprs.kt:252:1:265:1 | mulOperators | VarAccess | -| exprs.kt:262:3:262:17 | d | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | +| exprs.kt:262:7:262:7 | d | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | | exprs.kt:262:11:262:12 | dx | exprs.kt:252:1:265:1 | mulOperators | VarAccess | | exprs.kt:262:11:262:17 | ... * ... | exprs.kt:252:1:265:1 | mulOperators | MulExpr | | exprs.kt:262:16:262:17 | dy | exprs.kt:252:1:265:1 | mulOperators | VarAccess | -| exprs.kt:263:3:263:17 | f | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | +| exprs.kt:263:7:263:7 | f | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | | exprs.kt:263:11:263:12 | fx | exprs.kt:252:1:265:1 | mulOperators | VarAccess | | exprs.kt:263:11:263:17 | ... * ... | exprs.kt:252:1:265:1 | mulOperators | MulExpr | | exprs.kt:263:16:263:17 | fy | exprs.kt:252:1:265:1 | mulOperators | VarAccess | | exprs.kt:267:1:276:1 | Unit | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:269:3:269:17 | updated | exprs.kt:267:1:276:1 | inPlaceOperators | LocalVariableDeclExpr | +| exprs.kt:269:7:269:13 | updated | exprs.kt:267:1:276:1 | inPlaceOperators | LocalVariableDeclExpr | | exprs.kt:269:17:269:17 | 0 | exprs.kt:267:1:276:1 | inPlaceOperators | IntegerLiteral | | exprs.kt:270:3:270:9 | updated | exprs.kt:267:1:276:1 | inPlaceOperators | VarAccess | | exprs.kt:270:3:270:14 | ...+=... | exprs.kt:267:1:276:1 | inPlaceOperators | AssignAddExpr | @@ -1789,9 +1789,9 @@ | exprs.kt:289:5:289:6 | | exprs.kt:285:1:346:1 | unaryExprs | ImplicitCoercionToUnitExpr | | exprs.kt:289:5:289:6 | Unit | exprs.kt:285:1:346:1 | unaryExprs | TypeAccess | | exprs.kt:289:6:289:6 | d | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | -| exprs.kt:290:5:290:14 | i0 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | +| exprs.kt:290:9:290:10 | i0 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | | exprs.kt:290:14:290:14 | 1 | exprs.kt:285:1:346:1 | unaryExprs | IntegerLiteral | -| exprs.kt:291:5:291:14 | i1 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | +| exprs.kt:291:9:291:10 | i1 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | | exprs.kt:291:14:291:14 | 1 | exprs.kt:285:1:346:1 | unaryExprs | IntegerLiteral | | exprs.kt:292:5:292:6 | i0 | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | | exprs.kt:292:5:292:6 | i0 | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | @@ -1857,9 +1857,9 @@ | exprs.kt:303:5:303:6 | | exprs.kt:285:1:346:1 | unaryExprs | ImplicitCoercionToUnitExpr | | exprs.kt:303:5:303:6 | Unit | exprs.kt:285:1:346:1 | unaryExprs | TypeAccess | | exprs.kt:303:6:303:6 | b | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | -| exprs.kt:304:5:304:20 | b0 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | +| exprs.kt:304:9:304:10 | b0 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | | exprs.kt:304:20:304:20 | 1 | exprs.kt:285:1:346:1 | unaryExprs | IntegerLiteral | -| exprs.kt:305:5:305:20 | b1 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | +| exprs.kt:305:9:305:10 | b1 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | | exprs.kt:305:20:305:20 | 1 | exprs.kt:285:1:346:1 | unaryExprs | IntegerLiteral | | exprs.kt:306:5:306:6 | b0 | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | | exprs.kt:306:5:306:6 | b0 | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | @@ -1925,9 +1925,9 @@ | exprs.kt:317:5:317:6 | | exprs.kt:285:1:346:1 | unaryExprs | ImplicitCoercionToUnitExpr | | exprs.kt:317:5:317:6 | Unit | exprs.kt:285:1:346:1 | unaryExprs | TypeAccess | | exprs.kt:317:6:317:6 | s | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | -| exprs.kt:318:5:318:21 | s0 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | +| exprs.kt:318:9:318:10 | s0 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | | exprs.kt:318:21:318:21 | 1 | exprs.kt:285:1:346:1 | unaryExprs | IntegerLiteral | -| exprs.kt:319:5:319:21 | s1 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | +| exprs.kt:319:9:319:10 | s1 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | | exprs.kt:319:21:319:21 | 1 | exprs.kt:285:1:346:1 | unaryExprs | IntegerLiteral | | exprs.kt:320:5:320:6 | s0 | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | | exprs.kt:320:5:320:6 | s0 | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | @@ -1993,9 +1993,9 @@ | exprs.kt:331:5:331:6 | | exprs.kt:285:1:346:1 | unaryExprs | ImplicitCoercionToUnitExpr | | exprs.kt:331:5:331:6 | Unit | exprs.kt:285:1:346:1 | unaryExprs | TypeAccess | | exprs.kt:331:6:331:6 | l | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | -| exprs.kt:332:5:332:20 | l0 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | +| exprs.kt:332:9:332:10 | l0 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | | exprs.kt:332:20:332:20 | 1 | exprs.kt:285:1:346:1 | unaryExprs | LongLiteral | -| exprs.kt:333:5:333:20 | l1 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | +| exprs.kt:333:9:333:10 | l1 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | | exprs.kt:333:20:333:20 | 1 | exprs.kt:285:1:346:1 | unaryExprs | LongLiteral | | exprs.kt:334:5:334:6 | l0 | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | | exprs.kt:334:5:334:6 | l0 | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | @@ -3254,7 +3254,7 @@ | funcExprs.kt:77:20:77:55 | Integer | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:77:20:77:55 | String | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:82:9:96:1 | Unit | file://:0:0:0:0 | | TypeAccess | -| funcExprs.kt:83:5:83:51 | l1 | funcExprs.kt:82:9:96:1 | fn | LocalVariableDeclExpr | +| funcExprs.kt:83:9:83:10 | l1 | funcExprs.kt:82:9:96:1 | fn | LocalVariableDeclExpr | | funcExprs.kt:83:31:83:51 | ...->... | funcExprs.kt:82:9:96:1 | fn | LambdaExpr | | funcExprs.kt:83:31:83:51 | Function1 | funcExprs.kt:82:9:96:1 | fn | TypeAccess | | funcExprs.kt:83:31:83:51 | Integer | funcExprs.kt:82:9:96:1 | fn | TypeAccess | @@ -3268,7 +3268,7 @@ | funcExprs.kt:84:8:84:16 | | funcExprs.kt:82:9:96:1 | fn | ImplicitCoercionToUnitExpr | | funcExprs.kt:84:8:84:16 | Unit | funcExprs.kt:82:9:96:1 | fn | TypeAccess | | funcExprs.kt:84:15:84:15 | 5 | funcExprs.kt:82:9:96:1 | fn | IntegerLiteral | -| funcExprs.kt:86:5:86:59 | l2 | funcExprs.kt:82:9:96:1 | fn | LocalVariableDeclExpr | +| funcExprs.kt:86:9:86:10 | l2 | funcExprs.kt:82:9:96:1 | fn | LocalVariableDeclExpr | | funcExprs.kt:86:39:86:59 | ...->... | funcExprs.kt:82:9:96:1 | fn | LambdaExpr | | funcExprs.kt:86:39:86:59 | Function1 | funcExprs.kt:82:9:96:1 | fn | TypeAccess | | funcExprs.kt:86:39:86:59 | Integer | funcExprs.kt:82:9:96:1 | fn | TypeAccess | @@ -3282,7 +3282,7 @@ | funcExprs.kt:87:8:87:16 | | funcExprs.kt:82:9:96:1 | fn | ImplicitCoercionToUnitExpr | | funcExprs.kt:87:8:87:16 | Unit | funcExprs.kt:82:9:96:1 | fn | TypeAccess | | funcExprs.kt:87:15:87:15 | 5 | funcExprs.kt:82:9:96:1 | fn | IntegerLiteral | -| funcExprs.kt:89:5:90:69 | l3 | funcExprs.kt:82:9:96:1 | fn | LocalVariableDeclExpr | +| funcExprs.kt:89:9:89:10 | l3 | funcExprs.kt:82:9:96:1 | fn | LocalVariableDeclExpr | | funcExprs.kt:90:15:90:69 | 0 | funcExprs.kt:90:15:90:69 | invoke | IntegerLiteral | | funcExprs.kt:90:15:90:69 | 1 | funcExprs.kt:90:15:90:69 | invoke | IntegerLiteral | | funcExprs.kt:90:15:90:69 | 2 | funcExprs.kt:90:15:90:69 | invoke | IntegerLiteral | @@ -3459,7 +3459,7 @@ | funcExprs.kt:91:55:91:55 | 1 | funcExprs.kt:82:9:96:1 | fn | IntegerLiteral | | funcExprs.kt:91:57:91:57 | 2 | funcExprs.kt:82:9:96:1 | fn | IntegerLiteral | | funcExprs.kt:91:59:91:59 | 3 | funcExprs.kt:82:9:96:1 | fn | IntegerLiteral | -| funcExprs.kt:93:5:94:67 | l4 | funcExprs.kt:82:9:96:1 | fn | LocalVariableDeclExpr | +| funcExprs.kt:93:9:93:10 | l4 | funcExprs.kt:82:9:96:1 | fn | LocalVariableDeclExpr | | funcExprs.kt:94:15:94:67 | ...->... | funcExprs.kt:82:9:96:1 | fn | LambdaExpr | | funcExprs.kt:94:15:94:67 | Function22 | funcExprs.kt:82:9:96:1 | fn | TypeAccess | | funcExprs.kt:94:15:94:67 | Integer | funcExprs.kt:82:9:96:1 | fn | TypeAccess | @@ -3540,7 +3540,7 @@ | kFunctionInvoke.kt:7:1:10:1 | Unit | file://:0:0:0:0 | | TypeAccess | | kFunctionInvoke.kt:7:12:7:15 | A | file://:0:0:0:0 | | TypeAccess | | kFunctionInvoke.kt:7:18:7:26 | String | file://:0:0:0:0 | | TypeAccess | -| kFunctionInvoke.kt:8:5:8:47 | toCall | kFunctionInvoke.kt:7:1:10:1 | useRef | LocalVariableDeclExpr | +| kFunctionInvoke.kt:8:9:8:14 | toCall | kFunctionInvoke.kt:7:1:10:1 | useRef | LocalVariableDeclExpr | | kFunctionInvoke.kt:8:44:8:44 | a | kFunctionInvoke.kt:7:1:10:1 | useRef | VarAccess | | kFunctionInvoke.kt:8:44:8:47 | 1 | kFunctionInvoke.kt:8:44:8:47 | | IntegerLiteral | | kFunctionInvoke.kt:8:44:8:47 | ...::... | kFunctionInvoke.kt:7:1:10:1 | useRef | MemberRefExpr | @@ -3560,7 +3560,7 @@ | kFunctionInvoke.kt:9:5:9:13 | invoke(...) | kFunctionInvoke.kt:7:1:10:1 | useRef | MethodAccess | | kFunctionInvoke.kt:9:12:9:12 | s | kFunctionInvoke.kt:7:1:10:1 | useRef | VarAccess | | localFunctionCalls.kt:3:1:12:1 | Unit | file://:0:0:0:0 | | TypeAccess | -| localFunctionCalls.kt:4:5:4:13 | x | localFunctionCalls.kt:3:1:12:1 | x | LocalVariableDeclExpr | +| localFunctionCalls.kt:4:9:4:9 | x | localFunctionCalls.kt:3:1:12:1 | x | LocalVariableDeclExpr | | localFunctionCalls.kt:4:13:4:13 | 5 | localFunctionCalls.kt:3:1:12:1 | x | IntegerLiteral | | localFunctionCalls.kt:5:5:5:29 | int | file://:0:0:0:0 | | TypeAccess | | localFunctionCalls.kt:5:15:5:20 | int | file://:0:0:0:0 | | TypeAccess | @@ -3607,7 +3607,7 @@ | localFunctionCalls.kt:11:18:11:19 | 42 | localFunctionCalls.kt:3:1:12:1 | x | IntegerLiteral | | samConversion.kt:1:1:14:1 | Unit | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:1:10:1:19 | boolean | file://:0:0:0:0 | | TypeAccess | -| samConversion.kt:2:5:2:45 | isEven | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | +| samConversion.kt:2:9:2:14 | isEven | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | | samConversion.kt:2:18:2:45 | (...)... | samConversion.kt:1:1:14:1 | main | CastExpr | | samConversion.kt:2:18:2:45 | ...=... | samConversion.kt:2:18:2:45 | | AssignExpr | | samConversion.kt:2:18:2:45 | | samConversion.kt:2:18:2:45 | | VarAccess | @@ -3635,7 +3635,7 @@ | samConversion.kt:2:33:2:43 | ... (value equals) ... | samConversion.kt:2:31:2:45 | invoke | ValueEQExpr | | samConversion.kt:2:38:2:38 | 2 | samConversion.kt:2:31:2:45 | invoke | IntegerLiteral | | samConversion.kt:2:43:2:43 | 0 | samConversion.kt:2:31:2:45 | invoke | IntegerLiteral | -| samConversion.kt:4:5:4:42 | i0 | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | +| samConversion.kt:4:9:4:10 | i0 | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | | samConversion.kt:4:14:4:42 | (...)... | samConversion.kt:1:1:14:1 | main | CastExpr | | samConversion.kt:4:14:4:42 | ...=... | samConversion.kt:4:14:4:42 | | AssignExpr | | samConversion.kt:4:14:4:42 | | samConversion.kt:4:14:4:42 | | VarAccess | @@ -3664,7 +3664,7 @@ | samConversion.kt:4:29:4:29 | int | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:4:32:4:32 | int | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:4:37:4:40 | INSTANCE | samConversion.kt:4:27:4:42 | invoke | VarAccess | -| samConversion.kt:5:5:5:32 | i1 | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | +| samConversion.kt:5:9:5:10 | i1 | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | | samConversion.kt:5:14:5:32 | (...)... | samConversion.kt:1:1:14:1 | main | CastExpr | | samConversion.kt:5:14:5:32 | ...=... | samConversion.kt:5:14:5:32 | | AssignExpr | | samConversion.kt:5:14:5:32 | | samConversion.kt:5:14:5:32 | | VarAccess | @@ -3694,7 +3694,7 @@ | samConversion.kt:5:27:5:31 | a0 | samConversion.kt:5:27:5:31 | invoke | VarAccess | | samConversion.kt:5:27:5:31 | a1 | samConversion.kt:5:27:5:31 | invoke | VarAccess | | samConversion.kt:5:27:5:31 | fn2(...) | samConversion.kt:5:27:5:31 | invoke | MethodAccess | -| samConversion.kt:7:5:7:46 | i | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | +| samConversion.kt:7:9:7:9 | i | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | | samConversion.kt:7:13:7:46 | (...)... | samConversion.kt:1:1:14:1 | main | CastExpr | | samConversion.kt:7:13:7:46 | ...=... | samConversion.kt:7:13:7:46 | | AssignExpr | | samConversion.kt:7:13:7:46 | | samConversion.kt:7:13:7:46 | | VarAccess | @@ -3725,7 +3725,7 @@ | samConversion.kt:7:36:7:39 | this | samConversion.kt:7:29:7:46 | invoke | ExtensionReceiverAccess | | samConversion.kt:7:36:7:45 | ... (value equals) ... | samConversion.kt:7:29:7:46 | invoke | ValueEQExpr | | samConversion.kt:7:44:7:45 | "" | samConversion.kt:7:29:7:46 | invoke | StringLiteral | -| samConversion.kt:9:5:13:6 | x | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | +| samConversion.kt:9:9:9:9 | x | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | | samConversion.kt:9:13:13:6 | (...)... | samConversion.kt:1:1:14:1 | main | CastExpr | | samConversion.kt:9:13:13:6 | ...=... | samConversion.kt:9:13:13:6 | | AssignExpr | | samConversion.kt:9:13:13:6 | | samConversion.kt:9:13:13:6 | | VarAccess | @@ -3829,7 +3829,7 @@ | samConversion.kt:38:49:38:52 | true | samConversion.kt:36:1:38:52 | ff | BooleanLiteral | | samConversion.kt:40:1:47:1 | Unit | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:40:8:40:19 | boolean | file://:0:0:0:0 | | TypeAccess | -| samConversion.kt:41:5:41:16 | a | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr | +| samConversion.kt:41:9:41:9 | a | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr | | samConversion.kt:41:13:41:16 | 0 | samConversion.kt:41:13:41:16 | invoke | IntegerLiteral | | samConversion.kt:41:13:41:16 | 1 | samConversion.kt:41:13:41:16 | invoke | IntegerLiteral | | samConversion.kt:41:13:41:16 | 2 | samConversion.kt:41:13:41:16 | invoke | IntegerLiteral | @@ -3951,7 +3951,7 @@ | samConversion.kt:41:13:41:16 | int | samConversion.kt:41:13:41:16 | invoke | TypeAccess | | samConversion.kt:41:13:41:16 | int | samConversion.kt:41:13:41:16 | invoke | TypeAccess | | samConversion.kt:41:13:41:16 | int | samConversion.kt:41:13:41:16 | invoke | TypeAccess | -| samConversion.kt:42:5:42:32 | b | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr | +| samConversion.kt:42:9:42:9 | b | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr | | samConversion.kt:42:13:42:32 | 23 | samConversion.kt:42:13:42:32 | accept | IntegerLiteral | | samConversion.kt:42:13:42:32 | (...)... | samConversion.kt:40:1:47:1 | fn | CastExpr | | samConversion.kt:42:13:42:32 | ...=... | samConversion.kt:42:13:42:32 | | AssignExpr | @@ -4016,7 +4016,7 @@ | samConversion.kt:42:13:42:32 | this. | samConversion.kt:42:13:42:32 | | VarAccess | | samConversion.kt:42:13:42:32 | {...} | samConversion.kt:42:13:42:32 | accept | ArrayInit | | samConversion.kt:42:31:42:31 | a | samConversion.kt:40:1:47:1 | fn | VarAccess | -| samConversion.kt:43:5:45:68 | c | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr | +| samConversion.kt:43:9:43:9 | c | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr | | samConversion.kt:43:13:45:68 | 23 | samConversion.kt:43:13:45:68 | accept | IntegerLiteral | | samConversion.kt:43:13:45:68 | (...)... | samConversion.kt:40:1:47:1 | fn | CastExpr | | samConversion.kt:43:13:45:68 | ...=... | samConversion.kt:43:13:45:68 | | AssignExpr | @@ -4225,7 +4225,7 @@ | samConversion.kt:45:42:45:49 | int | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:45:52:45:59 | int | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:45:64:45:67 | true | samConversion.kt:43:31:45:68 | invoke | BooleanLiteral | -| samConversion.kt:46:5:46:44 | d | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr | +| samConversion.kt:46:9:46:9 | d | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr | | samConversion.kt:46:13:46:44 | (...)... | samConversion.kt:40:1:47:1 | fn | CastExpr | | samConversion.kt:46:13:46:44 | ...=... | samConversion.kt:46:13:46:44 | | AssignExpr | | samConversion.kt:46:13:46:44 | | samConversion.kt:46:13:46:44 | | VarAccess | @@ -4257,7 +4257,7 @@ | samConversion.kt:54:21:54:26 | int | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:54:29:54:34 | int | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:57:9:60:1 | Unit | file://:0:0:0:0 | | TypeAccess | -| samConversion.kt:58:5:58:45 | i0 | samConversion.kt:57:9:60:1 | test | LocalVariableDeclExpr | +| samConversion.kt:58:9:58:10 | i0 | samConversion.kt:57:9:60:1 | test | LocalVariableDeclExpr | | samConversion.kt:58:14:58:45 | (...)... | samConversion.kt:57:9:60:1 | test | CastExpr | | samConversion.kt:58:14:58:45 | ...=... | samConversion.kt:58:14:58:45 | | AssignExpr | | samConversion.kt:58:14:58:45 | | samConversion.kt:58:14:58:45 | | VarAccess | @@ -4302,7 +4302,7 @@ | samConversion.kt:71:5:71:16 | int | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:74:1:77:1 | Unit | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:74:22:74:42 | PropertyRefsTest | file://:0:0:0:0 | | TypeAccess | -| samConversion.kt:75:5:75:33 | test1 | samConversion.kt:74:1:77:1 | propertyRefsTest | LocalVariableDeclExpr | +| samConversion.kt:75:9:75:13 | test1 | samConversion.kt:74:1:77:1 | propertyRefsTest | LocalVariableDeclExpr | | samConversion.kt:75:17:75:33 | (...)... | samConversion.kt:74:1:77:1 | propertyRefsTest | CastExpr | | samConversion.kt:75:17:75:33 | ...=... | samConversion.kt:75:17:75:33 | | AssignExpr | | samConversion.kt:75:17:75:33 | | samConversion.kt:75:17:75:33 | | VarAccess | @@ -4330,7 +4330,7 @@ | samConversion.kt:75:27:75:32 | this | samConversion.kt:75:27:75:32 | invoke | ThisAccess | | samConversion.kt:75:27:75:32 | this. | samConversion.kt:75:27:75:32 | | VarAccess | | samConversion.kt:75:27:75:32 | this. | samConversion.kt:75:27:75:32 | get | VarAccess | -| samConversion.kt:76:5:76:55 | test2 | samConversion.kt:74:1:77:1 | propertyRefsTest | LocalVariableDeclExpr | +| samConversion.kt:76:9:76:13 | test2 | samConversion.kt:74:1:77:1 | propertyRefsTest | LocalVariableDeclExpr | | samConversion.kt:76:17:76:55 | (...)... | samConversion.kt:74:1:77:1 | propertyRefsTest | CastExpr | | samConversion.kt:76:17:76:55 | ...=... | samConversion.kt:76:17:76:55 | | AssignExpr | | samConversion.kt:76:17:76:55 | | samConversion.kt:76:17:76:55 | | VarAccess | diff --git a/java/ql/test/kotlin/library-tests/methods/exprs.expected b/java/ql/test/kotlin/library-tests/methods/exprs.expected index 6d2221b5bae..99315e33359 100644 --- a/java/ql/test/kotlin/library-tests/methods/exprs.expected +++ b/java/ql/test/kotlin/library-tests/methods/exprs.expected @@ -302,7 +302,7 @@ | methods4.kt:7:5:7:34 | Unit | TypeAccess | | methods4.kt:7:11:7:29 | InsideNestedTest | TypeAccess | | methods5.kt:3:1:11:1 | Unit | TypeAccess | -| methods5.kt:4:3:4:11 | x | LocalVariableDeclExpr | +| methods5.kt:4:7:4:7 | x | LocalVariableDeclExpr | | methods5.kt:4:11:4:11 | 5 | IntegerLiteral | | methods5.kt:5:3:5:27 | int | TypeAccess | | methods5.kt:5:13:5:18 | int | TypeAccess | diff --git a/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected b/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected index cdde306d74f..1a8613b00cc 100644 --- a/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected +++ b/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected @@ -67,4 +67,4 @@ | modifiers.kt:36:22:36:40 | getTest0$private | Method | private | | modifiers.kt:36:22:36:40 | setTest0$private | Method | private | | modifiers.kt:38:5:40:5 | fn | Method | public | -| modifiers.kt:39:9:39:36 | LateInit test1 | LocalVariableDecl | lateinit | +| modifiers.kt:39:22:39:26 | LateInit test1 | LocalVariableDecl | lateinit | diff --git a/java/ql/test/kotlin/library-tests/reflection/reflection.expected b/java/ql/test/kotlin/library-tests/reflection/reflection.expected index e6a864b11a4..873ffe0faef 100644 --- a/java/ql/test/kotlin/library-tests/reflection/reflection.expected +++ b/java/ql/test/kotlin/library-tests/reflection/reflection.expected @@ -1,26 +1,26 @@ variableInitializerType -| reflection.kt:7:9:7:54 | KFunction ref | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:7:49:7:54 | new Function2(...) { ... } | file:///Function2.class:0:0:0:0 | Function2 | true | -| reflection.kt:7:9:7:54 | KFunction ref | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:7:49:7:54 | new Function2(...) { ... } | file:///FunctionReference.class:0:0:0:0 | FunctionReference | true | -| reflection.kt:10:9:10:42 | KProperty1 x0 | file:///KProperty1.class:0:0:0:0 | KProperty1 | reflection.kt:10:38:10:42 | new KProperty1(...) { ... } | file:///KProperty1.class:0:0:0:0 | KProperty1 | true | -| reflection.kt:10:9:10:42 | KProperty1 x0 | file:///KProperty1.class:0:0:0:0 | KProperty1 | reflection.kt:10:38:10:42 | new KProperty1(...) { ... } | file:///PropertyReference.class:0:0:0:0 | PropertyReference | true | -| reflection.kt:13:9:13:53 | Getter x3 | file:///KProperty1$Getter.class:0:0:0:0 | Getter | file:///KProperty1$Getter.class:0:0:0:0 | Getter | file:///Function1.class:0:0:0:0 | Function1 | true | -| reflection.kt:13:9:13:53 | Getter x3 | file:///KProperty1$Getter.class:0:0:0:0 | Getter | file:///KProperty1$Getter.class:0:0:0:0 | Getter | file:///KProperty$Getter.class:0:0:0:0 | Getter | true | -| reflection.kt:14:9:14:44 | KFunction x4 | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:14:38:14:44 | new Function1(...) { ... } | file:///Function1.class:0:0:0:0 | Function1 | true | -| reflection.kt:14:9:14:44 | KFunction x4 | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:14:38:14:44 | new Function1(...) { ... } | file:///FunctionReference.class:0:0:0:0 | FunctionReference | true | -| reflection.kt:15:9:15:41 | KProperty0 x5 | file:///KProperty0.class:0:0:0:0 | KProperty0 | reflection.kt:15:35:15:41 | new KProperty0(...) { ... } | file:///KProperty0.class:0:0:0:0 | KProperty0 | true | -| reflection.kt:15:9:15:41 | KProperty0 x5 | file:///KProperty0.class:0:0:0:0 | KProperty0 | reflection.kt:15:35:15:41 | new KProperty0(...) { ... } | file:///PropertyReference.class:0:0:0:0 | PropertyReference | true | -| reflection.kt:17:9:17:49 | KMutableProperty1 y0 | file:///KMutableProperty1.class:0:0:0:0 | KMutableProperty1 | reflection.kt:17:45:17:49 | new KMutableProperty1(...) { ... } | file:///KMutableProperty1.class:0:0:0:0 | KMutableProperty1 | true | -| reflection.kt:17:9:17:49 | KMutableProperty1 y0 | file:///KMutableProperty1.class:0:0:0:0 | KMutableProperty1 | reflection.kt:17:45:17:49 | new KMutableProperty1(...) { ... } | file:///PropertyReference.class:0:0:0:0 | PropertyReference | true | -| reflection.kt:20:9:20:60 | Setter y3 | file:///KMutableProperty1$Setter.class:0:0:0:0 | Setter | file:///KMutableProperty1$Setter.class:0:0:0:0 | Setter | file:///Function2.class:0:0:0:0 | Function2 | true | -| reflection.kt:20:9:20:60 | Setter y3 | file:///KMutableProperty1$Setter.class:0:0:0:0 | Setter | file:///KMutableProperty1$Setter.class:0:0:0:0 | Setter | file:///KMutableProperty$Setter.class:0:0:0:0 | Setter | true | -| reflection.kt:21:9:21:50 | KFunction y4 | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:21:44:21:50 | new Function2(...) { ... } | file:///Function2.class:0:0:0:0 | Function2 | true | -| reflection.kt:21:9:21:50 | KFunction y4 | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:21:44:21:50 | new Function2(...) { ... } | file:///FunctionReference.class:0:0:0:0 | FunctionReference | true | -| reflection.kt:22:9:22:48 | KMutableProperty0 y5 | file:///KMutableProperty0.class:0:0:0:0 | KMutableProperty0 | reflection.kt:22:42:22:48 | new KMutableProperty0(...) { ... } | file:///KMutableProperty0.class:0:0:0:0 | KMutableProperty0 | true | -| reflection.kt:22:9:22:48 | KMutableProperty0 y5 | file:///KMutableProperty0.class:0:0:0:0 | KMutableProperty0 | reflection.kt:22:42:22:48 | new KMutableProperty0(...) { ... } | file:///PropertyReference.class:0:0:0:0 | PropertyReference | true | -| reflection.kt:24:9:24:91 | KProperty2 prop | file:///KProperty2.class:0:0:0:0 | KProperty2 | file:///KProperty2.class:0:0:0:0 | KProperty2 | file:///Function2.class:0:0:0:0 | Function2 | true | -| reflection.kt:24:9:24:91 | KProperty2 prop | file:///KProperty2.class:0:0:0:0 | KProperty2 | file:///KProperty2.class:0:0:0:0 | KProperty2 | file:///KProperty.class:0:0:0:0 | KProperty | true | -| reflection.kt:116:9:116:44 | KFunction x | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:116:40:116:44 | new Function1(...) { ... } | file:///Function1.class:0:0:0:0 | Function1 | true | -| reflection.kt:116:9:116:44 | KFunction x | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:116:40:116:44 | new Function1(...) { ... } | file:///FunctionReference.class:0:0:0:0 | FunctionReference | true | +| reflection.kt:7:13:7:15 | KFunction ref | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:7:49:7:54 | new Function2(...) { ... } | file:///Function2.class:0:0:0:0 | Function2 | true | +| reflection.kt:7:13:7:15 | KFunction ref | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:7:49:7:54 | new Function2(...) { ... } | file:///FunctionReference.class:0:0:0:0 | FunctionReference | true | +| reflection.kt:10:13:10:14 | KProperty1 x0 | file:///KProperty1.class:0:0:0:0 | KProperty1 | reflection.kt:10:38:10:42 | new KProperty1(...) { ... } | file:///KProperty1.class:0:0:0:0 | KProperty1 | true | +| reflection.kt:10:13:10:14 | KProperty1 x0 | file:///KProperty1.class:0:0:0:0 | KProperty1 | reflection.kt:10:38:10:42 | new KProperty1(...) { ... } | file:///PropertyReference.class:0:0:0:0 | PropertyReference | true | +| reflection.kt:13:13:13:14 | Getter x3 | file:///KProperty1$Getter.class:0:0:0:0 | Getter | file:///KProperty1$Getter.class:0:0:0:0 | Getter | file:///Function1.class:0:0:0:0 | Function1 | true | +| reflection.kt:13:13:13:14 | Getter x3 | file:///KProperty1$Getter.class:0:0:0:0 | Getter | file:///KProperty1$Getter.class:0:0:0:0 | Getter | file:///KProperty$Getter.class:0:0:0:0 | Getter | true | +| reflection.kt:14:13:14:14 | KFunction x4 | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:14:38:14:44 | new Function1(...) { ... } | file:///Function1.class:0:0:0:0 | Function1 | true | +| reflection.kt:14:13:14:14 | KFunction x4 | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:14:38:14:44 | new Function1(...) { ... } | file:///FunctionReference.class:0:0:0:0 | FunctionReference | true | +| reflection.kt:15:13:15:14 | KProperty0 x5 | file:///KProperty0.class:0:0:0:0 | KProperty0 | reflection.kt:15:35:15:41 | new KProperty0(...) { ... } | file:///KProperty0.class:0:0:0:0 | KProperty0 | true | +| reflection.kt:15:13:15:14 | KProperty0 x5 | file:///KProperty0.class:0:0:0:0 | KProperty0 | reflection.kt:15:35:15:41 | new KProperty0(...) { ... } | file:///PropertyReference.class:0:0:0:0 | PropertyReference | true | +| reflection.kt:17:13:17:14 | KMutableProperty1 y0 | file:///KMutableProperty1.class:0:0:0:0 | KMutableProperty1 | reflection.kt:17:45:17:49 | new KMutableProperty1(...) { ... } | file:///KMutableProperty1.class:0:0:0:0 | KMutableProperty1 | true | +| reflection.kt:17:13:17:14 | KMutableProperty1 y0 | file:///KMutableProperty1.class:0:0:0:0 | KMutableProperty1 | reflection.kt:17:45:17:49 | new KMutableProperty1(...) { ... } | file:///PropertyReference.class:0:0:0:0 | PropertyReference | true | +| reflection.kt:20:13:20:14 | Setter y3 | file:///KMutableProperty1$Setter.class:0:0:0:0 | Setter | file:///KMutableProperty1$Setter.class:0:0:0:0 | Setter | file:///Function2.class:0:0:0:0 | Function2 | true | +| reflection.kt:20:13:20:14 | Setter y3 | file:///KMutableProperty1$Setter.class:0:0:0:0 | Setter | file:///KMutableProperty1$Setter.class:0:0:0:0 | Setter | file:///KMutableProperty$Setter.class:0:0:0:0 | Setter | true | +| reflection.kt:21:13:21:14 | KFunction y4 | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:21:44:21:50 | new Function2(...) { ... } | file:///Function2.class:0:0:0:0 | Function2 | true | +| reflection.kt:21:13:21:14 | KFunction y4 | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:21:44:21:50 | new Function2(...) { ... } | file:///FunctionReference.class:0:0:0:0 | FunctionReference | true | +| reflection.kt:22:13:22:14 | KMutableProperty0 y5 | file:///KMutableProperty0.class:0:0:0:0 | KMutableProperty0 | reflection.kt:22:42:22:48 | new KMutableProperty0(...) { ... } | file:///KMutableProperty0.class:0:0:0:0 | KMutableProperty0 | true | +| reflection.kt:22:13:22:14 | KMutableProperty0 y5 | file:///KMutableProperty0.class:0:0:0:0 | KMutableProperty0 | reflection.kt:22:42:22:48 | new KMutableProperty0(...) { ... } | file:///PropertyReference.class:0:0:0:0 | PropertyReference | true | +| reflection.kt:24:13:24:16 | KProperty2 prop | file:///KProperty2.class:0:0:0:0 | KProperty2 | file:///KProperty2.class:0:0:0:0 | KProperty2 | file:///Function2.class:0:0:0:0 | Function2 | true | +| reflection.kt:24:13:24:16 | KProperty2 prop | file:///KProperty2.class:0:0:0:0 | KProperty2 | file:///KProperty2.class:0:0:0:0 | KProperty2 | file:///KProperty.class:0:0:0:0 | KProperty | true | +| reflection.kt:116:13:116:13 | KFunction x | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:116:40:116:44 | new Function1(...) { ... } | file:///Function1.class:0:0:0:0 | Function1 | true | +| reflection.kt:116:13:116:13 | KFunction x | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:116:40:116:44 | new Function1(...) { ... } | file:///FunctionReference.class:0:0:0:0 | FunctionReference | true | invocation | reflection.kt:8:17:8:24 | getName(...) | file:///KCallable.class:0:0:0:0 | getName | | reflection.kt:11:23:11:33 | get(...) | file:///KProperty1.class:0:0:0:0 | get | diff --git a/java/ql/test/kotlin/library-tests/stmts/PrintAst.expected b/java/ql/test/kotlin/library-tests/stmts/PrintAst.expected index 7ab29615bd3..9cb7aac3c0f 100644 --- a/java/ql/test/kotlin/library-tests/stmts/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/stmts/PrintAst.expected @@ -163,12 +163,12 @@ stmts.kt: # 41| 2: [BlockStmt] { ... } # 41| 0: [LocalVariableDeclStmt] var ...; # 41| 1: [LocalVariableDeclExpr] v -# 41| 0: [MethodAccess] component1(...) +# 0| 0: [MethodAccess] component1(...) # 41| -1: [VarAccess] tmp3_loop_parameter # 41| 1: [LocalVariableDeclStmt] var ...; # 41| 1: [LocalVariableDeclExpr] i -# 41| 0: [MethodAccess] component2(...) -# 41| -1: [VarAccess] tmp3_loop_parameter +# 0| 0: [MethodAccess] component2(...) +# 0| -1: [VarAccess] tmp3_loop_parameter # 41| 2: [BlockStmt] { ... } # 42| 0: [ExprStmt] ; # 42| 0: [WhenExpr] when ... diff --git a/java/ql/test/kotlin/library-tests/stmts/exprs.expected b/java/ql/test/kotlin/library-tests/stmts/exprs.expected index 9193248487f..5f652fdb17c 100644 --- a/java/ql/test/kotlin/library-tests/stmts/exprs.expected +++ b/java/ql/test/kotlin/library-tests/stmts/exprs.expected @@ -1,3 +1,6 @@ +| stmts.kt:0:0:0:0 | component1(...) | MethodAccess | +| stmts.kt:0:0:0:0 | component2(...) | MethodAccess | +| stmts.kt:0:0:0:0 | tmp3_loop_parameter | VarAccess | | stmts.kt:2:1:20:1 | int | TypeAccess | | stmts.kt:2:20:2:25 | int | TypeAccess | | stmts.kt:2:28:2:33 | int | TypeAccess | @@ -21,9 +24,9 @@ | stmts.kt:14:13:14:13 | x | VarAccess | | stmts.kt:14:13:14:17 | ... < ... | LTExpr | | stmts.kt:14:17:14:17 | y | VarAccess | -| stmts.kt:15:5:15:13 | z | LocalVariableDeclExpr | +| stmts.kt:15:9:15:9 | z | LocalVariableDeclExpr | | stmts.kt:15:13:15:13 | 3 | IntegerLiteral | -| stmts.kt:17:5:17:58 | q2 | LocalVariableDeclExpr | +| stmts.kt:17:9:17:10 | q2 | LocalVariableDeclExpr | | stmts.kt:17:26:17:58 | true | BooleanLiteral | | stmts.kt:17:26:17:58 | when ... | WhenExpr | | stmts.kt:17:29:17:32 | true | BooleanLiteral | @@ -33,7 +36,7 @@ | stmts.kt:17:52:17:52 | z | VarAccess | | stmts.kt:17:52:17:56 | ...=... | AssignExpr | | stmts.kt:17:56:17:56 | 5 | IntegerLiteral | -| stmts.kt:18:5:18:56 | q3 | LocalVariableDeclExpr | +| stmts.kt:18:9:18:10 | q3 | LocalVariableDeclExpr | | stmts.kt:18:26:18:56 | true | BooleanLiteral | | stmts.kt:18:26:18:56 | when ... | WhenExpr | | stmts.kt:18:29:18:32 | true | BooleanLiteral | @@ -81,13 +84,10 @@ | stmts.kt:38:18:38:18 | y | VarAccess | | stmts.kt:38:18:38:24 | ... > ... | GTExpr | | stmts.kt:38:22:38:24 | 100 | IntegerLiteral | -| stmts.kt:41:11:41:11 | component1(...) | MethodAccess | | stmts.kt:41:11:41:11 | v | LocalVariableDeclExpr | -| stmts.kt:41:13:41:13 | component2(...) | MethodAccess | | stmts.kt:41:13:41:13 | i | LocalVariableDeclExpr | | stmts.kt:41:19:41:36 | tmp3_loop_parameter | LocalVariableDeclExpr | | stmts.kt:41:19:41:36 | tmp3_loop_parameter | VarAccess | -| stmts.kt:41:19:41:36 | tmp3_loop_parameter | VarAccess | | stmts.kt:41:20:41:20 | x | VarAccess | | stmts.kt:41:20:41:23 | rangeTo(...) | MethodAccess | | stmts.kt:41:20:41:36 | CollectionsKt | TypeAccess | diff --git a/java/ql/test/kotlin/library-tests/stmts/stmts.expected b/java/ql/test/kotlin/library-tests/stmts/stmts.expected index c1fae753f23..716bea1649a 100644 --- a/java/ql/test/kotlin/library-tests/stmts/stmts.expected +++ b/java/ql/test/kotlin/library-tests/stmts/stmts.expected @@ -15,17 +15,17 @@ enclosing | stmts.kt:12:5:14:18 | { ... } | stmts.kt:2:41:20:1 | { ... } | | stmts.kt:12:8:14:5 | { ... } | stmts.kt:12:5:14:18 | do ... while (...) | | stmts.kt:13:9:13:16 | return ... | stmts.kt:12:8:14:5 | { ... } | -| stmts.kt:15:5:15:13 | var ...; | stmts.kt:2:41:20:1 | { ... } | -| stmts.kt:17:5:17:58 | var ...; | stmts.kt:2:41:20:1 | { ... } | -| stmts.kt:17:26:17:58 | ... -> ... | stmts.kt:17:5:17:58 | var ...; | -| stmts.kt:17:26:17:58 | ... -> ... | stmts.kt:17:5:17:58 | var ...; | +| stmts.kt:15:9:15:9 | var ...; | stmts.kt:2:41:20:1 | { ... } | +| stmts.kt:17:9:17:10 | var ...; | stmts.kt:2:41:20:1 | { ... } | +| stmts.kt:17:26:17:58 | ... -> ... | stmts.kt:17:9:17:10 | var ...; | +| stmts.kt:17:26:17:58 | ... -> ... | stmts.kt:17:9:17:10 | var ...; | | stmts.kt:17:35:17:43 | { ... } | stmts.kt:17:26:17:58 | ... -> ... | | stmts.kt:17:37:17:37 | ; | stmts.kt:17:35:17:43 | { ... } | | stmts.kt:17:50:17:58 | { ... } | stmts.kt:17:26:17:58 | ... -> ... | | stmts.kt:17:52:17:52 | ; | stmts.kt:17:50:17:58 | { ... } | -| stmts.kt:18:5:18:56 | var ...; | stmts.kt:2:41:20:1 | { ... } | -| stmts.kt:18:26:18:56 | ... -> ... | stmts.kt:18:5:18:56 | var ...; | -| stmts.kt:18:26:18:56 | ... -> ... | stmts.kt:18:5:18:56 | var ...; | +| stmts.kt:18:9:18:10 | var ...; | stmts.kt:2:41:20:1 | { ... } | +| stmts.kt:18:26:18:56 | ... -> ... | stmts.kt:18:9:18:10 | var ...; | +| stmts.kt:18:26:18:56 | ... -> ... | stmts.kt:18:9:18:10 | var ...; | | stmts.kt:18:37:18:37 | ; | stmts.kt:18:26:18:56 | ... -> ... | | stmts.kt:18:52:18:52 | ; | stmts.kt:18:26:18:56 | ... -> ... | | stmts.kt:19:5:19:16 | return ... | stmts.kt:2:41:20:1 | { ... } | @@ -88,15 +88,15 @@ enclosing | stmts.kt:12:5:14:18 | { ... } | BlockStmt | | stmts.kt:12:8:14:5 | { ... } | BlockStmt | | stmts.kt:13:9:13:16 | return ... | ReturnStmt | -| stmts.kt:15:5:15:13 | var ...; | LocalVariableDeclStmt | -| stmts.kt:17:5:17:58 | var ...; | LocalVariableDeclStmt | +| stmts.kt:15:9:15:9 | var ...; | LocalVariableDeclStmt | +| stmts.kt:17:9:17:10 | var ...; | LocalVariableDeclStmt | | stmts.kt:17:26:17:58 | ... -> ... | WhenBranch | | stmts.kt:17:26:17:58 | ... -> ... | WhenBranch | | stmts.kt:17:35:17:43 | { ... } | BlockStmt | | stmts.kt:17:37:17:37 | ; | ExprStmt | | stmts.kt:17:50:17:58 | { ... } | BlockStmt | | stmts.kt:17:52:17:52 | ; | ExprStmt | -| stmts.kt:18:5:18:56 | var ...; | LocalVariableDeclStmt | +| stmts.kt:18:9:18:10 | var ...; | LocalVariableDeclStmt | | stmts.kt:18:26:18:56 | ... -> ... | WhenBranch | | stmts.kt:18:26:18:56 | ... -> ... | WhenBranch | | stmts.kt:18:37:18:37 | ; | ExprStmt | From 32847c125a99d829cec982b446345f186b063adf Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 25 Nov 2022 10:47:48 +0000 Subject: [PATCH 531/796] Accept more test changes due to variable locations changing There is also one non-location change: kotlin.Byte (and likely other primitives) now have real equals and toString overrides, which matches their native source and documentation; before they appeared to have fake overrides. --- .../library-tests/comments/comments.expected | 2 +- .../controlflow/dominance/dominator.expected | 40 +++++++++---------- .../test.expected | 2 + .../kotlin/library-tests/trap/diags.expected | 16 ++++---- .../variables/variables.expected | 12 +++--- .../UnderscoreIdentifier/test.expected | 4 +- 6 files changed, 39 insertions(+), 37 deletions(-) diff --git a/java/ql/test/kotlin/library-tests/comments/comments.expected b/java/ql/test/kotlin/library-tests/comments/comments.expected index f37e8322feb..7bd80ec0ed0 100644 --- a/java/ql/test/kotlin/library-tests/comments/comments.expected +++ b/java/ql/test/kotlin/library-tests/comments/comments.expected @@ -25,7 +25,6 @@ commentOwners | comments.kt:19:5:22:7 | /**\n * Adds a [member] to this group.\n * @return the new size of the group.\n */ | comments.kt:23:5:26:5 | add | | comments.kt:35:5:35:34 | /** Medium is in the middle */ | comments.kt:36:5:36:14 | Medium | | comments.kt:37:5:37:23 | /** This is high */ | comments.kt:38:5:38:11 | High | -| comments.kt:42:5:44:7 | /**\n * A variable.\n */ | comments.kt:45:5:45:13 | int a | | comments.kt:48:1:50:3 | /**\n * A type alias comment\n */ | comments.kt:51:1:51:24 | MyType | | comments.kt:54:5:56:7 | /**\n * An init block comment\n */ | comments.kt:53:1:58:1 | InitBlock | | comments.kt:61:5:63:7 | /**\n * A prop comment\n */ | comments.kt:64:5:68:17 | prop | @@ -40,6 +39,7 @@ commentNoOwners | comments.kt:1:1:1:25 | /** Kdoc with no owner */ | | comments.kt:24:9:24:25 | // A line comment | | comments.kt:28:5:30:6 | /*\n A block comment\n */ | +| comments.kt:42:5:44:7 | /**\n * A variable.\n */ | | comments.kt:95:1:95:163 | // Diagnostic Matches: % Couldn't get owner of KDoc. The comment is extracted without an owner. ...while extracting a file (comments.kt) at %comments.kt:1:1:96:0% | commentSections | comments.kt:1:1:1:25 | /** Kdoc with no owner */ | Kdoc with no owner | diff --git a/java/ql/test/kotlin/library-tests/controlflow/dominance/dominator.expected b/java/ql/test/kotlin/library-tests/controlflow/dominance/dominator.expected index e08a5248672..b76a7777a0d 100644 --- a/java/ql/test/kotlin/library-tests/controlflow/dominance/dominator.expected +++ b/java/ql/test/kotlin/library-tests/controlflow/dominance/dominator.expected @@ -1,18 +1,18 @@ -| Test.kt:2:43:79:2 | { ... } | Test.kt:3:9:3:18 | var ...; | -| Test.kt:3:9:3:18 | var ...; | Test.kt:3:17:3:18 | px | -| Test.kt:3:9:3:18 | x | Test.kt:4:9:4:18 | var ...; | -| Test.kt:3:17:3:18 | px | Test.kt:3:9:3:18 | x | -| Test.kt:4:9:4:18 | var ...; | Test.kt:4:17:4:18 | pw | -| Test.kt:4:9:4:18 | w | Test.kt:5:9:5:18 | var ...; | -| Test.kt:4:17:4:18 | pw | Test.kt:4:9:4:18 | w | -| Test.kt:5:9:5:18 | var ...; | Test.kt:5:17:5:18 | pz | -| Test.kt:5:9:5:18 | z | Test.kt:7:3:7:12 | var ...; | -| Test.kt:5:17:5:18 | pz | Test.kt:5:9:5:18 | z | -| Test.kt:7:3:7:12 | j | Test.kt:8:3:8:18 | var ...; | -| Test.kt:7:3:7:12 | var ...; | Test.kt:7:3:7:12 | j | -| Test.kt:8:3:8:18 | var ...; | Test.kt:8:17:8:18 | 50 | -| Test.kt:8:3:8:18 | y | Test.kt:11:3:16:3 | ; | -| Test.kt:8:17:8:18 | 50 | Test.kt:8:3:8:18 | y | +| Test.kt:2:43:79:2 | { ... } | Test.kt:3:13:3:13 | var ...; | +| Test.kt:3:13:3:13 | var ...; | Test.kt:3:17:3:18 | px | +| Test.kt:3:13:3:13 | x | Test.kt:4:13:4:13 | var ...; | +| Test.kt:3:17:3:18 | px | Test.kt:3:13:3:13 | x | +| Test.kt:4:13:4:13 | var ...; | Test.kt:4:17:4:18 | pw | +| Test.kt:4:13:4:13 | w | Test.kt:5:13:5:13 | var ...; | +| Test.kt:4:17:4:18 | pw | Test.kt:4:13:4:13 | w | +| Test.kt:5:13:5:13 | var ...; | Test.kt:5:17:5:18 | pz | +| Test.kt:5:13:5:13 | z | Test.kt:7:7:7:7 | var ...; | +| Test.kt:5:17:5:18 | pz | Test.kt:5:13:5:13 | z | +| Test.kt:7:7:7:7 | j | Test.kt:8:7:8:7 | var ...; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:7:7:7:7 | j | +| Test.kt:8:7:8:7 | var ...; | Test.kt:8:17:8:18 | 50 | +| Test.kt:8:7:8:7 | y | Test.kt:11:3:16:3 | ; | +| Test.kt:8:17:8:18 | 50 | Test.kt:8:7:8:7 | y | | Test.kt:11:3:16:3 | ... -> ... | Test.kt:11:3:16:3 | true | | Test.kt:11:3:16:3 | ... -> ... | Test.kt:11:7:11:7 | x | | Test.kt:11:3:16:3 | ; | Test.kt:11:3:16:3 | when ... | @@ -111,11 +111,11 @@ | Test.kt:77:3:77:8 | ...=... | Test.kt:78:10:78:10 | w | | Test.kt:77:7:77:8 | 40 | Test.kt:77:3:77:8 | ...=... | | Test.kt:78:10:78:10 | w | Test.kt:78:3:78:10 | return ... | -| Test.kt:81:25:98:2 | { ... } | Test.kt:83:3:83:12 | var ...; | -| Test.kt:83:3:83:12 | b | Test.kt:84:3:84:12 | var ...; | -| Test.kt:83:3:83:12 | var ...; | Test.kt:83:3:83:12 | b | -| Test.kt:84:3:84:12 | c | Test.kt:85:3:85:3 | ; | -| Test.kt:84:3:84:12 | var ...; | Test.kt:84:3:84:12 | c | +| Test.kt:81:25:98:2 | { ... } | Test.kt:83:7:83:7 | var ...; | +| Test.kt:83:7:83:7 | b | Test.kt:84:7:84:7 | var ...; | +| Test.kt:83:7:83:7 | var ...; | Test.kt:83:7:83:7 | b | +| Test.kt:84:7:84:7 | c | Test.kt:85:3:85:3 | ; | +| Test.kt:84:7:84:7 | var ...; | Test.kt:84:7:84:7 | c | | Test.kt:85:3:85:3 | ; | Test.kt:85:7:85:7 | 0 | | Test.kt:85:3:85:7 | ...=... | Test.kt:86:3:96:3 | while (...) | | Test.kt:85:7:85:7 | 0 | Test.kt:85:3:85:7 | ...=... | diff --git a/java/ql/test/kotlin/library-tests/java-lang-number-conversions/test.expected b/java/ql/test/kotlin/library-tests/java-lang-number-conversions/test.expected index 2e674af64ee..52ed7b2ccfe 100644 --- a/java/ql/test/kotlin/library-tests/java-lang-number-conversions/test.expected +++ b/java/ql/test/kotlin/library-tests/java-lang-number-conversions/test.expected @@ -28,6 +28,7 @@ | kotlin.Byte | describeConstable | | kotlin.Byte | div | | kotlin.Byte | doubleValue | +| kotlin.Byte | equals | | kotlin.Byte | floatValue | | kotlin.Byte | inc | | kotlin.Byte | intValue | @@ -39,6 +40,7 @@ | kotlin.Byte | shortValue | | kotlin.Byte | times | | kotlin.Byte | toChar | +| kotlin.Byte | toString | | kotlin.Byte | unaryMinus | | kotlin.Byte | unaryPlus | | kotlin.Number | byteValue | diff --git a/java/ql/test/kotlin/library-tests/trap/diags.expected b/java/ql/test/kotlin/library-tests/trap/diags.expected index 6e145a5e4e0..a4a774de5f9 100644 --- a/java/ql/test/kotlin/library-tests/trap/diags.expected +++ b/java/ql/test/kotlin/library-tests/trap/diags.expected @@ -1,11 +1,11 @@ -| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting '"ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBC"' ...while extracting a expression () at long_string.kt:14:31:14:1048605\n ...while extracting a variable expr (longStringLiteral1) at long_string.kt:14:5:14:1048606\n ...while extracting a variable (longStringLiteral1) at long_string.kt:14:5:14:1048606\n ...while extracting a statement (longStringLiteral1) at long_string.kt:14:5:14:1048606\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting '"ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBC"' ...while extracting a expression () at long_string.kt:14:31:14:1048605\n ...while extracting a variable expr (longStringLiteral1) at long_string.kt:14:9:14:26\n ...while extracting a variable (longStringLiteral1) at long_string.kt:14:9:14:26\n ...while extracting a statement (longStringLiteral1) at long_string.kt:14:9:14:26\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | | file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting '//A03BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:24:0\n | -| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE' ...while extracting a expression () at long_string.kt:16:31:16:1048607\n ...while extracting a variable expr (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a variable (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a statement (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | -| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting '"ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCD"' ...while extracting a expression () at long_string.kt:15:31:15:1048606\n ...while extracting a variable expr (longStringLiteral2) at long_string.kt:15:5:15:1048607\n ...while extracting a variable (longStringLiteral2) at long_string.kt:15:5:15:1048607\n ...while extracting a statement (longStringLiteral2) at long_string.kt:15:5:15:1048607\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE' ...while extracting a expression () at long_string.kt:16:31:16:1048607\n ...while extracting a variable expr (longStringLiteral3) at long_string.kt:16:9:16:26\n ...while extracting a variable (longStringLiteral3) at long_string.kt:16:9:16:26\n ...while extracting a statement (longStringLiteral3) at long_string.kt:16:9:16:26\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting '"ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCD"' ...while extracting a expression () at long_string.kt:15:31:15:1048606\n ...while extracting a variable expr (longStringLiteral2) at long_string.kt:15:9:15:26\n ...while extracting a variable (longStringLiteral2) at long_string.kt:15:9:15:26\n ...while extracting a statement (longStringLiteral2) at long_string.kt:15:9:15:26\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | | file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting '//A04BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:24:0\n | | file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting '//A05"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:24:0\n | -| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'A"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF' ...while extracting a expression () at long_string.kt:18:31:18:2097181\n ...while extracting a variable expr (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a variable (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a statement (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | -| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF' ...while extracting a expression () at long_string.kt:17:31:17:1048608\n ...while extracting a variable expr (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a variable (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a statement (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | -| file://:0:0:0:0 | Truncated string of length 1048579 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048579 | DATE TIME Truncated string of length 1048579\nTruncated string of length 1048579, starting '"ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE"' ...while extracting a expression () at long_string.kt:16:31:16:1048607\n ...while extracting a variable expr (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a variable (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a statement (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | -| file://:0:0:0:0 | Truncated string of length 1048580 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048580 | DATE TIME Truncated string of length 1048580\nTruncated string of length 1048580, starting '"ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF"' ...while extracting a expression () at long_string.kt:17:31:17:1048608\n ...while extracting a variable expr (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a variable (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a statement (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | -| file://:0:0:0:0 | Truncated string of length 2097153 | CodeQL Kotlin extractor | 2 | | Truncated string of length 2097153 | DATE TIME Truncated string of length 2097153\nTruncated string of length 2097153, starting '"A\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"', ending '"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"CDEF"' ...while extracting a expression () at long_string.kt:18:31:18:2097181\n ...while extracting a variable expr (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a variable (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a statement (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'A"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF' ...while extracting a expression () at long_string.kt:18:31:18:2097181\n ...while extracting a variable expr (longStringLiteral5) at long_string.kt:18:9:18:26\n ...while extracting a variable (longStringLiteral5) at long_string.kt:18:9:18:26\n ...while extracting a statement (longStringLiteral5) at long_string.kt:18:9:18:26\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF' ...while extracting a expression () at long_string.kt:17:31:17:1048608\n ...while extracting a variable expr (longStringLiteral4) at long_string.kt:17:9:17:26\n ...while extracting a variable (longStringLiteral4) at long_string.kt:17:9:17:26\n ...while extracting a statement (longStringLiteral4) at long_string.kt:17:9:17:26\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048579 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048579 | DATE TIME Truncated string of length 1048579\nTruncated string of length 1048579, starting '"ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE"' ...while extracting a expression () at long_string.kt:16:31:16:1048607\n ...while extracting a variable expr (longStringLiteral3) at long_string.kt:16:9:16:26\n ...while extracting a variable (longStringLiteral3) at long_string.kt:16:9:16:26\n ...while extracting a statement (longStringLiteral3) at long_string.kt:16:9:16:26\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048580 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048580 | DATE TIME Truncated string of length 1048580\nTruncated string of length 1048580, starting '"ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF"' ...while extracting a expression () at long_string.kt:17:31:17:1048608\n ...while extracting a variable expr (longStringLiteral4) at long_string.kt:17:9:17:26\n ...while extracting a variable (longStringLiteral4) at long_string.kt:17:9:17:26\n ...while extracting a statement (longStringLiteral4) at long_string.kt:17:9:17:26\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 2097153 | CodeQL Kotlin extractor | 2 | | Truncated string of length 2097153 | DATE TIME Truncated string of length 2097153\nTruncated string of length 2097153, starting '"A\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"', ending '"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"CDEF"' ...while extracting a expression () at long_string.kt:18:31:18:2097181\n ...while extracting a variable expr (longStringLiteral5) at long_string.kt:18:9:18:26\n ...while extracting a variable (longStringLiteral5) at long_string.kt:18:9:18:26\n ...while extracting a statement (longStringLiteral5) at long_string.kt:18:9:18:26\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | diff --git a/java/ql/test/kotlin/library-tests/variables/variables.expected b/java/ql/test/kotlin/library-tests/variables/variables.expected index c4aaa4a1620..9b7abda1536 100644 --- a/java/ql/test/kotlin/library-tests/variables/variables.expected +++ b/java/ql/test/kotlin/library-tests/variables/variables.expected @@ -1,7 +1,7 @@ isFinal -| variables.kt:6:9:6:26 | int local1 | final | -| variables.kt:8:9:8:26 | int local2 | non-final | -| variables.kt:10:9:10:26 | int local3 | final | +| variables.kt:6:13:6:18 | int local1 | final | +| variables.kt:8:13:8:18 | int local2 | non-final | +| variables.kt:10:13:10:18 | int local3 | final | compileTimeConstant | variables.kt:3:5:3:21 | prop | | variables.kt:3:5:3:21 | this.prop | @@ -11,9 +11,9 @@ compileTimeConstant #select | variables.kt:3:5:3:21 | prop | int | variables.kt:3:21:3:21 | 1 | | variables.kt:5:20:5:29 | param | int | file://:0:0:0:0 | | -| variables.kt:6:9:6:26 | int local1 | int | variables.kt:6:22:6:26 | ... + ... | -| variables.kt:8:9:8:26 | int local2 | int | variables.kt:8:22:8:26 | ... + ... | -| variables.kt:10:9:10:26 | int local3 | int | variables.kt:10:22:10:26 | param | +| variables.kt:6:13:6:18 | int local1 | int | variables.kt:6:22:6:26 | ... + ... | +| variables.kt:8:13:8:18 | int local2 | int | variables.kt:8:22:8:26 | ... + ... | +| variables.kt:10:13:10:18 | int local3 | int | variables.kt:10:22:10:26 | param | | variables.kt:15:1:15:21 | topLevel | int | variables.kt:15:21:15:21 | 1 | | variables.kt:21:11:21:18 | o | C1 | file://:0:0:0:0 | | | variables.kt:21:11:21:18 | o | C1 | variables.kt:21:11:21:18 | o | diff --git a/java/ql/test/kotlin/query-tests/UnderscoreIdentifier/test.expected b/java/ql/test/kotlin/query-tests/UnderscoreIdentifier/test.expected index dc118062b3d..48fa4a1e4ab 100644 --- a/java/ql/test/kotlin/query-tests/UnderscoreIdentifier/test.expected +++ b/java/ql/test/kotlin/query-tests/UnderscoreIdentifier/test.expected @@ -1,7 +1,7 @@ -| Test.kt:3:9:3:31 | List l | +| Test.kt:3:13:3:13 | List l | | Test.kt:4:28:4:32 | index | | Test.kt:4:35:4:35 | p1 | -| Test.kt:6:9:6:26 | Pair p | +| Test.kt:6:13:6:13 | Pair p | | Test.kt:7:14:7:18 | int first | | Test.kt:7:26:7:26 | Pair tmp0_container | | Test.kt:8:14:8:25 | Exception _ | From 180c3cee44adf4b97392a5183a699ef5b6bb96a2 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 25 Nov 2022 10:54:50 +0000 Subject: [PATCH 532/796] Accept integration test changes caused by variable location changes --- .../kotlin/enhanced-nullability/test.expected | 2 +- .../kotlin/nested_generic_types/test.expected | 44 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/test.expected b/java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/test.expected index 04702df7916..e78d827c621 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/test.expected +++ b/java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/test.expected @@ -2,7 +2,7 @@ exprs | Test.java:5:19:5:25 | Integer | Integer | | Test.java:5:38:5:44 | Integer | Integer | | Test.java:5:58:5:58 | p | Integer | -| user.kt:2:3:2:16 | x | int | +| user.kt:2:7:2:7 | x | int | | user.kt:2:11:2:11 | t | Test | | user.kt:2:11:2:16 | f(...) | Integer | | user.kt:2:13:2:16 | | int | diff --git a/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.expected b/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.expected index 94ec21eca1a..0441e5afe70 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.expected +++ b/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.expected @@ -319,28 +319,28 @@ javaKotlinConstructorAgreement | JavaUser.java:25:62:25:82 | new OuterNotGeneric(...) | KotlinUser.kt:26:28:26:44 | new OuterNotGeneric(...) | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | | JavaUser.java:27:39:27:71 | new TypeParamVisibility(...) | KotlinUser.kt:28:15:28:43 | new TypeParamVisibility(...) | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | javaKotlinLocalTypeAgreement -| JavaUser.java:7:5:7:111 | InnerGeneric a | KotlinUser.kt:9:5:9:63 | InnerGeneric a | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:7:5:7:111 | InnerGeneric a | KotlinUser.kt:10:5:10:65 | InnerGeneric a2 | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:8:5:8:124 | InnerGeneric a2 | KotlinUser.kt:9:5:9:63 | InnerGeneric a | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:8:5:8:124 | InnerGeneric a2 | KotlinUser.kt:10:5:10:65 | InnerGeneric a2 | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:9:5:9:139 | InnerGeneric a3 | KotlinUser.kt:9:5:9:63 | InnerGeneric a | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:9:5:9:139 | InnerGeneric a3 | KotlinUser.kt:10:5:10:65 | InnerGeneric a2 | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:10:5:10:98 | InnerNotGeneric<> b | KotlinUser.kt:11:5:11:49 | InnerNotGeneric<> b | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | -| JavaUser.java:11:5:11:97 | InnerNotGeneric<> b2 | KotlinUser.kt:12:5:12:53 | InnerNotGeneric<> b2 | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | -| JavaUser.java:11:5:11:97 | InnerNotGeneric<> b2 | KotlinUser.kt:25:5:25:69 | InnerNotGeneric<> innerGetterTest | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | -| JavaUser.java:12:5:12:96 | InnerGeneric c | KotlinUser.kt:13:5:13:52 | InnerGeneric c | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:12:5:12:96 | InnerGeneric c | KotlinUser.kt:26:5:26:62 | InnerGeneric innerGetterTest2 | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:13:5:13:112 | InnerStaticGeneric d | KotlinUser.kt:14:5:14:63 | InnerStaticGeneric d | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | InnerStaticGeneric | -| JavaUser.java:14:5:14:249 | InnerManyParams e | KotlinUser.kt:15:5:15:100 | InnerManyParams e | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | -| JavaUser.java:24:5:24:109 | InnerNotGeneric<> innerGetterTest | KotlinUser.kt:12:5:12:53 | InnerNotGeneric<> b2 | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | -| JavaUser.java:24:5:24:109 | InnerNotGeneric<> innerGetterTest | KotlinUser.kt:25:5:25:69 | InnerNotGeneric<> innerGetterTest | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | -| JavaUser.java:25:5:25:102 | InnerGeneric innerGetterTest2 | KotlinUser.kt:13:5:13:52 | InnerGeneric c | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:25:5:25:102 | InnerGeneric innerGetterTest2 | KotlinUser.kt:26:5:26:62 | InnerGeneric innerGetterTest2 | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:27:5:27:72 | TypeParamVisibility tpv | KotlinUser.kt:28:5:28:43 | TypeParamVisibility tpv | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | -| JavaUser.java:28:5:28:111 | VisibleBecauseInner visibleBecauseInner | KotlinUser.kt:29:5:29:58 | VisibleBecauseInner visibleBecauseInner | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | -| JavaUser.java:29:5:29:172 | VisibleBecauseInnerIndirect visibleBecauseInnerIndirect | KotlinUser.kt:30:5:30:74 | VisibleBecauseInnerIndirect visibleBecauseInnerIndirect | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | -| JavaUser.java:30:5:30:115 | NotVisibleBecauseStatic notVisibleBecauseStatic | KotlinUser.kt:31:5:31:66 | NotVisibleBecauseStatic notVisibleBecauseStatic | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic | -| JavaUser.java:31:5:31:180 | NotVisibleBecauseStaticIndirect notVisibleBecauseStaticIndirect | KotlinUser.kt:32:5:32:82 | NotVisibleBecauseStaticIndirect notVisibleBecauseStaticIndirect | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect | +| JavaUser.java:7:5:7:111 | InnerGeneric a | KotlinUser.kt:9:9:9:9 | InnerGeneric a | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:7:5:7:111 | InnerGeneric a | KotlinUser.kt:10:9:10:10 | InnerGeneric a2 | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:8:5:8:124 | InnerGeneric a2 | KotlinUser.kt:9:9:9:9 | InnerGeneric a | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:8:5:8:124 | InnerGeneric a2 | KotlinUser.kt:10:9:10:10 | InnerGeneric a2 | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:9:5:9:139 | InnerGeneric a3 | KotlinUser.kt:9:9:9:9 | InnerGeneric a | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:9:5:9:139 | InnerGeneric a3 | KotlinUser.kt:10:9:10:10 | InnerGeneric a2 | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:10:5:10:98 | InnerNotGeneric<> b | KotlinUser.kt:11:9:11:9 | InnerNotGeneric<> b | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | +| JavaUser.java:11:5:11:97 | InnerNotGeneric<> b2 | KotlinUser.kt:12:9:12:10 | InnerNotGeneric<> b2 | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | +| JavaUser.java:11:5:11:97 | InnerNotGeneric<> b2 | KotlinUser.kt:25:9:25:23 | InnerNotGeneric<> innerGetterTest | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | +| JavaUser.java:12:5:12:96 | InnerGeneric c | KotlinUser.kt:13:9:13:9 | InnerGeneric c | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:12:5:12:96 | InnerGeneric c | KotlinUser.kt:26:9:26:24 | InnerGeneric innerGetterTest2 | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:13:5:13:112 | InnerStaticGeneric d | KotlinUser.kt:14:9:14:9 | InnerStaticGeneric d | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | InnerStaticGeneric | +| JavaUser.java:14:5:14:249 | InnerManyParams e | KotlinUser.kt:15:9:15:9 | InnerManyParams e | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | +| JavaUser.java:24:5:24:109 | InnerNotGeneric<> innerGetterTest | KotlinUser.kt:12:9:12:10 | InnerNotGeneric<> b2 | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | +| JavaUser.java:24:5:24:109 | InnerNotGeneric<> innerGetterTest | KotlinUser.kt:25:9:25:23 | InnerNotGeneric<> innerGetterTest | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | +| JavaUser.java:25:5:25:102 | InnerGeneric innerGetterTest2 | KotlinUser.kt:13:9:13:9 | InnerGeneric c | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:25:5:25:102 | InnerGeneric innerGetterTest2 | KotlinUser.kt:26:9:26:24 | InnerGeneric innerGetterTest2 | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:27:5:27:72 | TypeParamVisibility tpv | KotlinUser.kt:28:9:28:11 | TypeParamVisibility tpv | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| JavaUser.java:28:5:28:111 | VisibleBecauseInner visibleBecauseInner | KotlinUser.kt:29:9:29:27 | VisibleBecauseInner visibleBecauseInner | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | +| JavaUser.java:29:5:29:172 | VisibleBecauseInnerIndirect visibleBecauseInnerIndirect | KotlinUser.kt:30:9:30:35 | VisibleBecauseInnerIndirect visibleBecauseInnerIndirect | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | +| JavaUser.java:30:5:30:115 | NotVisibleBecauseStatic notVisibleBecauseStatic | KotlinUser.kt:31:9:31:31 | NotVisibleBecauseStatic notVisibleBecauseStatic | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic | +| JavaUser.java:31:5:31:180 | NotVisibleBecauseStaticIndirect notVisibleBecauseStaticIndirect | KotlinUser.kt:32:9:32:39 | NotVisibleBecauseStaticIndirect notVisibleBecauseStaticIndirect | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect | #select | JavaUser.java:7:52:7:110 | new InnerGeneric(...) | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | JavaUser.java:7:99:7:104 | String | | JavaUser.java:7:53:7:79 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | JavaUser.java:7:70:7:76 | Integer | From edddaaa838ed72483a7cf775b65adf4b2694bff7 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 25 Nov 2022 13:10:33 +0100 Subject: [PATCH 533/796] Swift: make mapping from swift types to tags explicit This should decouple schema names from swift names, allowing to rename schema names regardless of internal swift compiler names. --- swift/extractor/infra/CheckTypeMapping.cpp | 42 ++ swift/extractor/infra/SwiftDispatcher.h | 6 +- swift/extractor/infra/SwiftTagTraits.h | 379 +++++++++++++++---- swift/extractor/translators/DeclTranslator.h | 6 +- swift/extractor/translators/TranslatorBase.h | 2 +- swift/extractor/trap/TrapTagTraits.h | 13 +- 6 files changed, 357 insertions(+), 91 deletions(-) create mode 100644 swift/extractor/infra/CheckTypeMapping.cpp diff --git a/swift/extractor/infra/CheckTypeMapping.cpp b/swift/extractor/infra/CheckTypeMapping.cpp new file mode 100644 index 00000000000..6ed763ecdcb --- /dev/null +++ b/swift/extractor/infra/CheckTypeMapping.cpp @@ -0,0 +1,42 @@ +// this is a sanity check that the hierarchy in swift is mapped by the mapping in +// SwiftTypesToTagsMap.def to the hierarchy in schema.py +// We rely on that so that the LabelStore will preserve correct typing. +// For a class Derived: Base we could store the label for a Derived* pointer, and then fetch the +// label for the same pointer as Base*. If the mapping did not preserve inheritance, we would end up +// using a trap key of the DB type associated with Derived in a position expecting the incompatible +// DB type associated with Base. + +#include "swift/extractor/infra/SwiftTagTraits.h" + +using namespace codeql; + +#define CHECK(KIND, TYPE, PARENT) \ + static_assert(std::is_same_v, void> || \ + std::is_base_of_v, TrapTagOf>, \ + "Tag of " #PARENT " must be a base of the tag of " #TYPE #KIND); +#define CHECK_CONCRETE(KIND, TYPE, PARENT) \ + CHECK(KIND, TYPE, PARENT) \ + static_assert( \ + std::is_same_v, void> || \ + std::is_base_of_v, ConcreteTrapTagOf>, \ + "Tag of " #TYPE #KIND " must be a base of its concrete tag"); + +#define STMT(CLASS, PARENT) CHECK_CONCRETE(Stmt, CLASS, PARENT) +#define ABSTRACT_STMT(CLASS, PARENT) CHECK(Stmt, CLASS, PARENT) +#include + +#define EXPR(CLASS, PARENT) CHECK_CONCRETE(Expr, CLASS, PARENT) +#define ABSTRACT_EXPR(CLASS, PARENT) CHECK(Expr, CLASS, PARENT) +#include + +#define DECL(CLASS, PARENT) CHECK_CONCRETE(Decl, CLASS, PARENT) +#define ABSTRACT_DECL(CLASS, PARENT) CHECK(Decl, CLASS, PARENT) +#include + +#define PATTERN(CLASS, PARENT) CHECK_CONCRETE(Pattern, CLASS, PARENT) +#define ABSTRACT_PATTERN(CLASS, PARENT) CHECK(Pattern, CLASS, PARENT) +#include + +#define TYPE(CLASS, PARENT) CHECK_CONCRETE(Type, CLASS, PARENT) +#define ABSTRACT_TYPE(CLASS, PARENT) CHECK(Type, CLASS, PARENT) +#include diff --git a/swift/extractor/infra/SwiftDispatcher.h b/swift/extractor/infra/SwiftDispatcher.h index 991511e300c..304d5b183f4 100644 --- a/swift/extractor/infra/SwiftDispatcher.h +++ b/swift/extractor/infra/SwiftDispatcher.h @@ -179,16 +179,16 @@ class SwiftDispatcher { // it actually gets emitted to handle recursive cases such as recursive calls, or recursive type // declarations template >* = nullptr> - TrapLabelOf assignNewLabel(const E& e, Args&&... args) { + TrapLabel> assignNewLabel(const E& e, Args&&... args) { assert(waitingForNewLabel == Store::Handle{e} && "assignNewLabel called on wrong entity"); - auto label = trap.createLabel>(std::forward(args)...); + auto label = trap.createLabel>(std::forward(args)...); store.insert(e, label); waitingForNewLabel = std::monostate{}; return label; } template >* = nullptr> - TrapLabelOf assignNewLabel(const E& e, Args&&... args) { + TrapLabel> assignNewLabel(const E& e, Args&&... args) { return assignNewLabel(&e, std::forward(args)...); } diff --git a/swift/extractor/infra/SwiftTagTraits.h b/swift/extractor/infra/SwiftTagTraits.h index 78b7bcc530e..acfbd20410f 100644 --- a/swift/extractor/infra/SwiftTagTraits.h +++ b/swift/extractor/infra/SwiftTagTraits.h @@ -1,100 +1,319 @@ #pragma once // This file implements the mapping needed by the API defined in the TrapTagTraits.h, so that -// TrapTagOf/TrapLabelOf provide the tags/labels for specific swift entity types. +// TrapTagOf/TrapLabelOf/TrapClassOf provide the tags/labels for specific swift entity types. #include -#include #include "swift/extractor/trap/TrapTagTraits.h" #include "swift/extractor/trap/generated/TrapTags.h" +#include +#include +#include +#include +#include +#include +#include namespace codeql { -// OverloadSetRefExpr is collapsed with its only derived class OverloadedDeclRefExpr -using OverloadSetRefExprTag = OverloadedDeclRefExprTag; - -// We don't really expect to see the following in extraction. Mapping these tags to void effectively -// ignores all elements of that class (with a message). - -// only generated for code editing -using CodeCompletionExprTag = void; -using EditorPlaceholderExprTag = void; -// not present after the Sema phase -using ArrowExprTag = void; -// experimental variadic generics, implemented only in the frontend for now, thus not compilable -using PackExprTag = void; -using PackTypeTag = void; -using ReifyPackExprTag = void; -using PackExpansionTypeTag = void; -using SequenceArchetypeTypeTag = void; -// Placeholder types appear in ambiguous types but are anyway transformed to UnresolvedType -using PlaceholderTypeTag = void; -// SIL types that cannot really appear in the frontend run -using SILBlockStorageTypeTag = void; -using SILBoxTypeTag = void; -using SILFunctionTypeTag = void; -using SILTokenTypeTag = void; -// This is created during type checking and is only used for constraint checking -using TypeVariableTypeTag = void; - -#define MAP_TYPE_TO_TAG(TYPE, TAG) \ +#define MAP(TYPE, TAG) \ template <> \ struct detail::ToTagFunctor { \ using type = TAG; \ - } -#define MAP_TAG(TYPE) MAP_TYPE_TO_TAG(swift::TYPE, TYPE##Tag) -#define MAP_SUBTAG(TYPE, PARENT) \ - MAP_TAG(TYPE); \ - static_assert(std::is_same_v || std::is_base_of_v, \ - #PARENT "Tag must be a base of " #TYPE "Tag"); + }; +#define MAP_CONCRETE(TYPE, TAG) \ + template <> \ + struct detail::ToTagConcreteOverride { \ + using type = TAG; \ + }; -#define OVERRIDE_TAG(TYPE, TAG) \ - template <> \ - struct detail::ToTagOverride { \ - using type = TAG; \ - }; \ - static_assert(std::is_base_of_v, "override is not a subtag"); +// clang-format off +// use indentation to recreate all involved type hierarchies +MAP(std::filesystem::path, DbFileTag) +MAP(swift::StmtCondition, StmtConditionTag) +MAP(swift::StmtConditionElement, ConditionElementTag) +MAP(swift::CaseLabelItem, CaseLabelItemTag) -MAP_TAG(Stmt); -MAP_TAG(StmtCondition); -MAP_TYPE_TO_TAG(swift::StmtConditionElement, ConditionElementTag); -MAP_TAG(CaseLabelItem); -#define ABSTRACT_STMT(CLASS, PARENT) MAP_SUBTAG(CLASS##Stmt, PARENT) -#define STMT(CLASS, PARENT) ABSTRACT_STMT(CLASS, PARENT) -#include +MAP(swift::Stmt, StmtTag) + MAP(swift::BraceStmt, BraceStmtTag) + MAP(swift::ReturnStmt, ReturnStmtTag) + MAP(swift::YieldStmt, YieldStmtTag) + MAP(swift::DeferStmt, DeferStmtTag) + MAP(swift::LabeledStmt, LabeledStmtTag) + MAP(swift::LabeledConditionalStmt, LabeledConditionalStmtTag) + MAP(swift::IfStmt, IfStmtTag) + MAP(swift::GuardStmt, GuardStmtTag) + MAP(swift::WhileStmt, WhileStmtTag) + MAP(swift::DoStmt, DoStmtTag) + MAP(swift::DoCatchStmt, DoCatchStmtTag) + MAP(swift::RepeatWhileStmt, RepeatWhileStmtTag) + MAP(swift::ForEachStmt, ForEachStmtTag) + MAP(swift::SwitchStmt, SwitchStmtTag) + MAP(swift::CaseStmt, CaseStmtTag) + MAP(swift::BreakStmt, BreakStmtTag) + MAP(swift::ContinueStmt, ContinueStmtTag) + MAP(swift::FallthroughStmt, FallthroughStmtTag) + MAP(swift::FailStmt, FailStmtTag) + MAP(swift::ThrowStmt, ThrowStmtTag) + MAP(swift::PoundAssertStmt, PoundAssertStmtTag) -MAP_TAG(Expr); -MAP_TAG(Argument); -#define ABSTRACT_EXPR(CLASS, PARENT) MAP_SUBTAG(CLASS##Expr, PARENT) -#define EXPR(CLASS, PARENT) ABSTRACT_EXPR(CLASS, PARENT) -#include +MAP(swift::Argument, ArgumentTag) +MAP(swift::Expr, ExprTag) + MAP(swift::ErrorExpr, ErrorExprTag) + MAP(swift::LiteralExpr, LiteralExprTag) + MAP(swift::NilLiteralExpr, NilLiteralExprTag) + MAP(swift::BuiltinLiteralExpr, BuiltinLiteralExprTag) + MAP(swift::BooleanLiteralExpr, BooleanLiteralExprTag) + MAP(swift::NumberLiteralExpr, NumberLiteralExprTag) + MAP(swift::IntegerLiteralExpr, IntegerLiteralExprTag) + MAP(swift::FloatLiteralExpr, FloatLiteralExprTag) + MAP(swift::StringLiteralExpr, StringLiteralExprTag) + MAP(swift::MagicIdentifierLiteralExpr, MagicIdentifierLiteralExprTag) + MAP(swift::InterpolatedStringLiteralExpr, InterpolatedStringLiteralExprTag) + MAP(swift::RegexLiteralExpr, RegexLiteralExprTag) + MAP(swift::ObjectLiteralExpr, ObjectLiteralExprTag) + MAP(swift::DiscardAssignmentExpr, DiscardAssignmentExprTag) + MAP(swift::DeclRefExpr, DeclRefExprTag) + MAP(swift::SuperRefExpr, SuperRefExprTag) + MAP(swift::TypeExpr, TypeExprTag) + MAP(swift::OtherConstructorDeclRefExpr, OtherConstructorDeclRefExprTag) + MAP(swift::DotSyntaxBaseIgnoredExpr, DotSyntaxBaseIgnoredExprTag) + MAP(swift::OverloadSetRefExpr, OverloadedDeclRefExprTag) // collapsed with its only derived class OverloadedDeclRefExpr + MAP(swift::OverloadedDeclRefExpr, OverloadedDeclRefExprTag) + MAP(swift::UnresolvedDeclRefExpr, UnresolvedDeclRefExprTag) + MAP(swift::LookupExpr, LookupExprTag) + MAP(swift::MemberRefExpr, MemberRefExprTag) + MAP(swift::SubscriptExpr, SubscriptExprTag) + MAP(swift::DynamicLookupExpr, DynamicLookupExprTag) + MAP(swift::DynamicMemberRefExpr, DynamicMemberRefExprTag) + MAP(swift::DynamicSubscriptExpr, DynamicSubscriptExprTag) + MAP(swift::UnresolvedSpecializeExpr, UnresolvedSpecializeExprTag) + MAP(swift::UnresolvedMemberExpr, UnresolvedMemberExprTag) + MAP(swift::UnresolvedDotExpr, UnresolvedDotExprTag) + MAP(swift::SequenceExpr, SequenceExprTag) + MAP(swift::IdentityExpr, IdentityExprTag) + MAP(swift::ParenExpr, ParenExprTag) + MAP(swift::DotSelfExpr, DotSelfExprTag) + MAP(swift::AwaitExpr, AwaitExprTag) + MAP(swift::UnresolvedMemberChainResultExpr, UnresolvedMemberChainResultExprTag) + MAP(swift::AnyTryExpr, AnyTryExprTag) + MAP(swift::TryExpr, TryExprTag) + MAP(swift::ForceTryExpr, ForceTryExprTag) + MAP(swift::OptionalTryExpr, OptionalTryExprTag) + MAP(swift::TupleExpr, TupleExprTag) + MAP(swift::CollectionExpr, CollectionExprTag) + MAP(swift::ArrayExpr, ArrayExprTag) + MAP(swift::DictionaryExpr, DictionaryExprTag) + MAP(swift::KeyPathApplicationExpr, KeyPathApplicationExprTag) + MAP(swift::TupleElementExpr, TupleElementExprTag) + MAP(swift::CaptureListExpr, CaptureListExprTag) + MAP(swift::AbstractClosureExpr, AbstractClosureExprTag) + MAP(swift::ClosureExpr, ClosureExprTag) + MAP(swift::AutoClosureExpr, AutoClosureExprTag) + MAP(swift::InOutExpr, InOutExprTag) + MAP(swift::VarargExpansionExpr, VarargExpansionExprTag) + MAP(swift::DynamicTypeExpr, DynamicTypeExprTag) + MAP(swift::RebindSelfInConstructorExpr, RebindSelfInConstructorExprTag) + MAP(swift::OpaqueValueExpr, OpaqueValueExprTag) + MAP(swift::PropertyWrapperValuePlaceholderExpr, PropertyWrapperValuePlaceholderExprTag) + MAP(swift::AppliedPropertyWrapperExpr, AppliedPropertyWrapperExprTag) + MAP(swift::DefaultArgumentExpr, DefaultArgumentExprTag) + MAP(swift::BindOptionalExpr, BindOptionalExprTag) + MAP(swift::OptionalEvaluationExpr, OptionalEvaluationExprTag) + MAP(swift::ForceValueExpr, ForceValueExprTag) + MAP(swift::OpenExistentialExpr, OpenExistentialExprTag) + MAP(swift::MakeTemporarilyEscapableExpr, MakeTemporarilyEscapableExprTag) + MAP(swift::ApplyExpr, ApplyExprTag) + MAP(swift::CallExpr, CallExprTag) + MAP(swift::PrefixUnaryExpr, PrefixUnaryExprTag) + MAP(swift::PostfixUnaryExpr, PostfixUnaryExprTag) + MAP(swift::BinaryExpr, BinaryExprTag) + MAP(swift::SelfApplyExpr, SelfApplyExprTag) + MAP(swift::DotSyntaxCallExpr, DotSyntaxCallExprTag) + MAP(swift::ConstructorRefCallExpr, ConstructorRefCallExprTag) + MAP(swift::ImplicitConversionExpr, ImplicitConversionExprTag) + MAP(swift::LoadExpr, LoadExprTag) + MAP(swift::DestructureTupleExpr, DestructureTupleExprTag) + MAP(swift::UnresolvedTypeConversionExpr, UnresolvedTypeConversionExprTag) + MAP(swift::FunctionConversionExpr, FunctionConversionExprTag) + MAP(swift::CovariantFunctionConversionExpr, CovariantFunctionConversionExprTag) + MAP(swift::CovariantReturnConversionExpr, CovariantReturnConversionExprTag) + MAP(swift::MetatypeConversionExpr, MetatypeConversionExprTag) + MAP(swift::CollectionUpcastConversionExpr, CollectionUpcastConversionExprTag) + MAP(swift::ErasureExpr, ErasureExprTag) + MAP(swift::AnyHashableErasureExpr, AnyHashableErasureExprTag) + MAP(swift::BridgeToObjCExpr, BridgeToObjCExprTag) + MAP(swift::BridgeFromObjCExpr, BridgeFromObjCExprTag) + MAP(swift::ConditionalBridgeFromObjCExpr, ConditionalBridgeFromObjCExprTag) + MAP(swift::DerivedToBaseExpr, DerivedToBaseExprTag) + MAP(swift::ArchetypeToSuperExpr, ArchetypeToSuperExprTag) + MAP(swift::InjectIntoOptionalExpr, InjectIntoOptionalExprTag) + MAP(swift::ClassMetatypeToObjectExpr, ClassMetatypeToObjectExprTag) + MAP(swift::ExistentialMetatypeToObjectExpr, ExistentialMetatypeToObjectExprTag) + MAP(swift::ProtocolMetatypeToObjectExpr, ProtocolMetatypeToObjectExprTag) + MAP(swift::InOutToPointerExpr, InOutToPointerExprTag) + MAP(swift::ArrayToPointerExpr, ArrayToPointerExprTag) + MAP(swift::StringToPointerExpr, StringToPointerExprTag) + MAP(swift::PointerToPointerExpr, PointerToPointerExprTag) + MAP(swift::ForeignObjectConversionExpr, ForeignObjectConversionExprTag) + MAP(swift::UnevaluatedInstanceExpr, UnevaluatedInstanceExprTag) + MAP(swift::UnderlyingToOpaqueExpr, UnderlyingToOpaqueExprTag) + MAP(swift::DifferentiableFunctionExpr, DifferentiableFunctionExprTag) + MAP(swift::LinearFunctionExpr, LinearFunctionExprTag) + MAP(swift::DifferentiableFunctionExtractOriginalExpr, DifferentiableFunctionExtractOriginalExprTag) + MAP(swift::LinearFunctionExtractOriginalExpr, LinearFunctionExtractOriginalExprTag) + MAP(swift::LinearToDifferentiableFunctionExpr, LinearToDifferentiableFunctionExprTag) + MAP(swift::ReifyPackExpr, void) // experimental variadic generics + MAP(swift::ExplicitCastExpr, ExplicitCastExprTag) + MAP(swift::CheckedCastExpr, CheckedCastExprTag) + MAP(swift::ForcedCheckedCastExpr, ForcedCheckedCastExprTag) + MAP(swift::ConditionalCheckedCastExpr, ConditionalCheckedCastExprTag) + MAP(swift::IsExpr, IsExprTag) + MAP(swift::CoerceExpr, CoerceExprTag) + MAP(swift::ArrowExpr, void) // not present after the Sema phase + MAP(swift::IfExpr, IfExprTag) + MAP(swift::EnumIsCaseExpr, EnumIsCaseExprTag) + MAP(swift::AssignExpr, AssignExprTag) + MAP(swift::CodeCompletionExpr, void) // only generated for code editing + MAP(swift::UnresolvedPatternExpr, UnresolvedPatternExprTag) + MAP(swift::LazyInitializerExpr, LazyInitializerExprTag) + MAP(swift::EditorPlaceholderExpr, void) // only generated for code editing + MAP(swift::ObjCSelectorExpr, ObjCSelectorExprTag) + MAP(swift::KeyPathExpr, KeyPathExprTag) + MAP(swift::KeyPathDotExpr, KeyPathDotExprTag) + MAP(swift::OneWayExpr, OneWayExprTag) + MAP(swift::TapExpr, TapExprTag) + MAP(swift::PackExpr, void) // experimental variadic generics -MAP_TAG(Decl); -#define ABSTRACT_DECL(CLASS, PARENT) MAP_SUBTAG(CLASS##Decl, PARENT) -#define DECL(CLASS, PARENT) ABSTRACT_DECL(CLASS, PARENT) -#include +MAP(swift::Decl, DeclTag) + MAP(swift::ValueDecl, ValueDeclTag) + MAP(swift::TypeDecl, TypeDeclTag) + MAP(swift::GenericTypeDecl, GenericTypeDeclTag) + MAP(swift::NominalTypeDecl, NominalTypeDeclTag) + MAP(swift::EnumDecl, EnumDeclTag) + MAP(swift::StructDecl, StructDeclTag) + MAP(swift::ClassDecl, ClassDeclTag) + MAP(swift::ProtocolDecl, ProtocolDeclTag) + MAP(swift::OpaqueTypeDecl, OpaqueTypeDeclTag) + MAP(swift::TypeAliasDecl, TypeAliasDeclTag) + MAP(swift::AbstractTypeParamDecl, AbstractTypeParamDeclTag) + MAP(swift::GenericTypeParamDecl, GenericTypeParamDeclTag) + MAP(swift::AssociatedTypeDecl, AssociatedTypeDeclTag) + MAP(swift::ModuleDecl, ModuleDeclTag) + MAP(swift::AbstractStorageDecl, AbstractStorageDeclTag) + MAP(swift::VarDecl, VarDeclTag) + MAP_CONCRETE(swift::VarDecl, ConcreteVarDeclTag) + MAP(swift::ParamDecl, ParamDeclTag) + MAP(swift::SubscriptDecl, SubscriptDeclTag) + MAP(swift::AbstractFunctionDecl, AbstractFunctionDeclTag) + MAP(swift::ConstructorDecl, ConstructorDeclTag) + MAP(swift::DestructorDecl, DestructorDeclTag) + MAP(swift::FuncDecl, FuncDeclTag) + MAP_CONCRETE(swift::FuncDecl, ConcreteFuncDeclTag) + MAP(swift::AccessorDecl, AccessorDeclTag) + MAP(swift::EnumElementDecl, EnumElementDeclTag) + MAP(swift::ExtensionDecl, ExtensionDeclTag) + MAP(swift::TopLevelCodeDecl, TopLevelCodeDeclTag) + MAP(swift::ImportDecl, ImportDeclTag) + MAP(swift::IfConfigDecl, IfConfigDeclTag) + MAP(swift::PoundDiagnosticDecl, PoundDiagnosticDeclTag) + MAP(swift::PrecedenceGroupDecl, PrecedenceGroupDeclTag) + MAP(swift::MissingMemberDecl, MissingMemberDeclTag) + MAP(swift::PatternBindingDecl, PatternBindingDeclTag) + MAP(swift::EnumCaseDecl, EnumCaseDeclTag) + MAP(swift::OperatorDecl, OperatorDeclTag) + MAP(swift::InfixOperatorDecl, InfixOperatorDeclTag) + MAP(swift::PrefixOperatorDecl, PrefixOperatorDeclTag) + MAP(swift::PostfixOperatorDecl, PostfixOperatorDeclTag) -MAP_TAG(Pattern); -#define ABSTRACT_PATTERN(CLASS, PARENT) MAP_SUBTAG(CLASS##Pattern, PARENT) -#define PATTERN(CLASS, PARENT) ABSTRACT_PATTERN(CLASS, PARENT) -#include +MAP(swift::Pattern, PatternTag) + MAP(swift::ParenPattern, ParenPatternTag) + MAP(swift::TuplePattern, TuplePatternTag) + MAP(swift::NamedPattern, NamedPatternTag) + MAP(swift::AnyPattern, AnyPatternTag) + MAP(swift::TypedPattern, TypedPatternTag) + MAP(swift::BindingPattern, BindingPatternTag) + MAP(swift::IsPattern, IsPatternTag) + MAP(swift::EnumElementPattern, EnumElementPatternTag) + MAP(swift::OptionalSomePattern, OptionalSomePatternTag) + MAP(swift::BoolPattern, BoolPatternTag) + MAP(swift::ExprPattern, ExprPatternTag) -MAP_TAG(TypeRepr); - -MAP_TYPE_TO_TAG(swift::TypeBase, TypeTag); -#define ABSTRACT_TYPE(CLASS, PARENT) MAP_SUBTAG(CLASS##Type, PARENT) -#define TYPE(CLASS, PARENT) ABSTRACT_TYPE(CLASS, PARENT) -#include - -OVERRIDE_TAG(FuncDecl, ConcreteFuncDeclTag); -OVERRIDE_TAG(VarDecl, ConcreteVarDeclTag); - -MAP_TYPE_TO_TAG(std::filesystem::path, DbFileTag); - -#undef MAP_TAG -#undef MAP_SUBTAG -#undef MAP_TYPE_TO_TAG -#undef OVERRIDE_TAG - -// All the other macros defined here are undefined by the .def files +MAP(swift::TypeRepr, TypeReprTag) +MAP(swift::Type, TypeTag) +MAP(swift::TypeBase, TypeTag) + MAP(swift::ErrorType, ErrorTypeTag) + MAP(swift::UnresolvedType, UnresolvedTypeTag) + MAP(swift::PlaceholderType, void) // appears in ambiguous types but are then transformed to UnresolvedType + MAP(swift::BuiltinType, BuiltinTypeTag) + MAP(swift::AnyBuiltinIntegerType, AnyBuiltinIntegerTypeTag) + MAP(swift::BuiltinIntegerType, BuiltinIntegerTypeTag) + MAP(swift::BuiltinIntegerLiteralType, BuiltinIntegerLiteralTypeTag) + MAP(swift::BuiltinExecutorType, BuiltinExecutorTypeTag) + MAP(swift::BuiltinFloatType, BuiltinFloatTypeTag) + MAP(swift::BuiltinJobType, BuiltinJobTypeTag) + MAP(swift::BuiltinRawPointerType, BuiltinRawPointerTypeTag) + MAP(swift::BuiltinRawUnsafeContinuationType, BuiltinRawUnsafeContinuationTypeTag) + MAP(swift::BuiltinNativeObjectType, BuiltinNativeObjectTypeTag) + MAP(swift::BuiltinBridgeObjectType, BuiltinBridgeObjectTypeTag) + MAP(swift::BuiltinUnsafeValueBufferType, BuiltinUnsafeValueBufferTypeTag) + MAP(swift::BuiltinDefaultActorStorageType, BuiltinDefaultActorStorageTypeTag) + MAP(swift::BuiltinVectorType, BuiltinVectorTypeTag) + MAP(swift::TupleType, TupleTypeTag) + MAP(swift::ReferenceStorageType, ReferenceStorageTypeTag) + MAP(swift::WeakStorageType, WeakStorageTypeTag) + MAP(swift::UnownedStorageType, UnownedStorageTypeTag) + MAP(swift::UnmanagedStorageType, UnmanagedStorageTypeTag) + MAP(swift::AnyGenericType, AnyGenericTypeTag) + MAP(swift::NominalOrBoundGenericNominalType, NominalOrBoundGenericNominalTypeTag) + MAP(swift::NominalType, NominalTypeTag) + MAP(swift::EnumType, EnumTypeTag) + MAP(swift::StructType, StructTypeTag) + MAP(swift::ClassType, ClassTypeTag) + MAP(swift::ProtocolType, ProtocolTypeTag) + MAP(swift::BoundGenericType, BoundGenericTypeTag) + MAP(swift::BoundGenericClassType, BoundGenericClassTypeTag) + MAP(swift::BoundGenericEnumType, BoundGenericEnumTypeTag) + MAP(swift::BoundGenericStructType, BoundGenericStructTypeTag) + MAP(swift::UnboundGenericType, UnboundGenericTypeTag) + MAP(swift::AnyMetatypeType, AnyMetatypeTypeTag) + MAP(swift::MetatypeType, MetatypeTypeTag) + MAP(swift::ExistentialMetatypeType, ExistentialMetatypeTypeTag) + MAP(swift::ModuleType, ModuleTypeTag) + MAP(swift::DynamicSelfType, DynamicSelfTypeTag) + MAP(swift::SubstitutableType, SubstitutableTypeTag) + MAP(swift::ArchetypeType, ArchetypeTypeTag) + MAP(swift::PrimaryArchetypeType, PrimaryArchetypeTypeTag) + MAP(swift::OpaqueTypeArchetypeType, OpaqueTypeArchetypeTypeTag) + MAP(swift::OpenedArchetypeType, OpenedArchetypeTypeTag) + MAP(swift::SequenceArchetypeType, void) // experimental variadic generics + MAP(swift::GenericTypeParamType, GenericTypeParamTypeTag) + MAP(swift::DependentMemberType, DependentMemberTypeTag) + MAP(swift::AnyFunctionType, AnyFunctionTypeTag) + MAP(swift::FunctionType, FunctionTypeTag) + MAP(swift::GenericFunctionType, GenericFunctionTypeTag) + MAP(swift::SILFunctionType, void) // SIL types cannot really appear in the frontend run) + MAP(swift::SILBlockStorageType, void) // SIL types cannot really appear in the frontend run) + MAP(swift::SILBoxType, void) // SIL types cannot really appear in the frontend run) + MAP(swift::SILTokenType, void) // SIL types cannot really appear in the frontend run) + MAP(swift::ProtocolCompositionType, ProtocolCompositionTypeTag) + MAP(swift::ParameterizedProtocolType, ParameterizedProtocolTypeTag) + MAP(swift::ExistentialType, ExistentialTypeTag) + MAP(swift::LValueType, LValueTypeTag) + MAP(swift::InOutType, InOutTypeTag) + MAP(swift::PackType, void) // experimental variadic generics + MAP(swift::PackExpansionType, void) // experimental variadic generics + MAP(swift::TypeVariableType, void) // created during type checking and only used for constraint checking + MAP(swift::SugarType, SugarTypeTag) + MAP(swift::ParenType, ParenTypeTag) + MAP(swift::TypeAliasType, TypeAliasTypeTag) + MAP(swift::SyntaxSugarType, SyntaxSugarTypeTag) + MAP(swift::UnarySyntaxSugarType, UnarySyntaxSugarTypeTag) + MAP(swift::ArraySliceType, ArraySliceTypeTag) + MAP(swift::OptionalType, OptionalTypeTag) + MAP(swift::VariadicSequenceType, VariadicSequenceTypeTag) + MAP(swift::DictionaryType, DictionaryTypeTag) +// clang-format on +#undef MAP +#undef MAP_CONCRETE } // namespace codeql diff --git a/swift/extractor/translators/DeclTranslator.h b/swift/extractor/translators/DeclTranslator.h index f72a29437d5..12fe39465b3 100644 --- a/swift/extractor/translators/DeclTranslator.h +++ b/swift/extractor/translators/DeclTranslator.h @@ -65,9 +65,9 @@ class DeclTranslator : public AstTranslatorBase { codeql::AbstractStorageDecl& entry); template - std::optional> createNamedEntry(const D& decl) { - auto id = dispatcher.assignNewLabel(decl, mangledName(decl)); + auto createNamedEntry(const D& decl) { std::optional> entry; + auto id = dispatcher.assignNewLabel(decl, mangledName(decl)); if (dispatcher.shouldEmitDeclBody(decl)) { entry.emplace(id); fillDecl(decl, *entry); @@ -76,7 +76,7 @@ class DeclTranslator : public AstTranslatorBase { } template - TrapClassOf createEntry(const D& decl) { + auto createEntry(const D& decl) { TrapClassOf entry{dispatcher.template assignNewLabel(decl)}; fillDecl(decl, entry); return entry; diff --git a/swift/extractor/translators/TranslatorBase.h b/swift/extractor/translators/TranslatorBase.h index 0f7d4cacd3d..5303ffd68a5 100644 --- a/swift/extractor/translators/TranslatorBase.h +++ b/swift/extractor/translators/TranslatorBase.h @@ -75,7 +75,7 @@ enum class TranslatorPolicy { #define DEFINE_VISIT(KIND, CLASS, PARENT) \ public: \ static constexpr TranslatorPolicy getPolicyFor##CLASS##KIND() { \ - if constexpr (std::is_same_v) { \ + if constexpr (std::is_same_v, void>) { \ return TranslatorPolicy::ignore; \ } else if constexpr (detail::HasTranslate##CLASS##KIND::value) { \ return TranslatorPolicy::translate; \ diff --git a/swift/extractor/trap/TrapTagTraits.h b/swift/extractor/trap/TrapTagTraits.h index f0f8c41cc8d..b9c0830cd45 100644 --- a/swift/extractor/trap/TrapTagTraits.h +++ b/swift/extractor/trap/TrapTagTraits.h @@ -4,6 +4,7 @@ // label tags #include +#include "swift/extractor/trap/TrapLabel.h" namespace codeql { @@ -14,7 +15,7 @@ struct ToTagFunctor; // can be instantiated to override the default mapping for special cases template -struct ToTagOverride : ToTagFunctor {}; +struct ToTagConcreteOverride : ToTagFunctor {}; // must be instantiated to map trap labels to the corresponding generated binding trap entry template @@ -27,15 +28,19 @@ struct ToTrapClassFunctor; template using TrapTagOf = - typename detail::ToTagOverride>>::type; + typename detail::ToTagFunctor>>::type; + +template +using ConcreteTrapTagOf = + typename detail::ToTagConcreteOverride>>::type; template using TrapLabelOf = TrapLabel>; template -using BindingTrapOf = typename detail::ToBindingTrapFunctor>::type; +using BindingTrapOf = typename detail::ToBindingTrapFunctor>>::type; template -using TrapClassOf = typename detail::ToTrapClassFunctor>::type; +using TrapClassOf = typename detail::ToTrapClassFunctor>::type; } // namespace codeql From a423f5f6951519121a229291299491bfd516047c Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Fri, 25 Nov 2022 16:27:45 +0000 Subject: [PATCH 534/796] Kotlin: Enable java/misnamed-type query We used to get alerts for the class around a local function, a lambda, or a function reference, which we give name "". Now those are marked as compiler-generated, and the query ignores compiler-generated types. --- java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt | 2 ++ java/ql/lib/semmle/code/java/Element.qll | 2 ++ java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql | 3 ++- .../2022-11-25-NamingConventionsRefTypes-kotlin.md | 4 ++++ .../NamingConventionsRefTypes.expected | 1 + 5 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 java/ql/src/change-notes/2022-11-25-NamingConventionsRefTypes-kotlin.md diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 489d1b85743..3d9b4ad37ce 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -5396,6 +5396,7 @@ open class KotlinFileExtractor( val id = ids.type.javaResult.id.cast() val pkgId = extractPackage("") tw.writeClasses(id, "", pkgId, id) + tw.writeCompiler_generated(id, CompilerGeneratedKinds.CALLABLE_CLASS.kind) tw.writeHasLocation(id, locId) // Extract constructor @@ -5520,5 +5521,6 @@ open class KotlinFileExtractor( DEFAULT_ARGUMENTS_METHOD(10), INTERFACE_FORWARDER(11), ENUM_CONSTRUCTOR_ARGUMENT(12), + CALLABLE_CLASS(13), } } diff --git a/java/ql/lib/semmle/code/java/Element.qll b/java/ql/lib/semmle/code/java/Element.qll index 751fe1a1d64..08689f05f94 100644 --- a/java/ql/lib/semmle/code/java/Element.qll +++ b/java/ql/lib/semmle/code/java/Element.qll @@ -71,6 +71,8 @@ class Element extends @element, Top { i = 11 and result = "Forwarder for a Kotlin class inheriting an interface default method" or i = 12 and result = "Argument for enum constructor call" + or + i = 13 and result = "The class around a local function, a lambda, or a function reference" ) } } diff --git a/java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql b/java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql index f0d6d20b1b2..6942eaab69a 100644 --- a/java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql +++ b/java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql @@ -12,7 +12,8 @@ import java from RefType t where - t.getFile().isJavaSourceFile() and + t.fromSource() and not t instanceof AnonymousClass and + not t.isCompilerGenerated() and not t.getName().substring(0, 1).toUpperCase() = t.getName().substring(0, 1) select t, "Class and interface names should start in uppercase." diff --git a/java/ql/src/change-notes/2022-11-25-NamingConventionsRefTypes-kotlin.md b/java/ql/src/change-notes/2022-11-25-NamingConventionsRefTypes-kotlin.md new file mode 100644 index 00000000000..c99d7168297 --- /dev/null +++ b/java/ql/src/change-notes/2022-11-25-NamingConventionsRefTypes-kotlin.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The query `java/misnamed-type` is now enabled for Kotlin. diff --git a/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.expected b/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.expected index e69de29bb2d..ffcd13ccc56 100644 --- a/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.expected +++ b/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.expected @@ -0,0 +1 @@ +| Test.kt:12:1:12:13 | aaaa | Class and interface names should start in uppercase. | From 0879f02db613858018cfef9c1f42e7efa0019388 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 25 Nov 2022 17:54:53 +0000 Subject: [PATCH 535/796] Adapt custom_plugin test to Kotlin 1.7.20 --- .../linux-only/kotlin/custom_plugin/plugin/Plugin.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/plugin/Plugin.kt b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/plugin/Plugin.kt index c88410ca9db..d80801974e2 100644 --- a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/plugin/Plugin.kt +++ b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/plugin/Plugin.kt @@ -4,7 +4,7 @@ import com.intellij.mock.MockProject import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext -import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor +import org.jetbrains.kotlin.backend.common.ir.addDispatchReceiver import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar import org.jetbrains.kotlin.config.CompilerConfiguration @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.types.typeWith +import org.jetbrains.kotlin.ir.util.createImplicitParameterDeclarationWithWrappedDescriptor import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name From b6034b493570f894aee9f8a063c0e6d825defe93 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 25 Nov 2022 16:22:46 +0100 Subject: [PATCH 536/796] delete language specific format check --- .github/workflows/go-tests.yml | 2 +- go/Makefile | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index 3cc61eafa5c..dfbe3f70603 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -32,7 +32,7 @@ jobs: cd go make - - name: Check that all QL and Go code is autoformatted + - name: Check that all Go code is autoformatted run: | cd go make check-formatting diff --git a/go/Makefile b/go/Makefile index 419b1991775..fc05fb9300e 100644 --- a/go/Makefile +++ b/go/Makefile @@ -34,7 +34,6 @@ autoformat: find . -path '**/vendor' -prune -or -type f -iname '*.go' ! -empty -print0 | xargs -0 grep -L "//\s*autoformat-ignore" | xargs gofmt -w check-formatting: - find ql -iregex '.*\.qll?' -print0 | xargs -0 codeql query format --check-only test -z "$$(find . -path '**/vendor' -prune -or -type f -iname '*.go' ! -empty -print0 | xargs -0 grep -L "//\s*autoformat-ignore" | xargs gofmt -l)" install-deps: From d7763f236f7a45f2b7d57cefb292723c496c1e54 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 25 Nov 2022 16:23:23 +0100 Subject: [PATCH 537/796] use more threads for codeql test --- go/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/Makefile b/go/Makefile index fc05fb9300e..2016f6fb5c1 100644 --- a/go/Makefile +++ b/go/Makefile @@ -116,9 +116,9 @@ ql/lib/go.dbscheme.stats: ql/lib/go.dbscheme build/stats/src.stamp extractor codeql dataset measure -o $@ build/stats/database/db-go test: all build/testdb/check-upgrade-path - codeql test run ql/test --search-path build/codeql-extractor-go --consistency-queries ql/test/consistency + codeql test run -j0 ql/test --search-path build/codeql-extractor-go --consistency-queries ql/test/consistency # use GOOS=linux because GOOS=darwin GOARCH=386 is no longer supported - env GOOS=linux GOARCH=386 codeql$(EXE) test run ql/test/query-tests/Security/CWE-681 --search-path build/codeql-extractor-go --consistency-queries ql/test/consistency + env GOOS=linux GOARCH=386 codeql$(EXE) test run -j0 ql/test/query-tests/Security/CWE-681 --search-path build/codeql-extractor-go --consistency-queries ql/test/consistency cd extractor; go test -mod=vendor ./... | grep -vF "[no test files]" bash extractor-smoke-test/test.sh || (echo "Extractor smoke test FAILED"; exit 1) From 1e732ad4d70c25471dd8c205aa54751cf37069df Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 25 Nov 2022 16:24:54 +0100 Subject: [PATCH 538/796] use XL workers, and update the windows runner --- .github/workflows/go-tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index dfbe3f70603..f82497e171b 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -9,7 +9,7 @@ on: jobs: test-linux: name: Test Linux (Ubuntu) - runs-on: ubuntu-latest + runs-on: ubuntu-latest-xl steps: - name: Set up Go 1.19 uses: actions/setup-go@v3 @@ -55,7 +55,7 @@ jobs: test-mac: name: Test MacOS - runs-on: macos-latest + runs-on: macos-latest-xl steps: - name: Set up Go 1.19 uses: actions/setup-go@v3 @@ -85,7 +85,7 @@ jobs: test-win: name: Test Windows - runs-on: windows-2019 + runs-on: windows-latest-xl steps: - name: Set up Go 1.19 uses: actions/setup-go@v3 From 2b996f11cce7d7be7578e1267d35397550809947 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 25 Nov 2022 16:26:31 +0100 Subject: [PATCH 539/796] use query compilation cache --- .github/workflows/go-tests.yml | 36 +++++++++++++++++++++++++++++++--- go/Makefile | 4 ++-- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index f82497e171b..90638334498 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -1,10 +1,21 @@ name: "Go: Run Tests" on: + push: + paths: + - "go/**" + - .github/workflows/go-tests.yml + - .github/actions/fetch-codeql/action.yml + - .github/actions/cache-query-compilation/action.yml + - codeql-workspace.yml + branches: + - main + - "rc/*" pull_request: paths: - "go/**" - .github/workflows/go-tests.yml - .github/actions/fetch-codeql/action.yml + - .github/actions/cache-query-compilation/action.yml - codeql-workspace.yml jobs: test-linux: @@ -48,14 +59,21 @@ jobs: name: qhelp-markdown path: go/qhelp-out/**/*.md + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: go-qltest + - name: Test run: | cd go - make test + make test cache="${{ steps.query-cache.outputs.cache-dir }}" test-mac: name: Test MacOS runs-on: macos-latest-xl + if: ${{ github.event_name == 'pull_request' }} steps: - name: Set up Go 1.19 uses: actions/setup-go@v3 @@ -78,14 +96,20 @@ jobs: cd go make + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: go-qltest - name: Test run: | cd go - make test + make test cache="${{ steps.query-cache.outputs.cache-dir }}" test-win: name: Test Windows runs-on: windows-latest-xl + if: ${{ github.event_name == 'pull_request' }} steps: - name: Set up Go 1.19 uses: actions/setup-go@v3 @@ -108,7 +132,13 @@ jobs: cd go make + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: go-qltest + - name: Test run: | cd go - make test + make test cache="${{ steps.query-cache.outputs.cache-dir }}" diff --git a/go/Makefile b/go/Makefile index 2016f6fb5c1..7e691d48803 100644 --- a/go/Makefile +++ b/go/Makefile @@ -116,9 +116,9 @@ ql/lib/go.dbscheme.stats: ql/lib/go.dbscheme build/stats/src.stamp extractor codeql dataset measure -o $@ build/stats/database/db-go test: all build/testdb/check-upgrade-path - codeql test run -j0 ql/test --search-path build/codeql-extractor-go --consistency-queries ql/test/consistency + codeql test run -j0 ql/test --search-path build/codeql-extractor-go --consistency-queries ql/test/consistency --compilation-cache=$(cache) # use GOOS=linux because GOOS=darwin GOARCH=386 is no longer supported - env GOOS=linux GOARCH=386 codeql$(EXE) test run -j0 ql/test/query-tests/Security/CWE-681 --search-path build/codeql-extractor-go --consistency-queries ql/test/consistency + env GOOS=linux GOARCH=386 codeql$(EXE) test run -j0 ql/test/query-tests/Security/CWE-681 --search-path build/codeql-extractor-go --consistency-queries ql/test/consistency --compilation-cache=$(cache) cd extractor; go test -mod=vendor ./... | grep -vF "[no test files]" bash extractor-smoke-test/test.sh || (echo "Extractor smoke test FAILED"; exit 1) From dcfa0b38c1c0aea88a9fb39f0e7f0907f09cc628 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 25 Nov 2022 16:47:20 +0100 Subject: [PATCH 540/796] use a non-xl mac runner because the XL runners keep queing --- .github/workflows/go-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index 90638334498..d1ec00bfb65 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -72,7 +72,7 @@ jobs: test-mac: name: Test MacOS - runs-on: macos-latest-xl + runs-on: macos-latest if: ${{ github.event_name == 'pull_request' }} steps: - name: Set up Go 1.19 From 2b0ecec0c83648ab023db090563b6719b6b52337 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Sat, 26 Nov 2022 10:32:12 +0100 Subject: [PATCH 541/796] only run other-os on non-ql changes --- .github/workflows/go-tests-other-os.yml | 81 +++++++++++++++++++++++++ .github/workflows/go-tests.yml | 73 ---------------------- 2 files changed, 81 insertions(+), 73 deletions(-) create mode 100644 .github/workflows/go-tests-other-os.yml diff --git a/.github/workflows/go-tests-other-os.yml b/.github/workflows/go-tests-other-os.yml new file mode 100644 index 00000000000..5d99a170be3 --- /dev/null +++ b/.github/workflows/go-tests-other-os.yml @@ -0,0 +1,81 @@ +name: "Go: Run Tests - Other OS" +on: + pull_request: + paths: + - "go/**" + - "!go/ql/**" # don't run other-os if only ql/ files changed + - .github/workflows/go-tests-other-os.yml + - .github/actions/fetch-codeql/action.yml + - .github/actions/cache-query-compilation/action.yml + - codeql-workspace.yml +jobs: + test-mac: + name: Test MacOS + runs-on: macos-latest + steps: + - name: Set up Go 1.19 + uses: actions/setup-go@v3 + with: + go-version: 1.19 + id: go + + - name: Check out code + uses: actions/checkout@v2 + + - name: Set up CodeQL CLI + uses: ./.github/actions/fetch-codeql + + - name: Enable problem matchers in repository + shell: bash + run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' + + - name: Build + run: | + cd go + make + + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: go-qltest + - name: Test + run: | + cd go + make test cache="${{ steps.query-cache.outputs.cache-dir }}" + + test-win: + name: Test Windows + runs-on: windows-latest-xl + steps: + - name: Set up Go 1.19 + uses: actions/setup-go@v3 + with: + go-version: 1.19 + id: go + + - name: Check out code + uses: actions/checkout@v2 + + - name: Set up CodeQL CLI + uses: ./.github/actions/fetch-codeql + + - name: Enable problem matchers in repository + shell: bash + run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' + + - name: Build + run: | + cd go + make + + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: go-qltest + + - name: Test + run: | + cd go + make test cache="${{ steps.query-cache.outputs.cache-dir }}" diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index d1ec00bfb65..685c28cf3e0 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -69,76 +69,3 @@ jobs: run: | cd go make test cache="${{ steps.query-cache.outputs.cache-dir }}" - - test-mac: - name: Test MacOS - runs-on: macos-latest - if: ${{ github.event_name == 'pull_request' }} - steps: - - name: Set up Go 1.19 - uses: actions/setup-go@v3 - with: - go-version: 1.19 - id: go - - - name: Check out code - uses: actions/checkout@v2 - - - name: Set up CodeQL CLI - uses: ./.github/actions/fetch-codeql - - - name: Enable problem matchers in repository - shell: bash - run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' - - - name: Build - run: | - cd go - make - - - name: Cache compilation cache - id: query-cache - uses: ./.github/actions/cache-query-compilation - with: - key: go-qltest - - name: Test - run: | - cd go - make test cache="${{ steps.query-cache.outputs.cache-dir }}" - - test-win: - name: Test Windows - runs-on: windows-latest-xl - if: ${{ github.event_name == 'pull_request' }} - steps: - - name: Set up Go 1.19 - uses: actions/setup-go@v3 - with: - go-version: 1.19 - id: go - - - name: Check out code - uses: actions/checkout@v2 - - - name: Set up CodeQL CLI - uses: ./.github/actions/fetch-codeql - - - name: Enable problem matchers in repository - shell: bash - run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' - - - name: Build - run: | - cd go - make - - - name: Cache compilation cache - id: query-cache - uses: ./.github/actions/cache-query-compilation - with: - key: go-qltest - - - name: Test - run: | - cd go - make test cache="${{ steps.query-cache.outputs.cache-dir }}" From abe4d99e12aaceb8dd7c66a1c73cc95e6d9c5dd4 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 25 Nov 2022 13:41:41 +0100 Subject: [PATCH 542/796] Java: Make some rudimentary tooling for testing the flow test case generator script. --- .../test/utils/flowtestcasegenerator/options | 1 + .../test/utils/flowtestcasegenerator/pom.xml | 133 ++++++++++++++++++ .../utils/flowtestcasegenerator/specs.csv | 11 ++ .../test/utils/flowtestcasegenerator/test.py | 17 +++ 4 files changed, 162 insertions(+) create mode 100644 java/ql/test/utils/flowtestcasegenerator/options create mode 100644 java/ql/test/utils/flowtestcasegenerator/pom.xml create mode 100644 java/ql/test/utils/flowtestcasegenerator/specs.csv create mode 100644 java/ql/test/utils/flowtestcasegenerator/test.py diff --git a/java/ql/test/utils/flowtestcasegenerator/options b/java/ql/test/utils/flowtestcasegenerator/options new file mode 100644 index 00000000000..5ae5aad3008 --- /dev/null +++ b/java/ql/test/utils/flowtestcasegenerator/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../stubs/apache-commons-collections4-4.4:${testdir}/../../stubs/apache-log4j-2.14.1:${testdir}/../../stubs/slf4j-2.0.0 \ No newline at end of file diff --git a/java/ql/test/utils/flowtestcasegenerator/pom.xml b/java/ql/test/utils/flowtestcasegenerator/pom.xml new file mode 100644 index 00000000000..b4fe0c30974 --- /dev/null +++ b/java/ql/test/utils/flowtestcasegenerator/pom.xml @@ -0,0 +1,133 @@ + + 4.0.0 + + com.semmle + parent + 1.0 + + + google + Google Maven + https://maven.google.com/ + + + + 31 + 1.8 + 1.8 + + + + org.apache.logging.log4j + log4j-api + 2.14.1 + + + org.apache.logging.log4j + log4j-core + 2.14.1 + + + org.slf4j + slf4j-api + 2.0.0-alpha5 + + + org.jboss.logging + jboss-logging + 3.4.2.Final + + + org.springframework.ldap + spring-ldap + 1.3.1.RELEASE + pom + + + org.springframework.ldap + spring-ldap-core + 2.3.5.RELEASE + + + org.springframework + spring-web + 5.3.18 + + + org.springframework + spring-context + 5.3.18 + + + org.springframework + spring-webmvc + 5.3.18 + + + org.springframework.data + spring-data-commons + 2.6.3 + + + org.apache.shiro + shiro-core + 1.8.0 + + + org.apache.directory.api + api-ldap-client-all + 2.1.0 + + + org.owasp.esapi + esapi + 2.2.3.1 + + + com.unboundid + unboundid-ldapsdk + 6.0.3 + + + javax.servlet + javax.servlet-api + 4.0.1 + + + com.squareup.retrofit2 + retrofit + 2.9.0 + + + com.squareup.okhttp3 + okhttp + 4.9.3 + + + org.freemarker + freemarker + 2.3.31 + + + org.thymeleaf + thymeleaf + 3.0.15.RELEASE + + + com.hubspot.jinjava + jinjava + 2.6.0 + + + io.pebbletemplates + pebble + 3.1.5 + + + org.apache.velocity + velocity-engine-core + 2.3 + + + diff --git a/java/ql/test/utils/flowtestcasegenerator/specs.csv b/java/ql/test/utils/flowtestcasegenerator/specs.csv new file mode 100644 index 00000000000..93f59d05916 --- /dev/null +++ b/java/ql/test/utils/flowtestcasegenerator/specs.csv @@ -0,0 +1,11 @@ +org.apache.logging.log4j;Logger;true;traceEntry;(Message);;Argument[0];ReturnValue;taint;manual +org.apache.logging.log4j;Logger;true;traceEntry;(String,Object[]);;Argument[0..1];ReturnValue;taint;manual +org.apache.logging.log4j;Logger;true;traceEntry;(String,Supplier[]);;Argument[0..1];ReturnValue;taint;manual +org.apache.logging.log4j;Logger;true;traceEntry;(Supplier[]);;Argument[0];ReturnValue;taint;manual +org.apache.logging.log4j;Logger;true;traceExit;(EntryMessage,Object);;Argument[1];ReturnValue;value;manual +org.apache.logging.log4j;Logger;true;traceExit;(Message,Object);;Argument[1];ReturnValue;value;manual +org.apache.logging.log4j;Logger;true;traceExit;(Object);;Argument[0];ReturnValue;value;manual +org.apache.logging.log4j;Logger;true;traceExit;(String,Object);;Argument[1];ReturnValue;value;manual +org.apache.commons.collections4;MapUtils;true;predicatedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual +org.apache.commons.collections4;MapUtils;true;toMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual +org.apache.commons.collections4;MapUtils;true;toMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual \ No newline at end of file diff --git a/java/ql/test/utils/flowtestcasegenerator/test.py b/java/ql/test/utils/flowtestcasegenerator/test.py new file mode 100644 index 00000000000..47b7c3a61f2 --- /dev/null +++ b/java/ql/test/utils/flowtestcasegenerator/test.py @@ -0,0 +1,17 @@ +# This script is for debugging purposes for the flow test case generator. +# Some dummy tests are created and executed. +# It requites that `--search-path /path/to/semmle-code/ql` is added to `~/.config/codeql/config` + +# Usage: python3 test.py + +import subprocess + +# Generate test cases +print('Generating test cases...') +if subprocess.check_call(["../../../src/utils/flowtestcasegenerator/GenerateFlowTestCase.py", "specs.csv", "pom.xml", "--force", "."]): + print("Failed to generate test cases.") + exit(1) + +# Run test cases. +print('Running test cases...') +subprocess.call(["codeql", "test", "run", "test.ql"]) \ No newline at end of file From 24e830f91dc342be042fe17bf4199bac32c20d5a Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 25 Nov 2022 13:42:39 +0100 Subject: [PATCH 543/796] Java: Fix some minor bugs in the CSV printing of summaries for flow test generation. --- .../flowtestcasegenerator/FlowTestCaseSupportMethods.qll | 8 ++++---- .../utils/flowtestcasegenerator/testModelsHeader.qlfrag | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/java/ql/src/utils/flowtestcasegenerator/FlowTestCaseSupportMethods.qll b/java/ql/src/utils/flowtestcasegenerator/FlowTestCaseSupportMethods.qll index 713c484ff4b..c3a47b5adea 100644 --- a/java/ql/src/utils/flowtestcasegenerator/FlowTestCaseSupportMethods.qll +++ b/java/ql/src/utils/flowtestcasegenerator/FlowTestCaseSupportMethods.qll @@ -164,8 +164,8 @@ private class DefaultGetMethod extends GetMethod { override string getCsvModel() { result = - "generatedtest;Test;false;" + this.getName() + ";(Object);;" + - getComponentSpec(SummaryComponent::content(c)) + "Argument[0].;ReturnValue;value;manual" + "generatedtest;Test;false;" + this.getName() + ";(Object);;Argument[0]." + + getComponentSpec(SummaryComponent::content(c)) + ";ReturnValue;value;manual" } } @@ -360,8 +360,8 @@ private class DefaultGenMethod extends GenMethod { override string getCsvModel() { result = - "generatedtest;Test;false;" + this.getName() + ";(Object);;Argument[0];" + - getComponentSpec(SummaryComponent::content(c)) + "ReturnValue.;value;manual" + "generatedtest;Test;false;" + this.getName() + ";(Object);;Argument[0];ReturnValue." + + getComponentSpec(SummaryComponent::content(c)) + ";value;manual" } } diff --git a/java/ql/src/utils/flowtestcasegenerator/testModelsHeader.qlfrag b/java/ql/src/utils/flowtestcasegenerator/testModelsHeader.qlfrag index a49dbbe5404..fb33b7eb5db 100644 --- a/java/ql/src/utils/flowtestcasegenerator/testModelsHeader.qlfrag +++ b/java/ql/src/utils/flowtestcasegenerator/testModelsHeader.qlfrag @@ -2,4 +2,4 @@ class SummaryModelTest extends SummaryModelCsv { override predicate row(string row) { row = [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", + //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind;provenance" From d5725255fe1a3c3493a09652778b9654548f4f48 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 28 Nov 2022 09:53:03 +0100 Subject: [PATCH 544/796] add failing test for splat parameter flow --- ruby/ql/test/library-tests/dataflow/params/params_flow.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ruby/ql/test/library-tests/dataflow/params/params_flow.rb b/ruby/ql/test/library-tests/dataflow/params/params_flow.rb index 1dbbbec0734..415e0bf2a2b 100644 --- a/ruby/ql/test/library-tests/dataflow/params/params_flow.rb +++ b/ruby/ql/test/library-tests/dataflow/params/params_flow.rb @@ -57,4 +57,10 @@ args = [taint(22)] posargs(taint(23), *args) args = [taint(24), taint(25)] -posargs(*args) \ No newline at end of file +posargs(*args) + +args = taint(26) +def splatstuff(*x) + sink x[0] # $ MISSING: hasValueFlow=26 +end +splatstuff(*args) \ No newline at end of file From 0c2ff98dc20c4d79a1e0085e70fbba7740d99947 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 28 Nov 2022 09:54:05 +0100 Subject: [PATCH 545/796] add flow from the first splat argument to the first splat parameter --- .../ruby/dataflow/internal/DataFlowDispatch.qll | 12 ++++++++++++ .../ruby/dataflow/internal/DataFlowPrivate.qll | 10 +++++++++- .../dataflow/params/params-flow.expected | 12 ++++++++++++ .../library-tests/dataflow/params/params_flow.rb | 2 +- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll index 4b97772d2c9..5b39b6c407d 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll @@ -497,6 +497,7 @@ private module Cached { FlowSummaryImplSpecific::ParsePositions::isParsedKeywordParameterPosition(_, name) } or THashSplatArgumentPosition() or + TSplatAllArgumentPosition() or TAnyArgumentPosition() or TAnyKeywordArgumentPosition() @@ -518,6 +519,7 @@ private module Cached { FlowSummaryImplSpecific::ParsePositions::isParsedKeywordArgumentPosition(_, name) } or THashSplatParameterPosition() or + TSplatAllParameterPosition() or TAnyParameterPosition() or TAnyKeywordParameterPosition() } @@ -1149,6 +1151,8 @@ class ParameterPosition extends TParameterPosition { /** Holds if this position represents a hash-splat parameter. */ predicate isHashSplat() { this = THashSplatParameterPosition() } + predicate isSplatAll() { this = TSplatAllParameterPosition() } + /** * Holds if this position represents any parameter, except `self` parameters. This * includes both positional, named, and block parameters. @@ -1172,6 +1176,8 @@ class ParameterPosition extends TParameterPosition { or this.isHashSplat() and result = "**" or + this.isSplatAll() and result = "*" + or this.isAny() and result = "any" or this.isAnyNamed() and result = "any-named" @@ -1207,6 +1213,8 @@ class ArgumentPosition extends TArgumentPosition { */ predicate isHashSplat() { this = THashSplatArgumentPosition() } + predicate isSplatAll() { this = TSplatAllArgumentPosition() } + /** Gets a textual representation of this position. */ string toString() { this.isSelf() and result = "self" @@ -1222,6 +1230,8 @@ class ArgumentPosition extends TArgumentPosition { this.isAnyNamed() and result = "any-named" or this.isHashSplat() and result = "**" + or + this.isSplatAll() and result = "*" } } @@ -1248,6 +1258,8 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { or ppos.isHashSplat() and apos.isHashSplat() or + ppos.isSplatAll() and apos.isSplatAll() + or ppos.isAny() and argumentPositionIsNotSelf(apos) or apos.isAny() and parameterPositionIsNotSelf(ppos) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index 8c9c8242c71..8353fad1e50 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -241,6 +241,10 @@ private class Argument extends CfgNodes::ExprCfgNode { this = call.getAnArgument() and this.getExpr() instanceof HashSplatExpr and arg.isHashSplat() + or + this = call.getArgument(0) and + this.getExpr() instanceof SplatExpr and + arg.isSplatAll() } /** Holds if this expression is the `i`th argument of `c`. */ @@ -276,7 +280,8 @@ private module Cached { p instanceof SimpleParameter or p instanceof OptionalParameter or p instanceof KeywordParameter or - p instanceof HashSplatParameter + p instanceof HashSplatParameter or + p instanceof SplatParameter } or TSelfParameterNode(MethodBase m) or TBlockParameterNode(MethodBase m) or @@ -616,6 +621,9 @@ private module ParameterNodes { or parameter = callable.getAParameter().(HashSplatParameter) and pos.isHashSplat() + or + parameter = callable.getParameter(0).(SplatParameter) and + pos.isSplatAll() ) } diff --git a/ruby/ql/test/library-tests/dataflow/params/params-flow.expected b/ruby/ql/test/library-tests/dataflow/params/params-flow.expected index 52ad4bc3bea..12db100a968 100644 --- a/ruby/ql/test/library-tests/dataflow/params/params-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/params/params-flow.expected @@ -40,6 +40,11 @@ edges | params_flow.rb:49:13:49:14 | p1 : | params_flow.rb:50:10:50:11 | p1 | | params_flow.rb:54:9:54:17 | call to taint : | params_flow.rb:49:13:49:14 | p1 : | | params_flow.rb:57:9:57:17 | call to taint : | params_flow.rb:49:13:49:14 | p1 : | +| params_flow.rb:62:8:62:16 | call to taint : | params_flow.rb:66:13:66:16 | args : | +| params_flow.rb:63:16:63:17 | *x [element 0] : | params_flow.rb:64:10:64:10 | x [element 0] : | +| params_flow.rb:64:10:64:10 | x [element 0] : | params_flow.rb:64:10:64:13 | ...[...] | +| params_flow.rb:66:12:66:16 | * ... [element 0] : | params_flow.rb:63:16:63:17 | *x [element 0] : | +| params_flow.rb:66:13:66:16 | args : | params_flow.rb:66:12:66:16 | * ... [element 0] : | nodes | params_flow.rb:9:16:9:17 | p1 : | semmle.label | p1 : | | params_flow.rb:9:20:9:21 | p2 : | semmle.label | p2 : | @@ -89,6 +94,12 @@ nodes | params_flow.rb:50:10:50:11 | p1 | semmle.label | p1 | | params_flow.rb:54:9:54:17 | call to taint : | semmle.label | call to taint : | | params_flow.rb:57:9:57:17 | call to taint : | semmle.label | call to taint : | +| params_flow.rb:62:8:62:16 | call to taint : | semmle.label | call to taint : | +| params_flow.rb:63:16:63:17 | *x [element 0] : | semmle.label | *x [element 0] : | +| params_flow.rb:64:10:64:10 | x [element 0] : | semmle.label | x [element 0] : | +| params_flow.rb:64:10:64:13 | ...[...] | semmle.label | ...[...] | +| params_flow.rb:66:12:66:16 | * ... [element 0] : | semmle.label | * ... [element 0] : | +| params_flow.rb:66:13:66:16 | args : | semmle.label | args : | subpaths #select | params_flow.rb:10:10:10:11 | p1 | params_flow.rb:14:12:14:19 | call to taint : | params_flow.rb:10:10:10:11 | p1 | $@ | params_flow.rb:14:12:14:19 | call to taint : | call to taint : | @@ -111,3 +122,4 @@ subpaths | params_flow.rb:29:10:29:22 | ( ... ) | params_flow.rb:34:14:34:22 | call to taint : | params_flow.rb:29:10:29:22 | ( ... ) | $@ | params_flow.rb:34:14:34:22 | call to taint : | call to taint : | | params_flow.rb:50:10:50:11 | p1 | params_flow.rb:54:9:54:17 | call to taint : | params_flow.rb:50:10:50:11 | p1 | $@ | params_flow.rb:54:9:54:17 | call to taint : | call to taint : | | params_flow.rb:50:10:50:11 | p1 | params_flow.rb:57:9:57:17 | call to taint : | params_flow.rb:50:10:50:11 | p1 | $@ | params_flow.rb:57:9:57:17 | call to taint : | call to taint : | +| params_flow.rb:64:10:64:13 | ...[...] | params_flow.rb:62:8:62:16 | call to taint : | params_flow.rb:64:10:64:13 | ...[...] | $@ | params_flow.rb:62:8:62:16 | call to taint : | call to taint : | diff --git a/ruby/ql/test/library-tests/dataflow/params/params_flow.rb b/ruby/ql/test/library-tests/dataflow/params/params_flow.rb index 415e0bf2a2b..41ae58a58da 100644 --- a/ruby/ql/test/library-tests/dataflow/params/params_flow.rb +++ b/ruby/ql/test/library-tests/dataflow/params/params_flow.rb @@ -61,6 +61,6 @@ posargs(*args) args = taint(26) def splatstuff(*x) - sink x[0] # $ MISSING: hasValueFlow=26 + sink x[0] # $ hasValueFlow=26 end splatstuff(*args) \ No newline at end of file From a5a459fe0a6c52dfe3d84a82757d69717ffd83f3 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 28 Nov 2022 09:39:38 +0000 Subject: [PATCH 546/796] Swift: Update swift/unsafe-js-eval to include local flow sources. --- swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql index e5764416d27..286b06f0b1b 100644 --- a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql +++ b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql @@ -20,9 +20,8 @@ import DataFlow::PathGraph /** * A source of untrusted, user-controlled data. - * TODO: Extend to more (non-remote) sources in the future. */ -class Source = RemoteFlowSource; +class Source = FlowSource; /** * A sink that evaluates a string of JavaScript code. From b3d2e759a6b68bc00411ef8d0a1f573da15ddadc Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 28 Nov 2022 10:06:22 +0000 Subject: [PATCH 547/796] Swift: Update swift/sql-injection to include local flow sources. --- swift/ql/src/queries/Security/CWE-089/SqlInjection.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/src/queries/Security/CWE-089/SqlInjection.ql b/swift/ql/src/queries/Security/CWE-089/SqlInjection.ql index 3fab9759c6f..fcd6618658d 100644 --- a/swift/ql/src/queries/Security/CWE-089/SqlInjection.ql +++ b/swift/ql/src/queries/Security/CWE-089/SqlInjection.ql @@ -69,7 +69,7 @@ class SQLiteSwiftSqlSink extends SqlSink { class SqlInjectionConfig extends TaintTracking::Configuration { SqlInjectionConfig() { this = "SqlInjectionConfig" } - override predicate isSource(DataFlow::Node node) { node instanceof RemoteFlowSource } + override predicate isSource(DataFlow::Node node) { node instanceof FlowSource } override predicate isSink(DataFlow::Node node) { node instanceof SqlSink } } From e99571baaedf051df2209a5b386f02474106fc0c Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 28 Nov 2022 11:45:08 +0100 Subject: [PATCH 548/796] Update javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll Co-authored-by: Erik Krogh Kristensen --- .../frameworks/data/internal/ApiGraphModelsSpecific.qll | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll index 73a2fd28d0c..df8710c37e2 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll @@ -31,6 +31,13 @@ import semmle.javascript.frameworks.data.internal.AccessPathSyntax as AccessPath import JS::DataFlow as DataFlow private import AccessPathSyntax +/** + * Holds if `rawType` represents the JavaScript npm `package` with type `qualifiedName`. + * The `qualifiedName` is everything after the first ".". + * So e.g. `rawType = "foo.bar"` will parse to `package = "foo" and qualifiedName = "bar"`. + * `package´ can be enclosed in single-quotes if the package name includes dots, + * e.g. `'my.package'.type` parses to `package = "my.package" and qualifiedName = "type"`. + */ bindingset[rawType] predicate parseTypeString(string rawType, string package, string qualifiedName) { exists(string regexp | From 70d2a0df8af532b0422c13c9d46d93085c147d84 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 24 Nov 2022 14:46:59 +0100 Subject: [PATCH 549/796] Data flow: Track parameter position instead of parameter in pruning stages 2-4 --- .../ruby/dataflow/internal/DataFlowImpl.qll | 150 +++++++++++------- .../dataflow/internal/DataFlowImplCommon.qll | 18 +-- 2 files changed, 105 insertions(+), 63 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index bfdb6c9c9a3..13d7687c188 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,7 +1017,7 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } @@ -1102,6 +1119,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1132,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1152,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1266,15 +1285,16 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { exists(ReturnPosition pos | flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and kind = pos.getKind() and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() ) } @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,9 +1382,10 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or @@ -1372,7 +1393,7 @@ private module MkStage { fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1402,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1427,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1437,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1428,8 +1449,8 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx out, FlowState state, Cc ccOut, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { exists( DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, @@ -1445,14 +1466,18 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + exists( + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc + | + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1487,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,13 +1514,29 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, FlowState state, CcCall ccc, DataFlowCallable c, ParameterPosition ppos, + Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), _, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + pos = ret.getReturnPosition() and + parameterFlowThroughAllowed(p, pos.getKind()) + ) } pragma[nomagic] @@ -1506,7 +1547,7 @@ private module MkStage { flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, pragma[only_bind_into](config)) and fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), pragma[only_bind_into](argAp), _, + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, pragma[only_bind_into](config)) ) } @@ -1671,7 +1712,7 @@ private module MkStage { revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, returnPos.getKind()) ) } @@ -1763,13 +1804,13 @@ private module MkStage { ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config ) { revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, returnPos.getKind()) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and parameterFlowsThroughRev(p, ap, pos, config) ) } @@ -1777,7 +1818,7 @@ private module MkStage { pragma[nomagic] predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and parameterFlowsThroughRev(p, ap, pos, config) ) } @@ -1803,9 +1844,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -2555,12 +2595,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2569,9 +2610,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3504,7 +3546,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll index 621ed34f9d0..6a79e7eb6ce 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll @@ -916,9 +916,9 @@ private module Cached { TDataFlowCallSome(DataFlowCall call) cached - newtype TParamNodeOption = - TParamNodeNone() or - TParamNodeSome(ParamNode p) + newtype TParameterPositionOption = + TParameterPositionNone() or + TParameterPositionSome(ParameterPosition pos) cached newtype TReturnCtx = @@ -1315,15 +1315,15 @@ class DataFlowCallOption extends TDataFlowCallOption { } } -/** An optional `ParamNode`. */ -class ParamNodeOption extends TParamNodeOption { +/** An optional `ParameterPosition`. */ +class ParameterPositionOption extends TParameterPositionOption { string toString() { - this = TParamNodeNone() and + this = TParameterPositionNone() and result = "(none)" or - exists(ParamNode p | - this = TParamNodeSome(p) and - result = p.toString() + exists(ParameterPosition pos | + this = TParameterPositionSome(pos) and + result = pos.toString() ) } } From 4346a7f426f9f8781a97e5509596ad454d8d74bb Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 24 Nov 2022 14:48:30 +0100 Subject: [PATCH 550/796] Data flow: Inline `fwdFlowOutNotFromArg` --- .../ruby/dataflow/internal/DataFlowImpl.qll | 28 +++++++------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index 13d7687c188..911f2299bcc 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -1390,7 +1390,16 @@ private module MkStage { ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | @@ -1447,23 +1456,6 @@ private module MkStage { ) } - pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParameterPositionOption summaryCtx, ApOption argAp, - Ap ap, Configuration config - ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - pragma[nomagic] private predicate fwdFlowOutFromArg( DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, From bdb205a318618c4136cf0cfb116d98711c9250e9 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 24 Nov 2022 15:03:38 +0100 Subject: [PATCH 551/796] Data flow: Track return kind instead of return position in pruning stages 2-4 --- .../ruby/dataflow/internal/DataFlowImpl.qll | 118 +++++++++--------- .../dataflow/internal/DataFlowImplCommon.qll | 10 +- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index 911f2299bcc..89be164852f 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -1022,9 +1022,9 @@ private module Stage1 implements StageSig { } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1083,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1149,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1193,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1259,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1288,14 +1291,11 @@ private module MkStage { DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) and - c = ret.getEnclosingCallable() - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1507,12 +1507,12 @@ private module MkStage { pragma[nomagic] private predicate returnFlowsThrough0( - RetNodeEx ret, FlowState state, CcCall ccc, DataFlowCallable c, ParameterPosition ppos, - Ap argAp, Ap ap, Configuration config + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { exists(boolean allowsFieldFlow | fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and - flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), _, _, allowsFieldFlow, + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, pragma[only_bind_into](config)) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1520,14 +1520,13 @@ private module MkStage { pragma[nomagic] private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, Ap ap, Configuration config ) { exists(DataFlowCallable c, ParameterPosition ppos | - returnFlowsThrough0(ret, state, ccc, c, ppos, argAp, ap, config) and + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and p.isParameterOf(c, ppos) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1631,17 +1630,17 @@ private module MkStage { returnCtx = TReturnCtxNone() or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1674,12 +1673,12 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1697,14 +1696,15 @@ private module MkStage { pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p, returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1715,12 +1715,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1793,37 +1793,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p, returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -2027,10 +2027,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2546,11 +2546,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll index 6a79e7eb6ce..f981834a6d4 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll @@ -924,7 +924,7 @@ private module Cached { newtype TReturnCtx = TReturnCtxNone() or TReturnCtxNoFlowThrough() or - TReturnCtxMaybeFlowThrough(ReturnPosition pos) + TReturnCtxMaybeFlowThrough(ReturnKindExt kind) cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1335,7 +1335,7 @@ class ParameterPositionOption extends TParameterPositionOption { * * - `TReturnCtxNone()`: no return flow. * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. - * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * - `TReturnCtxMaybeFlowThrough(ReturnKindExt kind)`: return flow, of kind `kind`, and * flow through may be possible. */ class ReturnCtx extends TReturnCtx { @@ -1346,9 +1346,9 @@ class ReturnCtx extends TReturnCtx { this = TReturnCtxNoFlowThrough() and result = "(no flow through)" or - exists(ReturnPosition pos | - this = TReturnCtxMaybeFlowThrough(pos) and - result = pos.toString() + exists(ReturnKindExt kind | + this = TReturnCtxMaybeFlowThrough(kind) and + result = kind.toString() ) } } From c65780ee99cd015e496ee17aa3e9a3f732b7bb50 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 24 Nov 2022 15:06:54 +0100 Subject: [PATCH 552/796] Data flow: Inline `revFlowInNotToReturn` --- .../ruby/dataflow/internal/DataFlowImpl.qll | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index 89be164852f..e4cfd5986be 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -1626,8 +1626,12 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | @@ -1683,17 +1687,6 @@ private module MkStage { ) } - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - pragma[nomagic] private predicate revFlowInToReturn( DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, From cde05e11907827d753141da89d8f22cf7a267812 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 24 Nov 2022 15:07:45 +0100 Subject: [PATCH 553/796] Data flow: Sync files --- .../cpp/ir/dataflow/internal/DataFlowImpl.qll | 292 ++++++++++-------- .../ir/dataflow/internal/DataFlowImpl2.qll | 292 ++++++++++-------- .../ir/dataflow/internal/DataFlowImpl3.qll | 292 ++++++++++-------- .../ir/dataflow/internal/DataFlowImpl4.qll | 292 ++++++++++-------- .../dataflow/internal/DataFlowImplCommon.qll | 28 +- .../cpp/dataflow/internal/DataFlowImpl.qll | 292 ++++++++++-------- .../cpp/dataflow/internal/DataFlowImpl2.qll | 292 ++++++++++-------- .../cpp/dataflow/internal/DataFlowImpl3.qll | 292 ++++++++++-------- .../cpp/dataflow/internal/DataFlowImpl4.qll | 292 ++++++++++-------- .../dataflow/internal/DataFlowImplCommon.qll | 28 +- .../dataflow/internal/DataFlowImplLocal.qll | 292 ++++++++++-------- .../cpp/ir/dataflow/internal/DataFlowImpl.qll | 292 ++++++++++-------- .../ir/dataflow/internal/DataFlowImpl2.qll | 292 ++++++++++-------- .../ir/dataflow/internal/DataFlowImpl3.qll | 292 ++++++++++-------- .../ir/dataflow/internal/DataFlowImpl4.qll | 292 ++++++++++-------- .../dataflow/internal/DataFlowImplCommon.qll | 28 +- .../csharp/dataflow/internal/DataFlowImpl.qll | 292 ++++++++++-------- .../dataflow/internal/DataFlowImpl2.qll | 292 ++++++++++-------- .../dataflow/internal/DataFlowImpl3.qll | 292 ++++++++++-------- .../dataflow/internal/DataFlowImpl4.qll | 292 ++++++++++-------- .../dataflow/internal/DataFlowImpl5.qll | 292 ++++++++++-------- .../dataflow/internal/DataFlowImplCommon.qll | 28 +- .../DataFlowImplForContentDataFlow.qll | 292 ++++++++++-------- .../java/dataflow/internal/DataFlowImpl.qll | 292 ++++++++++-------- .../java/dataflow/internal/DataFlowImpl2.qll | 292 ++++++++++-------- .../java/dataflow/internal/DataFlowImpl3.qll | 292 ++++++++++-------- .../java/dataflow/internal/DataFlowImpl4.qll | 292 ++++++++++-------- .../java/dataflow/internal/DataFlowImpl5.qll | 292 ++++++++++-------- .../java/dataflow/internal/DataFlowImpl6.qll | 292 ++++++++++-------- .../dataflow/internal/DataFlowImplCommon.qll | 28 +- .../DataFlowImplForOnActivityResult.qll | 292 ++++++++++-------- .../DataFlowImplForSerializability.qll | 292 ++++++++++-------- .../dataflow/new/internal/DataFlowImpl.qll | 292 ++++++++++-------- .../dataflow/new/internal/DataFlowImpl2.qll | 292 ++++++++++-------- .../dataflow/new/internal/DataFlowImpl3.qll | 292 ++++++++++-------- .../dataflow/new/internal/DataFlowImpl4.qll | 292 ++++++++++-------- .../new/internal/DataFlowImplCommon.qll | 28 +- .../ruby/dataflow/internal/DataFlowImpl2.qll | 292 ++++++++++-------- .../DataFlowImplForHttpClientLibraries.qll | 292 ++++++++++-------- .../internal/DataFlowImplForPathname.qll | 292 ++++++++++-------- .../internal/DataFlowImplForRegExp.qll | 292 ++++++++++-------- .../swift/dataflow/internal/DataFlowImpl.qll | 292 ++++++++++-------- .../dataflow/internal/DataFlowImplCommon.qll | 28 +- 43 files changed, 5894 insertions(+), 4814 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index a52ad110662..e4cfd5986be 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index a52ad110662..e4cfd5986be 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index a52ad110662..e4cfd5986be 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index a52ad110662..e4cfd5986be 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll index 621ed34f9d0..f981834a6d4 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll @@ -916,15 +916,15 @@ private module Cached { TDataFlowCallSome(DataFlowCall call) cached - newtype TParamNodeOption = - TParamNodeNone() or - TParamNodeSome(ParamNode p) + newtype TParameterPositionOption = + TParameterPositionNone() or + TParameterPositionSome(ParameterPosition pos) cached newtype TReturnCtx = TReturnCtxNone() or TReturnCtxNoFlowThrough() or - TReturnCtxMaybeFlowThrough(ReturnPosition pos) + TReturnCtxMaybeFlowThrough(ReturnKindExt kind) cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1315,15 +1315,15 @@ class DataFlowCallOption extends TDataFlowCallOption { } } -/** An optional `ParamNode`. */ -class ParamNodeOption extends TParamNodeOption { +/** An optional `ParameterPosition`. */ +class ParameterPositionOption extends TParameterPositionOption { string toString() { - this = TParamNodeNone() and + this = TParameterPositionNone() and result = "(none)" or - exists(ParamNode p | - this = TParamNodeSome(p) and - result = p.toString() + exists(ParameterPosition pos | + this = TParameterPositionSome(pos) and + result = pos.toString() ) } } @@ -1335,7 +1335,7 @@ class ParamNodeOption extends TParamNodeOption { * * - `TReturnCtxNone()`: no return flow. * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. - * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * - `TReturnCtxMaybeFlowThrough(ReturnKindExt kind)`: return flow, of kind `kind`, and * flow through may be possible. */ class ReturnCtx extends TReturnCtx { @@ -1346,9 +1346,9 @@ class ReturnCtx extends TReturnCtx { this = TReturnCtxNoFlowThrough() and result = "(no flow through)" or - exists(ReturnPosition pos | - this = TReturnCtxMaybeFlowThrough(pos) and - result = pos.toString() + exists(ReturnKindExt kind | + this = TReturnCtxMaybeFlowThrough(kind) and + result = kind.toString() ) } } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index a52ad110662..e4cfd5986be 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index a52ad110662..e4cfd5986be 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index a52ad110662..e4cfd5986be 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index a52ad110662..e4cfd5986be 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll index 621ed34f9d0..f981834a6d4 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll @@ -916,15 +916,15 @@ private module Cached { TDataFlowCallSome(DataFlowCall call) cached - newtype TParamNodeOption = - TParamNodeNone() or - TParamNodeSome(ParamNode p) + newtype TParameterPositionOption = + TParameterPositionNone() or + TParameterPositionSome(ParameterPosition pos) cached newtype TReturnCtx = TReturnCtxNone() or TReturnCtxNoFlowThrough() or - TReturnCtxMaybeFlowThrough(ReturnPosition pos) + TReturnCtxMaybeFlowThrough(ReturnKindExt kind) cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1315,15 +1315,15 @@ class DataFlowCallOption extends TDataFlowCallOption { } } -/** An optional `ParamNode`. */ -class ParamNodeOption extends TParamNodeOption { +/** An optional `ParameterPosition`. */ +class ParameterPositionOption extends TParameterPositionOption { string toString() { - this = TParamNodeNone() and + this = TParameterPositionNone() and result = "(none)" or - exists(ParamNode p | - this = TParamNodeSome(p) and - result = p.toString() + exists(ParameterPosition pos | + this = TParameterPositionSome(pos) and + result = pos.toString() ) } } @@ -1335,7 +1335,7 @@ class ParamNodeOption extends TParamNodeOption { * * - `TReturnCtxNone()`: no return flow. * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. - * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * - `TReturnCtxMaybeFlowThrough(ReturnKindExt kind)`: return flow, of kind `kind`, and * flow through may be possible. */ class ReturnCtx extends TReturnCtx { @@ -1346,9 +1346,9 @@ class ReturnCtx extends TReturnCtx { this = TReturnCtxNoFlowThrough() and result = "(no flow through)" or - exists(ReturnPosition pos | - this = TReturnCtxMaybeFlowThrough(pos) and - result = pos.toString() + exists(ReturnKindExt kind | + this = TReturnCtxMaybeFlowThrough(kind) and + result = kind.toString() ) } } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index a52ad110662..e4cfd5986be 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index a52ad110662..e4cfd5986be 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index a52ad110662..e4cfd5986be 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index a52ad110662..e4cfd5986be 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index a52ad110662..e4cfd5986be 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll index 621ed34f9d0..f981834a6d4 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll @@ -916,15 +916,15 @@ private module Cached { TDataFlowCallSome(DataFlowCall call) cached - newtype TParamNodeOption = - TParamNodeNone() or - TParamNodeSome(ParamNode p) + newtype TParameterPositionOption = + TParameterPositionNone() or + TParameterPositionSome(ParameterPosition pos) cached newtype TReturnCtx = TReturnCtxNone() or TReturnCtxNoFlowThrough() or - TReturnCtxMaybeFlowThrough(ReturnPosition pos) + TReturnCtxMaybeFlowThrough(ReturnKindExt kind) cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1315,15 +1315,15 @@ class DataFlowCallOption extends TDataFlowCallOption { } } -/** An optional `ParamNode`. */ -class ParamNodeOption extends TParamNodeOption { +/** An optional `ParameterPosition`. */ +class ParameterPositionOption extends TParameterPositionOption { string toString() { - this = TParamNodeNone() and + this = TParameterPositionNone() and result = "(none)" or - exists(ParamNode p | - this = TParamNodeSome(p) and - result = p.toString() + exists(ParameterPosition pos | + this = TParameterPositionSome(pos) and + result = pos.toString() ) } } @@ -1335,7 +1335,7 @@ class ParamNodeOption extends TParamNodeOption { * * - `TReturnCtxNone()`: no return flow. * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. - * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * - `TReturnCtxMaybeFlowThrough(ReturnKindExt kind)`: return flow, of kind `kind`, and * flow through may be possible. */ class ReturnCtx extends TReturnCtx { @@ -1346,9 +1346,9 @@ class ReturnCtx extends TReturnCtx { this = TReturnCtxNoFlowThrough() and result = "(no flow through)" or - exists(ReturnPosition pos | - this = TReturnCtxMaybeFlowThrough(pos) and - result = pos.toString() + exists(ReturnKindExt kind | + this = TReturnCtxMaybeFlowThrough(kind) and + result = kind.toString() ) } } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index a52ad110662..e4cfd5986be 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index a52ad110662..e4cfd5986be 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index a52ad110662..e4cfd5986be 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index a52ad110662..e4cfd5986be 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index a52ad110662..e4cfd5986be 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll index 621ed34f9d0..f981834a6d4 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll @@ -916,15 +916,15 @@ private module Cached { TDataFlowCallSome(DataFlowCall call) cached - newtype TParamNodeOption = - TParamNodeNone() or - TParamNodeSome(ParamNode p) + newtype TParameterPositionOption = + TParameterPositionNone() or + TParameterPositionSome(ParameterPosition pos) cached newtype TReturnCtx = TReturnCtxNone() or TReturnCtxNoFlowThrough() or - TReturnCtxMaybeFlowThrough(ReturnPosition pos) + TReturnCtxMaybeFlowThrough(ReturnKindExt kind) cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1315,15 +1315,15 @@ class DataFlowCallOption extends TDataFlowCallOption { } } -/** An optional `ParamNode`. */ -class ParamNodeOption extends TParamNodeOption { +/** An optional `ParameterPosition`. */ +class ParameterPositionOption extends TParameterPositionOption { string toString() { - this = TParamNodeNone() and + this = TParameterPositionNone() and result = "(none)" or - exists(ParamNode p | - this = TParamNodeSome(p) and - result = p.toString() + exists(ParameterPosition pos | + this = TParameterPositionSome(pos) and + result = pos.toString() ) } } @@ -1335,7 +1335,7 @@ class ParamNodeOption extends TParamNodeOption { * * - `TReturnCtxNone()`: no return flow. * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. - * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * - `TReturnCtxMaybeFlowThrough(ReturnKindExt kind)`: return flow, of kind `kind`, and * flow through may be possible. */ class ReturnCtx extends TReturnCtx { @@ -1346,9 +1346,9 @@ class ReturnCtx extends TReturnCtx { this = TReturnCtxNoFlowThrough() and result = "(no flow through)" or - exists(ReturnPosition pos | - this = TReturnCtxMaybeFlowThrough(pos) and - result = pos.toString() + exists(ReturnKindExt kind | + this = TReturnCtxMaybeFlowThrough(kind) and + result = kind.toString() ) } } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll index a52ad110662..e4cfd5986be 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index a52ad110662..e4cfd5986be 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index a52ad110662..e4cfd5986be 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index a52ad110662..e4cfd5986be 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index a52ad110662..e4cfd5986be 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index a52ad110662..e4cfd5986be 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index a52ad110662..e4cfd5986be 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll index 621ed34f9d0..f981834a6d4 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll @@ -916,15 +916,15 @@ private module Cached { TDataFlowCallSome(DataFlowCall call) cached - newtype TParamNodeOption = - TParamNodeNone() or - TParamNodeSome(ParamNode p) + newtype TParameterPositionOption = + TParameterPositionNone() or + TParameterPositionSome(ParameterPosition pos) cached newtype TReturnCtx = TReturnCtxNone() or TReturnCtxNoFlowThrough() or - TReturnCtxMaybeFlowThrough(ReturnPosition pos) + TReturnCtxMaybeFlowThrough(ReturnKindExt kind) cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1315,15 +1315,15 @@ class DataFlowCallOption extends TDataFlowCallOption { } } -/** An optional `ParamNode`. */ -class ParamNodeOption extends TParamNodeOption { +/** An optional `ParameterPosition`. */ +class ParameterPositionOption extends TParameterPositionOption { string toString() { - this = TParamNodeNone() and + this = TParameterPositionNone() and result = "(none)" or - exists(ParamNode p | - this = TParamNodeSome(p) and - result = p.toString() + exists(ParameterPosition pos | + this = TParameterPositionSome(pos) and + result = pos.toString() ) } } @@ -1335,7 +1335,7 @@ class ParamNodeOption extends TParamNodeOption { * * - `TReturnCtxNone()`: no return flow. * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. - * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * - `TReturnCtxMaybeFlowThrough(ReturnKindExt kind)`: return flow, of kind `kind`, and * flow through may be possible. */ class ReturnCtx extends TReturnCtx { @@ -1346,9 +1346,9 @@ class ReturnCtx extends TReturnCtx { this = TReturnCtxNoFlowThrough() and result = "(no flow through)" or - exists(ReturnPosition pos | - this = TReturnCtxMaybeFlowThrough(pos) and - result = pos.toString() + exists(ReturnKindExt kind | + this = TReturnCtxMaybeFlowThrough(kind) and + result = kind.toString() ) } } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll index a52ad110662..e4cfd5986be 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll index a52ad110662..e4cfd5986be 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll index a52ad110662..e4cfd5986be 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll index a52ad110662..e4cfd5986be 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll index a52ad110662..e4cfd5986be 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll index a52ad110662..e4cfd5986be 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll index 621ed34f9d0..f981834a6d4 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll @@ -916,15 +916,15 @@ private module Cached { TDataFlowCallSome(DataFlowCall call) cached - newtype TParamNodeOption = - TParamNodeNone() or - TParamNodeSome(ParamNode p) + newtype TParameterPositionOption = + TParameterPositionNone() or + TParameterPositionSome(ParameterPosition pos) cached newtype TReturnCtx = TReturnCtxNone() or TReturnCtxNoFlowThrough() or - TReturnCtxMaybeFlowThrough(ReturnPosition pos) + TReturnCtxMaybeFlowThrough(ReturnKindExt kind) cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1315,15 +1315,15 @@ class DataFlowCallOption extends TDataFlowCallOption { } } -/** An optional `ParamNode`. */ -class ParamNodeOption extends TParamNodeOption { +/** An optional `ParameterPosition`. */ +class ParameterPositionOption extends TParameterPositionOption { string toString() { - this = TParamNodeNone() and + this = TParameterPositionNone() and result = "(none)" or - exists(ParamNode p | - this = TParamNodeSome(p) and - result = p.toString() + exists(ParameterPosition pos | + this = TParameterPositionSome(pos) and + result = pos.toString() ) } } @@ -1335,7 +1335,7 @@ class ParamNodeOption extends TParamNodeOption { * * - `TReturnCtxNone()`: no return flow. * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. - * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * - `TReturnCtxMaybeFlowThrough(ReturnKindExt kind)`: return flow, of kind `kind`, and * flow through may be possible. */ class ReturnCtx extends TReturnCtx { @@ -1346,9 +1346,9 @@ class ReturnCtx extends TReturnCtx { this = TReturnCtxNoFlowThrough() and result = "(no flow through)" or - exists(ReturnPosition pos | - this = TReturnCtxMaybeFlowThrough(pos) and - result = pos.toString() + exists(ReturnKindExt kind | + this = TReturnCtxMaybeFlowThrough(kind) and + result = kind.toString() ) } } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll index a52ad110662..e4cfd5986be 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll index a52ad110662..e4cfd5986be 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll index a52ad110662..e4cfd5986be 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll index a52ad110662..e4cfd5986be 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index a52ad110662..e4cfd5986be 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -613,11 +613,28 @@ private predicate hasSinkCallCtx(Configuration config) { * explicitly allowed */ bindingset[p, kind] -private predicate parameterFlowThroughAllowed(ParamNode p, ReturnKindExt kind) { +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { exists(ParameterPosition pos | p.isParameterOf(_, pos) | not kind.(ParamUpdateReturnKind).getPosition() = pos or - allowParameterReturnInSelfCached(p) + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1000,14 +1017,14 @@ private module Stage1 implements StageSig { returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - parameterFlowThroughAllowed(p.asNode(), kind) + parameterFlowThroughAllowed(p, kind) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { throughFlowNodeCand(ret, config) and - pos = ret.getReturnPosition() + kind = ret.getKind() } pragma[nomagic] @@ -1066,13 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, pos, out, config) and - pos = ret.getReturnPosition() and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1102,6 +1122,7 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | @@ -1114,6 +1135,7 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | @@ -1130,10 +1152,10 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, ret, pos, out, pragma[only_bind_into](config)) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | b = branch(ret, pragma[only_bind_into](config)) and j = join(out, pragma[only_bind_into](config)) and @@ -1152,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1174,7 +1196,7 @@ private signature module StageSig { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1240,7 +1262,7 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, Configuration config ); @@ -1266,16 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - exists(ReturnPosition pos | - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, pragma[only_bind_into](config)) and - kind = pos.getKind() and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::returnMayFlowThrough(ret, pos, pragma[only_bind_into](config)) and - matchesCall(ccc, call) - ) + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1284,12 +1304,12 @@ private module MkStage { * * The call context `cc` records whether the node is reached through an * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter and access path of that argument, respectively. + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and @@ -1298,13 +1318,13 @@ private module MkStage { pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, - Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | @@ -1322,7 +1342,7 @@ private module MkStage { fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or @@ -1330,7 +1350,7 @@ private module MkStage { fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1339,7 +1359,7 @@ private module MkStage { fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) @@ -1362,17 +1382,27 @@ private module MkStage { apa = getApprox(ap) and if PrevStage::parameterMayFlowThrough(node, apa, config) then ( - summaryCtx = TParamNodeSome(node.asNode()) and argAp = apSome(ap) + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) ) else ( - summaryCtx = TParamNodeNone() and argAp = apNone() + summaryCtx = TParameterPositionNone() and argAp = apNone() ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, summaryCtx, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or // flow through a callable - exists(DataFlowCall call, ParamNode summaryCtx0, Ap argAp0 | + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) @@ -1381,7 +1411,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and @@ -1406,7 +1436,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and @@ -1416,7 +1446,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowIn( DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, - ParamNodeOption summaryCtx, ApOption argAp, Ap ap, Configuration config + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and @@ -1427,32 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and - flowOutOfCall(call, ret, _, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, ParamNode summaryCtx, Ap argAp, Ap ap, - Configuration config - ) { - exists(RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, TParamNodeSome(summaryCtx), apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, kind, out, allowsFieldFlow, config) and + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(summaryCtx, kind) + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1462,13 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ParamNode p, Ap ap, - Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { exists(ParamNodeEx param | fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and - p = param.asNode() + pos = param.getPosition() ) } @@ -1489,23 +1506,41 @@ private module MkStage { } pragma[nomagic] - private predicate returnFlowsThrough( - RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNode p, Ap argAp, Ap ap, - Configuration config + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config ) { - fwdFlow(ret, state, ccc, TParamNodeSome(p), apSome(argAp), ap, config) and - pos = ret.getReturnPosition() and - parameterFlowThroughAllowed(p, pos.getKind()) + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) + ) } pragma[nomagic] private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, - pragma[only_bind_into](config)) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](config)) and - returnFlowsThrough(_, _, _, _, p.asNode(), _, _, pragma[only_bind_into](config)) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** @@ -1591,21 +1626,25 @@ private module MkStage { ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - returnCtx = TReturnCtxNone() + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or // flow through a callable - exists(DataFlowCall call, ReturnPosition returnPos0, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - exists(ReturnPosition pos | - revFlowOut(_, node, pos, state, _, _, ap, config) and - if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) then ( - returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnCtx = TReturnCtxMaybeFlowThrough(kind) and returnAp = apSome(ap) ) else ( returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() @@ -1638,37 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | revFlow(out, state, returnCtx, returnAp, ap, config) and - flowOutOfCall(call, ret, pos, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnPosition returnPos, Ap returnAp, - Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, TReturnCtxMaybeFlowThrough(returnPos), apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + parameterFlowThroughAllowed(p, kind) ) } @@ -1679,12 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and - returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1757,37 +1786,37 @@ private module MkStage { pragma[nomagic] private predicate parameterFlowsThroughRev( - ParamNodeEx p, Ap ap, ReturnPosition returnPos, Configuration config + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, TReturnCtxMaybeFlowThrough(returnPos), apSome(_), ap, config) and - parameterFlowThroughAllowed(p.asNode(), returnPos.getKind()) + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { - exists(RetNodeEx ret, ReturnPosition pos | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, ReturnPosition pos, Configuration config) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { exists(ParamNodeEx p, Ap ap | - returnFlowsThrough(ret, pos, _, _, p.asNode(), ap, _, config) and - parameterFlowsThroughRev(p, ap, pos, config) + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - ReturnPosition returnPos0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnPos0, returnAp0, ap, config) and - revFlowIsReturned(call, returnCtx, returnAp, returnPos0, returnAp0, config) + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1800,9 +1829,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1992,10 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCallNodeCand1(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2511,11 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, ReturnPosition pos, NodeEx node2, boolean allowsFieldFlow, + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, pos, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2552,12 +2580,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(p, _, _) and + c = n.getEnclosingCallable() and Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), TAccessPathApproxSome(apa), apa0, config) ) } @@ -2566,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(ParamNodeEx p | + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | Stage4::parameterMayFlowThrough(p, apa, config) and - nodeMayUseSummary0(n, p, state, apa, config) + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -3501,7 +3531,7 @@ private predicate paramFlowsThrough( pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode().asNode(), kind) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll index 621ed34f9d0..f981834a6d4 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll @@ -916,15 +916,15 @@ private module Cached { TDataFlowCallSome(DataFlowCall call) cached - newtype TParamNodeOption = - TParamNodeNone() or - TParamNodeSome(ParamNode p) + newtype TParameterPositionOption = + TParameterPositionNone() or + TParameterPositionSome(ParameterPosition pos) cached newtype TReturnCtx = TReturnCtxNone() or TReturnCtxNoFlowThrough() or - TReturnCtxMaybeFlowThrough(ReturnPosition pos) + TReturnCtxMaybeFlowThrough(ReturnKindExt kind) cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1315,15 +1315,15 @@ class DataFlowCallOption extends TDataFlowCallOption { } } -/** An optional `ParamNode`. */ -class ParamNodeOption extends TParamNodeOption { +/** An optional `ParameterPosition`. */ +class ParameterPositionOption extends TParameterPositionOption { string toString() { - this = TParamNodeNone() and + this = TParameterPositionNone() and result = "(none)" or - exists(ParamNode p | - this = TParamNodeSome(p) and - result = p.toString() + exists(ParameterPosition pos | + this = TParameterPositionSome(pos) and + result = pos.toString() ) } } @@ -1335,7 +1335,7 @@ class ParamNodeOption extends TParamNodeOption { * * - `TReturnCtxNone()`: no return flow. * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. - * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * - `TReturnCtxMaybeFlowThrough(ReturnKindExt kind)`: return flow, of kind `kind`, and * flow through may be possible. */ class ReturnCtx extends TReturnCtx { @@ -1346,9 +1346,9 @@ class ReturnCtx extends TReturnCtx { this = TReturnCtxNoFlowThrough() and result = "(no flow through)" or - exists(ReturnPosition pos | - this = TReturnCtxMaybeFlowThrough(pos) and - result = pos.toString() + exists(ReturnKindExt kind | + this = TReturnCtxMaybeFlowThrough(kind) and + result = kind.toString() ) } } From 7a3898168f54e9c4c161c9d83ea81a000ac6bd64 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 28 Nov 2022 12:12:36 +0100 Subject: [PATCH 554/796] Update README.md --- javascript/extractor/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/extractor/README.md b/javascript/extractor/README.md index e9495dd21ec..cf26d9db784 100644 --- a/javascript/extractor/README.md +++ b/javascript/extractor/README.md @@ -2,8 +2,8 @@ This directory contains the source code of the JavaScript extractor. The extractor depends on various libraries that are not currently bundled with the source code, so at present it cannot be built in isolation. -The extractor consists of a parser for the latest version of ECMAScript, including a few proposed and historic extensions (see `src/com/semmle/jcorn`), classes for representing JavaScript and TypeScript ASTs (`src/com/semmle/js/ast` and `src/com/semmle/ts/ast`), and various other bits of functionality. Historically, the main entry point of the JavaScript extractor has been `com.semmle.js.extractor.Main`. However, this class is slowly being phased out in favour of `com.semmle.js.extractor.AutoBuild`, which is the entry point used by LGTM. +The extractor consists of a parser for the latest version of ECMAScript, including a few proposed and historic extensions (see `src/com/semmle/jcorn`), classes for representing JavaScript and TypeScript ASTs (`src/com/semmle/js/ast` and `src/com/semmle/ts/ast`), and various other bits of functionality. Historically, the main entry point of the JavaScript extractor has been `com.semmle.js.extractor.Main`. However, this class is slowly being phased out in favour of `com.semmle.js.extractor.AutoBuild`, which is the entry point used by CodeQL. ## License -Like the LGTM queries, the JavaScript extractor is licensed under [Apache License 2.0](LICENSE) by [GitHub](https://github.com). Some code is derived from other projects, whose licenses are noted in other `LICENSE-*.md` files in this folder. +Like the CodeQL queries, the JavaScript extractor is licensed under [Apache License 2.0](LICENSE) by [GitHub](https://github.com). Some code is derived from other projects, whose licenses are noted in other `LICENSE-*.md` files in this folder. From 663112576a517aa8bf73d5a3cee7299086baaa6d Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 14 Nov 2022 09:57:30 +0100 Subject: [PATCH 555/796] Java: Update commons-io models. --- .../ql/lib/semmle/code/java/frameworks/apache/IOGenerated.qll | 4 ++++ .../code/java/frameworks/apache/NegativeIOGenerated.qll | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/IOGenerated.qll b/java/ql/lib/semmle/code/java/frameworks/apache/IOGenerated.qll index 931764d56d8..db1ed1bea58 100644 --- a/java/ql/lib/semmle/code/java/frameworks/apache/IOGenerated.qll +++ b/java/ql/lib/semmle/code/java/frameworks/apache/IOGenerated.qll @@ -540,6 +540,7 @@ private class IOGeneratedSummaryCsv extends SummaryModelCsv { "org.apache.commons.io;DirectoryWalker$CancelException;true;getFile;();;Argument[-1];ReturnValue;taint;generated", "org.apache.commons.io;FileCleaningTracker;true;getDeleteFailures;();;Argument[-1];ReturnValue;taint;generated", "org.apache.commons.io;FileDeleteStrategy;true;toString;();;Argument[-1];ReturnValue;taint;generated", + "org.apache.commons.io;FileSystem;false;normalizeSeparators;(String);;Argument[0];ReturnValue;taint;generated", "org.apache.commons.io;FileSystem;false;toLegalFileName;(String,char);;Argument[0];ReturnValue;taint;generated", "org.apache.commons.io;FileUtils;true;checksum;(File,Checksum);;Argument[1];ReturnValue;taint;generated", "org.apache.commons.io;FileUtils;true;convertFileCollectionToFileArray;(Collection);;Argument[0].Element;ReturnValue;taint;generated", @@ -563,6 +564,9 @@ private class IOGeneratedSummaryCsv extends SummaryModelCsv { "org.apache.commons.io;FilenameUtils;true;normalizeNoEndSeparator;(String);;Argument[0];ReturnValue;taint;generated", "org.apache.commons.io;FilenameUtils;true;normalizeNoEndSeparator;(String,boolean);;Argument[0];ReturnValue;taint;generated", "org.apache.commons.io;FilenameUtils;true;removeExtension;(String);;Argument[0];ReturnValue;taint;generated", + "org.apache.commons.io;FilenameUtils;true;separatorsToSystem;(String);;Argument[0];ReturnValue;taint;generated", + "org.apache.commons.io;FilenameUtils;true;separatorsToUnix;(String);;Argument[0];ReturnValue;taint;generated", + "org.apache.commons.io;FilenameUtils;true;separatorsToWindows;(String);;Argument[0];ReturnValue;taint;generated", "org.apache.commons.io;IOExceptionList;true;IOExceptionList;(List);;Argument[0].Element;Argument[-1];taint;generated", "org.apache.commons.io;IOExceptionList;true;IOExceptionList;(String,List);;Argument[1].Element;Argument[-1];taint;generated", "org.apache.commons.io;IOExceptionList;true;getCause;(int);;Argument[-1];ReturnValue;taint;generated", diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/NegativeIOGenerated.qll b/java/ql/lib/semmle/code/java/frameworks/apache/NegativeIOGenerated.qll index 4a9a6394aaf..8c2e0684942 100644 --- a/java/ql/lib/semmle/code/java/frameworks/apache/NegativeIOGenerated.qll +++ b/java/ql/lib/semmle/code/java/frameworks/apache/NegativeIOGenerated.qll @@ -506,7 +506,6 @@ private class IOGeneratedNegativesummaryCsv extends NegativeSummaryModelCsv { "org.apache.commons.io;FileSystem;isCaseSensitive;();generated", "org.apache.commons.io;FileSystem;isLegalFileName;(CharSequence);generated", "org.apache.commons.io;FileSystem;isReservedFileName;(CharSequence);generated", - "org.apache.commons.io;FileSystem;normalizeSeparators;(String);generated", "org.apache.commons.io;FileSystem;supportsDriveLetter;();generated", "org.apache.commons.io;FileSystemUtils;FileSystemUtils;();generated", "org.apache.commons.io;FileSystemUtils;freeSpace;(String);generated", @@ -652,9 +651,6 @@ private class IOGeneratedNegativesummaryCsv extends NegativeSummaryModelCsv { "org.apache.commons.io;FilenameUtils;isExtension;(String,Collection);generated", "org.apache.commons.io;FilenameUtils;isExtension;(String,String);generated", "org.apache.commons.io;FilenameUtils;isExtension;(String,String[]);generated", - "org.apache.commons.io;FilenameUtils;separatorsToSystem;(String);generated", - "org.apache.commons.io;FilenameUtils;separatorsToUnix;(String);generated", - "org.apache.commons.io;FilenameUtils;separatorsToWindows;(String);generated", "org.apache.commons.io;FilenameUtils;wildcardMatch;(String,String);generated", "org.apache.commons.io;FilenameUtils;wildcardMatch;(String,String,IOCase);generated", "org.apache.commons.io;FilenameUtils;wildcardMatchOnSystem;(String,String);generated", From a8ee8783561588681862bb40f3a6ea4e3e513941 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 14 Nov 2022 10:52:55 +0100 Subject: [PATCH 556/796] Java: Add bi-directional import of FragmentInjection. --- java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 8460c662d5c..a6f9e2b17c7 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -135,6 +135,7 @@ private module Frameworks { private import semmle.code.java.security.ResponseSplitting private import semmle.code.java.security.InformationLeak private import semmle.code.java.security.Files + private import semmle.code.java.security.FragmentInjection private import semmle.code.java.security.GroovyInjection private import semmle.code.java.security.ImplicitPendingIntents private import semmle.code.java.security.JexlInjectionSinkModels @@ -613,7 +614,8 @@ module CsvValidation { "open-url", "jndi-injection", "ldap", "sql", "jdbc-url", "logging", "mvel", "xpath", "groovy", "xss", "ognl-injection", "intent-start", "pending-intent-sent", "url-open-stream", "url-redirect", "create-file", "write-file", "set-hostname-verifier", - "header-splitting", "information-leak", "xslt", "jexl", "bean-validation", "ssti" + "header-splitting", "information-leak", "xslt", "jexl", "bean-validation", "ssti", + "fragment-injection" ] and not kind.matches("regex-use%") and not kind.matches("qltest%") and From 9f7103c4fb583279a1538c7ca486e81d2e3f2c61 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 14 Nov 2022 11:08:09 +0100 Subject: [PATCH 557/796] Java: Add queries for extracting sources, sinks and summaries. --- .../ql/src/utils/modelconverter/ExtractSinks.ql | 17 +++++++++++++++++ .../src/utils/modelconverter/ExtractSources.ql | 17 +++++++++++++++++ .../utils/modelconverter/ExtractSummaries.ql | 17 +++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 java/ql/src/utils/modelconverter/ExtractSinks.ql create mode 100644 java/ql/src/utils/modelconverter/ExtractSources.ql create mode 100644 java/ql/src/utils/modelconverter/ExtractSummaries.ql diff --git a/java/ql/src/utils/modelconverter/ExtractSinks.ql b/java/ql/src/utils/modelconverter/ExtractSinks.ql new file mode 100644 index 00000000000..cbfd4f7cebb --- /dev/null +++ b/java/ql/src/utils/modelconverter/ExtractSinks.ql @@ -0,0 +1,17 @@ +/** + * @name Extract MaD sink model rows. + * @description This extracts the Models as data sink model rows. + * @id java/utils/modelconverter/generate-data-extensions-sink + */ + +import java +import semmle.code.java.dataflow.ExternalFlow + +from + string package, string type, boolean subtypes, string name, string signature, string ext, + string input, string kind, string provenance +where + sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance) and + provenance != "generated" +select package, type, subtypes, name, signature, ext, input, kind, provenance order by + package, type, name, signature, input, kind diff --git a/java/ql/src/utils/modelconverter/ExtractSources.ql b/java/ql/src/utils/modelconverter/ExtractSources.ql new file mode 100644 index 00000000000..b74a97e3728 --- /dev/null +++ b/java/ql/src/utils/modelconverter/ExtractSources.ql @@ -0,0 +1,17 @@ +/** + * @name Extract MaD source model rows. + * @description This extracts the Models as data source model rows. + * @id java/utils/modelconverter/generate-data-extensions-source + */ + +import java +import semmle.code.java.dataflow.ExternalFlow + +from + string package, string type, boolean subtypes, string name, string signature, string ext, + string output, string kind, string provenance +where + sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance) and + provenance != "generated" +select package, type, subtypes, name, signature, ext, output, kind, provenance order by + package, type, name, signature, output, kind diff --git a/java/ql/src/utils/modelconverter/ExtractSummaries.ql b/java/ql/src/utils/modelconverter/ExtractSummaries.ql new file mode 100644 index 00000000000..65af62b3259 --- /dev/null +++ b/java/ql/src/utils/modelconverter/ExtractSummaries.ql @@ -0,0 +1,17 @@ +/** + * @name Extract MaD summary model rows. + * @description This extracts the Models as data summary model rows. + * @id java/utils/modelconverter/generate-data-extensions-summary + */ + +import java +import semmle.code.java.dataflow.ExternalFlow + +from + string package, string type, boolean subtypes, string name, string signature, string ext, + string input, string output, string kind, string provenance +where + summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) and + provenance != "generated" +select package, type, subtypes, name, signature, ext, input, output, kind, provenance order by + package, type, name, signature, input, output, kind From fc4b9827b9b7754139f51a9c8e2c2039f5a8a90a Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 14 Nov 2022 11:38:40 +0100 Subject: [PATCH 558/796] Java: Add script for converting extensions. --- .../utils/modelconverter/ConvertExtensions.py | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 java/ql/src/utils/modelconverter/ConvertExtensions.py diff --git a/java/ql/src/utils/modelconverter/ConvertExtensions.py b/java/ql/src/utils/modelconverter/ConvertExtensions.py new file mode 100644 index 00000000000..c2d2e7b2e09 --- /dev/null +++ b/java/ql/src/utils/modelconverter/ConvertExtensions.py @@ -0,0 +1,41 @@ +# Tool to generate data extensions files based on the existing models. +# Usage: +# python3 ConvertExtensions.py +# (1) A folder named `java/ql/lib/ext` will be created, if it doesn't already exist. +# (2) The converted models will be written to `java/ql/lib/ext`. One file for each namespace. + +import os +import subprocess +import sys +import tempfile + +# Add Models as Data script directory to sys.path. +gitroot = subprocess.check_output(["git", "rev-parse", "--show-toplevel"]).decode("utf-8").strip() +madpath = os.path.join(gitroot, "misc/scripts/models-as-data/") +sys.path.append(madpath) + +import helpers +import convert_extensions as extensions + +print('Running script to generate data extensions files from the existing MaD models.') +print('Making a dummy database.') + +# Configuration +language = "java" +workDir = tempfile.mkdtemp() +projectDir = os.path.join(workDir, "project") +emptyFile = os.path.join(workDir, "Empty.java") +dbDir = os.path.join(workDir, "db") + +# Make dummy project +with open(emptyFile, "w") as f: + f.write("class Empty {}") +helpers.run_cmd(['codeql', 'database', 'create', f'--language={language}', '-c', f'javac {emptyFile}', dbDir], "Failed to create dummy database.") + +print('Converting data extensions for Java.') +extensions.Converter(language, dbDir).run() + +print('Cleanup.') +# Cleanup - delete database. +helpers.remove_dir(dbDir) +print('Done.') \ No newline at end of file From 63e2206d16bed2e4951562fdd4af32a2d03e9332 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 14 Nov 2022 12:20:49 +0100 Subject: [PATCH 559/796] Java: Prepare QL pack for data extensions. --- java/ql/lib/qlpack.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index dfab979e9bd..ed5323ebe4a 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -6,4 +6,7 @@ extractor: java library: true upgrades: upgrades dependencies: - codeql/regex: ${workspace} \ No newline at end of file + codeql/regex: ${workspace} +dataExtensions: + - ext/*.model.yml + - ext/generated/*.model.yml From 7b6f202f23d3507f42d8375bb151958b6db43989 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 14 Nov 2022 12:51:27 +0100 Subject: [PATCH 560/796] Java: Renaming. --- .../code/java/dataflow/ExternalFlow.qll | 81 ++++++++++--------- .../external-models/negativesummaries.ql | 2 +- .../dataflow/external-models/sinks.ql | 2 +- .../dataflow/external-models/srcs.ql | 2 +- .../dataflow/external-models/steps.ql | 2 +- .../dataflow/synth-global/test.ql | 2 +- 6 files changed, 46 insertions(+), 45 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index a6f9e2b17c7..4d1d93c062c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -1,22 +1,23 @@ /** * INTERNAL use only. This is an experimental API subject to change without notice. * - * Provides classes and predicates for dealing with flow models specified in CSV format. + * Provides classes and predicates for dealing with flow models specified + * in data extensions and CSV format. * * The CSV specification has the following columns: * - Sources: - * `namespace; type; subtypes; name; signature; ext; output; kind; provenance` + * `package; type; subtypes; name; signature; ext; output; kind; provenance` * - Sinks: - * `namespace; type; subtypes; name; signature; ext; input; kind; provenance` + * `package; type; subtypes; name; signature; ext; input; kind; provenance` * - Summaries: - * `namespace; type; subtypes; name; signature; ext; input; output; kind; provenance` + * `package; type; subtypes; name; signature; ext; input; output; kind; provenance` * - Negative Summaries: - * `namespace; type; name; signature; provenance` + * `package; type; name; signature; provenance` * A negative summary is used to indicate that there is no flow via a callable. * * The interpretation of a row is similar to API-graphs with a left-to-right * reading. - * 1. The `namespace` column selects a package. + * 1. The `package` column selects a package. * 2. The `type` column selects a type within that package. * 3. The `subtypes` is a boolean that indicates whether to jump to an * arbitrary subtype of that type. @@ -433,12 +434,12 @@ predicate negativeSummaryModel(string row) { any(NegativeSummaryModelCsv s).row( /** Holds if a source model exists for the given parameters. */ predicate sourceModel( - string namespace, string type, boolean subtypes, string name, string signature, string ext, + string package, string type, boolean subtypes, string name, string signature, string ext, string output, string kind, string provenance ) { exists(string row | sourceModel(row) and - row.splitAt(";", 0) = namespace and + row.splitAt(";", 0) = package and row.splitAt(";", 1) = type and row.splitAt(";", 2) = subtypes.toString() and subtypes = [true, false] and @@ -453,12 +454,12 @@ predicate sourceModel( /** Holds if a sink model exists for the given parameters. */ predicate sinkModel( - string namespace, string type, boolean subtypes, string name, string signature, string ext, + string package, string type, boolean subtypes, string name, string signature, string ext, string input, string kind, string provenance ) { exists(string row | sinkModel(row) and - row.splitAt(";", 0) = namespace and + row.splitAt(";", 0) = package and row.splitAt(";", 1) = type and row.splitAt(";", 2) = subtypes.toString() and subtypes = [true, false] and @@ -473,19 +474,19 @@ predicate sinkModel( /** Holds if a summary model exists for the given parameters. */ predicate summaryModel( - string namespace, string type, boolean subtypes, string name, string signature, string ext, + string package, string type, boolean subtypes, string name, string signature, string ext, string input, string output, string kind, string provenance ) { - summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance, _) + summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance, _) } /** Holds if a summary model `row` exists for the given parameters. */ predicate summaryModel( - string namespace, string type, boolean subtypes, string name, string signature, string ext, + string package, string type, boolean subtypes, string name, string signature, string ext, string input, string output, string kind, string provenance, string row ) { summaryModel(row) and - row.splitAt(";", 0) = namespace and + row.splitAt(";", 0) = package and row.splitAt(";", 1) = type and row.splitAt(";", 2) = subtypes.toString() and subtypes = [true, false] and @@ -500,11 +501,11 @@ predicate summaryModel( /** Holds if a summary model exists indicating there is no flow for the given parameters. */ predicate negativeSummaryModel( - string namespace, string type, string name, string signature, string provenance + string package, string type, string name, string signature, string provenance ) { exists(string row | negativeSummaryModel(row) and - row.splitAt(";", 0) = namespace and + row.splitAt(";", 0) = package and row.splitAt(";", 1) = type and row.splitAt(";", 2) = name and row.splitAt(";", 3) = signature and @@ -534,7 +535,7 @@ private predicate canonicalPkgLink(string package, string subpkg) { } /** - * Holds if CSV framework coverage of `package` is `n` api endpoints of the + * Holds if MaD framework coverage of `package` is `n` api endpoints of the * kind `(kind, part)`. */ predicate modelCoverage(string package, int pkgs, string kind, string part, int n) { @@ -566,8 +567,8 @@ predicate modelCoverage(string package, int pkgs, string kind, string part, int ) } -/** Provides a query predicate to check the CSV data for validation errors. */ -module CsvValidation { +/** Provides a query predicate to check the MaD models for validation errors. */ +module ModelValidation { private string getInvalidModelInput() { exists(string pred, string input, string part | sinkModel(_, _, _, _, _, _, input, _, _) and pred = "sink" @@ -668,22 +669,22 @@ module CsvValidation { private string getInvalidModelSignature() { exists( - string pred, string namespace, string type, string name, string signature, string ext, + string pred, string package, string type, string name, string signature, string ext, string provenance | - sourceModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "source" + sourceModel(package, type, _, name, signature, ext, _, _, provenance) and pred = "source" or - sinkModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "sink" + sinkModel(package, type, _, name, signature, ext, _, _, provenance) and pred = "sink" or - summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance) and + summaryModel(package, type, _, name, signature, ext, _, _, _, provenance) and pred = "summary" or - negativeSummaryModel(namespace, type, name, signature, provenance) and + negativeSummaryModel(package, type, name, signature, provenance) and ext = "" and pred = "negative summary" | - not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and - result = "Dubious namespace \"" + namespace + "\" in " + pred + " model." + not package.regexpMatch("[a-zA-Z0-9_\\.]+") and + result = "Dubious package \"" + package + "\" in " + pred + " model." or not type.regexpMatch("[a-zA-Z0-9_\\$<>]+") and result = "Dubious type \"" + type + "\" in " + pred + " model." @@ -702,7 +703,7 @@ module CsvValidation { ) } - /** Holds if some row in a CSV-based flow model appears to contain typos. */ + /** Holds if some row in a MaD flow model appears to contain typos. */ query predicate invalidModelRow(string msg) { msg = [ @@ -714,15 +715,15 @@ module CsvValidation { pragma[nomagic] private predicate elementSpec( - string namespace, string type, boolean subtypes, string name, string signature, string ext + string package, string type, boolean subtypes, string name, string signature, string ext ) { - sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _) + sourceModel(package, type, subtypes, name, signature, ext, _, _, _) or - sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _) + sinkModel(package, type, subtypes, name, signature, ext, _, _, _) or - summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) + summaryModel(package, type, subtypes, name, signature, ext, _, _, _, _) or - negativeSummaryModel(namespace, type, name, signature, _) and ext = "" and subtypes = false + negativeSummaryModel(package, type, name, signature, _) and ext = "" and subtypes = false } private string paramsStringPart(Callable c, int i) { @@ -747,10 +748,10 @@ cached string paramsString(Callable c) { result = concat(int i | | paramsStringPart(c, i) order by i) } private Element interpretElement0( - string namespace, string type, boolean subtypes, string name, string signature + string package, string type, boolean subtypes, string name, string signature ) { - elementSpec(namespace, type, subtypes, name, signature, _) and - exists(RefType t | t.hasQualifiedName(namespace, type) | + elementSpec(package, type, subtypes, name, signature, _) and + exists(RefType t | t.hasQualifiedName(package, type) | exists(Member m | ( result = m @@ -773,10 +774,10 @@ private Element interpretElement0( /** Gets the source/sink/summary/negativesummary element corresponding to the supplied parameters. */ Element interpretElement( - string namespace, string type, boolean subtypes, string name, string signature, string ext + string package, string type, boolean subtypes, string name, string signature, string ext ) { - elementSpec(namespace, type, subtypes, name, signature, ext) and - exists(Element e | e = interpretElement0(namespace, type, subtypes, name, signature) | + elementSpec(package, type, subtypes, name, signature, ext) and + exists(Element e | e = interpretElement0(package, type, subtypes, name, signature) | ext = "" and result = e or ext = "Annotated" and result.(Annotatable).getAnAnnotation().getType() = e @@ -831,7 +832,7 @@ predicate parseContent(AccessPathToken component, Content content) { cached private module Cached { /** - * Holds if `node` is specified as a source with the given kind in a CSV flow + * Holds if `node` is specified as a source with the given kind in a MaD flow * model. */ cached @@ -840,7 +841,7 @@ private module Cached { } /** - * Holds if `node` is specified as a sink with the given kind in a CSV flow + * Holds if `node` is specified as a sink with the given kind in a MaD flow * model. */ cached diff --git a/java/ql/test/library-tests/dataflow/external-models/negativesummaries.ql b/java/ql/test/library-tests/dataflow/external-models/negativesummaries.ql index 8425cf880b0..b1e104a0fcd 100644 --- a/java/ql/test/library-tests/dataflow/external-models/negativesummaries.ql +++ b/java/ql/test/library-tests/dataflow/external-models/negativesummaries.ql @@ -4,5 +4,5 @@ import java import semmle.code.java.dataflow.ExternalFlow -import CsvValidation +import ModelValidation import semmle.code.java.dataflow.internal.NegativeSummary diff --git a/java/ql/test/library-tests/dataflow/external-models/sinks.ql b/java/ql/test/library-tests/dataflow/external-models/sinks.ql index b44a9eefd88..aa1b3a549f3 100644 --- a/java/ql/test/library-tests/dataflow/external-models/sinks.ql +++ b/java/ql/test/library-tests/dataflow/external-models/sinks.ql @@ -1,7 +1,7 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.ExternalFlow -import CsvValidation +import ModelValidation class SinkModelTest extends SinkModelCsv { override predicate row(string row) { diff --git a/java/ql/test/library-tests/dataflow/external-models/srcs.ql b/java/ql/test/library-tests/dataflow/external-models/srcs.ql index 5e428c412ea..08b13328fa4 100644 --- a/java/ql/test/library-tests/dataflow/external-models/srcs.ql +++ b/java/ql/test/library-tests/dataflow/external-models/srcs.ql @@ -1,7 +1,7 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.ExternalFlow -import CsvValidation +import ModelValidation class SourceModelTest extends SourceModelCsv { override predicate row(string row) { diff --git a/java/ql/test/library-tests/dataflow/external-models/steps.ql b/java/ql/test/library-tests/dataflow/external-models/steps.ql index eec52c383cd..7875763f5e8 100644 --- a/java/ql/test/library-tests/dataflow/external-models/steps.ql +++ b/java/ql/test/library-tests/dataflow/external-models/steps.ql @@ -1,7 +1,7 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.ExternalFlow -import CsvValidation +import ModelValidation import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl class SummaryModelTest extends SummaryModelCsv { diff --git a/java/ql/test/library-tests/dataflow/synth-global/test.ql b/java/ql/test/library-tests/dataflow/synth-global/test.ql index 47a1573865c..de3866636c0 100644 --- a/java/ql/test/library-tests/dataflow/synth-global/test.ql +++ b/java/ql/test/library-tests/dataflow/synth-global/test.ql @@ -1,6 +1,6 @@ import java import TestUtilities.InlineFlowTest -import CsvValidation +import ModelValidation class SummaryModelTest extends SummaryModelCsv { override predicate row(string row) { From 8e25cac6535b4ee23d8fcdabe8a7465f0d454027 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 14 Nov 2022 13:00:29 +0100 Subject: [PATCH 561/796] Java: Add extensible predicates. --- .../code/java/dataflow/ExternalFlow.qll | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 4d1d93c062c..6bd13135c1b 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -432,6 +432,14 @@ predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) } /** Holds if `row` is negative summary model. */ predicate negativeSummaryModel(string row) { any(NegativeSummaryModelCsv s).row(row) } +/** + * Holds if a source model exists for the given parameters. + */ +extensible predicate extSourceModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string output, string kind, string provenance +); + /** Holds if a source model exists for the given parameters. */ predicate sourceModel( string package, string type, boolean subtypes, string name, string signature, string ext, @@ -452,6 +460,12 @@ predicate sourceModel( ) } +/** Holds if a sink model exists for the given parameters. */ +extensible predicate extSinkModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string input, string kind, string provenance +); + /** Holds if a sink model exists for the given parameters. */ predicate sinkModel( string package, string type, boolean subtypes, string name, string signature, string ext, @@ -472,6 +486,12 @@ predicate sinkModel( ) } +/** Holds if a summary model exists for the given parameters. */ +extensible predicate extSummaryModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string input, string output, string kind, string provenance +); + /** Holds if a summary model exists for the given parameters. */ predicate summaryModel( string package, string type, boolean subtypes, string name, string signature, string ext, @@ -499,6 +519,11 @@ predicate summaryModel( row.splitAt(";", 9) = provenance } +/** Holds if a summary model exists indicating there is no flow for the given parameters. */ +extensible predicate extNegativeSummaryModel( + string package, string type, string name, string signature, string provenance +); + /** Holds if a summary model exists indicating there is no flow for the given parameters. */ predicate negativeSummaryModel( string package, string type, string name, string signature, string provenance From 9cb5ff1cdcb687eb5ae30fac95dc42ee6ad307e9 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 14 Nov 2022 13:01:07 +0100 Subject: [PATCH 562/796] Java: Add data extensions for all manual models. --- java/ql/lib/ext/android.app.model.yml | 147 +++++ java/ql/lib/ext/android.content.model.yml | 222 +++++++ java/ql/lib/ext/android.database.model.yml | 27 + .../lib/ext/android.database.sqlite.model.yml | 89 +++ java/ql/lib/ext/android.net.model.yml | 65 ++ java/ql/lib/ext/android.os.model.yml | 133 +++++ .../lib/ext/android.support.v4.app.model.yml | 16 + java/ql/lib/ext/android.util.model.yml | 31 + java/ql/lib/ext/android.webkit.model.yml | 14 + java/ql/lib/ext/android.widget.model.yml | 11 + java/ql/lib/ext/androidx.core.app.model.yml | 110 ++++ .../lib/ext/androidx.fragment.app.model.yml | 16 + .../lib/ext/androidx.slice.builders.model.yml | 93 +++ java/ql/lib/ext/androidx.slice.model.yml | 16 + .../ql/lib/ext/cn.hutool.core.codec.model.yml | 6 + .../com.esotericsoftware.kryo.io.model.yml | 6 + .../com.esotericsoftware.kryo5.io.model.yml | 6 + .../ext/com.fasterxml.jackson.core.model.yml | 6 + .../com.fasterxml.jackson.databind.model.yml | 11 + .../lib/ext/com.google.common.base.model.yml | 98 +++ .../lib/ext/com.google.common.cache.model.yml | 22 + .../ext/com.google.common.collect.model.yml | 558 ++++++++++++++++++ .../ext/com.google.common.flogger.model.yml | 34 ++ .../ql/lib/ext/com.google.common.io.model.yml | 88 +++ java/ql/lib/ext/com.hubspot.jinjava.model.yml | 7 + .../ext/com.mitchellbosecke.pebble.model.yml | 7 + .../com.opensymphony.xwork2.ognl.model.yml | 8 + .../ext/com.rabbitmq.client.impl.model.yml | 15 + java/ql/lib/ext/com.rabbitmq.client.model.yml | 31 + .../lib/ext/com.unboundid.ldap.sdk.model.yml | 22 + java/ql/lib/ext/com.zaxxer.hikari.model.yml | 7 + java/ql/lib/ext/flexjson.model.yml | 6 + java/ql/lib/ext/freemarker.cache.model.yml | 6 + java/ql/lib/ext/freemarker.template.model.yml | 12 + java/ql/lib/ext/groovy.lang.model.yml | 31 + java/ql/lib/ext/groovy.util.model.yml | 10 + .../lib/ext/jakarta.faces.context.model.yml | 18 + java/ql/lib/ext/jakarta.json.model.yml | 127 ++++ java/ql/lib/ext/jakarta.json.stream.model.yml | 6 + .../ql/lib/ext/jakarta.ws.rs.client.model.yml | 6 + .../lib/ext/jakarta.ws.rs.container.model.yml | 14 + java/ql/lib/ext/jakarta.ws.rs.core.model.yml | 160 +++++ java/ql/lib/ext/java.beans.model.yml | 6 + java/ql/lib/ext/java.io.model.yml | 86 +++ java/ql/lib/ext/java.lang.model.yml | 88 +++ java/ql/lib/ext/java.net.http.model.yml | 12 + java/ql/lib/ext/java.net.model.yml | 30 + java/ql/lib/ext/java.nio.channels.model.yml | 7 + java/ql/lib/ext/java.nio.file.model.yml | 33 ++ java/ql/lib/ext/java.nio.model.yml | 8 + java/ql/lib/ext/java.sql.model.yml | 16 + .../ql/lib/ext/java.util.concurrent.model.yml | 23 + java/ql/lib/ext/java.util.function.model.yml | 6 + java/ql/lib/ext/java.util.logging.model.yml | 44 ++ java/ql/lib/ext/java.util.model.yml | 357 +++++++++++ java/ql/lib/ext/java.util.regex.model.yml | 26 + java/ql/lib/ext/java.util.stream.model.yml | 85 +++ java/ql/lib/ext/java.util.zip.model.yml | 7 + java/ql/lib/ext/javax.faces.context.model.yml | 18 + java/ql/lib/ext/javax.jms.model.yml | 75 +++ java/ql/lib/ext/javax.json.model.yml | 127 ++++ java/ql/lib/ext/javax.json.stream.model.yml | 6 + .../lib/ext/javax.management.remote.model.yml | 7 + .../lib/ext/javax.naming.directory.model.yml | 6 + java/ql/lib/ext/javax.naming.model.yml | 11 + java/ql/lib/ext/javax.net.ssl.model.yml | 7 + java/ql/lib/ext/javax.script.model.yml | 6 + java/ql/lib/ext/javax.servlet.http.model.yml | 34 ++ java/ql/lib/ext/javax.servlet.model.yml | 11 + java/ql/lib/ext/javax.validation.model.yml | 11 + java/ql/lib/ext/javax.ws.rs.client.model.yml | 6 + .../lib/ext/javax.ws.rs.container.model.yml | 14 + java/ql/lib/ext/javax.ws.rs.core.model.yml | 161 +++++ java/ql/lib/ext/javax.xml.transform.model.yml | 6 + .../lib/ext/javax.xml.transform.sax.model.yml | 9 + .../ext/javax.xml.transform.stream.model.yml | 7 + java/ql/lib/ext/javax.xml.xpath.model.yml | 8 + java/ql/lib/ext/jodd.json.model.yml | 15 + java/ql/lib/ext/kotlin.collections.model.yml | 6 + java/ql/lib/ext/kotlin.jvm.internal.model.yml | 6 + java/ql/lib/ext/net.sf.saxon.s9api.model.yml | 10 + java/ql/lib/ext/ognl.enhance.model.yml | 7 + java/ql/lib/ext/ognl.model.yml | 9 + java/ql/lib/ext/okhttp3.model.yml | 58 ++ .../ext/org.apache.commons.codec.model.yml | 11 + ...g.apache.commons.collections.bag.model.yml | 23 + ...ache.commons.collections.bidimap.model.yml | 37 ++ ...e.commons.collections.collection.model.yml | 45 ++ ...he.commons.collections.iterators.model.yml | 80 +++ ...che.commons.collections.keyvalue.model.yml | 57 ++ ....apache.commons.collections.list.model.yml | 27 + ...g.apache.commons.collections.map.model.yml | 133 +++++ .../org.apache.commons.collections.model.yml | 365 ++++++++++++ ...che.commons.collections.multimap.model.yml | 17 + ...che.commons.collections.multiset.model.yml | 9 + ...e.commons.collections.properties.model.yml | 13 + ...apache.commons.collections.queue.model.yml | 11 + ...g.apache.commons.collections.set.model.yml | 36 ++ ...che.commons.collections.splitmap.model.yml | 9 + ....apache.commons.collections.trie.model.yml | 13 + ....apache.commons.collections4.bag.model.yml | 23 + ...che.commons.collections4.bidimap.model.yml | 37 ++ ....commons.collections4.collection.model.yml | 45 ++ ...e.commons.collections4.iterators.model.yml | 80 +++ ...he.commons.collections4.keyvalue.model.yml | 57 ++ ...apache.commons.collections4.list.model.yml | 27 + ....apache.commons.collections4.map.model.yml | 133 +++++ .../org.apache.commons.collections4.model.yml | 365 ++++++++++++ ...he.commons.collections4.multimap.model.yml | 17 + ...he.commons.collections4.multiset.model.yml | 9 + ....commons.collections4.properties.model.yml | 13 + ...pache.commons.collections4.queue.model.yml | 11 + ....apache.commons.collections4.set.model.yml | 36 ++ ...he.commons.collections4.splitmap.model.yml | 9 + ...apache.commons.collections4.trie.model.yml | 13 + .../lib/ext/org.apache.commons.io.model.yml | 10 + .../ext/org.apache.commons.jexl2.model.yml | 20 + .../ext/org.apache.commons.jexl3.model.yml | 20 + ...org.apache.commons.lang3.builder.model.yml | 22 + .../ext/org.apache.commons.lang3.model.yml | 207 +++++++ ...org.apache.commons.lang3.mutable.model.yml | 8 + .../org.apache.commons.lang3.text.model.yml | 160 +++++ .../org.apache.commons.lang3.tuple.model.yml | 52 ++ .../ext/org.apache.commons.logging.model.yml | 11 + .../org.apache.commons.ognl.enhance.model.yml | 7 + .../lib/ext/org.apache.commons.ognl.model.yml | 9 + .../org.apache.commons.text.lookup.model.yml | 7 + .../lib/ext/org.apache.commons.text.model.yml | 275 +++++++++ ...apache.directory.ldap.client.api.model.yml | 6 + .../org.apache.hc.core5.function.model.yml | 6 + ...g.apache.hc.core5.http.io.entity.model.yml | 19 + .../ext/org.apache.hc.core5.http.io.model.yml | 7 + ...org.apache.hc.core5.http.message.model.yml | 10 + .../ext/org.apache.hc.core5.http.model.yml | 30 + .../lib/ext/org.apache.hc.core5.net.model.yml | 7 + .../ext/org.apache.hc.core5.util.model.yml | 29 + .../org.apache.http.client.methods.model.yml | 23 + .../lib/ext/org.apache.http.entity.model.yml | 11 + .../lib/ext/org.apache.http.message.model.yml | 16 + java/ql/lib/ext/org.apache.http.model.yml | 42 ++ .../lib/ext/org.apache.http.params.model.yml | 12 + .../ext/org.apache.http.protocol.model.yml | 6 + .../ql/lib/ext/org.apache.http.util.model.yml | 41 ++ .../lib/ext/org.apache.ibatis.jdbc.model.yml | 72 +++ java/ql/lib/ext/org.apache.log4j.model.yml | 16 + .../ext/org.apache.logging.log4j.model.yml | 376 ++++++++++++ .../lib/ext/org.apache.shiro.codec.model.yml | 6 + .../lib/ext/org.apache.shiro.jndi.model.yml | 6 + .../lib/ext/org.apache.velocity.app.model.yml | 9 + .../ext/org.apache.velocity.runtime.model.yml | 8 + ...e.velocity.runtime.resource.util.model.yml | 6 + .../ext/org.codehaus.groovy.control.model.yml | 6 + java/ql/lib/ext/org.dom4j.model.yml | 20 + java/ql/lib/ext/org.dom4j.tree.model.yml | 7 + java/ql/lib/ext/org.dom4j.util.model.yml | 8 + java/ql/lib/ext/org.hibernate.model.yml | 12 + java/ql/lib/ext/org.jboss.logging.model.yml | 329 +++++++++++ java/ql/lib/ext/org.jdbi.v3.core.model.yml | 11 + java/ql/lib/ext/org.jooq.model.yml | 6 + java/ql/lib/ext/org.json.model.yml | 241 ++++++++ java/ql/lib/ext/org.mvel2.compiler.model.yml | 9 + java/ql/lib/ext/org.mvel2.jsr223.model.yml | 8 + java/ql/lib/ext/org.mvel2.model.yml | 12 + java/ql/lib/ext/org.mvel2.templates.model.yml | 7 + java/ql/lib/ext/org.scijava.log.model.yml | 18 + java/ql/lib/ext/org.slf4j.model.yml | 55 ++ java/ql/lib/ext/org.slf4j.spi.model.yml | 20 + .../ext/org.springframework.beans.model.yml | 35 ++ .../org.springframework.boot.jdbc.model.yml | 6 + .../ext/org.springframework.cache.model.yml | 18 + .../ext/org.springframework.context.model.yml | 8 + ....springframework.data.repository.model.yml | 6 + .../ext/org.springframework.http.model.yml | 93 +++ .../org.springframework.jdbc.core.model.yml | 15 + ....springframework.jdbc.datasource.model.yml | 9 + .../org.springframework.jdbc.object.model.yml | 14 + .../ext/org.springframework.jndi.model.yml | 6 + .../org.springframework.ldap.core.model.yml | 38 ++ .../ext/org.springframework.ldap.model.yml | 19 + ...mework.security.web.savedrequest.model.yml | 11 + .../lib/ext/org.springframework.ui.model.yml | 37 ++ .../ext/org.springframework.util.model.yml | 144 +++++ .../org.springframework.validation.model.yml | 18 + .../org.springframework.web.client.model.yml | 25 + ...ingframework.web.context.request.model.yml | 13 + ...rg.springframework.web.multipart.model.yml | 34 ++ ...ork.web.reactive.function.client.model.yml | 7 + .../org.springframework.web.util.model.yml | 168 ++++++ java/ql/lib/ext/org.thymeleaf.model.yml | 13 + java/ql/lib/ext/org.xml.sax.model.yml | 6 + java/ql/lib/ext/org.xmlpull.v1.model.yml | 8 + java/ql/lib/ext/play.mvc.model.yml | 9 + java/ql/lib/ext/ratpack.core.form.model.yml | 8 + .../lib/ext/ratpack.core.handling.model.yml | 19 + java/ql/lib/ext/ratpack.core.http.model.yml | 29 + java/ql/lib/ext/ratpack.exec.model.yml | 53 ++ java/ql/lib/ext/ratpack.form.model.yml | 8 + java/ql/lib/ext/ratpack.func.model.yml | 40 ++ java/ql/lib/ext/ratpack.handling.model.yml | 19 + java/ql/lib/ext/ratpack.http.model.yml | 29 + java/ql/lib/ext/ratpack.util.model.yml | 40 ++ java/ql/lib/ext/retrofit2.model.yml | 6 + 202 files changed, 8906 insertions(+) create mode 100644 java/ql/lib/ext/android.app.model.yml create mode 100644 java/ql/lib/ext/android.content.model.yml create mode 100644 java/ql/lib/ext/android.database.model.yml create mode 100644 java/ql/lib/ext/android.database.sqlite.model.yml create mode 100644 java/ql/lib/ext/android.net.model.yml create mode 100644 java/ql/lib/ext/android.os.model.yml create mode 100644 java/ql/lib/ext/android.support.v4.app.model.yml create mode 100644 java/ql/lib/ext/android.util.model.yml create mode 100644 java/ql/lib/ext/android.webkit.model.yml create mode 100644 java/ql/lib/ext/android.widget.model.yml create mode 100644 java/ql/lib/ext/androidx.core.app.model.yml create mode 100644 java/ql/lib/ext/androidx.fragment.app.model.yml create mode 100644 java/ql/lib/ext/androidx.slice.builders.model.yml create mode 100644 java/ql/lib/ext/androidx.slice.model.yml create mode 100644 java/ql/lib/ext/cn.hutool.core.codec.model.yml create mode 100644 java/ql/lib/ext/com.esotericsoftware.kryo.io.model.yml create mode 100644 java/ql/lib/ext/com.esotericsoftware.kryo5.io.model.yml create mode 100644 java/ql/lib/ext/com.fasterxml.jackson.core.model.yml create mode 100644 java/ql/lib/ext/com.fasterxml.jackson.databind.model.yml create mode 100644 java/ql/lib/ext/com.google.common.base.model.yml create mode 100644 java/ql/lib/ext/com.google.common.cache.model.yml create mode 100644 java/ql/lib/ext/com.google.common.collect.model.yml create mode 100644 java/ql/lib/ext/com.google.common.flogger.model.yml create mode 100644 java/ql/lib/ext/com.google.common.io.model.yml create mode 100644 java/ql/lib/ext/com.hubspot.jinjava.model.yml create mode 100644 java/ql/lib/ext/com.mitchellbosecke.pebble.model.yml create mode 100644 java/ql/lib/ext/com.opensymphony.xwork2.ognl.model.yml create mode 100644 java/ql/lib/ext/com.rabbitmq.client.impl.model.yml create mode 100644 java/ql/lib/ext/com.rabbitmq.client.model.yml create mode 100644 java/ql/lib/ext/com.unboundid.ldap.sdk.model.yml create mode 100644 java/ql/lib/ext/com.zaxxer.hikari.model.yml create mode 100644 java/ql/lib/ext/flexjson.model.yml create mode 100644 java/ql/lib/ext/freemarker.cache.model.yml create mode 100644 java/ql/lib/ext/freemarker.template.model.yml create mode 100644 java/ql/lib/ext/groovy.lang.model.yml create mode 100644 java/ql/lib/ext/groovy.util.model.yml create mode 100644 java/ql/lib/ext/jakarta.faces.context.model.yml create mode 100644 java/ql/lib/ext/jakarta.json.model.yml create mode 100644 java/ql/lib/ext/jakarta.json.stream.model.yml create mode 100644 java/ql/lib/ext/jakarta.ws.rs.client.model.yml create mode 100644 java/ql/lib/ext/jakarta.ws.rs.container.model.yml create mode 100644 java/ql/lib/ext/jakarta.ws.rs.core.model.yml create mode 100644 java/ql/lib/ext/java.beans.model.yml create mode 100644 java/ql/lib/ext/java.io.model.yml create mode 100644 java/ql/lib/ext/java.lang.model.yml create mode 100644 java/ql/lib/ext/java.net.http.model.yml create mode 100644 java/ql/lib/ext/java.net.model.yml create mode 100644 java/ql/lib/ext/java.nio.channels.model.yml create mode 100644 java/ql/lib/ext/java.nio.file.model.yml create mode 100644 java/ql/lib/ext/java.nio.model.yml create mode 100644 java/ql/lib/ext/java.sql.model.yml create mode 100644 java/ql/lib/ext/java.util.concurrent.model.yml create mode 100644 java/ql/lib/ext/java.util.function.model.yml create mode 100644 java/ql/lib/ext/java.util.logging.model.yml create mode 100644 java/ql/lib/ext/java.util.model.yml create mode 100644 java/ql/lib/ext/java.util.regex.model.yml create mode 100644 java/ql/lib/ext/java.util.stream.model.yml create mode 100644 java/ql/lib/ext/java.util.zip.model.yml create mode 100644 java/ql/lib/ext/javax.faces.context.model.yml create mode 100644 java/ql/lib/ext/javax.jms.model.yml create mode 100644 java/ql/lib/ext/javax.json.model.yml create mode 100644 java/ql/lib/ext/javax.json.stream.model.yml create mode 100644 java/ql/lib/ext/javax.management.remote.model.yml create mode 100644 java/ql/lib/ext/javax.naming.directory.model.yml create mode 100644 java/ql/lib/ext/javax.naming.model.yml create mode 100644 java/ql/lib/ext/javax.net.ssl.model.yml create mode 100644 java/ql/lib/ext/javax.script.model.yml create mode 100644 java/ql/lib/ext/javax.servlet.http.model.yml create mode 100644 java/ql/lib/ext/javax.servlet.model.yml create mode 100644 java/ql/lib/ext/javax.validation.model.yml create mode 100644 java/ql/lib/ext/javax.ws.rs.client.model.yml create mode 100644 java/ql/lib/ext/javax.ws.rs.container.model.yml create mode 100644 java/ql/lib/ext/javax.ws.rs.core.model.yml create mode 100644 java/ql/lib/ext/javax.xml.transform.model.yml create mode 100644 java/ql/lib/ext/javax.xml.transform.sax.model.yml create mode 100644 java/ql/lib/ext/javax.xml.transform.stream.model.yml create mode 100644 java/ql/lib/ext/javax.xml.xpath.model.yml create mode 100644 java/ql/lib/ext/jodd.json.model.yml create mode 100644 java/ql/lib/ext/kotlin.collections.model.yml create mode 100644 java/ql/lib/ext/kotlin.jvm.internal.model.yml create mode 100644 java/ql/lib/ext/net.sf.saxon.s9api.model.yml create mode 100644 java/ql/lib/ext/ognl.enhance.model.yml create mode 100644 java/ql/lib/ext/ognl.model.yml create mode 100644 java/ql/lib/ext/okhttp3.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.codec.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections.bag.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections.bidimap.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections.collection.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections.iterators.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections.keyvalue.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections.list.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections.map.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections.multimap.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections.multiset.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections.properties.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections.queue.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections.set.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections.splitmap.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections.trie.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections4.bag.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections4.bidimap.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections4.collection.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections4.iterators.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections4.keyvalue.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections4.list.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections4.map.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections4.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections4.multimap.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections4.multiset.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections4.properties.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections4.queue.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections4.set.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections4.splitmap.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.collections4.trie.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.io.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.jexl2.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.jexl3.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.lang3.builder.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.lang3.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.lang3.mutable.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.lang3.text.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.lang3.tuple.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.logging.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.ognl.enhance.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.ognl.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.text.lookup.model.yml create mode 100644 java/ql/lib/ext/org.apache.commons.text.model.yml create mode 100644 java/ql/lib/ext/org.apache.directory.ldap.client.api.model.yml create mode 100644 java/ql/lib/ext/org.apache.hc.core5.function.model.yml create mode 100644 java/ql/lib/ext/org.apache.hc.core5.http.io.entity.model.yml create mode 100644 java/ql/lib/ext/org.apache.hc.core5.http.io.model.yml create mode 100644 java/ql/lib/ext/org.apache.hc.core5.http.message.model.yml create mode 100644 java/ql/lib/ext/org.apache.hc.core5.http.model.yml create mode 100644 java/ql/lib/ext/org.apache.hc.core5.net.model.yml create mode 100644 java/ql/lib/ext/org.apache.hc.core5.util.model.yml create mode 100644 java/ql/lib/ext/org.apache.http.client.methods.model.yml create mode 100644 java/ql/lib/ext/org.apache.http.entity.model.yml create mode 100644 java/ql/lib/ext/org.apache.http.message.model.yml create mode 100644 java/ql/lib/ext/org.apache.http.model.yml create mode 100644 java/ql/lib/ext/org.apache.http.params.model.yml create mode 100644 java/ql/lib/ext/org.apache.http.protocol.model.yml create mode 100644 java/ql/lib/ext/org.apache.http.util.model.yml create mode 100644 java/ql/lib/ext/org.apache.ibatis.jdbc.model.yml create mode 100644 java/ql/lib/ext/org.apache.log4j.model.yml create mode 100644 java/ql/lib/ext/org.apache.logging.log4j.model.yml create mode 100644 java/ql/lib/ext/org.apache.shiro.codec.model.yml create mode 100644 java/ql/lib/ext/org.apache.shiro.jndi.model.yml create mode 100644 java/ql/lib/ext/org.apache.velocity.app.model.yml create mode 100644 java/ql/lib/ext/org.apache.velocity.runtime.model.yml create mode 100644 java/ql/lib/ext/org.apache.velocity.runtime.resource.util.model.yml create mode 100644 java/ql/lib/ext/org.codehaus.groovy.control.model.yml create mode 100644 java/ql/lib/ext/org.dom4j.model.yml create mode 100644 java/ql/lib/ext/org.dom4j.tree.model.yml create mode 100644 java/ql/lib/ext/org.dom4j.util.model.yml create mode 100644 java/ql/lib/ext/org.hibernate.model.yml create mode 100644 java/ql/lib/ext/org.jboss.logging.model.yml create mode 100644 java/ql/lib/ext/org.jdbi.v3.core.model.yml create mode 100644 java/ql/lib/ext/org.jooq.model.yml create mode 100644 java/ql/lib/ext/org.json.model.yml create mode 100644 java/ql/lib/ext/org.mvel2.compiler.model.yml create mode 100644 java/ql/lib/ext/org.mvel2.jsr223.model.yml create mode 100644 java/ql/lib/ext/org.mvel2.model.yml create mode 100644 java/ql/lib/ext/org.mvel2.templates.model.yml create mode 100644 java/ql/lib/ext/org.scijava.log.model.yml create mode 100644 java/ql/lib/ext/org.slf4j.model.yml create mode 100644 java/ql/lib/ext/org.slf4j.spi.model.yml create mode 100644 java/ql/lib/ext/org.springframework.beans.model.yml create mode 100644 java/ql/lib/ext/org.springframework.boot.jdbc.model.yml create mode 100644 java/ql/lib/ext/org.springframework.cache.model.yml create mode 100644 java/ql/lib/ext/org.springframework.context.model.yml create mode 100644 java/ql/lib/ext/org.springframework.data.repository.model.yml create mode 100644 java/ql/lib/ext/org.springframework.http.model.yml create mode 100644 java/ql/lib/ext/org.springframework.jdbc.core.model.yml create mode 100644 java/ql/lib/ext/org.springframework.jdbc.datasource.model.yml create mode 100644 java/ql/lib/ext/org.springframework.jdbc.object.model.yml create mode 100644 java/ql/lib/ext/org.springframework.jndi.model.yml create mode 100644 java/ql/lib/ext/org.springframework.ldap.core.model.yml create mode 100644 java/ql/lib/ext/org.springframework.ldap.model.yml create mode 100644 java/ql/lib/ext/org.springframework.security.web.savedrequest.model.yml create mode 100644 java/ql/lib/ext/org.springframework.ui.model.yml create mode 100644 java/ql/lib/ext/org.springframework.util.model.yml create mode 100644 java/ql/lib/ext/org.springframework.validation.model.yml create mode 100644 java/ql/lib/ext/org.springframework.web.client.model.yml create mode 100644 java/ql/lib/ext/org.springframework.web.context.request.model.yml create mode 100644 java/ql/lib/ext/org.springframework.web.multipart.model.yml create mode 100644 java/ql/lib/ext/org.springframework.web.reactive.function.client.model.yml create mode 100644 java/ql/lib/ext/org.springframework.web.util.model.yml create mode 100644 java/ql/lib/ext/org.thymeleaf.model.yml create mode 100644 java/ql/lib/ext/org.xml.sax.model.yml create mode 100644 java/ql/lib/ext/org.xmlpull.v1.model.yml create mode 100644 java/ql/lib/ext/play.mvc.model.yml create mode 100644 java/ql/lib/ext/ratpack.core.form.model.yml create mode 100644 java/ql/lib/ext/ratpack.core.handling.model.yml create mode 100644 java/ql/lib/ext/ratpack.core.http.model.yml create mode 100644 java/ql/lib/ext/ratpack.exec.model.yml create mode 100644 java/ql/lib/ext/ratpack.form.model.yml create mode 100644 java/ql/lib/ext/ratpack.func.model.yml create mode 100644 java/ql/lib/ext/ratpack.handling.model.yml create mode 100644 java/ql/lib/ext/ratpack.http.model.yml create mode 100644 java/ql/lib/ext/ratpack.util.model.yml create mode 100644 java/ql/lib/ext/retrofit2.model.yml diff --git a/java/ql/lib/ext/android.app.model.yml b/java/ql/lib/ext/android.app.model.yml new file mode 100644 index 00000000000..c96fee8b282 --- /dev/null +++ b/java/ql/lib/ext/android.app.model.yml @@ -0,0 +1,147 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["android.app", "Activity", True, "bindService", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.app", "Activity", True, "bindServiceAsUser", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.app", "Activity", True, "setResult", "(int,Intent)", "", "Argument[1]", "pending-intent-sent", "manual"] + - ["android.app", "Activity", True, "startActivityAsCaller", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.app", "Activity", True, "startActivityForResult", "(Intent,int)", "", "Argument[0]", "intent-start", "manual"] + - ["android.app", "Activity", True, "startActivityForResult", "(Intent,int,Bundle)", "", "Argument[0]", "intent-start", "manual"] + - ["android.app", "Activity", True, "startActivityForResult", "(String,Intent,int,Bundle)", "", "Argument[1]", "intent-start", "manual"] + - ["android.app", "Activity", True, "startActivityForResultAsUser", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.app", "AlarmManager", True, "set", "(int,long,PendingIntent)", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "AlarmManager", True, "setAlarmClock", "", "", "Argument[1]", "pending-intent-sent", "manual"] + - ["android.app", "AlarmManager", True, "setAndAllowWhileIdle", "", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "AlarmManager", True, "setExact", "(int,long,PendingIntent)", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "AlarmManager", True, "setExactAndAllowWhileIdle", "", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "AlarmManager", True, "setInexactRepeating", "", "", "Argument[3]", "pending-intent-sent", "manual"] + - ["android.app", "AlarmManager", True, "setRepeating", "", "", "Argument[3]", "pending-intent-sent", "manual"] + - ["android.app", "AlarmManager", True, "setWindow", "(int,long,long,PendingIntent)", "", "Argument[3]", "pending-intent-sent", "manual"] + - ["android.app", "FragmentTransaction", True, "add", "(Class,Bundle,String)", "", "Argument[0]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "add", "(Fragment,String)", "", "Argument[0]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "add", "(int,Class,Bundle)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "add", "(int,Class,Bundle,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "add", "(int,Fragment)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "add", "(int,Fragment,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "attach", "(Fragment)", "", "Argument[0]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "replace", "(int,Class,Bundle)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "replace", "(int,Class,Bundle,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "replace", "(int,Fragment)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "replace", "(int,Fragment,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.app", "NotificationManager", True, "notify", "(String,int,Notification)", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "NotificationManager", True, "notify", "(int,Notification)", "", "Argument[1]", "pending-intent-sent", "manual"] + - ["android.app", "NotificationManager", True, "notifyAsPackage", "(String,String,int,Notification)", "", "Argument[3]", "pending-intent-sent", "manual"] + - ["android.app", "NotificationManager", True, "notifyAsUser", "(String,int,Notification,UserHandle)", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "PendingIntent", False, "send", "(Context,int,Intent)", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "PendingIntent", False, "send", "(Context,int,Intent,OnFinished,Handler)", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "PendingIntent", False, "send", "(Context,int,Intent,OnFinished,Handler,String)", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "PendingIntent", False, "send", "(Context,int,Intent,OnFinished,Handler,String,Bundle)", "", "Argument[2]", "pending-intent-sent", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["android.app", "Notification$Action", True, "Action", "(int,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Action", True, "getExtras", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "Builder", "(Action)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Action$Builder", True, "Builder", "(Icon,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Action$Builder", True, "Builder", "(int,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Action$Builder", True, "addExtras", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "addExtras", "", "", "Argument[0].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "addExtras", "", "", "Argument[0].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "addRemoteInput", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.app", "Notification$Action$Builder", True, "build", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue.SyntheticField[android.content.Intent.extras]", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "extend", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "getExtras", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "setAllowGeneratedReplies", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "setAuthenticationRequired", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "setContextual", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "setSemanticAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigPictureStyle", True, "BigPictureStyle", "(Builder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$BigPictureStyle", True, "bigLargeIcon", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigPictureStyle", True, "bigPicture", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigPictureStyle", True, "setBigContentTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigPictureStyle", True, "setContentDescription", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigPictureStyle", True, "setSummaryText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigPictureStyle", True, "showBigPictureWhenCollapsed", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigTextStyle", True, "BigTextStyle", "(Builder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$BigTextStyle", True, "bigText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigTextStyle", True, "setBigContentTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigTextStyle", True, "setSummaryText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "addAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "addAction", "(Action)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Builder", True, "addAction", "(int,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Builder", True, "addExtras", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "addExtras", "", "", "Argument[0].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.app", "Notification$Builder", True, "addExtras", "", "", "Argument[0].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "addPerson", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.app", "Notification$Builder", True, "build", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue.Field[android.app.Notification.extras]", "value", "manual"] + - ["android.app", "Notification$Builder", True, "extend", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "getExtras", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "recoverBuilder", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["android.app", "Notification$Builder", True, "setActions", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setActions", "", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Builder", True, "setAutoCancel", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setBadgeIconType", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setBubbleMetadata", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setCategory", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setChannelId", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setChronometerCountDown", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setColor", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setColorized", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setContent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setContentInfo", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setContentIntent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setContentIntent", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Builder", True, "setContentText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setContentTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setCustomBigContentView", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setCustomHeadsUpContentView", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setDefaults", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setDeleteIntent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setDeleteIntent", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Builder", True, "setExtras", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setExtras", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.extras]", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setFlag", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setForegroundServiceBehavior", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setFullScreenIntent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setGroup", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setGroupAlertBehavior", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setGroupSummary", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setLargeIcon", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setLights", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setLocalOnly", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setLocusId", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setNumber", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setOngoing", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setOnlyAlertOnce", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setPriority", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setProgress", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setPublicVersion", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setPublicVersion", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Builder", True, "setRemoteInputHistory", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setSettingsText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setShortcutId", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setShowWhen", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setSmallIcon", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setSortKey", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setSound", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setStyle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setSubText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setTicker", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setTimeoutAfter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setUsesChronometer", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setVibrate", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setVisibility", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setWhen", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$InboxStyle", True, "InboxStyle", "(Builder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$InboxStyle", True, "addLine", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$InboxStyle", True, "setBigContentTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$InboxStyle", True, "setSummaryText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$MediaStyle", True, "MediaStyle", "(Builder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$MediaStyle", True, "setMediaSession", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$MediaStyle", True, "setShowActionsInCompactView", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Style", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/android.content.model.yml b/java/ql/lib/ext/android.content.model.yml new file mode 100644 index 00000000000..23e3e376c12 --- /dev/null +++ b/java/ql/lib/ext/android.content.model.yml @@ -0,0 +1,222 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["android.content", "ContentInterface", True, "call", "(String,String,String,Bundle)", "", "Parameter[0..3]", "contentprovider", "manual"] + - ["android.content", "ContentInterface", True, "delete", "(Uri,Bundle)", "", "Parameter[0..1]", "contentprovider", "manual"] + - ["android.content", "ContentInterface", True, "getType", "(Uri)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentInterface", True, "insert", "(Uri,ContentValues,Bundle)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentInterface", True, "openAssetFile", "(Uri,String,CancellationSignal)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentInterface", True, "openFile", "(Uri,String,CancellationSignal)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentInterface", True, "openTypedAssetFile", "(Uri,String,Bundle,CancellationSignal)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentInterface", True, "query", "(Uri,String[],Bundle,CancellationSignal)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentInterface", True, "update", "(Uri,ContentValues,Bundle)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "call", "(String,String,Bundle)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "call", "(String,String,String,Bundle)", "", "Parameter[0..3]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "delete", "(Uri,Bundle)", "", "Parameter[0..1]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "delete", "(Uri,String,String[])", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "getType", "(Uri)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "insert", "(Uri,ContentValues)", "", "Parameter[0..1]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "insert", "(Uri,ContentValues,Bundle)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "openAssetFile", "(Uri,String)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "openAssetFile", "(Uri,String,CancellationSignal)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "openFile", "(Uri,String)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "openFile", "(Uri,String,CancellationSignal)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "openTypedAssetFile", "(Uri,String,Bundle)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "openTypedAssetFile", "(Uri,String,Bundle,CancellationSignal)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "query", "(Uri,String[],Bundle,CancellationSignal)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String)", "", "Parameter[0..4]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String,CancellationSignal)", "", "Parameter[0..4]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "update", "(Uri,ContentValues,Bundle)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "update", "(Uri,ContentValues,String,String[])", "", "Parameter[0..3]", "contentprovider", "manual"] + - ["android.content", "Context", True, "getExternalCacheDir", "()", "", "ReturnValue", "android-external-storage-dir", "manual"] + - ["android.content", "Context", True, "getExternalCacheDirs", "()", "", "ReturnValue", "android-external-storage-dir", "manual"] + - ["android.content", "Context", True, "getExternalFilesDir", "(String)", "", "ReturnValue", "android-external-storage-dir", "manual"] + - ["android.content", "Context", True, "getExternalFilesDirs", "(String)", "", "ReturnValue", "android-external-storage-dir", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["android.content", "ContentProvider", True, "delete", "(Uri,String,String[])", "", "Argument[1]", "sql", "manual"] + - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String)", "", "Argument[2]", "sql", "manual"] + - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String,CancellationSignal)", "", "Argument[2]", "sql", "manual"] + - ["android.content", "ContentProvider", True, "update", "(Uri,ContentValues,String,String[])", "", "Argument[2]", "sql", "manual"] + - ["android.content", "ContentResolver", True, "delete", "(Uri,String,String[])", "", "Argument[1]", "sql", "manual"] + - ["android.content", "ContentResolver", True, "query", "(Uri,String[],String,String[],String)", "", "Argument[2]", "sql", "manual"] + - ["android.content", "ContentResolver", True, "query", "(Uri,String[],String,String[],String,CancellationSignal)", "", "Argument[2]", "sql", "manual"] + - ["android.content", "ContentResolver", True, "update", "(Uri,ContentValues,String,String[])", "", "Argument[2]", "sql", "manual"] + - ["android.content", "Context", True, "sendBroadcast", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "sendBroadcastAsUser", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "sendBroadcastWithMultiplePermissions", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "sendStickyBroadcast", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "sendStickyBroadcastAsUser", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "sendStickyOrderedBroadcast", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "sendStickyOrderedBroadcastAsUser", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "startActivities", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "startActivity", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "startActivityAsUser", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "startActivityFromChild", "", "", "Argument[1]", "intent-start", "manual"] + - ["android.content", "Context", True, "startActivityFromFragment", "", "", "Argument[1]", "intent-start", "manual"] + - ["android.content", "Context", True, "startActivityIfNeeded", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "startForegroundService", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "startService", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "startServiceAsUser", "", "", "Argument[0]", "intent-start", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["android.content", "ComponentName", False, "ComponentName", "(Context,Class)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["android.content", "ComponentName", False, "ComponentName", "(Context,String)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["android.content", "ComponentName", False, "ComponentName", "(Parcel)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.content", "ComponentName", False, "ComponentName", "(String,String)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["android.content", "ComponentName", False, "createRelative", "(Context,String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ComponentName", False, "createRelative", "(String,String)", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ComponentName", False, "flattenToShortString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ComponentName", False, "flattenToString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ComponentName", False, "getClassName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ComponentName", False, "getPackageName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ComponentName", False, "getShortClassName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ComponentName", False, "unflattenFromString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String,CancellationSignal)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderClient", True, "applyBatch", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderClient", True, "call", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderClient", True, "canonicalize", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderClient", True, "getLocalContentProvider", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderClient", True, "getStreamTypes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderClient", True, "insert", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderClient", True, "query", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderClient", True, "uncanonicalize", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "apply", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "apply", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "getUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "newAssertQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "newCall", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "newDelete", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "newInsert", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "newUpdate", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "resolveExtrasBackReferences", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "resolveSelectionArgsBackReferences", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "resolveValueBackReferences", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withExceptionAllowed", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withExpectedCount", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withExtra", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withExtraBackReference", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withExtras", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withSelection", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withSelectionBackReference", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withValue", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withValueBackReference", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withValues", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withYieldAllowed", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderResult", False, "ContentProviderResult", "(Bundle)", "", "Argument[0]", "Argument[-1].Field[android.content.ContentProviderResult.extras]", "value", "manual"] + - ["android.content", "ContentProviderResult", False, "ContentProviderResult", "(Parcel)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.content", "ContentProviderResult", False, "ContentProviderResult", "(Throwable)", "", "Argument[0]", "Argument[-1].Field[android.content.ContentProviderResult.exception]", "value", "manual"] + - ["android.content", "ContentProviderResult", False, "ContentProviderResult", "(Uri)", "", "Argument[0]", "Argument[-1].Field[android.content.ContentProviderResult.uri]", "value", "manual"] + - ["android.content", "ContentResolver", True, "acquireContentProviderClient", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "acquireUnstableContentProviderClient", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "applyBatch", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "call", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "canonicalize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "getStreamTypes", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "getType", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "insert", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "query", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "query", "(Uri,String[],String,String[],String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "query", "(Uri,String[],String,String[],String,CancellationSignal)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "uncanonicalize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "wrap", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentValues", False, "put", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.content", "ContentValues", False, "put", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.content", "ContentValues", False, "putAll", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["android.content", "ContentValues", False, "putAll", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "Intent", "(Context,Class)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["android.content", "Intent", True, "Intent", "(Intent)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.content", "Intent", False, "Intent", "(Intent)", "", "Argument[0].SyntheticField[android.content.Intent.extras].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", False, "Intent", "(Intent)", "", "Argument[0].SyntheticField[android.content.Intent.extras].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", False, "Intent", "(String,Uri)", "", "Argument[1]", "Argument[-1].SyntheticField[android.content.Intent.data]", "value", "manual"] + - ["android.content", "Intent", False, "Intent", "(String,Uri,Context,Class)", "", "Argument[1]", "Argument[-1].SyntheticField[android.content.Intent.data]", "value", "manual"] + - ["android.content", "Intent", True, "Intent", "(String,Uri,Context,Class)", "", "Argument[3]", "Argument[-1]", "taint", "manual"] + - ["android.content", "Intent", True, "addCategory", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "addFlags", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", False, "createChooser", "", "", "Argument[0..2]", "ReturnValue.SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "getBundleExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getByteArrayExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getCharArrayExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getCharSequenceArrayExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getCharSequenceArrayListExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getCharSequenceExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getData", "", "", "Argument[-1].SyntheticField[android.content.Intent.data]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getDataString", "", "", "Argument[-1].SyntheticField[android.content.Intent.data]", "ReturnValue", "taint", "manual"] + - ["android.content", "Intent", True, "getExtras", "()", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", False, "getIntent", "", "", "Argument[0]", "ReturnValue.SyntheticField[android.content.Intent.data]", "taint", "manual"] + - ["android.content", "Intent", True, "getIntent", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "Intent", False, "getIntentOld", "", "", "Argument[0]", "ReturnValue.SyntheticField[android.content.Intent.data]", "taint", "manual"] + - ["android.content", "Intent", True, "getIntentOld", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "Intent", True, "getParcelableArrayExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getParcelableArrayListExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getParcelableExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getSerializableExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getStringArrayExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getStringArrayListExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getStringExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", False, "parseUri", "", "", "Argument[0]", "ReturnValue.SyntheticField[android.content.Intent.data]", "taint", "manual"] + - ["android.content", "Intent", True, "parseUri", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "Intent", True, "putCharSequenceArrayListExtra", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "putCharSequenceArrayListExtra", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "putCharSequenceArrayListExtra", "", "", "Argument[1]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "putExtra", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "putExtra", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "putExtra", "", "", "Argument[1]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "putExtras", "(Bundle)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "putExtras", "(Bundle)", "", "Argument[0].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "putExtras", "(Bundle)", "", "Argument[0].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "putExtras", "(Intent)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "putExtras", "(Intent)", "", "Argument[0].SyntheticField[android.content.Intent.extras].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "putExtras", "(Intent)", "", "Argument[0].SyntheticField[android.content.Intent.extras].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "putIntegerArrayListExtra", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "putIntegerArrayListExtra", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "putParcelableArrayListExtra", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "putParcelableArrayListExtra", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "putParcelableArrayListExtra", "", "", "Argument[1]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "putStringArrayListExtra", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "putStringArrayListExtra", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "putStringArrayListExtra", "", "", "Argument[1]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "replaceExtras", "(Bundle)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "replaceExtras", "(Bundle)", "", "Argument[0].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "replaceExtras", "(Bundle)", "", "Argument[0].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "replaceExtras", "(Intent)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "replaceExtras", "(Intent)", "", "Argument[0].SyntheticField[android.content.Intent.extras].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "replaceExtras", "(Intent)", "", "Argument[0].SyntheticField[android.content.Intent.extras].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "setAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setClass", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setClass", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["android.content", "Intent", True, "setClassName", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setClassName", "(Context,String)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["android.content", "Intent", True, "setClassName", "(String,String)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["android.content", "Intent", True, "setComponent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setComponent", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.content", "Intent", True, "setData", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setData", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.data]", "value", "manual"] + - ["android.content", "Intent", True, "setDataAndNormalize", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setDataAndNormalize", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.data]", "value", "manual"] + - ["android.content", "Intent", True, "setDataAndType", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setDataAndType", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.data]", "value", "manual"] + - ["android.content", "Intent", True, "setDataAndTypeAndNormalize", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setDataAndTypeAndNormalize", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.data]", "value", "manual"] + - ["android.content", "Intent", True, "setFlags", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setIdentifier", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setPackage", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setPackage", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.content", "Intent", True, "setType", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setTypeAndNormalize", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "SharedPreferences$Editor", True, "clear", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "SharedPreferences$Editor", True, "putBoolean", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "SharedPreferences$Editor", True, "putFloat", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "SharedPreferences$Editor", True, "putInt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "SharedPreferences$Editor", True, "putLong", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "SharedPreferences$Editor", True, "putString", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "SharedPreferences$Editor", True, "putStringSet", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "SharedPreferences$Editor", True, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/android.database.model.yml b/java/ql/lib/ext/android.database.model.yml new file mode 100644 index 00000000000..11aa4a46f74 --- /dev/null +++ b/java/ql/lib/ext/android.database.model.yml @@ -0,0 +1,27 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["android.database", "DatabaseUtils", False, "blobFileDescriptorForQuery", "(SQLiteDatabase,String,String[])", "", "Argument[1]", "sql", "manual"] + - ["android.database", "DatabaseUtils", False, "createDbFromSqlStatements", "(Context,String,int,String)", "", "Argument[3]", "sql", "manual"] + - ["android.database", "DatabaseUtils", False, "longForQuery", "(SQLiteDatabase,String,String[])", "", "Argument[1]", "sql", "manual"] + - ["android.database", "DatabaseUtils", False, "queryNumEntries", "(SQLiteDatabase,String)", "", "Argument[1]", "sql", "manual"] + - ["android.database", "DatabaseUtils", False, "queryNumEntries", "(SQLiteDatabase,String,String)", "", "Argument[1..2]", "sql", "manual"] + - ["android.database", "DatabaseUtils", False, "queryNumEntries", "(SQLiteDatabase,String,String,String[])", "", "Argument[1..2]", "sql", "manual"] + - ["android.database", "DatabaseUtils", False, "stringForQuery", "(SQLiteDatabase,String,String[])", "", "Argument[1]", "sql", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["android.database", "Cursor", True, "copyStringToBuffer", "", "", "Argument[-1]", "Argument[1]", "taint", "manual"] + - ["android.database", "Cursor", True, "getBlob", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database", "Cursor", True, "getColumnName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database", "Cursor", True, "getColumnNames", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database", "Cursor", True, "getExtras", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database", "Cursor", True, "getNotificationUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database", "Cursor", True, "getNotificationUris", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database", "Cursor", True, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database", "Cursor", True, "respond", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database", "DatabaseUtils", False, "appendSelectionArgs", "(String[],String[])", "", "Argument[0..1].ArrayElement", "ReturnValue.ArrayElement", "taint", "manual"] + - ["android.database", "DatabaseUtils", False, "concatenateWhere", "(String,String)", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/android.database.sqlite.model.yml b/java/ql/lib/ext/android.database.sqlite.model.yml new file mode 100644 index 00000000000..09f5b803661 --- /dev/null +++ b/java/ql/lib/ext/android.database.sqlite.model.yml @@ -0,0 +1,89 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["android.database.sqlite", "SQLiteDatabase", False, "compileStatement", "(String)", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "delete", "(String,String,String[])", "", "Argument[0..1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "execPerConnectionSQL", "(String,Object[])", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "execSQL", "(String)", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "execSQL", "(String,Object[])", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String)", "", "Argument[0..2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String)", "", "Argument[4..6]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String,String)", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String,String)", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String,String)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String,String)", "", "Argument[4..7]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[3]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[5..8]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[3]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[5..8]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[3]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[4]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[6..9]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[3]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[4]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[6..9]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "rawQuery", "(String,String[])", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "rawQuery", "(String,String[],CancellationSignal)", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "rawQueryWithFactory", "(CursorFactory,String,String[],String)", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "rawQueryWithFactory", "(CursorFactory,String,String[],String,CancellationSignal)", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "update", "(String,ContentValues,String,String[])", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "update", "(String,ContentValues,String,String[])", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "updateWithOnConflict", "(String,ContentValues,String,String[],int)", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "updateWithOnConflict", "(String,ContentValues,String,String[],int)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "delete", "(SQLiteDatabase,String,String[])", "", "Argument[-1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "delete", "(SQLiteDatabase,String,String[])", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "insert", "(SQLiteDatabase,ContentValues)", "", "Argument[-1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String)", "", "Argument[-1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String)", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String)", "", "Argument[4..6]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String)", "", "Argument[-1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String)", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String)", "", "Argument[4..7]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[-1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[4..7]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "update", "(SQLiteDatabase,ContentValues,String,String[])", "", "Argument[-1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "update", "(SQLiteDatabase,ContentValues,String,String[])", "", "Argument[2]", "sql", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "appendColumns", "(StringBuilder,String[])", "", "Argument[1].ArrayElement", "Argument[0]", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "appendWhere", "(CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "appendWhereStandalone", "(CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQuery", "(String[],String,String,String,String,String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQuery", "(String[],String,String,String,String,String)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQuery", "(String[],String,String,String,String,String)", "", "Argument[1..5]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQuery", "(String[],String,String[],String,String,String,String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQuery", "(String[],String,String[],String,String,String,String)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQuery", "(String[],String,String[],String,String,String,String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQuery", "(String[],String,String[],String,String,String,String)", "", "Argument[3..6]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQueryString", "(boolean,String,String[],String,String,String,String,String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQueryString", "(boolean,String,String[],String,String,String,String,String)", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQueryString", "(boolean,String,String[],String,String,String,String,String)", "", "Argument[3..7]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionQuery", "(String[],String,String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionQuery", "(String[],String,String)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionQuery", "(String[],String,String)", "", "Argument[1..2]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String,String)", "", "Argument[-1..0]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String,String)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String,String)", "", "Argument[2].Element", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String,String)", "", "Argument[4..7]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String[],String,String)", "", "Argument[-1..0]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String[],String,String)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String[],String,String)", "", "Argument[2].Element", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String[],String,String)", "", "Argument[4..5]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String[],String,String)", "", "Argument[7..8]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "setProjectionMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "setProjectionMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "setTables", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/android.net.model.yml b/java/ql/lib/ext/android.net.model.yml new file mode 100644 index 00000000000..222ef1e0a2e --- /dev/null +++ b/java/ql/lib/ext/android.net.model.yml @@ -0,0 +1,65 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["android.net", "Uri", True, "buildUpon", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", False, "decode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", False, "encode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", False, "fromFile", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", False, "fromParts", "", "", "Argument[0..2]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getAuthority", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getEncodedAuthority", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getEncodedFragment", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getEncodedPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getEncodedQuery", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getEncodedSchemeSpecificPart", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getEncodedUserInfo", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getFragment", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getHost", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getLastPathSegment", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getPathSegments", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getQuery", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getQueryParameter", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getQueryParameterNames", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getQueryParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getScheme", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getSchemeSpecificPart", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getUserInfo", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "normalizeScheme", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", False, "parse", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", False, "withAppendedPath", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", False, "writeToParcel", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "appendEncodedPath", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "appendEncodedPath", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "appendPath", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "appendPath", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "appendQueryParameter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "appendQueryParameter", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "authority", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "authority", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "clearQuery", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "encodedAuthority", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "encodedAuthority", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "encodedFragment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "encodedFragment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "encodedOpaquePart", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "encodedOpaquePart", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "encodedPath", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "encodedPath", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "encodedQuery", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "encodedQuery", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "fragment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "fragment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "opaquePart", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "opaquePart", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "path", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "path", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "query", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "query", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "scheme", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "scheme", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/android.os.model.yml b/java/ql/lib/ext/android.os.model.yml new file mode 100644 index 00000000000..8581a3f47ae --- /dev/null +++ b/java/ql/lib/ext/android.os.model.yml @@ -0,0 +1,133 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["android.os", "Environment", False, "getExternalStorageDirectory", "()", "", "ReturnValue", "android-external-storage-dir", "manual"] + - ["android.os", "Environment", False, "getExternalStoragePublicDirectory", "(String)", "", "ReturnValue", "android-external-storage-dir", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["android.os", "BaseBundle", True, "get", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "BaseBundle", True, "getString", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "BaseBundle", True, "getString", "(String,String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "BaseBundle", True, "getString", "(String,String)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["android.os", "BaseBundle", True, "getStringArray", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "BaseBundle", True, "keySet", "()", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["android.os", "BaseBundle", True, "putAll", "(PersistableBundle)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putAll", "(PersistableBundle)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "BaseBundle", True, "putBoolean", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putBooleanArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putDouble", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putDoubleArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putInt", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putIntArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putLong", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putLongArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putString", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putString", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "BaseBundle", True, "putStringArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putStringArray", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", False, "Bundle", "(Bundle)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", False, "Bundle", "(Bundle)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", False, "Bundle", "(PersistableBundle)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", False, "Bundle", "(PersistableBundle)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "clone", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "clone", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "deepCopy", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "deepCopy", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "getBinder", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getBundle", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getByteArray", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getCharArray", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getCharSequence", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getCharSequence", "(String,CharSequence)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getCharSequence", "(String,CharSequence)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getCharSequenceArray", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getCharSequenceArrayList", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getParcelable", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getParcelableArray", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getParcelableArrayList", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getSerializable", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getSparseParcelableArray", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getStringArrayList", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "putAll", "(Bundle)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putAll", "(Bundle)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putBinder", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putBinder", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putBundle", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putBundle", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putByte", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putByteArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putByteArray", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putChar", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putCharArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putCharArray", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putCharSequence", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putCharSequence", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putCharSequenceArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putCharSequenceArray", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putCharSequenceArrayList", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putCharSequenceArrayList", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putFloat", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putFloatArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putIntegerArrayList", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putParcelable", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putParcelable", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putParcelableArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putParcelableArray", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putParcelableArrayList", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putParcelableArrayList", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putSerializable", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putSerializable", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putShort", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putShortArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putSize", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putSizeF", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putSparseParcelableArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putSparseParcelableArray", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putStringArrayList", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putStringArrayList", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "readFromParcel", "", "", "Argument[0]", "Argument[-1].MapKey", "taint", "manual"] + - ["android.os", "Bundle", True, "readFromParcel", "", "", "Argument[0]", "Argument[-1].MapValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readArrayList", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readBinderArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readBinderList", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readBooleanArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readBundle", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readByte", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readByteArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readCharArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readDouble", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readDoubleArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readFileDescriptor", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readFloat", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readFloatArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readHashMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readIntArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readList", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readLong", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readLongArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readMap", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readParcelable", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readParcelableArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readParcelableList", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readParcelableList", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["android.os", "Parcel", False, "readPersistableBundle", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readSerializable", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readSize", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readSizeF", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readSparseArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readSparseBooleanArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readStringArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readStringList", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readStrongBinder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readTypedArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readTypedList", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readTypedObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/android.support.v4.app.model.yml b/java/ql/lib/ext/android.support.v4.app.model.yml new file mode 100644 index 00000000000..42df9f0a87a --- /dev/null +++ b/java/ql/lib/ext/android.support.v4.app.model.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["android.support.v4.app", "FragmentTransaction", True, "add", "(Class,Bundle,String)", "", "Argument[0]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "add", "(Fragment,String)", "", "Argument[0]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "add", "(int,Class,Bundle)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "add", "(int,Class,Bundle,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "add", "(int,Fragment)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "add", "(int,Fragment,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "attach", "(Fragment)", "", "Argument[0]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "replace", "(int,Class,Bundle)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "replace", "(int,Class,Bundle,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "replace", "(int,Fragment)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "replace", "(int,Fragment,String)", "", "Argument[1]", "fragment-injection", "manual"] diff --git a/java/ql/lib/ext/android.util.model.yml b/java/ql/lib/ext/android.util.model.yml new file mode 100644 index 00000000000..63d0612ea41 --- /dev/null +++ b/java/ql/lib/ext/android.util.model.yml @@ -0,0 +1,31 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["android.util", "AttributeSet", False, "getAttributeBooleanValue", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeCount", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeFloatValue", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeIntValue", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeListValue", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeName", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeNameResource", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeNamespace", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeResourceValue", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeUnsignedIntValue", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeValue", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getClassAttribute", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getIdAttribute", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getIdAttributeResourceValue", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getPositionDescription", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getStyleAttribute", "", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["android.util", "Log", True, "d", "", "", "Argument[1]", "logging", "manual"] + - ["android.util", "Log", True, "e", "", "", "Argument[1]", "logging", "manual"] + - ["android.util", "Log", True, "i", "", "", "Argument[1]", "logging", "manual"] + - ["android.util", "Log", True, "v", "", "", "Argument[1]", "logging", "manual"] + - ["android.util", "Log", True, "w", "", "", "Argument[1]", "logging", "manual"] + - ["android.util", "Log", True, "wtf", "", "", "Argument[1]", "logging", "manual"] diff --git a/java/ql/lib/ext/android.webkit.model.yml b/java/ql/lib/ext/android.webkit.model.yml new file mode 100644 index 00000000000..a12ffdd44dd --- /dev/null +++ b/java/ql/lib/ext/android.webkit.model.yml @@ -0,0 +1,14 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["android.webkit", "WebView", False, "getOriginalUrl", "()", "", "ReturnValue", "remote", "manual"] + - ["android.webkit", "WebView", False, "getUrl", "()", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["android.webkit", "WebView", False, "evaluateJavascript", "", "", "Argument[0]", "xss", "manual"] + - ["android.webkit", "WebView", False, "loadData", "", "", "Argument[0]", "xss", "manual"] + - ["android.webkit", "WebView", False, "loadDataWithBaseURL", "", "", "Argument[1]", "xss", "manual"] diff --git a/java/ql/lib/ext/android.widget.model.yml b/java/ql/lib/ext/android.widget.model.yml new file mode 100644 index 00000000000..917167d6156 --- /dev/null +++ b/java/ql/lib/ext/android.widget.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["android.widget", "EditText", True, "getText", "", "", "ReturnValue", "android-widget", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["android.widget", "EditText", True, "getText", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/androidx.core.app.model.yml b/java/ql/lib/ext/androidx.core.app.model.yml new file mode 100644 index 00000000000..48a97fbba57 --- /dev/null +++ b/java/ql/lib/ext/androidx.core.app.model.yml @@ -0,0 +1,110 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["androidx.core.app", "AlarmManagerCompat", True, "setAlarmClock", "", "", "Argument[2..3]", "pending-intent-sent", "manual"] + - ["androidx.core.app", "AlarmManagerCompat", True, "setAndAllowWhileIdle", "", "", "Argument[3]", "pending-intent-sent", "manual"] + - ["androidx.core.app", "AlarmManagerCompat", True, "setExact", "", "", "Argument[3]", "pending-intent-sent", "manual"] + - ["androidx.core.app", "AlarmManagerCompat", True, "setExactAndAllowWhileIdle", "", "", "Argument[3]", "pending-intent-sent", "manual"] + - ["androidx.core.app", "NotificationManagerCompat", True, "notify", "(String,int,Notification)", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["androidx.core.app", "NotificationManagerCompat", True, "notify", "(int,Notification)", "", "Argument[1]", "pending-intent-sent", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["androidx.core.app", "NotificationCompat$Action", True, "Action", "(IconCompat,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Action", True, "Action", "(int,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Action", True, "getExtras", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "Builder", "(Action)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "Builder", "(IconCompat,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "Builder", "(int,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "addExtras", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "addExtras", "", "", "Argument[0].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "addExtras", "", "", "Argument[0].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "addRemoteInput", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "build", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue.SyntheticField[android.content.Intent.extras]", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "extend", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "getExtras", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "setAllowGeneratedReplies", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "setAuthenticationRequired", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "setContextual", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "setSemanticAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigPictureStyle", True, "bigLargeIcon", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigPictureStyle", True, "bigPicture", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigPictureStyle", True, "setBigContentTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigPictureStyle", True, "setContentDescription", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigPictureStyle", True, "setSummaryText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigPictureStyle", True, "showBigPictureWhenCollapsed", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigTextStyle", True, "bigText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigTextStyle", True, "setBigContentTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigTextStyle", True, "setSummaryText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "addAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "addAction", "(Action)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "addAction", "(int,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "addExtras", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "addExtras", "", "", "Argument[0].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "addExtras", "", "", "Argument[0].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "addPerson", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "build", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue.Field[android.app.Notification.extras]", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "extend", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "getExtras", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setActions", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setAutoCancel", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setBadgeIconType", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setBubbleMetadata", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setCategory", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setChannelId", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setChronometerCountDown", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setColor", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setColorized", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setContent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setContentInfo", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setContentIntent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setContentIntent", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setContentText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setContentTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setCustomBigContentView", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setCustomHeadsUpContentView", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setDefaults", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setDeleteIntent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setDeleteIntent", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setExtras", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setExtras", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.extras]", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setFlag", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setForegroundServiceBehavior", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setFullScreenIntent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setGroup", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setGroupAlertBehavior", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setGroupSummary", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setLargeIcon", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setLights", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setLocalOnly", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setLocusId", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setNumber", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setOngoing", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setOnlyAlertOnce", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setPriority", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setProgress", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setPublicVersion", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setPublicVersion", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setRemoteInputHistory", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setSettingsText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setShortcutId", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setShowWhen", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setSmallIcon", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setSortKey", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setSound", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setStyle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setSubText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setTicker", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setTimeoutAfter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setUsesChronometer", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setVibrate", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setVisibility", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setWhen", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$InboxStyle", True, "addLine", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$InboxStyle", True, "setBigContentTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$InboxStyle", True, "setSummaryText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/androidx.fragment.app.model.yml b/java/ql/lib/ext/androidx.fragment.app.model.yml new file mode 100644 index 00000000000..8e219640c7d --- /dev/null +++ b/java/ql/lib/ext/androidx.fragment.app.model.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["androidx.fragment.app", "FragmentTransaction", True, "add", "(Class,Bundle,String)", "", "Argument[0]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "add", "(Fragment,String)", "", "Argument[0]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "add", "(int,Class,Bundle)", "", "Argument[1]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "add", "(int,Class,Bundle,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "add", "(int,Fragment)", "", "Argument[1]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "add", "(int,Fragment,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "attach", "(Fragment)", "", "Argument[0]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "replace", "(int,Class,Bundle)", "", "Argument[1]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "replace", "(int,Class,Bundle,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "replace", "(int,Fragment)", "", "Argument[1]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "replace", "(int,Fragment,String)", "", "Argument[1]", "fragment-injection", "manual"] diff --git a/java/ql/lib/ext/androidx.slice.builders.model.yml b/java/ql/lib/ext/androidx.slice.builders.model.yml new file mode 100644 index 00000000000..066fae518b2 --- /dev/null +++ b/java/ql/lib/ext/androidx.slice.builders.model.yml @@ -0,0 +1,93 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["androidx.slice.builders", "ListBuilder", True, "addAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addAction", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addGridRow", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addGridRow", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addInputRange", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addInputRange", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addRange", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addRange", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addRating", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addRating", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addRow", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addRow", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addSelection", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addSelection", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "build", "", "", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "ReturnValue", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setAccentColor", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setHeader", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setHeader", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setHostExtras", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setIsError", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setKeywords", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setLayoutDirection", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setSeeMoreAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setSeeMoreAction", "(PendingIntent)", "", "Argument[0]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setSeeMoreRow", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setSeeMoreRow", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$HeaderBuilder", True, "setContentDescription", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$HeaderBuilder", True, "setLayoutDirection", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$HeaderBuilder", True, "setPrimaryAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$HeaderBuilder", True, "setPrimaryAction", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$HeaderBuilder", True, "setSubtitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$HeaderBuilder", True, "setSummary", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$HeaderBuilder", True, "setTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "addEndItem", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "addEndItem", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setContentDescription", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setInputAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setInputAction", "(PendingIntent)", "", "Argument[0]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setLayoutDirection", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setMax", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setMin", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setPrimaryAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setPrimaryAction", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setSubtitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setThumb", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setTitleItem", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setValue", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setContentDescription", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setMax", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setMode", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setPrimaryAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setPrimaryAction", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setSubtitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setTitleItem", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setValue", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setContentDescription", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setInputAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setInputAction", "(PendingIntent)", "", "Argument[0]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setMax", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setMin", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setPrimaryAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setPrimaryAction", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setSubtitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setTitleItem", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setValue", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "addEndItem", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "addEndItem", "(SliceAction)", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "addEndItem", "(SliceAction,boolean)", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setContentDescription", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setEndOfSection", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setLayoutDirection", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setPrimaryAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setPrimaryAction", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setSubtitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setTitleItem", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setTitleItem", "(SliceAction)", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setTitleItem", "(SliceAction,boolean)", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "SliceAction", True, "create", "(PendingIntent,IconCompat,int,CharSequence)", "", "Argument[0]", "ReturnValue.SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "SliceAction", True, "createDeeplink", "(PendingIntent,IconCompat,int,CharSequence)", "", "Argument[0]", "ReturnValue.SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "SliceAction", True, "createToggle", "(PendingIntent,CharSequence,boolean)", "", "Argument[0]", "ReturnValue.SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "SliceAction", True, "getAction", "", "", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "ReturnValue", "taint", "manual"] + - ["androidx.slice.builders", "SliceAction", True, "setChecked", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "SliceAction", True, "setContentDescription", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "SliceAction", True, "setPriority", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/androidx.slice.model.yml b/java/ql/lib/ext/androidx.slice.model.yml new file mode 100644 index 00000000000..770b1797538 --- /dev/null +++ b/java/ql/lib/ext/androidx.slice.model.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["androidx.slice", "SliceProvider", True, "onBindSlice", "", "", "Parameter[0]", "contentprovider", "manual"] + - ["androidx.slice", "SliceProvider", True, "onCreatePermissionRequest", "", "", "Parameter[0]", "contentprovider", "manual"] + - ["androidx.slice", "SliceProvider", True, "onMapIntentToUri", "", "", "Parameter[0]", "contentprovider", "manual"] + - ["androidx.slice", "SliceProvider", True, "onSlicePinned", "", "", "Parameter[0]", "contentprovider", "manual"] + - ["androidx.slice", "SliceProvider", True, "onSliceUnpinned", "", "", "Parameter[0]", "contentprovider", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["androidx.slice", "SliceProvider", True, "onBindSlice", "", "", "ReturnValue", "pending-intent-sent", "manual"] + - ["androidx.slice", "SliceProvider", True, "onCreatePermissionRequest", "", "", "ReturnValue", "pending-intent-sent", "manual"] diff --git a/java/ql/lib/ext/cn.hutool.core.codec.model.yml b/java/ql/lib/ext/cn.hutool.core.codec.model.yml new file mode 100644 index 00000000000..fdd0766ffe4 --- /dev/null +++ b/java/ql/lib/ext/cn.hutool.core.codec.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["cn.hutool.core.codec", "Base64", True, "decode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/com.esotericsoftware.kryo.io.model.yml b/java/ql/lib/ext/com.esotericsoftware.kryo.io.model.yml new file mode 100644 index 00000000000..0acf40fe015 --- /dev/null +++ b/java/ql/lib/ext/com.esotericsoftware.kryo.io.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["com.esotericsoftware.kryo.io", "Input", False, "Input", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/com.esotericsoftware.kryo5.io.model.yml b/java/ql/lib/ext/com.esotericsoftware.kryo5.io.model.yml new file mode 100644 index 00000000000..e71107e7a63 --- /dev/null +++ b/java/ql/lib/ext/com.esotericsoftware.kryo5.io.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["com.esotericsoftware.kryo5.io", "Input", False, "Input", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/com.fasterxml.jackson.core.model.yml b/java/ql/lib/ext/com.fasterxml.jackson.core.model.yml new file mode 100644 index 00000000000..7510d7ed936 --- /dev/null +++ b/java/ql/lib/ext/com.fasterxml.jackson.core.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["com.fasterxml.jackson.core", "JsonFactory", False, "createParser", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/com.fasterxml.jackson.databind.model.yml b/java/ql/lib/ext/com.fasterxml.jackson.databind.model.yml new file mode 100644 index 00000000000..880b6bee044 --- /dev/null +++ b/java/ql/lib/ext/com.fasterxml.jackson.databind.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["com.fasterxml.jackson.databind", "ObjectMapper", True, "convertValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.fasterxml.jackson.databind", "ObjectMapper", False, "createParser", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.fasterxml.jackson.databind", "ObjectMapper", True, "valueToTree", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.fasterxml.jackson.databind", "ObjectMapper", True, "valueToTree", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["com.fasterxml.jackson.databind", "ObjectMapper", True, "valueToTree", "", "", "Argument[0].MapValue.Element", "ReturnValue", "taint", "manual"] + - ["com.fasterxml.jackson.databind", "ObjectReader", False, "createParser", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/com.google.common.base.model.yml b/java/ql/lib/ext/com.google.common.base.model.yml new file mode 100644 index 00000000000..aaff117fbed --- /dev/null +++ b/java/ql/lib/ext/com.google.common.base.model.yml @@ -0,0 +1,98 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["com.google.common.base", "Splitter", False, "onPattern", "(String)", "", "Argument[0]", "regex-use[]", "manual"] + - ["com.google.common.base", "Splitter", False, "split", "(CharSequence)", "", "Argument[-1]", "regex-use[0]", "manual"] + - ["com.google.common.base", "Splitter", False, "splitToList", "(CharSequence)", "", "Argument[-1]", "regex-use[0]", "manual"] + - ["com.google.common.base", "Splitter$MapSplitter", False, "split", "(CharSequence)", "", "Argument[-1]", "regex-use[0]", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["com.google.common.base", "Ascii", False, "toLowerCase", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Ascii", False, "toLowerCase", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Ascii", False, "toUpperCase", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Ascii", False, "toUpperCase", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Ascii", False, "truncate", "(CharSequence,int,String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Ascii", False, "truncate", "(CharSequence,int,String)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "CaseFormat", True, "to", "(CaseFormat,String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Converter", True, "apply", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Converter", True, "convert", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Converter", True, "convertAll", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(Appendable,Iterable)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(Appendable,Iterator)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(Appendable,Object,Object,Object[])", "", "Argument[1..2]", "Argument[0]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(Appendable,Object,Object,Object[])", "", "Argument[3].ArrayElement", "Argument[0]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(Appendable,Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(StringBuilder,Iterable)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(StringBuilder,Iterator)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(StringBuilder,Object,Object,Object[])", "", "Argument[1..2]", "Argument[0]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(StringBuilder,Object,Object,Object[])", "", "Argument[3].ArrayElement", "Argument[0]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(StringBuilder,Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "join", "", "", "Argument[-1..2]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "on", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "skipNulls", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "useForNull", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "useForNull", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "withKeyValueSeparator", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "withKeyValueSeparator", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "withKeyValueSeparator", "(char)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "appendTo", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "appendTo", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "join", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "join", "(Iterable)", "", "Argument[0].Element.MapKey", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "join", "(Iterable)", "", "Argument[0].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "join", "(Iterator)", "", "Argument[0].Element.MapKey", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "join", "(Iterator)", "", "Argument[0].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "join", "(Map)", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "join", "(Map)", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "useForNull", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "useForNull", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "MoreObjects", False, "firstNonNull", "(Object,Object)", "", "Argument[0..1]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "MoreObjects", False, "toStringHelper", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "add", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "add", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "add", "(String,Object)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "add", "(String,Object)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "addValue", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "addValue", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "addValue", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "omitNullValues", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Optional", True, "asSet", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.base", "Optional", True, "fromJavaUtil", "(Optional)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.base", "Optional", True, "fromNullable", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.base", "Optional", True, "get", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Optional", True, "of", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.base", "Optional", True, "or", "(Object)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Optional", True, "or", "(Object)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Optional", True, "or", "(Optional)", "", "Argument[-1..0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.base", "Optional", True, "or", "(Supplier)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Optional", True, "or", "(Supplier)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Optional", True, "orNull", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Optional", True, "presentInstances", "(Iterable)", "", "Argument[0].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.base", "Optional", True, "toJavaUtil", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.base", "Optional", True, "toJavaUtil", "(Optional)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.base", "Preconditions", False, "checkNotNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Splitter", False, "split", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Splitter", False, "splitToList", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Splitter", False, "splitToStream", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Splitter$MapSplitter", False, "split", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Strings", False, "emptyToNull", "(String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Strings", False, "lenientFormat", "(String,Object[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Strings", False, "lenientFormat", "(String,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Strings", False, "nullToEmpty", "(String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Strings", False, "padEnd", "(String,int,char)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Strings", False, "padStart", "(String,int,char)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Strings", False, "repeat", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Supplier", True, "get", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Suppliers", False, "memoize", "(Supplier)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Suppliers", False, "memoizeWithExpiration", "(Supplier,long,TimeUnit)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Suppliers", False, "ofInstance", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Suppliers", False, "synchronizedSupplier", "(Supplier)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Verify", False, "verifyNotNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/com.google.common.cache.model.yml b/java/ql/lib/ext/com.google.common.cache.model.yml new file mode 100644 index 00000000000..673ee594992 --- /dev/null +++ b/java/ql/lib/ext/com.google.common.cache.model.yml @@ -0,0 +1,22 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["com.google.common.cache", "Cache", True, "asMap", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "asMap", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "get", "(Object,Callable)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "getAllPresent", "(Iterable)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "getAllPresent", "(Iterable)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "getAllPresent", "(Iterable)", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "getIfPresent", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "put", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "put", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "putAll", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.cache", "LoadingCache", True, "apply", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.common.cache", "LoadingCache", True, "get", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.common.cache", "LoadingCache", True, "getAll", "(Iterable)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.cache", "LoadingCache", True, "getAll", "(Iterable)", "", "Argument[0].Element", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.cache", "LoadingCache", True, "getAll", "(Iterable)", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.cache", "LoadingCache", True, "getUnchecked", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/com.google.common.collect.model.yml b/java/ql/lib/ext/com.google.common.collect.model.yml new file mode 100644 index 00000000000..434fb34d728 --- /dev/null +++ b/java/ql/lib/ext/com.google.common.collect.model.yml @@ -0,0 +1,558 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["com.google.common.collect", "ArrayListMultimap", True, "create", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ArrayListMultimap", True, "create", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ArrayTable", True, "create", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "ArrayTable", True, "create", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "ArrayTable", True, "create", "(Table)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ArrayTable", True, "create", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "ArrayTable", True, "create", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "BiMap", True, "forcePut", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "BiMap", True, "forcePut", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "BiMap", True, "inverse", "()", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "BiMap", True, "inverse", "()", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ClassToInstanceMap", True, "getInstance", "(Class)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ClassToInstanceMap", True, "putInstance", "(Class,Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ClassToInstanceMap", True, "putInstance", "(Class,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "Collections2", False, "filter", "(Collection,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Collections2", False, "orderedPermutations", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Collections2", False, "orderedPermutations", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Collections2", False, "permutations", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "ConcurrentHashMultiset", True, "create", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "HashBasedTable", True, "create", "(Table)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "HashBasedTable", True, "create", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "HashBasedTable", True, "create", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "HashBiMap", True, "create", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "HashBiMap", True, "create", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "HashMultimap", True, "create", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "HashMultimap", True, "create", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "HashMultiset", True, "create", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[2]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[3]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[4]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[5]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[6]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[7]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[8]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[9]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableClassToInstanceMap", True, "copyOf", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableClassToInstanceMap", True, "copyOf", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableClassToInstanceMap", True, "of", "(Class,Object)", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableClassToInstanceMap", True, "of", "(Class,Object)", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableCollection", True, "asList", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableCollection$Builder", True, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableCollection$Builder", True, "add", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableCollection$Builder", True, "add", "(Object[])", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableCollection$Builder", True, "addAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableCollection$Builder", True, "addAll", "(Iterable)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableCollection$Builder", True, "addAll", "(Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableCollection$Builder", True, "build", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "copyOf", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "copyOf", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "copyOf", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "copyOf", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "of", "", "", "Argument[0..11]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "of", "", "", "Argument[12].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "reverse", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "sortedCopyOf", "(Comparator,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "sortedCopyOf", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[2]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[3]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[4]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[5]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[6]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[7]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[8]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[9]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "copyOf", "(Iterable)", "", "Argument[0].Element.MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "copyOf", "(Iterable)", "", "Argument[0].Element.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "copyOf", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "copyOf", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[2]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[3]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[4]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[5]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[6]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[7]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[8]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[9]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "build", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "build", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "orderEntriesByValue", "(Comparator)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "put", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "put", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "put", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "put", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "put", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "putAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "putAll", "(Iterable)", "", "Argument[0].Element.MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "putAll", "(Iterable)", "", "Argument[0].Element.MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "putAll", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "copyOf", "(Iterable)", "", "Argument[0].Element.MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "copyOf", "(Iterable)", "", "Argument[0].Element.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "copyOf", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "copyOf", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "inverse", "()", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "inverse", "()", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[2]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[3]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[4]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[5]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[6]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[7]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[8]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[9]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "build", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "build", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "orderKeysBy", "(Comparator)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "orderValuesBy", "(Comparator)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "put", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "put", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "put", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "put", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "put", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "(Iterable)", "", "Argument[0].Element.MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "(Iterable)", "", "Argument[0].Element.MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "(Multimap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "(Multimap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "(Object,Object[])", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultiset", True, "copyOf", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultiset", True, "copyOf", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultiset", True, "copyOf", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultiset", True, "of", "", "", "Argument[0..5]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultiset", True, "of", "", "", "Argument[6].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultiset$Builder", True, "addCopies", "(Object,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultiset$Builder", True, "addCopies", "(Object,int)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultiset$Builder", True, "setCount", "(Object,int)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSet", True, "copyOf", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSet", True, "copyOf", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSet", True, "copyOf", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSet", True, "copyOf", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSet", True, "of", "", "", "Argument[0..5]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSet", True, "of", "", "", "Argument[6].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[2]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[3]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[4]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[5]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[6]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[7]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[8]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[9]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOf", "(Iterable)", "", "Argument[0].Element.MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOf", "(Iterable)", "", "Argument[0].Element.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOf", "(Iterable,Comparator)", "", "Argument[0].Element.MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOf", "(Iterable,Comparator)", "", "Argument[0].Element.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOf", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOf", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOf", "(Map,Comparator)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOf", "(Map,Comparator)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOfSorted", "(SortedMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOfSorted", "(SortedMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[2]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[3]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[4]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[5]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[6]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[7]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[8]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[9]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMultiset", True, "copyOf", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMultiset", True, "copyOf", "(Comparator,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMultiset", True, "copyOf", "(Comparator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMultiset", True, "copyOf", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMultiset", True, "copyOf", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMultiset", True, "copyOfSorted", "(SortedMultiset)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMultiset", True, "of", "", "", "Argument[0..5]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMultiset", True, "of", "", "", "Argument[6].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "copyOf", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "copyOf", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "copyOf", "(Comparator,Collection)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "copyOf", "(Comparator,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "copyOf", "(Comparator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "copyOf", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "copyOf", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "copyOfSorted", "(SortedSet)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "of", "", "", "Argument[0..5]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "of", "", "", "Argument[6].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable", True, "copyOf", "(Table)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable", True, "copyOf", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable", True, "copyOf", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable", True, "of", "(Object,Object,Object)", "", "Argument[0]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable", True, "of", "(Object,Object,Object)", "", "Argument[1]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable", True, "of", "(Object,Object,Object)", "", "Argument[2]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "build", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "build", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "build", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "orderColumnsBy", "(Comparator)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "orderRowsBy", "(Comparator)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "put", "(Cell)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "put", "(Cell)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "put", "(Cell)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "put", "(Cell)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "put", "(Object,Object,Object)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "put", "(Object,Object,Object)", "", "Argument[0]", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "put", "(Object,Object,Object)", "", "Argument[1]", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "put", "(Object,Object,Object)", "", "Argument[2]", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "putAll", "(Table)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "putAll", "(Table)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "putAll", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "putAll", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "addAll", "(Collection,Iterable)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "concat", "(Iterable)", "", "Argument[0].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "concat", "(Iterable,Iterable)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "concat", "(Iterable,Iterable,Iterable)", "", "Argument[0..2].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "concat", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[0..3].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "concat", "(Iterable[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "consumingIterable", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "cycle", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "cycle", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "filter", "(Iterable,Class)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "filter", "(Iterable,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "find", "(Iterable,Predicate)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "find", "(Iterable,Predicate,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "find", "(Iterable,Predicate,Object)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "get", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "get", "(Iterable,int,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "get", "(Iterable,int,Object)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "getLast", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "getLast", "(Iterable,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "getLast", "(Iterable,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "getOnlyElement", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "getOnlyElement", "(Iterable,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "getOnlyElement", "(Iterable,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "limit", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "mergeSorted", "(Iterable,Comparator)", "", "Argument[0].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "paddedPartition", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "partition", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "skip", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "toArray", "(Iterable,Class)", "", "Argument[0].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "tryFind", "(Iterable,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "unmodifiableIterable", "(ImmutableCollection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "unmodifiableIterable", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "addAll", "(Collection,Iterator)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "asEnumeration", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "concat", "(Iterator)", "", "Argument[0].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "concat", "(Iterator,Iterator)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "concat", "(Iterator,Iterator,Iterator)", "", "Argument[0..2].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "concat", "(Iterator,Iterator,Iterator,Iterator)", "", "Argument[0..3].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "concat", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "consumingIterator", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "cycle", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "cycle", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "filter", "(Iterator,Class)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "filter", "(Iterator,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "find", "(Iterator,Predicate)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "find", "(Iterator,Predicate,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "find", "(Iterator,Predicate,Object)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "forArray", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "forEnumeration", "(Enumeration)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "get", "(Iterator,int)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "get", "(Iterator,int,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "get", "(Iterator,int,Object)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "getLast", "(Iterator)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "getLast", "(Iterator,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "getLast", "(Iterator,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "getNext", "(Iterator,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "getNext", "(Iterator,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "getOnlyElement", "(Iterator)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "getOnlyElement", "(Iterator,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "getOnlyElement", "(Iterator,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "limit", "(Iterator,int)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "mergeSorted", "(Iterable,Comparator)", "", "Argument[0].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "paddedPartition", "(Iterator,int)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "partition", "(Iterator,int)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "peekingIterator", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "peekingIterator", "(PeekingIterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "singletonIterator", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "toArray", "(Iterator,Class)", "", "Argument[0].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "tryFind", "(Iterator,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "unmodifiableIterator", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "unmodifiableIterator", "(UnmodifiableIterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "LinkedHashMultimap", True, "create", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "LinkedHashMultimap", True, "create", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "LinkedHashMultiset", True, "create", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "LinkedListMultimap", True, "create", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "LinkedListMultimap", True, "create", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "asList", "(Object,Object,Object[])", "", "Argument[0..1]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "asList", "(Object,Object,Object[])", "", "Argument[2].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "asList", "(Object,Object[])", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "asList", "(Object,Object[])", "", "Argument[1].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "cartesianProduct", "(List)", "", "Argument[0].Element.Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "cartesianProduct", "(List[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "charactersOf", "(CharSequence)", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] + - ["com.google.common.collect", "Lists", False, "charactersOf", "(String)", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] + - ["com.google.common.collect", "Lists", False, "newArrayList", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "newArrayList", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "newArrayList", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "newCopyOnWriteArrayList", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "newLinkedList", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "partition", "(List,int)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "reverse", "(List)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesDiffering", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesDiffering", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapValue", "ReturnValue.MapValue.SyntheticField[com.google.common.collect.MapDifference.left]", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesDiffering", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesDiffering", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapValue", "ReturnValue.MapValue.SyntheticField[com.google.common.collect.MapDifference.right]", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesInCommon", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesInCommon", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesInCommon", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesInCommon", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesOnlyOnLeft", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesOnlyOnLeft", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesOnlyOnRight", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesOnlyOnRight", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "MapDifference$ValueDifference", True, "leftValue", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "MapDifference$ValueDifference", True, "rightValue", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "asMap", "(NavigableSet,Function)", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "asMap", "(Set,Function)", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "asMap", "(SortedSet,Function)", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(Map,Map)", "", "Argument[0].MapKey", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(Map,Map)", "", "Argument[0].MapValue", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(Map,Map)", "", "Argument[1].MapKey", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(Map,Map)", "", "Argument[1].MapValue", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(Map,Map,Equivalence)", "", "Argument[0].MapKey", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(Map,Map,Equivalence)", "", "Argument[0].MapValue", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(Map,Map,Equivalence)", "", "Argument[1].MapKey", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(Map,Map,Equivalence)", "", "Argument[1].MapValue", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(SortedMap,Map)", "", "Argument[0].MapKey", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(SortedMap,Map)", "", "Argument[0].MapValue", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(SortedMap,Map)", "", "Argument[1].MapKey", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(SortedMap,Map)", "", "Argument[1].MapValue", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "filterEntries", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "filterKeys", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "filterValues", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "fromProperties", "(Properties)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "fromProperties", "(Properties)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "immutableEntry", "(Object,Object)", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "immutableEntry", "(Object,Object)", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "immutableEnumMap", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "newEnumMap", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "newHashMap", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "newHashMap", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "newLinkedHashMap", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "newLinkedHashMap", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "newTreeMap", "(SortedMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "newTreeMap", "(SortedMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "subMap", "(NavigableMap,Range)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "subMap", "(NavigableMap,Range)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "synchronizedBiMap", "(BiMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "synchronizedBiMap", "(BiMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "synchronizedNavigableMap", "(NavigableMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "synchronizedNavigableMap", "(NavigableMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "toMap", "(Iterable,Function)", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "toMap", "(Iterator,Function)", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "transformValues", "(Map,Function)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "transformValues", "(NavigableMap,Function)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "transformValues", "(SortedMap,Function)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "uniqueIndex", "(Iterable,Function)", "", "Argument[0].Element", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "uniqueIndex", "(Iterator,Function)", "", "Argument[0].Element", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "unmodifiableBiMap", "(BiMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "unmodifiableBiMap", "(BiMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "unmodifiableNavigableMap", "(NavigableMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "unmodifiableNavigableMap", "(NavigableMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "asMap", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "asMap", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "entries", "()", "", "Argument[-1].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "entries", "()", "", "Argument[-1].MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "get", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "keySet", "()", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "keys", "()", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "put", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "put", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "putAll", "(Multimap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "putAll", "(Multimap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "putAll", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "putAll", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "removeAll", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "replaceValues", "(Object,Iterable)", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "replaceValues", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "replaceValues", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "values", "()", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "asMap", "(ListMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "asMap", "(ListMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "asMap", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "asMap", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "asMap", "(SetMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "asMap", "(SetMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "asMap", "(SortedSetMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "asMap", "(SortedSetMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterEntries", "(Multimap,Predicate)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterEntries", "(Multimap,Predicate)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterEntries", "(SetMultimap,Predicate)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterEntries", "(SetMultimap,Predicate)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterKeys", "(Multimap,Predicate)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterKeys", "(Multimap,Predicate)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterKeys", "(SetMultimap,Predicate)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterKeys", "(SetMultimap,Predicate)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterValues", "(Multimap,Predicate)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterValues", "(Multimap,Predicate)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterValues", "(SetMultimap,Predicate)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterValues", "(SetMultimap,Predicate)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "forMap", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "forMap", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "index", "(Iterable,Function)", "", "Argument[0].Element", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "index", "(Iterator,Function)", "", "Argument[0].Element", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "invertFrom", "(Multimap,Multimap)", "", "Argument[0].MapKey", "Argument[1].MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "invertFrom", "(Multimap,Multimap)", "", "Argument[0].MapValue", "Argument[1].MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "invertFrom", "(Multimap,Multimap)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "newListMultimap", "(Map,Supplier)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "newListMultimap", "(Map,Supplier)", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "newMultimap", "(Map,Supplier)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "newMultimap", "(Map,Supplier)", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "newSetMultimap", "(Map,Supplier)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "newSetMultimap", "(Map,Supplier)", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "newSortedSetMultimap", "(Map,Supplier)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "newSortedSetMultimap", "(Map,Supplier)", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "synchronizedListMultimap", "(ListMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "synchronizedListMultimap", "(ListMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "synchronizedMultimap", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "synchronizedMultimap", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "synchronizedSetMultimap", "(SetMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "synchronizedSetMultimap", "(SetMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "synchronizedSortedSetMultimap", "(SortedSetMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "synchronizedSortedSetMultimap", "(SortedSetMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "transformValues", "(ListMultimap,Function)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "transformValues", "(Multimap,Function)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableListMultimap", "(ImmutableListMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableListMultimap", "(ImmutableListMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableListMultimap", "(ListMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableListMultimap", "(ListMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableMultimap", "(ImmutableMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableMultimap", "(ImmutableMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableMultimap", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableMultimap", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableSetMultimap", "(ImmutableSetMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableSetMultimap", "(ImmutableSetMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableSetMultimap", "(SetMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableSetMultimap", "(SetMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableSortedSetMultimap", "(SortedSetMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableSortedSetMultimap", "(SortedSetMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multiset", True, "add", "(Object,int)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "Multiset", True, "elementSet", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multiset", True, "entrySet", "()", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Multiset", True, "setCount", "(Object,int)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "Multiset", True, "setCount", "(Object,int,int)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "Multiset$Entry", True, "getElement", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "copyHighestCountFirst", "(Multiset)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "difference", "(Multiset,Multiset)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "filter", "(Multiset,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "immutableEntry", "(Object,int)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "intersection", "(Multiset,Multiset)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "sum", "(Multiset,Multiset)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "union", "(Multiset,Multiset)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "unmodifiableMultiset", "(ImmutableMultiset)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "unmodifiableMultiset", "(Multiset)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "unmodifiableSortedMultiset", "(SortedMultiset)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "MutableClassToInstanceMap", True, "create", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "MutableClassToInstanceMap", True, "create", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ObjectArrays", False, "concat", "(Object,Object[])", "", "Argument[0]", "ReturnValue.ArrayElement", "value", "manual"] + - ["com.google.common.collect", "ObjectArrays", False, "concat", "(Object,Object[])", "", "Argument[1].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["com.google.common.collect", "ObjectArrays", False, "concat", "(Object[],Object)", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["com.google.common.collect", "ObjectArrays", False, "concat", "(Object[],Object)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["com.google.common.collect", "ObjectArrays", False, "concat", "(Object[],Object[],Class)", "", "Argument[0..1].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "drain", "(BlockingQueue,Collection,int,Duration)", "", "Argument[0].Element", "Argument[1].Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "drain", "(BlockingQueue,Collection,int,long,TimeUnit)", "", "Argument[0].Element", "Argument[1].Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "newArrayDeque", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "newConcurrentLinkedQueue", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "newLinkedBlockingDeque", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "newLinkedBlockingQueue", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "newPriorityBlockingQueue", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "newPriorityQueue", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "synchronizedDeque", "(Deque)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "synchronizedQueue", "(Queue)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "cartesianProduct", "(List)", "", "Argument[0].Element.Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "cartesianProduct", "(Set[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "combinations", "(Set,int)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "difference", "(Set,Set)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "filter", "(NavigableSet,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "filter", "(Set,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "filter", "(SortedSet,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "intersection", "(Set,Set)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "newConcurrentHashSet", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "newCopyOnWriteArraySet", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "newHashSet", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "newHashSet", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "newHashSet", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "newLinkedHashSet", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "newSetFromMap", "(Map)", "", "Argument[0].MapKey", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "newTreeSet", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "powerSet", "(Set)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "subSet", "(NavigableSet,Range)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "symmetricDifference", "(Set,Set)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "synchronizedNavigableSet", "(NavigableSet)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "union", "(Set,Set)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "unmodifiableNavigableSet", "(NavigableSet)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets$SetView", True, "copyInto", "(Set)", "", "Argument[-1].Element", "Argument[0].Element", "value", "manual"] + - ["com.google.common.collect", "Sets$SetView", True, "immutableCopy", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Table", True, "cellSet", "()", "", "Argument[-1].MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "cellSet", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.Element.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Table", True, "cellSet", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.Element.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Table", True, "column", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "column", "(Object)", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Table", True, "columnKeySet", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Table", True, "columnMap", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "columnMap", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Table", True, "columnMap", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.MapValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Table", True, "get", "(Object,Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "put", "(Object,Object,Object)", "", "Argument[0]", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Table", True, "put", "(Object,Object,Object)", "", "Argument[1]", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Table", True, "put", "(Object,Object,Object)", "", "Argument[2]", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "putAll", "(Table)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "putAll", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Table", True, "putAll", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Table", True, "remove", "(Object,Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "row", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "row", "(Object)", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Table", True, "rowKeySet", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Table", True, "rowMap", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "rowMap", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.MapValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Table", True, "rowMap", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Table", True, "values", "()", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Table$Cell", True, "getColumnKey", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Table$Cell", True, "getRowKey", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Table$Cell", True, "getValue", "()", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "immutableCell", "(Object,Object,Object)", "", "Argument[0]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "immutableCell", "(Object,Object,Object)", "", "Argument[1]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "immutableCell", "(Object,Object,Object)", "", "Argument[2]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "newCustomTable", "(Map,Supplier)", "", "Argument[0].MapKey", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "newCustomTable", "(Map,Supplier)", "", "Argument[0].MapValue.MapKey", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "newCustomTable", "(Map,Supplier)", "", "Argument[0].MapValue.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "synchronizedTable", "(Table)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "synchronizedTable", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "synchronizedTable", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "transformValues", "(Table,Function)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "transformValues", "(Table,Function)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "transpose", "(Table)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "transpose", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "transpose", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "unmodifiableRowSortedTable", "(RowSortedTable)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "unmodifiableRowSortedTable", "(RowSortedTable)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "unmodifiableRowSortedTable", "(RowSortedTable)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "unmodifiableTable", "(Table)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "unmodifiableTable", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "unmodifiableTable", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "TreeBasedTable", True, "create", "(TreeBasedTable)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "TreeBasedTable", True, "create", "(TreeBasedTable)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "TreeBasedTable", True, "create", "(TreeBasedTable)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "TreeMultimap", True, "create", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "TreeMultimap", True, "create", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "TreeMultiset", True, "create", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/com.google.common.flogger.model.yml b/java/ql/lib/ext/com.google.common.flogger.model.yml new file mode 100644 index 00000000000..21c8b0e9fcb --- /dev/null +++ b/java/ql/lib/ext/com.google.common.flogger.model.yml @@ -0,0 +1,34 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["com.google.common.flogger", "LoggingApi", True, "log", "", "", "Argument[0]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object[])", "", "Argument[1..11]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,boolean)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,byte)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,char)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,double)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,float)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,int)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,long)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,short)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,boolean,Object)", "", "Argument[2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,byte,Object)", "", "Argument[2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,char,Object)", "", "Argument[2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,double,Object)", "", "Argument[2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,float,Object)", "", "Argument[2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,int,Object)", "", "Argument[2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,long,Object)", "", "Argument[2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,short,Object)", "", "Argument[2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "logVarargs", "", "", "Argument[0..1]", "logging", "manual"] diff --git a/java/ql/lib/ext/com.google.common.io.model.yml b/java/ql/lib/ext/com.google.common.io.model.yml new file mode 100644 index 00000000000..5cba3d58e12 --- /dev/null +++ b/java/ql/lib/ext/com.google.common.io.model.yml @@ -0,0 +1,88 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["com.google.common.io", "Resources", False, "asByteSource", "(URL)", "", "Argument[0]", "url-open-stream", "manual"] + - ["com.google.common.io", "Resources", False, "asCharSource", "(URL,Charset)", "", "Argument[0]", "url-open-stream", "manual"] + - ["com.google.common.io", "Resources", False, "copy", "(URL,OutputStream)", "", "Argument[0]", "url-open-stream", "manual"] + - ["com.google.common.io", "Resources", False, "readLines", "", "", "Argument[0]", "url-open-stream", "manual"] + - ["com.google.common.io", "Resources", False, "toByteArray", "(URL)", "", "Argument[0]", "url-open-stream", "manual"] + - ["com.google.common.io", "Resources", False, "toString", "(URL,Charset)", "", "Argument[0]", "url-open-stream", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["com.google.common.io", "BaseEncoding", True, "decode", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "decode", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "decodingSource", "(CharSource)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "decodingSource", "(CharSource)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "decodingStream", "(Reader)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "decodingStream", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "encode", "(byte[])", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "encode", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "encode", "(byte[],int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "encode", "(byte[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "lowerCase", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "omitPadding", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "upperCase", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "withPadChar", "(char)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "withSeparator", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "toByteArray", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "write", "(byte[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "write", "(byte[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "write", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeByte", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeBytes", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeChar", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeChars", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeDouble", "(double)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeFloat", "(float)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeInt", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeLong", "(long)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeShort", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeUTF", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "asCharSource", "(Charset)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "concat", "(ByteSource[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "concat", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "concat", "(Iterator)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "copyTo", "(OutputStream)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "openBufferedStream", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "openStream", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "read", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "slice", "(long,long)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "wrap", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "copy", "(InputStream,OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "copy", "(ReadableByteChannel,WritableByteChannel)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "limit", "(InputStream,long)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "newDataInput", "(ByteArrayInputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "newDataInput", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "newDataInput", "(byte[],int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "newDataOutput", "(ByteArrayOutputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "read", "(InputStream,byte[],int,int)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "readFully", "(InputStream,byte[])", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "readFully", "(InputStream,byte[],int,int)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "toByteArray", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "asByteSource", "(Charset)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "concat", "(CharSource[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "concat", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "concat", "(Iterator)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "copyTo", "(Appendable)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "lines", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "openBufferedStream", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "openStream", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "read", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "readFirstLine", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "readLines", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "wrap", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharStreams", False, "copy", "(Readable,Appendable)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["com.google.common.io", "CharStreams", False, "readLines", "(Readable)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharStreams", False, "toString", "(Readable)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "Closer", True, "register", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["com.google.common.io", "Files", False, "getFileExtension", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "Files", False, "getNameWithoutExtension", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "Files", False, "simplifyPath", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "LineReader", False, "LineReader", "(Readable)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "LineReader", True, "readLine", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "MoreFiles", False, "getFileExtension", "(Path)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "MoreFiles", False, "getNameWithoutExtension", "(Path)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/com.hubspot.jinjava.model.yml b/java/ql/lib/ext/com.hubspot.jinjava.model.yml new file mode 100644 index 00000000000..c1a30915e33 --- /dev/null +++ b/java/ql/lib/ext/com.hubspot.jinjava.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["com.hubspot.jinjava", "Jinjava", True, "render", "", "", "Argument[0]", "ssti", "manual"] + - ["com.hubspot.jinjava", "Jinjava", True, "renderForResult", "", "", "Argument[0]", "ssti", "manual"] diff --git a/java/ql/lib/ext/com.mitchellbosecke.pebble.model.yml b/java/ql/lib/ext/com.mitchellbosecke.pebble.model.yml new file mode 100644 index 00000000000..a8ae018da3c --- /dev/null +++ b/java/ql/lib/ext/com.mitchellbosecke.pebble.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["com.mitchellbosecke.pebble", "PebbleEngine", True, "getLiteralTemplate", "", "", "Argument[0]", "ssti", "manual"] + - ["com.mitchellbosecke.pebble", "PebbleEngine", True, "getTemplate", "", "", "Argument[0]", "ssti", "manual"] diff --git a/java/ql/lib/ext/com.opensymphony.xwork2.ognl.model.yml b/java/ql/lib/ext/com.opensymphony.xwork2.ognl.model.yml new file mode 100644 index 00000000000..60cd1b114d6 --- /dev/null +++ b/java/ql/lib/ext/com.opensymphony.xwork2.ognl.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["com.opensymphony.xwork2.ognl", "OgnlUtil", False, "callMethod", "", "", "Argument[0]", "ognl-injection", "manual"] + - ["com.opensymphony.xwork2.ognl", "OgnlUtil", False, "getValue", "", "", "Argument[0]", "ognl-injection", "manual"] + - ["com.opensymphony.xwork2.ognl", "OgnlUtil", False, "setValue", "", "", "Argument[0]", "ognl-injection", "manual"] diff --git a/java/ql/lib/ext/com.rabbitmq.client.impl.model.yml b/java/ql/lib/ext/com.rabbitmq.client.impl.model.yml new file mode 100644 index 00000000000..cd2a74a741d --- /dev/null +++ b/java/ql/lib/ext/com.rabbitmq.client.impl.model.yml @@ -0,0 +1,15 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["com.rabbitmq.client.impl", "Frame", True, "getInputStream", "()", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client.impl", "Frame", True, "getPayload", "()", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client.impl", "FrameHandler", True, "readFrame", "()", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["com.rabbitmq.client.impl", "Frame", False, "fromBodyFragment", "(int,byte[],int,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["com.rabbitmq.client.impl", "Frame", False, "readFrom", "(DataInputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.rabbitmq.client.impl", "Frame", True, "writeTo", "(DataOutputStream)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/java/ql/lib/ext/com.rabbitmq.client.model.yml b/java/ql/lib/ext/com.rabbitmq.client.model.yml new file mode 100644 index 00000000000..ef452bf7005 --- /dev/null +++ b/java/ql/lib/ext/com.rabbitmq.client.model.yml @@ -0,0 +1,31 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["com.rabbitmq.client", "Command", True, "getContentBody", "()", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client", "Command", True, "getContentHeader", "()", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client", "Consumer", True, "handleDelivery", "(String,Envelope,BasicProperties,byte[])", "", "Parameter[3]", "remote", "manual"] + - ["com.rabbitmq.client", "QueueingConsumer", True, "nextDelivery", "", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client", "RpcClient", True, "doCall", "", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client", "RpcClient", True, "mapCall", "", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client", "RpcClient", True, "primitiveCall", "", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client", "RpcClient", True, "responseCall", "", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client", "RpcClient", True, "stringCall", "(String)", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client", "RpcServer", True, "handleCall", "(BasicProperties,byte[],BasicProperties)", "", "Parameter[1]", "remote", "manual"] + - ["com.rabbitmq.client", "RpcServer", True, "handleCall", "(Delivery,BasicProperties)", "", "Parameter[0]", "remote", "manual"] + - ["com.rabbitmq.client", "RpcServer", True, "handleCall", "(byte[],BasicProperties)", "", "Parameter[0]", "remote", "manual"] + - ["com.rabbitmq.client", "RpcServer", True, "handleCast", "(BasicProperties,byte[])", "", "Parameter[1]", "remote", "manual"] + - ["com.rabbitmq.client", "RpcServer", True, "handleCast", "(Delivery)", "", "Parameter[0]", "remote", "manual"] + - ["com.rabbitmq.client", "RpcServer", True, "handleCast", "(byte[])", "", "Parameter[0]", "remote", "manual"] + - ["com.rabbitmq.client", "RpcServer", True, "postprocessReplyProperties", "(Delivery,Builder)", "", "Parameter[0]", "remote", "manual"] + - ["com.rabbitmq.client", "RpcServer", True, "preprocessReplyProperties", "(Delivery,Builder)", "", "Parameter[0]", "remote", "manual"] + - ["com.rabbitmq.client", "StringRpcServer", True, "handleStringCall", "", "", "Parameter[0]", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["com.rabbitmq.client", "GetResponse", True, "GetResponse", "", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["com.rabbitmq.client", "GetResponse", True, "getBody", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.rabbitmq.client", "QueueingConsumer$Delivery", True, "getBody", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.rabbitmq.client", "RpcClient$Response", True, "getBody", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/com.unboundid.ldap.sdk.model.yml b/java/ql/lib/ext/com.unboundid.ldap.sdk.model.yml new file mode 100644 index 00000000000..f9d1d872f28 --- /dev/null +++ b/java/ql/lib/ext/com.unboundid.ldap.sdk.model.yml @@ -0,0 +1,22 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "asyncSearch", "", "", "Argument[0]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(ReadOnlySearchRequest)", "", "Argument[0]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchRequest)", "", "Argument[0]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchResultListener,String,SearchScope,DereferencePolicy,int,int,boolean,Filter,String[])", "", "Argument[0..7]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchResultListener,String,SearchScope,DereferencePolicy,int,int,boolean,String,String[])", "", "Argument[0..7]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchResultListener,String,SearchScope,Filter,String[])", "", "Argument[0..3]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchResultListener,String,SearchScope,String,String[])", "", "Argument[0..3]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(String,SearchScope,DereferencePolicy,int,int,boolean,Filter,String[])", "", "Argument[0..6]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(String,SearchScope,DereferencePolicy,int,int,boolean,String,String[])", "", "Argument[0..6]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(String,SearchScope,Filter,String[])", "", "Argument[0..2]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(String,SearchScope,String,String[])", "", "Argument[0..2]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(ReadOnlySearchRequest)", "", "Argument[0]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(SearchRequest)", "", "Argument[0]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(String,SearchScope,DereferencePolicy,int,boolean,Filter,String[])", "", "Argument[0..5]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(String,SearchScope,DereferencePolicy,int,boolean,String,String[])", "", "Argument[0..5]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(String,SearchScope,Filter,String[])", "", "Argument[0..2]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(String,SearchScope,String,String[])", "", "Argument[0..2]", "ldap", "manual"] diff --git a/java/ql/lib/ext/com.zaxxer.hikari.model.yml b/java/ql/lib/ext/com.zaxxer.hikari.model.yml new file mode 100644 index 00000000000..fb9f8f3cb80 --- /dev/null +++ b/java/ql/lib/ext/com.zaxxer.hikari.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["com.zaxxer.hikari", "HikariConfig", False, "HikariConfig", "(Properties)", "", "Argument[0]", "jdbc-url", "manual"] + - ["com.zaxxer.hikari", "HikariConfig", False, "setJdbcUrl", "(String)", "", "Argument[0]", "jdbc-url", "manual"] diff --git a/java/ql/lib/ext/flexjson.model.yml b/java/ql/lib/ext/flexjson.model.yml new file mode 100644 index 00000000000..af35c167d81 --- /dev/null +++ b/java/ql/lib/ext/flexjson.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["flexjson", "JSONDeserializer", True, "use", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/freemarker.cache.model.yml b/java/ql/lib/ext/freemarker.cache.model.yml new file mode 100644 index 00000000000..031ad7244dd --- /dev/null +++ b/java/ql/lib/ext/freemarker.cache.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["freemarker.cache", "StringTemplateLoader", True, "putTemplate", "", "", "Argument[1]", "ssti", "manual"] diff --git a/java/ql/lib/ext/freemarker.template.model.yml b/java/ql/lib/ext/freemarker.template.model.yml new file mode 100644 index 00000000000..10f90c6ea87 --- /dev/null +++ b/java/ql/lib/ext/freemarker.template.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["freemarker.template", "Template", True, "Template", "(String,Reader)", "", "Argument[1]", "ssti", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,Reader,Configuration)", "", "Argument[1]", "ssti", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,Reader,Configuration,String)", "", "Argument[1]", "ssti", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,String,Configuration)", "", "Argument[1]", "ssti", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,String,Reader,Configuration)", "", "Argument[2]", "ssti", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,String,Reader,Configuration,ParserConfiguration,String)", "", "Argument[2]", "ssti", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,String,Reader,Configuration,String)", "", "Argument[2]", "ssti", "manual"] diff --git a/java/ql/lib/ext/groovy.lang.model.yml b/java/ql/lib/ext/groovy.lang.model.yml new file mode 100644 index 00000000000..5299bf55afa --- /dev/null +++ b/java/ql/lib/ext/groovy.lang.model.yml @@ -0,0 +1,31 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(GroovyCodeSource)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(GroovyCodeSource,boolean)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(InputStream,String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(Reader,String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(String,String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(GroovyCodeSource)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(Reader)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(Reader,String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(String,String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(String,String,String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(URI)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "parse", "(Reader)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "parse", "(Reader,String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "parse", "(String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "parse", "(String,String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "parse", "(URI)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(GroovyCodeSource,List)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(GroovyCodeSource,String[])", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(Reader,String,List)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(Reader,String,String[])", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(String,String,List)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(String,String,String[])", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(URI,List)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(URI,String[])", "", "Argument[0]", "groovy", "manual"] diff --git a/java/ql/lib/ext/groovy.util.model.yml b/java/ql/lib/ext/groovy.util.model.yml new file mode 100644 index 00000000000..17b3d10ffae --- /dev/null +++ b/java/ql/lib/ext/groovy.util.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["groovy.util", "Eval", False, "me", "(String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.util", "Eval", False, "me", "(String,Object,String)", "", "Argument[2]", "groovy", "manual"] + - ["groovy.util", "Eval", False, "x", "(Object,String)", "", "Argument[1]", "groovy", "manual"] + - ["groovy.util", "Eval", False, "xy", "(Object,Object,String)", "", "Argument[2]", "groovy", "manual"] + - ["groovy.util", "Eval", False, "xyz", "(Object,Object,Object,String)", "", "Argument[3]", "groovy", "manual"] diff --git a/java/ql/lib/ext/jakarta.faces.context.model.yml b/java/ql/lib/ext/jakarta.faces.context.model.yml new file mode 100644 index 00000000000..968a15369c9 --- /dev/null +++ b/java/ql/lib/ext/jakarta.faces.context.model.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["jakarta.faces.context", "ExternalContext", True, "getRequestCookieMap", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.faces.context", "ExternalContext", True, "getRequestHeaderMap", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.faces.context", "ExternalContext", True, "getRequestHeaderValuesMap", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.faces.context", "ExternalContext", True, "getRequestParameterMap", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.faces.context", "ExternalContext", True, "getRequestParameterNames", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.faces.context", "ExternalContext", True, "getRequestParameterValuesMap", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.faces.context", "ExternalContext", True, "getRequestPathInfo", "()", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["jakarta.faces.context", "ResponseStream", True, "write", "", "", "Argument[0]", "xss", "manual"] + - ["jakarta.faces.context", "ResponseWriter", True, "write", "", "", "Argument[0]", "xss", "manual"] diff --git a/java/ql/lib/ext/jakarta.json.model.yml b/java/ql/lib/ext/jakarta.json.model.yml new file mode 100644 index 00000000000..40c2a465fa6 --- /dev/null +++ b/java/ql/lib/ext/jakarta.json.model.yml @@ -0,0 +1,127 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["jakarta.json", "Json", False, "createArrayBuilder", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createArrayBuilder", "(JsonArray)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createDiff", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createMergeDiff", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createMergePatch", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createObjectBuilder", "(JsonObject)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createObjectBuilder", "(Map)", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createObjectBuilder", "(Map)", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createPatch", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createPatchBuilder", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createPointer", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createWriter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "decodePointer", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "encodePointer", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArray", False, "getBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArray", False, "getBoolean", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonArray", False, "getInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArray", False, "getInt", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonArray", False, "getJsonArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArray", False, "getJsonNumber", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArray", False, "getJsonObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArray", False, "getJsonString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArray", False, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArray", False, "getString", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonArray", False, "getValuesAs", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(BigDecimal)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(BigInteger)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(JsonArrayBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(JsonObjectBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(JsonValue)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(boolean)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(double)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,BigDecimal)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,BigInteger)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,JsonArrayBuilder)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,JsonObjectBuilder)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,JsonValue)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,String)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,double)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,long)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(long)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "addAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "addAll", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "addNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "set", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "set", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "setNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonMergePatch", False, "apply", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonMergePatch", False, "apply", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonMergePatch", False, "toJsonValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "bigDecimalValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "bigIntegerValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "bigIntegerValueExact", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "doubleValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "intValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "intValueExact", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "longValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "longValueExact", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "numberValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObject", False, "getBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObject", False, "getBoolean", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonObject", False, "getInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObject", False, "getInt", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonObject", False, "getJsonArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObject", False, "getJsonNumber", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObject", False, "getJsonObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObject", False, "getJsonString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObject", False, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObject", False, "getString", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonObjectBuilder", False, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonObjectBuilder", False, "add", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonObjectBuilder", False, "addAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonObjectBuilder", False, "addAll", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonObjectBuilder", False, "addNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonObjectBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObjectBuilder", False, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonPatch", False, "apply", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatch", False, "apply", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatch", False, "toJsonArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "add", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "copy", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "copy", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "move", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "move", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "remove", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "replace", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "replace", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "test", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "test", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPointer", False, "add", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPointer", False, "add", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPointer", False, "getValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPointer", False, "remove", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPointer", False, "replace", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPointer", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonReader", False, "read", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonReader", False, "readArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonReader", False, "readObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonReader", False, "readValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonReaderFactory", False, "createReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonString", False, "getChars", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonString", False, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonStructure", True, "getValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonValue", True, "asJsonArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonValue", True, "asJsonObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonValue", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonWriter", False, "write", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonWriter", False, "writeArray", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonWriter", False, "writeObject", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonWriterFactory", False, "createWriter", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/java/ql/lib/ext/jakarta.json.stream.model.yml b/java/ql/lib/ext/jakarta.json.stream.model.yml new file mode 100644 index 00000000000..1d8a0f2532a --- /dev/null +++ b/java/ql/lib/ext/jakarta.json.stream.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["jakarta.json.stream", "JsonParserFactory", False, "createParser", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/jakarta.ws.rs.client.model.yml b/java/ql/lib/ext/jakarta.ws.rs.client.model.yml new file mode 100644 index 00000000000..37ec5916e86 --- /dev/null +++ b/java/ql/lib/ext/jakarta.ws.rs.client.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["jakarta.ws.rs.client", "Client", True, "target", "", "", "Argument[0]", "open-url", "manual"] diff --git a/java/ql/lib/ext/jakarta.ws.rs.container.model.yml b/java/ql/lib/ext/jakarta.ws.rs.container.model.yml new file mode 100644 index 00000000000..ac3be002e11 --- /dev/null +++ b/java/ql/lib/ext/jakarta.ws.rs.container.model.yml @@ -0,0 +1,14 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getAcceptableLanguages", "", "", "ReturnValue", "remote", "manual"] + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getAcceptableMediaTypes", "", "", "ReturnValue", "remote", "manual"] + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getCookies", "", "", "ReturnValue", "remote", "manual"] + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getEntityStream", "", "", "ReturnValue", "remote", "manual"] + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getHeaderString", "", "", "ReturnValue", "remote", "manual"] + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getHeaders", "", "", "ReturnValue", "remote", "manual"] + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getLanguage", "", "", "ReturnValue", "remote", "manual"] + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getMediaType", "", "", "ReturnValue", "remote", "manual"] + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getUriInfo", "", "", "ReturnValue", "remote", "manual"] diff --git a/java/ql/lib/ext/jakarta.ws.rs.core.model.yml b/java/ql/lib/ext/jakarta.ws.rs.core.model.yml new file mode 100644 index 00000000000..1f1cc59d161 --- /dev/null +++ b/java/ql/lib/ext/jakarta.ws.rs.core.model.yml @@ -0,0 +1,160 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["jakarta.ws.rs.core", "Response", True, "seeOther", "", "", "Argument[0]", "url-redirect", "manual"] + - ["jakarta.ws.rs.core", "Response", True, "temporaryRedirect", "", "", "Argument[0]", "url-redirect", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["jakarta.ws.rs.core", "AbstractMultivaluedMap", False, "AbstractMultivaluedMap", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["jakarta.ws.rs.core", "AbstractMultivaluedMap", False, "AbstractMultivaluedMap", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Cookie", False, "Cookie", "", "", "Argument[0..4]", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "Cookie", True, "getDomain", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Cookie", True, "getName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Cookie", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Cookie", True, "getValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Cookie", True, "getVersion", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Cookie", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Cookie", False, "valueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Form", False, "Form", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "Form", False, "Form", "", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "Form", False, "Form", "", "", "Argument[0].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "Form", True, "asMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Form", True, "param", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Form", True, "param", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "GenericEntity", False, "GenericEntity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "GenericEntity", True, "getEntity", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "HttpHeaders", True, "getAcceptableLanguages", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "HttpHeaders", True, "getAcceptableMediaTypes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "HttpHeaders", True, "getCookies", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "HttpHeaders", True, "getHeaderString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "HttpHeaders", True, "getLanguage", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "HttpHeaders", True, "getMediaType", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "HttpHeaders", True, "getRequestHeader", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "HttpHeaders", True, "getRequestHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "MediaType", False, "MediaType", "", "", "Argument[0..2]", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "MediaType", True, "getParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "MediaType", True, "getSubtype", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "MediaType", True, "getType", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "MediaType", False, "valueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "MediaType", True, "withCharset", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedHashMap", False, "MultivaluedHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedHashMap", False, "MultivaluedHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedHashMap", False, "MultivaluedHashMap", "(MultivaluedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedHashMap", False, "MultivaluedHashMap", "(MultivaluedMap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "add", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "add", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "addAll", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "addAll", "(Object,List)", "", "Argument[1].Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "addAll", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].MapValue.Element", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "addFirst", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "addFirst", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "getFirst", "", "", "Argument[-1].MapValue.Element", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "putSingle", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "putSingle", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["jakarta.ws.rs.core", "NewCookie", False, "NewCookie", "", "", "Argument[0..9]", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "NewCookie", True, "getComment", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "NewCookie", True, "getExpiry", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "NewCookie", True, "getMaxAge", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "NewCookie", True, "toCookie", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "NewCookie", False, "valueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "PathSegment", True, "getMatrixParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "PathSegment", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Response", False, "accepted", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Response", False, "fromResponse", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Response", False, "ok", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "allow", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "cacheControl", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "contentLocation", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "cookie", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "encoding", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "entity", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "entity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "expires", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "header", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "language", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "lastModified", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "link", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "links", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "location", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "status", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "tag", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "type", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "variant", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "variants", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "build", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "buildFromEncoded", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "buildFromEncoded", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "buildFromEncodedMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "buildFromEncodedMap", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "buildFromEncodedMap", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "buildFromMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "buildFromMap", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "buildFromMap", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "fragment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "fragment", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", False, "fromLink", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", False, "fromPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", False, "fromUri", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "host", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "host", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "matrixParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "matrixParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "matrixParam", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "path", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "path", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "queryParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "queryParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "queryParam", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceMatrix", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceMatrix", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceMatrixParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceMatrixParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceMatrixParam", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replacePath", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replacePath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceQuery", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceQueryParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceQueryParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceQueryParam", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplate", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplate", "", "", "Argument[0..2]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplateFromEncoded", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplateFromEncoded", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplates", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplates", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplates", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplatesFromEncoded", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplatesFromEncoded", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplatesFromEncoded", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "scheme", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "scheme", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "schemeSpecificPart", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "schemeSpecificPart", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "segment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "segment", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "toTemplate", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "uri", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "uri", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "userInfo", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "userInfo", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "getAbsolutePath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "getAbsolutePathBuilder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "getPathParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "getPathSegments", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "getQueryParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "getRequestUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "getRequestUriBuilder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "relativize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "resolve", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "resolve", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/java.beans.model.yml b/java/ql/lib/ext/java.beans.model.yml new file mode 100644 index 00000000000..155d1348c35 --- /dev/null +++ b/java/ql/lib/ext/java.beans.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["java.beans", "XMLDecoder", False, "XMLDecoder", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml new file mode 100644 index 00000000000..33a4e04628d --- /dev/null +++ b/java/ql/lib/ext/java.io.model.yml @@ -0,0 +1,86 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["java.io", "FileOutputStream", False, "FileOutputStream", "", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "FileOutputStream", False, "write", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "FileWriter", False, "FileWriter", "", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(File)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(File,Charset)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(File,String)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(String)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(String,Charset)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(String,String)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintStream", True, "append", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "PrintStream", True, "format", "(Locale,String,Object[])", "", "Argument[1..2]", "write-file", "manual"] + - ["java.io", "PrintStream", True, "format", "(String,Object[])", "", "Argument[0..1]", "write-file", "manual"] + - ["java.io", "PrintStream", True, "print", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "PrintStream", True, "printf", "(Locale,String,Object[])", "", "Argument[1..2]", "write-file", "manual"] + - ["java.io", "PrintStream", True, "printf", "(String,Object[])", "", "Argument[0..1]", "write-file", "manual"] + - ["java.io", "PrintStream", True, "println", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "PrintStream", True, "write", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "PrintStream", True, "writeBytes", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(File)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(File,Charset)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(File,String)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(String)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(String,Charset)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(String,String)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintWriter", False, "format", "(Locale,String,Object[])", "", "Argument[1..2]", "write-file", "manual"] + - ["java.io", "PrintWriter", False, "format", "(String,Object[])", "", "Argument[0..1]", "write-file", "manual"] + - ["java.io", "PrintWriter", False, "print", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "PrintWriter", False, "printf", "(Locale,String,Object[])", "", "Argument[1..2]", "write-file", "manual"] + - ["java.io", "PrintWriter", False, "printf", "(String,Object[])", "", "Argument[0..1]", "write-file", "manual"] + - ["java.io", "PrintWriter", False, "println", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "RandomAccessFile", False, "RandomAccessFile", "", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "RandomAccessFile", False, "write", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "RandomAccessFile", False, "writeBytes", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "RandomAccessFile", False, "writeChars", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "RandomAccessFile", False, "writeUTF", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "Writer", True, "append", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "Writer", True, "write", "", "", "Argument[0]", "write-file", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["java.io", "BufferedInputStream", False, "BufferedInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "BufferedReader", False, "BufferedReader", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "BufferedReader", True, "readLine", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "ByteArrayInputStream", False, "ByteArrayInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "ByteArrayOutputStream", False, "toByteArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "ByteArrayOutputStream", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "ByteArrayOutputStream", False, "writeTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["java.io", "CharArrayReader", False, "CharArrayReader", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "CharArrayWriter", True, "toCharArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "DataInput", True, "readFully", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["java.io", "DataInput", True, "readLine", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "DataInput", True, "readUTF", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "DataInputStream", False, "DataInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "File", False, "File", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "File", False, "File", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["java.io", "File", True, "getAbsoluteFile", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", True, "getAbsolutePath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", True, "getCanonicalFile", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", True, "getCanonicalPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", True, "toPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", True, "toURI", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "FilterOutputStream", True, "FilterOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "InputStream", True, "read", "(byte[])", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["java.io", "InputStream", True, "read", "(byte[],int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["java.io", "InputStream", True, "readAllBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "InputStream", True, "readNBytes", "(byte[],int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["java.io", "InputStream", True, "readNBytes", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "InputStream", True, "transferTo", "(OutputStream)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["java.io", "InputStreamReader", False, "InputStreamReader", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "ObjectInput", True, "read", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["java.io", "ObjectInputStream", False, "ObjectInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "OutputStream", True, "write", "(byte[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "OutputStream", True, "write", "(byte[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "OutputStream", True, "write", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "Reader", True, "read", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["java.io", "Reader", True, "read", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "StringReader", False, "StringReader", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "Writer", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "Writer", True, "write", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml new file mode 100644 index 00000000000..679a99b3e3d --- /dev/null +++ b/java/ql/lib/ext/java.lang.model.yml @@ -0,0 +1,88 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["java.lang", "String", False, "matches", "(String)", "", "Argument[0]", "regex-use[f-1]", "manual"] + - ["java.lang", "String", False, "replaceAll", "(String,String)", "", "Argument[0]", "regex-use[-1]", "manual"] + - ["java.lang", "String", False, "replaceFirst", "(String,String)", "", "Argument[0]", "regex-use[-1]", "manual"] + - ["java.lang", "String", False, "split", "(String)", "", "Argument[0]", "regex-use[-1]", "manual"] + - ["java.lang", "String", False, "split", "(String,int)", "", "Argument[0]", "regex-use[-1]", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,Object)", "", "Argument[1]", "logging", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,ResourceBundle,String,Object[])", "", "Argument[2..3]", "logging", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,ResourceBundle,String,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,String)", "", "Argument[1]", "logging", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,String,Supplier,Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["java.lang", "AbstractStringBuilder", True, "AbstractStringBuilder", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "append", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "append", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "getChars", "", "", "Argument[-1]", "Argument[2]", "taint", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "insert", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "insert", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "replace", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "replace", "", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "reverse", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "subSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "substring", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "Appendable", True, "append", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.lang", "Appendable", True, "append", "", "", "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"] + - ["java.lang", "Iterable", True, "forEach", "(Consumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.lang", "Iterable", True, "iterator", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.lang", "Iterable", True, "spliterator", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.lang", "Object", True, "clone", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.lang", "Object", True, "clone", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.lang", "Object", True, "clone", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.lang", "String", False, "String", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.lang", "String", False, "concat", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "concat", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "copyValueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "endsWith", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "format", "(Locale,String,Object[])", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "format", "(Locale,String,Object[])", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "format", "(String,Object[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "format", "(String,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "formatted", "(Object[])", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "formatted", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "getBytes", "", "", "Argument[-1]", "Argument[2]", "taint", "manual"] + - ["java.lang", "String", False, "getBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "getChars", "", "", "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, "replace", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "replaceAll", "", "", "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, "replaceFirst", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "split", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "strip", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "stripIndent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "stripLeading", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "stripTrailing", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "substring", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "toCharArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "toLowerCase", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "toString", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.lang", "String", False, "toUpperCase", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "translateEscapes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "trim", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "valueOf", "(char)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "valueOf", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "valueOf", "(char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["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", "System", False, "arraycopy", "", "", "Argument[0]", "Argument[2]", "taint", "manual"] diff --git a/java/ql/lib/ext/java.net.http.model.yml b/java/ql/lib/ext/java.net.http.model.yml new file mode 100644 index 00000000000..fa1222d2e28 --- /dev/null +++ b/java/ql/lib/ext/java.net.http.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["java.net.http", "WebSocket$Listener", True, "onText", "(WebSocket,CharSequence,boolean)", "", "Parameter[1]", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["java.net.http", "HttpRequest", False, "newBuilder", "", "", "Argument[0]", "open-url", "manual"] + - ["java.net.http", "HttpRequest$Builder", False, "uri", "", "", "Argument[0]", "open-url", "manual"] diff --git a/java/ql/lib/ext/java.net.model.yml b/java/ql/lib/ext/java.net.model.yml new file mode 100644 index 00000000000..7042a3e280f --- /dev/null +++ b/java/ql/lib/ext/java.net.model.yml @@ -0,0 +1,30 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["java.net", "Socket", False, "getInputStream", "()", "", "ReturnValue", "remote", "manual"] + - ["java.net", "URLConnection", False, "getInputStream", "()", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["java.net", "URL", False, "openConnection", "", "", "Argument[-1]", "open-url", "manual"] + - ["java.net", "URL", False, "openStream", "", "", "Argument[-1]", "open-url", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(String,URL[],ClassLoader)", "", "Argument[1]", "open-url", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(String,URL[],ClassLoader,URLStreamHandlerFactory)", "", "Argument[1]", "open-url", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[])", "", "Argument[0]", "open-url", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[],ClassLoader)", "", "Argument[0]", "open-url", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[],ClassLoader,URLStreamHandlerFactory)", "", "Argument[0]", "open-url", "manual"] + - ["java.net", "URLClassLoader", False, "newInstance", "", "", "Argument[0]", "open-url", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["java.net", "URI", False, "URI", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.net", "URI", False, "create", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.net", "URI", False, "toAsciiString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.net", "URI", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.net", "URI", False, "toURL", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.net", "URL", False, "URL", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.net", "URLDecoder", False, "decode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/java.nio.channels.model.yml b/java/ql/lib/ext/java.nio.channels.model.yml new file mode 100644 index 00000000000..0e7081567a6 --- /dev/null +++ b/java/ql/lib/ext/java.nio.channels.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["java.nio.channels", "Channels", False, "newChannel", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.nio.channels", "ReadableByteChannel", True, "read", "(ByteBuffer)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml new file mode 100644 index 00000000000..a593f0e7bf7 --- /dev/null +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -0,0 +1,33 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["java.nio.file", "Files", False, "copy", "", "", "Argument[1]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "createDirectories", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "createDirectory", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "createFile", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "createLink", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "createSymbolicLink", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "createTempDirectory", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "createTempFile", "(Path,String,String,FileAttribute[])", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "move", "", "", "Argument[1]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "newBufferedWriter", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "newOutputStream", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "write", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "write", "", "", "Argument[1]", "write-file", "manual"] + - ["java.nio.file", "Files", False, "writeString", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "writeString", "", "", "Argument[1]", "write-file", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["java.nio.file", "FileSystem", True, "getPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "FileSystem", True, "getRootDirectories", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Path", True, "normalize", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Path", True, "resolve", "", "", "Argument[-1..0]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Path", True, "toAbsolutePath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Path", False, "toFile", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Path", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Path", True, "toUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Paths", True, "get", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/java.nio.model.yml b/java/ql/lib/ext/java.nio.model.yml new file mode 100644 index 00000000000..7864355b4c5 --- /dev/null +++ b/java/ql/lib/ext/java.nio.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["java.nio", "ByteBuffer", False, "array", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.nio", "ByteBuffer", False, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.nio", "ByteBuffer", False, "wrap", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/java.sql.model.yml b/java/ql/lib/ext/java.sql.model.yml new file mode 100644 index 00000000000..944981e2094 --- /dev/null +++ b/java/ql/lib/ext/java.sql.model.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["java.sql", "Connection", True, "prepareCall", "", "", "Argument[0]", "sql", "manual"] + - ["java.sql", "Connection", True, "prepareStatement", "", "", "Argument[0]", "sql", "manual"] + - ["java.sql", "Driver", False, "connect", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"] + - ["java.sql", "DriverManager", False, "getConnection", "(String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["java.sql", "DriverManager", False, "getConnection", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"] + - ["java.sql", "DriverManager", False, "getConnection", "(String,String,String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["java.sql", "Statement", True, "addBatch", "", "", "Argument[0]", "sql", "manual"] + - ["java.sql", "Statement", True, "execute", "", "", "Argument[0]", "sql", "manual"] + - ["java.sql", "Statement", True, "executeLargeUpdate", "", "", "Argument[0]", "sql", "manual"] + - ["java.sql", "Statement", True, "executeQuery", "", "", "Argument[0]", "sql", "manual"] + - ["java.sql", "Statement", True, "executeUpdate", "", "", "Argument[0]", "sql", "manual"] diff --git a/java/ql/lib/ext/java.util.concurrent.model.yml b/java/ql/lib/ext/java.util.concurrent.model.yml new file mode 100644 index 00000000000..ba34d7e8fea --- /dev/null +++ b/java/ql/lib/ext/java.util.concurrent.model.yml @@ -0,0 +1,23 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["java.util.concurrent", "BlockingDeque", True, "offerFirst", "(Object,long,TimeUnit)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util.concurrent", "BlockingDeque", True, "offerLast", "(Object,long,TimeUnit)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util.concurrent", "BlockingDeque", True, "pollFirst", "(long,TimeUnit)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util.concurrent", "BlockingDeque", True, "pollLast", "(long,TimeUnit)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util.concurrent", "BlockingDeque", True, "putFirst", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util.concurrent", "BlockingDeque", True, "putLast", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util.concurrent", "BlockingDeque", True, "takeFirst", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util.concurrent", "BlockingDeque", True, "takeLast", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util.concurrent", "BlockingQueue", True, "drainTo", "(Collection)", "", "Argument[-1].Element", "Argument[0].Element", "value", "manual"] + - ["java.util.concurrent", "BlockingQueue", True, "drainTo", "(Collection,int)", "", "Argument[-1].Element", "Argument[0].Element", "value", "manual"] + - ["java.util.concurrent", "BlockingQueue", True, "offer", "(Object,long,TimeUnit)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util.concurrent", "BlockingQueue", True, "poll", "(long,TimeUnit)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util.concurrent", "BlockingQueue", True, "put", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util.concurrent", "BlockingQueue", True, "take", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util.concurrent", "ConcurrentHashMap", True, "elements", "()", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["java.util.concurrent", "TransferQueue", True, "transfer", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util.concurrent", "TransferQueue", True, "tryTransfer", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util.concurrent", "TransferQueue", True, "tryTransfer", "(Object,long,TimeUnit)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] diff --git a/java/ql/lib/ext/java.util.function.model.yml b/java/ql/lib/ext/java.util.function.model.yml new file mode 100644 index 00000000000..b95a50d5119 --- /dev/null +++ b/java/ql/lib/ext/java.util.function.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["java.util.function", "Predicate", False, "test", "(Object)", "", "Argument[-1]", "regex-use[0]", "manual"] diff --git a/java/ql/lib/ext/java.util.logging.model.yml b/java/ql/lib/ext/java.util.logging.model.yml new file mode 100644 index 00000000000..6e90734ae07 --- /dev/null +++ b/java/ql/lib/ext/java.util.logging.model.yml @@ -0,0 +1,44 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["java.util.logging", "Logger", True, "config", "", "", "Argument[0]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "entering", "(String,String)", "", "Argument[0..1]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "entering", "(String,String,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "entering", "(String,String,Object[])", "", "Argument[0..2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "exiting", "(String,String)", "", "Argument[0..1]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "exiting", "(String,String,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "fine", "", "", "Argument[0]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "finer", "", "", "Argument[0]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "finest", "", "", "Argument[0]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "info", "", "", "Argument[0]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,String)", "", "Argument[1]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,Supplier)", "", "Argument[1]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,Throwable,Supplier)", "", "Argument[2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "log", "(LogRecord)", "", "Argument[0]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,String)", "", "Argument[1..3]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,String,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,String,Object[])", "", "Argument[1..4]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,String,Throwable)", "", "Argument[1..3]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,Supplier)", "", "Argument[1..3]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,Throwable,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,Throwable,Supplier)", "", "Argument[4]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,ResourceBundle,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,ResourceBundle,String,Object[])", "", "Argument[4..5]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,ResourceBundle,String,Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,ResourceBundle,String,Throwable)", "", "Argument[4]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,String,String)", "", "Argument[1..4]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,String,String,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,String,String,Object[])", "", "Argument[1..5]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,String,String,Throwable)", "", "Argument[1..4]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "severe", "", "", "Argument[0]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "warning", "", "", "Argument[0]", "logging", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["java.util.logging", "LogRecord", False, "LogRecord", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/java.util.model.yml b/java/ql/lib/ext/java.util.model.yml new file mode 100644 index 00000000000..787f0d355be --- /dev/null +++ b/java/ql/lib/ext/java.util.model.yml @@ -0,0 +1,357 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["java.util", "AbstractMap$SimpleEntry", False, "SimpleEntry", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "AbstractMap$SimpleEntry", False, "SimpleEntry", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "AbstractMap$SimpleEntry", False, "SimpleEntry", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "AbstractMap$SimpleEntry", False, "SimpleEntry", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "AbstractMap$SimpleImmutableEntry", False, "SimpleImmutableEntry", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "AbstractMap$SimpleImmutableEntry", False, "SimpleImmutableEntry", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "AbstractMap$SimpleImmutableEntry", False, "SimpleImmutableEntry", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "AbstractMap$SimpleImmutableEntry", False, "SimpleImmutableEntry", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "ArrayDeque", False, "ArrayDeque", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "ArrayList", False, "ArrayList", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Arrays", False, "asList", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Arrays", False, "copyOf", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "copyOfRange", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(Object[],Object)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(Object[],int,int,Object)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(boolean[],boolean)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(boolean[],int,int,boolean)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(byte[],byte)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(byte[],int,int,byte)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(char[],char)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(char[],int,int,char)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(double[],double)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(double[],int,int,double)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(float[],float)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(float[],int,int,float)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(int[],int)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(int[],int,int,int)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(long[],int,int,long)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(long[],long)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(short[],int,int,short)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(short[],short)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "spliterator", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Arrays", False, "stream", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Base64$Decoder", False, "decode", "(ByteBuffer)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util", "Base64$Decoder", False, "decode", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util", "Base64$Decoder", False, "decode", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util", "Base64$Decoder", False, "wrap", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util", "Base64$Encoder", False, "encode", "(ByteBuffer)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util", "Base64$Encoder", False, "encode", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util", "Base64$Encoder", False, "encodeToString", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util", "Base64$Encoder", False, "wrap", "(OutputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util", "Collection", True, "add", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Collection", True, "addAll", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Collection", True, "parallelStream", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collection", True, "stream", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collection", True, "toArray", "", "", "Argument[-1].Element", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Collection", True, "toArray", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["java.util", "Collections", False, "addAll", "(Collection,Object[])", "", "Argument[1].ArrayElement", "Argument[0].Element", "value", "manual"] + - ["java.util", "Collections", False, "checkedCollection", "(Collection,Class)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "checkedList", "(List,Class)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "checkedMap", "(Map,Class,Class)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "checkedMap", "(Map,Class,Class)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "checkedNavigableMap", "(NavigableMap,Class,Class)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "checkedNavigableMap", "(NavigableMap,Class,Class)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "checkedNavigableSet", "(NavigableSet,Class)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "checkedSet", "(Set,Class)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "checkedSortedMap", "(SortedMap,Class,Class)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "checkedSortedMap", "(SortedMap,Class,Class)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "checkedSortedSet", "(SortedSet,Class)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "copy", "(List,List)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["java.util", "Collections", False, "enumeration", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "fill", "(List,Object)", "", "Argument[1]", "Argument[0].Element", "value", "manual"] + - ["java.util", "Collections", False, "list", "(Enumeration)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "max", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Collections", False, "min", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Collections", False, "nCopies", "(int,Object)", "", "Argument[1]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "replaceAll", "(List,Object,Object)", "", "Argument[2]", "Argument[0].Element", "value", "manual"] + - ["java.util", "Collections", False, "singleton", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "singletonList", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "singletonMap", "(Object,Object)", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "singletonMap", "(Object,Object)", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedCollection", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedList", "(List)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedMap", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedMap", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedNavigableMap", "(NavigableMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedNavigableMap", "(NavigableMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedNavigableSet", "(NavigableSet)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedSet", "(Set)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedSortedMap", "(SortedMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedSortedMap", "(SortedMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedSortedSet", "(SortedSet)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableCollection", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableList", "(List)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableMap", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableMap", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableNavigableMap", "(NavigableMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableNavigableMap", "(NavigableMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableNavigableSet", "(NavigableSet)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableSet", "(Set)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableSortedMap", "(SortedMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableSortedMap", "(SortedMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableSortedSet", "(SortedSet)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Deque", True, "addFirst", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Deque", True, "addLast", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Deque", True, "descendingIterator", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Deque", True, "getFirst", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Deque", True, "getLast", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Deque", True, "offerFirst", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Deque", True, "offerLast", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Deque", True, "peekFirst", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Deque", True, "peekLast", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Deque", True, "pollFirst", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Deque", True, "pollLast", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Deque", True, "pop", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Deque", True, "push", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Deque", True, "removeFirst", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Deque", True, "removeLast", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Dictionary", True, "elements", "()", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Dictionary", True, "get", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Dictionary", True, "keys", "()", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Dictionary", True, "put", "(Object,Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Dictionary", True, "put", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "Dictionary", True, "put", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Dictionary", True, "remove", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "EnumMap", False, "EnumMap", "(EnumMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "EnumMap", False, "EnumMap", "(EnumMap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "EnumMap", False, "EnumMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "EnumMap", False, "EnumMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Enumeration", True, "asIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Enumeration", True, "nextElement", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "HashMap", False, "HashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "HashMap", False, "HashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "HashSet", False, "HashSet", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Hashtable", False, "Hashtable", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "Hashtable", False, "Hashtable", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "IdentityHashMap", False, "IdentityHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "IdentityHashMap", False, "IdentityHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Iterator", True, "forEachRemaining", "(Consumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util", "Iterator", True, "next", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "LinkedHashMap", False, "LinkedHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "LinkedHashMap", False, "LinkedHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "LinkedHashSet", False, "LinkedHashSet", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "LinkedList", False, "LinkedList", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "List", True, "add", "(int,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "List", True, "addAll", "(int,Collection)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "List", False, "copyOf", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", True, "get", "(int)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "List", True, "listIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object)", "", "Argument[0..1]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object,Object)", "", "Argument[0..2]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object,Object,Object)", "", "Argument[0..3]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object,Object,Object,Object)", "", "Argument[0..4]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", True, "remove", "(int)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "List", True, "set", "(int,Object)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "List", True, "set", "(int,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "List", True, "subList", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "ListIterator", True, "add", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "ListIterator", True, "previous", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "ListIterator", True, "set", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Map", True, "computeIfAbsent", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map", True, "computeIfAbsent", "", "", "Argument[1].ReturnValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Map", True, "computeIfAbsent", "", "", "Argument[1].ReturnValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map", False, "copyOf", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "copyOf", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "entry", "(Object,Object)", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "entry", "(Object,Object)", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", True, "entrySet", "", "", "Argument[-1].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["java.util", "Map", True, "entrySet", "", "", "Argument[-1].MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["java.util", "Map", True, "forEach", "(BiConsumer)", "", "Argument[-1].MapKey", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util", "Map", True, "forEach", "(BiConsumer)", "", "Argument[-1].MapValue", "Argument[0].Parameter[1]", "value", "manual"] + - ["java.util", "Map", True, "get", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map", True, "getOrDefault", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map", True, "getOrDefault", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["java.util", "Map", True, "keySet", "()", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Map", True, "merge", "(Object,Object,BiFunction)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[10]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[11]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[12]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[13]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[14]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[15]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[16]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[17]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[18]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[19]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[2]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[3]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[4]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[5]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[6]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[7]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[8]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[9]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "ofEntries", "", "", "Argument[0].ArrayElement.MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "ofEntries", "", "", "Argument[0].ArrayElement.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", True, "put", "(Object,Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map", True, "put", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "Map", True, "put", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Map", True, "putAll", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "Map", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Map", True, "putIfAbsent", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map", True, "putIfAbsent", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "Map", True, "putIfAbsent", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Map", True, "remove", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map", True, "replace", "(Object,Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map", True, "replace", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "Map", True, "replace", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Map", True, "replace", "(Object,Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "Map", True, "replace", "(Object,Object,Object)", "", "Argument[2]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Map", True, "values", "()", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Map$Entry", True, "getKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["java.util", "Map$Entry", True, "getValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map$Entry", True, "setValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map$Entry", True, "setValue", "", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "ceilingEntry", "(Object)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "ceilingEntry", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "descendingMap", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "descendingMap", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "firstEntry", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "firstEntry", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "floorEntry", "(Object)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "floorEntry", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "headMap", "(Object,boolean)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "headMap", "(Object,boolean)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "higherEntry", "(Object)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "higherEntry", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "lastEntry", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "lastEntry", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "lowerEntry", "(Object)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "lowerEntry", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "pollFirstEntry", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "pollFirstEntry", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "pollLastEntry", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "pollLastEntry", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "subMap", "(Object,boolean,Object,boolean)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "subMap", "(Object,boolean,Object,boolean)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "tailMap", "(Object,boolean)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "tailMap", "(Object,boolean)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableSet", True, "ceiling", "(Object)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "NavigableSet", True, "descendingIterator", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "NavigableSet", True, "descendingSet", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "NavigableSet", True, "floor", "(Object)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "NavigableSet", True, "headSet", "(Object,boolean)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "NavigableSet", True, "higher", "(Object)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "NavigableSet", True, "lower", "(Object)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "NavigableSet", True, "pollFirst", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "NavigableSet", True, "pollLast", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "NavigableSet", True, "subSet", "(Object,boolean,Object,boolean)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "NavigableSet", True, "tailSet", "(Object,boolean)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Objects", False, "requireNonNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["java.util", "Objects", False, "requireNonNullElse", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["java.util", "Objects", False, "requireNonNullElse", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["java.util", "Objects", False, "requireNonNullElseGet", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["java.util", "Objects", False, "toString", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "filter", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util", "Optional", False, "filter", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Optional", False, "flatMap", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util", "Optional", False, "flatMap", "", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "ifPresent", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util", "Optional", False, "ifPresentOrElse", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util", "Optional", False, "map", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util", "Optional", False, "map", "", "", "Argument[0].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Optional", False, "of", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Optional", False, "ofNullable", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Optional", False, "or", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Optional", False, "or", "", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "orElse", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "orElse", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "orElseGet", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "orElseGet", "", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "orElseThrow", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "stream", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "PriorityQueue", False, "PriorityQueue", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "PriorityQueue", False, "PriorityQueue", "(PriorityQueue)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "PriorityQueue", False, "PriorityQueue", "(SortedSet)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Properties", True, "getProperty", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Properties", True, "getProperty", "(String,String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Properties", True, "getProperty", "(String,String)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["java.util", "Properties", True, "setProperty", "(String,String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Properties", True, "setProperty", "(String,String)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "Properties", True, "setProperty", "(String,String)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Queue", True, "element", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Queue", True, "offer", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Queue", True, "peek", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Queue", True, "poll", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Queue", True, "remove", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Scanner", True, "Scanner", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.util", "Scanner", True, "findInLine", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "findWithinHorizon", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "next", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextBigDecimal", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextBigInteger", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextByte", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextDouble", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextFloat", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextLine", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextLong", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextShort", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "reset", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.util", "Scanner", True, "skip", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.util", "Scanner", True, "useDelimiter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.util", "Scanner", True, "useLocale", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.util", "Scanner", True, "useRadix", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.util", "Set", False, "copyOf", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object)", "", "Argument[0..1]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object,Object)", "", "Argument[0..2]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object,Object,Object)", "", "Argument[0..3]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object,Object,Object,Object)", "", "Argument[0..4]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["java.util", "SortedMap", True, "headMap", "(Object)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "SortedMap", True, "headMap", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "SortedMap", True, "subMap", "(Object,Object)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "SortedMap", True, "subMap", "(Object,Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "SortedMap", True, "tailMap", "(Object)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "SortedMap", True, "tailMap", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "SortedSet", True, "first", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "SortedSet", True, "headSet", "(Object)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "SortedSet", True, "last", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "SortedSet", True, "subSet", "(Object,Object)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "SortedSet", True, "tailSet", "(Object)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Stack", True, "peek", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Stack", True, "pop", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Stack", True, "push", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "StringTokenizer", False, "StringTokenizer", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.util", "StringTokenizer", False, "nextElement", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "StringTokenizer", False, "nextToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "TreeMap", False, "TreeMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "TreeMap", False, "TreeMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "TreeMap", False, "TreeMap", "(SortedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "TreeMap", False, "TreeMap", "(SortedMap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "TreeSet", False, "TreeSet", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "TreeSet", False, "TreeSet", "(SortedSet)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Vector", False, "Vector", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Vector", True, "addElement", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Vector", True, "copyInto", "(Object[])", "", "Argument[-1].Element", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Vector", True, "elementAt", "(int)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Vector", True, "elements", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Vector", True, "firstElement", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Vector", True, "insertElementAt", "(Object,int)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Vector", True, "lastElement", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Vector", True, "setElementAt", "(Object,int)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "WeakHashMap", False, "WeakHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "WeakHashMap", False, "WeakHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/java.util.regex.model.yml b/java/ql/lib/ext/java.util.regex.model.yml new file mode 100644 index 00000000000..b5c329e7a60 --- /dev/null +++ b/java/ql/lib/ext/java.util.regex.model.yml @@ -0,0 +1,26 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["java.util.regex", "Matcher", False, "matches", "()", "", "Argument[-1]", "regex-use[f]", "manual"] + - ["java.util.regex", "Pattern", False, "asMatchPredicate", "()", "", "Argument[-1]", "regex-use[f]", "manual"] + - ["java.util.regex", "Pattern", False, "compile", "(String)", "", "Argument[0]", "regex-use[]", "manual"] + - ["java.util.regex", "Pattern", False, "compile", "(String,int)", "", "Argument[0]", "regex-use[]", "manual"] + - ["java.util.regex", "Pattern", False, "matcher", "(CharSequence)", "", "Argument[-1]", "regex-use[0]", "manual"] + - ["java.util.regex", "Pattern", False, "matches", "(String,CharSequence)", "", "Argument[0]", "regex-use[f1]", "manual"] + - ["java.util.regex", "Pattern", False, "split", "(CharSequence)", "", "Argument[-1]", "regex-use[0]", "manual"] + - ["java.util.regex", "Pattern", False, "split", "(CharSequence,int)", "", "Argument[-1]", "regex-use[0]", "manual"] + - ["java.util.regex", "Pattern", False, "splitAsStream", "(CharSequence)", "", "Argument[-1]", "regex-use[0]", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["java.util.regex", "Matcher", False, "group", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util.regex", "Matcher", False, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util.regex", "Matcher", False, "replaceAll", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util.regex", "Matcher", False, "replaceFirst", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util.regex", "Matcher", False, "replaceFirst", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util.regex", "Pattern", False, "matcher", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util.regex", "Pattern", False, "quote", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util.regex", "Pattern", False, "split", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/java.util.stream.model.yml b/java/ql/lib/ext/java.util.stream.model.yml new file mode 100644 index 00000000000..431829ec322 --- /dev/null +++ b/java/ql/lib/ext/java.util.stream.model.yml @@ -0,0 +1,85 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["java.util.stream", "BaseStream", True, "iterator", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "BaseStream", True, "onClose", "(Runnable)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "BaseStream", True, "parallel", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "BaseStream", True, "sequential", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "BaseStream", True, "spliterator", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "BaseStream", True, "unordered", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "allMatch", "(Predicate)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "anyMatch", "(Predicate)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "collect", "(Supplier,BiConsumer,BiConsumer)", "", "Argument[-1].Element", "Argument[1].Parameter[1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "collect", "(Supplier,BiConsumer,BiConsumer)", "", "Argument[0].ReturnValue", "Argument[1].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "collect", "(Supplier,BiConsumer,BiConsumer)", "", "Argument[1].Parameter[0]", "Argument[2].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "collect", "(Supplier,BiConsumer,BiConsumer)", "", "Argument[1].Parameter[0]", "ReturnValue", "value", "manual"] + - ["java.util.stream", "Stream", True, "collect", "(Supplier,BiConsumer,BiConsumer)", "", "Argument[2].Parameter[0..1]", "Argument[1].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "concat", "(Stream,Stream)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "distinct", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "dropWhile", "(Predicate)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "dropWhile", "(Predicate)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "filter", "(Predicate)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "filter", "(Predicate)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "findAny", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "findFirst", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "flatMap", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "flatMap", "(Function)", "", "Argument[0].ReturnValue.Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "flatMapToDouble", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "flatMapToInt", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "flatMapToLong", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "forEach", "(Consumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "forEachOrdered", "(Consumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "generate", "(Supplier)", "", "Argument[0].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "iterate", "(Object,Predicate,UnaryOperator)", "", "Argument[0]", "Argument[1..2].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "iterate", "(Object,Predicate,UnaryOperator)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "iterate", "(Object,Predicate,UnaryOperator)", "", "Argument[2].ReturnValue", "Argument[1..2].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "iterate", "(Object,Predicate,UnaryOperator)", "", "Argument[2].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "iterate", "(Object,UnaryOperator)", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "iterate", "(Object,UnaryOperator)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "iterate", "(Object,UnaryOperator)", "", "Argument[1].ReturnValue", "Argument[1].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "iterate", "(Object,UnaryOperator)", "", "Argument[1].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "limit", "(long)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "map", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "map", "(Function)", "", "Argument[0].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "mapMulti", "(BiConsumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "mapMultiToDouble", "(BiConsumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "mapMultiToInt", "(BiConsumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "mapMultiToLong", "(BiConsumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "mapToDouble", "(ToDoubleFunction)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "mapToInt", "(ToIntFunction)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "mapToLong", "(ToLongFunction)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "max", "(Comparator)", "", "Argument[-1].Element", "Argument[0].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "max", "(Comparator)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "min", "(Comparator)", "", "Argument[-1].Element", "Argument[0].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "min", "(Comparator)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "noneMatch", "(Predicate)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "of", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "of", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "ofNullable", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "peek", "(Consumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "peek", "(Consumer)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(BinaryOperator)", "", "Argument[-1].Element", "Argument[0].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(BinaryOperator)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(BinaryOperator)", "", "Argument[0].ReturnValue", "Argument[0].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(BinaryOperator)", "", "Argument[0].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BiFunction,BinaryOperator)", "", "Argument[-1].Element", "Argument[1].Parameter[1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BiFunction,BinaryOperator)", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BiFunction,BinaryOperator)", "", "Argument[0]", "Argument[2].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BiFunction,BinaryOperator)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BiFunction,BinaryOperator)", "", "Argument[1..2].ReturnValue", "Argument[1].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BiFunction,BinaryOperator)", "", "Argument[1..2].ReturnValue", "Argument[2].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BiFunction,BinaryOperator)", "", "Argument[1..2].ReturnValue", "ReturnValue", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BinaryOperator)", "", "Argument[-1].Element", "Argument[1].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BinaryOperator)", "", "Argument[0]", "Argument[1].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BinaryOperator)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BinaryOperator)", "", "Argument[1].ReturnValue", "Argument[1].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BinaryOperator)", "", "Argument[1].ReturnValue", "ReturnValue", "value", "manual"] + - ["java.util.stream", "Stream", True, "skip", "(long)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "sorted", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "sorted", "(Comparator)", "", "Argument[-1].Element", "Argument[0].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "takeWhile", "(Predicate)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "takeWhile", "(Predicate)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "toArray", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["java.util.stream", "Stream", True, "toList", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/java.util.zip.model.yml b/java/ql/lib/ext/java.util.zip.model.yml new file mode 100644 index 00000000000..a65be51a58c --- /dev/null +++ b/java/ql/lib/ext/java.util.zip.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["java.util.zip", "GZIPInputStream", False, "GZIPInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.util.zip", "ZipInputStream", False, "ZipInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/javax.faces.context.model.yml b/java/ql/lib/ext/javax.faces.context.model.yml new file mode 100644 index 00000000000..b3d9af75ef6 --- /dev/null +++ b/java/ql/lib/ext/javax.faces.context.model.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["javax.faces.context", "ExternalContext", True, "getRequestCookieMap", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.faces.context", "ExternalContext", True, "getRequestHeaderMap", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.faces.context", "ExternalContext", True, "getRequestHeaderValuesMap", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.faces.context", "ExternalContext", True, "getRequestParameterMap", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.faces.context", "ExternalContext", True, "getRequestParameterNames", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.faces.context", "ExternalContext", True, "getRequestParameterValuesMap", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.faces.context", "ExternalContext", True, "getRequestPathInfo", "()", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["javax.faces.context", "ResponseStream", True, "write", "", "", "Argument[0]", "xss", "manual"] + - ["javax.faces.context", "ResponseWriter", True, "write", "", "", "Argument[0]", "xss", "manual"] diff --git a/java/ql/lib/ext/javax.jms.model.yml b/java/ql/lib/ext/javax.jms.model.yml new file mode 100644 index 00000000000..9f153e35370 --- /dev/null +++ b/java/ql/lib/ext/javax.jms.model.yml @@ -0,0 +1,75 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["javax.jms", "JMSConsumer", True, "receive", "", "", "ReturnValue", "remote", "manual"] + - ["javax.jms", "JMSConsumer", True, "receiveBody", "", "", "ReturnValue", "remote", "manual"] + - ["javax.jms", "JMSConsumer", True, "receiveBodyNoWait", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.jms", "JMSConsumer", True, "receiveNoWait", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.jms", "MessageConsumer", True, "receive", "", "", "ReturnValue", "remote", "manual"] + - ["javax.jms", "MessageConsumer", True, "receiveNoWait", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.jms", "MessageListener", True, "onMessage", "(Message)", "", "Parameter[0]", "remote", "manual"] + - ["javax.jms", "QueueRequestor", True, "request", "(Message)", "", "ReturnValue", "remote", "manual"] + - ["javax.jms", "TopicRequestor", True, "request", "(Message)", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["javax.jms", "BytesMessage", True, "readBoolean", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readByte", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readBytes", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readChar", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readDouble", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readFloat", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readInt", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readLong", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readShort", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readUTF", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readUnsignedByte", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readUnsignedShort", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getBoolean", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getByte", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getBytes", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getChar", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getDouble", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getFloat", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getInt", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getLong", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getMapNames", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getObject", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getShort", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getString", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getBody", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getBooleanProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getByteProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getDoubleProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getFloatProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getIntProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getJMSCorrelationID", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getJMSCorrelationIDAsBytes", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getJMSDestination", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getJMSReplyTo", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getJMSType", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getLongProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getObjectProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getPropertyNames", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getShortProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getStringProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "ObjectMessage", True, "getObject", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Queue", True, "getQueueName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Queue", True, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readBoolean", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readByte", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readBytes", "(byte[])", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readChar", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readDouble", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readFloat", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readInt", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readLong", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readObject", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readShort", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "TextMessage", True, "getText", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Topic", True, "getTopicName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Topic", True, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/javax.json.model.yml b/java/ql/lib/ext/javax.json.model.yml new file mode 100644 index 00000000000..2771ce69f6b --- /dev/null +++ b/java/ql/lib/ext/javax.json.model.yml @@ -0,0 +1,127 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["javax.json", "Json", False, "createArrayBuilder", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createArrayBuilder", "(JsonArray)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createDiff", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createMergeDiff", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createMergePatch", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createObjectBuilder", "(JsonObject)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createObjectBuilder", "(Map)", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createObjectBuilder", "(Map)", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createPatch", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createPatchBuilder", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createPointer", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createWriter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "decodePointer", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "encodePointer", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArray", False, "getBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArray", False, "getBoolean", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonArray", False, "getInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArray", False, "getInt", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonArray", False, "getJsonArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArray", False, "getJsonNumber", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArray", False, "getJsonObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArray", False, "getJsonString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArray", False, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArray", False, "getString", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonArray", False, "getValuesAs", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(BigDecimal)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(BigInteger)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(JsonArrayBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(JsonObjectBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(JsonValue)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(boolean)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(double)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,BigDecimal)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,BigInteger)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,JsonArrayBuilder)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,JsonObjectBuilder)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,JsonValue)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,String)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,double)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,long)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(long)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "addAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "addAll", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "addNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "set", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "set", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "setNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonMergePatch", False, "apply", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonMergePatch", False, "apply", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonMergePatch", False, "toJsonValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "bigDecimalValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "bigIntegerValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "bigIntegerValueExact", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "doubleValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "intValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "intValueExact", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "longValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "longValueExact", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "numberValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObject", False, "getBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObject", False, "getBoolean", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonObject", False, "getInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObject", False, "getInt", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonObject", False, "getJsonArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObject", False, "getJsonNumber", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObject", False, "getJsonObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObject", False, "getJsonString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObject", False, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObject", False, "getString", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonObjectBuilder", False, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonObjectBuilder", False, "add", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonObjectBuilder", False, "addAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonObjectBuilder", False, "addAll", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonObjectBuilder", False, "addNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonObjectBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObjectBuilder", False, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonPatch", False, "apply", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatch", False, "apply", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatch", False, "toJsonArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "add", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "copy", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "copy", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "move", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "move", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "remove", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "replace", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "replace", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "test", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "test", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPointer", False, "add", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPointer", False, "add", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPointer", False, "getValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPointer", False, "remove", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPointer", False, "replace", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPointer", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonReader", False, "read", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonReader", False, "readArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonReader", False, "readObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonReader", False, "readValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonReaderFactory", False, "createReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonString", False, "getChars", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonString", False, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonStructure", True, "getValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonValue", True, "asJsonArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonValue", True, "asJsonObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonValue", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonWriter", False, "write", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonWriter", False, "writeArray", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonWriter", False, "writeObject", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonWriterFactory", False, "createWriter", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/java/ql/lib/ext/javax.json.stream.model.yml b/java/ql/lib/ext/javax.json.stream.model.yml new file mode 100644 index 00000000000..f354b3bed5b --- /dev/null +++ b/java/ql/lib/ext/javax.json.stream.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["javax.json.stream", "JsonParserFactory", False, "createParser", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/javax.management.remote.model.yml b/java/ql/lib/ext/javax.management.remote.model.yml new file mode 100644 index 00000000000..da3ab68968c --- /dev/null +++ b/java/ql/lib/ext/javax.management.remote.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["javax.management.remote", "JMXConnector", True, "connect", "", "", "Argument[-1]", "jndi-injection", "manual"] + - ["javax.management.remote", "JMXConnectorFactory", False, "connect", "", "", "Argument[0]", "jndi-injection", "manual"] diff --git a/java/ql/lib/ext/javax.naming.directory.model.yml b/java/ql/lib/ext/javax.naming.directory.model.yml new file mode 100644 index 00000000000..d4ff18a773c --- /dev/null +++ b/java/ql/lib/ext/javax.naming.directory.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["javax.naming.directory", "DirContext", True, "search", "", "", "Argument[0..1]", "ldap", "manual"] diff --git a/java/ql/lib/ext/javax.naming.model.yml b/java/ql/lib/ext/javax.naming.model.yml new file mode 100644 index 00000000000..7a29b0640a6 --- /dev/null +++ b/java/ql/lib/ext/javax.naming.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["javax.naming", "Context", True, "list", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["javax.naming", "Context", True, "listBindings", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["javax.naming", "Context", True, "lookup", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["javax.naming", "Context", True, "lookupLink", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["javax.naming", "Context", True, "rename", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["javax.naming", "InitialContext", True, "doLookup", "", "", "Argument[0]", "jndi-injection", "manual"] diff --git a/java/ql/lib/ext/javax.net.ssl.model.yml b/java/ql/lib/ext/javax.net.ssl.model.yml new file mode 100644 index 00000000000..f0b7b516595 --- /dev/null +++ b/java/ql/lib/ext/javax.net.ssl.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["javax.net.ssl", "HttpsURLConnection", True, "setDefaultHostnameVerifier", "", "", "Argument[0]", "set-hostname-verifier", "manual"] + - ["javax.net.ssl", "HttpsURLConnection", True, "setHostnameVerifier", "", "", "Argument[0]", "set-hostname-verifier", "manual"] diff --git a/java/ql/lib/ext/javax.script.model.yml b/java/ql/lib/ext/javax.script.model.yml new file mode 100644 index 00000000000..675055758e1 --- /dev/null +++ b/java/ql/lib/ext/javax.script.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["javax.script", "CompiledScript", False, "eval", "", "", "Argument[-1]", "mvel", "manual"] diff --git a/java/ql/lib/ext/javax.servlet.http.model.yml b/java/ql/lib/ext/javax.servlet.http.model.yml new file mode 100644 index 00000000000..469424e4021 --- /dev/null +++ b/java/ql/lib/ext/javax.servlet.http.model.yml @@ -0,0 +1,34 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["javax.servlet.http", "Cookie", False, "getComment", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "Cookie", False, "getName", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "Cookie", False, "getValue", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getHeader", "(String)", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getHeaderNames", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getHeaders", "(String)", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getParameter", "(String)", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getParameterMap", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getParameterNames", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getParameterValues", "(String)", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getPathInfo", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getQueryString", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getRemoteUser", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getRequestURI", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getRequestURL", "()", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["javax.servlet.http", "HttpServletResponse", False, "addCookie", "", "", "Argument[0]", "header-splitting", "manual"] + - ["javax.servlet.http", "HttpServletResponse", False, "addHeader", "", "", "Argument[0..1]", "header-splitting", "manual"] + - ["javax.servlet.http", "HttpServletResponse", False, "sendError", "(int,String)", "", "Argument[1]", "information-leak", "manual"] + - ["javax.servlet.http", "HttpServletResponse", False, "setHeader", "", "", "Argument[0..1]", "header-splitting", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["javax.servlet.http", "Cookie", False, "Cookie", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.servlet.http", "Cookie", False, "Cookie", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/javax.servlet.model.yml b/java/ql/lib/ext/javax.servlet.model.yml new file mode 100644 index 00000000000..accfa736f82 --- /dev/null +++ b/java/ql/lib/ext/javax.servlet.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["javax.servlet", "ServletRequest", False, "getInputStream", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet", "ServletRequest", False, "getParameter", "(String)", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet", "ServletRequest", False, "getParameterMap", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet", "ServletRequest", False, "getParameterNames", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet", "ServletRequest", False, "getParameterValues", "(String)", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet", "ServletRequest", False, "getReader", "()", "", "ReturnValue", "remote", "manual"] diff --git a/java/ql/lib/ext/javax.validation.model.yml b/java/ql/lib/ext/javax.validation.model.yml new file mode 100644 index 00000000000..464b95dfb11 --- /dev/null +++ b/java/ql/lib/ext/javax.validation.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["javax.validation", "ConstraintValidator", True, "isValid", "", "", "Parameter[0]", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["javax.validation", "ConstraintValidatorContext", True, "buildConstraintViolationWithTemplate", "", "", "Argument[0]", "bean-validation", "manual"] diff --git a/java/ql/lib/ext/javax.ws.rs.client.model.yml b/java/ql/lib/ext/javax.ws.rs.client.model.yml new file mode 100644 index 00000000000..b2fb8b75ad0 --- /dev/null +++ b/java/ql/lib/ext/javax.ws.rs.client.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["javax.ws.rs.client", "Client", True, "target", "", "", "Argument[0]", "open-url", "manual"] diff --git a/java/ql/lib/ext/javax.ws.rs.container.model.yml b/java/ql/lib/ext/javax.ws.rs.container.model.yml new file mode 100644 index 00000000000..1277c14a663 --- /dev/null +++ b/java/ql/lib/ext/javax.ws.rs.container.model.yml @@ -0,0 +1,14 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getAcceptableLanguages", "", "", "ReturnValue", "remote", "manual"] + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getAcceptableMediaTypes", "", "", "ReturnValue", "remote", "manual"] + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getCookies", "", "", "ReturnValue", "remote", "manual"] + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getEntityStream", "", "", "ReturnValue", "remote", "manual"] + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getHeaderString", "", "", "ReturnValue", "remote", "manual"] + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getHeaders", "", "", "ReturnValue", "remote", "manual"] + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getLanguage", "", "", "ReturnValue", "remote", "manual"] + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getMediaType", "", "", "ReturnValue", "remote", "manual"] + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getUriInfo", "", "", "ReturnValue", "remote", "manual"] diff --git a/java/ql/lib/ext/javax.ws.rs.core.model.yml b/java/ql/lib/ext/javax.ws.rs.core.model.yml new file mode 100644 index 00000000000..079f1afa9d2 --- /dev/null +++ b/java/ql/lib/ext/javax.ws.rs.core.model.yml @@ -0,0 +1,161 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["javax.ws.rs.core", "Response", True, "seeOther", "", "", "Argument[0]", "url-redirect", "manual"] + - ["javax.ws.rs.core", "Response", True, "temporaryRedirect", "", "", "Argument[0]", "url-redirect", "manual"] + - ["javax.ws.rs.core", "ResponseBuilder", False, "header", "", "", "Argument[1]", "header-splitting", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["javax.ws.rs.core", "AbstractMultivaluedMap", False, "AbstractMultivaluedMap", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["javax.ws.rs.core", "AbstractMultivaluedMap", False, "AbstractMultivaluedMap", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["javax.ws.rs.core", "Cookie", False, "Cookie", "", "", "Argument[0..4]", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "Cookie", True, "getDomain", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Cookie", True, "getName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Cookie", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Cookie", True, "getValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Cookie", True, "getVersion", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Cookie", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Cookie", False, "valueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Form", False, "Form", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "Form", False, "Form", "", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "Form", False, "Form", "", "", "Argument[0].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "Form", True, "asMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Form", True, "param", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Form", True, "param", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "GenericEntity", False, "GenericEntity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "GenericEntity", True, "getEntity", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "HttpHeaders", True, "getAcceptableLanguages", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "HttpHeaders", True, "getAcceptableMediaTypes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "HttpHeaders", True, "getCookies", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "HttpHeaders", True, "getHeaderString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "HttpHeaders", True, "getLanguage", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "HttpHeaders", True, "getMediaType", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "HttpHeaders", True, "getRequestHeader", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "HttpHeaders", True, "getRequestHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "MediaType", False, "MediaType", "", "", "Argument[0..2]", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "MediaType", True, "getParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "MediaType", True, "getSubtype", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "MediaType", True, "getType", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "MediaType", False, "valueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "MediaType", True, "withCharset", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "MultivaluedHashMap", False, "MultivaluedHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedHashMap", False, "MultivaluedHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedHashMap", False, "MultivaluedHashMap", "(MultivaluedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedHashMap", False, "MultivaluedHashMap", "(MultivaluedMap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "add", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "add", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "addAll", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "addAll", "(Object,List)", "", "Argument[1].Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "addAll", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].MapValue.Element", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "addFirst", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "addFirst", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "getFirst", "", "", "Argument[-1].MapValue.Element", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "putSingle", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "putSingle", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["javax.ws.rs.core", "NewCookie", False, "NewCookie", "", "", "Argument[0..9]", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "NewCookie", True, "getComment", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "NewCookie", True, "getExpiry", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "NewCookie", True, "getMaxAge", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "NewCookie", True, "toCookie", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "NewCookie", False, "valueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "PathSegment", True, "getMatrixParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "PathSegment", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Response", False, "accepted", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Response", False, "fromResponse", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Response", False, "ok", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "allow", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "cacheControl", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "contentLocation", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "cookie", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "encoding", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "entity", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "entity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "expires", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "header", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "language", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "lastModified", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "link", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "links", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "location", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "status", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "tag", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "type", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "variant", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "variants", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "build", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "buildFromEncoded", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "buildFromEncoded", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "buildFromEncodedMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "buildFromEncodedMap", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "buildFromEncodedMap", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "buildFromMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "buildFromMap", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "buildFromMap", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "fragment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "fragment", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", False, "fromLink", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", False, "fromPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", False, "fromUri", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "host", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "host", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "matrixParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "matrixParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "matrixParam", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "path", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "path", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "queryParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "queryParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "queryParam", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceMatrix", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceMatrix", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceMatrixParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceMatrixParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceMatrixParam", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replacePath", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replacePath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceQuery", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceQueryParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceQueryParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceQueryParam", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplate", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplate", "", "", "Argument[0..2]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplateFromEncoded", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplateFromEncoded", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplates", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplates", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplates", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplatesFromEncoded", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplatesFromEncoded", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplatesFromEncoded", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "scheme", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "scheme", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "schemeSpecificPart", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "schemeSpecificPart", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "segment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "segment", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "toTemplate", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "uri", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "uri", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "userInfo", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "userInfo", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "getAbsolutePath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "getAbsolutePathBuilder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "getPathParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "getPathSegments", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "getQueryParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "getRequestUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "getRequestUriBuilder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "relativize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "resolve", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "resolve", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/javax.xml.transform.model.yml b/java/ql/lib/ext/javax.xml.transform.model.yml new file mode 100644 index 00000000000..2032ecac6d6 --- /dev/null +++ b/java/ql/lib/ext/javax.xml.transform.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["javax.xml.transform", "Transformer", False, "transform", "", "", "Argument[-1]", "xslt", "manual"] diff --git a/java/ql/lib/ext/javax.xml.transform.sax.model.yml b/java/ql/lib/ext/javax.xml.transform.sax.model.yml new file mode 100644 index 00000000000..33765c1678f --- /dev/null +++ b/java/ql/lib/ext/javax.xml.transform.sax.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["javax.xml.transform.sax", "SAXSource", False, "SAXSource", "(InputSource)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.xml.transform.sax", "SAXSource", False, "SAXSource", "(XMLReader,InputSource)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.xml.transform.sax", "SAXSource", False, "getInputSource", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.xml.transform.sax", "SAXSource", False, "sourceToInputSource", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/javax.xml.transform.stream.model.yml b/java/ql/lib/ext/javax.xml.transform.stream.model.yml new file mode 100644 index 00000000000..858fbb0ab5a --- /dev/null +++ b/java/ql/lib/ext/javax.xml.transform.stream.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["javax.xml.transform.stream", "StreamSource", False, "StreamSource", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.xml.transform.stream", "StreamSource", False, "getInputStream", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/javax.xml.xpath.model.yml b/java/ql/lib/ext/javax.xml.xpath.model.yml new file mode 100644 index 00000000000..24be66eb8e9 --- /dev/null +++ b/java/ql/lib/ext/javax.xml.xpath.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["javax.xml.xpath", "XPath", True, "compile", "", "", "Argument[0]", "xpath", "manual"] + - ["javax.xml.xpath", "XPath", True, "evaluate", "", "", "Argument[0]", "xpath", "manual"] + - ["javax.xml.xpath", "XPath", True, "evaluateExpression", "", "", "Argument[0]", "xpath", "manual"] diff --git a/java/ql/lib/ext/jodd.json.model.yml b/java/ql/lib/ext/jodd.json.model.yml new file mode 100644 index 00000000000..6335ce520c0 --- /dev/null +++ b/java/ql/lib/ext/jodd.json.model.yml @@ -0,0 +1,15 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["jodd.json", "JsonParser", False, "allowAllClasses", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "allowClass", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "lazy", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "looseMode", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "map", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "setClassMetadataName", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "strictTypes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "useAltPaths", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "withClassMetadata", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "withValueConverter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/kotlin.collections.model.yml b/java/ql/lib/ext/kotlin.collections.model.yml new file mode 100644 index 00000000000..8336bff3b0a --- /dev/null +++ b/java/ql/lib/ext/kotlin.collections.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["kotlin.collections", "ArraysKt", False, "withIndex", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/kotlin.jvm.internal.model.yml b/java/ql/lib/ext/kotlin.jvm.internal.model.yml new file mode 100644 index 00000000000..40a6b605a53 --- /dev/null +++ b/java/ql/lib/ext/kotlin.jvm.internal.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["kotlin.jvm.internal", "ArrayIteratorKt", False, "iterator", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/net.sf.saxon.s9api.model.yml b/java/ql/lib/ext/net.sf.saxon.s9api.model.yml new file mode 100644 index 00000000000..7b64bdade8c --- /dev/null +++ b/java/ql/lib/ext/net.sf.saxon.s9api.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["net.sf.saxon.s9api", "Xslt30Transformer", False, "applyTemplates", "", "", "Argument[-1]", "xslt", "manual"] + - ["net.sf.saxon.s9api", "Xslt30Transformer", False, "callFunction", "", "", "Argument[-1]", "xslt", "manual"] + - ["net.sf.saxon.s9api", "Xslt30Transformer", False, "callTemplate", "", "", "Argument[-1]", "xslt", "manual"] + - ["net.sf.saxon.s9api", "Xslt30Transformer", False, "transform", "", "", "Argument[-1]", "xslt", "manual"] + - ["net.sf.saxon.s9api", "XsltTransformer", False, "transform", "", "", "Argument[-1]", "xslt", "manual"] diff --git a/java/ql/lib/ext/ognl.enhance.model.yml b/java/ql/lib/ext/ognl.enhance.model.yml new file mode 100644 index 00000000000..c3f49d72897 --- /dev/null +++ b/java/ql/lib/ext/ognl.enhance.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["ognl.enhance", "ExpressionAccessor", True, "get", "", "", "Argument[-1]", "ognl-injection", "manual"] + - ["ognl.enhance", "ExpressionAccessor", True, "set", "", "", "Argument[-1]", "ognl-injection", "manual"] diff --git a/java/ql/lib/ext/ognl.model.yml b/java/ql/lib/ext/ognl.model.yml new file mode 100644 index 00000000000..133fc36b410 --- /dev/null +++ b/java/ql/lib/ext/ognl.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["ognl", "Node", False, "getValue", "", "", "Argument[-1]", "ognl-injection", "manual"] + - ["ognl", "Node", False, "setValue", "", "", "Argument[-1]", "ognl-injection", "manual"] + - ["ognl", "Ognl", False, "getValue", "", "", "Argument[0]", "ognl-injection", "manual"] + - ["ognl", "Ognl", False, "setValue", "", "", "Argument[0]", "ognl-injection", "manual"] diff --git a/java/ql/lib/ext/okhttp3.model.yml b/java/ql/lib/ext/okhttp3.model.yml new file mode 100644 index 00000000000..1c9032c9211 --- /dev/null +++ b/java/ql/lib/ext/okhttp3.model.yml @@ -0,0 +1,58 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["okhttp3", "Request", True, "Request", "", "", "Argument[0]", "open-url", "manual"] + - ["okhttp3", "Request$Builder", True, "url", "", "", "Argument[0]", "open-url", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["okhttp3", "HttpUrl", False, "parse", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["okhttp3", "HttpUrl", False, "uri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["okhttp3", "HttpUrl", False, "url", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addEncodedPathSegment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addEncodedPathSegment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addEncodedPathSegments", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addEncodedPathSegments", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addEncodedQueryParameter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addEncodedQueryParameter", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addPathSegment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addPathSegment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addPathSegments", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addPathSegments", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addQueryParameter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addQueryParameter", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "encodedFragment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "encodedFragment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "encodedPassword", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "encodedPath", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "encodedPath", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "encodedQuery", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "encodedQuery", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "encodedUsername", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "fragment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "fragment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "host", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "host", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "password", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "port", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "port", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "query", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "query", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "removeAllEncodedQueryParameters", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "removeAllQueryParameters", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "removePathSegment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "scheme", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "scheme", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "setEncodedPathSegment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "setEncodedPathSegment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "setEncodedQueryParameter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "setEncodedQueryParameter", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "setPathSegment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "setPathSegment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "setQueryParameter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "setQueryParameter", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "username", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.codec.model.yml b/java/ql/lib/ext/org.apache.commons.codec.model.yml new file mode 100644 index 00000000000..963aa6ce843 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.codec.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.codec", "BinaryDecoder", True, "decode", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.codec", "BinaryEncoder", True, "encode", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.codec", "Decoder", True, "decode", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.codec", "Encoder", True, "encode", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.codec", "StringDecoder", True, "decode", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.codec", "StringEncoder", True, "encode", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.bag.model.yml b/java/ql/lib/ext/org.apache.commons.collections.bag.model.yml new file mode 100644 index 00000000000..ae77069bdee --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.bag.model.yml @@ -0,0 +1,23 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections.bag", "AbstractBagDecorator", True, "AbstractBagDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "AbstractMapBag", True, "AbstractMapBag", "", "", "Argument[0].MapKey", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "AbstractMapBag", True, "getMap", "", "", "Argument[-1].Element", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.bag", "AbstractSortedBagDecorator", True, "AbstractSortedBagDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "CollectionBag", True, "CollectionBag", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "CollectionBag", True, "collectionBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "CollectionSortedBag", True, "CollectionSortedBag", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "CollectionSortedBag", True, "collectionSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "HashBag", True, "HashBag", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "PredicatedBag", True, "predicatedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "PredicatedSortedBag", True, "predicatedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "SynchronizedBag", True, "synchronizedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "SynchronizedSortedBag", True, "synchronizedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "TransformedBag", True, "transformedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "TransformedSortedBag", True, "transformedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "TreeBag", True, "TreeBag", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "UnmodifiableBag", True, "unmodifiableBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "UnmodifiableSortedBag", True, "unmodifiableSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.bidimap.model.yml b/java/ql/lib/ext/org.apache.commons.collections.bidimap.model.yml new file mode 100644 index 00000000000..c47f56654b9 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.bidimap.model.yml @@ -0,0 +1,37 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections.bidimap", "AbstractBidiMapDecorator", True, "AbstractBidiMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractBidiMapDecorator", True, "AbstractBidiMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[1].MapKey", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[1].MapValue", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[2].MapKey", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[2].MapValue", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractOrderedBidiMapDecorator", True, "AbstractOrderedBidiMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractOrderedBidiMapDecorator", True, "AbstractOrderedBidiMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractSortedBidiMapDecorator", True, "AbstractSortedBidiMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractSortedBidiMapDecorator", True, "AbstractSortedBidiMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualHashBidiMap", True, "DualHashBidiMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualHashBidiMap", True, "DualHashBidiMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualLinkedHashBidiMap", True, "DualLinkedHashBidiMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualLinkedHashBidiMap", True, "DualLinkedHashBidiMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualTreeBidiMap", True, "DualTreeBidiMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualTreeBidiMap", True, "DualTreeBidiMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualTreeBidiMap", True, "inverseOrderedBidiMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualTreeBidiMap", True, "inverseOrderedBidiMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualTreeBidiMap", True, "inverseSortedBidiMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualTreeBidiMap", True, "inverseSortedBidiMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "TreeBidiMap", True, "TreeBidiMap", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "TreeBidiMap", True, "TreeBidiMap", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "UnmodifiableBidiMap", True, "unmodifiableBidiMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "UnmodifiableBidiMap", True, "unmodifiableBidiMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "UnmodifiableOrderedBidiMap", True, "inverseOrderedBidiMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "UnmodifiableOrderedBidiMap", True, "inverseOrderedBidiMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "UnmodifiableOrderedBidiMap", True, "unmodifiableOrderedBidiMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "UnmodifiableOrderedBidiMap", True, "unmodifiableOrderedBidiMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "UnmodifiableSortedBidiMap", True, "unmodifiableSortedBidiMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "UnmodifiableSortedBidiMap", True, "unmodifiableSortedBidiMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.collection.model.yml b/java/ql/lib/ext/org.apache.commons.collections.collection.model.yml new file mode 100644 index 00000000000..53e523e74ed --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.collection.model.yml @@ -0,0 +1,45 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections.collection", "AbstractCollectionDecorator", True, "AbstractCollectionDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "AbstractCollectionDecorator", True, "decorated", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "AbstractCollectionDecorator", True, "setCollection", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "CompositeCollection", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "CompositeCollection", "(Collection,Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "CompositeCollection", "(Collection,Collection)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "CompositeCollection", "(Collection[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "addComposited", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "addComposited", "(Collection,Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "addComposited", "(Collection,Collection)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "addComposited", "(Collection[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "getCollections", "", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "toCollection", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection$CollectionMutator", True, "add", "", "", "Argument[2]", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection$CollectionMutator", True, "add", "", "", "Argument[2]", "Argument[1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection$CollectionMutator", True, "addAll", "", "", "Argument[2].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection$CollectionMutator", True, "addAll", "", "", "Argument[2].Element", "Argument[1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "IndexedCollection", True, "IndexedCollection", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "IndexedCollection", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.collection", "IndexedCollection", True, "nonUniqueIndexedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "IndexedCollection", True, "uniqueIndexedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "IndexedCollection", True, "values", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection", True, "predicatedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "add", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "addAll", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedBag", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedList", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedMultiSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedQueue", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "rejectedElements", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "SynchronizedCollection", True, "synchronizedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "TransformedCollection", True, "transformingCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "UnmodifiableBoundedCollection", True, "unmodifiableBoundedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "UnmodifiableCollection", True, "unmodifiableCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.iterators.model.yml b/java/ql/lib/ext/org.apache.commons.collections.iterators.model.yml new file mode 100644 index 00000000000..d5cf30ca7cc --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.iterators.model.yml @@ -0,0 +1,80 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections.iterators", "AbstractIteratorDecorator", True, "AbstractIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractListIteratorDecorator", True, "AbstractListIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractListIteratorDecorator", True, "getListIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractMapIteratorDecorator", True, "AbstractMapIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractMapIteratorDecorator", True, "AbstractMapIteratorDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractMapIteratorDecorator", True, "getMapIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractMapIteratorDecorator", True, "getMapIterator", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractOrderedMapIteratorDecorator", True, "AbstractOrderedMapIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractOrderedMapIteratorDecorator", True, "AbstractOrderedMapIteratorDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractOrderedMapIteratorDecorator", True, "getOrderedMapIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractOrderedMapIteratorDecorator", True, "getOrderedMapIterator", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractUntypedIteratorDecorator", True, "AbstractUntypedIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractUntypedIteratorDecorator", True, "getIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ArrayIterator", True, "ArrayIterator", "", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ArrayIterator", True, "getArray", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ArrayListIterator", True, "ArrayListIterator", "", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "BoundedIterator", True, "BoundedIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "CollatingIterator", True, "CollatingIterator", "(Comparator,Collection)", "", "Argument[1].Element.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "CollatingIterator", True, "CollatingIterator", "(Comparator,Iterator,Iterator)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "CollatingIterator", True, "CollatingIterator", "(Comparator,Iterator,Iterator)", "", "Argument[2].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "CollatingIterator", True, "CollatingIterator", "(Comparator,Iterator[])", "", "Argument[1].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "CollatingIterator", True, "addIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "CollatingIterator", True, "getIterators", "", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "CollatingIterator", True, "setIterator", "", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "EnumerationIterator", True, "EnumerationIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "EnumerationIterator", True, "getEnumeration", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "EnumerationIterator", True, "setEnumeration", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "FilterIterator", True, "FilterIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "FilterIterator", True, "getIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "FilterIterator", True, "setIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "FilterListIterator", True, "FilterListIterator", "(ListIterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "FilterListIterator", True, "FilterListIterator", "(ListIterator,Predicate)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "FilterListIterator", True, "getListIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "FilterListIterator", True, "setListIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorChain", True, "IteratorChain", "(Collection)", "", "Argument[0].Element.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorChain", True, "IteratorChain", "(Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorChain", True, "IteratorChain", "(Iterator,Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorChain", True, "IteratorChain", "(Iterator,Iterator)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorChain", True, "IteratorChain", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorChain", True, "addIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorEnumeration", True, "IteratorEnumeration", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorEnumeration", True, "getIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorEnumeration", True, "setIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorIterable", True, "IteratorIterable", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ListIteratorWrapper", True, "ListIteratorWrapper", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "LoopingIterator", True, "LoopingIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "LoopingListIterator", True, "LoopingListIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ObjectArrayIterator", True, "ObjectArrayIterator", "", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ObjectArrayIterator", True, "getArray", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ObjectArrayListIterator", True, "ObjectArrayListIterator", "", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "PeekingIterator", True, "PeekingIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "PeekingIterator", True, "element", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.iterators", "PeekingIterator", True, "peek", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.iterators", "PeekingIterator", True, "peekingIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "PermutationIterator", True, "PermutationIterator", "", "", "Argument[0].Element", "Argument[-1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "PushbackIterator", True, "PushbackIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "PushbackIterator", True, "pushback", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "PushbackIterator", True, "pushbackIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ReverseListIterator", True, "ReverseListIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "SingletonIterator", True, "SingletonIterator", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "SingletonListIterator", True, "SingletonListIterator", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "SkippingIterator", True, "SkippingIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "UniqueFilterIterator", True, "UniqueFilterIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "UnmodifiableIterator", True, "unmodifiableIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "UnmodifiableListIterator", True, "umodifiableListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "UnmodifiableMapIterator", True, "unmodifiableMapIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "UnmodifiableMapIterator", True, "unmodifiableMapIterator", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.iterators", "UnmodifiableOrderedMapIterator", True, "unmodifiableOrderedMapIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "UnmodifiableOrderedMapIterator", True, "unmodifiableOrderedMapIterator", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[2].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.keyvalue.model.yml b/java/ql/lib/ext/org.apache.commons.collections.keyvalue.model.yml new file mode 100644 index 00000000000..679da24a74c --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.keyvalue.model.yml @@ -0,0 +1,57 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections.keyvalue", "AbstractKeyValue", True, "AbstractKeyValue", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractKeyValue", True, "AbstractKeyValue", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractKeyValue", True, "setKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractKeyValue", True, "setKey", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractKeyValue", True, "setValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractKeyValue", True, "setValue", "", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractMapEntry", True, "AbstractMapEntry", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractMapEntry", True, "AbstractMapEntry", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractMapEntryDecorator", True, "AbstractMapEntryDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractMapEntryDecorator", True, "AbstractMapEntryDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractMapEntryDecorator", True, "getMapEntry", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractMapEntryDecorator", True, "getMapEntry", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(KeyValue)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(KeyValue)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultKeyValue", True, "toMapEntry", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultKeyValue", True, "toMapEntry", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(KeyValue)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(KeyValue)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object)", "", "Argument[2]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object)", "", "Argument[2]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object)", "", "Argument[3]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[2]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[3]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[4]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object[])", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object[],boolean)", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "getKey", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "getKeys", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "TiedMapEntry", True, "TiedMapEntry", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "TiedMapEntry", True, "TiedMapEntry", "", "", "Argument[1]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(KeyValue)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(KeyValue)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.list.model.yml b/java/ql/lib/ext/org.apache.commons.collections.list.model.yml new file mode 100644 index 00000000000..d97d893a2c0 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.list.model.yml @@ -0,0 +1,27 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections.list", "AbstractLinkedList", True, "AbstractLinkedList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "AbstractLinkedList", True, "addFirst", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "AbstractLinkedList", True, "addLast", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "AbstractLinkedList", True, "getFirst", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.list", "AbstractLinkedList", True, "getLast", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.list", "AbstractLinkedList", True, "removeFirst", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.list", "AbstractLinkedList", True, "removeLast", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.list", "AbstractListDecorator", True, "AbstractListDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "AbstractSerializableListDecorator", True, "AbstractSerializableListDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "CursorableLinkedList", True, "CursorableLinkedList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "CursorableLinkedList", True, "cursor", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.list", "FixedSizeList", True, "fixedSizeList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.list", "GrowthList", True, "growthList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.list", "LazyList", True, "lazyList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.list", "NodeCachingLinkedList", True, "NodeCachingLinkedList", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "PredicatedList", True, "predicatedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.list", "SetUniqueList", True, "asSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.list", "SetUniqueList", True, "setUniqueList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.list", "TransformedList", True, "transformingList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.list", "TreeList", True, "TreeList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "UnmodifiableList", True, "UnmodifiableList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "UnmodifiableList", True, "unmodifiableList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.map.model.yml b/java/ql/lib/ext/org.apache.commons.collections.map.model.yml new file mode 100644 index 00000000000..85b368c7fcd --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.map.model.yml @@ -0,0 +1,133 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections.map", "AbstractHashedMap", True, "AbstractHashedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractHashedMap", True, "AbstractHashedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractLinkedMap", True, "AbstractLinkedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractLinkedMap", True, "AbstractLinkedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractMapDecorator", True, "AbstractMapDecorator", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractMapDecorator", True, "AbstractMapDecorator", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractMapDecorator", True, "decorated", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractMapDecorator", True, "decorated", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractOrderedMapDecorator", True, "AbstractOrderedMapDecorator", "(OrderedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractOrderedMapDecorator", True, "AbstractOrderedMapDecorator", "(OrderedMap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractSortedMapDecorator", True, "AbstractSortedMapDecorator", "(SortedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractSortedMapDecorator", True, "AbstractSortedMapDecorator", "(SortedMap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CaseInsensitiveMap", True, "CaseInsensitiveMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CaseInsensitiveMap", True, "CaseInsensitiveMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map,Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map,Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map,Map)", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map,Map)", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map,Map,MapMutator)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map,Map,MapMutator)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map,Map,MapMutator)", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map,Map,MapMutator)", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map[])", "", "Argument[0].ArrayElement.MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map[])", "", "Argument[0].ArrayElement.MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map[],MapMutator)", "", "Argument[0].ArrayElement.MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map[],MapMutator)", "", "Argument[0].ArrayElement.MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "addComposited", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "addComposited", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "removeComposited", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "removeComposited", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "removeComposited", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "DefaultedMap", True, "DefaultedMap", "(Object)", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "DefaultedMap", True, "defaultedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "DefaultedMap", True, "defaultedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "DefaultedMap", True, "defaultedMap", "(Map,Object)", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "EntrySetToMapIteratorAdapter", True, "EntrySetToMapIteratorAdapter", "", "", "Argument[0].Element.MapKey", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.map", "EntrySetToMapIteratorAdapter", True, "EntrySetToMapIteratorAdapter", "", "", "Argument[0].Element.MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "FixedSizeMap", True, "fixedSizeMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "FixedSizeMap", True, "fixedSizeMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "FixedSizeSortedMap", True, "fixedSizeSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "FixedSizeSortedMap", True, "fixedSizeSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "Flat3Map", True, "Flat3Map", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "Flat3Map", True, "Flat3Map", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "HashedMap", True, "HashedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "HashedMap", True, "HashedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LRUMap", True, "LRUMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "LRUMap", True, "LRUMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LRUMap", True, "LRUMap", "(Map,boolean)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "LRUMap", True, "LRUMap", "(Map,boolean)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LRUMap", True, "get", "(Object,boolean)", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LazyMap", True, "lazyMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "LazyMap", True, "lazyMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LazySortedMap", True, "lazySortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "LazySortedMap", True, "lazySortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LinkedMap", True, "LinkedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "LinkedMap", True, "LinkedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LinkedMap", True, "asList", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "LinkedMap", True, "get", "(int)", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LinkedMap", True, "getValue", "(int)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LinkedMap", True, "remove", "(int)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "asList", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "get", "(int)", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "getValue", "(int)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "keyList", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "listOrderedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "listOrderedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "put", "", "", "Argument[1]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "put", "", "", "Argument[2]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "putAll", "", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "putAll", "", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "remove", "(int)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "setValue", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "valueList", "", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "get", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "(Object,Object,Object)", "", "Argument[0..1]", "Argument[-1].MapKey.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "(Object,Object,Object)", "", "Argument[2]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object)", "", "Argument[0..2]", "Argument[-1].MapKey.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object)", "", "Argument[3]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object,Object)", "", "Argument[0..3]", "Argument[-1].MapKey.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object,Object)", "", "Argument[4]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object,Object,Object)", "", "Argument[0..4]", "Argument[-1].MapKey.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object,Object,Object)", "", "Argument[5]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "removeMultiKey", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "getCollection", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "iterator", "()", "", "Argument[-1].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "iterator", "()", "", "Argument[-1].MapValue.Element", "ReturnValue.Element.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "iterator", "(Object)", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "multiValueMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "multiValueMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "putAll", "(Map)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "putAll", "(Object,Collection)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "putAll", "(Object,Collection)", "", "Argument[1].Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "values", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(ExpirationPolicy,Map)", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(ExpirationPolicy,Map)", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(long,Map)", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(long,Map)", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(long,TimeUnit,Map)", "", "Argument[2].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(long,TimeUnit,Map)", "", "Argument[2].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "PredicatedMap", True, "predicatedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "PredicatedMap", True, "predicatedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "PredicatedSortedMap", True, "predicatedSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "PredicatedSortedMap", True, "predicatedSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "SingletonMap", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "SingletonMap", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "SingletonMap", "(KeyValue)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "SingletonMap", "(KeyValue)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "SingletonMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "SingletonMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "SingletonMap", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "SingletonMap", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "setValue", "", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "TransformedMap", True, "transformingMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "TransformedMap", True, "transformingMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "TransformedSortedMap", True, "transformingSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "TransformedSortedMap", True, "transformingSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "UnmodifiableEntrySet", True, "unmodifiableEntrySet", "", "", "Argument[0].Element.MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "UnmodifiableEntrySet", True, "unmodifiableEntrySet", "", "", "Argument[0].Element.MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "UnmodifiableMap", True, "unmodifiableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "UnmodifiableMap", True, "unmodifiableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "UnmodifiableOrderedMap", True, "unmodifiableOrderedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "UnmodifiableOrderedMap", True, "unmodifiableOrderedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "UnmodifiableSortedMap", True, "unmodifiableSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "UnmodifiableSortedMap", True, "unmodifiableSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.model.yml b/java/ql/lib/ext/org.apache.commons.collections.model.yml new file mode 100644 index 00000000000..13192b5a709 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.model.yml @@ -0,0 +1,365 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections", "ArrayStack", True, "peek", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "ArrayStack", True, "pop", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "ArrayStack", True, "push", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections", "ArrayStack", True, "push", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "Bag", True, "add", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections", "Bag", True, "uniqueSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "collectionBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "predicatedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "predicatedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "synchronizedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "synchronizedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "transformingBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "transformingSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "unmodifiableBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "unmodifiableSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BidiMap", True, "getKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "BidiMap", True, "inverseBidiMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "BidiMap", True, "inverseBidiMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "BidiMap", True, "removeValue", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "addAll", "(Collection,Enumeration)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "addAll", "(Collection,Iterable)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "addAll", "(Collection,Iterator)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "addAll", "(Collection,Object[])", "", "Argument[1].ArrayElement", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "addIgnoreNull", "", "", "Argument[1]", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "collate", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "collate", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "disjunction", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "disjunction", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "extractSingleton", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "find", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "get", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "get", "(Iterator,int)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "get", "(Map,int)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "get", "(Map,int)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "get", "(Object,int)", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "get", "(Object,int)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "get", "(Object,int)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "get", "(Object,int)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "getCardinalityMap", "", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "intersection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "intersection", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "permutations", "", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "predicatedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "removeAll", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "retainAll", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "select", "(Iterable,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection)", "", "Argument[0].Element", "Argument[2].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection,Collection)", "", "Argument[0].Element", "Argument[2].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection,Collection)", "", "Argument[0].Element", "Argument[3].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection,Collection)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "selectRejected", "(Iterable,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "selectRejected", "(Iterable,Predicate,Collection)", "", "Argument[0].Element", "Argument[2].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "selectRejected", "(Iterable,Predicate,Collection)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "subtract", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "synchronizedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "transformingCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "union", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "union", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "unmodifiableCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "EnumerationUtils", True, "get", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "EnumerationUtils", True, "toList", "(Enumeration)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "EnumerationUtils", True, "toList", "(StringTokenizer)", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "append", "(Iterable)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "append", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "append", "(Object[])", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "append", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "asEnumeration", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "collate", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "collate", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "copyInto", "", "", "Argument[-1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "eval", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "filter", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "limit", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "loop", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "of", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "of", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "of", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "reverse", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "skip", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "toArray", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "toList", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "unique", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "unmodifiable", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "zip", "(Iterable)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "zip", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "zip", "(Iterable[])", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "zip", "(Iterable[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "Get", True, "entrySet", "", "", "Argument[-1].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "Get", True, "entrySet", "", "", "Argument[-1].MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "Get", True, "get", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "Get", True, "keySet", "()", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "Get", True, "remove", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "Get", True, "values", "()", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableGet", True, "mapIterator", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableGet", True, "mapIterator", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "boundedIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[3].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "collatedIterable", "(Comparator,Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "collatedIterable", "(Comparator,Iterable,Iterable)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "collatedIterable", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "collatedIterable", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "filteredIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "find", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "first", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "forEachButLast", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "get", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "loopingIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "partition", "", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "reversedIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "skippingIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "toList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "toString", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "toString", "", "", "Argument[3]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "toString", "", "", "Argument[4]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "uniqueIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "unmodifiableIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "zippingIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "zippingIterable", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "zippingIterable", "(Iterable,Iterable[])", "", "Argument[1].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "arrayIterator", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "arrayListIterator", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "asEnumeration", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "asIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "asIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "asMultipleUseIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "boundedIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "chainedIterator", "(Collection)", "", "Argument[0].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "chainedIterator", "(Iterator,Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "chainedIterator", "(Iterator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "chainedIterator", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "collatedIterator", "(Comparator,Collection)", "", "Argument[1].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "collatedIterator", "(Comparator,Iterator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "collatedIterator", "(Comparator,Iterator,Iterator)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "collatedIterator", "(Comparator,Iterator[])", "", "Argument[1].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "filteredIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "filteredListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "find", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "first", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "forEachButLast", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "get", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "getIterator", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "getIterator", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "getIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "getIterator", "", "", "Argument[0].MapValue", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "loopingIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "loopingListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "peekingIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "pushbackIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "singletonIterator", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "singletonListIterator", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "skippingIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "toArray", "", "", "Argument[0].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "toList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "toListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "toString", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "toString", "", "", "Argument[3]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "toString", "", "", "Argument[4]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "unmodifiableIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "unmodifiableListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "unmodifiableMapIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "unmodifiableMapIterator", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "zippingIterator", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "KeyValue", True, "getKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "KeyValue", True, "getValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "defaultIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "defaultIfNull", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "fixedSizeList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "intersection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "intersection", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "lazyList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "longestCommonSubsequence", "(CharSequence,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "longestCommonSubsequence", "(CharSequence,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "longestCommonSubsequence", "(List,List)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "longestCommonSubsequence", "(List,List)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "longestCommonSubsequence", "(List,List,Equator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "longestCommonSubsequence", "(List,List,Equator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "partition", "", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "predicatedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "removeAll", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "retainAll", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "select", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "selectRejected", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "subtract", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "sum", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "sum", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "synchronizedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "transformedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "union", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "union", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "unmodifiableList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MapIterator", True, "getKey", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapIterator", True, "getValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapIterator", True, "setValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapIterator", True, "setValue", "", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "fixedSizeMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "fixedSizeMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "fixedSizeSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "fixedSizeSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "getMap", "", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "getMap", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "getObject", "", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "getObject", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "getString", "", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "getString", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "invertMap", "", "", "Argument[0].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "invertMap", "", "", "Argument[0].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "iterableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "iterableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "iterableSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "iterableSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "lazyMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "lazyMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "lazySortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "lazySortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "multiValueMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "multiValueMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "orderedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "orderedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "populateMap", "(Map,Iterable,Transformer)", "", "Argument[1].Element", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "populateMap", "(MultiMap,Iterable,Transformer)", "", "Argument[1].Element", "Argument[0].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "predicatedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "predicatedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "predicatedSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "predicatedSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement", "Argument[0].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.ArrayElement", "Argument[0].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.ArrayElement", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.ArrayElement", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.ArrayElement", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.MapKey", "Argument[0].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.MapValue", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "safeAddToMap", "", "", "Argument[1]", "Argument[0].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "safeAddToMap", "", "", "Argument[2]", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "synchronizedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "synchronizedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "synchronizedSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "synchronizedSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "toMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "toMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "transformedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "transformedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "transformedSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "transformedSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "unmodifiableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "unmodifiableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "unmodifiableSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "unmodifiableSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MultiMap", True, "get", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiMap", True, "put", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiMap", True, "put", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiMap", True, "values", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "getCollection", "", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "getValuesAsBag", "", "", "Argument[0].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "getValuesAsList", "", "", "Argument[0].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "getValuesAsSet", "", "", "Argument[0].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "transformedMultiValuedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "transformedMultiValuedMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "unmodifiableMultiValuedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "unmodifiableMultiValuedMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiSet", True, "add", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiSet", True, "entrySet", "", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiSet", True, "uniqueSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiSet$Entry", True, "getElement", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MultiSetUtils", True, "predicatedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiSetUtils", True, "synchronizedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiSetUtils", True, "unmodifiableMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "asMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "asMap", "", "", "Argument[-1].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "entries", "", "", "Argument[-1].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "entries", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "get", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "keySet", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "keys", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "mapIterator", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "mapIterator", "", "", "Argument[-1].MapValue.Element", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "put", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "put", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "putAll", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "putAll", "(MultiValuedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "putAll", "(MultiValuedMap)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "putAll", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "putAll", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "remove", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "values", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "OrderedIterator", True, "previous", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "OrderedMap", True, "firstKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "OrderedMap", True, "lastKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "OrderedMap", True, "nextKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "OrderedMap", True, "previousKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "Put", True, "put", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "Put", True, "put", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "Put", True, "put", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections", "Put", True, "putAll", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "Put", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections", "QueueUtils", True, "predicatedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "QueueUtils", True, "synchronizedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "QueueUtils", True, "transformingQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "QueueUtils", True, "unmodifiableQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "difference", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "disjunction", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "disjunction", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "hashSet", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "intersection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "intersection", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "orderedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "predicatedNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "predicatedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "predicatedSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "synchronizedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "synchronizedSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "transformedNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "transformedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "transformedSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "union", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "union", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "unmodifiableNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "unmodifiableSet", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "unmodifiableSet", "(Set)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "unmodifiableSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils$SetView", True, "copyInto", "", "", "Argument[-1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils$SetView", True, "createIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils$SetView", True, "toSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SortedBag", True, "first", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "SortedBag", True, "last", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "SplitMapUtils", True, "readableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "SplitMapUtils", True, "readableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "SplitMapUtils", True, "writableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "SplitMapUtils", True, "writableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "Trie", True, "prefixMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "Trie", True, "prefixMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "TrieUtils", True, "unmodifiableTrie", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "TrieUtils", True, "unmodifiableTrie", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.multimap.model.yml b/java/ql/lib/ext/org.apache.commons.collections.multimap.model.yml new file mode 100644 index 00000000000..be759e9ccbb --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.multimap.model.yml @@ -0,0 +1,17 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.multimap", "HashSetValuedHashMap", True, "HashSetValuedHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.multimap", "HashSetValuedHashMap", True, "HashSetValuedHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.multimap", "HashSetValuedHashMap", True, "HashSetValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.multimap", "HashSetValuedHashMap", True, "HashSetValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.multimap", "TransformedMultiValuedMap", True, "transformingMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.multimap", "TransformedMultiValuedMap", True, "transformingMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.multimap", "UnmodifiableMultiValuedMap", True, "unmodifiableMultiValuedMap", "(MultiValuedMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.multimap", "UnmodifiableMultiValuedMap", True, "unmodifiableMultiValuedMap", "(MultiValuedMap)", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.multiset.model.yml b/java/ql/lib/ext/org.apache.commons.collections.multiset.model.yml new file mode 100644 index 00000000000..af9e42fb88a --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.multiset.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections.multiset", "HashMultiSet", True, "HashMultiSet", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.multiset", "PredicatedMultiSet", True, "predicatedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.multiset", "SynchronizedMultiSet", True, "synchronizedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.multiset", "UnmodifiableMultiSet", True, "unmodifiableMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.properties.model.yml b/java/ql/lib/ext/org.apache.commons.collections.properties.model.yml new file mode 100644 index 00000000000..0552bb105bb --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.properties.model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections.properties", "AbstractPropertiesFactory", True, "load", "(ClassLoader,String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections.properties", "AbstractPropertiesFactory", True, "load", "(File)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections.properties", "AbstractPropertiesFactory", True, "load", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections.properties", "AbstractPropertiesFactory", True, "load", "(Path)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections.properties", "AbstractPropertiesFactory", True, "load", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections.properties", "AbstractPropertiesFactory", True, "load", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections.properties", "AbstractPropertiesFactory", True, "load", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections.properties", "AbstractPropertiesFactory", True, "load", "(URL)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.queue.model.yml b/java/ql/lib/ext/org.apache.commons.collections.queue.model.yml new file mode 100644 index 00000000000..41c40f6fb4c --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.queue.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections.queue", "CircularFifoQueue", True, "CircularFifoQueue", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.queue", "CircularFifoQueue", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.queue", "PredicatedQueue", True, "predicatedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.queue", "SynchronizedQueue", True, "synchronizedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.queue", "TransformedQueue", True, "transformingQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.queue", "UnmodifiableQueue", True, "unmodifiableQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.set.model.yml b/java/ql/lib/ext/org.apache.commons.collections.set.model.yml new file mode 100644 index 00000000000..56f97fd9b2e --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.set.model.yml @@ -0,0 +1,36 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections.set", "AbstractNavigableSetDecorator", True, "AbstractNavigableSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "AbstractSetDecorator", True, "AbstractSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "AbstractSortedSetDecorator", True, "AbstractSortedSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet", True, "CompositeSet", "(Set)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet", True, "CompositeSet", "(Set[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet", True, "addComposited", "(Set)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet", True, "addComposited", "(Set,Set)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet", True, "addComposited", "(Set,Set)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet", True, "addComposited", "(Set[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet", True, "getSets", "", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet", True, "toSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet$SetMutator", True, "add", "", "", "Argument[2]", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet$SetMutator", True, "add", "", "", "Argument[2]", "Argument[1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet$SetMutator", True, "addAll", "", "", "Argument[2].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet$SetMutator", True, "addAll", "", "", "Argument[2].Element", "Argument[1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "ListOrderedSet", True, "add", "", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "ListOrderedSet", True, "addAll", "", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "ListOrderedSet", True, "asList", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "ListOrderedSet", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.set", "ListOrderedSet", True, "listOrderedSet", "(List)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "ListOrderedSet", True, "listOrderedSet", "(Set)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "MapBackedSet", True, "mapBackedSet", "", "", "Argument[0].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "PredicatedNavigableSet", True, "predicatedNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "PredicatedSet", True, "predicatedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "PredicatedSortedSet", True, "predicatedSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "TransformedNavigableSet", True, "transformingNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "TransformedSet", True, "transformingSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "TransformedSortedSet", True, "transformingSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "UnmodifiableNavigableSet", True, "unmodifiableNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "UnmodifiableSet", True, "unmodifiableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "UnmodifiableSortedSet", True, "unmodifiableSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.splitmap.model.yml b/java/ql/lib/ext/org.apache.commons.collections.splitmap.model.yml new file mode 100644 index 00000000000..307081c6171 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.splitmap.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections.splitmap", "AbstractIterableGetMapDecorator", True, "AbstractIterableGetMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.splitmap", "AbstractIterableGetMapDecorator", True, "AbstractIterableGetMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.splitmap", "TransformedSplitMap", True, "transformingMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.splitmap", "TransformedSplitMap", True, "transformingMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.trie.model.yml b/java/ql/lib/ext/org.apache.commons.collections.trie.model.yml new file mode 100644 index 00000000000..1312bd074b8 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.trie.model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections.trie", "AbstractPatriciaTrie", True, "select", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.trie", "AbstractPatriciaTrie", True, "select", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.trie", "AbstractPatriciaTrie", True, "selectKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.trie", "AbstractPatriciaTrie", True, "selectValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.trie", "PatriciaTrie", True, "PatriciaTrie", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.trie", "PatriciaTrie", True, "PatriciaTrie", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.trie", "UnmodifiableTrie", True, "unmodifiableTrie", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.trie", "UnmodifiableTrie", True, "unmodifiableTrie", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.bag.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.bag.model.yml new file mode 100644 index 00000000000..5261491c1c7 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.bag.model.yml @@ -0,0 +1,23 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections4.bag", "AbstractBagDecorator", True, "AbstractBagDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "AbstractMapBag", True, "AbstractMapBag", "", "", "Argument[0].MapKey", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "AbstractMapBag", True, "getMap", "", "", "Argument[-1].Element", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bag", "AbstractSortedBagDecorator", True, "AbstractSortedBagDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "CollectionBag", True, "CollectionBag", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "CollectionBag", True, "collectionBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "CollectionSortedBag", True, "CollectionSortedBag", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "CollectionSortedBag", True, "collectionSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "HashBag", True, "HashBag", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "PredicatedBag", True, "predicatedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "PredicatedSortedBag", True, "predicatedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "SynchronizedBag", True, "synchronizedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "SynchronizedSortedBag", True, "synchronizedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "TransformedBag", True, "transformedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "TransformedSortedBag", True, "transformedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "TreeBag", True, "TreeBag", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "UnmodifiableBag", True, "unmodifiableBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "UnmodifiableSortedBag", True, "unmodifiableSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.bidimap.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.bidimap.model.yml new file mode 100644 index 00000000000..3be0532ec4d --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.bidimap.model.yml @@ -0,0 +1,37 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections4.bidimap", "AbstractBidiMapDecorator", True, "AbstractBidiMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractBidiMapDecorator", True, "AbstractBidiMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[1].MapKey", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[1].MapValue", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[2].MapKey", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[2].MapValue", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractOrderedBidiMapDecorator", True, "AbstractOrderedBidiMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractOrderedBidiMapDecorator", True, "AbstractOrderedBidiMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractSortedBidiMapDecorator", True, "AbstractSortedBidiMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractSortedBidiMapDecorator", True, "AbstractSortedBidiMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualHashBidiMap", True, "DualHashBidiMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualHashBidiMap", True, "DualHashBidiMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualLinkedHashBidiMap", True, "DualLinkedHashBidiMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualLinkedHashBidiMap", True, "DualLinkedHashBidiMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualTreeBidiMap", True, "DualTreeBidiMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualTreeBidiMap", True, "DualTreeBidiMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualTreeBidiMap", True, "inverseOrderedBidiMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualTreeBidiMap", True, "inverseOrderedBidiMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualTreeBidiMap", True, "inverseSortedBidiMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualTreeBidiMap", True, "inverseSortedBidiMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "TreeBidiMap", True, "TreeBidiMap", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "TreeBidiMap", True, "TreeBidiMap", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "UnmodifiableBidiMap", True, "unmodifiableBidiMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "UnmodifiableBidiMap", True, "unmodifiableBidiMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "UnmodifiableOrderedBidiMap", True, "inverseOrderedBidiMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "UnmodifiableOrderedBidiMap", True, "inverseOrderedBidiMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "UnmodifiableOrderedBidiMap", True, "unmodifiableOrderedBidiMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "UnmodifiableOrderedBidiMap", True, "unmodifiableOrderedBidiMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "UnmodifiableSortedBidiMap", True, "unmodifiableSortedBidiMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "UnmodifiableSortedBidiMap", True, "unmodifiableSortedBidiMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.collection.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.collection.model.yml new file mode 100644 index 00000000000..1c53d650fd3 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.collection.model.yml @@ -0,0 +1,45 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections4.collection", "AbstractCollectionDecorator", True, "AbstractCollectionDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "AbstractCollectionDecorator", True, "decorated", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "AbstractCollectionDecorator", True, "setCollection", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "CompositeCollection", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "CompositeCollection", "(Collection,Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "CompositeCollection", "(Collection,Collection)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "CompositeCollection", "(Collection[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "addComposited", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "addComposited", "(Collection,Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "addComposited", "(Collection,Collection)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "addComposited", "(Collection[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "getCollections", "", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "toCollection", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection$CollectionMutator", True, "add", "", "", "Argument[2]", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection$CollectionMutator", True, "add", "", "", "Argument[2]", "Argument[1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection$CollectionMutator", True, "addAll", "", "", "Argument[2].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection$CollectionMutator", True, "addAll", "", "", "Argument[2].Element", "Argument[1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "IndexedCollection", True, "IndexedCollection", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "IndexedCollection", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.collection", "IndexedCollection", True, "nonUniqueIndexedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "IndexedCollection", True, "uniqueIndexedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "IndexedCollection", True, "values", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection", True, "predicatedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "add", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "addAll", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedBag", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedList", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedMultiSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedQueue", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "rejectedElements", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "SynchronizedCollection", True, "synchronizedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "TransformedCollection", True, "transformingCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "UnmodifiableBoundedCollection", True, "unmodifiableBoundedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "UnmodifiableCollection", True, "unmodifiableCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.iterators.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.iterators.model.yml new file mode 100644 index 00000000000..ca86086d08b --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.iterators.model.yml @@ -0,0 +1,80 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections4.iterators", "AbstractIteratorDecorator", True, "AbstractIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractListIteratorDecorator", True, "AbstractListIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractListIteratorDecorator", True, "getListIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractMapIteratorDecorator", True, "AbstractMapIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractMapIteratorDecorator", True, "AbstractMapIteratorDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractMapIteratorDecorator", True, "getMapIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractMapIteratorDecorator", True, "getMapIterator", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractOrderedMapIteratorDecorator", True, "AbstractOrderedMapIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractOrderedMapIteratorDecorator", True, "AbstractOrderedMapIteratorDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractOrderedMapIteratorDecorator", True, "getOrderedMapIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractOrderedMapIteratorDecorator", True, "getOrderedMapIterator", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractUntypedIteratorDecorator", True, "AbstractUntypedIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractUntypedIteratorDecorator", True, "getIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ArrayIterator", True, "ArrayIterator", "", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ArrayIterator", True, "getArray", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ArrayListIterator", True, "ArrayListIterator", "", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "BoundedIterator", True, "BoundedIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "CollatingIterator", True, "CollatingIterator", "(Comparator,Collection)", "", "Argument[1].Element.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "CollatingIterator", True, "CollatingIterator", "(Comparator,Iterator,Iterator)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "CollatingIterator", True, "CollatingIterator", "(Comparator,Iterator,Iterator)", "", "Argument[2].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "CollatingIterator", True, "CollatingIterator", "(Comparator,Iterator[])", "", "Argument[1].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "CollatingIterator", True, "addIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "CollatingIterator", True, "getIterators", "", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "CollatingIterator", True, "setIterator", "", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "EnumerationIterator", True, "EnumerationIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "EnumerationIterator", True, "getEnumeration", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "EnumerationIterator", True, "setEnumeration", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "FilterIterator", True, "FilterIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "FilterIterator", True, "getIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "FilterIterator", True, "setIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "FilterListIterator", True, "FilterListIterator", "(ListIterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "FilterListIterator", True, "FilterListIterator", "(ListIterator,Predicate)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "FilterListIterator", True, "getListIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "FilterListIterator", True, "setListIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorChain", True, "IteratorChain", "(Collection)", "", "Argument[0].Element.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorChain", True, "IteratorChain", "(Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorChain", True, "IteratorChain", "(Iterator,Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorChain", True, "IteratorChain", "(Iterator,Iterator)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorChain", True, "IteratorChain", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorChain", True, "addIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorEnumeration", True, "IteratorEnumeration", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorEnumeration", True, "getIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorEnumeration", True, "setIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorIterable", True, "IteratorIterable", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ListIteratorWrapper", True, "ListIteratorWrapper", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "LoopingIterator", True, "LoopingIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "LoopingListIterator", True, "LoopingListIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ObjectArrayIterator", True, "ObjectArrayIterator", "", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ObjectArrayIterator", True, "getArray", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ObjectArrayListIterator", True, "ObjectArrayListIterator", "", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "PeekingIterator", True, "PeekingIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "PeekingIterator", True, "element", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "PeekingIterator", True, "peek", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "PeekingIterator", True, "peekingIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "PermutationIterator", True, "PermutationIterator", "", "", "Argument[0].Element", "Argument[-1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "PushbackIterator", True, "PushbackIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "PushbackIterator", True, "pushback", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "PushbackIterator", True, "pushbackIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ReverseListIterator", True, "ReverseListIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "SingletonIterator", True, "SingletonIterator", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "SingletonListIterator", True, "SingletonListIterator", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "SkippingIterator", True, "SkippingIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "UniqueFilterIterator", True, "UniqueFilterIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "UnmodifiableIterator", True, "unmodifiableIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "UnmodifiableListIterator", True, "umodifiableListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "UnmodifiableMapIterator", True, "unmodifiableMapIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "UnmodifiableMapIterator", True, "unmodifiableMapIterator", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "UnmodifiableOrderedMapIterator", True, "unmodifiableOrderedMapIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "UnmodifiableOrderedMapIterator", True, "unmodifiableOrderedMapIterator", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[2].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.keyvalue.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.keyvalue.model.yml new file mode 100644 index 00000000000..b62873ed707 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.keyvalue.model.yml @@ -0,0 +1,57 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections4.keyvalue", "AbstractKeyValue", True, "AbstractKeyValue", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractKeyValue", True, "AbstractKeyValue", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractKeyValue", True, "setKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractKeyValue", True, "setKey", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractKeyValue", True, "setValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractKeyValue", True, "setValue", "", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractMapEntry", True, "AbstractMapEntry", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractMapEntry", True, "AbstractMapEntry", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractMapEntryDecorator", True, "AbstractMapEntryDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractMapEntryDecorator", True, "AbstractMapEntryDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractMapEntryDecorator", True, "getMapEntry", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractMapEntryDecorator", True, "getMapEntry", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(KeyValue)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(KeyValue)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultKeyValue", True, "toMapEntry", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultKeyValue", True, "toMapEntry", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(KeyValue)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(KeyValue)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object)", "", "Argument[2]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object)", "", "Argument[2]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object)", "", "Argument[3]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[2]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[3]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[4]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object[])", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object[],boolean)", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "getKey", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "getKeys", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "TiedMapEntry", True, "TiedMapEntry", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "TiedMapEntry", True, "TiedMapEntry", "", "", "Argument[1]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(KeyValue)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(KeyValue)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.list.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.list.model.yml new file mode 100644 index 00000000000..4307d7f1a92 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.list.model.yml @@ -0,0 +1,27 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections4.list", "AbstractLinkedList", True, "AbstractLinkedList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "AbstractLinkedList", True, "addFirst", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "AbstractLinkedList", True, "addLast", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "AbstractLinkedList", True, "getFirst", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.list", "AbstractLinkedList", True, "getLast", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.list", "AbstractLinkedList", True, "removeFirst", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.list", "AbstractLinkedList", True, "removeLast", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.list", "AbstractListDecorator", True, "AbstractListDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "AbstractSerializableListDecorator", True, "AbstractSerializableListDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "CursorableLinkedList", True, "CursorableLinkedList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "CursorableLinkedList", True, "cursor", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "FixedSizeList", True, "fixedSizeList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "GrowthList", True, "growthList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "LazyList", True, "lazyList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "NodeCachingLinkedList", True, "NodeCachingLinkedList", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "PredicatedList", True, "predicatedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "SetUniqueList", True, "asSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "SetUniqueList", True, "setUniqueList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "TransformedList", True, "transformingList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "TreeList", True, "TreeList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "UnmodifiableList", True, "UnmodifiableList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "UnmodifiableList", True, "unmodifiableList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.map.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.map.model.yml new file mode 100644 index 00000000000..77b0d66f081 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.map.model.yml @@ -0,0 +1,133 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections4.map", "AbstractHashedMap", True, "AbstractHashedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractHashedMap", True, "AbstractHashedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractLinkedMap", True, "AbstractLinkedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractLinkedMap", True, "AbstractLinkedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractMapDecorator", True, "AbstractMapDecorator", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractMapDecorator", True, "AbstractMapDecorator", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractMapDecorator", True, "decorated", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractMapDecorator", True, "decorated", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractOrderedMapDecorator", True, "AbstractOrderedMapDecorator", "(OrderedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractOrderedMapDecorator", True, "AbstractOrderedMapDecorator", "(OrderedMap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractSortedMapDecorator", True, "AbstractSortedMapDecorator", "(SortedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractSortedMapDecorator", True, "AbstractSortedMapDecorator", "(SortedMap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CaseInsensitiveMap", True, "CaseInsensitiveMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CaseInsensitiveMap", True, "CaseInsensitiveMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map,Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map,Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map,Map)", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map,Map)", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map,Map,MapMutator)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map,Map,MapMutator)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map,Map,MapMutator)", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map,Map,MapMutator)", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map[])", "", "Argument[0].ArrayElement.MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map[])", "", "Argument[0].ArrayElement.MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map[],MapMutator)", "", "Argument[0].ArrayElement.MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map[],MapMutator)", "", "Argument[0].ArrayElement.MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "addComposited", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "addComposited", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "removeComposited", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "removeComposited", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "removeComposited", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "DefaultedMap", True, "DefaultedMap", "(Object)", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "DefaultedMap", True, "defaultedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "DefaultedMap", True, "defaultedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "DefaultedMap", True, "defaultedMap", "(Map,Object)", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "EntrySetToMapIteratorAdapter", True, "EntrySetToMapIteratorAdapter", "", "", "Argument[0].Element.MapKey", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "EntrySetToMapIteratorAdapter", True, "EntrySetToMapIteratorAdapter", "", "", "Argument[0].Element.MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "FixedSizeMap", True, "fixedSizeMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "FixedSizeMap", True, "fixedSizeMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "FixedSizeSortedMap", True, "fixedSizeSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "FixedSizeSortedMap", True, "fixedSizeSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "Flat3Map", True, "Flat3Map", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "Flat3Map", True, "Flat3Map", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "HashedMap", True, "HashedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "HashedMap", True, "HashedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LRUMap", True, "LRUMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "LRUMap", True, "LRUMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LRUMap", True, "LRUMap", "(Map,boolean)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "LRUMap", True, "LRUMap", "(Map,boolean)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LRUMap", True, "get", "(Object,boolean)", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LazyMap", True, "lazyMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "LazyMap", True, "lazyMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LazySortedMap", True, "lazySortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "LazySortedMap", True, "lazySortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LinkedMap", True, "LinkedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "LinkedMap", True, "LinkedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LinkedMap", True, "asList", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "LinkedMap", True, "get", "(int)", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LinkedMap", True, "getValue", "(int)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LinkedMap", True, "remove", "(int)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "asList", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "get", "(int)", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "getValue", "(int)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "keyList", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "listOrderedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "listOrderedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "put", "", "", "Argument[1]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "put", "", "", "Argument[2]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "putAll", "", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "putAll", "", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "remove", "(int)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "setValue", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "valueList", "", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "get", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "(Object,Object,Object)", "", "Argument[0..1]", "Argument[-1].MapKey.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "(Object,Object,Object)", "", "Argument[2]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object)", "", "Argument[0..2]", "Argument[-1].MapKey.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object)", "", "Argument[3]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object,Object)", "", "Argument[0..3]", "Argument[-1].MapKey.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object,Object)", "", "Argument[4]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object,Object,Object)", "", "Argument[0..4]", "Argument[-1].MapKey.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object,Object,Object)", "", "Argument[5]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "removeMultiKey", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "getCollection", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "iterator", "()", "", "Argument[-1].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "iterator", "()", "", "Argument[-1].MapValue.Element", "ReturnValue.Element.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "iterator", "(Object)", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "multiValueMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "multiValueMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "putAll", "(Map)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "putAll", "(Object,Collection)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "putAll", "(Object,Collection)", "", "Argument[1].Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "values", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(ExpirationPolicy,Map)", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(ExpirationPolicy,Map)", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(long,Map)", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(long,Map)", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(long,TimeUnit,Map)", "", "Argument[2].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(long,TimeUnit,Map)", "", "Argument[2].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "PredicatedMap", True, "predicatedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "PredicatedMap", True, "predicatedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "PredicatedSortedMap", True, "predicatedSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "PredicatedSortedMap", True, "predicatedSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "SingletonMap", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "SingletonMap", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "SingletonMap", "(KeyValue)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "SingletonMap", "(KeyValue)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "SingletonMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "SingletonMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "SingletonMap", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "SingletonMap", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "setValue", "", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "TransformedMap", True, "transformingMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "TransformedMap", True, "transformingMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "TransformedSortedMap", True, "transformingSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "TransformedSortedMap", True, "transformingSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "UnmodifiableEntrySet", True, "unmodifiableEntrySet", "", "", "Argument[0].Element.MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "UnmodifiableEntrySet", True, "unmodifiableEntrySet", "", "", "Argument[0].Element.MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "UnmodifiableMap", True, "unmodifiableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "UnmodifiableMap", True, "unmodifiableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "UnmodifiableOrderedMap", True, "unmodifiableOrderedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "UnmodifiableOrderedMap", True, "unmodifiableOrderedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "UnmodifiableSortedMap", True, "unmodifiableSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "UnmodifiableSortedMap", True, "unmodifiableSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.model.yml new file mode 100644 index 00000000000..c3e91e9939b --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.model.yml @@ -0,0 +1,365 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections4", "ArrayStack", True, "peek", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "ArrayStack", True, "pop", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "ArrayStack", True, "push", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4", "ArrayStack", True, "push", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "Bag", True, "add", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4", "Bag", True, "uniqueSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "collectionBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "predicatedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "predicatedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "synchronizedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "synchronizedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "transformingBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "transformingSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "unmodifiableBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "unmodifiableSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BidiMap", True, "getKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "BidiMap", True, "inverseBidiMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "BidiMap", True, "inverseBidiMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "BidiMap", True, "removeValue", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "addAll", "(Collection,Enumeration)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "addAll", "(Collection,Iterable)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "addAll", "(Collection,Iterator)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "addAll", "(Collection,Object[])", "", "Argument[1].ArrayElement", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "addIgnoreNull", "", "", "Argument[1]", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "collate", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "collate", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "disjunction", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "disjunction", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "extractSingleton", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "find", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "get", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "get", "(Iterator,int)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "get", "(Map,int)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "get", "(Map,int)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "get", "(Object,int)", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "get", "(Object,int)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "get", "(Object,int)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "get", "(Object,int)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "getCardinalityMap", "", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "intersection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "intersection", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "permutations", "", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "predicatedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "removeAll", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "retainAll", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "select", "(Iterable,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection)", "", "Argument[0].Element", "Argument[2].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection,Collection)", "", "Argument[0].Element", "Argument[2].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection,Collection)", "", "Argument[0].Element", "Argument[3].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection,Collection)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "selectRejected", "(Iterable,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "selectRejected", "(Iterable,Predicate,Collection)", "", "Argument[0].Element", "Argument[2].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "selectRejected", "(Iterable,Predicate,Collection)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "subtract", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "synchronizedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "transformingCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "union", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "union", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "unmodifiableCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "EnumerationUtils", True, "get", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "EnumerationUtils", True, "toList", "(Enumeration)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "EnumerationUtils", True, "toList", "(StringTokenizer)", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "append", "(Iterable)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "append", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "append", "(Object[])", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "append", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "asEnumeration", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "collate", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "collate", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "copyInto", "", "", "Argument[-1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "eval", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "filter", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "limit", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "loop", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "of", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "of", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "of", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "reverse", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "skip", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "toArray", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "toList", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "unique", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "unmodifiable", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "zip", "(Iterable)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "zip", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "zip", "(Iterable[])", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "zip", "(Iterable[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "Get", True, "entrySet", "", "", "Argument[-1].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "Get", True, "entrySet", "", "", "Argument[-1].MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "Get", True, "get", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "Get", True, "keySet", "()", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "Get", True, "remove", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "Get", True, "values", "()", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableGet", True, "mapIterator", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableGet", True, "mapIterator", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "boundedIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[3].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "collatedIterable", "(Comparator,Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "collatedIterable", "(Comparator,Iterable,Iterable)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "collatedIterable", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "collatedIterable", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "filteredIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "find", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "first", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "forEachButLast", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "get", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "loopingIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "partition", "", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "reversedIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "skippingIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "toList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "toString", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "toString", "", "", "Argument[3]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "toString", "", "", "Argument[4]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "uniqueIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "unmodifiableIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "zippingIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "zippingIterable", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "zippingIterable", "(Iterable,Iterable[])", "", "Argument[1].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "arrayIterator", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "arrayListIterator", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "asEnumeration", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "asIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "asIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "asMultipleUseIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "boundedIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "chainedIterator", "(Collection)", "", "Argument[0].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "chainedIterator", "(Iterator,Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "chainedIterator", "(Iterator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "chainedIterator", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "collatedIterator", "(Comparator,Collection)", "", "Argument[1].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "collatedIterator", "(Comparator,Iterator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "collatedIterator", "(Comparator,Iterator,Iterator)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "collatedIterator", "(Comparator,Iterator[])", "", "Argument[1].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "filteredIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "filteredListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "find", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "first", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "forEachButLast", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "get", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "getIterator", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "getIterator", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "getIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "getIterator", "", "", "Argument[0].MapValue", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "loopingIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "loopingListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "peekingIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "pushbackIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "singletonIterator", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "singletonListIterator", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "skippingIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "toArray", "", "", "Argument[0].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "toList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "toListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "toString", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "toString", "", "", "Argument[3]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "toString", "", "", "Argument[4]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "unmodifiableIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "unmodifiableListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "unmodifiableMapIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "unmodifiableMapIterator", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "zippingIterator", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "KeyValue", True, "getKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "KeyValue", True, "getValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "defaultIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "defaultIfNull", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "fixedSizeList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "intersection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "intersection", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "lazyList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "longestCommonSubsequence", "(CharSequence,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "longestCommonSubsequence", "(CharSequence,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "longestCommonSubsequence", "(List,List)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "longestCommonSubsequence", "(List,List)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "longestCommonSubsequence", "(List,List,Equator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "longestCommonSubsequence", "(List,List,Equator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "partition", "", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "predicatedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "removeAll", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "retainAll", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "select", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "selectRejected", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "subtract", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "sum", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "sum", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "synchronizedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "transformedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "union", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "union", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "unmodifiableList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MapIterator", True, "getKey", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapIterator", True, "getValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapIterator", True, "setValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapIterator", True, "setValue", "", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "fixedSizeMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "fixedSizeMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "fixedSizeSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "fixedSizeSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "getMap", "", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "getMap", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "getObject", "", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "getObject", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "getString", "", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "getString", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "invertMap", "", "", "Argument[0].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "invertMap", "", "", "Argument[0].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "iterableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "iterableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "iterableSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "iterableSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "lazyMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "lazyMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "lazySortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "lazySortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "multiValueMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "multiValueMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "orderedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "orderedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "populateMap", "(Map,Iterable,Transformer)", "", "Argument[1].Element", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "populateMap", "(MultiMap,Iterable,Transformer)", "", "Argument[1].Element", "Argument[0].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "predicatedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "predicatedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "predicatedSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "predicatedSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement", "Argument[0].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.ArrayElement", "Argument[0].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.ArrayElement", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.ArrayElement", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.ArrayElement", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.MapKey", "Argument[0].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.MapValue", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "safeAddToMap", "", "", "Argument[1]", "Argument[0].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "safeAddToMap", "", "", "Argument[2]", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "synchronizedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "synchronizedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "synchronizedSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "synchronizedSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "toMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "toMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "transformedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "transformedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "transformedSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "transformedSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "unmodifiableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "unmodifiableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "unmodifiableSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "unmodifiableSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMap", True, "get", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMap", True, "put", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMap", True, "put", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMap", True, "values", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "getCollection", "", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "getValuesAsBag", "", "", "Argument[0].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "getValuesAsList", "", "", "Argument[0].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "getValuesAsSet", "", "", "Argument[0].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "transformedMultiValuedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "transformedMultiValuedMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "unmodifiableMultiValuedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "unmodifiableMultiValuedMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiSet", True, "add", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiSet", True, "entrySet", "", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiSet", True, "uniqueSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiSet$Entry", True, "getElement", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MultiSetUtils", True, "predicatedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiSetUtils", True, "synchronizedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiSetUtils", True, "unmodifiableMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "asMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "asMap", "", "", "Argument[-1].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "entries", "", "", "Argument[-1].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "entries", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "get", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "keySet", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "keys", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "mapIterator", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "mapIterator", "", "", "Argument[-1].MapValue.Element", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "put", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "put", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "putAll", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "putAll", "(MultiValuedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "putAll", "(MultiValuedMap)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "putAll", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "putAll", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "remove", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "values", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "OrderedIterator", True, "previous", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "OrderedMap", True, "firstKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "OrderedMap", True, "lastKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "OrderedMap", True, "nextKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "OrderedMap", True, "previousKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "Put", True, "put", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "Put", True, "put", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "Put", True, "put", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "Put", True, "putAll", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "Put", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "QueueUtils", True, "predicatedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "QueueUtils", True, "synchronizedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "QueueUtils", True, "transformingQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "QueueUtils", True, "unmodifiableQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "difference", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "disjunction", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "disjunction", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "hashSet", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "intersection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "intersection", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "orderedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "predicatedNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "predicatedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "predicatedSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "synchronizedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "synchronizedSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "transformedNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "transformedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "transformedSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "union", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "union", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "unmodifiableNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "unmodifiableSet", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "unmodifiableSet", "(Set)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "unmodifiableSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils$SetView", True, "copyInto", "", "", "Argument[-1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils$SetView", True, "createIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils$SetView", True, "toSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SortedBag", True, "first", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "SortedBag", True, "last", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "SplitMapUtils", True, "readableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "SplitMapUtils", True, "readableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "SplitMapUtils", True, "writableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "SplitMapUtils", True, "writableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "Trie", True, "prefixMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "Trie", True, "prefixMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "TrieUtils", True, "unmodifiableTrie", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "TrieUtils", True, "unmodifiableTrie", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.multimap.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.multimap.model.yml new file mode 100644 index 00000000000..0611ffb8e90 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.multimap.model.yml @@ -0,0 +1,17 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections4.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "HashSetValuedHashMap", True, "HashSetValuedHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "HashSetValuedHashMap", True, "HashSetValuedHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "HashSetValuedHashMap", True, "HashSetValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "HashSetValuedHashMap", True, "HashSetValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "TransformedMultiValuedMap", True, "transformingMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "TransformedMultiValuedMap", True, "transformingMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "UnmodifiableMultiValuedMap", True, "unmodifiableMultiValuedMap", "(MultiValuedMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "UnmodifiableMultiValuedMap", True, "unmodifiableMultiValuedMap", "(MultiValuedMap)", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.multiset.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.multiset.model.yml new file mode 100644 index 00000000000..b73862089c0 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.multiset.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections4.multiset", "HashMultiSet", True, "HashMultiSet", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.multiset", "PredicatedMultiSet", True, "predicatedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.multiset", "SynchronizedMultiSet", True, "synchronizedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.multiset", "UnmodifiableMultiSet", True, "unmodifiableMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.properties.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.properties.model.yml new file mode 100644 index 00000000000..548b50959e1 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.properties.model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections4.properties", "AbstractPropertiesFactory", True, "load", "(ClassLoader,String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4.properties", "AbstractPropertiesFactory", True, "load", "(File)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4.properties", "AbstractPropertiesFactory", True, "load", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4.properties", "AbstractPropertiesFactory", True, "load", "(Path)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4.properties", "AbstractPropertiesFactory", True, "load", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4.properties", "AbstractPropertiesFactory", True, "load", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4.properties", "AbstractPropertiesFactory", True, "load", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4.properties", "AbstractPropertiesFactory", True, "load", "(URL)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.queue.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.queue.model.yml new file mode 100644 index 00000000000..e4385072bc6 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.queue.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections4.queue", "CircularFifoQueue", True, "CircularFifoQueue", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.queue", "CircularFifoQueue", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.queue", "PredicatedQueue", True, "predicatedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.queue", "SynchronizedQueue", True, "synchronizedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.queue", "TransformedQueue", True, "transformingQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.queue", "UnmodifiableQueue", True, "unmodifiableQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.set.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.set.model.yml new file mode 100644 index 00000000000..e6df878695e --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.set.model.yml @@ -0,0 +1,36 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections4.set", "AbstractNavigableSetDecorator", True, "AbstractNavigableSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "AbstractSetDecorator", True, "AbstractSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "AbstractSortedSetDecorator", True, "AbstractSortedSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet", True, "CompositeSet", "(Set)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet", True, "CompositeSet", "(Set[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet", True, "addComposited", "(Set)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet", True, "addComposited", "(Set,Set)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet", True, "addComposited", "(Set,Set)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet", True, "addComposited", "(Set[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet", True, "getSets", "", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet", True, "toSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet$SetMutator", True, "add", "", "", "Argument[2]", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet$SetMutator", True, "add", "", "", "Argument[2]", "Argument[1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet$SetMutator", True, "addAll", "", "", "Argument[2].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet$SetMutator", True, "addAll", "", "", "Argument[2].Element", "Argument[1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "ListOrderedSet", True, "add", "", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "ListOrderedSet", True, "addAll", "", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "ListOrderedSet", True, "asList", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "ListOrderedSet", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.set", "ListOrderedSet", True, "listOrderedSet", "(List)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "ListOrderedSet", True, "listOrderedSet", "(Set)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "MapBackedSet", True, "mapBackedSet", "", "", "Argument[0].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "PredicatedNavigableSet", True, "predicatedNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "PredicatedSet", True, "predicatedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "PredicatedSortedSet", True, "predicatedSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "TransformedNavigableSet", True, "transformingNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "TransformedSet", True, "transformingSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "TransformedSortedSet", True, "transformingSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "UnmodifiableNavigableSet", True, "unmodifiableNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "UnmodifiableSet", True, "unmodifiableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "UnmodifiableSortedSet", True, "unmodifiableSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.splitmap.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.splitmap.model.yml new file mode 100644 index 00000000000..4be99cb8ec9 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.splitmap.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections4.splitmap", "AbstractIterableGetMapDecorator", True, "AbstractIterableGetMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.splitmap", "AbstractIterableGetMapDecorator", True, "AbstractIterableGetMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.splitmap", "TransformedSplitMap", True, "transformingMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.splitmap", "TransformedSplitMap", True, "transformingMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.trie.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.trie.model.yml new file mode 100644 index 00000000000..44d64dda75d --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.trie.model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.collections4.trie", "AbstractPatriciaTrie", True, "select", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.trie", "AbstractPatriciaTrie", True, "select", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.trie", "AbstractPatriciaTrie", True, "selectKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.trie", "AbstractPatriciaTrie", True, "selectValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.trie", "PatriciaTrie", True, "PatriciaTrie", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.trie", "PatriciaTrie", True, "PatriciaTrie", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.trie", "UnmodifiableTrie", True, "unmodifiableTrie", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.trie", "UnmodifiableTrie", True, "unmodifiableTrie", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.io.model.yml b/java/ql/lib/ext/org.apache.commons.io.model.yml new file mode 100644 index 00000000000..c135623eff6 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.io.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.io", "IOUtils", False, "toBufferedInputStream", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.io", "IOUtils", True, "toByteArray", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.io", "IOUtils", True, "toByteArray", "(Reader,String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.io", "IOUtils", True, "writeLines", "(Collection,String,Writer)", "", "Argument[0].Element", "Argument[2]", "taint", "manual"] + - ["org.apache.commons.io", "IOUtils", True, "writeLines", "(Collection,String,Writer)", "", "Argument[1]", "Argument[2]", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.jexl2.model.yml b/java/ql/lib/ext/org.apache.commons.jexl2.model.yml new file mode 100644 index 00000000000..7d6e5d070d2 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.jexl2.model.yml @@ -0,0 +1,20 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.commons.jexl2", "Expression", False, "callable", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "Expression", False, "evaluate", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "JexlEngine", False, "getProperty", "(JexlContext,Object,String)", "", "Argument[2]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "JexlEngine", False, "getProperty", "(Object,String)", "", "Argument[1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "JexlEngine", False, "setProperty", "(JexlContext,Object,String,Object)", "", "Argument[2]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "JexlEngine", False, "setProperty", "(Object,String,Object)", "", "Argument[1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "JexlExpression", False, "callable", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "JexlExpression", False, "evaluate", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "JexlScript", False, "callable", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "JexlScript", False, "execute", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "Script", False, "callable", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "Script", False, "execute", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "UnifiedJEXL$Expression", False, "evaluate", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "UnifiedJEXL$Expression", False, "prepare", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "UnifiedJEXL$Template", False, "evaluate", "", "", "Argument[-1]", "jexl", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.jexl3.model.yml b/java/ql/lib/ext/org.apache.commons.jexl3.model.yml new file mode 100644 index 00000000000..a911fe7f22c --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.jexl3.model.yml @@ -0,0 +1,20 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.commons.jexl3", "Expression", False, "callable", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "Expression", False, "evaluate", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JexlEngine", False, "getProperty", "(JexlContext,Object,String)", "", "Argument[2]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JexlEngine", False, "getProperty", "(Object,String)", "", "Argument[1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JexlEngine", False, "setProperty", "(JexlContext,Object,String)", "", "Argument[2]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JexlEngine", False, "setProperty", "(Object,String,Object)", "", "Argument[1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JexlExpression", False, "callable", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JexlExpression", False, "evaluate", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JexlScript", False, "callable", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JexlScript", False, "execute", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JxltEngine$Expression", False, "evaluate", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JxltEngine$Expression", False, "prepare", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JxltEngine$Template", False, "evaluate", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "Script", False, "callable", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "Script", False, "execute", "", "", "Argument[-1]", "jexl", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.lang3.builder.model.yml b/java/ql/lib/ext/org.apache.commons.lang3.builder.model.yml new file mode 100644 index 00000000000..cf4967b0cb5 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.lang3.builder.model.yml @@ -0,0 +1,22 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "(java.lang.Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "(java.lang.Object[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "(java.lang.String,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "(java.lang.String,java.lang.Object)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "(java.lang.String,java.lang.Object[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "(java.lang.String,java.lang.Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "(java.lang.String,java.lang.Object[],boolean)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "(java.lang.String,java.lang.Object[],boolean)", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "appendAsObjectToString", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "appendSuper", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "appendSuper", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "appendToString", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "appendToString", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "getStringBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.lang3.model.yml b/java/ql/lib/ext/org.apache.commons.lang3.model.yml new file mode 100644 index 00000000000..4b0c89d2731 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.lang3.model.yml @@ -0,0 +1,207 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "", "", "Argument[2]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(boolean[],boolean)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(byte[],byte)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(char[],char)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(double[],double)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(float[],float)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(int[],int)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(java.lang.Object[],java.lang.Object)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(long[],long)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(short[],short)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "addAll", "", "", "Argument[0..1].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "addFirst", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "addFirst", "", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "clone", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "get", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "get", "(java.lang.Object[],int,java.lang.Object)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "insert", "", "", "Argument[1..2].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "nullToEmpty", "(java.lang.Object[],java.lang.Class)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "nullToEmpty", "(java.lang.String[])", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "remove", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "removeAll", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "removeAllOccurences", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "removeAllOccurrences", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "removeElement", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "removeElements", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "subarray", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "toArray", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "toMap", "", "", "Argument[0].ArrayElement.ArrayElement", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "toMap", "", "", "Argument[0].ArrayElement.ArrayElement", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "toMap", "", "", "Argument[0].ArrayElement.MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "toMap", "", "", "Argument[0].ArrayElement.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "toObject", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "toPrimitive", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "toPrimitive", "", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "CONST", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "CONST_BYTE", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "CONST_SHORT", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "clone", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "cloneIfPossible", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "defaultIfNull", "", "", "Argument[0..1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "firstNonNull", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "getIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "max", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "median", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "min", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "mode", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "requireNonEmpty", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "toString", "(Object,String)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "removeAll", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "removeFirst", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "removePattern", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replaceAll", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replaceAll", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replaceFirst", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replaceFirst", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replacePattern", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replacePattern", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringEscapeUtils", False, "escapeJson", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "abbreviate", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "abbreviate", "(java.lang.String,java.lang.String,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "abbreviate", "(java.lang.String,java.lang.String,int,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "abbreviateMiddle", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "abbreviateMiddle", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "appendIfMissing", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "appendIfMissing", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "appendIfMissingIgnoreCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "appendIfMissingIgnoreCase", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "capitalize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "center", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "center", "(java.lang.String,int,java.lang.String)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "chomp", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "chomp", "(java.lang.String,java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "chop", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "defaultIfBlank", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "defaultIfEmpty", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "defaultString", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "deleteWhitespace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "difference", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "firstNonBlank", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "firstNonEmpty", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "getBytes", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "getCommonPrefix", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "getDigits", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "getIfBlank", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "getIfEmpty", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(char[],char)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(char[],char,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Iterable,char)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Iterable,java.lang.String)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Iterable,java.lang.String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Object[],char)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Object[],char,int,int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Object[],java.lang.String)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Object[],java.lang.String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Object[],java.lang.String,int,int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Object[],java.lang.String,int,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.util.Iterator,char)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.util.Iterator,java.lang.String)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.util.Iterator,java.lang.String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.util.List,char,int,int)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.util.List,java.lang.String,int,int)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.util.List,java.lang.String,int,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "joinWith", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "joinWith", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "left", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "leftPad", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "leftPad", "(java.lang.String,int,java.lang.String)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "lowerCase", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "lowerCase", "(java.lang.String,java.util.Locale)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "mid", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "normalizeSpace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "overlay", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "overlay", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "prependIfMissing", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "prependIfMissing", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "prependIfMissingIgnoreCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "prependIfMissingIgnoreCase", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "remove", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "removeAll", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "removeEnd", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "removeEndIgnoreCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "removeFirst", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "removeIgnoreCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "removePattern", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "removeStart", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "removeStartIgnoreCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "repeat", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "repeat", "(java.lang.String,java.lang.String,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replace", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceAll", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceAll", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceChars", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceChars", "(java.lang.String,java.lang.String,java.lang.String)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceEach", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceEach", "", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceEachRepeatedly", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceEachRepeatedly", "", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceFirst", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceFirst", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceIgnoreCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceIgnoreCase", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceOnce", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceOnce", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceOnceIgnoreCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceOnceIgnoreCase", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replacePattern", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replacePattern", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "reverse", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "reverseDelimited", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "right", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "rightPad", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "rightPad", "(java.lang.String,int,java.lang.String)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "rotate", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "split", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "split", "(java.lang.String,char)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "split", "(java.lang.String,java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "split", "(java.lang.String,java.lang.String,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "splitByCharacterType", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "splitByCharacterTypeCamelCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "splitByWholeSeparator", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "splitByWholeSeparatorPreserveAllTokens", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "splitPreserveAllTokens", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "splitPreserveAllTokens", "(java.lang.String,char)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "splitPreserveAllTokens", "(java.lang.String,java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "splitPreserveAllTokens", "(java.lang.String,java.lang.String,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "strip", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "strip", "(java.lang.String,java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "stripAccents", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "stripAll", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "stripEnd", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "stripStart", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "stripToEmpty", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "stripToNull", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "substring", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "substringAfter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "substringAfterLast", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "substringBefore", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "substringBeforeLast", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "substringBetween", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "substringsBetween", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "swapCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "toCodePoints", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "toEncodedString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "toRootLowerCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "toRootUpperCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "trim", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "trimToEmpty", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "trimToNull", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "truncate", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "uncapitalize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "unwrap", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "upperCase", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "upperCase", "(java.lang.String,java.util.Locale)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "valueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "wrap", "(java.lang.String,char)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "wrap", "(java.lang.String,java.lang.String)", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "wrapIfMissing", "(java.lang.String,char)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "wrapIfMissing", "(java.lang.String,java.lang.String)", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.lang3.mutable.model.yml b/java/ql/lib/ext/org.apache.commons.lang3.mutable.model.yml new file mode 100644 index 00000000000..0a576393e10 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.lang3.mutable.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.lang3.mutable", "Mutable", True, "getValue", "", "", "Argument[-1].SyntheticField[org.apache.commons.lang3.mutable.MutableObject.value]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.mutable", "Mutable", True, "setValue", "", "", "Argument[0]", "Argument[-1].SyntheticField[org.apache.commons.lang3.mutable.MutableObject.value]", "value", "manual"] + - ["org.apache.commons.lang3.mutable", "MutableObject", False, "MutableObject", "", "", "Argument[0]", "Argument[-1].SyntheticField[org.apache.commons.lang3.mutable.MutableObject.value]", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.lang3.text.model.yml b/java/ql/lib/ext/org.apache.commons.lang3.text.model.yml new file mode 100644 index 00000000000..c31cffeb62c --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.lang3.text.model.yml @@ -0,0 +1,160 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.lang3.text", "StrBuilder", False, "StrBuilder", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(char[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.CharSequence,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.String,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.String,java.lang.Object[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.String,java.lang.Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.StringBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.StringBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.StringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.StringBuilder,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.nio.CharBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.nio.CharBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(org.apache.commons.lang3.text.StrBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendAll", "(Iterable)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendAll", "(Iterator)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendAll", "(Object[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendNewLine", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendPadding", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendSeparator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendSeparator", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendSeparator", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendSeparator", "(java.lang.String,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendSeparator", "(java.lang.String,java.lang.String)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendWithSeparators", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendWithSeparators", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendWithSeparators", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendWithSeparators", "(Iterable,String)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendWithSeparators", "(Iterator,String)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendWithSeparators", "(Object[],String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(char[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.String,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.String,java.lang.Object[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.String,java.lang.Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.StringBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.StringBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.StringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.StringBuilder,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(org.apache.commons.lang3.text.StrBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "asReader", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "asTokenizer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "delete", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "deleteAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "deleteCharAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "deleteFirst", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "ensureCapacity", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "getChars", "(char[])", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "getChars", "(char[])", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "getChars", "(int,int,char[],int)", "", "Argument[-1]", "Argument[2]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "insert", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "insert", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "insert", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "leftString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "midString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "minimizeCapacity", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "readFrom", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replace", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replace", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replace", "(int,int,java.lang.String)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replace", "(org.apache.commons.lang3.text.StrMatcher,java.lang.String,int,int,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replaceAll", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replaceFirst", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replaceFirst", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replaceFirst", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "reverse", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "rightString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "setCharAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "setLength", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "setNewLineText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "setNullText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "subSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "substring", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "toCharArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "toStringBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "toStringBuilder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "trim", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrLookup", False, "lookup", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrLookup", False, "mapLookup", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "StrSubstitutor", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "StrSubstitutor", "", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.CharSequence,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.Object,java.util.Map)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.Object,java.util.Map)", "", "Argument[1].MapValue", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.Object,java.util.Map,java.lang.String,java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.Object,java.util.Map,java.lang.String,java.lang.String)", "", "Argument[1].MapValue", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.Object,java.util.Properties)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.Object,java.util.Properties)", "", "Argument[1].MapValue", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.String,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.StringBuffer)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.StringBuffer,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(org.apache.commons.lang3.text.StrBuilder)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(org.apache.commons.lang3.text.StrBuilder,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replaceIn", "(java.lang.StringBuffer)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replaceIn", "(java.lang.StringBuffer,int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replaceIn", "(java.lang.StringBuilder)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replaceIn", "(java.lang.StringBuilder,int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replaceIn", "(org.apache.commons.lang3.text.StrBuilder)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replaceIn", "(org.apache.commons.lang3.text.StrBuilder,int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "setVariableResolver", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "StrTokenizer", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "getCSVInstance", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "getContent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "getTSVInstance", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "getTokenArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "getTokenList", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "next", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "nextToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "previous", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "previousToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "reset", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "reset", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "capitalize", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "capitalize", "(java.lang.String,char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "capitalizeFully", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "capitalizeFully", "(java.lang.String,char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "initials", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "initials", "(java.lang.String,char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "swapCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "uncapitalize", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "uncapitalize", "(java.lang.String,char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "wrap", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "wrap", "(java.lang.String,int,java.lang.String,boolean)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "wrap", "(java.lang.String,int,java.lang.String,boolean,java.lang.String)", "", "Argument[2]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.lang3.tuple.model.yml b/java/ql/lib/ext/org.apache.commons.lang3.tuple.model.yml new file mode 100644 index 00000000000..204c890dd5e --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.lang3.tuple.model.yml @@ -0,0 +1,52 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.lang3.tuple", "ImmutablePair", False, "ImmutablePair", "(java.lang.Object,java.lang.Object)", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutablePair", False, "ImmutablePair", "(java.lang.Object,java.lang.Object)", "", "Argument[1]", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutablePair", False, "left", "", "", "Argument[0]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutablePair", False, "of", "(java.lang.Object,java.lang.Object)", "", "Argument[0]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutablePair", False, "of", "(java.lang.Object,java.lang.Object)", "", "Argument[1]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutablePair", False, "right", "", "", "Argument[0]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutableTriple", False, "ImmutableTriple", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutableTriple", False, "ImmutableTriple", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[1]", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutableTriple", False, "ImmutableTriple", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[2]", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutableTriple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[0]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutableTriple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[1]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutableTriple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[2]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutablePair", False, "MutablePair", "(java.lang.Object,java.lang.Object)", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutablePair", False, "MutablePair", "(java.lang.Object,java.lang.Object)", "", "Argument[1]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutablePair", False, "of", "(java.lang.Object,java.lang.Object)", "", "Argument[0]", "ReturnValue.Field[org.apache.commons.lang3.tuple.MutablePair.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutablePair", False, "of", "(java.lang.Object,java.lang.Object)", "", "Argument[1]", "ReturnValue.Field[org.apache.commons.lang3.tuple.MutablePair.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutablePair", False, "setLeft", "", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutablePair", False, "setRight", "", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutablePair", False, "setValue", "", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "MutableTriple", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "MutableTriple", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[1]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.middle]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "MutableTriple", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[2]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[0]", "ReturnValue.Field[org.apache.commons.lang3.tuple.MutableTriple.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[1]", "ReturnValue.Field[org.apache.commons.lang3.tuple.MutableTriple.middle]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[2]", "ReturnValue.Field[org.apache.commons.lang3.tuple.MutableTriple.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "setLeft", "", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "setMiddle", "", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.middle]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "setRight", "", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", True, "getKey", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.left]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", True, "getKey", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.left]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", True, "getLeft", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.left]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", True, "getLeft", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.left]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", True, "getRight", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.right]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", True, "getRight", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", True, "getValue", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.right]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", True, "getValue", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", False, "of", "(java.lang.Object,java.lang.Object)", "", "Argument[0]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", False, "of", "(java.lang.Object,java.lang.Object)", "", "Argument[1]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", True, "getLeft", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.left]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", True, "getLeft", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.left]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", True, "getMiddle", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", True, "getMiddle", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.middle]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", True, "getRight", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.right]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", True, "getRight", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.right]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[0]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[1]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[2]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.right]", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.logging.model.yml b/java/ql/lib/ext/org.apache.commons.logging.model.yml new file mode 100644 index 00000000000..252ebf9634a --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.logging.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.commons.logging", "Log", True, "debug", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.commons.logging", "Log", True, "error", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.commons.logging", "Log", True, "fatal", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.commons.logging", "Log", True, "info", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.commons.logging", "Log", True, "trace", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.commons.logging", "Log", True, "warn", "", "", "Argument[0]", "logging", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.ognl.enhance.model.yml b/java/ql/lib/ext/org.apache.commons.ognl.enhance.model.yml new file mode 100644 index 00000000000..8f3e1a5a966 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.ognl.enhance.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.commons.ognl.enhance", "ExpressionAccessor", True, "get", "", "", "Argument[-1]", "ognl-injection", "manual"] + - ["org.apache.commons.ognl.enhance", "ExpressionAccessor", True, "set", "", "", "Argument[-1]", "ognl-injection", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.ognl.model.yml b/java/ql/lib/ext/org.apache.commons.ognl.model.yml new file mode 100644 index 00000000000..4f7190d5342 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.ognl.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.commons.ognl", "Node", True, "getValue", "", "", "Argument[-1]", "ognl-injection", "manual"] + - ["org.apache.commons.ognl", "Node", True, "setValue", "", "", "Argument[-1]", "ognl-injection", "manual"] + - ["org.apache.commons.ognl", "Ognl", False, "getValue", "", "", "Argument[0]", "ognl-injection", "manual"] + - ["org.apache.commons.ognl", "Ognl", False, "setValue", "", "", "Argument[0]", "ognl-injection", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.text.lookup.model.yml b/java/ql/lib/ext/org.apache.commons.text.lookup.model.yml new file mode 100644 index 00000000000..9bea394d619 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.text.lookup.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.text.lookup", "StringLookup", True, "lookup", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text.lookup", "StringLookupFactory", False, "mapStringLookup", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.text.model.yml b/java/ql/lib/ext/org.apache.commons.text.model.yml new file mode 100644 index 00000000000..8fd87c79147 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.text.model.yml @@ -0,0 +1,275 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.text", "StrBuilder", False, "StrBuilder", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(char[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.CharSequence,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.String,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.String,java.lang.Object[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.String,java.lang.Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.StringBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.StringBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.StringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.StringBuilder,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.nio.CharBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.nio.CharBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(org.apache.commons.text.StrBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendAll", "(Iterable)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendAll", "(Iterator)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendAll", "(Object[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendNewLine", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendPadding", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendSeparator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendSeparator", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendSeparator", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendSeparator", "(java.lang.String,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendSeparator", "(java.lang.String,java.lang.String)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendWithSeparators", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendWithSeparators", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendWithSeparators", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendWithSeparators", "(Iterable,String)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendWithSeparators", "(Iterator,String)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendWithSeparators", "(Object[],String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(char[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.String,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.String,java.lang.Object[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.String,java.lang.Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.StringBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.StringBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.StringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.StringBuilder,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(org.apache.commons.text.StrBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "asReader", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "asTokenizer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "delete", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "deleteAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "deleteCharAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "deleteFirst", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "ensureCapacity", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "getChars", "(char[])", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "getChars", "(char[])", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "getChars", "(int,int,char[],int)", "", "Argument[-1]", "Argument[2]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "insert", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "insert", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "insert", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "leftString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "midString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "minimizeCapacity", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "readFrom", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replace", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replace", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replace", "(int,int,java.lang.String)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replace", "(org.apache.commons.text.StrMatcher,java.lang.String,int,int,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replaceAll", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replaceFirst", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replaceFirst", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replaceFirst", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "reverse", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "rightString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "setCharAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "setLength", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "setNewLineText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "setNullText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "subSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "substring", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "toCharArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "toStringBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "toStringBuilder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "trim", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "StrTokenizer", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "getCSVInstance", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "getContent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "getTSVInstance", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "getTokenArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "getTokenList", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "next", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "nextToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "previous", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "previousToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "reset", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "reset", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "StringSubstitutor", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "StringSubstitutor", "", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.CharSequence,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.Object,java.util.Map)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.Object,java.util.Map)", "", "Argument[1].MapValue", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.Object,java.util.Map,java.lang.String,java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.Object,java.util.Map,java.lang.String,java.lang.String)", "", "Argument[1].MapValue", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.Object,java.util.Properties)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.Object,java.util.Properties)", "", "Argument[1].MapValue", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.String,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.StringBuffer)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.StringBuffer,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(org.apache.commons.text.TextStringBuilder)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(org.apache.commons.text.TextStringBuilder,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replaceIn", "(java.lang.StringBuffer)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replaceIn", "(java.lang.StringBuffer,int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replaceIn", "(java.lang.StringBuilder)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replaceIn", "(java.lang.StringBuilder,int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replaceIn", "(org.apache.commons.text.TextStringBuilder)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replaceIn", "(org.apache.commons.text.TextStringBuilder,int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "setVariableResolver", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "StringTokenizer", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "getCSVInstance", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "getContent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "getTSVInstance", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "getTokenArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "getTokenList", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "next", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "nextToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "previous", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "previousToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "reset", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "reset", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "TextStringBuilder", "(java.lang.CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "TextStringBuilder", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(char[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.CharSequence,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.String,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.String,java.lang.Object[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.String,java.lang.Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.StringBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.StringBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.StringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.StringBuilder,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.nio.CharBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.nio.CharBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(org.apache.commons.text.TextStringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendAll", "(Iterable)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendAll", "(Iterator)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendAll", "(Object[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendNewLine", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendPadding", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendSeparator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendSeparator", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendSeparator", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendSeparator", "(java.lang.String,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendSeparator", "(java.lang.String,java.lang.String)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendWithSeparators", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendWithSeparators", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendWithSeparators", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendWithSeparators", "(Iterable,String)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendWithSeparators", "(Iterator,String)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendWithSeparators", "(Object[],String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(char[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.String,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.String,java.lang.Object[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.String,java.lang.Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.StringBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.StringBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.StringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.StringBuilder,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(org.apache.commons.text.TextStringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "asReader", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "asTokenizer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "delete", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "deleteAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "deleteCharAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "deleteFirst", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "ensureCapacity", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "getChars", "(char[])", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "getChars", "(char[])", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "getChars", "(int,int,char[],int)", "", "Argument[-1]", "Argument[2]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "insert", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "insert", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "insert", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "leftString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "midString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "minimizeCapacity", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "readFrom", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replace", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replace", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replace", "(int,int,java.lang.String)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replace", "(org.apache.commons.text.matcher.StringMatcher,java.lang.String,int,int,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replaceAll", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replaceFirst", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replaceFirst", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replaceFirst", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "reverse", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "rightString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "setCharAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "setLength", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "setNewLineText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "setNullText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "subSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "substring", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "toCharArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "toStringBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "toStringBuilder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "trim", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "abbreviate", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "abbreviate", "", "", "Argument[3]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "capitalize", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "capitalize", "(java.lang.String,char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "capitalizeFully", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "capitalizeFully", "(java.lang.String,char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "initials", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "initials", "(java.lang.String,char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "swapCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "uncapitalize", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "uncapitalize", "(java.lang.String,char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "wrap", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "wrap", "(java.lang.String,int,java.lang.String,boolean)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "wrap", "(java.lang.String,int,java.lang.String,boolean,java.lang.String)", "", "Argument[2]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.directory.ldap.client.api.model.yml b/java/ql/lib/ext/org.apache.directory.ldap.client.api.model.yml new file mode 100644 index 00000000000..5eb28c7c073 --- /dev/null +++ b/java/ql/lib/ext/org.apache.directory.ldap.client.api.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.directory.ldap.client.api", "LdapConnection", True, "search", "", "", "Argument[0..2]", "ldap", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.function.model.yml b/java/ql/lib/ext/org.apache.hc.core5.function.model.yml new file mode 100644 index 00000000000..f001872f720 --- /dev/null +++ b/java/ql/lib/ext/org.apache.hc.core5.function.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.hc.core5.function", "Supplier", True, "get", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.http.io.entity.model.yml b/java/ql/lib/ext/org.apache.hc.core5.http.io.entity.model.yml new file mode 100644 index 00000000000..14ce196044f --- /dev/null +++ b/java/ql/lib/ext/org.apache.hc.core5.http.io.entity.model.yml @@ -0,0 +1,19 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.hc.core5.http.io.entity", "BasicHttpEntity", True, "BasicHttpEntity", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "BufferedHttpEntity", True, "BufferedHttpEntity", "(HttpEntity)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "ByteArrayEntity", True, "ByteArrayEntity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "EntityUtils", True, "parse", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "EntityUtils", True, "toByteArray", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "EntityUtils", True, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "HttpEntities", True, "create", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "HttpEntities", True, "createGzipped", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "HttpEntities", True, "createUrlEncoded", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "HttpEntities", True, "gzip", "(HttpEntity)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "HttpEntities", True, "withTrailers", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "HttpEntityWrapper", True, "HttpEntityWrapper", "(HttpEntity)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "InputStreamEntity", True, "InputStreamEntity", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "StringEntity", True, "StringEntity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.http.io.model.yml b/java/ql/lib/ext/org.apache.hc.core5.http.io.model.yml new file mode 100644 index 00000000000..9fdf2b1fd2e --- /dev/null +++ b/java/ql/lib/ext/org.apache.hc.core5.http.io.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["org.apache.hc.core5.http.io", "HttpRequestHandler", True, "handle", "(ClassicHttpRequest,ClassicHttpResponse,HttpContext)", "", "Parameter[0]", "remote", "manual"] + - ["org.apache.hc.core5.http.io", "HttpServerRequestHandler", True, "handle", "(ClassicHttpRequest,ResponseTrigger,HttpContext)", "", "Parameter[0]", "remote", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.http.message.model.yml b/java/ql/lib/ext/org.apache.hc.core5.http.message.model.yml new file mode 100644 index 00000000000..9d982e54178 --- /dev/null +++ b/java/ql/lib/ext/org.apache.hc.core5.http.message.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.hc.core5.http.message", "RequestLine", True, "RequestLine", "(HttpRequest)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.http.message", "RequestLine", True, "RequestLine", "(String,String,ProtocolVersion)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.http.message", "RequestLine", True, "getMethod", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.message", "RequestLine", True, "getUri", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.message", "RequestLine", True, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.http.model.yml b/java/ql/lib/ext/org.apache.hc.core5.http.model.yml new file mode 100644 index 00000000000..220728fadca --- /dev/null +++ b/java/ql/lib/ext/org.apache.hc.core5.http.model.yml @@ -0,0 +1,30 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.hc.core5.http", "HttpEntityContainer", True, "setEntity", "(HttpEntity)", "", "Argument[0]", "xss", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.hc.core5.http", "EntityDetails", True, "getContentEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "EntityDetails", True, "getContentType", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "EntityDetails", True, "getTrailerNames", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "HttpEntity", True, "getContent", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "HttpEntity", True, "getTrailers", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "HttpEntityContainer", True, "getEntity", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "HttpRequest", True, "getAuthority", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "HttpRequest", True, "getMethod", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "HttpRequest", True, "getPath", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "HttpRequest", True, "getRequestUri", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "HttpRequest", True, "getUri", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "MessageHeaders", True, "getFirstHeader", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "MessageHeaders", True, "getHeader", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "MessageHeaders", True, "getHeaders", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "MessageHeaders", True, "getHeaders", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "MessageHeaders", True, "getLastHeader", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "MessageHeaders", True, "headerIterator", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "MessageHeaders", True, "headerIterator", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "NameValuePair", True, "getName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "NameValuePair", True, "getValue", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.net.model.yml b/java/ql/lib/ext/org.apache.hc.core5.net.model.yml new file mode 100644 index 00000000000..19213c0764f --- /dev/null +++ b/java/ql/lib/ext/org.apache.hc.core5.net.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.hc.core5.net", "URIAuthority", True, "getHostName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.net", "URIAuthority", True, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.util.model.yml b/java/ql/lib/ext/org.apache.hc.core5.util.model.yml new file mode 100644 index 00000000000..ae9af22ac77 --- /dev/null +++ b/java/ql/lib/ext/org.apache.hc.core5.util.model.yml @@ -0,0 +1,29 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.hc.core5.util", "Args", True, "containsNoBlanks", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.hc.core5.util", "Args", True, "notBlank", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.hc.core5.util", "Args", True, "notEmpty", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.hc.core5.util", "Args", True, "notEmpty", "(Collection,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.hc.core5.util", "Args", True, "notEmpty", "(Object,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.hc.core5.util", "Args", True, "notNull", "(Object,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.hc.core5.util", "ByteArrayBuffer", True, "append", "(CharArrayBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "ByteArrayBuffer", True, "append", "(byte[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "ByteArrayBuffer", True, "append", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "ByteArrayBuffer", True, "array", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.util", "ByteArrayBuffer", True, "toByteArray", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "append", "(ByteArrayBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "append", "(CharArrayBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "append", "(CharArrayBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "append", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "append", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "append", "(byte[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "append", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "array", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "subSequence", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "substring", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "substringTrimmed", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "toCharArray", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.http.client.methods.model.yml b/java/ql/lib/ext/org.apache.http.client.methods.model.yml new file mode 100644 index 00000000000..99b0a4968cf --- /dev/null +++ b/java/ql/lib/ext/org.apache.http.client.methods.model.yml @@ -0,0 +1,23 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.http.client.methods", "HttpDelete", False, "HttpDelete", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "HttpGet", False, "HttpGet", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "HttpHead", False, "HttpHead", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "HttpOptions", False, "HttpOptions", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "HttpPatch", False, "HttpPatch", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "HttpPost", False, "HttpPost", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "HttpPut", False, "HttpPut", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "HttpRequestBase", True, "setURI", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "HttpTrace", False, "HttpTrace", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "delete", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "get", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "head", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "options", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "patch", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "post", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "put", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "setUri", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "trace", "", "", "Argument[0]", "open-url", "manual"] diff --git a/java/ql/lib/ext/org.apache.http.entity.model.yml b/java/ql/lib/ext/org.apache.http.entity.model.yml new file mode 100644 index 00000000000..2e299bff5d4 --- /dev/null +++ b/java/ql/lib/ext/org.apache.http.entity.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.http.entity", "BasicHttpEntity", True, "setContent", "(InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.entity", "BufferedHttpEntity", True, "BufferedHttpEntity", "(HttpEntity)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.entity", "ByteArrayEntity", True, "ByteArrayEntity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.entity", "HttpEntityWrapper", True, "HttpEntityWrapper", "(HttpEntity)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.entity", "InputStreamEntity", True, "InputStreamEntity", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.entity", "StringEntity", True, "StringEntity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.http.message.model.yml b/java/ql/lib/ext/org.apache.http.message.model.yml new file mode 100644 index 00000000000..b1caf80721b --- /dev/null +++ b/java/ql/lib/ext/org.apache.http.message.model.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.http.message", "BasicHttpEntityEnclosingRequest", False, "BasicHttpEntityEnclosingRequest", "(RequestLine)", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.message", "BasicHttpEntityEnclosingRequest", False, "BasicHttpEntityEnclosingRequest", "(String,String)", "", "Argument[1]", "open-url", "manual"] + - ["org.apache.http.message", "BasicHttpEntityEnclosingRequest", False, "BasicHttpEntityEnclosingRequest", "(String,String,ProtocolVersion)", "", "Argument[1]", "open-url", "manual"] + - ["org.apache.http.message", "BasicHttpRequest", False, "BasicHttpRequest", "(RequestLine)", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.message", "BasicHttpRequest", False, "BasicHttpRequest", "(String,String)", "", "Argument[1]", "open-url", "manual"] + - ["org.apache.http.message", "BasicHttpRequest", False, "BasicHttpRequest", "(String,String,ProtocolVersion)", "", "Argument[1]", "open-url", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.http.message", "BasicRequestLine", False, "BasicRequestLine", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.http.model.yml b/java/ql/lib/ext/org.apache.http.model.yml new file mode 100644 index 00000000000..76de35242b7 --- /dev/null +++ b/java/ql/lib/ext/org.apache.http.model.yml @@ -0,0 +1,42 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["org.apache.http", "HttpEntity", False, "getContent", "()", "", "ReturnValue", "remote", "manual"] + - ["org.apache.http", "HttpMessage", False, "getParams", "()", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.http", "HttpRequest", True, "setURI", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http", "HttpResponse", True, "setEntity", "(HttpEntity)", "", "Argument[0]", "xss", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.http", "Header", True, "getElements", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HeaderElement", True, "getName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HeaderElement", True, "getParameter", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HeaderElement", True, "getParameterByName", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HeaderElement", True, "getParameters", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HeaderElement", True, "getValue", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HeaderIterator", True, "nextHeader", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpEntity", True, "getContent", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpEntity", True, "getContentEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpEntity", True, "getContentType", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpEntityEnclosingRequest", True, "getEntity", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpMessage", True, "getAllHeaders", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpMessage", True, "getFirstHeader", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpMessage", True, "getHeaders", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpMessage", True, "getLastHeader", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpMessage", True, "getParams", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpMessage", True, "headerIterator", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpMessage", True, "headerIterator", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpRequest", True, "getRequestLine", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "NameValuePair", True, "getName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "NameValuePair", True, "getValue", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "RequestLine", True, "getMethod", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "RequestLine", True, "getUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "RequestLine", True, "getUri", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "RequestLine", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.http.params.model.yml b/java/ql/lib/ext/org.apache.http.params.model.yml new file mode 100644 index 00000000000..0f9facaede8 --- /dev/null +++ b/java/ql/lib/ext/org.apache.http.params.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.http.params", "HttpParams", True, "getDoubleParameter", "(String,double)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.params", "HttpParams", True, "getDoubleParameter", "(String,double)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.apache.http.params", "HttpParams", True, "getIntParameter", "(String,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.params", "HttpParams", True, "getIntParameter", "(String,int)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.apache.http.params", "HttpParams", True, "getLongParameter", "(String,long)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.params", "HttpParams", True, "getLongParameter", "(String,long)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.apache.http.params", "HttpParams", True, "getParameter", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.http.protocol.model.yml b/java/ql/lib/ext/org.apache.http.protocol.model.yml new file mode 100644 index 00000000000..fb99d7f6aa1 --- /dev/null +++ b/java/ql/lib/ext/org.apache.http.protocol.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["org.apache.http.protocol", "HttpRequestHandler", True, "handle", "(HttpRequest,HttpResponse,HttpContext)", "", "Parameter[0]", "remote", "manual"] diff --git a/java/ql/lib/ext/org.apache.http.util.model.yml b/java/ql/lib/ext/org.apache.http.util.model.yml new file mode 100644 index 00000000000..e95178e8281 --- /dev/null +++ b/java/ql/lib/ext/org.apache.http.util.model.yml @@ -0,0 +1,41 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.http.util", "EntityUtils", True, "updateEntity", "(HttpResponse,HttpEntity)", "", "Argument[1]", "xss", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.http.util", "Args", True, "containsNoBlanks", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.http.util", "Args", True, "notBlank", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.http.util", "Args", True, "notEmpty", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.http.util", "Args", True, "notEmpty", "(Collection,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.http.util", "Args", True, "notNull", "(Object,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.http.util", "ByteArrayBuffer", True, "append", "(CharArrayBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "ByteArrayBuffer", True, "append", "(byte[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "ByteArrayBuffer", True, "append", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "ByteArrayBuffer", True, "buffer", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "ByteArrayBuffer", True, "toByteArray", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "append", "(ByteArrayBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "append", "(CharArrayBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "append", "(CharArrayBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "append", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "append", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "append", "(byte[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "append", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "buffer", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "subSequence", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "substring", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "substringTrimmed", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "toCharArray", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "EncodingUtils", True, "getAsciiBytes", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "EncodingUtils", True, "getAsciiString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "EncodingUtils", True, "getBytes", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "EncodingUtils", True, "getString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "EntityUtils", True, "getContentCharSet", "(HttpEntity)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "EntityUtils", True, "getContentMimeType", "(HttpEntity)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "EntityUtils", True, "toByteArray", "(HttpEntity)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "EntityUtils", True, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.ibatis.jdbc.model.yml b/java/ql/lib/ext/org.apache.ibatis.jdbc.model.yml new file mode 100644 index 00000000000..16cfe1404da --- /dev/null +++ b/java/ql/lib/ext/org.apache.ibatis.jdbc.model.yml @@ -0,0 +1,72 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "delete", "(String,Object[])", "", "Argument[0]", "sql", "manual"] + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "insert", "(String,Object[])", "", "Argument[0]", "sql", "manual"] + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "run", "(String)", "", "Argument[0]", "sql", "manual"] + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "selectAll", "(String,Object[])", "", "Argument[0]", "sql", "manual"] + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "selectOne", "(String,Object[])", "", "Argument[0]", "sql", "manual"] + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "update", "(String,Object[])", "", "Argument[0]", "sql", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "DELETE_FROM", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "FETCH_FIRST_ROWS_ONLY", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "FROM", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "FROM", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "FROM", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "FROM", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "GROUP_BY", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "GROUP_BY", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "GROUP_BY", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "GROUP_BY", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "HAVING", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "HAVING", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "HAVING", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "HAVING", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "INNER_JOIN", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "INNER_JOIN", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "INNER_JOIN", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "INNER_JOIN", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "INSERT_INTO", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "INTO_COLUMNS", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "INTO_VALUES", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "JOIN", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "LEFT_OUTER_JOIN", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "LEFT_OUTER_JOIN", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "LEFT_OUTER_JOIN", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "LEFT_OUTER_JOIN", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "LIMIT", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "OFFSET", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "OFFSET_ROWS", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "ORDER_BY", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "ORDER_BY", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "ORDER_BY", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "ORDER_BY", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "OUTER_JOIN", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "OUTER_JOIN", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "OUTER_JOIN", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "OUTER_JOIN", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "RIGHT_OUTER_JOIN", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "RIGHT_OUTER_JOIN", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "RIGHT_OUTER_JOIN", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "RIGHT_OUTER_JOIN", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SELECT", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SELECT_DISTINCT", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SELECT_DISTINCT", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SELECT_DISTINCT", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SELECT_DISTINCT", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SET", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SET", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SET", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SET", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "UPDATE", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "VALUES", "(String,String)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "WHERE", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "WHERE", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "WHERE", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "WHERE", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.log4j.model.yml b/java/ql/lib/ext/org.apache.log4j.model.yml new file mode 100644 index 00000000000..6c10a824dce --- /dev/null +++ b/java/ql/lib/ext/org.apache.log4j.model.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.log4j", "Category", True, "assertLog", "", "", "Argument[1]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "debug", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "error", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "fatal", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "forcedLog", "", "", "Argument[2]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "info", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "l7dlog", "(Priority,String,Object[],Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "log", "(Priority,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "log", "(Priority,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "log", "(String,Priority,Object,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "warn", "", "", "Argument[0]", "logging", "manual"] diff --git a/java/ql/lib/ext/org.apache.logging.log4j.model.yml b/java/ql/lib/ext/org.apache.logging.log4j.model.yml new file mode 100644 index 00000000000..c26023c5fdd --- /dev/null +++ b/java/ql/lib/ext/org.apache.logging.log4j.model.yml @@ -0,0 +1,376 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(CharSequence)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Message)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Supplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(CharSequence)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Message)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Supplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "entry", "(Object[])", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(CharSequence)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Message)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Supplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(CharSequence)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Message)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Supplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(CharSequence)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Message)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Supplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,CharSequence)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,CharSequence)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,CharSequence,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Message)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,MessageSupplier)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,MessageSupplier,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Object)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Object,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object)", "", "Argument[2..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object)", "", "Argument[2..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object)", "", "Argument[2..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object)", "", "Argument[2..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object)", "", "Argument[2..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[2..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..11]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..12]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object[])", "", "Argument[2..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Supplier)", "", "Argument[2..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Supplier)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Supplier,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Message)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Message,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,MessageSupplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Supplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "logMessage", "(Level,Marker,String,StackTraceElement,Message,Throwable)", "", "Argument[4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "printf", "(Level,Marker,String,Object[])", "", "Argument[2..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "printf", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(CharSequence)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Message)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Supplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(Message)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(String,Supplier[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(Supplier[])", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(EntryMessage)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(EntryMessage,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(Message,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(CharSequence)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Message)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Supplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(Message)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(String,Object[])", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(String,Supplier[])", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(Supplier[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(EntryMessage,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(Message,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(Object)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(String,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.shiro.codec.model.yml b/java/ql/lib/ext/org.apache.shiro.codec.model.yml new file mode 100644 index 00000000000..ce779246090 --- /dev/null +++ b/java/ql/lib/ext/org.apache.shiro.codec.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.shiro.codec", "Base64", False, "decode", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.shiro.jndi.model.yml b/java/ql/lib/ext/org.apache.shiro.jndi.model.yml new file mode 100644 index 00000000000..335e4d880ea --- /dev/null +++ b/java/ql/lib/ext/org.apache.shiro.jndi.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.shiro.jndi", "JndiTemplate", False, "lookup", "", "", "Argument[0]", "jndi-injection", "manual"] diff --git a/java/ql/lib/ext/org.apache.velocity.app.model.yml b/java/ql/lib/ext/org.apache.velocity.app.model.yml new file mode 100644 index 00000000000..d29cdea2720 --- /dev/null +++ b/java/ql/lib/ext/org.apache.velocity.app.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.velocity.app", "Velocity", True, "evaluate", "", "", "Argument[3]", "ssti", "manual"] + - ["org.apache.velocity.app", "Velocity", True, "mergeTemplate", "", "", "Argument[2]", "ssti", "manual"] + - ["org.apache.velocity.app", "VelocityEngine", True, "evaluate", "", "", "Argument[3]", "ssti", "manual"] + - ["org.apache.velocity.app", "VelocityEngine", True, "mergeTemplate", "", "", "Argument[2]", "ssti", "manual"] diff --git a/java/ql/lib/ext/org.apache.velocity.runtime.model.yml b/java/ql/lib/ext/org.apache.velocity.runtime.model.yml new file mode 100644 index 00000000000..732bc9036c8 --- /dev/null +++ b/java/ql/lib/ext/org.apache.velocity.runtime.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.velocity.runtime", "RuntimeServices", True, "evaluate", "", "", "Argument[3]", "ssti", "manual"] + - ["org.apache.velocity.runtime", "RuntimeServices", True, "parse", "", "", "Argument[0]", "ssti", "manual"] + - ["org.apache.velocity.runtime", "RuntimeSingleton", True, "parse", "", "", "Argument[0]", "ssti", "manual"] diff --git a/java/ql/lib/ext/org.apache.velocity.runtime.resource.util.model.yml b/java/ql/lib/ext/org.apache.velocity.runtime.resource.util.model.yml new file mode 100644 index 00000000000..cfeadc54e91 --- /dev/null +++ b/java/ql/lib/ext/org.apache.velocity.runtime.resource.util.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.velocity.runtime.resource.util", "StringResourceRepository", True, "putStringResource", "", "", "Argument[1]", "ssti", "manual"] diff --git a/java/ql/lib/ext/org.codehaus.groovy.control.model.yml b/java/ql/lib/ext/org.codehaus.groovy.control.model.yml new file mode 100644 index 00000000000..4727e21f82b --- /dev/null +++ b/java/ql/lib/ext/org.codehaus.groovy.control.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.codehaus.groovy.control", "CompilationUnit", False, "compile", "", "", "Argument[-1]", "groovy", "manual"] diff --git a/java/ql/lib/ext/org.dom4j.model.yml b/java/ql/lib/ext/org.dom4j.model.yml new file mode 100644 index 00000000000..4e40f64dc1b --- /dev/null +++ b/java/ql/lib/ext/org.dom4j.model.yml @@ -0,0 +1,20 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.dom4j", "DocumentFactory", True, "createPattern", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "DocumentFactory", True, "createXPath", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "DocumentFactory", True, "createXPathFilter", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "DocumentHelper", False, "createPattern", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "DocumentHelper", False, "createXPath", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "DocumentHelper", False, "createXPathFilter", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "DocumentHelper", False, "selectNodes", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "DocumentHelper", False, "sort", "", "", "Argument[1]", "xpath", "manual"] + - ["org.dom4j", "Node", True, "createXPath", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "Node", True, "matches", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "Node", True, "numberValueOf", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "Node", True, "selectNodes", "", "", "Argument[0..1]", "xpath", "manual"] + - ["org.dom4j", "Node", True, "selectObject", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "Node", True, "selectSingleNode", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "Node", True, "valueOf", "", "", "Argument[0]", "xpath", "manual"] diff --git a/java/ql/lib/ext/org.dom4j.tree.model.yml b/java/ql/lib/ext/org.dom4j.tree.model.yml new file mode 100644 index 00000000000..dbad39e0f4c --- /dev/null +++ b/java/ql/lib/ext/org.dom4j.tree.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.dom4j.tree", "AbstractNode", True, "createPattern", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j.tree", "AbstractNode", True, "createXPathFilter", "", "", "Argument[0]", "xpath", "manual"] diff --git a/java/ql/lib/ext/org.dom4j.util.model.yml b/java/ql/lib/ext/org.dom4j.util.model.yml new file mode 100644 index 00000000000..587a1b68d32 --- /dev/null +++ b/java/ql/lib/ext/org.dom4j.util.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.dom4j.util", "ProxyDocumentFactory", True, "createPattern", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j.util", "ProxyDocumentFactory", True, "createXPath", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j.util", "ProxyDocumentFactory", True, "createXPathFilter", "", "", "Argument[0]", "xpath", "manual"] diff --git a/java/ql/lib/ext/org.hibernate.model.yml b/java/ql/lib/ext/org.hibernate.model.yml new file mode 100644 index 00000000000..aa550a510e4 --- /dev/null +++ b/java/ql/lib/ext/org.hibernate.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.hibernate", "QueryProducer", True, "createNativeQuery", "", "", "Argument[0]", "sql", "manual"] + - ["org.hibernate", "QueryProducer", True, "createQuery", "", "", "Argument[0]", "sql", "manual"] + - ["org.hibernate", "QueryProducer", True, "createSQLQuery", "", "", "Argument[0]", "sql", "manual"] + - ["org.hibernate", "Session", True, "createQuery", "", "", "Argument[0]", "sql", "manual"] + - ["org.hibernate", "Session", True, "createSQLQuery", "", "", "Argument[0]", "sql", "manual"] + - ["org.hibernate", "SharedSessionContract", True, "createQuery", "", "", "Argument[0]", "sql", "manual"] + - ["org.hibernate", "SharedSessionContract", True, "createSQLQuery", "", "", "Argument[0]", "sql", "manual"] diff --git a/java/ql/lib/ext/org.jboss.logging.model.yml b/java/ql/lib/ext/org.jboss.logging.model.yml new file mode 100644 index 00000000000..e0eb0cd3afe --- /dev/null +++ b/java/ql/lib/ext/org.jboss.logging.model.yml @@ -0,0 +1,329 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.jboss.logging", "BasicLogger", True, "debug", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debug", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debug", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debug", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debug", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,Object,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,String,Object,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(String,Level,Object,Object[],Throwable)", "", "Argument[2..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,Throwable,String,Object)", "", "Argument[2..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,Throwable,String,Object,Object)", "", "Argument[2..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,Throwable,String,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(String,Level,Throwable,String,Object)", "", "Argument[3..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(String,Level,Throwable,String,Object,Object)", "", "Argument[3..5]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(String,Level,Throwable,String,Object,Object,Object)", "", "Argument[3..6]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(String,Level,Throwable,String,Object[])", "", "Argument[3..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,Throwable,String,Object)", "", "Argument[2..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,Throwable,String,Object,Object)", "", "Argument[2..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,Throwable,String,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(String,Level,Throwable,String,Object)", "", "Argument[3..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(String,Level,Throwable,String,Object,Object)", "", "Argument[3..5]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(String,Level,Throwable,String,Object,Object,Object)", "", "Argument[3..6]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(String,Level,Throwable,String,Object[])", "", "Argument[3..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(Level,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(Level,Object,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(Level,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(Level,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(Level,String,Object,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(String,Level,Object,Object[],Throwable)", "", "Argument[2..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,Throwable,String,Object)", "", "Argument[2..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,Throwable,String,Object,Object)", "", "Argument[2..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,Throwable,String,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(String,Level,Throwable,String,Object)", "", "Argument[3..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(String,Level,Throwable,String,Object,Object)", "", "Argument[3..5]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(String,Level,Throwable,String,Object,Object,Object)", "", "Argument[3..6]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(String,Level,Throwable,String,Object[])", "", "Argument[3..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,Throwable,String,Object)", "", "Argument[2..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,Throwable,String,Object,Object)", "", "Argument[2..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,Throwable,String,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(String,Level,Throwable,String,Object)", "", "Argument[3..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(String,Level,Throwable,String,Object,Object)", "", "Argument[3..5]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(String,Level,Throwable,String,Object,Object,Object)", "", "Argument[3..6]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(String,Level,Throwable,String,Object[])", "", "Argument[3..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] diff --git a/java/ql/lib/ext/org.jdbi.v3.core.model.yml b/java/ql/lib/ext/org.jdbi.v3.core.model.yml new file mode 100644 index 00000000000..ae662d16dfd --- /dev/null +++ b/java/ql/lib/ext/org.jdbi.v3.core.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.jdbi.v3.core", "Jdbi", False, "create", "(String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.jdbi.v3.core", "Jdbi", False, "create", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.jdbi.v3.core", "Jdbi", False, "create", "(String,String,String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.jdbi.v3.core", "Jdbi", False, "open", "(String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.jdbi.v3.core", "Jdbi", False, "open", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.jdbi.v3.core", "Jdbi", False, "open", "(String,String,String)", "", "Argument[0]", "jdbc-url", "manual"] diff --git a/java/ql/lib/ext/org.jooq.model.yml b/java/ql/lib/ext/org.jooq.model.yml new file mode 100644 index 00000000000..7de7bdfa6e6 --- /dev/null +++ b/java/ql/lib/ext/org.jooq.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.jooq", "PlainSQL", False, "", "", "Annotated", "Argument[0]", "sql", "manual"] diff --git a/java/ql/lib/ext/org.json.model.yml b/java/ql/lib/ext/org.json.model.yml new file mode 100644 index 00000000000..98a5bb795de --- /dev/null +++ b/java/ql/lib/ext/org.json.model.yml @@ -0,0 +1,241 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.json", "CDL", False, "rowToJSONArray", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "CDL", False, "rowToJSONObject", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.json", "CDL", False, "rowToString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "CDL", False, "toJSONArray", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.json", "CDL", False, "toString", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.json", "Cookie", False, "escape", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "Cookie", False, "toJSONObject", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "Cookie", False, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "Cookie", False, "unescape", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "CookieList", False, "toJSONObject", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "CookieList", False, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "HTTP", False, "toJSONObject", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "HTTP", False, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "HTTPTokener", False, "HTTPTokener", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "HTTPTokener", False, "nextToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "JSONArray", "(Collection)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "JSONArray", "(Iterable)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "JSONArray", "(JSONArray)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "JSONArray", "(JSONTokener)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "JSONArray", "(Object)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "JSONArray", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getBigDecimal", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getBigInteger", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getDouble", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getEnum", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getFloat", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getJSONArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getJSONObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getLong", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getNumber", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "iterator", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.json", "JSONArray", False, "join", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "join", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "opt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optBigDecimal", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optBigDecimal", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optBigInteger", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optBigInteger", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optBoolean", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optDouble", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optDouble", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optEnum", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optEnum", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optFloat", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optFloat", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optInt", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optJSONArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optJSONObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optLong", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optLong", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optNumber", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optNumber", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optQuery", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optString", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "put", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "put", "(Collection)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(Map)", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(Map)", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(boolean)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(double)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(float)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,Collection)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,Map)", "", "Argument[1].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,Map)", "", "Argument[1].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,Object)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,double)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,float)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,long)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(long)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "putAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "putAll", "(Collection)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "putAll", "(Iterable)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "putAll", "(JSONArray)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "putAll", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "query", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "remove", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "toJSONObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "toJSONObject", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "toList", "", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] + - ["org.json", "JSONArray", False, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "write", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.json", "JSONArray", False, "write", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONML", False, "toJSONArray", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONML", False, "toJSONObject", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONML", False, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(JSONObject,String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(JSONObject,String[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(JSONTokener)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(Map)", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(Map)", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(Object,String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(Object,String[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(String,Locale)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "accumulate", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "accumulate", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "append", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "append", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "doubleToString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", True, "entrySet", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.json", "JSONObject", False, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getBigDecimal", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getBigInteger", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getDouble", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getEnum", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getFloat", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getJSONArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getJSONObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getLong", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getNames", "", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.json", "JSONObject", False, "getNumber", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "increment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "increment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "keySet", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.json", "JSONObject", False, "keys", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.json", "JSONObject", False, "names", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "numberToString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "opt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optBigDecimal", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optBigDecimal", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optBigInteger", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optBigInteger", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optBoolean", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optDouble", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optDouble", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optEnum", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optEnum", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optFloat", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optFloat", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optInt", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optJSONArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optJSONObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optLong", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optLong", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optNumber", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optNumber", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optQuery", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optString", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "put", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,Collection)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,Collection)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,Map)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,Map)", "", "Argument[1].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,Map)", "", "Argument[1].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,Object)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,double)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,double)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,float)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,float)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,long)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,long)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "putOnce", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "putOnce", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "putOpt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "putOpt", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "query", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "quote", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "quote", "(String,Writer)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "quote", "(String,Writer)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "remove", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "stringToValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "toJSONArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "toMap", "", "", "Argument[-1]", "ReturnValue.MapKey", "taint", "manual"] + - ["org.json", "JSONObject", False, "toMap", "", "", "Argument[-1]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "valueToString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "wrap", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "write", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.json", "JSONObject", False, "write", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONPointer", False, "JSONPointer", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONPointer", False, "JSONPointer", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONPointer", False, "queryFrom", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONPointer", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONPointer", False, "toURIFragment", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONPointer$Builder", False, "append", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONPointer$Builder", False, "append", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONPointer$Builder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONString", True, "toJSONString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONStringer", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONTokener", True, "JSONTokener", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONTokener", True, "next", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONTokener", True, "nextClean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONTokener", True, "nextString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONTokener", True, "nextTo", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONTokener", True, "nextValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONTokener", True, "syntaxError", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONTokener", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONWriter", True, "JSONWriter", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.json", "JSONWriter", True, "array", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONWriter", True, "endArray", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONWriter", True, "endObject", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONWriter", True, "key", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONWriter", True, "key", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONWriter", True, "object", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONWriter", True, "value", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONWriter", True, "value", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONWriter", True, "valueToString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "Property", False, "toJSONObject", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["org.json", "Property", False, "toJSONObject", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["org.json", "Property", False, "toProperties", "", "", "Argument[0]", "ReturnValue.MapKey", "taint", "manual"] + - ["org.json", "Property", False, "toProperties", "", "", "Argument[0]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.json", "XML", False, "escape", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "XML", False, "stringToValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "XML", False, "toJSONObject", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "XML", False, "toString", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.json", "XML", False, "unescape", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "XMLTokener", False, "XMLTokener", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "XMLTokener", False, "nextCDATA", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "XMLTokener", False, "nextContent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "XMLTokener", False, "nextEntity", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "XMLTokener", False, "nextMeta", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "XMLTokener", False, "nextToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "XMLXsiTypeConverter", True, "convert", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.mvel2.compiler.model.yml b/java/ql/lib/ext/org.mvel2.compiler.model.yml new file mode 100644 index 00000000000..de360871229 --- /dev/null +++ b/java/ql/lib/ext/org.mvel2.compiler.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.mvel2.compiler", "Accessor", False, "getValue", "", "", "Argument[-1]", "mvel", "manual"] + - ["org.mvel2.compiler", "CompiledAccExpression", False, "getValue", "", "", "Argument[-1]", "mvel", "manual"] + - ["org.mvel2.compiler", "CompiledExpression", False, "getDirectValue", "", "", "Argument[-1]", "mvel", "manual"] + - ["org.mvel2.compiler", "ExecutableStatement", False, "getValue", "", "", "Argument[-1]", "mvel", "manual"] diff --git a/java/ql/lib/ext/org.mvel2.jsr223.model.yml b/java/ql/lib/ext/org.mvel2.jsr223.model.yml new file mode 100644 index 00000000000..a7761277e6c --- /dev/null +++ b/java/ql/lib/ext/org.mvel2.jsr223.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.mvel2.jsr223", "MvelCompiledScript", False, "eval", "", "", "Argument[-1]", "mvel", "manual"] + - ["org.mvel2.jsr223", "MvelScriptEngine", False, "eval", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2.jsr223", "MvelScriptEngine", False, "evaluate", "", "", "Argument[0]", "mvel", "manual"] diff --git a/java/ql/lib/ext/org.mvel2.model.yml b/java/ql/lib/ext/org.mvel2.model.yml new file mode 100644 index 00000000000..895d3a15c8c --- /dev/null +++ b/java/ql/lib/ext/org.mvel2.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.mvel2", "MVEL", False, "eval", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2", "MVEL", False, "evalToBoolean", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2", "MVEL", False, "evalToString", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2", "MVEL", False, "executeAllExpression", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2", "MVEL", False, "executeExpression", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2", "MVEL", False, "executeSetExpression", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2", "MVELRuntime", False, "execute", "", "", "Argument[1]", "mvel", "manual"] diff --git a/java/ql/lib/ext/org.mvel2.templates.model.yml b/java/ql/lib/ext/org.mvel2.templates.model.yml new file mode 100644 index 00000000000..fac30dca38a --- /dev/null +++ b/java/ql/lib/ext/org.mvel2.templates.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.mvel2.templates", "TemplateRuntime", False, "eval", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2.templates", "TemplateRuntime", False, "execute", "", "", "Argument[0]", "mvel", "manual"] diff --git a/java/ql/lib/ext/org.scijava.log.model.yml b/java/ql/lib/ext/org.scijava.log.model.yml new file mode 100644 index 00000000000..561de4980f4 --- /dev/null +++ b/java/ql/lib/ext/org.scijava.log.model.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.scijava.log", "Logger", True, "alwaysLog", "(int,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "debug", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "error", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "error", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "info", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "info", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "log", "(int,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "log", "(int,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "trace", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "warn", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] diff --git a/java/ql/lib/ext/org.slf4j.model.yml b/java/ql/lib/ext/org.slf4j.model.yml new file mode 100644 index 00000000000..f321c13d1e0 --- /dev/null +++ b/java/ql/lib/ext/org.slf4j.model.yml @@ -0,0 +1,55 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.slf4j", "Logger", True, "debug", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] diff --git a/java/ql/lib/ext/org.slf4j.spi.model.yml b/java/ql/lib/ext/org.slf4j.spi.model.yml new file mode 100644 index 00000000000..2c6c44f0908 --- /dev/null +++ b/java/ql/lib/ext/org.slf4j.spi.model.yml @@ -0,0 +1,20 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "(Supplier)", "", "Argument[0]", "logging", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.slf4j.spi", "LoggingEventBuilder", True, "addArgument", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "addArgument", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "addKeyValue", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "addKeyValue", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "addMarker", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "setCause", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.springframework.beans.model.yml b/java/ql/lib/ext/org.springframework.beans.model.yml new file mode 100644 index 00000000000..44f6b24ee06 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.beans.model.yml @@ -0,0 +1,35 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.springframework.beans", "MutablePropertyValues", True, "MutablePropertyValues", "(List)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "MutablePropertyValues", "(Map)", "", "Argument[0].MapKey", "Argument[-1].Element.MapKey", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "MutablePropertyValues", "(Map)", "", "Argument[0].MapValue", "Argument[-1].Element.MapValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "MutablePropertyValues", "(PropertyValues)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "add", "(String,Object)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "add", "(String,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "add", "(String,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValue", "(PropertyValue)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValue", "(PropertyValue)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValue", "(String,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValue", "(String,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValues", "(Map)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValues", "(Map)", "", "Argument[0].MapKey", "Argument[-1].Element.MapKey", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValues", "(Map)", "", "Argument[0].MapValue", "Argument[-1].Element.MapValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValues", "(PropertyValues)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValues", "(PropertyValues)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "get", "", "", "Argument[-1].Element.MapValue", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "getPropertyValue", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "getPropertyValueList", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "getPropertyValues", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "setPropertyValueAt", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.springframework.beans", "PropertyValue", False, "PropertyValue", "(PropertyValue)", "", "Argument[0]", "Argument[-1]", "value", "manual"] + - ["org.springframework.beans", "PropertyValue", False, "PropertyValue", "(PropertyValue,Object)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.beans", "PropertyValue", False, "PropertyValue", "(PropertyValue,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.beans", "PropertyValue", False, "PropertyValue", "(String,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.beans", "PropertyValue", False, "PropertyValue", "(String,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.beans", "PropertyValue", False, "getName", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "PropertyValue", False, "getValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "PropertyValues", True, "getPropertyValue", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "PropertyValues", True, "getPropertyValues", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] diff --git a/java/ql/lib/ext/org.springframework.boot.jdbc.model.yml b/java/ql/lib/ext/org.springframework.boot.jdbc.model.yml new file mode 100644 index 00000000000..79556f4a285 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.boot.jdbc.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.springframework.boot.jdbc", "DataSourceBuilder", False, "url", "(String)", "", "Argument[0]", "jdbc-url", "manual"] diff --git a/java/ql/lib/ext/org.springframework.cache.model.yml b/java/ql/lib/ext/org.springframework.cache.model.yml new file mode 100644 index 00000000000..450997df83c --- /dev/null +++ b/java/ql/lib/ext/org.springframework.cache.model.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.springframework.cache", "Cache", True, "get", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "get", "(Object,Callable)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "get", "(Object,Class)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "getNativeCache", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "getNativeCache", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "put", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "put", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "putIfAbsent", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "putIfAbsent", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "putIfAbsent", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.cache", "Cache$ValueRetrievalException", False, "ValueRetrievalException", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.cache", "Cache$ValueRetrievalException", False, "getKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.springframework.cache", "Cache$ValueWrapper", True, "get", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.springframework.context.model.yml b/java/ql/lib/ext/org.springframework.context.model.yml new file mode 100644 index 00000000000..adb3431c27c --- /dev/null +++ b/java/ql/lib/ext/org.springframework.context.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.springframework.context", "MessageSource", True, "getMessage", "(String,Object[],Locale)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.context", "MessageSource", True, "getMessage", "(String,Object[],String,Locale)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.context", "MessageSource", True, "getMessage", "(String,Object[],String,Locale)", "", "Argument[2]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.springframework.data.repository.model.yml b/java/ql/lib/ext/org.springframework.data.repository.model.yml new file mode 100644 index 00000000000..ff4f0808118 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.data.repository.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.springframework.data.repository", "CrudRepository", True, "save", "", "", "Argument[0]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.springframework.http.model.yml b/java/ql/lib/ext/org.springframework.http.model.yml new file mode 100644 index 00000000000..b8ca57fa10d --- /dev/null +++ b/java/ql/lib/ext/org.springframework.http.model.yml @@ -0,0 +1,93 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(HttpMethod,URI)", "", "Argument[1]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(MultiValueMap,HttpMethod,URI)", "", "Argument[2]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(Object,HttpMethod,URI)", "", "Argument[2]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(Object,HttpMethod,URI,Type)", "", "Argument[2]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(Object,MultiValueMap,HttpMethod,URI)", "", "Argument[3]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(Object,MultiValueMap,HttpMethod,URI,Type)", "", "Argument[3]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "delete", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "get", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "head", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "method", "", "", "Argument[1]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "options", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "patch", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "post", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "put", "", "", "Argument[0]", "open-url", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.springframework.http", "HttpEntity", True, "HttpEntity", "(MultiValueMap)", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpEntity", True, "HttpEntity", "(MultiValueMap)", "", "Argument[0].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpEntity", True, "HttpEntity", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpEntity", True, "HttpEntity", "(Object,MultiValueMap)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpEntity", True, "HttpEntity", "(Object,MultiValueMap)", "", "Argument[1].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpEntity", True, "HttpEntity", "(Object,MultiValueMap)", "", "Argument[1].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpEntity", True, "getBody", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpEntity", True, "getHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "HttpHeaders", "(MultiValueMap)", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "HttpHeaders", "(MultiValueMap)", "", "Argument[0].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "add", "(String,String)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "addAll", "(MultiValueMap)", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "addAll", "(MultiValueMap)", "", "Argument[0].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "addAll", "(String,List)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "addAll", "(String,List)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "encodeBasicAuth", "(String,String,Charset)", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "formatHeaders", "(MultiValueMap)", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "formatHeaders", "(MultiValueMap)", "", "Argument[0].MapValue.Element", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "get", "(Object)", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getAccessControlAllowHeaders", "()", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getAccessControlAllowOrigin", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getAccessControlExposeHeaders", "()", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getAccessControlRequestHeaders", "()", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getCacheControl", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getConnection", "()", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getETag", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getETagValuesAsList", "(String)", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getFieldValues", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getFirst", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getHost", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getIfMatch", "()", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getIfNoneMatch", "()", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getLocation", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getOrEmpty", "(Object)", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getOrigin", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getPragma", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getUpgrade", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getValuesAsList", "(String)", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getVary", "()", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "set", "(String,String)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "RequestEntity", True, "getUrl", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(MultiValueMap,HttpStatus)", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(MultiValueMap,HttpStatus)", "", "Argument[0].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,HttpStatus)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatus)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatus)", "", "Argument[1].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatus)", "", "Argument[1].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,int)", "", "Argument[1].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,int)", "", "Argument[1].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "created", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "of", "(Optional)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ok", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity$BodyBuilder", True, "body", "(Object)", "", "Argument[-1..0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity$BodyBuilder", True, "contentLength", "(long)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$BodyBuilder", True, "contentType", "(MediaType)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "allow", "(HttpMethod[])", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "build", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "eTag", "(String)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "eTag", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "header", "(String,String[])", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "header", "(String,String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "header", "(String,String[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "headers", "(Consumer)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "headers", "(HttpHeaders)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "headers", "(HttpHeaders)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "lastModified", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "location", "(URI)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "location", "(URI)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "varyBy", "(String[])", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.springframework.jdbc.core.model.yml b/java/ql/lib/ext/org.springframework.jdbc.core.model.yml new file mode 100644 index 00000000000..36bf98f9ebc --- /dev/null +++ b/java/ql/lib/ext/org.springframework.jdbc.core.model.yml @@ -0,0 +1,15 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "batchUpdate", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "batchUpdate", "(String[])", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "execute", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "query", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForList", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForMap", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForObject", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForRowSet", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForStream", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "update", "", "", "Argument[0]", "sql", "manual"] diff --git a/java/ql/lib/ext/org.springframework.jdbc.datasource.model.yml b/java/ql/lib/ext/org.springframework.jdbc.datasource.model.yml new file mode 100644 index 00000000000..54d607485f9 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.jdbc.datasource.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.springframework.jdbc.datasource", "AbstractDriverBasedDataSource", False, "setUrl", "(String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.springframework.jdbc.datasource", "DriverManagerDataSource", False, "DriverManagerDataSource", "(String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.springframework.jdbc.datasource", "DriverManagerDataSource", False, "DriverManagerDataSource", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.springframework.jdbc.datasource", "DriverManagerDataSource", False, "DriverManagerDataSource", "(String,String,String)", "", "Argument[0]", "jdbc-url", "manual"] diff --git a/java/ql/lib/ext/org.springframework.jdbc.object.model.yml b/java/ql/lib/ext/org.springframework.jdbc.object.model.yml new file mode 100644 index 00000000000..fc15867d36d --- /dev/null +++ b/java/ql/lib/ext/org.springframework.jdbc.object.model.yml @@ -0,0 +1,14 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.springframework.jdbc.object", "BatchSqlUpdate", False, "BatchSqlUpdate", "", "", "Argument[1]", "sql", "manual"] + - ["org.springframework.jdbc.object", "MappingSqlQuery", False, "BatchSqlUpdate", "", "", "Argument[1]", "sql", "manual"] + - ["org.springframework.jdbc.object", "MappingSqlQueryWithParameters", False, "BatchSqlUpdate", "", "", "Argument[1]", "sql", "manual"] + - ["org.springframework.jdbc.object", "RdbmsOperation", True, "setSql", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.object", "SqlCall", False, "SqlCall", "", "", "Argument[1]", "sql", "manual"] + - ["org.springframework.jdbc.object", "SqlFunction", False, "SqlFunction", "", "", "Argument[1]", "sql", "manual"] + - ["org.springframework.jdbc.object", "SqlQuery", False, "SqlQuery", "", "", "Argument[1]", "sql", "manual"] + - ["org.springframework.jdbc.object", "SqlUpdate", False, "SqlUpdate", "", "", "Argument[1]", "sql", "manual"] + - ["org.springframework.jdbc.object", "UpdatableSqlQuery", False, "UpdatableSqlQuery", "", "", "Argument[1]", "sql", "manual"] diff --git a/java/ql/lib/ext/org.springframework.jndi.model.yml b/java/ql/lib/ext/org.springframework.jndi.model.yml new file mode 100644 index 00000000000..0df0234a379 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.jndi.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.springframework.jndi", "JndiTemplate", False, "lookup", "", "", "Argument[0]", "jndi-injection", "manual"] diff --git a/java/ql/lib/ext/org.springframework.ldap.core.model.yml b/java/ql/lib/ext/org.springframework.ldap.core.model.yml new file mode 100644 index 00000000000..bebe96fc14a --- /dev/null +++ b/java/ql/lib/ext/org.springframework.ldap.core.model.yml @@ -0,0 +1,38 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.springframework.ldap.core", "LdapOperations", True, "findByDn", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "list", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "listBindings", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "lookup", "(Name)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "lookup", "(Name,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "lookup", "(Name,String[],ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "lookup", "(String)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "lookup", "(String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "lookup", "(String,String[],ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "lookupContext", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "rename", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "search", "(Name,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "search", "(Name,String,int,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "search", "(Name,String,int,String[],ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "search", "(String,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "search", "(String,String,int,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "search", "(String,String,int,String[],ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "searchForObject", "(Name,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "searchForObject", "(String,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(LdapQuery,String)", "", "Argument[0]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(Name,String,String)", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(Name,String,String,AuthenticatedLdapEntryContextCallback)", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(Name,String,String,AuthenticatedLdapEntryContextCallback,AuthenticationErrorCallback)", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(Name,String,String,AuthenticationErrorCallback)", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(String,String,String)", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(String,String,String,AuthenticatedLdapEntryContextCallback)", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(String,String,String,AuthenticatedLdapEntryContextCallback,AuthenticationErrorCallback)", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(String,String,String,AuthenticationErrorCallback)", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "find", "", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "findOne", "", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "search", "", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "searchForContext", "", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "searchForObject", "", "", "Argument[0..1]", "ldap", "manual"] diff --git a/java/ql/lib/ext/org.springframework.ldap.model.yml b/java/ql/lib/ext/org.springframework.ldap.model.yml new file mode 100644 index 00000000000..3ce0ad5d6b5 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.ldap.model.yml @@ -0,0 +1,19 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.springframework.ldap", "LdapOperations", True, "findByDn", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "list", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "listBindings", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "lookup", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "lookupContext", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "rename", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "search", "(Name,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "search", "(Name,String,int,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "search", "(Name,String,int,String[],ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "search", "(String,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "search", "(String,String,int,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "search", "(String,String,int,String[],ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "searchForObject", "(Name,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "searchForObject", "(String,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] diff --git a/java/ql/lib/ext/org.springframework.security.web.savedrequest.model.yml b/java/ql/lib/ext/org.springframework.security.web.savedrequest.model.yml new file mode 100644 index 00000000000..0dd6df9116e --- /dev/null +++ b/java/ql/lib/ext/org.springframework.security.web.savedrequest.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["org.springframework.security.web.savedrequest", "SavedRequest", True, "getCookies", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.security.web.savedrequest", "SavedRequest", True, "getHeaderNames", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.security.web.savedrequest", "SavedRequest", True, "getHeaderValues", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.security.web.savedrequest", "SavedRequest", True, "getParameterMap", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.security.web.savedrequest", "SavedRequest", True, "getParameterValues", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.security.web.savedrequest", "SavedRequest", True, "getRedirectUrl", "", "", "ReturnValue", "remote", "manual"] diff --git a/java/ql/lib/ext/org.springframework.ui.model.yml b/java/ql/lib/ext/org.springframework.ui.model.yml new file mode 100644 index 00000000000..0ff23939bed --- /dev/null +++ b/java/ql/lib/ext/org.springframework.ui.model.yml @@ -0,0 +1,37 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.springframework.ui", "ConcurrentModel", False, "ConcurrentModel", "(Object)", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "ConcurrentModel", False, "ConcurrentModel", "(String,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.ui", "ConcurrentModel", False, "ConcurrentModel", "(String,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "addAllAttributes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "addAllAttributes", "(Collection)", "", "Argument[0].Element", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "addAllAttributes", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.ui", "Model", True, "addAllAttributes", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "addAttribute", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "addAttribute", "(Object)", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "addAttribute", "(String,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.ui", "Model", True, "addAttribute", "(String,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "asMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.ui", "Model", True, "asMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "getAttribute", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "mergeAttributes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "mergeAttributes", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.ui", "Model", True, "mergeAttributes", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "ModelMap", "(Object)", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "ModelMap", "(String,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "ModelMap", "(String,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "addAllAttributes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "addAllAttributes", "(Collection)", "", "Argument[0].Element", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "addAllAttributes", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "addAllAttributes", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "addAttribute", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "addAttribute", "(Object)", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "addAttribute", "(String,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "addAttribute", "(String,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "getAttribute", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "mergeAttributes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "mergeAttributes", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "mergeAttributes", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.springframework.util.model.yml b/java/ql/lib/ext/org.springframework.util.model.yml new file mode 100644 index 00000000000..62eb0af5bd1 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.util.model.yml @@ -0,0 +1,144 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.springframework.util", "AntPathMatcher", False, "combine", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "AntPathMatcher", False, "doMatch", "", "", "Argument[1]", "Argument[3].MapValue", "taint", "manual"] + - ["org.springframework.util", "AntPathMatcher", False, "extractPathWithinPattern", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "AntPathMatcher", False, "extractUriTemplateVariables", "", "", "Argument[1]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.util", "AntPathMatcher", False, "tokenizePath", "", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.util", "AntPathMatcher", False, "tokenizePattern", "", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.util", "AutoPopulatingList", False, "AutoPopulatingList", "(java.util.List,java.lang.Class)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.springframework.util", "AutoPopulatingList", False, "AutoPopulatingList", "(java.util.List,org.springframework.util.AutoPopulatingList.ElementFactory)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.springframework.util", "Base64Utils", False, "decode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "Base64Utils", False, "decodeFromString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "Base64Utils", False, "decodeFromUrlSafeString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "Base64Utils", False, "decodeUrlSafe", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "Base64Utils", False, "encode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "Base64Utils", False, "encodeToString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "Base64Utils", False, "encodeToUrlSafeString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "Base64Utils", False, "encodeUrlSafe", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "arrayToList", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "findFirstMatch", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "findValueOfType", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "firstElement", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "lastElement", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "mergeArrayIntoCollection", "", "", "Argument[0].ArrayElement", "Argument[1].Element", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "mergePropertiesIntoMap", "", "", "Argument[0].MapKey", "Argument[1].MapKey", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "mergePropertiesIntoMap", "", "", "Argument[0].MapValue", "Argument[1].MapValue", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "toArray", "", "", "Argument[0].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "toIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "toMultiValueMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "toMultiValueMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "unmodifiableMultiValueMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "unmodifiableMultiValueMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.util", "CompositeIterator", False, "add", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.springframework.util", "ConcurrentReferenceHashMap", False, "getReference", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.util", "ConcurrentReferenceHashMap", False, "getReference", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.util", "ConcurrentReferenceHashMap", False, "getSegment", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.util", "ConcurrentReferenceHashMap", False, "getSegment", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.util", "FastByteArrayOutputStream", False, "getInputStream", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "FastByteArrayOutputStream", False, "toByteArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "FastByteArrayOutputStream", False, "write", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.util", "FastByteArrayOutputStream", False, "writeTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.springframework.util", "FileCopyUtils", False, "copy", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "FileCopyUtils", False, "copyToByteArray", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "FileCopyUtils", False, "copyToString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "FileSystemUtils", False, "copyRecursively", "(java.io.File,java.io.File)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "LinkedMultiValueMap", False, "LinkedMultiValueMap", "(java.util.Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.util", "LinkedMultiValueMap", False, "LinkedMultiValueMap", "(java.util.Map)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.springframework.util", "LinkedMultiValueMap", False, "deepCopy", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.util", "LinkedMultiValueMap", False, "deepCopy", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "add", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "add", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "addAll", "(java.lang.Object,java.util.List)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "addAll", "(java.lang.Object,java.util.List)", "", "Argument[1].Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "addAll", "(org.springframework.util.MultiValueMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "addAll", "(org.springframework.util.MultiValueMap)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "addIfAbsent", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "addIfAbsent", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "getFirst", "", "", "Argument[-1].MapValue.Element", "ReturnValue", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "set", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "set", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "setAll", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "setAll", "", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "toSingleValueMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "toSingleValueMap", "", "", "Argument[-1].MapValue.Element", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.util", "MultiValueMapAdapter", False, "MultiValueMapAdapter", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.util", "MultiValueMapAdapter", False, "MultiValueMapAdapter", "", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.springframework.util", "ObjectUtils", False, "addObjectToArray", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "ObjectUtils", False, "addObjectToArray", "", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "ObjectUtils", False, "toObjectArray", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "ObjectUtils", False, "unwrapOptional", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.springframework.util", "PropertiesPersister", True, "load", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["org.springframework.util", "PropertiesPersister", True, "loadFromXml", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["org.springframework.util", "PropertiesPersister", True, "store", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "PropertiesPersister", True, "store", "", "", "Argument[2]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "PropertiesPersister", True, "storeToXml", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "PropertiesPersister", True, "storeToXml", "", "", "Argument[2]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "PropertyPlaceholderHelper", False, "PropertyPlaceholderHelper", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.util", "PropertyPlaceholderHelper", False, "parseStringValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "PropertyPlaceholderHelper", False, "replacePlaceholders", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "PropertyPlaceholderHelper", False, "replacePlaceholders", "(java.lang.String,java.util.Properties)", "", "Argument[1].MapValue", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "ResourceUtils", False, "extractArchiveURL", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "ResourceUtils", False, "extractJarFileURL", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "ResourceUtils", False, "getFile", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "ResourceUtils", False, "getURL", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "ResourceUtils", False, "toURI", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "RouteMatcher", True, "combine", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "RouteMatcher", True, "matchAndExtract", "", "", "Argument[0]", "ReturnValue.MapKey", "taint", "manual"] + - ["org.springframework.util", "RouteMatcher", True, "matchAndExtract", "", "", "Argument[1]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.util", "RouteMatcher", True, "parseRoute", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "SerializationUtils", False, "deserialize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "SerializationUtils", False, "serialize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StreamUtils", False, "copy", "(byte[],java.io.OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "StreamUtils", False, "copy", "(java.io.InputStream,java.io.OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "StreamUtils", False, "copy", "(java.lang.String,java.nio.charset.Charset,java.io.OutputStream)", "", "Argument[0]", "Argument[2]", "taint", "manual"] + - ["org.springframework.util", "StreamUtils", False, "copyRange", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "StreamUtils", False, "copyToByteArray", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StreamUtils", False, "copyToString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "addStringToArray", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "StringUtils", False, "addStringToArray", "", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "StringUtils", False, "applyRelativePath", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "arrayToCommaDelimitedString", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "arrayToDelimitedString", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "arrayToDelimitedString", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "capitalize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "cleanPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "collectionToCommaDelimitedString", "", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "collectionToDelimitedString", "", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "collectionToDelimitedString", "", "", "Argument[1..3]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "commaDelimitedListToSet", "", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "commaDelimitedListToStringArray", "", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "concatenateStringArrays", "", "", "Argument[0..1].ArrayElement", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "delete", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "deleteAny", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "delimitedListToStringArray", "", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "getFilename", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "getFilenameExtension", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "mergeStringArrays", "", "", "Argument[0..1].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "StringUtils", False, "quote", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "quoteIfString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "removeDuplicateStrings", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "StringUtils", False, "replace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "replace", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "sortStringArray", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "StringUtils", False, "split", "", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "splitArrayElementsIntoProperties", "", "", "Argument[0].ArrayElement", "ReturnValue.MapKey", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "splitArrayElementsIntoProperties", "", "", "Argument[0].ArrayElement", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "stripFilenameExtension", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "toStringArray", "", "", "Argument[0].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "StringUtils", False, "tokenizeToStringArray", "", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "trimAllWhitespace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "trimArrayElements", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "trimLeadingCharacter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "trimLeadingWhitespace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "trimTrailingCharacter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "trimTrailingWhitespace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "trimWhitespace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "uncapitalize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "unqualify", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "uriDecode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringValueResolver", False, "resolveStringValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "SystemPropertyUtils", False, "resolvePlaceholders", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.springframework.validation.model.yml b/java/ql/lib/ext/org.springframework.validation.model.yml new file mode 100644 index 00000000000..46b3c3d016f --- /dev/null +++ b/java/ql/lib/ext/org.springframework.validation.model.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.springframework.validation", "Errors", True, "addAllErrors", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "getAllErrors", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "getFieldError", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "getFieldErrors", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "getGlobalError", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "getGlobalErrors", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "reject", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "reject", "", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "reject", "", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "rejectValue", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "rejectValue", "", "", "Argument[3]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "rejectValue", "(java.lang.String,java.lang.String,java.lang.Object[],java.lang.String)", "", "Argument[2].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "rejectValue", "(java.lang.String,java.lang.String,java.lang.String)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/org.springframework.web.client.model.yml b/java/ql/lib/ext/org.springframework.web.client.model.yml new file mode 100644 index 00000000000..92f9a558245 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.web.client.model.yml @@ -0,0 +1,25 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["org.springframework.web.client", "RestTemplate", False, "exchange", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "getForEntity", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "postForEntity", "", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.springframework.web.client", "RestTemplate", False, "delete", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "doExecute", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "exchange", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "execute", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "getForEntity", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "getForObject", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "headForHeaders", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "optionsForAllow", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "patchForObject", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "postForEntity", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "postForLocation", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "postForObject", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "put", "", "", "Argument[0]", "open-url", "manual"] diff --git a/java/ql/lib/ext/org.springframework.web.context.request.model.yml b/java/ql/lib/ext/org.springframework.web.context.request.model.yml new file mode 100644 index 00000000000..56e276e4cc0 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.web.context.request.model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["org.springframework.web.context.request", "WebRequest", False, "getDescription", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.context.request", "WebRequest", False, "getHeader", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.context.request", "WebRequest", False, "getHeaderNames", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.context.request", "WebRequest", False, "getHeaderValues", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.context.request", "WebRequest", False, "getParameter", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.context.request", "WebRequest", False, "getParameterMap", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.context.request", "WebRequest", False, "getParameterNames", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.context.request", "WebRequest", False, "getParameterValues", "", "", "ReturnValue", "remote", "manual"] diff --git a/java/ql/lib/ext/org.springframework.web.multipart.model.yml b/java/ql/lib/ext/org.springframework.web.multipart.model.yml new file mode 100644 index 00000000000..d57d44f8a48 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.web.multipart.model.yml @@ -0,0 +1,34 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["org.springframework.web.multipart", "MultipartFile", True, "getBytes", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getContentType", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getInputStream", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getName", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getOriginalFilename", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getResource", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getFile", "(String)", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getFileMap", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getFileNames", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getFiles", "(String)", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getMultiFileMap", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getMultipartContentType", "(String)", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.springframework.web.multipart", "MultipartFile", True, "getBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getInputStream", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getOriginalFilename", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getResource", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartHttpServletRequest", True, "getMultipartHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartHttpServletRequest", True, "getRequestHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getFile", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getFileMap", "", "", "Argument[-1]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getFileNames", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getFiles", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getMultiFileMap", "", "", "Argument[-1]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartResolver", True, "resolveMultipart", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.springframework.web.reactive.function.client.model.yml b/java/ql/lib/ext/org.springframework.web.reactive.function.client.model.yml new file mode 100644 index 00000000000..e3ffd17cd7e --- /dev/null +++ b/java/ql/lib/ext/org.springframework.web.reactive.function.client.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.springframework.web.reactive.function.client", "WebClient", False, "create", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.reactive.function.client", "WebClient$Builder", False, "baseUrl", "", "", "Argument[0]", "open-url", "manual"] diff --git a/java/ql/lib/ext/org.springframework.web.util.model.yml b/java/ql/lib/ext/org.springframework.web.util.model.yml new file mode 100644 index 00000000000..c3f70b66cf8 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.web.util.model.yml @@ -0,0 +1,168 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.springframework.web.util", "AbstractUriTemplateHandler", True, "getBaseUrl", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "AbstractUriTemplateHandler", True, "setBaseUrl", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "AbstractUriTemplateHandler", True, "setDefaultUriVariables", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "ContentCachingRequestWrapper", False, "ContentCachingRequestWrapper", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "ContentCachingRequestWrapper", False, "getContentAsByteArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "ContentCachingResponseWrapper", False, "ContentCachingResponseWrapper", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "ContentCachingResponseWrapper", False, "getContentAsByteArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "ContentCachingResponseWrapper", False, "getContentInputStream", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "DefaultUriBuilderFactory", False, "DefaultUriBuilderFactory", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "DefaultUriBuilderFactory", False, "builder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "DefaultUriBuilderFactory", False, "getDefaultUriVariables", "", "", "Argument[-1]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.util", "DefaultUriBuilderFactory", False, "setDefaultUriVariables", "", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "DefaultUriBuilderFactory", False, "uriString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "HtmlUtils", False, "htmlEscape", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "HtmlUtils", False, "htmlEscapeDecimal", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "HtmlUtils", False, "htmlEscapeHex", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "HtmlUtils", False, "htmlUnescape", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "ServletContextPropertyUtils", False, "resolvePlaceholders", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "ServletRequestPathUtils", False, "getCachedPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "ServletRequestPathUtils", False, "getCachedPathValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "ServletRequestPathUtils", False, "getParsedRequestPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "ServletRequestPathUtils", False, "parseAndCache", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "ServletRequestPathUtils", False, "setParsedRequestPath", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "build", "(Map)", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "build", "(Map)", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "build", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "fragment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "fragment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "host", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "host", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "path", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "path", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "pathSegment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "pathSegment", "", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "port", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "port", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "query", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "query", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParam", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParam", "(String,Collection)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParam", "(String,Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParamIfPresent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParamIfPresent", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParamIfPresent", "", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParams", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParams", "", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParams", "", "", "Argument[0].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replacePath", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replacePath", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQuery", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQuery", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQueryParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQueryParam", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQueryParam", "(String,Collection)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQueryParam", "(String,Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQueryParams", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQueryParams", "", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQueryParams", "", "", "Argument[0].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "scheme", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "scheme", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "userInfo", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "userInfo", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilderFactory", True, "builder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilderFactory", True, "uriString", "", "", "Argument[-1..0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "UriComponents", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "copyToUriComponentsBuilder", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "encode", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "expand", "(Map)", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "expand", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "expand", "(UriTemplateVariables)", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getFragment", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getHost", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getPathSegments", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getQuery", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getQueryParams", "", "", "Argument[-1]", "ReturnValue.MapKey", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getQueryParams", "", "", "Argument[-1]", "ReturnValue.MapValue.Element", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getScheme", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getSchemeSpecificPart", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getUserInfo", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "normalize", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "toUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "toUriString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents$UriTemplateVariables", True, "getValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "buildAndExpand", "(Map)", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "buildAndExpand", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "cloneBuilder", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "encode", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "fromHttpRequest", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "fromHttpUrl", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "fromOriginHeader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "fromPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "fromUri", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "fromUriString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "parseForwardedFor", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "schemeSpecificPart", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "schemeSpecificPart", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "toUriString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "uri", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "uri", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "uriComponents", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "uriComponents", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "uriVariables", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "uriVariables", "", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriTemplate", False, "expand", "(Map)", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriTemplate", False, "expand", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriTemplate", False, "getVariableNames", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.web.util", "UriTemplate", False, "match", "", "", "Argument[0]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.util", "UriTemplate", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriTemplateHandler", True, "expand", "", "", "Argument[-1..0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriTemplateHandler", True, "expand", "(String,Map)", "", "Argument[1].MapValue", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriTemplateHandler", True, "expand", "(String,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "decode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeAuthority", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeFragment", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeHost", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodePath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodePathSegment", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodePort", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeQueryParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeQueryParams", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeQueryParams", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeScheme", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeUriVariables", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeUriVariables", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeUriVariables", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeUserInfo", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "extractFileExtension", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "decodeMatrixVariables", "", "", "Argument[1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "decodeMatrixVariables", "", "", "Argument[1].MapValue", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "decodePathVariables", "", "", "Argument[1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "decodePathVariables", "", "", "Argument[1].MapValue", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "decodeRequestString", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getContextPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getOriginatingContextPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getOriginatingQueryString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getOriginatingRequestUri", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getPathWithinApplication", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getPathWithinServletMapping", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getRequestUri", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getResolvedLookupPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getServletPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "removeSemicolonContent", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "resolveAndCacheLookupPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "findParameterValue", "(Map,String)", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "findParameterValue", "(ServletRequest,String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "getCookie", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "getNativeRequest", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "getNativeResponse", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "getParametersStartingWith", "", "", "Argument[0]", "ReturnValue.MapKey", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "getParametersStartingWith", "", "", "Argument[0]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "getRealPath", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "getRequiredSessionAttribute", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "getSessionAttribute", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "parseMatrixVariables", "", "", "Argument[0]", "ReturnValue.MapKey", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "parseMatrixVariables", "", "", "Argument[0]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "setSessionAttribute", "", "", "Argument[2]", "Argument[0]", "taint", "manual"] diff --git a/java/ql/lib/ext/org.thymeleaf.model.yml b/java/ql/lib/ext/org.thymeleaf.model.yml new file mode 100644 index 00000000000..a7413343ce4 --- /dev/null +++ b/java/ql/lib/ext/org.thymeleaf.model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.thymeleaf", "ITemplateEngine", True, "process", "", "", "Argument[0]", "ssti", "manual"] + - ["org.thymeleaf", "ITemplateEngine", True, "processThrottled", "", "", "Argument[0]", "ssti", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.thymeleaf", "TemplateSpec", False, "TemplateSpec", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.thymeleaf", "TemplateSpec", False, "getTemplate", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.xml.sax.model.yml b/java/ql/lib/ext/org.xml.sax.model.yml new file mode 100644 index 00000000000..ecd2ba3c544 --- /dev/null +++ b/java/ql/lib/ext/org.xml.sax.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.xml.sax", "InputSource", False, "InputSource", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/org.xmlpull.v1.model.yml b/java/ql/lib/ext/org.xmlpull.v1.model.yml new file mode 100644 index 00000000000..01af9ba332b --- /dev/null +++ b/java/ql/lib/ext/org.xmlpull.v1.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["org.xmlpull.v1", "XmlPullParser", False, "getName", "()", "", "ReturnValue", "remote", "manual"] + - ["org.xmlpull.v1", "XmlPullParser", False, "getNamespace", "()", "", "ReturnValue", "remote", "manual"] + - ["org.xmlpull.v1", "XmlPullParser", False, "getText", "()", "", "ReturnValue", "remote", "manual"] diff --git a/java/ql/lib/ext/play.mvc.model.yml b/java/ql/lib/ext/play.mvc.model.yml new file mode 100644 index 00000000000..98e665062a3 --- /dev/null +++ b/java/ql/lib/ext/play.mvc.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["play.mvc", "Http$RequestHeader", False, "getHeader", "", "", "ReturnValue", "remote", "manual"] + - ["play.mvc", "Http$RequestHeader", False, "getQueryString", "", "", "ReturnValue", "remote", "manual"] + - ["play.mvc", "Http$RequestHeader", False, "header", "", "", "ReturnValue", "remote", "manual"] + - ["play.mvc", "Http$RequestHeader", False, "queryString", "", "", "ReturnValue", "remote", "manual"] diff --git a/java/ql/lib/ext/ratpack.core.form.model.yml b/java/ql/lib/ext/ratpack.core.form.model.yml new file mode 100644 index 00000000000..20d34162ac0 --- /dev/null +++ b/java/ql/lib/ext/ratpack.core.form.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["ratpack.core.form", "Form", True, "file", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.form", "Form", True, "files", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.form", "UploadedFile", True, "getFileName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/ratpack.core.handling.model.yml b/java/ql/lib/ext/ratpack.core.handling.model.yml new file mode 100644 index 00000000000..edb02aaeced --- /dev/null +++ b/java/ql/lib/ext/ratpack.core.handling.model.yml @@ -0,0 +1,19 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["ratpack.core.handling", "Context", True, "parse", "(com.google.common.reflect.TypeToken)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.handling", "Context", True, "parse", "(com.google.common.reflect.TypeToken,java.lang.Object)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.handling", "Context", True, "parse", "(java.lang.Class)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.handling", "Context", True, "parse", "(java.lang.Class,java.lang.Object)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.handling", "Context", True, "parse", "(ratpack.core.parse.Parse)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.handling", "Context", True, "parse", "(ratpack.parse.Parse)", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["ratpack.core.handling", "Context", True, "parse", "(ratpack.core.http.TypedData,ratpack.core.parse.Parse)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.handling", "Context", True, "parse", "(ratpack.core.http.TypedData,ratpack.core.parse.Parse)", "", "Argument[0]", "ReturnValue.MapKey", "taint", "manual"] + - ["ratpack.core.handling", "Context", True, "parse", "(ratpack.core.http.TypedData,ratpack.core.parse.Parse)", "", "Argument[0]", "ReturnValue.MapValue", "taint", "manual"] + - ["ratpack.core.handling", "Context", True, "parse", "(ratpack.http.TypedData,ratpack.parse.Parse)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/ratpack.core.http.model.yml b/java/ql/lib/ext/ratpack.core.http.model.yml new file mode 100644 index 00000000000..094c90be1bd --- /dev/null +++ b/java/ql/lib/ext/ratpack.core.http.model.yml @@ -0,0 +1,29 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["ratpack.core.http", "Request", True, "getBody", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "getContentLength", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "getCookies", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "getHeaders", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "getPath", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "getQuery", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "getQueryParams", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "getRawUri", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "getUri", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "oneCookie", "", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["ratpack.core.http", "Headers", True, "asMultiValueMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "Headers", True, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "Headers", True, "getAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "Headers", True, "getNames", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "TypedData", True, "getBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "TypedData", True, "getBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "TypedData", True, "getContentType", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "TypedData", True, "getInputStream", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "TypedData", True, "getText", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "TypedData", True, "writeTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/java/ql/lib/ext/ratpack.exec.model.yml b/java/ql/lib/ext/ratpack.exec.model.yml new file mode 100644 index 00000000000..0303f5cfd26 --- /dev/null +++ b/java/ql/lib/ext/ratpack.exec.model.yml @@ -0,0 +1,53 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["ratpack.exec", "Promise", True, "apply", "", "", "Argument[-1].Element", "Argument[0].Parameter[0].Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "apply", "", "", "Argument[0].ReturnValue.Element", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "blockingMap", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "blockingMap", "", "", "Argument[0].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "blockingOp", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "cacheIf", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatLeft", "", "", "Argument[-1].Element", "ReturnValue.Element.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatLeft", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatLeft", "(Function)", "", "Argument[0].ReturnValue.Element", "ReturnValue.Element.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatMap", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatMap", "", "", "Argument[0].ReturnValue.Element", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatMapError", "", "", "Argument[1].ReturnValue.Element", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatOp", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatRight", "", "", "Argument[-1].Element", "ReturnValue.Element.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatRight", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatRight", "(Function)", "", "Argument[0].ReturnValue.Element", "ReturnValue.Element.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatten", "", "", "Argument[0].ReturnValue.Element", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "left", "", "", "Argument[-1].Element", "ReturnValue.Element.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "left", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "left", "(Function)", "", "Argument[0].ReturnValue", "ReturnValue.Element.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "left", "(Promise)", "", "Argument[0].Element", "ReturnValue.Element.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "map", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "map", "", "", "Argument[0].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "mapError", "", "", "Argument[1].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "mapIf", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "mapIf", "", "", "Argument[-1].Element", "Argument[1].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "mapIf", "", "", "Argument[-1].Element", "Argument[2].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "mapIf", "", "", "Argument[1].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "mapIf", "", "", "Argument[2].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "next", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "nextOp", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "nextOpIf", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "nextOpIf", "", "", "Argument[-1].Element", "Argument[1].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "replace", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "right", "", "", "Argument[-1].Element", "ReturnValue.Element.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "right", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "right", "(Function)", "", "Argument[0].ReturnValue", "ReturnValue.Element.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "right", "(Promise)", "", "Argument[0].Element", "ReturnValue.Element.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "route", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["ratpack.exec", "Promise", True, "route", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "route", "", "", "Argument[-1].Element", "Argument[1].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "sync", "", "", "Argument[0].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "then", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "value", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "wiretap", "", "", "Argument[-1].Element", "Argument[0].Parameter[0].Element", "value", "manual"] + - ["ratpack.exec", "Result", True, "getValue", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["ratpack.exec", "Result", True, "getValueOrThrow", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["ratpack.exec", "Result", True, "success", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/ratpack.form.model.yml b/java/ql/lib/ext/ratpack.form.model.yml new file mode 100644 index 00000000000..c4677cecd8d --- /dev/null +++ b/java/ql/lib/ext/ratpack.form.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["ratpack.form", "Form", True, "file", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.form", "Form", True, "files", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.form", "UploadedFile", True, "getFileName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/ratpack.func.model.yml b/java/ql/lib/ext/ratpack.func.model.yml new file mode 100644 index 00000000000..e850a8cbfe1 --- /dev/null +++ b/java/ql/lib/ext/ratpack.func.model.yml @@ -0,0 +1,40 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["ratpack.func", "MultiValueMap", True, "asMultimap", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["ratpack.func", "MultiValueMap", True, "asMultimap", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["ratpack.func", "MultiValueMap", True, "getAll", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["ratpack.func", "MultiValueMap", True, "getAll", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue.Element", "value", "manual"] + - ["ratpack.func", "MultiValueMap", True, "getAll", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["ratpack.func", "Pair", True, "getLeft", "", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue", "value", "manual"] + - ["ratpack.func", "Pair", True, "getRight", "", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue", "value", "manual"] + - ["ratpack.func", "Pair", True, "left", "()", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue", "value", "manual"] + - ["ratpack.func", "Pair", True, "left", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "left", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "map", "", "", "Argument[-1]", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.func", "Pair", True, "map", "", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] + - ["ratpack.func", "Pair", True, "mapLeft", "", "", "Argument[-1].Field[ratpack.func.Pair.left]", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.func", "Pair", True, "mapLeft", "", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "mapLeft", "", "", "Argument[0].ReturnValue", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "mapRight", "", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "mapRight", "", "", "Argument[-1].Field[ratpack.func.Pair.right]", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.func", "Pair", True, "mapRight", "", "", "Argument[0].ReturnValue", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "nestLeft", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left].Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "nestLeft", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "nestLeft", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left].Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "nestRight", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "nestRight", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right].Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "nestRight", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.right].Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "of", "", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "of", "", "", "Argument[1]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "pair", "", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "pair", "", "", "Argument[1]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "pushLeft", "(Object)", "", "Argument[-1]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "pushLeft", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "pushRight", "(Object)", "", "Argument[-1]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "pushRight", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "right", "()", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue", "value", "manual"] + - ["ratpack.func", "Pair", True, "right", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "right", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] diff --git a/java/ql/lib/ext/ratpack.handling.model.yml b/java/ql/lib/ext/ratpack.handling.model.yml new file mode 100644 index 00000000000..3523d1cf937 --- /dev/null +++ b/java/ql/lib/ext/ratpack.handling.model.yml @@ -0,0 +1,19 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["ratpack.handling", "Context", True, "parse", "(com.google.common.reflect.TypeToken)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.handling", "Context", True, "parse", "(com.google.common.reflect.TypeToken,java.lang.Object)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.handling", "Context", True, "parse", "(java.lang.Class)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.handling", "Context", True, "parse", "(java.lang.Class,java.lang.Object)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.handling", "Context", True, "parse", "(ratpack.core.parse.Parse)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.handling", "Context", True, "parse", "(ratpack.parse.Parse)", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["ratpack.handling", "Context", True, "parse", "(ratpack.core.http.TypedData,ratpack.core.parse.Parse)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["ratpack.handling", "Context", True, "parse", "(ratpack.core.http.TypedData,ratpack.core.parse.Parse)", "", "Argument[0]", "ReturnValue.MapKey", "taint", "manual"] + - ["ratpack.handling", "Context", True, "parse", "(ratpack.core.http.TypedData,ratpack.core.parse.Parse)", "", "Argument[0]", "ReturnValue.MapValue", "taint", "manual"] + - ["ratpack.handling", "Context", True, "parse", "(ratpack.http.TypedData,ratpack.parse.Parse)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/ratpack.http.model.yml b/java/ql/lib/ext/ratpack.http.model.yml new file mode 100644 index 00000000000..fc96663138e --- /dev/null +++ b/java/ql/lib/ext/ratpack.http.model.yml @@ -0,0 +1,29 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: + - ["ratpack.http", "Request", True, "getBody", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "getContentLength", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "getCookies", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "getHeaders", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "getPath", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "getQuery", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "getQueryParams", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "getRawUri", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "getUri", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "oneCookie", "", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["ratpack.http", "Headers", True, "asMultiValueMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "Headers", True, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "Headers", True, "getAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "Headers", True, "getNames", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "TypedData", True, "getBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "TypedData", True, "getBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "TypedData", True, "getContentType", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "TypedData", True, "getInputStream", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "TypedData", True, "getText", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "TypedData", True, "writeTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/java/ql/lib/ext/ratpack.util.model.yml b/java/ql/lib/ext/ratpack.util.model.yml new file mode 100644 index 00000000000..b594e03aecd --- /dev/null +++ b/java/ql/lib/ext/ratpack.util.model.yml @@ -0,0 +1,40 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["ratpack.util", "MultiValueMap", True, "asMultimap", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["ratpack.util", "MultiValueMap", True, "asMultimap", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["ratpack.util", "MultiValueMap", True, "getAll", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["ratpack.util", "MultiValueMap", True, "getAll", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue.Element", "value", "manual"] + - ["ratpack.util", "MultiValueMap", True, "getAll", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["ratpack.util", "Pair", True, "getLeft", "", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue", "value", "manual"] + - ["ratpack.util", "Pair", True, "getRight", "", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue", "value", "manual"] + - ["ratpack.util", "Pair", True, "left", "()", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue", "value", "manual"] + - ["ratpack.util", "Pair", True, "left", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "left", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "map", "", "", "Argument[-1]", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.util", "Pair", True, "map", "", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] + - ["ratpack.util", "Pair", True, "mapLeft", "", "", "Argument[-1].Field[ratpack.func.Pair.left]", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.util", "Pair", True, "mapLeft", "", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "mapLeft", "", "", "Argument[0].ReturnValue", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "mapRight", "", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "mapRight", "", "", "Argument[-1].Field[ratpack.func.Pair.right]", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.util", "Pair", True, "mapRight", "", "", "Argument[0].ReturnValue", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "nestLeft", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left].Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "nestLeft", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "nestLeft", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left].Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "nestRight", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "nestRight", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right].Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "nestRight", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.right].Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "of", "", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "of", "", "", "Argument[1]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "pair", "", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "pair", "", "", "Argument[1]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "pushLeft", "(Object)", "", "Argument[-1]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "pushLeft", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "pushRight", "(Object)", "", "Argument[-1]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "pushRight", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "right", "()", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue", "value", "manual"] + - ["ratpack.util", "Pair", True, "right", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "right", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] diff --git a/java/ql/lib/ext/retrofit2.model.yml b/java/ql/lib/ext/retrofit2.model.yml new file mode 100644 index 00000000000..7b1a109365a --- /dev/null +++ b/java/ql/lib/ext/retrofit2.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["retrofit2", "Retrofit$Builder", True, "baseUrl", "", "", "Argument[0]", "open-url", "manual"] From 663d091776bb16c16732eba041a59a77691f8bbd Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 15 Nov 2022 10:33:13 +0100 Subject: [PATCH 563/796] Java: Invert dependencies and use the extensible predicates. --- .../code/java/dataflow/ExternalFlow.qll | 121 +++++++++++------- 1 file changed, 77 insertions(+), 44 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 6bd13135c1b..520890146a0 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -161,41 +161,57 @@ private module Frameworks { } /** + * DEPRECATED: Define source models as data extensions instead. + * * A unit class for adding additional source model rows. * * Extend this class to add additional source definitions. */ -class SourceModelCsv extends Unit { +class SourceModelCsv = SourceModelCsvInternal; + +private class SourceModelCsvInternal extends Unit { /** Holds if `row` specifies a source definition. */ abstract predicate row(string row); } /** + * DEPRECATED: Define sink models as data extensions instead. + * * A unit class for adding additional sink model rows. * * Extend this class to add additional sink definitions. */ -class SinkModelCsv extends Unit { +class SinkModelCsv = SinkModelCsvInternal; + +private class SinkModelCsvInternal extends Unit { /** Holds if `row` specifies a sink definition. */ abstract predicate row(string row); } /** + * DEPRECATED: Define summary models as data extensions instead. + * * A unit class for adding additional summary model rows. * * Extend this class to add additional flow summary definitions. */ -class SummaryModelCsv extends Unit { +class SummaryModelCsv = SummaryModelCsvInternal; + +private class SummaryModelCsvInternal extends Unit { /** Holds if `row` specifies a summary definition. */ abstract predicate row(string row); } /** - * A unit class for adding negative summary model rows. + * DEPRECATED: Define negative summary models as data extensions instead. * - * Extend this class to add additional flow summary definitions. + * A unit class for adding additional negative summary model rows. + * + * Extend this class to add additional negative summary definitions. */ -class NegativeSummaryModelCsv extends Unit { +class NegativeSummaryModelCsv = NegativeSummaryModelCsvInternal; + +private class NegativeSummaryModelCsvInternal extends Unit { /** Holds if `row` specifies a negative summary definition. */ abstract predicate row(string row); } @@ -420,17 +436,15 @@ private class SummaryModelCsvBase extends SummaryModelCsv { } } -/** Holds if `row` is a source model. */ -predicate sourceModel(string row) { any(SourceModelCsv s).row(row) } +private predicate sourceModelInternal(string row) { any(SourceModelCsvInternal s).row(row) } -/** Holds if `row` is a sink model. */ -predicate sinkModel(string row) { any(SinkModelCsv s).row(row) } +private predicate summaryModelInternal(string row) { any(SummaryModelCsvInternal s).row(row) } -/** Holds if `row` is a summary model. */ -predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) } +private predicate sinkModelInternal(string row) { any(SinkModelCsvInternal s).row(row) } -/** Holds if `row` is negative summary model. */ -predicate negativeSummaryModel(string row) { any(NegativeSummaryModelCsv s).row(row) } +private predicate negativeSummaryModelInternal(string row) { + any(NegativeSummaryModelCsvInternal s).row(row) +} /** * Holds if a source model exists for the given parameters. @@ -446,7 +460,7 @@ predicate sourceModel( string output, string kind, string provenance ) { exists(string row | - sourceModel(row) and + sourceModelInternal(row) and row.splitAt(";", 0) = package and row.splitAt(";", 1) = type and row.splitAt(";", 2) = subtypes.toString() and @@ -458,6 +472,8 @@ predicate sourceModel( row.splitAt(";", 7) = kind and row.splitAt(";", 8) = provenance ) + or + extSourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance) } /** Holds if a sink model exists for the given parameters. */ @@ -472,7 +488,7 @@ predicate sinkModel( string input, string kind, string provenance ) { exists(string row | - sinkModel(row) and + sinkModelInternal(row) and row.splitAt(";", 0) = package and row.splitAt(";", 1) = type and row.splitAt(";", 2) = subtypes.toString() and @@ -484,6 +500,8 @@ predicate sinkModel( row.splitAt(";", 7) = kind and row.splitAt(";", 8) = provenance ) + or + extSinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance) } /** Holds if a summary model exists for the given parameters. */ @@ -497,26 +515,42 @@ predicate summaryModel( string package, string type, boolean subtypes, string name, string signature, string ext, string input, string output, string kind, string provenance ) { - summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance, _) + exists(string row | + summaryModelInternal(row) and + row.splitAt(";", 0) = package and + row.splitAt(";", 1) = type and + row.splitAt(";", 2) = subtypes.toString() and + subtypes = [true, false] and + row.splitAt(";", 3) = name and + row.splitAt(";", 4) = signature and + row.splitAt(";", 5) = ext and + row.splitAt(";", 6) = input and + row.splitAt(";", 7) = output and + row.splitAt(";", 8) = kind and + row.splitAt(";", 9) = provenance + ) + or + extSummaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) } /** Holds if a summary model `row` exists for the given parameters. */ +bindingset[row] predicate summaryModel( string package, string type, boolean subtypes, string name, string signature, string ext, string input, string output, string kind, string provenance, string row ) { - summaryModel(row) and - row.splitAt(";", 0) = package and - row.splitAt(";", 1) = type and - row.splitAt(";", 2) = subtypes.toString() and - subtypes = [true, false] and - row.splitAt(";", 3) = name and - row.splitAt(";", 4) = signature and - row.splitAt(";", 5) = ext and - row.splitAt(";", 6) = input and - row.splitAt(";", 7) = output and - row.splitAt(";", 8) = kind and - row.splitAt(";", 9) = provenance + summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) and + row = + package + ";" // + + type + ";" // + + subtypes.toString() + ";" // + + name + ";" // + + signature + ";" // + + ext + ";" // + + input + ";" // + + output + ";" // + + kind + ";" // + + provenance } /** Holds if a summary model exists indicating there is no flow for the given parameters. */ @@ -529,19 +563,21 @@ predicate negativeSummaryModel( string package, string type, string name, string signature, string provenance ) { exists(string row | - negativeSummaryModel(row) and + negativeSummaryModelInternal(row) and row.splitAt(";", 0) = package and row.splitAt(";", 1) = type and row.splitAt(";", 2) = name and row.splitAt(";", 3) = signature and row.splitAt(";", 4) = provenance ) + or + extNegativeSummaryModel(package, type, name, signature, provenance) } private predicate relevantPackage(string package) { sourceModel(package, _, _, _, _, _, _, _, _) or sinkModel(package, _, _, _, _, _, _, _, _) or - summaryModel(package, _, _, _, _, _, _, _, _, _, _) + summaryModel(package, _, _, _, _, _, _, _, _, _) } private predicate packageLink(string shortpkg, string longpkg) { @@ -627,14 +663,12 @@ module ModelValidation { } private string getInvalidModelKind() { - exists(string row, string kind | summaryModel(row) | - kind = row.splitAt(";", 8) and + exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) | not kind = ["taint", "value"] and result = "Invalid kind \"" + kind + "\" in summary model." ) or - exists(string row, string kind | sinkModel(row) | - kind = row.splitAt(";", 7) and + exists(string kind | sinkModel(_, _, _, _, _, _, _, kind, _) | not kind = [ "open-url", "jndi-injection", "ldap", "sql", "jdbc-url", "logging", "mvel", "xpath", @@ -648,8 +682,7 @@ module ModelValidation { result = "Invalid kind \"" + kind + "\" in sink model." ) or - exists(string row, string kind | sourceModel(row) | - kind = row.splitAt(";", 7) and + exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | not kind = ["remote", "contentprovider", "android-widget", "android-external-storage-dir"] and not kind.matches("qltest%") and result = "Invalid kind \"" + kind + "\" in source model." @@ -658,11 +691,11 @@ module ModelValidation { private string getInvalidModelSubtype() { exists(string pred, string row | - sourceModel(row) and pred = "source" + sourceModelInternal(row) and pred = "source" or - sinkModel(row) and pred = "sink" + sinkModelInternal(row) and pred = "sink" or - summaryModel(row) and pred = "summary" + summaryModelInternal(row) and pred = "summary" | exists(string b | b = row.splitAt(";", 2) and @@ -674,13 +707,13 @@ module ModelValidation { private string getInvalidModelColumnCount() { exists(string pred, string row, int expect | - sourceModel(row) and expect = 9 and pred = "source" + sourceModelInternal(row) and expect = 9 and pred = "source" or - sinkModel(row) and expect = 9 and pred = "sink" + sinkModelInternal(row) and expect = 9 and pred = "sink" or - summaryModel(row) and expect = 10 and pred = "summary" + summaryModelInternal(row) and expect = 10 and pred = "summary" or - negativeSummaryModel(row) and expect = 5 and pred = "negative summary" + negativeSummaryModelInternal(row) and expect = 5 and pred = "negative summary" | exists(int cols | cols = 1 + max(int n | exists(row.splitAt(";", n))) and From 0abeb831c73e2068d7eeaf8843bf8bf3416ab7dd Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 15 Nov 2022 10:47:11 +0100 Subject: [PATCH 564/796] Java: Move summaryModel predicate, which constructs a CSV row to the testcode where it is used. --- .../code/java/dataflow/ExternalFlow.qll | 20 ---------------- .../flowtestcasegenerator/FlowTestCase.qll | 24 +++++++++++++++++-- .../GenerateFlowTestCase.qll | 8 +++---- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 520890146a0..082fa167103 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -533,26 +533,6 @@ predicate summaryModel( extSummaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) } -/** Holds if a summary model `row` exists for the given parameters. */ -bindingset[row] -predicate summaryModel( - string package, string type, boolean subtypes, string name, string signature, string ext, - string input, string output, string kind, string provenance, string row -) { - summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) and - row = - package + ";" // - + type + ";" // - + subtypes.toString() + ";" // - + name + ";" // - + signature + ";" // - + ext + ";" // - + input + ";" // - + output + ";" // - + kind + ";" // - + provenance -} - /** Holds if a summary model exists indicating there is no flow for the given parameters. */ extensible predicate extNegativeSummaryModel( string package, string type, string name, string signature, string provenance diff --git a/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll b/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll index 046debc5019..bab34473ed7 100644 --- a/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll +++ b/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll @@ -21,6 +21,26 @@ class TargetSummaryModelCsv extends Unit { abstract predicate row(string r); } +/** Holds if a summary model `row` exists for the given parameters. */ +bindingset[row] +predicate summaryModelRow( + string package, string type, boolean subtypes, string name, string signature, string ext, + string input, string output, string kind, string provenance, string row +) { + summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) and + row = + package + ";" // + + type + ";" // + + subtypes.toString() + ";" // + + name + ";" // + + signature + ";" // + + ext + ";" // + + input + ";" // + + output + ";" // + + kind + ";" // + + provenance +} + /** * Gets a CSV row for which a test has been requested, but `SummaryModelCsv.row` does not hold of it. */ @@ -64,8 +84,8 @@ private newtype TTestCase = string inputSpec, string outputSpec | any(TargetSummaryModelCsv tsmc).row(row) and - summaryModel(namespace, type, subtypes, name, signature, ext, inputSpec, outputSpec, kind, _, - row) and + summaryModelRow(namespace, type, subtypes, name, signature, ext, inputSpec, outputSpec, kind, + _, row) and callable = interpretElement(namespace, type, subtypes, name, signature, ext) and Private::External::interpretSpec(inputSpec, input) and Private::External::interpretSpec(outputSpec, output) diff --git a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll index 9eb925be422..613ea19753f 100644 --- a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll +++ b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll @@ -21,25 +21,25 @@ query string getAParseFailure(string reason) { any(TargetSummaryModelCsv target).row(result) and any(SummaryModelCsv model).row(result) and ( - not summaryModel(_, _, _, _, _, _, _, _, _, _, result) and + not summaryModelRow(_, _, _, _, _, _, _, _, _, _, result) and reason = "row could not be parsed" or exists( string namespace, string type, boolean subtypes, string name, string signature, string ext | - summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, result) and + summaryModelRow(namespace, type, subtypes, name, signature, ext, _, _, _, _, result) and not interpretElement(namespace, type, subtypes, name, signature, ext) instanceof Callable and reason = "callable could not be resolved" ) or exists(string inputSpec | - summaryModel(_, _, _, _, _, _, inputSpec, _, _, _, result) and + summaryModelRow(_, _, _, _, _, _, inputSpec, _, _, _, result) and not Private::External::interpretSpec(inputSpec, _) and reason = "input spec could not be parsed" ) or exists(string outputSpec | - summaryModel(_, _, _, _, _, _, _, outputSpec, _, _, result) and + summaryModelRow(_, _, _, _, _, _, _, outputSpec, _, _, result) and not Private::External::interpretSpec(outputSpec, _) and reason = "output spec could not be parsed" ) From f4e1867d28ed2a8538af0b39a5fb0e483a11f4c9 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 15 Nov 2022 10:56:55 +0100 Subject: [PATCH 565/796] Java: Define extensible predicates to at least be empty. --- java/ql/lib/ext/dummy.model.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 java/ql/lib/ext/dummy.model.yml diff --git a/java/ql/lib/ext/dummy.model.yml b/java/ql/lib/ext/dummy.model.yml new file mode 100644 index 00000000000..01642dccae6 --- /dev/null +++ b/java/ql/lib/ext/dummy.model.yml @@ -0,0 +1,18 @@ +extensions: + # Make sure that the extensible model predicates are at least defined as empty. + - addsTo: + pack: codeql/java-all + extensible: extSourceModel + data: [] + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: [] + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: [] + - addsTo: + pack: codeql/java-all + extensible: extNegativeSummaryModel + data: [] \ No newline at end of file From b3a3b676bafd9120e19db49f22d9e000e8115e76 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 15 Nov 2022 13:33:18 +0100 Subject: [PATCH 566/796] Java: Remove manual models from QL code. --- java/ql/lib/ext/android.content.model.yml | 3 + java/ql/lib/ext/android.os.model.yml | 1 + java/ql/lib/ext/android.webkit.model.yml | 1 + .../lib/ext/com.google.common.cache.model.yml | 2 + .../ext/com.google.common.collect.model.yml | 2 + java/ql/lib/ext/jakarta.ws.rs.core.model.yml | 7 + java/ql/lib/ext/java.nio.file.model.yml | 4 +- java/ql/lib/ext/java.util.stream.model.yml | 4 + java/ql/lib/ext/javax.jms.model.yml | 5 + java/ql/lib/ext/javax.ws.rs.core.model.yml | 7 + java/ql/lib/ext/jodd.json.model.yml | 6 + ...g.apache.commons.collections.bag.model.yml | 1 + ...e.commons.collections.collection.model.yml | 1 + ...he.commons.collections.iterators.model.yml | 1 + ...che.commons.collections.keyvalue.model.yml | 3 + ....apache.commons.collections.list.model.yml | 1 + ...g.apache.commons.collections.map.model.yml | 1 + .../org.apache.commons.collections.model.yml | 12 + ...che.commons.collections.multimap.model.yml | 1 + ...apache.commons.collections.queue.model.yml | 1 + ...g.apache.commons.collections.set.model.yml | 1 + ...che.commons.collections.splitmap.model.yml | 1 + ....apache.commons.collections.trie.model.yml | 1 + ....apache.commons.collections4.bag.model.yml | 1 + ....commons.collections4.collection.model.yml | 1 + ...e.commons.collections4.iterators.model.yml | 1 + ...he.commons.collections4.keyvalue.model.yml | 3 + ...apache.commons.collections4.list.model.yml | 1 + ....apache.commons.collections4.map.model.yml | 1 + .../org.apache.commons.collections4.model.yml | 12 + ...he.commons.collections4.multimap.model.yml | 1 + ...pache.commons.collections4.queue.model.yml | 1 + ....apache.commons.collections4.set.model.yml | 1 + ...he.commons.collections4.splitmap.model.yml | 1 + ...apache.commons.collections4.trie.model.yml | 1 + .../lib/ext/org.apache.commons.io.model.yml | 4 + .../ext/org.apache.commons.lang3.model.yml | 10 + .../org.springframework.web.util.model.yml | 1 + .../lib/ext/ratpack.core.handling.model.yml | 1 + java/ql/lib/ext/ratpack.func.model.yml | 4 + java/ql/lib/ext/ratpack.handling.model.yml | 1 + java/ql/lib/ext/ratpack.util.model.yml | 4 + .../code/java/dataflow/ExternalFlow.qll | 252 ---- .../java/dataflow/internal/ContainerFlow.qll | 349 ----- .../code/java/frameworks/ApacheHttp.qll | 199 --- .../semmle/code/java/frameworks/Flexjson.qll | 6 - .../semmle/code/java/frameworks/Hibernate.qll | 16 - .../semmle/code/java/frameworks/HikariCP.qll | 17 - .../lib/semmle/code/java/frameworks/JMS.qll | 112 -- .../semmle/code/java/frameworks/JavaIo.qll | 24 - .../semmle/code/java/frameworks/JavaxJson.qll | 138 -- .../lib/semmle/code/java/frameworks/JaxWS.qll | 331 ----- .../lib/semmle/code/java/frameworks/Jdbc.qll | 30 - .../lib/semmle/code/java/frameworks/Jdbi.qll | 21 - .../semmle/code/java/frameworks/JoddJson.qll | 25 - .../semmle/code/java/frameworks/JsonJava.qll | 252 ---- .../semmle/code/java/frameworks/Logging.qll | 340 ----- .../semmle/code/java/frameworks/MyBatis.qll | 86 -- .../semmle/code/java/frameworks/Objects.qll | 18 - .../semmle/code/java/frameworks/OkHttp.qll | 71 - .../semmle/code/java/frameworks/Optional.qll | 30 - .../semmle/code/java/frameworks/RabbitMQ.qll | 58 - .../lib/semmle/code/java/frameworks/Regex.qll | 17 - .../semmle/code/java/frameworks/Retrofit.qll | 12 - .../code/java/frameworks/SpringJdbc.qll | 42 - .../semmle/code/java/frameworks/Stream.qll | 92 -- .../semmle/code/java/frameworks/Strings.qll | 70 - .../semmle/code/java/frameworks/Thymeleaf.qll | 16 - .../code/java/frameworks/android/Android.qll | 94 -- .../frameworks/android/ContentProviders.qll | 104 -- .../frameworks/android/ExternalStorage.qll | 15 - .../code/java/frameworks/android/Intent.qll | 193 --- .../java/frameworks/android/Notifications.qll | 101 -- .../code/java/frameworks/android/SQLite.qll | 135 -- .../frameworks/android/SharedPreferences.qll | 16 - .../code/java/frameworks/android/Slice.qll | 84 -- .../code/java/frameworks/android/Widget.qll | 12 - .../code/java/frameworks/android/XssSinks.qll | 16 - .../java/frameworks/apache/Collections.qll | 1160 ----------------- .../semmle/code/java/frameworks/apache/IO.qll | 23 - .../code/java/frameworks/apache/Lang.qll | 2 - .../java/frameworks/apache/Lang2Generated.qll | 284 ---- .../java/frameworks/apache/Lang3Generated.qll | 436 ------- .../code/java/frameworks/guava/Base.qll | 98 -- .../code/java/frameworks/guava/Cache.qll | 32 - .../java/frameworks/guava/Collections.qll | 565 -------- .../code/java/frameworks/guava/Guava.qll | 3 - .../semmle/code/java/frameworks/guava/IO.qll | 101 -- .../lib/semmle/code/java/frameworks/jOOQ.qll | 6 - .../jackson/JacksonSerializability.qll | 15 - .../frameworks/javaee/jsf/JSFRenderer.qll | 28 - .../code/java/frameworks/kotlin/StdLib.qll | 14 - .../code/java/frameworks/ratpack/Ratpack.qll | 135 -- .../java/frameworks/ratpack/RatpackExec.qll | 96 -- .../code/java/frameworks/spring/Spring.qll | 9 - .../java/frameworks/spring/SpringBeans.qll | 48 - .../java/frameworks/spring/SpringCache.qll | 27 - .../java/frameworks/spring/SpringContext.qll | 18 - .../java/frameworks/spring/SpringData.qll | 17 - .../java/frameworks/spring/SpringHttp.qll | 101 -- .../code/java/frameworks/spring/SpringUi.qll | 46 - .../java/frameworks/spring/SpringUtil.qll | 153 --- .../frameworks/spring/SpringValidation.qll | 25 - .../frameworks/spring/SpringWebClient.qll | 23 - .../frameworks/spring/SpringWebMultipart.qll | 25 - .../java/frameworks/spring/SpringWebUtil.qll | 176 --- .../code/java/regex/RegexFlowConfigs.qll | 1 - .../code/java/regex/RegexFlowModels.qll | 38 - .../security/AndroidIntentRedirection.qll | 31 - ...CleartextStorageAndroidFilesystemQuery.qll | 1 - .../lib/semmle/code/java/security/Files.qll | 100 -- .../code/java/security/FragmentInjection.qll | 16 - .../code/java/security/GroovyInjection.qll | 41 - .../java/security/ImplicitPendingIntents.qll | 33 - .../code/java/security/InformationLeak.qll | 8 - .../java/security/JexlInjectionSinkModels.qll | 43 - .../code/java/security/JndiInjection.qll | 56 - .../code/java/security/LdapInjection.qll | 47 - .../code/java/security/MvelInjection.qll | 25 - .../code/java/security/OgnlInjection.qll | 23 - .../code/java/security/ResponseSplitting.qll | 12 - .../code/java/security/TemplateInjection.qll | 30 - .../lib/semmle/code/java/security/XPath.qll | 32 - .../code/java/security/XsltInjection.qll | 14 - .../java/security/regexp/RegexInjection.qll | 2 +- 125 files changed, 117 insertions(+), 7613 deletions(-) delete mode 100644 java/ql/lib/semmle/code/java/frameworks/HikariCP.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/JMS.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/JavaIo.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/JavaxJson.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/Jdbi.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/JsonJava.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/Logging.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/Objects.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/OkHttp.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/Optional.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/RabbitMQ.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/Retrofit.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/Strings.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/Thymeleaf.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/android/Notifications.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/android/XssSinks.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/apache/IO.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/apache/Lang2Generated.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/apache/Lang3Generated.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/guava/Base.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/guava/Cache.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/guava/IO.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/kotlin/StdLib.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/ratpack/Ratpack.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/spring/SpringBeans.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/spring/SpringCache.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/spring/SpringContext.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/spring/SpringData.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/spring/SpringUi.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/spring/SpringUtil.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/spring/SpringValidation.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/spring/SpringWebMultipart.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/spring/SpringWebUtil.qll delete mode 100644 java/ql/lib/semmle/code/java/regex/RegexFlowModels.qll delete mode 100644 java/ql/lib/semmle/code/java/security/Files.qll delete mode 100644 java/ql/lib/semmle/code/java/security/JexlInjectionSinkModels.qll diff --git a/java/ql/lib/ext/android.content.model.yml b/java/ql/lib/ext/android.content.model.yml index 23e3e376c12..a07799665db 100644 --- a/java/ql/lib/ext/android.content.model.yml +++ b/java/ql/lib/ext/android.content.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSourceModel data: + # ContentInterface models are here for backwards compatibility (it was removed in API 28) - ["android.content", "ContentInterface", True, "call", "(String,String,String,Bundle)", "", "Parameter[0..3]", "contentprovider", "manual"] - ["android.content", "ContentInterface", True, "delete", "(Uri,Bundle)", "", "Parameter[0..1]", "contentprovider", "manual"] - ["android.content", "ContentInterface", True, "getType", "(Uri)", "", "Parameter[0]", "contentprovider", "manual"] @@ -80,6 +81,7 @@ extensions: - ["android.content", "ComponentName", False, "unflattenFromString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String,CancellationSignal)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + # ContentProviderClient is tainted at its creation, not by its arguments - ["android.content", "ContentProviderClient", True, "applyBatch", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["android.content", "ContentProviderClient", True, "call", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["android.content", "ContentProviderClient", True, "canonicalize", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] @@ -132,6 +134,7 @@ extensions: - ["android.content", "ContentValues", False, "put", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] - ["android.content", "ContentValues", False, "putAll", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] - ["android.content", "ContentValues", False, "putAll", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + # Currently only the Extras part of the intent and the data field are fully modeled - ["android.content", "Intent", True, "Intent", "(Context,Class)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["android.content", "Intent", True, "Intent", "(Intent)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["android.content", "Intent", False, "Intent", "(Intent)", "", "Argument[0].SyntheticField[android.content.Intent.extras].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] diff --git a/java/ql/lib/ext/android.os.model.yml b/java/ql/lib/ext/android.os.model.yml index 8581a3f47ae..32860445cf4 100644 --- a/java/ql/lib/ext/android.os.model.yml +++ b/java/ql/lib/ext/android.os.model.yml @@ -35,6 +35,7 @@ extensions: - ["android.os", "Bundle", False, "Bundle", "(PersistableBundle)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] - ["android.os", "Bundle", True, "clone", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] - ["android.os", "Bundle", True, "clone", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + # Model for Bundle.deepCopy is not fully precise, as some map values aren't copied by value - ["android.os", "Bundle", True, "deepCopy", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] - ["android.os", "Bundle", True, "deepCopy", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] - ["android.os", "Bundle", True, "getBinder", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/android.webkit.model.yml b/java/ql/lib/ext/android.webkit.model.yml index a12ffdd44dd..c5a3ed8661f 100644 --- a/java/ql/lib/ext/android.webkit.model.yml +++ b/java/ql/lib/ext/android.webkit.model.yml @@ -9,6 +9,7 @@ extensions: pack: codeql/java-all extensible: extSinkModel data: + # Models representing methods susceptible to XSS attacks. - ["android.webkit", "WebView", False, "evaluateJavascript", "", "", "Argument[0]", "xss", "manual"] - ["android.webkit", "WebView", False, "loadData", "", "", "Argument[0]", "xss", "manual"] - ["android.webkit", "WebView", False, "loadDataWithBaseURL", "", "", "Argument[1]", "xss", "manual"] diff --git a/java/ql/lib/ext/com.google.common.cache.model.yml b/java/ql/lib/ext/com.google.common.cache.model.yml index 673ee594992..852542d19d6 100644 --- a/java/ql/lib/ext/com.google.common.cache.model.yml +++ b/java/ql/lib/ext/com.google.common.cache.model.yml @@ -5,7 +5,9 @@ extensions: data: - ["com.google.common.cache", "Cache", True, "asMap", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] - ["com.google.common.cache", "Cache", True, "asMap", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + # Lambda flow from Argument[1] not implemented - ["com.google.common.cache", "Cache", True, "get", "(Object,Callable)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + # The true flow to MapKey of ReturnValue for getAllPresent is the intersection of the these inputs, but intersections cannot be modeled fully accurately. - ["com.google.common.cache", "Cache", True, "getAllPresent", "(Iterable)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] - ["com.google.common.cache", "Cache", True, "getAllPresent", "(Iterable)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] - ["com.google.common.cache", "Cache", True, "getAllPresent", "(Iterable)", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] diff --git a/java/ql/lib/ext/com.google.common.collect.model.yml b/java/ql/lib/ext/com.google.common.collect.model.yml index 434fb34d728..98124e42679 100644 --- a/java/ql/lib/ext/com.google.common.collect.model.yml +++ b/java/ql/lib/ext/com.google.common.collect.model.yml @@ -3,6 +3,8 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Methods depending on lambda flow are not currently modeled + # Methods depending on stronger aliasing properties than we support are also not modeled. - ["com.google.common.collect", "ArrayListMultimap", True, "create", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] - ["com.google.common.collect", "ArrayListMultimap", True, "create", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] - ["com.google.common.collect", "ArrayTable", True, "create", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] diff --git a/java/ql/lib/ext/jakarta.ws.rs.core.model.yml b/java/ql/lib/ext/jakarta.ws.rs.core.model.yml index 1f1cc59d161..44c8ed66881 100644 --- a/java/ql/lib/ext/jakarta.ws.rs.core.model.yml +++ b/java/ql/lib/ext/jakarta.ws.rs.core.model.yml @@ -27,6 +27,9 @@ extensions: - ["jakarta.ws.rs.core", "Form", True, "param", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] - ["jakarta.ws.rs.core", "GenericEntity", False, "GenericEntity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["jakarta.ws.rs.core", "GenericEntity", True, "getEntity", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + # Methods that Date have to be syntax-checked, but those returning MediaType + # or Locale are assumed potentially dangerous, as these types do not generally check that the + # input data is recognised, only that it conforms to the expected syntax. - ["jakarta.ws.rs.core", "HttpHeaders", True, "getAcceptableLanguages", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["jakarta.ws.rs.core", "HttpHeaders", True, "getAcceptableMediaTypes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["jakarta.ws.rs.core", "HttpHeaders", True, "getCookies", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] @@ -63,9 +66,13 @@ extensions: - ["jakarta.ws.rs.core", "NewCookie", False, "valueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["jakarta.ws.rs.core", "PathSegment", True, "getMatrixParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["jakarta.ws.rs.core", "PathSegment", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + # The returned ResponseBuilder gains taint from a tainted entity or existing Response - ["jakarta.ws.rs.core", "Response", False, "accepted", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["jakarta.ws.rs.core", "Response", False, "fromResponse", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["jakarta.ws.rs.core", "Response", False, "ok", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + # Becomes tainted by a tainted entity, but not by metadata, headers etc + # Build() method returns taint + # Almost all methods are fluent, and so preserve value - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "allow", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "cacheControl", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index a593f0e7bf7..43c19fedbff 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -24,10 +24,12 @@ extensions: data: - ["java.nio.file", "FileSystem", True, "getPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["java.nio.file", "FileSystem", True, "getRootDirectories", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Path", True, "getParent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["java.nio.file", "Path", True, "normalize", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["java.nio.file", "Path", True, "resolve", "", "", "Argument[-1..0]", "ReturnValue", "taint", "manual"] - ["java.nio.file", "Path", True, "toAbsolutePath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["java.nio.file", "Path", False, "toFile", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["java.nio.file", "Path", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["java.nio.file", "Path", True, "toUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["java.nio.file", "Paths", True, "get", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Paths", True, "get", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Paths", True, "get", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/java.util.stream.model.yml b/java/ql/lib/ext/java.util.stream.model.yml index 431829ec322..ae453444faf 100644 --- a/java/ql/lib/ext/java.util.stream.model.yml +++ b/java/ql/lib/ext/java.util.stream.model.yml @@ -16,6 +16,7 @@ extensions: - ["java.util.stream", "Stream", True, "collect", "(Supplier,BiConsumer,BiConsumer)", "", "Argument[1].Parameter[0]", "Argument[2].Parameter[0..1]", "value", "manual"] - ["java.util.stream", "Stream", True, "collect", "(Supplier,BiConsumer,BiConsumer)", "", "Argument[1].Parameter[0]", "ReturnValue", "value", "manual"] - ["java.util.stream", "Stream", True, "collect", "(Supplier,BiConsumer,BiConsumer)", "", "Argument[2].Parameter[0..1]", "Argument[1].Parameter[0]", "value", "manual"] + # collect(Collector collector) is handled separately on a case-by-case basis as it is too complex for MaD - ["java.util.stream", "Stream", True, "concat", "(Stream,Stream)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] - ["java.util.stream", "Stream", True, "distinct", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] - ["java.util.stream", "Stream", True, "dropWhile", "(Predicate)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] @@ -43,6 +44,9 @@ extensions: - ["java.util.stream", "Stream", True, "limit", "(long)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] - ["java.util.stream", "Stream", True, "map", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] - ["java.util.stream", "Stream", True, "map", "(Function)", "", "Argument[0].ReturnValue", "ReturnValue.Element", "value", "manual"] + # Missing for mapMulti(BiConsumer) (not currently supported): + # Argument[0] of Parameter[1] of Argument[0] -> Element of Parameter[1] of Argument[0] + # Element of Parameter[1] of Argument[0] -> Element of ReturnValue - ["java.util.stream", "Stream", True, "mapMulti", "(BiConsumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] - ["java.util.stream", "Stream", True, "mapMultiToDouble", "(BiConsumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] - ["java.util.stream", "Stream", True, "mapMultiToInt", "(BiConsumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] diff --git a/java/ql/lib/ext/javax.jms.model.yml b/java/ql/lib/ext/javax.jms.model.yml index 9f153e35370..9ccf3e7a379 100644 --- a/java/ql/lib/ext/javax.jms.model.yml +++ b/java/ql/lib/ext/javax.jms.model.yml @@ -1,3 +1,8 @@ + # This model covers JMS API versions 1 and 2. + # + # https://docs.oracle.com/javaee/6/api/javax/jms/package-summary.html + # https://docs.oracle.com/javaee/7/api/javax/jms/package-summary.html + # extensions: - addsTo: pack: codeql/java-all diff --git a/java/ql/lib/ext/javax.ws.rs.core.model.yml b/java/ql/lib/ext/javax.ws.rs.core.model.yml index 079f1afa9d2..3c1611970f9 100644 --- a/java/ql/lib/ext/javax.ws.rs.core.model.yml +++ b/java/ql/lib/ext/javax.ws.rs.core.model.yml @@ -28,6 +28,9 @@ extensions: - ["javax.ws.rs.core", "Form", True, "param", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] - ["javax.ws.rs.core", "GenericEntity", False, "GenericEntity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["javax.ws.rs.core", "GenericEntity", True, "getEntity", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + # Methods that Date have to be syntax-checked, but those returning MediaType + # or Locale are assumed potentially dangerous, as these types do not generally check that the + # input data is recognised, only that it conforms to the expected syntax. - ["javax.ws.rs.core", "HttpHeaders", True, "getAcceptableLanguages", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["javax.ws.rs.core", "HttpHeaders", True, "getAcceptableMediaTypes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["javax.ws.rs.core", "HttpHeaders", True, "getCookies", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] @@ -64,9 +67,13 @@ extensions: - ["javax.ws.rs.core", "NewCookie", False, "valueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["javax.ws.rs.core", "PathSegment", True, "getMatrixParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["javax.ws.rs.core", "PathSegment", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + # The returned ResponseBuilder gains taint from a tainted entity or existing Response - ["javax.ws.rs.core", "Response", False, "accepted", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["javax.ws.rs.core", "Response", False, "fromResponse", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["javax.ws.rs.core", "Response", False, "ok", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + # Becomes tainted by a tainted entity, but not by metadata, headers etc + # Build() method returns taint + # Almost all methods are fluent, and so preserve value - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "allow", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "cacheControl", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/jodd.json.model.yml b/java/ql/lib/ext/jodd.json.model.yml index 6335ce520c0..6187110797d 100644 --- a/java/ql/lib/ext/jodd.json.model.yml +++ b/java/ql/lib/ext/jodd.json.model.yml @@ -1,3 +1,9 @@ + # A partial model of jodd.json.JsonParser noting fluent methods. + # + # This means that DataFlow::localFlow and similar methods are aware + # that the result of (e.g.) JsonParser.allowClass is an alias of the + # qualifier. + # extensions: - addsTo: pack: codeql/java-all diff --git a/java/ql/lib/ext/org.apache.commons.collections.bag.model.yml b/java/ql/lib/ext/org.apache.commons.collections.bag.model.yml index ae77069bdee..55ab021d9ff 100644 --- a/java/ql/lib/ext/org.apache.commons.collections.bag.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections.bag.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformedBag, TransformedSortedBag - ["org.apache.commons.collections.bag", "AbstractBagDecorator", True, "AbstractBagDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections.bag", "AbstractMapBag", True, "AbstractMapBag", "", "", "Argument[0].MapKey", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections.bag", "AbstractMapBag", True, "getMap", "", "", "Argument[-1].Element", "ReturnValue.MapKey", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.collection.model.yml b/java/ql/lib/ext/org.apache.commons.collections.collection.model.yml index 53e523e74ed..a2cdd0a2d80 100644 --- a/java/ql/lib/ext/org.apache.commons.collections.collection.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections.collection.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformedCollection - ["org.apache.commons.collections.collection", "AbstractCollectionDecorator", True, "AbstractCollectionDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections.collection", "AbstractCollectionDecorator", True, "decorated", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections.collection", "AbstractCollectionDecorator", True, "setCollection", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.iterators.model.yml b/java/ql/lib/ext/org.apache.commons.collections.iterators.model.yml index d5cf30ca7cc..d65fc0e6f93 100644 --- a/java/ql/lib/ext/org.apache.commons.collections.iterators.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections.iterators.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformIterator - ["org.apache.commons.collections.iterators", "AbstractIteratorDecorator", True, "AbstractIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections.iterators", "AbstractListIteratorDecorator", True, "AbstractListIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections.iterators", "AbstractListIteratorDecorator", True, "getListIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.keyvalue.model.yml b/java/ql/lib/ext/org.apache.commons.collections.keyvalue.model.yml index 679da24a74c..9c7e0fd4bca 100644 --- a/java/ql/lib/ext/org.apache.commons.collections.keyvalue.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections.keyvalue.model.yml @@ -3,6 +3,9 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should model the package `org.apache.commons.collections4.functors`, + # and when more general callable flow is supported we should model the package + # `org.apache.commons.collections4.sequence`. - ["org.apache.commons.collections.keyvalue", "AbstractKeyValue", True, "AbstractKeyValue", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] - ["org.apache.commons.collections.keyvalue", "AbstractKeyValue", True, "AbstractKeyValue", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] - ["org.apache.commons.collections.keyvalue", "AbstractKeyValue", True, "setKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.list.model.yml b/java/ql/lib/ext/org.apache.commons.collections.list.model.yml index d97d893a2c0..53ad3035659 100644 --- a/java/ql/lib/ext/org.apache.commons.collections.list.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections.list.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformedList - ["org.apache.commons.collections.list", "AbstractLinkedList", True, "AbstractLinkedList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections.list", "AbstractLinkedList", True, "addFirst", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections.list", "AbstractLinkedList", True, "addLast", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.map.model.yml b/java/ql/lib/ext/org.apache.commons.collections.map.model.yml index 85b368c7fcd..a6280315075 100644 --- a/java/ql/lib/ext/org.apache.commons.collections.map.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections.map.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for DefaultedMap, LazyMap, TransformedMap, TransformedSortedMap - ["org.apache.commons.collections.map", "AbstractHashedMap", True, "AbstractHashedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] - ["org.apache.commons.collections.map", "AbstractHashedMap", True, "AbstractHashedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] - ["org.apache.commons.collections.map", "AbstractLinkedMap", True, "AbstractLinkedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.model.yml b/java/ql/lib/ext/org.apache.commons.collections.model.yml index 13192b5a709..5846d092b5c 100644 --- a/java/ql/lib/ext/org.apache.commons.collections.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections.model.yml @@ -3,6 +3,13 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should model things relating to Closure, Factory, Transformer, FluentIterable.forEach, FluentIterable.transform + # Note that when lambdas are supported we should model the package `org.apache.commons.collections4.functors`, + # and when more general callable flow is supported we should model the package + # `org.apache.commons.collections4.sequence`. + # Note that when lambdas are supported we should have more models for populateMap + # Note that when lambdas are supported we should have a model for collect, forAllButLastDo, forAllDo, transform + # Note that when lambdas are supported we should have a model for forEach, forEachButLast, transformedIterator - ["org.apache.commons.collections", "ArrayStack", True, "peek", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] - ["org.apache.commons.collections", "ArrayStack", True, "pop", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] - ["org.apache.commons.collections", "ArrayStack", True, "push", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] @@ -60,6 +67,7 @@ extensions: - ["org.apache.commons.collections", "CollectionUtils", True, "selectRejected", "(Iterable,Predicate,Collection)", "", "Argument[2]", "ReturnValue", "value", "manual"] - ["org.apache.commons.collections", "CollectionUtils", True, "subtract", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections", "CollectionUtils", True, "synchronizedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + # Note that `CollectionUtils.transformingCollection` does not transform existing list elements - ["org.apache.commons.collections", "CollectionUtils", True, "transformingCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections", "CollectionUtils", True, "union", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections", "CollectionUtils", True, "union", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] @@ -191,6 +199,7 @@ extensions: - ["org.apache.commons.collections", "ListUtils", True, "fixedSizeList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections", "ListUtils", True, "intersection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections", "ListUtils", True, "intersection", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + # Note that `ListUtils.lazyList` does not transform existing list elements - ["org.apache.commons.collections", "ListUtils", True, "lazyList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections", "ListUtils", True, "longestCommonSubsequence", "(CharSequence,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["org.apache.commons.collections", "ListUtils", True, "longestCommonSubsequence", "(CharSequence,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "manual"] @@ -208,10 +217,13 @@ extensions: - ["org.apache.commons.collections", "ListUtils", True, "sum", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections", "ListUtils", True, "sum", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections", "ListUtils", True, "synchronizedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + # Note that `ListUtils.transformedList` does not transform existing list elements - ["org.apache.commons.collections", "ListUtils", True, "transformedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections", "ListUtils", True, "union", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections", "ListUtils", True, "union", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections", "ListUtils", True, "unmodifiableList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + # Note that MapIterator implements Iterator, so it iterates over the keys of the map. + # In order for the models of Iterator to work we have to use Element instead of MapKey for key data. - ["org.apache.commons.collections", "MapIterator", True, "getKey", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] - ["org.apache.commons.collections", "MapIterator", True, "getValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] - ["org.apache.commons.collections", "MapIterator", True, "setValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.multimap.model.yml b/java/ql/lib/ext/org.apache.commons.collections.multimap.model.yml index be759e9ccbb..d1d0b5a885c 100644 --- a/java/ql/lib/ext/org.apache.commons.collections.multimap.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections.multimap.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformedMultiValuedMap - ["org.apache.commons.collections.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] - ["org.apache.commons.collections.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] - ["org.apache.commons.collections.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.queue.model.yml b/java/ql/lib/ext/org.apache.commons.collections.queue.model.yml index 41c40f6fb4c..5a9db9599d4 100644 --- a/java/ql/lib/ext/org.apache.commons.collections.queue.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections.queue.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformedQueue - ["org.apache.commons.collections.queue", "CircularFifoQueue", True, "CircularFifoQueue", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections.queue", "CircularFifoQueue", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] - ["org.apache.commons.collections.queue", "PredicatedQueue", True, "predicatedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.set.model.yml b/java/ql/lib/ext/org.apache.commons.collections.set.model.yml index 56f97fd9b2e..019f862568d 100644 --- a/java/ql/lib/ext/org.apache.commons.collections.set.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections.set.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformedNavigableSet - ["org.apache.commons.collections.set", "AbstractNavigableSetDecorator", True, "AbstractNavigableSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections.set", "AbstractSetDecorator", True, "AbstractSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections.set", "AbstractSortedSetDecorator", True, "AbstractSortedSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.splitmap.model.yml b/java/ql/lib/ext/org.apache.commons.collections.splitmap.model.yml index 307081c6171..447b3533fbc 100644 --- a/java/ql/lib/ext/org.apache.commons.collections.splitmap.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections.splitmap.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformedSplitMap - ["org.apache.commons.collections.splitmap", "AbstractIterableGetMapDecorator", True, "AbstractIterableGetMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] - ["org.apache.commons.collections.splitmap", "AbstractIterableGetMapDecorator", True, "AbstractIterableGetMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] - ["org.apache.commons.collections.splitmap", "TransformedSplitMap", True, "transformingMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.trie.model.yml b/java/ql/lib/ext/org.apache.commons.collections.trie.model.yml index 1312bd074b8..451e0b60bc7 100644 --- a/java/ql/lib/ext/org.apache.commons.collections.trie.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections.trie.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformedSplitMap - ["org.apache.commons.collections.trie", "AbstractPatriciaTrie", True, "select", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] - ["org.apache.commons.collections.trie", "AbstractPatriciaTrie", True, "select", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] - ["org.apache.commons.collections.trie", "AbstractPatriciaTrie", True, "selectKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.bag.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.bag.model.yml index 5261491c1c7..ddc26f49b7f 100644 --- a/java/ql/lib/ext/org.apache.commons.collections4.bag.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections4.bag.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformedBag, TransformedSortedBag - ["org.apache.commons.collections4.bag", "AbstractBagDecorator", True, "AbstractBagDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections4.bag", "AbstractMapBag", True, "AbstractMapBag", "", "", "Argument[0].MapKey", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections4.bag", "AbstractMapBag", True, "getMap", "", "", "Argument[-1].Element", "ReturnValue.MapKey", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.collection.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.collection.model.yml index 1c53d650fd3..f3ac93c242d 100644 --- a/java/ql/lib/ext/org.apache.commons.collections4.collection.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections4.collection.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformedCollection - ["org.apache.commons.collections4.collection", "AbstractCollectionDecorator", True, "AbstractCollectionDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections4.collection", "AbstractCollectionDecorator", True, "decorated", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections4.collection", "AbstractCollectionDecorator", True, "setCollection", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.iterators.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.iterators.model.yml index ca86086d08b..f6671a823c4 100644 --- a/java/ql/lib/ext/org.apache.commons.collections4.iterators.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections4.iterators.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformIterator - ["org.apache.commons.collections4.iterators", "AbstractIteratorDecorator", True, "AbstractIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections4.iterators", "AbstractListIteratorDecorator", True, "AbstractListIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections4.iterators", "AbstractListIteratorDecorator", True, "getListIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.keyvalue.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.keyvalue.model.yml index b62873ed707..aa4a663115e 100644 --- a/java/ql/lib/ext/org.apache.commons.collections4.keyvalue.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections4.keyvalue.model.yml @@ -3,6 +3,9 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should model the package `org.apache.commons.collections4.functors`, + # and when more general callable flow is supported we should model the package + # `org.apache.commons.collections4.sequence`. - ["org.apache.commons.collections4.keyvalue", "AbstractKeyValue", True, "AbstractKeyValue", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] - ["org.apache.commons.collections4.keyvalue", "AbstractKeyValue", True, "AbstractKeyValue", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] - ["org.apache.commons.collections4.keyvalue", "AbstractKeyValue", True, "setKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.list.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.list.model.yml index 4307d7f1a92..7d82ffdcfa5 100644 --- a/java/ql/lib/ext/org.apache.commons.collections4.list.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections4.list.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformedList - ["org.apache.commons.collections4.list", "AbstractLinkedList", True, "AbstractLinkedList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections4.list", "AbstractLinkedList", True, "addFirst", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections4.list", "AbstractLinkedList", True, "addLast", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.map.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.map.model.yml index 77b0d66f081..52d1221ed1d 100644 --- a/java/ql/lib/ext/org.apache.commons.collections4.map.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections4.map.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for DefaultedMap, LazyMap, TransformedMap, TransformedSortedMap - ["org.apache.commons.collections4.map", "AbstractHashedMap", True, "AbstractHashedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] - ["org.apache.commons.collections4.map", "AbstractHashedMap", True, "AbstractHashedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] - ["org.apache.commons.collections4.map", "AbstractLinkedMap", True, "AbstractLinkedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.model.yml index c3e91e9939b..ce5fc6b9fe9 100644 --- a/java/ql/lib/ext/org.apache.commons.collections4.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections4.model.yml @@ -3,6 +3,13 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should model things relating to Closure, Factory, Transformer, FluentIterable.forEach, FluentIterable.transform + # Note that when lambdas are supported we should model the package `org.apache.commons.collections4.functors`, + # and when more general callable flow is supported we should model the package + # `org.apache.commons.collections4.sequence`. + # Note that when lambdas are supported we should have more models for populateMap + # Note that when lambdas are supported we should have a model for collect, forAllButLastDo, forAllDo, transform + # Note that when lambdas are supported we should have a model for forEach, forEachButLast, transformedIterator - ["org.apache.commons.collections4", "ArrayStack", True, "peek", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] - ["org.apache.commons.collections4", "ArrayStack", True, "pop", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] - ["org.apache.commons.collections4", "ArrayStack", True, "push", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] @@ -60,6 +67,7 @@ extensions: - ["org.apache.commons.collections4", "CollectionUtils", True, "selectRejected", "(Iterable,Predicate,Collection)", "", "Argument[2]", "ReturnValue", "value", "manual"] - ["org.apache.commons.collections4", "CollectionUtils", True, "subtract", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections4", "CollectionUtils", True, "synchronizedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + # Note that `CollectionUtils.transformingCollection` does not transform existing list elements - ["org.apache.commons.collections4", "CollectionUtils", True, "transformingCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections4", "CollectionUtils", True, "union", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections4", "CollectionUtils", True, "union", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] @@ -191,6 +199,7 @@ extensions: - ["org.apache.commons.collections4", "ListUtils", True, "fixedSizeList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections4", "ListUtils", True, "intersection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections4", "ListUtils", True, "intersection", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + # Note that `ListUtils.lazyList` does not transform existing list elements - ["org.apache.commons.collections4", "ListUtils", True, "lazyList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections4", "ListUtils", True, "longestCommonSubsequence", "(CharSequence,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["org.apache.commons.collections4", "ListUtils", True, "longestCommonSubsequence", "(CharSequence,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "manual"] @@ -208,10 +217,13 @@ extensions: - ["org.apache.commons.collections4", "ListUtils", True, "sum", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections4", "ListUtils", True, "sum", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections4", "ListUtils", True, "synchronizedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + # Note that `ListUtils.transformedList` does not transform existing list elements - ["org.apache.commons.collections4", "ListUtils", True, "transformedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections4", "ListUtils", True, "union", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections4", "ListUtils", True, "union", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] - ["org.apache.commons.collections4", "ListUtils", True, "unmodifiableList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + # Note that MapIterator implements Iterator, so it iterates over the keys of the map. + # In order for the models of Iterator to work we have to use Element instead of MapKey for key data. - ["org.apache.commons.collections4", "MapIterator", True, "getKey", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] - ["org.apache.commons.collections4", "MapIterator", True, "getValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] - ["org.apache.commons.collections4", "MapIterator", True, "setValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.multimap.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.multimap.model.yml index 0611ffb8e90..3812b6766fd 100644 --- a/java/ql/lib/ext/org.apache.commons.collections4.multimap.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections4.multimap.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformedMultiValuedMap - ["org.apache.commons.collections4.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] - ["org.apache.commons.collections4.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] - ["org.apache.commons.collections4.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.queue.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.queue.model.yml index e4385072bc6..f9067b758e9 100644 --- a/java/ql/lib/ext/org.apache.commons.collections4.queue.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections4.queue.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformedQueue - ["org.apache.commons.collections4.queue", "CircularFifoQueue", True, "CircularFifoQueue", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections4.queue", "CircularFifoQueue", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] - ["org.apache.commons.collections4.queue", "PredicatedQueue", True, "predicatedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.set.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.set.model.yml index e6df878695e..63ac0c91141 100644 --- a/java/ql/lib/ext/org.apache.commons.collections4.set.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections4.set.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformedNavigableSet - ["org.apache.commons.collections4.set", "AbstractNavigableSetDecorator", True, "AbstractNavigableSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections4.set", "AbstractSetDecorator", True, "AbstractSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] - ["org.apache.commons.collections4.set", "AbstractSortedSetDecorator", True, "AbstractSortedSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.splitmap.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.splitmap.model.yml index 4be99cb8ec9..5a1de63ba6a 100644 --- a/java/ql/lib/ext/org.apache.commons.collections4.splitmap.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections4.splitmap.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformedSplitMap - ["org.apache.commons.collections4.splitmap", "AbstractIterableGetMapDecorator", True, "AbstractIterableGetMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] - ["org.apache.commons.collections4.splitmap", "AbstractIterableGetMapDecorator", True, "AbstractIterableGetMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] - ["org.apache.commons.collections4.splitmap", "TransformedSplitMap", True, "transformingMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.trie.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.trie.model.yml index 44d64dda75d..1f33d441e18 100644 --- a/java/ql/lib/ext/org.apache.commons.collections4.trie.model.yml +++ b/java/ql/lib/ext/org.apache.commons.collections4.trie.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Note that when lambdas are supported we should have more models for TransformedSplitMap - ["org.apache.commons.collections4.trie", "AbstractPatriciaTrie", True, "select", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] - ["org.apache.commons.collections4.trie", "AbstractPatriciaTrie", True, "select", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] - ["org.apache.commons.collections4.trie", "AbstractPatriciaTrie", True, "selectKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.io.model.yml b/java/ql/lib/ext/org.apache.commons.io.model.yml index c135623eff6..6cb7aa0b251 100644 --- a/java/ql/lib/ext/org.apache.commons.io.model.yml +++ b/java/ql/lib/ext/org.apache.commons.io.model.yml @@ -3,6 +3,10 @@ extensions: pack: codeql/java-all extensible: extSummaryModel data: + # Models that are not yet auto generated or where the generated summaries will + # be ignored. + # Note that if a callable has any handwritten summary, all generated summaries + # will be ignored for that callable. - ["org.apache.commons.io", "IOUtils", False, "toBufferedInputStream", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["org.apache.commons.io", "IOUtils", True, "toByteArray", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["org.apache.commons.io", "IOUtils", True, "toByteArray", "(Reader,String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.lang3.model.yml b/java/ql/lib/ext/org.apache.commons.lang3.model.yml index 4b0c89d2731..3fda3a551af 100644 --- a/java/ql/lib/ext/org.apache.commons.lang3.model.yml +++ b/java/ql/lib/ext/org.apache.commons.lang3.model.yml @@ -1,4 +1,14 @@ extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.commons.lang3", "RegExUtils", False, "removeAll", "(String,String)", "", "Argument[1]", "regex-use", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "removeFirst", "(String,String)", "", "Argument[1]", "regex-use", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "removePattern", "(String,String)", "", "Argument[1]", "regex-use", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replaceAll", "(String,String,String)", "", "Argument[1]", "regex-use", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replaceFirst", "(String,String,String)", "", "Argument[1]", "regex-use", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replacePattern", "(String,String,String)", "", "Argument[1]", "regex-use", "manual"] - addsTo: pack: codeql/java-all extensible: extSummaryModel diff --git a/java/ql/lib/ext/org.springframework.web.util.model.yml b/java/ql/lib/ext/org.springframework.web.util.model.yml index c3f70b66cf8..151be5867e0 100644 --- a/java/ql/lib/ext/org.springframework.web.util.model.yml +++ b/java/ql/lib/ext/org.springframework.web.util.model.yml @@ -6,6 +6,7 @@ extensions: - ["org.springframework.web.util", "AbstractUriTemplateHandler", True, "getBaseUrl", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["org.springframework.web.util", "AbstractUriTemplateHandler", True, "setBaseUrl", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["org.springframework.web.util", "AbstractUriTemplateHandler", True, "setDefaultUriVariables", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + # Writing to a `Request` or `Response` currently doesn't propagate taint to the object itself. - ["org.springframework.web.util", "ContentCachingRequestWrapper", False, "ContentCachingRequestWrapper", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["org.springframework.web.util", "ContentCachingRequestWrapper", False, "getContentAsByteArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["org.springframework.web.util", "ContentCachingResponseWrapper", False, "ContentCachingResponseWrapper", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/ratpack.core.handling.model.yml b/java/ql/lib/ext/ratpack.core.handling.model.yml index edb02aaeced..7662cc6c79d 100644 --- a/java/ql/lib/ext/ratpack.core.handling.model.yml +++ b/java/ql/lib/ext/ratpack.core.handling.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSourceModel data: + # All Context#parse methods that return a Promise are remote flow sources. - ["ratpack.core.handling", "Context", True, "parse", "(com.google.common.reflect.TypeToken)", "", "ReturnValue", "remote", "manual"] - ["ratpack.core.handling", "Context", True, "parse", "(com.google.common.reflect.TypeToken,java.lang.Object)", "", "ReturnValue", "remote", "manual"] - ["ratpack.core.handling", "Context", True, "parse", "(java.lang.Class)", "", "ReturnValue", "remote", "manual"] diff --git a/java/ql/lib/ext/ratpack.func.model.yml b/java/ql/lib/ext/ratpack.func.model.yml index e850a8cbfe1..04e5a0cec8c 100644 --- a/java/ql/lib/ext/ratpack.func.model.yml +++ b/java/ql/lib/ext/ratpack.func.model.yml @@ -13,17 +13,21 @@ extensions: - ["ratpack.func", "Pair", True, "left", "()", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue", "value", "manual"] - ["ratpack.func", "Pair", True, "left", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] - ["ratpack.func", "Pair", True, "left", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + # `map` maps over the `Pair` - ["ratpack.func", "Pair", True, "map", "", "", "Argument[-1]", "Argument[0].Parameter[0]", "value", "manual"] - ["ratpack.func", "Pair", True, "map", "", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] + # `mapLeft` & `mapRight` map over their respective fields - ["ratpack.func", "Pair", True, "mapLeft", "", "", "Argument[-1].Field[ratpack.func.Pair.left]", "Argument[0].Parameter[0]", "value", "manual"] - ["ratpack.func", "Pair", True, "mapLeft", "", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] - ["ratpack.func", "Pair", True, "mapLeft", "", "", "Argument[0].ReturnValue", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] - ["ratpack.func", "Pair", True, "mapRight", "", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] - ["ratpack.func", "Pair", True, "mapRight", "", "", "Argument[-1].Field[ratpack.func.Pair.right]", "Argument[0].Parameter[0]", "value", "manual"] - ["ratpack.func", "Pair", True, "mapRight", "", "", "Argument[0].ReturnValue", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + # `nestLeft` Pair.nestLeft(C) -> Pair, B> - ["ratpack.func", "Pair", True, "nestLeft", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left].Field[ratpack.func.Pair.right]", "value", "manual"] - ["ratpack.func", "Pair", True, "nestLeft", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] - ["ratpack.func", "Pair", True, "nestLeft", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left].Field[ratpack.func.Pair.left]", "value", "manual"] + # `nestRight` Pair.nestRight(C) -> Pair> - ["ratpack.func", "Pair", True, "nestRight", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] - ["ratpack.func", "Pair", True, "nestRight", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right].Field[ratpack.func.Pair.right]", "value", "manual"] - ["ratpack.func", "Pair", True, "nestRight", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.right].Field[ratpack.func.Pair.left]", "value", "manual"] diff --git a/java/ql/lib/ext/ratpack.handling.model.yml b/java/ql/lib/ext/ratpack.handling.model.yml index 3523d1cf937..3c2c54d0bba 100644 --- a/java/ql/lib/ext/ratpack.handling.model.yml +++ b/java/ql/lib/ext/ratpack.handling.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: extSourceModel data: + # All Context#parse methods that return a Promise are remote flow sources. - ["ratpack.handling", "Context", True, "parse", "(com.google.common.reflect.TypeToken)", "", "ReturnValue", "remote", "manual"] - ["ratpack.handling", "Context", True, "parse", "(com.google.common.reflect.TypeToken,java.lang.Object)", "", "ReturnValue", "remote", "manual"] - ["ratpack.handling", "Context", True, "parse", "(java.lang.Class)", "", "ReturnValue", "remote", "manual"] diff --git a/java/ql/lib/ext/ratpack.util.model.yml b/java/ql/lib/ext/ratpack.util.model.yml index b594e03aecd..218a023bcd3 100644 --- a/java/ql/lib/ext/ratpack.util.model.yml +++ b/java/ql/lib/ext/ratpack.util.model.yml @@ -13,17 +13,21 @@ extensions: - ["ratpack.util", "Pair", True, "left", "()", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue", "value", "manual"] - ["ratpack.util", "Pair", True, "left", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] - ["ratpack.util", "Pair", True, "left", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + # `map` maps over the `Pair` - ["ratpack.util", "Pair", True, "map", "", "", "Argument[-1]", "Argument[0].Parameter[0]", "value", "manual"] - ["ratpack.util", "Pair", True, "map", "", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] + # `mapLeft` & `mapRight` map over their respective fields - ["ratpack.util", "Pair", True, "mapLeft", "", "", "Argument[-1].Field[ratpack.func.Pair.left]", "Argument[0].Parameter[0]", "value", "manual"] - ["ratpack.util", "Pair", True, "mapLeft", "", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] - ["ratpack.util", "Pair", True, "mapLeft", "", "", "Argument[0].ReturnValue", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] - ["ratpack.util", "Pair", True, "mapRight", "", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] - ["ratpack.util", "Pair", True, "mapRight", "", "", "Argument[-1].Field[ratpack.func.Pair.right]", "Argument[0].Parameter[0]", "value", "manual"] - ["ratpack.util", "Pair", True, "mapRight", "", "", "Argument[0].ReturnValue", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + # `nestLeft` Pair.nestLeft(C) -> Pair, B> - ["ratpack.util", "Pair", True, "nestLeft", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left].Field[ratpack.func.Pair.right]", "value", "manual"] - ["ratpack.util", "Pair", True, "nestLeft", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] - ["ratpack.util", "Pair", True, "nestLeft", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left].Field[ratpack.func.Pair.left]", "value", "manual"] + # `nestRight` Pair.nestRight(C) -> Pair> - ["ratpack.util", "Pair", True, "nestRight", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] - ["ratpack.util", "Pair", True, "nestRight", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right].Field[ratpack.func.Pair.right]", "value", "manual"] - ["ratpack.util", "Pair", True, "nestRight", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.right].Field[ratpack.func.Pair.left]", "value", "manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 082fa167103..b9688809c45 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -90,56 +90,30 @@ private module Frameworks { private import semmle.code.java.frameworks.android.ContentProviders private import semmle.code.java.frameworks.android.ExternalStorage private import semmle.code.java.frameworks.android.Intent - private import semmle.code.java.frameworks.android.Notifications private import semmle.code.java.frameworks.android.SharedPreferences private import semmle.code.java.frameworks.android.Slice private import semmle.code.java.frameworks.android.SQLite private import semmle.code.java.frameworks.android.Widget - private import semmle.code.java.frameworks.android.XssSinks private import semmle.code.java.frameworks.ApacheHttp private import semmle.code.java.frameworks.apache.Collections - private import semmle.code.java.frameworks.apache.IO private import semmle.code.java.frameworks.apache.Lang private import semmle.code.java.frameworks.Flexjson private import semmle.code.java.frameworks.generated private import semmle.code.java.frameworks.guava.Guava private import semmle.code.java.frameworks.jackson.JacksonSerializability private import semmle.code.java.frameworks.javaee.jsf.JSFRenderer - private import semmle.code.java.frameworks.JavaIo - private import semmle.code.java.frameworks.JavaxJson private import semmle.code.java.frameworks.JaxWS private import semmle.code.java.frameworks.JoddJson - private import semmle.code.java.frameworks.JsonJava - private import semmle.code.java.frameworks.Logging - private import semmle.code.java.frameworks.Objects - private import semmle.code.java.frameworks.OkHttp - private import semmle.code.java.frameworks.Optional - private import semmle.code.java.frameworks.Regex - private import semmle.code.java.frameworks.Retrofit private import semmle.code.java.frameworks.Stream - private import semmle.code.java.frameworks.Strings - private import semmle.code.java.frameworks.Thymeleaf - private import semmle.code.java.frameworks.ratpack.Ratpack private import semmle.code.java.frameworks.ratpack.RatpackExec - private import semmle.code.java.frameworks.spring.SpringCache - private import semmle.code.java.frameworks.spring.SpringContext - private import semmle.code.java.frameworks.spring.SpringData private import semmle.code.java.frameworks.spring.SpringHttp - private import semmle.code.java.frameworks.spring.SpringUtil - private import semmle.code.java.frameworks.spring.SpringUi - private import semmle.code.java.frameworks.spring.SpringValidation private import semmle.code.java.frameworks.spring.SpringWebClient - private import semmle.code.java.frameworks.spring.SpringBeans - private import semmle.code.java.frameworks.spring.SpringWebMultipart - private import semmle.code.java.frameworks.spring.SpringWebUtil private import semmle.code.java.security.AndroidIntentRedirection private import semmle.code.java.security.ResponseSplitting private import semmle.code.java.security.InformationLeak - private import semmle.code.java.security.Files private import semmle.code.java.security.FragmentInjection private import semmle.code.java.security.GroovyInjection private import semmle.code.java.security.ImplicitPendingIntents - private import semmle.code.java.security.JexlInjectionSinkModels private import semmle.code.java.security.JndiInjection private import semmle.code.java.security.LdapInjection private import semmle.code.java.security.MvelInjection @@ -148,16 +122,10 @@ private module Frameworks { private import semmle.code.java.security.XPath private import semmle.code.java.security.XsltInjection private import semmle.code.java.frameworks.Jdbc - private import semmle.code.java.frameworks.Jdbi - private import semmle.code.java.frameworks.HikariCP private import semmle.code.java.frameworks.SpringJdbc private import semmle.code.java.frameworks.MyBatis private import semmle.code.java.frameworks.Hibernate private import semmle.code.java.frameworks.jOOQ - private import semmle.code.java.frameworks.JMS - private import semmle.code.java.frameworks.RabbitMQ - private import semmle.code.java.regex.RegexFlowModels - private import semmle.code.java.frameworks.kotlin.StdLib } /** @@ -216,226 +184,6 @@ private class NegativeSummaryModelCsvInternal extends Unit { abstract predicate row(string row); } -private class SourceModelCsvBase extends SourceModelCsv { - override predicate row(string row) { - row = - [ - // org.springframework.security.web.savedrequest.SavedRequest - "org.springframework.security.web.savedrequest;SavedRequest;true;getRedirectUrl;;;ReturnValue;remote;manual", - "org.springframework.security.web.savedrequest;SavedRequest;true;getCookies;;;ReturnValue;remote;manual", - "org.springframework.security.web.savedrequest;SavedRequest;true;getHeaderValues;;;ReturnValue;remote;manual", - "org.springframework.security.web.savedrequest;SavedRequest;true;getHeaderNames;;;ReturnValue;remote;manual", - "org.springframework.security.web.savedrequest;SavedRequest;true;getParameterValues;;;ReturnValue;remote;manual", - "org.springframework.security.web.savedrequest;SavedRequest;true;getParameterMap;;;ReturnValue;remote;manual", - // ServletRequestGetParameterMethod - "javax.servlet;ServletRequest;false;getParameter;(String);;ReturnValue;remote;manual", - "javax.servlet;ServletRequest;false;getParameterValues;(String);;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getParameter;(String);;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getParameterValues;(String);;ReturnValue;remote;manual", - // ServletRequestGetParameterMapMethod - "javax.servlet;ServletRequest;false;getParameterMap;();;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getParameterMap;();;ReturnValue;remote;manual", - // ServletRequestGetParameterNamesMethod - "javax.servlet;ServletRequest;false;getParameterNames;();;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getParameterNames;();;ReturnValue;remote;manual", - // HttpServletRequestGetQueryStringMethod - "javax.servlet.http;HttpServletRequest;false;getQueryString;();;ReturnValue;remote;manual", - // - // URLConnectionGetInputStreamMethod - "java.net;URLConnection;false;getInputStream;();;ReturnValue;remote;manual", - // SocketGetInputStreamMethod - "java.net;Socket;false;getInputStream;();;ReturnValue;remote;manual", - // BeanValidationSource - "javax.validation;ConstraintValidator;true;isValid;;;Parameter[0];remote;manual", - // SpringMultipartRequestSource - "org.springframework.web.multipart;MultipartRequest;true;getFile;(String);;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartRequest;true;getFileMap;();;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartRequest;true;getFileNames;();;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartRequest;true;getFiles;(String);;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartRequest;true;getMultiFileMap;();;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartRequest;true;getMultipartContentType;(String);;ReturnValue;remote;manual", - // SpringMultipartFileSource - "org.springframework.web.multipart;MultipartFile;true;getBytes;();;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartFile;true;getContentType;();;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartFile;true;getInputStream;();;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartFile;true;getName;();;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartFile;true;getOriginalFilename;();;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartFile;true;getResource;();;ReturnValue;remote;manual", - // HttpServletRequest.get* - "javax.servlet.http;HttpServletRequest;false;getHeader;(String);;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getHeaders;(String);;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getHeaderNames;();;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getPathInfo;();;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getRequestURI;();;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getRequestURL;();;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getRemoteUser;();;ReturnValue;remote;manual", - // SpringWebRequestGetMethod - "org.springframework.web.context.request;WebRequest;false;getDescription;;;ReturnValue;remote;manual", - "org.springframework.web.context.request;WebRequest;false;getHeader;;;ReturnValue;remote;manual", - "org.springframework.web.context.request;WebRequest;false;getHeaderNames;;;ReturnValue;remote;manual", - "org.springframework.web.context.request;WebRequest;false;getHeaderValues;;;ReturnValue;remote;manual", - "org.springframework.web.context.request;WebRequest;false;getParameter;;;ReturnValue;remote;manual", - "org.springframework.web.context.request;WebRequest;false;getParameterMap;;;ReturnValue;remote;manual", - "org.springframework.web.context.request;WebRequest;false;getParameterNames;;;ReturnValue;remote;manual", - "org.springframework.web.context.request;WebRequest;false;getParameterValues;;;ReturnValue;remote;manual", - // TODO consider org.springframework.web.context.request.WebRequest.getRemoteUser - // ServletRequestGetBodyMethod - "javax.servlet;ServletRequest;false;getInputStream;();;ReturnValue;remote;manual", - "javax.servlet;ServletRequest;false;getReader;();;ReturnValue;remote;manual", - // CookieGet* - "javax.servlet.http;Cookie;false;getValue;();;ReturnValue;remote;manual", - "javax.servlet.http;Cookie;false;getName;();;ReturnValue;remote;manual", - "javax.servlet.http;Cookie;false;getComment;();;ReturnValue;remote;manual", - // ApacheHttp* - "org.apache.http;HttpMessage;false;getParams;();;ReturnValue;remote;manual", - "org.apache.http;HttpEntity;false;getContent;();;ReturnValue;remote;manual", - // In the setting of Android we assume that XML has been transmitted over - // the network, so may be tainted. - // XmlPullGetMethod - "org.xmlpull.v1;XmlPullParser;false;getName;();;ReturnValue;remote;manual", - "org.xmlpull.v1;XmlPullParser;false;getNamespace;();;ReturnValue;remote;manual", - "org.xmlpull.v1;XmlPullParser;false;getText;();;ReturnValue;remote;manual", - // XmlAttrSetGetMethod - "android.util;AttributeSet;false;getAttributeBooleanValue;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeCount;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeFloatValue;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeIntValue;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeListValue;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeName;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeNameResource;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeNamespace;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeResourceValue;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeUnsignedIntValue;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeValue;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getClassAttribute;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getIdAttribute;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getIdAttributeResourceValue;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getPositionDescription;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getStyleAttribute;;;ReturnValue;remote;manual", - // The current URL in a browser may be untrusted or uncontrolled. - // WebViewGetUrlMethod - "android.webkit;WebView;false;getUrl;();;ReturnValue;remote;manual", - "android.webkit;WebView;false;getOriginalUrl;();;ReturnValue;remote;manual", - // SpringRestTemplateResponseEntityMethod - "org.springframework.web.client;RestTemplate;false;exchange;;;ReturnValue;remote;manual", - "org.springframework.web.client;RestTemplate;false;getForEntity;;;ReturnValue;remote;manual", - "org.springframework.web.client;RestTemplate;false;postForEntity;;;ReturnValue;remote;manual", - // WebSocketMessageParameterSource - "java.net.http;WebSocket$Listener;true;onText;(WebSocket,CharSequence,boolean);;Parameter[1];remote;manual", - // PlayRequestGetMethod - "play.mvc;Http$RequestHeader;false;queryString;;;ReturnValue;remote;manual", - "play.mvc;Http$RequestHeader;false;getQueryString;;;ReturnValue;remote;manual", - "play.mvc;Http$RequestHeader;false;header;;;ReturnValue;remote;manual", - "play.mvc;Http$RequestHeader;false;getHeader;;;ReturnValue;remote;manual" - ] - } -} - -private class SinkModelCsvBase extends SinkModelCsv { - override predicate row(string row) { - row = - [ - // Open URL - "java.net;URL;false;openConnection;;;Argument[-1];open-url;manual", - "java.net;URL;false;openStream;;;Argument[-1];open-url;manual", - "java.net.http;HttpRequest;false;newBuilder;;;Argument[0];open-url;manual", - "java.net.http;HttpRequest$Builder;false;uri;;;Argument[0];open-url;manual", - "java.net;URLClassLoader;false;URLClassLoader;(URL[]);;Argument[0];open-url;manual", - "java.net;URLClassLoader;false;URLClassLoader;(URL[],ClassLoader);;Argument[0];open-url;manual", - "java.net;URLClassLoader;false;URLClassLoader;(URL[],ClassLoader,URLStreamHandlerFactory);;Argument[0];open-url;manual", - "java.net;URLClassLoader;false;URLClassLoader;(String,URL[],ClassLoader);;Argument[1];open-url;manual", - "java.net;URLClassLoader;false;URLClassLoader;(String,URL[],ClassLoader,URLStreamHandlerFactory);;Argument[1];open-url;manual", - "java.net;URLClassLoader;false;newInstance;;;Argument[0];open-url;manual", - // Bean validation - "javax.validation;ConstraintValidatorContext;true;buildConstraintViolationWithTemplate;;;Argument[0];bean-validation;manual", - // Set hostname - "javax.net.ssl;HttpsURLConnection;true;setDefaultHostnameVerifier;;;Argument[0];set-hostname-verifier;manual", - "javax.net.ssl;HttpsURLConnection;true;setHostnameVerifier;;;Argument[0];set-hostname-verifier;manual" - ] - } -} - -private class SummaryModelCsvBase extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - // qualifier to arg - "java.io;InputStream;true;read;(byte[]);;Argument[-1];Argument[0];taint;manual", - "java.io;InputStream;true;read;(byte[],int,int);;Argument[-1];Argument[0];taint;manual", - "java.io;InputStream;true;readNBytes;(byte[],int,int);;Argument[-1];Argument[0];taint;manual", - "java.io;InputStream;true;transferTo;(OutputStream);;Argument[-1];Argument[0];taint;manual", - "java.io;ByteArrayOutputStream;false;writeTo;;;Argument[-1];Argument[0];taint;manual", - "java.io;Reader;true;read;;;Argument[-1];Argument[0];taint;manual", - // qualifier to return - "java.io;ByteArrayOutputStream;false;toByteArray;;;Argument[-1];ReturnValue;taint;manual", - "java.io;ByteArrayOutputStream;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "java.io;InputStream;true;readAllBytes;;;Argument[-1];ReturnValue;taint;manual", - "java.io;InputStream;true;readNBytes;(int);;Argument[-1];ReturnValue;taint;manual", - "java.util;StringTokenizer;false;nextElement;();;Argument[-1];ReturnValue;taint;manual", - "java.util;StringTokenizer;false;nextToken;;;Argument[-1];ReturnValue;taint;manual", - "javax.xml.transform.sax;SAXSource;false;getInputSource;;;Argument[-1];ReturnValue;taint;manual", - "javax.xml.transform.stream;StreamSource;false;getInputStream;;;Argument[-1];ReturnValue;taint;manual", - "java.nio;ByteBuffer;false;get;;;Argument[-1];ReturnValue;taint;manual", - "java.net;URI;false;toURL;;;Argument[-1];ReturnValue;taint;manual", - "java.net;URI;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "java.net;URI;false;toAsciiString;;;Argument[-1];ReturnValue;taint;manual", - "java.nio;ByteBuffer;false;array;();;Argument[-1];ReturnValue;taint;manual", - "java.io;BufferedReader;true;readLine;;;Argument[-1];ReturnValue;taint;manual", - "java.io;Reader;true;read;();;Argument[-1];ReturnValue;taint;manual", - // arg to return - "java.nio;ByteBuffer;false;wrap;(byte[]);;Argument[0];ReturnValue;taint;manual", - "java.util;Base64$Encoder;false;encode;(byte[]);;Argument[0];ReturnValue;taint;manual", - "java.util;Base64$Encoder;false;encode;(ByteBuffer);;Argument[0];ReturnValue;taint;manual", - "java.util;Base64$Encoder;false;encodeToString;(byte[]);;Argument[0];ReturnValue;taint;manual", - "java.util;Base64$Encoder;false;wrap;(OutputStream);;Argument[0];ReturnValue;taint;manual", - "java.util;Base64$Decoder;false;decode;(byte[]);;Argument[0];ReturnValue;taint;manual", - "java.util;Base64$Decoder;false;decode;(ByteBuffer);;Argument[0];ReturnValue;taint;manual", - "java.util;Base64$Decoder;false;decode;(String);;Argument[0];ReturnValue;taint;manual", - "java.util;Base64$Decoder;false;wrap;(InputStream);;Argument[0];ReturnValue;taint;manual", - "cn.hutool.core.codec;Base64;true;decode;;;Argument[0];ReturnValue;taint;manual", - "org.apache.shiro.codec;Base64;false;decode;(String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.codec;Encoder;true;encode;(Object);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.codec;Decoder;true;decode;(Object);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.codec;BinaryEncoder;true;encode;(byte[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.codec;BinaryDecoder;true;decode;(byte[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.codec;StringEncoder;true;encode;(String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.codec;StringDecoder;true;decode;(String);;Argument[0];ReturnValue;taint;manual", - "java.net;URLDecoder;false;decode;;;Argument[0];ReturnValue;taint;manual", - "java.net;URI;false;create;;;Argument[0];ReturnValue;taint;manual", - "javax.xml.transform.sax;SAXSource;false;sourceToInputSource;;;Argument[0];ReturnValue;taint;manual", - // arg to arg - "java.lang;System;false;arraycopy;;;Argument[0];Argument[2];taint;manual", - // constructor flow - "java.net;URI;false;URI;(String);;Argument[0];Argument[-1];taint;manual", - "java.net;URL;false;URL;(String);;Argument[0];Argument[-1];taint;manual", - "javax.xml.transform.stream;StreamSource;false;StreamSource;;;Argument[0];Argument[-1];taint;manual", - "javax.xml.transform.sax;SAXSource;false;SAXSource;(InputSource);;Argument[0];Argument[-1];taint;manual", - "javax.xml.transform.sax;SAXSource;false;SAXSource;(XMLReader,InputSource);;Argument[1];Argument[-1];taint;manual", - "org.xml.sax;InputSource;false;InputSource;;;Argument[0];Argument[-1];taint;manual", - "javax.servlet.http;Cookie;false;Cookie;;;Argument[0];Argument[-1];taint;manual", - "javax.servlet.http;Cookie;false;Cookie;;;Argument[1];Argument[-1];taint;manual", - "java.util.zip;ZipInputStream;false;ZipInputStream;;;Argument[0];Argument[-1];taint;manual", - "java.util.zip;GZIPInputStream;false;GZIPInputStream;;;Argument[0];Argument[-1];taint;manual", - "java.util;StringTokenizer;false;StringTokenizer;;;Argument[0];Argument[-1];taint;manual", - "java.beans;XMLDecoder;false;XMLDecoder;;;Argument[0];Argument[-1];taint;manual", - "com.esotericsoftware.kryo.io;Input;false;Input;;;Argument[0];Argument[-1];taint;manual", - "com.esotericsoftware.kryo5.io;Input;false;Input;;;Argument[0];Argument[-1];taint;manual", - "java.io;BufferedInputStream;false;BufferedInputStream;;;Argument[0];Argument[-1];taint;manual", - "java.io;DataInputStream;false;DataInputStream;;;Argument[0];Argument[-1];taint;manual", - "java.io;ByteArrayInputStream;false;ByteArrayInputStream;;;Argument[0];Argument[-1];taint;manual", - "java.io;ObjectInputStream;false;ObjectInputStream;;;Argument[0];Argument[-1];taint;manual", - "java.io;StringReader;false;StringReader;;;Argument[0];Argument[-1];taint;manual", - "java.io;CharArrayReader;false;CharArrayReader;;;Argument[0];Argument[-1];taint;manual", - "java.io;BufferedReader;false;BufferedReader;;;Argument[0];Argument[-1];taint;manual", - "java.io;InputStreamReader;false;InputStreamReader;;;Argument[0];Argument[-1];taint;manual", - "java.io;OutputStream;true;write;(byte[]);;Argument[0];Argument[-1];taint;manual", - "java.io;OutputStream;true;write;(byte[],int,int);;Argument[0];Argument[-1];taint;manual", - "java.io;OutputStream;true;write;(int);;Argument[0];Argument[-1];taint;manual", - "java.io;FilterOutputStream;true;FilterOutputStream;(OutputStream);;Argument[0];Argument[-1];taint;manual" - ] - } -} - private predicate sourceModelInternal(string row) { any(SourceModelCsvInternal s).row(row) } private predicate summaryModelInternal(string row) { any(SummaryModelCsvInternal s).row(row) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll b/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll index aebe509816f..19f11842d14 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll @@ -91,355 +91,6 @@ class ContainerType extends RefType { } } -private class ContainerFlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "java.lang;Object;true;clone;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.lang;Object;true;clone;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.lang;Object;true;clone;;;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Map$Entry;true;getKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - "java.util;Map$Entry;true;getValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map$Entry;true;setValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map$Entry;true;setValue;;;Argument[0];Argument[-1].MapValue;value;manual", - "java.lang;Iterable;true;iterator;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.lang;Iterable;true;spliterator;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.lang;Iterable;true;forEach;(Consumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util;Iterator;true;next;;;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Iterator;true;forEachRemaining;(Consumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util;ListIterator;true;previous;;;Argument[-1].Element;ReturnValue;value;manual", - "java.util;ListIterator;true;add;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;ListIterator;true;set;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Enumeration;true;asIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Enumeration;true;nextElement;;;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Map;true;computeIfAbsent;;;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map;true;computeIfAbsent;;;Argument[1].ReturnValue;ReturnValue;value;manual", - "java.util;Map;true;computeIfAbsent;;;Argument[1].ReturnValue;Argument[-1].MapValue;value;manual", - "java.util;Map;true;entrySet;;;Argument[-1].MapValue;ReturnValue.Element.MapValue;value;manual", - "java.util;Map;true;entrySet;;;Argument[-1].MapKey;ReturnValue.Element.MapKey;value;manual", - "java.util;Map;true;get;;;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map;true;getOrDefault;;;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map;true;getOrDefault;;;Argument[1];ReturnValue;value;manual", - "java.util;Map;true;put;(Object,Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map;true;put;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "java.util;Map;true;put;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "java.util;Map;true;putIfAbsent;;;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map;true;putIfAbsent;;;Argument[0];Argument[-1].MapKey;value;manual", - "java.util;Map;true;putIfAbsent;;;Argument[1];Argument[-1].MapValue;value;manual", - "java.util;Map;true;remove;(Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map;true;replace;(Object,Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map;true;replace;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "java.util;Map;true;replace;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "java.util;Map;true;replace;(Object,Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "java.util;Map;true;replace;(Object,Object,Object);;Argument[2];Argument[-1].MapValue;value;manual", - "java.util;Map;true;keySet;();;Argument[-1].MapKey;ReturnValue.Element;value;manual", - "java.util;Map;true;values;();;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "java.util;Map;true;merge;(Object,Object,BiFunction);;Argument[1];Argument[-1].MapValue;value;manual", - "java.util;Map;true;putAll;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;Map;true;putAll;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;Map;true;forEach;(BiConsumer);;Argument[-1].MapKey;Argument[0].Parameter[0];value;manual", - "java.util;Map;true;forEach;(BiConsumer);;Argument[-1].MapValue;Argument[0].Parameter[1];value;manual", - "java.util;Collection;true;parallelStream;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Collection;true;stream;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Collection;true;toArray;;;Argument[-1].Element;ReturnValue.ArrayElement;value;manual", - "java.util;Collection;true;toArray;;;Argument[-1].Element;Argument[0].ArrayElement;value;manual", - "java.util;Collection;true;add;;;Argument[0];Argument[-1].Element;value;manual", - "java.util;Collection;true;addAll;;;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;List;true;get;(int);;Argument[-1].Element;ReturnValue;value;manual", - "java.util;List;true;listIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;List;true;remove;(int);;Argument[-1].Element;ReturnValue;value;manual", - "java.util;List;true;set;(int,Object);;Argument[-1].Element;ReturnValue;value;manual", - "java.util;List;true;set;(int,Object);;Argument[1];Argument[-1].Element;value;manual", - "java.util;List;true;subList;;;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;List;true;add;(int,Object);;Argument[1];Argument[-1].Element;value;manual", - "java.util;List;true;addAll;(int,Collection);;Argument[1].Element;Argument[-1].Element;value;manual", - "java.util;Vector;true;elementAt;(int);;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Vector;true;elements;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Vector;true;firstElement;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Vector;true;lastElement;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Vector;true;addElement;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Vector;true;insertElementAt;(Object,int);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Vector;true;setElementAt;(Object,int);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Vector;true;copyInto;(Object[]);;Argument[-1].Element;Argument[0].ArrayElement;value;manual", - "java.util;Stack;true;peek;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Stack;true;pop;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Stack;true;push;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Queue;true;element;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Queue;true;peek;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Queue;true;poll;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Queue;true;remove;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Queue;true;offer;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Deque;true;descendingIterator;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Deque;true;getFirst;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;getLast;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;peekFirst;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;peekLast;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;pollFirst;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;pollLast;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;pop;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;removeFirst;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;removeLast;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;push;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Deque;true;offerLast;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Deque;true;offerFirst;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Deque;true;addLast;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Deque;true;addFirst;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;BlockingDeque;true;pollFirst;(long,TimeUnit);;Argument[-1].Element;ReturnValue;value;manual", - "java.util.concurrent;BlockingDeque;true;pollLast;(long,TimeUnit);;Argument[-1].Element;ReturnValue;value;manual", - "java.util.concurrent;BlockingDeque;true;takeFirst;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util.concurrent;BlockingDeque;true;takeLast;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util.concurrent;BlockingQueue;true;poll;(long,TimeUnit);;Argument[-1].Element;ReturnValue;value;manual", - "java.util.concurrent;BlockingQueue;true;take;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util.concurrent;BlockingQueue;true;offer;(Object,long,TimeUnit);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;BlockingQueue;true;put;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;BlockingDeque;true;offerLast;(Object,long,TimeUnit);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;BlockingDeque;true;offerFirst;(Object,long,TimeUnit);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;BlockingDeque;true;putLast;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;BlockingDeque;true;putFirst;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;BlockingQueue;true;drainTo;(Collection,int);;Argument[-1].Element;Argument[0].Element;value;manual", - "java.util.concurrent;BlockingQueue;true;drainTo;(Collection);;Argument[-1].Element;Argument[0].Element;value;manual", - "java.util.concurrent;ConcurrentHashMap;true;elements;();;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "java.util;Dictionary;true;elements;();;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "java.util;Dictionary;true;get;(Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Dictionary;true;keys;();;Argument[-1].MapKey;ReturnValue.Element;value;manual", - "java.util;Dictionary;true;put;(Object,Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Dictionary;true;put;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "java.util;Dictionary;true;put;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "java.util;Dictionary;true;remove;(Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;NavigableMap;true;ceilingEntry;(Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;ceilingEntry;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;descendingMap;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;descendingMap;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;firstEntry;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;firstEntry;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;floorEntry;(Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;floorEntry;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;headMap;(Object,boolean);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;headMap;(Object,boolean);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;higherEntry;(Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;higherEntry;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;lastEntry;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;lastEntry;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;lowerEntry;(Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;lowerEntry;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;pollFirstEntry;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;pollFirstEntry;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;pollLastEntry;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;pollLastEntry;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;subMap;(Object,boolean,Object,boolean);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;subMap;(Object,boolean,Object,boolean);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;tailMap;(Object,boolean);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;tailMap;(Object,boolean);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableSet;true;ceiling;(Object);;Argument[-1].Element;ReturnValue;value;manual", - "java.util;NavigableSet;true;descendingIterator;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;NavigableSet;true;descendingSet;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;NavigableSet;true;floor;(Object);;Argument[-1].Element;ReturnValue;value;manual", - "java.util;NavigableSet;true;headSet;(Object,boolean);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;NavigableSet;true;higher;(Object);;Argument[-1].Element;ReturnValue;value;manual", - "java.util;NavigableSet;true;lower;(Object);;Argument[-1].Element;ReturnValue;value;manual", - "java.util;NavigableSet;true;pollFirst;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;NavigableSet;true;pollLast;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;NavigableSet;true;subSet;(Object,boolean,Object,boolean);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;NavigableSet;true;tailSet;(Object,boolean);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Properties;true;getProperty;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Properties;true;getProperty;(String,String);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Properties;true;getProperty;(String,String);;Argument[1];ReturnValue;value;manual", - "java.util;Properties;true;setProperty;(String,String);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Properties;true;setProperty;(String,String);;Argument[0];Argument[-1].MapKey;value;manual", - "java.util;Properties;true;setProperty;(String,String);;Argument[1];Argument[-1].MapValue;value;manual", - "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual", - "java.util;Scanner;true;findInLine;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;findWithinHorizon;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;next;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextBigDecimal;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextBigInteger;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextBoolean;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextByte;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextDouble;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextFloat;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextInt;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextLine;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextLong;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextShort;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;reset;;;Argument[-1];ReturnValue;value;manual", - "java.util;Scanner;true;skip;;;Argument[-1];ReturnValue;value;manual", - "java.util;Scanner;true;useDelimiter;;;Argument[-1];ReturnValue;value;manual", - "java.util;Scanner;true;useLocale;;;Argument[-1];ReturnValue;value;manual", - "java.util;Scanner;true;useRadix;;;Argument[-1];ReturnValue;value;manual", - "java.util;SortedMap;true;headMap;(Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;SortedMap;true;headMap;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;SortedMap;true;subMap;(Object,Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;SortedMap;true;subMap;(Object,Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;SortedMap;true;tailMap;(Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;SortedMap;true;tailMap;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;SortedSet;true;first;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;SortedSet;true;headSet;(Object);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;SortedSet;true;last;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;SortedSet;true;subSet;(Object,Object);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;SortedSet;true;tailSet;(Object);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.concurrent;TransferQueue;true;tryTransfer;(Object,long,TimeUnit);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;TransferQueue;true;transfer;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;TransferQueue;true;tryTransfer;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;List;false;copyOf;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object);;Argument[0];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object);;Argument[0..1];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object,Object);;Argument[0..2];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object,Object,Object);;Argument[0..3];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object,Object,Object,Object);;Argument[0..4];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object,Object,Object,Object,Object);;Argument[0..5];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[0..6];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..8];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];ReturnValue.Element;value;manual", - "java.util;Map;false;copyOf;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Map;false;copyOf;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Map;false;entry;(Object,Object);;Argument[0];ReturnValue.MapKey;value;manual", - "java.util;Map;false;entry;(Object,Object);;Argument[1];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[0];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[1];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[2];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[3];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[4];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[5];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[6];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[7];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[8];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[9];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[10];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[11];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[12];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[13];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[14];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[15];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[16];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[17];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[18];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[19];ReturnValue.MapValue;value;manual", - "java.util;Map;false;ofEntries;;;Argument[0].ArrayElement.MapKey;ReturnValue.MapKey;value;manual", - "java.util;Map;false;ofEntries;;;Argument[0].ArrayElement.MapValue;ReturnValue.MapValue;value;manual", - "java.util;Set;false;copyOf;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object);;Argument[0];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object);;Argument[0..1];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object,Object);;Argument[0..2];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object,Object,Object);;Argument[0..3];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object,Object,Object,Object);;Argument[0..4];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object);;Argument[0..5];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[0..6];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..8];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];ReturnValue.Element;value;manual", - "java.util;Arrays;false;stream;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "java.util;Arrays;false;spliterator;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "java.util;Arrays;false;copyOfRange;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "java.util;Arrays;false;copyOf;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "java.util;Collections;false;list;(Enumeration);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;enumeration;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;nCopies;(int,Object);;Argument[1];ReturnValue.Element;value;manual", - "java.util;Collections;false;singletonMap;(Object,Object);;Argument[0];ReturnValue.MapKey;value;manual", - "java.util;Collections;false;singletonMap;(Object,Object);;Argument[1];ReturnValue.MapValue;value;manual", - "java.util;Collections;false;singletonList;(Object);;Argument[0];ReturnValue.Element;value;manual", - "java.util;Collections;false;singleton;(Object);;Argument[0];ReturnValue.Element;value;manual", - "java.util;Collections;false;checkedNavigableMap;(NavigableMap,Class,Class);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;checkedNavigableMap;(NavigableMap,Class,Class);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;checkedSortedMap;(SortedMap,Class,Class);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;checkedSortedMap;(SortedMap,Class,Class);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;checkedMap;(Map,Class,Class);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;checkedMap;(Map,Class,Class);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;checkedList;(List,Class);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;checkedNavigableSet;(NavigableSet,Class);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;checkedSortedSet;(SortedSet,Class);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;checkedSet;(Set,Class);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;checkedCollection;(Collection,Class);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;synchronizedNavigableMap;(NavigableMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;synchronizedNavigableMap;(NavigableMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;synchronizedSortedMap;(SortedMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;synchronizedSortedMap;(SortedMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;synchronizedMap;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;synchronizedMap;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;synchronizedList;(List);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;synchronizedNavigableSet;(NavigableSet);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;synchronizedSortedSet;(SortedSet);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;synchronizedSet;(Set);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;synchronizedCollection;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;unmodifiableNavigableMap;(NavigableMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;unmodifiableNavigableMap;(NavigableMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;unmodifiableSortedMap;(SortedMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;unmodifiableSortedMap;(SortedMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;unmodifiableMap;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;unmodifiableMap;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;unmodifiableList;(List);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;unmodifiableNavigableSet;(NavigableSet);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;unmodifiableSortedSet;(SortedSet);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;unmodifiableSet;(Set);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;unmodifiableCollection;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;max;;;Argument[0].Element;ReturnValue;value;manual", - "java.util;Collections;false;min;;;Argument[0].Element;ReturnValue;value;manual", - "java.util;Arrays;false;fill;(Object[],int,int,Object);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(Object[],Object);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(float[],int,int,float);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(float[],float);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(double[],int,int,double);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(double[],double);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(boolean[],int,int,boolean);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(boolean[],boolean);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(byte[],int,int,byte);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(byte[],byte);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(char[],int,int,char);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(char[],char);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(short[],int,int,short);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(short[],short);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(int[],int,int,int);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(int[],int);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(long[],int,int,long);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(long[],long);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Collections;false;replaceAll;(List,Object,Object);;Argument[2];Argument[0].Element;value;manual", - "java.util;Collections;false;copy;(List,List);;Argument[1].Element;Argument[0].Element;value;manual", - "java.util;Collections;false;fill;(List,Object);;Argument[1];Argument[0].Element;value;manual", - "java.util;Arrays;false;asList;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "java.util;Collections;false;addAll;(Collection,Object[]);;Argument[1].ArrayElement;Argument[0].Element;value;manual", - "java.util;AbstractMap$SimpleEntry;false;SimpleEntry;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "java.util;AbstractMap$SimpleEntry;false;SimpleEntry;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "java.util;AbstractMap$SimpleEntry;false;SimpleEntry;(Entry);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;AbstractMap$SimpleEntry;false;SimpleEntry;(Entry);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;AbstractMap$SimpleImmutableEntry;false;SimpleImmutableEntry;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "java.util;AbstractMap$SimpleImmutableEntry;false;SimpleImmutableEntry;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "java.util;AbstractMap$SimpleImmutableEntry;false;SimpleImmutableEntry;(Entry);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;AbstractMap$SimpleImmutableEntry;false;SimpleImmutableEntry;(Entry);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;ArrayDeque;false;ArrayDeque;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;ArrayList;false;ArrayList;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;EnumMap;false;EnumMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;EnumMap;false;EnumMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;EnumMap;false;EnumMap;(EnumMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;EnumMap;false;EnumMap;(EnumMap);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;HashMap;false;HashMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;HashMap;false;HashMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;HashSet;false;HashSet;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;Hashtable;false;Hashtable;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;Hashtable;false;Hashtable;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;IdentityHashMap;false;IdentityHashMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;IdentityHashMap;false;IdentityHashMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;LinkedHashMap;false;LinkedHashMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;LinkedHashMap;false;LinkedHashMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;LinkedHashSet;false;LinkedHashSet;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;LinkedList;false;LinkedList;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;PriorityQueue;false;PriorityQueue;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;PriorityQueue;false;PriorityQueue;(PriorityQueue);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;PriorityQueue;false;PriorityQueue;(SortedSet);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;TreeMap;false;TreeMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;TreeMap;false;TreeMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;TreeMap;false;TreeMap;(SortedMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;TreeMap;false;TreeMap;(SortedMap);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;TreeSet;false;TreeSet;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;TreeSet;false;TreeSet;(SortedSet);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;Vector;false;Vector;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;WeakHashMap;false;WeakHashMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;WeakHashMap;false;WeakHashMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual" - ] - } -} - private predicate taintPreservingQualifierToMethod(Method m) { // java.util.Map.Entry m.getDeclaringType() instanceof EntryType and diff --git a/java/ql/lib/semmle/code/java/frameworks/ApacheHttp.qll b/java/ql/lib/semmle/code/java/frameworks/ApacheHttp.qll index 8328a9dfbcb..8c77a050a9f 100644 --- a/java/ql/lib/semmle/code/java/frameworks/ApacheHttp.qll +++ b/java/ql/lib/semmle/code/java/frameworks/ApacheHttp.qll @@ -42,17 +42,6 @@ class TypeApacheHttpRequestBuilder extends Class { } } -private class ApacheHttpSource extends SourceModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.http.protocol;HttpRequestHandler;true;handle;(HttpRequest,HttpResponse,HttpContext);;Parameter[0];remote;manual", - "org.apache.hc.core5.http.io;HttpRequestHandler;true;handle;(ClassicHttpRequest,ClassicHttpResponse,HttpContext);;Parameter[0];remote;manual", - "org.apache.hc.core5.http.io;HttpServerRequestHandler;true;handle;(ClassicHttpRequest,ResponseTrigger,HttpContext);;Parameter[0];remote;manual" - ] - } -} - /** * A call that sets a header of an `HttpResponse`. */ @@ -80,191 +69,3 @@ class ApacheHttpSetHeader extends Call { /** Gets the expression used as the value of this header. */ Expr getValue() { result = this.getArgument(1) } } - -private class ApacheHttpXssSink extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.http;HttpResponse;true;setEntity;(HttpEntity);;Argument[0];xss;manual", - "org.apache.http.util;EntityUtils;true;updateEntity;(HttpResponse,HttpEntity);;Argument[1];xss;manual", - "org.apache.hc.core5.http;HttpEntityContainer;true;setEntity;(HttpEntity);;Argument[0];xss;manual" - ] - } -} - -private class ApacheHttpOpenUrlSink extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.http;HttpRequest;true;setURI;;;Argument[0];open-url;manual", - "org.apache.http.message;BasicHttpRequest;false;BasicHttpRequest;(RequestLine);;Argument[0];open-url;manual", - "org.apache.http.message;BasicHttpRequest;false;BasicHttpRequest;(String,String);;Argument[1];open-url;manual", - "org.apache.http.message;BasicHttpRequest;false;BasicHttpRequest;(String,String,ProtocolVersion);;Argument[1];open-url;manual", - "org.apache.http.message;BasicHttpEntityEnclosingRequest;false;BasicHttpEntityEnclosingRequest;(RequestLine);;Argument[0];open-url;manual", - "org.apache.http.message;BasicHttpEntityEnclosingRequest;false;BasicHttpEntityEnclosingRequest;(String,String);;Argument[1];open-url;manual", - "org.apache.http.message;BasicHttpEntityEnclosingRequest;false;BasicHttpEntityEnclosingRequest;(String,String,ProtocolVersion);;Argument[1];open-url;manual", - "org.apache.http.client.methods;HttpGet;false;HttpGet;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;HttpHead;false;HttpHead;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;HttpPut;false;HttpPut;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;HttpPost;false;HttpPost;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;HttpDelete;false;HttpDelete;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;HttpOptions;false;HttpOptions;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;HttpTrace;false;HttpTrace;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;HttpPatch;false;HttpPatch;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;HttpRequestBase;true;setURI;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;setUri;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;get;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;post;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;put;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;options;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;head;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;delete;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;trace;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;patch;;;Argument[0];open-url;manual" - ] - } -} - -private class ApacheHttpFlowStep extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.http;HttpMessage;true;getAllHeaders;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpMessage;true;getFirstHeader;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpMessage;true;getLastHeader;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpMessage;true;getHeaders;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpMessage;true;getParams;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpMessage;true;headerIterator;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpMessage;true;headerIterator;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpRequest;true;getRequestLine;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpEntityEnclosingRequest;true;getEntity;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;Header;true;getElements;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HeaderElement;true;getName;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HeaderElement;true;getValue;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HeaderElement;true;getParameter;(int);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HeaderElement;true;getParameterByName;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HeaderElement;true;getParameters;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;NameValuePair;true;getName;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;NameValuePair;true;getValue;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HeaderIterator;true;nextHeader;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpEntity;true;getContent;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpEntity;true;getContentEncoding;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpEntity;true;getContentType;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;RequestLine;true;getMethod;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;RequestLine;true;getUri;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.params;HttpParams;true;getParameter;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.params;HttpParams;true;getDoubleParameter;(String,double);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.params;HttpParams;true;getIntParameter;(String,int);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.params;HttpParams;true;getLongParameter;(String,long);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.params;HttpParams;true;getDoubleParameter;(String,double);;Argument[1];ReturnValue;value;manual", - "org.apache.http.params;HttpParams;true;getIntParameter;(String,int);;Argument[1];ReturnValue;value;manual", - "org.apache.http.params;HttpParams;true;getLongParameter;(String,long);;Argument[1];ReturnValue;value;manual", - "org.apache.hc.core5.http;MessageHeaders;true;getFirstHeader;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;MessageHeaders;true;getLastHeader;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;MessageHeaders;true;getHeader;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;MessageHeaders;true;getHeaders;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;MessageHeaders;true;getHeaders;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;MessageHeaders;true;headerIterator;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;MessageHeaders;true;headerIterator;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;HttpRequest;true;getAuthority;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;HttpRequest;true;getMethod;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;HttpRequest;true;getPath;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;HttpRequest;true;getUri;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;HttpRequest;true;getRequestUri;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;HttpEntityContainer;true;getEntity;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;NameValuePair;true;getName;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;NameValuePair;true;getValue;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;HttpEntity;true;getContent;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;HttpEntity;true;getTrailers;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;EntityDetails;true;getContentType;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;EntityDetails;true;getContentEncoding;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;EntityDetails;true;getTrailerNames;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http.message;RequestLine;true;getMethod;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http.message;RequestLine;true;getUri;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http.message;RequestLine;true;toString;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http.message;RequestLine;true;RequestLine;(HttpRequest);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.http.message;RequestLine;true;RequestLine;(String,String,ProtocolVersion);;Argument[1];Argument[-1];taint;manual", - "org.apache.hc.core5.function;Supplier;true;get;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.net;URIAuthority;true;getHostName;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.net;URIAuthority;true;toString;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.util;EntityUtils;true;toString;;;Argument[0];ReturnValue;taint;manual", - "org.apache.http.util;EntityUtils;true;toByteArray;(HttpEntity);;Argument[0];ReturnValue;taint;manual", - "org.apache.http.util;EntityUtils;true;getContentCharSet;(HttpEntity);;Argument[0];ReturnValue;taint;manual", - "org.apache.http.util;EntityUtils;true;getContentMimeType;(HttpEntity);;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;EntityUtils;true;toString;;;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;EntityUtils;true;toByteArray;;;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;EntityUtils;true;parse;;;Argument[0];ReturnValue;taint;manual", - "org.apache.http.util;EncodingUtils;true;getAsciiBytes;(String);;Argument[0];ReturnValue;taint;manual", - "org.apache.http.util;EncodingUtils;true;getAsciiString;;;Argument[0];ReturnValue;taint;manual", - "org.apache.http.util;EncodingUtils;true;getBytes;(String,String);;Argument[0];ReturnValue;taint;manual", - "org.apache.http.util;EncodingUtils;true;getString;;;Argument[0];ReturnValue;taint;manual", - "org.apache.http.util;Args;true;containsNoBlanks;(CharSequence,String);;Argument[0];ReturnValue;value;manual", - "org.apache.http.util;Args;true;notNull;(Object,String);;Argument[0];ReturnValue;value;manual", - "org.apache.http.util;Args;true;notEmpty;(CharSequence,String);;Argument[0];ReturnValue;value;manual", - "org.apache.http.util;Args;true;notEmpty;(Collection,String);;Argument[0];ReturnValue;value;manual", - "org.apache.http.util;Args;true;notBlank;(CharSequence,String);;Argument[0];ReturnValue;value;manual", - "org.apache.hc.core5.util;Args;true;containsNoBlanks;(CharSequence,String);;Argument[0];ReturnValue;value;manual", - "org.apache.hc.core5.util;Args;true;notNull;(Object,String);;Argument[0];ReturnValue;value;manual", - "org.apache.hc.core5.util;Args;true;notEmpty;(Collection,String);;Argument[0];ReturnValue;value;manual", - "org.apache.hc.core5.util;Args;true;notEmpty;(CharSequence,String);;Argument[0];ReturnValue;value;manual", - "org.apache.hc.core5.util;Args;true;notEmpty;(Object,String);;Argument[0];ReturnValue;value;manual", - "org.apache.hc.core5.util;Args;true;notBlank;(CharSequence,String);;Argument[0];ReturnValue;value;manual", - "org.apache.hc.core5.http.io.entity;HttpEntities;true;create;;;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;HttpEntities;true;createGzipped;;;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;HttpEntities;true;createUrlEncoded;;;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;HttpEntities;true;gzip;(HttpEntity);;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;HttpEntities;true;withTrailers;;;Argument[0];ReturnValue;taint;manual", - "org.apache.http.entity;BasicHttpEntity;true;setContent;(InputStream);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.entity;BufferedHttpEntity;true;BufferedHttpEntity;(HttpEntity);;Argument[0];ReturnValue;taint;manual", - "org.apache.http.entity;ByteArrayEntity;true;ByteArrayEntity;;;Argument[0];Argument[-1];taint;manual", - "org.apache.http.entity;HttpEntityWrapper;true;HttpEntityWrapper;(HttpEntity);;Argument[0];ReturnValue;taint;manual", - "org.apache.http.entity;InputStreamEntity;true;InputStreamEntity;;;Argument[0];ReturnValue;taint;manual", - "org.apache.http.entity;StringEntity;true;StringEntity;;;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.http.io.entity;BasicHttpEntity;true;BasicHttpEntity;;;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;BufferedHttpEntity;true;BufferedHttpEntity;(HttpEntity);;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;ByteArrayEntity;true;ByteArrayEntity;;;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.http.io.entity;HttpEntityWrapper;true;HttpEntityWrapper;(HttpEntity);;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;InputStreamEntity;true;InputStreamEntity;;;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;StringEntity;true;StringEntity;;;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;ByteArrayBuffer;true;append;(byte[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;ByteArrayBuffer;true;append;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;ByteArrayBuffer;true;append;(CharArrayBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;ByteArrayBuffer;true;buffer;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.util;ByteArrayBuffer;true;toByteArray;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.util;CharArrayBuffer;true;append;(byte[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;CharArrayBuffer;true;append;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;CharArrayBuffer;true;append;(CharArrayBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;CharArrayBuffer;true;append;(ByteArrayBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;CharArrayBuffer;true;append;(CharArrayBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;CharArrayBuffer;true;append;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;CharArrayBuffer;true;append;(Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;CharArrayBuffer;true;buffer;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.util;CharArrayBuffer;true;toCharArray;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.util;CharArrayBuffer;true;toString;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.util;CharArrayBuffer;true;substring;(int,int);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.util;CharArrayBuffer;true;subSequence;(int,int);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.util;CharArrayBuffer;true;substringTrimmed;(int,int);;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.util;ByteArrayBuffer;true;append;(byte[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;ByteArrayBuffer;true;append;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;ByteArrayBuffer;true;append;(CharArrayBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;ByteArrayBuffer;true;array;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.util;ByteArrayBuffer;true;toByteArray;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;append;(byte[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;append;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;append;(CharArrayBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;append;(ByteArrayBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;append;(CharArrayBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;append;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;append;(Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;array;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;toCharArray;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;toString;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;substring;(int,int);;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;subSequence;(int,int);;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;substringTrimmed;(int,int);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.message;BasicRequestLine;false;BasicRequestLine;;;Argument[1];Argument[-1];taint;manual", - "org.apache.http;RequestLine;true;getUri;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;RequestLine;true;toString;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Flexjson.qll b/java/ql/lib/semmle/code/java/frameworks/Flexjson.qll index 615d928a709..e0f04da2954 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Flexjson.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Flexjson.qll @@ -33,9 +33,3 @@ class FlexjsonDeserializerUseMethod extends Method { this.hasName("use") } } - -private class FluentUseMethodModel extends SummaryModelCsv { - override predicate row(string r) { - r = "flexjson;JSONDeserializer;true;use;;;Argument[-1];ReturnValue;value;manual" - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Hibernate.qll b/java/ql/lib/semmle/code/java/frameworks/Hibernate.qll index 4832576b7b9..dcb72cd9722 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Hibernate.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Hibernate.qll @@ -21,19 +21,3 @@ class HibernateSharedSessionContract extends RefType { class HibernateSession extends RefType { HibernateSession() { this.hasQualifiedName("org.hibernate", "Session") } } - -private class SqlSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "org.hibernate;QueryProducer;true;createQuery;;;Argument[0];sql;manual", - "org.hibernate;QueryProducer;true;createNativeQuery;;;Argument[0];sql;manual", - "org.hibernate;QueryProducer;true;createSQLQuery;;;Argument[0];sql;manual", - "org.hibernate;SharedSessionContract;true;createQuery;;;Argument[0];sql;manual", - "org.hibernate;SharedSessionContract;true;createSQLQuery;;;Argument[0];sql;manual", - "org.hibernate;Session;true;createQuery;;;Argument[0];sql;manual", - "org.hibernate;Session;true;createSQLQuery;;;Argument[0];sql;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/HikariCP.qll b/java/ql/lib/semmle/code/java/frameworks/HikariCP.qll deleted file mode 100644 index 05f764b357b..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/HikariCP.qll +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Definitions of sinks in the Hikari Connection Pool library. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class SsrfSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "com.zaxxer.hikari;HikariConfig;false;HikariConfig;(Properties);;Argument[0];jdbc-url;manual", - "com.zaxxer.hikari;HikariConfig;false;setJdbcUrl;(String);;Argument[0];jdbc-url;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/JMS.qll b/java/ql/lib/semmle/code/java/frameworks/JMS.qll deleted file mode 100644 index f1eb0ace982..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/JMS.qll +++ /dev/null @@ -1,112 +0,0 @@ -/** - * This model covers JMS API versions 1 and 2. - * - * https://docs.oracle.com/javaee/6/api/javax/jms/package-summary.html - * https://docs.oracle.com/javaee/7/api/javax/jms/package-summary.html - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -/** Defines sources of tainted data in JMS 1. */ -private class Jms1Source extends SourceModelCsv { - override predicate row(string row) { - row = - [ - // incoming messages are considered tainted - "javax.jms;MessageListener;true;onMessage;(Message);;Parameter[0];remote;manual", - "javax.jms;MessageConsumer;true;receive;;;ReturnValue;remote;manual", - "javax.jms;MessageConsumer;true;receiveNoWait;();;ReturnValue;remote;manual", - "javax.jms;QueueRequestor;true;request;(Message);;ReturnValue;remote;manual", - "javax.jms;TopicRequestor;true;request;(Message);;ReturnValue;remote;manual", - ] - } -} - -/** Defines taint propagation steps in JMS 1. */ -private class Jms1FlowStep extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - // if a message is tainted, then it returns tainted data - "javax.jms;Message;true;getBody;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getJMSCorrelationIDAsBytes;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getJMSCorrelationID;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getJMSReplyTo;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getJMSDestination;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getJMSType;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getBooleanProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getByteProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getShortProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getIntProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getLongProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getFloatProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getDoubleProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getStringProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getObjectProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getPropertyNames;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readBoolean;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readByte;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readUnsignedByte;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readShort;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readUnsignedShort;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readChar;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readInt;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readLong;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readFloat;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readDouble;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readUTF;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readBytes;;;Argument[-1];Argument[0];taint;manual", - "javax.jms;MapMessage;true;getBoolean;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getByte;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getShort;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getChar;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getInt;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getLong;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getFloat;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getDouble;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getString;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getBytes;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getObject;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getMapNames;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;ObjectMessage;true;getObject;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readBoolean;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readByte;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readShort;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readChar;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readInt;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readLong;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readFloat;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readDouble;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readString;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readBytes;(byte[]);;Argument[-1];Argument[0];taint;manual", - "javax.jms;StreamMessage;true;readObject;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;TextMessage;true;getText;();;Argument[-1];ReturnValue;taint;manual", - // if a destination is tainted, then it returns tainted data - "javax.jms;Queue;true;getQueueName;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Queue;true;toString;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Topic;true;getTopicName;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Topic;true;toString;();;Argument[-1];ReturnValue;taint;manual", - ] - } -} - -/** Defines additional sources of tainted data in JMS 2. */ -private class Jms2Source extends SourceModelCsv { - override predicate row(string row) { - row = - [ - "javax.jms;JMSConsumer;true;receive;;;ReturnValue;remote;manual", - "javax.jms;JMSConsumer;true;receiveBody;;;ReturnValue;remote;manual", - "javax.jms;JMSConsumer;true;receiveNoWait;();;ReturnValue;remote;manual", - "javax.jms;JMSConsumer;true;receiveBodyNoWait;();;ReturnValue;remote;manual", - ] - } -} - -/** Defines additional taint propagation steps in JMS 2. */ -private class Jms2FlowStep extends SummaryModelCsv { - override predicate row(string row) { - row = "javax.jms;Message;true;getBody;();;Argument[-1];ReturnValue;taint;manual" - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/JavaIo.qll b/java/ql/lib/semmle/code/java/frameworks/JavaIo.qll deleted file mode 100644 index 8748c2a0cb1..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/JavaIo.qll +++ /dev/null @@ -1,24 +0,0 @@ -/** Definitions of taint steps in Objects class of the JDK */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class JavaIoSummaryCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "java.lang;Appendable;true;append;;;Argument[0];Argument[-1];taint;manual", - "java.lang;Appendable;true;append;;;Argument[-1];ReturnValue;value;manual", - "java.io;Writer;true;write;;;Argument[0];Argument[-1];taint;manual", - "java.io;Writer;true;toString;;;Argument[-1];ReturnValue;taint;manual", - "java.io;CharArrayWriter;true;toCharArray;;;Argument[-1];ReturnValue;taint;manual", - "java.io;ObjectInput;true;read;;;Argument[-1];Argument[0];taint;manual", - "java.io;DataInput;true;readFully;;;Argument[-1];Argument[0];taint;manual", - "java.io;DataInput;true;readLine;();;Argument[-1];ReturnValue;taint;manual", - "java.io;DataInput;true;readUTF;();;Argument[-1];ReturnValue;taint;manual", - "java.nio.channels;ReadableByteChannel;true;read;(ByteBuffer);;Argument[-1];Argument[0];taint;manual", - "java.nio.channels;Channels;false;newChannel;(InputStream);;Argument[0];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/JavaxJson.qll b/java/ql/lib/semmle/code/java/frameworks/JavaxJson.qll deleted file mode 100644 index 0a2db0d06fc..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/JavaxJson.qll +++ /dev/null @@ -1,138 +0,0 @@ -/** - * Provides models for the `javax.json` and `jakarta.json` packages. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class FlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + - [ - ".json;Json;false;createArrayBuilder;(JsonArray);;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;createArrayBuilder;(Collection);;Argument[0].Element;ReturnValue;taint;manual", - ".json;Json;false;createDiff;;;Argument[0..1];ReturnValue;taint;manual", - ".json;Json;false;createMergeDiff;;;Argument[0..1];ReturnValue;taint;manual", - ".json;Json;false;createMergePatch;;;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;createObjectBuilder;(JsonObject);;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;createObjectBuilder;(Map);;Argument[0].MapKey;ReturnValue;taint;manual", - ".json;Json;false;createObjectBuilder;(Map);;Argument[0].MapValue;ReturnValue;taint;manual", - ".json;Json;false;createPatch;;;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;createPatchBuilder;;;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;createPointer;;;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;createReader;;;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;createValue;;;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;createWriter;;;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;decodePointer;;;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;encodePointer;;;Argument[0];ReturnValue;taint;manual", - ".json;JsonArray;false;getBoolean;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArray;false;getBoolean;;;Argument[1];ReturnValue;value;manual", - ".json;JsonArray;false;getInt;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArray;false;getInt;;;Argument[1];ReturnValue;value;manual", - ".json;JsonArray;false;getJsonArray;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArray;false;getJsonNumber;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArray;false;getJsonObject;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArray;false;getJsonString;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArray;false;getString;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArray;false;getString;;;Argument[1];ReturnValue;value;manual", - ".json;JsonArray;false;getValuesAs;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArrayBuilder;false;add;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonArrayBuilder;false;add;(boolean);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(double);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(long);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(JsonArrayBuilder);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(JsonObjectBuilder);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(JsonValue);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(String);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(BigDecimal);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(BigInteger);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,boolean);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,double);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,int);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,long);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,JsonArrayBuilder);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,JsonObjectBuilder);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,JsonValue);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,String);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,BigDecimal);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,BigInteger);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;addAll;;;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;addAll;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonArrayBuilder;false;addNull;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonArrayBuilder;false;build;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArrayBuilder;false;remove;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonArrayBuilder;false;set;;;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;set;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonArrayBuilder;false;setNull;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonMergePatch;false;apply;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonMergePatch;false;apply;;;Argument[0];ReturnValue;taint;manual", - ".json;JsonMergePatch;false;toJsonValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;bigDecimalValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;bigIntegerValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;bigIntegerValueExact;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;doubleValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;intValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;intValueExact;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;longValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;longValueExact;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;numberValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObject;false;getBoolean;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObject;false;getBoolean;;;Argument[1];ReturnValue;value;manual", - ".json;JsonObject;false;getInt;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObject;false;getInt;;;Argument[1];ReturnValue;value;manual", - ".json;JsonObject;false;getJsonArray;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObject;false;getJsonNumber;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObject;false;getJsonObject;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObject;false;getJsonString;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObject;false;getString;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObject;false;getString;;;Argument[1];ReturnValue;value;manual", - ".json;JsonObjectBuilder;false;add;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonObjectBuilder;false;add;;;Argument[1];Argument[-1];taint;manual", - ".json;JsonObjectBuilder;false;addAll;;;Argument[0];ReturnValue;value;manual", - ".json;JsonObjectBuilder;false;addAll;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonObjectBuilder;false;addNull;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonObjectBuilder;false;build;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObjectBuilder;false;remove;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonPatch;false;apply;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonPatch;false;apply;;;Argument[0];ReturnValue;taint;manual", - ".json;JsonPatch;false;toJsonArray;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonPatchBuilder;false;add;;;Argument[0..1];ReturnValue;taint;manual", - ".json;JsonPatchBuilder;false;add;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonPatchBuilder;false;build;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonPatchBuilder;false;copy;;;Argument[0..1];ReturnValue;taint;manual", - ".json;JsonPatchBuilder;false;copy;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonPatchBuilder;false;move;;;Argument[0..1];ReturnValue;taint;manual", - ".json;JsonPatchBuilder;false;move;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonPatchBuilder;false;remove;;;Argument[0];ReturnValue;taint;manual", - ".json;JsonPatchBuilder;false;remove;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonPatchBuilder;false;replace;;;Argument[0..1];ReturnValue;taint;manual", - ".json;JsonPatchBuilder;false;replace;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonPatchBuilder;false;test;;;Argument[0..1];ReturnValue;taint;manual", - ".json;JsonPatchBuilder;false;test;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonPointer;false;add;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonPointer;false;add;;;Argument[0..1];ReturnValue;taint;manual", - ".json;JsonPointer;false;getValue;;;Argument[0];ReturnValue;taint;manual", - ".json;JsonPointer;false;remove;;;Argument[0];ReturnValue;taint;manual", - ".json;JsonPointer;false;replace;;;Argument[0..1];ReturnValue;taint;manual", - ".json;JsonPointer;false;toString;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonReader;false;read;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonReader;false;readArray;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonReader;false;readObject;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonReader;false;readValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonReaderFactory;false;createReader;;;Argument[0];ReturnValue;taint;manual", - ".json;JsonString;false;getChars;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonString;false;getString;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonStructure;true;getValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonValue;true;asJsonArray;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonValue;true;asJsonObject;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonValue;true;toString;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonWriter;false;write;;;Argument[0];Argument[-1];taint;manual", - ".json;JsonWriter;false;writeArray;;;Argument[0];Argument[-1];taint;manual", - ".json;JsonWriter;false;writeObject;;;Argument[0];Argument[-1];taint;manual", - ".json;JsonWriterFactory;false;createWriter;;;Argument[-1];Argument[0];taint;manual", - ".json.stream;JsonParserFactory;false;createParser;;;Argument[0];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll b/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll index c60c3ff0369..23f304be83a 100644 --- a/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll +++ b/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll @@ -321,323 +321,6 @@ private class JaxRSXssSink extends XssSink { } } -/** A URL redirection sink from JAX-RS */ -private class JaxRsUrlRedirectSink extends SinkModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;Response;true;" + ["seeOther", "temporaryRedirect"] + - ";;;Argument[0];url-redirect;manual" - } -} - -/** - * Model Response: - * - * - the returned ResponseBuilder gains taint from a tainted entity or existing Response - */ -private class ResponseModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;Response;false;" + ["accepted", "fromResponse", "ok"] + - ";;;Argument[0];ReturnValue;taint;manual" - } -} - -/** - * Model ResponseBuilder: - * - * - becomes tainted by a tainted entity, but not by metadata, headers etc - * - build() method returns taint - * - almost all methods are fluent, and so preserve value - */ -private class ResponseBuilderModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;Response$ResponseBuilder;true;" + - [ - "allow", "cacheControl", "contentLocation", "cookie", "encoding", "entity", "expires", - "header", "language", "lastModified", "link", "links", "location", "replaceAll", "status", - "tag", "type", "variant", "variants" - ] + ";;;Argument[-1];ReturnValue;value;manual" - or - row = - ["javax", "jakarta"] + ".ws.rs.core;Response$ResponseBuilder;true;" + - [ - "build;;;Argument[-1];ReturnValue;taint;manual", - "entity;;;Argument[0];Argument[-1];taint;manual", - "clone;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} - -/** - * Model HttpHeaders: methods that Date have to be syntax-checked, but those returning MediaType - * or Locale are assumed potentially dangerous, as these types do not generally check that the - * input data is recognised, only that it conforms to the expected syntax. - */ -private class HttpHeadersModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;HttpHeaders;true;" + - [ - "getAcceptableLanguages", "getAcceptableMediaTypes", "getCookies", "getHeaderString", - "getLanguage", "getMediaType", "getRequestHeader", "getRequestHeaders" - ] + ";;;Argument[-1];ReturnValue;taint;manual" - } -} - -/** - * Model MultivaluedMap, which extends `Map>` and provides a few extra helper methods. - */ -private class MultivaluedMapModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;MultivaluedMap;true;" + - [ - "add;;;Argument[0];Argument[-1].MapKey;value;manual", - "add;;;Argument[1];Argument[-1].MapValue.Element;value;manual", - "addAll;;;Argument[0];Argument[-1].MapKey;value;manual", - "addAll;(Object,List);;Argument[1].Element;Argument[-1].MapValue.Element;value;manual", - "addAll;(Object,Object[]);;Argument[1].ArrayElement;Argument[-1].MapValue.Element;value;manual", - "addFirst;;;Argument[0];Argument[-1].MapKey;value;manual", - "addFirst;;;Argument[1];Argument[-1].MapValue.Element;value;manual", - "getFirst;;;Argument[-1].MapValue.Element;ReturnValue;value;manual", - "putSingle;;;Argument[0];Argument[-1].MapKey;value;manual", - "putSingle;;;Argument[1];Argument[-1].MapValue.Element;value;manual" - ] - } -} - -/** - * Model AbstractMultivaluedMap, which implements MultivaluedMap. - */ -private class AbstractMultivaluedMapModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;AbstractMultivaluedMap;false;AbstractMultivaluedMap;;;" + - [ - "Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "Argument[0].MapValue;Argument[-1].MapValue;value;manual" - ] - } -} - -/** - * Model MultivaluedHashMap, which extends AbstractMultivaluedMap. - */ -private class MultivaluedHashMapModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;MultivaluedHashMap;false;MultivaluedHashMap;" + - [ - "(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "(Map);;Argument[0].MapValue;Argument[-1].MapValue.Element;value;manual", - "(MultivaluedMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "(MultivaluedMap);;Argument[0].MapValue;Argument[-1].MapValue;value;manual" - ] - } -} - -/** - * Model PathSegment, which wraps a path and its associated matrix parameters. - */ -private class PathSegmentModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;PathSegment;true;" + ["getMatrixParameters", "getPath"] + - ";;;Argument[-1];ReturnValue;taint;manual" - } -} - -/** - * Model UriInfo, which provides URI element accessors. - */ -private class UriInfoModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;UriInfo;true;" + - [ - "getAbsolutePath;;;Argument[-1];ReturnValue;taint;manual", - "getAbsolutePathBuilder;;;Argument[-1];ReturnValue;taint;manual", - "getPath;;;Argument[-1];ReturnValue;taint;manual", - "getPathParameters;;;Argument[-1];ReturnValue;taint;manual", - "getPathSegments;;;Argument[-1];ReturnValue;taint;manual", - "getQueryParameters;;;Argument[-1];ReturnValue;taint;manual", - "getRequestUri;;;Argument[-1];ReturnValue;taint;manual", - "getRequestUriBuilder;;;Argument[-1];ReturnValue;taint;manual", - "relativize;;;Argument[0];ReturnValue;taint;manual", - "resolve;;;Argument[-1];ReturnValue;taint;manual", - "resolve;;;Argument[0];ReturnValue;taint;manual" - ] - } -} - -/** - * Model Cookie, a simple tuple type. - */ -private class CookieModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;Cookie;" + - [ - "true;getDomain;;;Argument[-1];ReturnValue;taint;manual", - "true;getName;;;Argument[-1];ReturnValue;taint;manual", - "true;getPath;;;Argument[-1];ReturnValue;taint;manual", - "true;getValue;;;Argument[-1];ReturnValue;taint;manual", - "true;getVersion;;;Argument[-1];ReturnValue;taint;manual", - "true;toString;;;Argument[-1];ReturnValue;taint;manual", - "false;Cookie;;;Argument[0..4];Argument[-1];taint;manual", - "false;valueOf;;;Argument[0];ReturnValue;taint;manual" - ] - } -} - -/** - * Model NewCookie, a simple tuple type. - */ -private class NewCookieModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;NewCookie;" + - [ - "true;getComment;;;Argument[-1];ReturnValue;taint;manual", - "true;getExpiry;;;Argument[-1];ReturnValue;taint;manual", - "true;getMaxAge;;;Argument[-1];ReturnValue;taint;manual", - "true;toCookie;;;Argument[-1];ReturnValue;taint;manual", - "false;NewCookie;;;Argument[0..9];Argument[-1];taint;manual", - "false;valueOf;;;Argument[0];ReturnValue;taint;manual" - ] - } -} - -/** - * Model Form, a simple container type. - */ -private class FormModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;Form;" + - [ - "false;Form;;;Argument[0].MapKey;Argument[-1];taint;manual", - "false;Form;;;Argument[0].MapValue.Element;Argument[-1];taint;manual", - "false;Form;;;Argument[0..1];Argument[-1];taint;manual", - "true;asMap;;;Argument[-1];ReturnValue;taint;manual", - "true;param;;;Argument[0..1];Argument[-1];taint;manual", - "true;param;;;Argument[-1];ReturnValue;value;manual" - ] - } -} - -/** - * Model GenericEntity, a wrapper for HTTP entities (e.g., documents). - */ -private class GenericEntityModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;GenericEntity;" + - [ - "false;GenericEntity;;;Argument[0];Argument[-1];taint;manual", - "true;getEntity;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} - -/** - * Model MediaType, which provides accessors for elements of Content-Type and similar - * media type specifications. - */ -private class MediaTypeModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;MediaType;" + - [ - "false;MediaType;;;Argument[0..2];Argument[-1];taint;manual", - "true;getParameters;;;Argument[-1];ReturnValue;taint;manual", - "true;getSubtype;;;Argument[-1];ReturnValue;taint;manual", - "true;getType;;;Argument[-1];ReturnValue;taint;manual", - "false;valueOf;;;Argument[0];ReturnValue;taint;manual", - "true;withCharset;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} - -/** - * Model UriBuilder, which provides a fluent interface to build a URI from components. - */ -private class UriBuilderModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;UriBuilder;" + - [ - "true;build;;;Argument[0].ArrayElement;ReturnValue;taint;manual", - "true;build;;;Argument[-1];ReturnValue;taint;manual", - "true;buildFromEncoded;;;Argument[0].ArrayElement;ReturnValue;taint;manual", - "true;buildFromEncoded;;;Argument[-1];ReturnValue;taint;manual", - "true;buildFromEncodedMap;;;Argument[0].MapKey;ReturnValue;taint;manual", - "true;buildFromEncodedMap;;;Argument[0].MapValue;ReturnValue;taint;manual", - "true;buildFromEncodedMap;;;Argument[-1];ReturnValue;taint;manual", - "true;buildFromMap;;;Argument[0].MapKey;ReturnValue;taint;manual", - "true;buildFromMap;;;Argument[0].MapValue;ReturnValue;taint;manual", - "true;buildFromMap;;;Argument[-1];ReturnValue;taint;manual", - "true;clone;;;Argument[-1];ReturnValue;taint;manual", - "true;fragment;;;Argument[0];ReturnValue;taint;manual", - "true;fragment;;;Argument[-1];ReturnValue;value;manual", - "false;fromLink;;;Argument[0];ReturnValue;taint;manual", - "false;fromPath;;;Argument[0];ReturnValue;taint;manual", - "false;fromUri;;;Argument[0];ReturnValue;taint;manual", - "true;host;;;Argument[0];ReturnValue;taint;manual", - "true;host;;;Argument[-1];ReturnValue;value;manual", - "true;matrixParam;;;Argument[0];ReturnValue;taint;manual", - "true;matrixParam;;;Argument[1].ArrayElement;ReturnValue;taint;manual", - "true;matrixParam;;;Argument[-1];ReturnValue;value;manual", - "true;path;;;Argument[0..1];ReturnValue;taint;manual", - "true;path;;;Argument[-1];ReturnValue;value;manual", - "true;queryParam;;;Argument[0];ReturnValue;taint;manual", - "true;queryParam;;;Argument[1].ArrayElement;ReturnValue;taint;manual", - "true;queryParam;;;Argument[-1];ReturnValue;value;manual", - "true;replaceMatrix;;;Argument[0];ReturnValue;taint;manual", - "true;replaceMatrix;;;Argument[-1];ReturnValue;value;manual", - "true;replaceMatrixParam;;;Argument[0];ReturnValue;taint;manual", - "true;replaceMatrixParam;;;Argument[1].ArrayElement;ReturnValue;taint;manual", - "true;replaceMatrixParam;;;Argument[-1];ReturnValue;value;manual", - "true;replacePath;;;Argument[0];ReturnValue;taint;manual", - "true;replacePath;;;Argument[-1];ReturnValue;value;manual", - "true;replaceQuery;;;Argument[0];ReturnValue;taint;manual", - "true;replaceQuery;;;Argument[-1];ReturnValue;value;manual", - "true;replaceQueryParam;;;Argument[0];ReturnValue;taint;manual", - "true;replaceQueryParam;;;Argument[1].ArrayElement;ReturnValue;taint;manual", - "true;replaceQueryParam;;;Argument[-1];ReturnValue;value;manual", - "true;resolveTemplate;;;Argument[0..2];ReturnValue;taint;manual", - "true;resolveTemplate;;;Argument[-1];ReturnValue;value;manual", - "true;resolveTemplateFromEncoded;;;Argument[0..1];ReturnValue;taint;manual", - "true;resolveTemplateFromEncoded;;;Argument[-1];ReturnValue;value;manual", - "true;resolveTemplates;;;Argument[0].MapKey;ReturnValue;taint;manual", - "true;resolveTemplates;;;Argument[0].MapValue;ReturnValue;taint;manual", - "true;resolveTemplates;;;Argument[-1];ReturnValue;value;manual", - "true;resolveTemplatesFromEncoded;;;Argument[0].MapKey;ReturnValue;taint;manual", - "true;resolveTemplatesFromEncoded;;;Argument[0].MapValue;ReturnValue;taint;manual", - "true;resolveTemplatesFromEncoded;;;Argument[-1];ReturnValue;value;manual", - "true;scheme;;;Argument[0];ReturnValue;taint;manual", - "true;scheme;;;Argument[-1];ReturnValue;value;manual", - "true;schemeSpecificPart;;;Argument[0];ReturnValue;taint;manual", - "true;schemeSpecificPart;;;Argument[-1];ReturnValue;value;manual", - "true;segment;;;Argument[0].ArrayElement;ReturnValue;taint;manual", - "true;segment;;;Argument[-1];ReturnValue;value;manual", - "true;toTemplate;;;Argument[-1];ReturnValue;taint;manual", - "true;uri;;;Argument[0];ReturnValue;taint;manual", - "true;uri;;;Argument[-1];ReturnValue;value;manual", - "true;userInfo;;;Argument[0];ReturnValue;taint;manual", - "true;userInfo;;;Argument[-1];ReturnValue;value;manual" - ] - } -} - -private class JaxRsUrlOpenSink extends SinkModelCsv { - override predicate row(string row) { - row = ["javax", "jakarta"] + ".ws.rs.client;Client;true;target;;;Argument[0];open-url;manual" - } -} - private predicate isXssVulnerableContentTypeExpr(Expr e) { isXssVulnerableContentType(getContentTypeString(e)) } @@ -784,17 +467,3 @@ private class VulnerableEntity extends XssSinkBarrier { ).getArgument(0) } } - -/** - * Model sources stemming from `ContainerRequestContext`. - */ -private class ContainerRequestContextModel extends SourceModelCsv { - override predicate row(string s) { - s = - ["javax", "jakarta"] + ".ws.rs.container;ContainerRequestContext;true;" + - [ - "getAcceptableLanguages", "getAcceptableMediaTypes", "getCookies", "getEntityStream", - "getHeaders", "getHeaderString", "getLanguage", "getMediaType", "getUriInfo" - ] + ";;;ReturnValue;remote;manual" - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Jdbc.qll b/java/ql/lib/semmle/code/java/frameworks/Jdbc.qll index ba9dd8d445c..be22f2716be 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Jdbc.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Jdbc.qll @@ -34,33 +34,3 @@ class ResultSetGetStringMethod extends Method { getReturnType() instanceof TypeString } } - -/*--- Other definitions ---*/ -private class SqlSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "java.sql;Connection;true;prepareStatement;;;Argument[0];sql;manual", - "java.sql;Connection;true;prepareCall;;;Argument[0];sql;manual", - "java.sql;Statement;true;execute;;;Argument[0];sql;manual", - "java.sql;Statement;true;executeQuery;;;Argument[0];sql;manual", - "java.sql;Statement;true;executeUpdate;;;Argument[0];sql;manual", - "java.sql;Statement;true;executeLargeUpdate;;;Argument[0];sql;manual", - "java.sql;Statement;true;addBatch;;;Argument[0];sql;manual" - ] - } -} - -private class SsrfSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "java.sql;DriverManager;false;getConnection;(String);;Argument[0];jdbc-url;manual", - "java.sql;DriverManager;false;getConnection;(String,Properties);;Argument[0];jdbc-url;manual", - "java.sql;DriverManager;false;getConnection;(String,String,String);;Argument[0];jdbc-url;manual", - "java.sql;Driver;false;connect;(String,Properties);;Argument[0];jdbc-url;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Jdbi.qll b/java/ql/lib/semmle/code/java/frameworks/Jdbi.qll deleted file mode 100644 index 698d27d07ed..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/Jdbi.qll +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Definitions of sinks in the JDBI library. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class SsrfSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "org.jdbi.v3.core;Jdbi;false;create;(String);;Argument[0];jdbc-url;manual", - "org.jdbi.v3.core;Jdbi;false;create;(String,Properties);;Argument[0];jdbc-url;manual", - "org.jdbi.v3.core;Jdbi;false;create;(String,String,String);;Argument[0];jdbc-url;manual", - "org.jdbi.v3.core;Jdbi;false;open;(String);;Argument[0];jdbc-url;manual", - "org.jdbi.v3.core;Jdbi;false;open;(String,Properties);;Argument[0];jdbc-url;manual", - "org.jdbi.v3.core;Jdbi;false;open;(String,String,String);;Argument[0];jdbc-url;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/JoddJson.qll b/java/ql/lib/semmle/code/java/frameworks/JoddJson.qll index 9ed563091d7..5440b1ca5d6 100644 --- a/java/ql/lib/semmle/code/java/frameworks/JoddJson.qll +++ b/java/ql/lib/semmle/code/java/frameworks/JoddJson.qll @@ -41,28 +41,3 @@ class AllowClassMethod extends Method { this.hasName("allowClass") } } - -/** - * A partial model of jodd.json.JsonParser noting fluent methods. - * - * This means that DataFlow::localFlow and similar methods are aware - * that the result of (e.g.) JsonParser.allowClass is an alias of the - * qualifier. - */ -private class JsonParserFluentMethods extends SummaryModelCsv { - override predicate row(string s) { - s = - [ - "jodd.json;JsonParser;false;allowAllClasses;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;allowClass;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;lazy;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;looseMode;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;map;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;setClassMetadataName;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;strictTypes;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;useAltPaths;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;withClassMetadata;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;withValueConverter;;;Argument[-1];ReturnValue;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/JsonJava.qll b/java/ql/lib/semmle/code/java/frameworks/JsonJava.qll deleted file mode 100644 index b8c79a010c0..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/JsonJava.qll +++ /dev/null @@ -1,252 +0,0 @@ -/** - * Provides models for working with the JSON-java library (package `org.json`). - */ - -private import semmle.code.java.dataflow.ExternalFlow - -private class FlowModels extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.json;JSONString;true;toJSONString;;;Argument[-1];ReturnValue;taint;manual", - "org.json;XMLXsiTypeConverter;true;convert;;;Argument[0];ReturnValue;taint;manual", - "org.json;CDL;false;rowToJSONArray;;;Argument[0];ReturnValue;taint;manual", - "org.json;CDL;false;rowToJSONObject;;;Argument[0..1];ReturnValue;taint;manual", - "org.json;CDL;false;rowToString;;;Argument[0];ReturnValue;taint;manual", - "org.json;CDL;false;toJSONArray;;;Argument[0..1];ReturnValue;taint;manual", - "org.json;CDL;false;toString;;;Argument[0..1];ReturnValue;taint;manual", - "org.json;Cookie;false;escape;;;Argument[0];ReturnValue;taint;manual", - "org.json;Cookie;false;toJSONObject;;;Argument[0];ReturnValue;taint;manual", - "org.json;Cookie;false;toString;;;Argument[0];ReturnValue;taint;manual", - "org.json;Cookie;false;unescape;;;Argument[0];ReturnValue;taint;manual", - "org.json;CookieList;false;toJSONObject;;;Argument[0];ReturnValue;taint;manual", - "org.json;CookieList;false;toString;;;Argument[0];ReturnValue;taint;manual", - "org.json;HTTP;false;toJSONObject;;;Argument[0];ReturnValue;taint;manual", - "org.json;HTTP;false;toString;;;Argument[0];ReturnValue;taint;manual", - "org.json;HTTPTokener;false;HTTPTokener;;;Argument[0];Argument[-1];taint;manual", - "org.json;HTTPTokener;false;nextToken;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;JSONArray;(Collection);;Argument[0].Element;Argument[-1];taint;manual", - "org.json;JSONArray;false;JSONArray;(Iterable);;Argument[0].Element;Argument[-1];taint;manual", - "org.json;JSONArray;false;JSONArray;(JSONArray);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;JSONArray;(JSONTokener);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;JSONArray;(Object);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.json;JSONArray;false;JSONArray;(String);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;get;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getBigDecimal;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getBigInteger;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getBoolean;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getDouble;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getEnum;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getFloat;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getInt;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getJSONArray;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getJSONObject;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getLong;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getNumber;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getString;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;iterator;;;Argument[-1];ReturnValue.Element;taint;manual", - "org.json;JSONArray;false;join;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;join;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONArray;false;opt;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optBigDecimal;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optBigInteger;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optBoolean;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optDouble;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optEnum;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optFloat;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optInt;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optJSONArray;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optJSONObject;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optLong;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optNumber;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optQuery;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optString;;;Argument[-1];ReturnValue;taint;manual", - // Default values that may be returned by the `opt*` methods above: - "org.json;JSONArray;false;optBigDecimal;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;optBigInteger;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;optBoolean;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;optDouble;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;optEnum;;;Argument[2];ReturnValue;value;manual", - "org.json;JSONArray;false;optFloat;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;optInt;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;optLong;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;optNumber;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;optString;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;put;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONArray;false;put;(boolean);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(Collection);;Argument[0].Element;Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(double);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(float);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(long);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(Map);;Argument[0].MapKey;Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(Map);;Argument[0].MapValue;Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(Object);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,boolean);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,Collection);;Argument[1].Element;Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,double);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,float);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,int);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,long);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,Map);;Argument[1].MapKey;Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,Map);;Argument[1].MapValue;Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,Object);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONArray;false;putAll;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONArray;false;putAll;(Collection);;Argument[0].Element;Argument[-1];taint;manual", - "org.json;JSONArray;false;putAll;(Iterable);;Argument[0].Element;Argument[-1];taint;manual", - "org.json;JSONArray;false;putAll;(JSONArray);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;putAll;(Object);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;query;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;remove;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;toJSONObject;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONArray;false;toJSONObject;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;toList;;;Argument[0];ReturnValue.Element;taint;manual", - "org.json;JSONArray;false;toString;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONArray;false;write;;;Argument[-1];Argument[0];taint;manual", - "org.json;JSONArray;false;write;;;Argument[0];ReturnValue;value;manual", - "org.json;JSONML;false;toJSONArray;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONML;false;toJSONObject;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONML;false;toString;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONObject;false;JSONObject;(JSONObject,String[]);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(JSONObject,String[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(JSONTokener);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(Map);;Argument[0].MapKey;Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(Map);;Argument[0].MapValue;Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(Object);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(Object,String[]);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(Object,String[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(String);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(String,Locale);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;accumulate;;;Argument[0..1];Argument[-1];taint;manual", - "org.json;JSONObject;false;accumulate;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONObject;false;append;;;Argument[0..1];Argument[-1];taint;manual", - "org.json;JSONObject;false;append;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONObject;false;doubleToString;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONObject;true;entrySet;;;Argument[-1];ReturnValue.Element;taint;manual", - "org.json;JSONObject;false;get;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getBigDecimal;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getBigInteger;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getBoolean;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getDouble;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getEnum;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getFloat;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getInt;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getJSONArray;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getJSONObject;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getLong;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getNames;;;Argument[0];ReturnValue.ArrayElement;taint;manual", - "org.json;JSONObject;false;getNumber;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getString;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;increment;;;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;increment;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONObject;false;keys;;;Argument[-1];ReturnValue.Element;taint;manual", - "org.json;JSONObject;false;keySet;;;Argument[-1];ReturnValue.Element;taint;manual", - "org.json;JSONObject;false;names;;;Argument[-1];ReturnValue;taint;manual", // Returns a JSONArray, hence this has no Element qualifier or similar - "org.json;JSONObject;false;numberToString;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONObject;false;opt;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optBigDecimal;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optBigInteger;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optBoolean;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optDouble;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optEnum;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optFloat;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optInt;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optJSONArray;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optJSONObject;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optLong;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optNumber;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optQuery;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optString;;;Argument[-1];ReturnValue;taint;manual", - // Default values that may be returned by the `opt*` methods above: - "org.json;JSONObject;false;optBigDecimal;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;optBigInteger;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;optBoolean;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;optDouble;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;optEnum;;;Argument[2];ReturnValue;value;manual", - "org.json;JSONObject;false;optFloat;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;optInt;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;optLong;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;optNumber;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;optString;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;put;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONObject;false;put;(String,boolean);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,Collection);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,double);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,float);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,int);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,long);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,Map);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,Object);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,boolean);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,Collection);;Argument[1].Element;Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,double);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,float);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,int);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,long);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,Map);;Argument[1].MapKey;Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,Map);;Argument[1].MapValue;Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,Object);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONObject;false;putOnce;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONObject;false;putOnce;;;Argument[0..1];Argument[-1];taint;manual", - "org.json;JSONObject;false;putOpt;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONObject;false;putOpt;;;Argument[0..1];Argument[-1];taint;manual", - "org.json;JSONObject;false;query;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;quote;(String);;Argument[0];ReturnValue;taint;manual", - "org.json;JSONObject;false;quote;(String,Writer);;Argument[0];Argument[1];taint;manual", - "org.json;JSONObject;false;quote;(String,Writer);;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;remove;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;stringToValue;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONObject;false;toJSONArray;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;toMap;;;Argument[-1];ReturnValue.MapKey;taint;manual", - "org.json;JSONObject;false;toMap;;;Argument[-1];ReturnValue.MapValue;taint;manual", - "org.json;JSONObject;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;valueToString;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONObject;false;wrap;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONObject;false;write;;;Argument[-1];Argument[0];taint;manual", - "org.json;JSONObject;false;write;;;Argument[0];ReturnValue;value;manual", - "org.json;JSONPointer;false;JSONPointer;(List);;Argument[0].Element;Argument[-1];taint;manual", - "org.json;JSONPointer;false;JSONPointer;(String);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONPointer;false;queryFrom;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONPointer;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONPointer;false;toURIFragment;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONPointer$Builder;false;append;;;Argument[0];Argument[-1];taint;manual", - "org.json;JSONPointer$Builder;false;append;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONPointer$Builder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONStringer;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONTokener;true;JSONTokener;;;Argument[0];Argument[-1];taint;manual", - "org.json;JSONTokener;true;next;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONTokener;true;nextClean;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONTokener;true;nextString;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONTokener;true;nextTo;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONTokener;true;nextValue;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONTokener;true;syntaxError;;;Argument[0..1];ReturnValue;taint;manual", - "org.json;JSONTokener;true;toString;;;Argument[-1];ReturnValue;taint;manual", - // The following model doesn't work yet due to lack of support for reverse taint flow: - "org.json;JSONWriter;true;JSONWriter;;;Argument[-1];Argument[0];taint;manual", - "org.json;JSONWriter;true;key;;;Argument[0];Argument[-1];taint;manual", - "org.json;JSONWriter;true;value;;;Argument[0];Argument[-1];taint;manual", - "org.json;JSONWriter;true;valueToString;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONWriter;true;array;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONWriter;true;endArray;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONWriter;true;endObject;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONWriter;true;key;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONWriter;true;object;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONWriter;true;value;;;Argument[-1];ReturnValue;value;manual", - "org.json;Property;false;toJSONObject;;;Argument[0].MapKey;ReturnValue;taint;manual", - "org.json;Property;false;toJSONObject;;;Argument[0].MapValue;ReturnValue;taint;manual", - "org.json;Property;false;toProperties;;;Argument[0];ReturnValue.MapKey;taint;manual", - "org.json;Property;false;toProperties;;;Argument[0];ReturnValue.MapValue;taint;manual", - "org.json;XML;false;escape;;;Argument[0];ReturnValue;taint;manual", - "org.json;XML;false;stringToValue;;;Argument[0];ReturnValue;taint;manual", - "org.json;XML;false;toJSONObject;;;Argument[0];ReturnValue;taint;manual", - "org.json;XML;false;toString;;;Argument[0..1];ReturnValue;taint;manual", - "org.json;XML;false;unescape;;;Argument[0];ReturnValue;taint;manual", - "org.json;XMLTokener;false;XMLTokener;;;Argument[0];Argument[-1];taint;manual", - "org.json;XMLTokener;false;nextCDATA;;;Argument[-1];ReturnValue;taint;manual", - "org.json;XMLTokener;false;nextContent;;;Argument[-1];ReturnValue;taint;manual", - "org.json;XMLTokener;false;nextEntity;;;Argument[-1];ReturnValue;taint;manual", - "org.json;XMLTokener;false;nextMeta;;;Argument[-1];ReturnValue;taint;manual", - "org.json;XMLTokener;false;nextToken;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Logging.qll b/java/ql/lib/semmle/code/java/frameworks/Logging.qll deleted file mode 100644 index 4c00873781c..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/Logging.qll +++ /dev/null @@ -1,340 +0,0 @@ -/** Provides classes and predicates to reason about logging. */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class LoggingSummaryModels extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.logging.log4j;Logger;true;traceEntry;(Message);;Argument[0];ReturnValue;taint;manual", - "org.apache.logging.log4j;Logger;true;traceEntry;(String,Object[]);;Argument[0..1];ReturnValue;taint;manual", - "org.apache.logging.log4j;Logger;true;traceEntry;(String,Supplier[]);;Argument[0..1];ReturnValue;taint;manual", - "org.apache.logging.log4j;Logger;true;traceEntry;(Supplier[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(EntryMessage,Object);;Argument[1];ReturnValue;value;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(Message,Object);;Argument[1];ReturnValue;value;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(Object);;Argument[0];ReturnValue;value;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(String,Object);;Argument[1];ReturnValue;value;manual", - "org.slf4j.spi;LoggingEventBuilder;true;addArgument;;;Argument[1];Argument[-1];taint;manual", - "org.slf4j.spi;LoggingEventBuilder;true;addArgument;;;Argument[-1];ReturnValue;value;manual", - "org.slf4j.spi;LoggingEventBuilder;true;addKeyValue;;;Argument[1];Argument[-1];taint;manual", - "org.slf4j.spi;LoggingEventBuilder;true;addKeyValue;;;Argument[-1];ReturnValue;value;manual", - "org.slf4j.spi;LoggingEventBuilder;true;addMarker;;;Argument[-1];ReturnValue;value;manual", - "org.slf4j.spi;LoggingEventBuilder;true;setCause;;;Argument[-1];ReturnValue;value;manual", - "java.util.logging;LogRecord;false;LogRecord;;;Argument[1];Argument[-1];taint;manual" - ] - } -} - -private string jBossLogger() { result = "org.jboss.logging;" + ["BasicLogger", "Logger"] } - -private class LoggingSinkModels extends SinkModelCsv { - override predicate row(string row) { - row = - [ - // org.apache.log4j.Category - "org.apache.log4j;Category;true;assertLog;;;Argument[1];logging;manual", - "org.apache.log4j;Category;true;debug;;;Argument[0];logging;manual", - "org.apache.log4j;Category;true;error;;;Argument[0];logging;manual", - "org.apache.log4j;Category;true;fatal;;;Argument[0];logging;manual", - "org.apache.log4j;Category;true;forcedLog;;;Argument[2];logging;manual", - "org.apache.log4j;Category;true;info;;;Argument[0];logging;manual", - "org.apache.log4j;Category;true;l7dlog;(Priority,String,Object[],Throwable);;Argument[2];logging;manual", - "org.apache.log4j;Category;true;log;(Priority,Object);;Argument[1];logging;manual", - "org.apache.log4j;Category;true;log;(Priority,Object,Throwable);;Argument[1];logging;manual", - "org.apache.log4j;Category;true;log;(String,Priority,Object,Throwable);;Argument[2];logging;manual", - "org.apache.log4j;Category;true;warn;;;Argument[0];logging;manual", - // org.apache.logging.log4j.Logger - "org.apache.logging.log4j;Logger;true;" + - ["debug", "error", "fatal", "info", "trace", "warn"] + - [ - ";(CharSequence);;Argument[0];logging;manual", - ";(CharSequence,Throwable);;Argument[0];logging;manual", - ";(Marker,CharSequence);;Argument[1];logging;manual", - ";(Marker,CharSequence,Throwable);;Argument[1];logging;manual", - ";(Marker,Message);;Argument[1];logging;manual", - ";(Marker,MessageSupplier);;Argument[1];logging;manual", - ";(Marker,MessageSupplier);;Argument[1];logging;manual", - ";(Marker,MessageSupplier,Throwable);;Argument[1];logging;manual", - ";(Marker,Object);;Argument[1];logging;manual", - ";(Marker,Object,Throwable);;Argument[1];logging;manual", - ";(Marker,String);;Argument[1];logging;manual", - ";(Marker,String,Object[]);;Argument[1..2];logging;manual", - ";(Marker,String,Object);;Argument[1..2];logging;manual", - ";(Marker,String,Object,Object);;Argument[1..3];logging;manual", - ";(Marker,String,Object,Object,Object);;Argument[1..4];logging;manual", - ";(Marker,String,Object,Object,Object,Object);;Argument[1..5];logging;manual", - ";(Marker,String,Object,Object,Object,Object,Object);;Argument[1..6];logging;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object);;Argument[1..7];logging;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object,Object);;Argument[1..8];logging;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..9];logging;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..10];logging;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..11];logging;manual", - ";(Marker,String,Supplier);;Argument[1..2];logging;manual", - ";(Marker,String,Throwable);;Argument[1];logging;manual", - ";(Marker,Supplier);;Argument[1];logging;manual", - ";(Marker,Supplier,Throwable);;Argument[1];logging;manual", - ";(MessageSupplier);;Argument[0];logging;manual", - ";(MessageSupplier,Throwable);;Argument[0];logging;manual", - ";(Message);;Argument[0];logging;manual", - ";(Message,Throwable);;Argument[0];logging;manual", - ";(Object);;Argument[0];logging;manual", - ";(Object,Throwable);;Argument[0];logging;manual", - ";(String);;Argument[0];logging;manual", - ";(String,Object[]);;Argument[0..1];logging;manual", - ";(String,Object);;Argument[0..1];logging;manual", - ";(String,Object,Object);;Argument[0..2];logging;manual", - ";(String,Object,Object,Object);;Argument[0..3];logging;manual", - ";(String,Object,Object,Object,Object);;Argument[0..4];logging;manual", - ";(String,Object,Object,Object,Object,Object);;Argument[0..5];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object);;Argument[0..6];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..8];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..10];logging;manual", - ";(String,Supplier);;Argument[0..1];logging;manual", - ";(String,Throwable);;Argument[0];logging;manual", - ";(Supplier);;Argument[0];logging;manual", - ";(Supplier,Throwable);;Argument[0];logging;manual" - ], - "org.apache.logging.log4j;Logger;true;log" + - [ - ";(Level,CharSequence);;Argument[1];logging;manual", - ";(Level,CharSequence,Throwable);;Argument[1];logging;manual", - ";(Level,Marker,CharSequence);;Argument[2];logging;manual", - ";(Level,Marker,CharSequence,Throwable);;Argument[2];logging;manual", - ";(Level,Marker,Message);;Argument[2];logging;manual", - ";(Level,Marker,MessageSupplier);;Argument[2];logging;manual", - ";(Level,Marker,MessageSupplier);;Argument[2];logging;manual", - ";(Level,Marker,MessageSupplier,Throwable);;Argument[2];logging;manual", - ";(Level,Marker,Object);;Argument[2];logging;manual", - ";(Level,Marker,Object,Throwable);;Argument[2];logging;manual", - ";(Level,Marker,String);;Argument[2];logging;manual", - ";(Level,Marker,String,Object[]);;Argument[2..3];logging;manual", - ";(Level,Marker,String,Object);;Argument[2..3];logging;manual", - ";(Level,Marker,String,Object,Object);;Argument[2..4];logging;manual", - ";(Level,Marker,String,Object,Object,Object);;Argument[2..5];logging;manual", - ";(Level,Marker,String,Object,Object,Object,Object);;Argument[2..6];logging;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object);;Argument[2..7];logging;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object);;Argument[2..8];logging;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object);;Argument[2..9];logging;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2..10];logging;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2..11];logging;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2..12];logging;manual", - ";(Level,Marker,String,Supplier);;Argument[2..3];logging;manual", - ";(Level,Marker,String,Throwable);;Argument[2];logging;manual", - ";(Level,Marker,Supplier);;Argument[2];logging;manual", - ";(Level,Marker,Supplier,Throwable);;Argument[2];logging;manual", - ";(Level,Message);;Argument[1];logging;manual", - ";(Level,MessageSupplier);;Argument[1];logging;manual", - ";(Level,MessageSupplier,Throwable);;Argument[1];logging;manual", - ";(Level,Message);;Argument[1];logging;manual", - ";(Level,Message,Throwable);;Argument[1];logging;manual", - ";(Level,Object);;Argument[1];logging;manual", - ";(Level,Object);;Argument[1];logging;manual", - ";(Level,String);;Argument[1];logging;manual", - ";(Level,Object,Throwable);;Argument[1];logging;manual", - ";(Level,String);;Argument[1];logging;manual", - ";(Level,String,Object[]);;Argument[1..2];logging;manual", - ";(Level,String,Object);;Argument[1..2];logging;manual", - ";(Level,String,Object,Object);;Argument[1..3];logging;manual", - ";(Level,String,Object,Object,Object);;Argument[1..4];logging;manual", - ";(Level,String,Object,Object,Object,Object);;Argument[1..5];logging;manual", - ";(Level,String,Object,Object,Object,Object,Object);;Argument[1..6];logging;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object);;Argument[1..7];logging;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object,Object);;Argument[1..8];logging;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..9];logging;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..10];logging;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..11];logging;manual", - ";(Level,String,Supplier);;Argument[1..2];logging;manual", - ";(Level,String,Throwable);;Argument[1];logging;manual", - ";(Level,Supplier);;Argument[1];logging;manual", - ";(Level,Supplier,Throwable);;Argument[1];logging;manual" - ], "org.apache.logging.log4j;Logger;true;entry;(Object[]);;Argument[0];logging;manual", - "org.apache.logging.log4j;Logger;true;logMessage;(Level,Marker,String,StackTraceElement,Message,Throwable);;Argument[4];logging;manual", - "org.apache.logging.log4j;Logger;true;printf;(Level,Marker,String,Object[]);;Argument[2..3];logging;manual", - "org.apache.logging.log4j;Logger;true;printf;(Level,String,Object[]);;Argument[1..2];logging;manual", - "org.apache.logging.log4j;Logger;true;traceEntry;(Message);;Argument[0];logging;manual", - "org.apache.logging.log4j;Logger;true;traceEntry;(String,Object[]);;Argument[0..1];logging;manual", - "org.apache.logging.log4j;Logger;true;traceEntry;(String,Supplier[]);;Argument[0..1];logging;manual", - "org.apache.logging.log4j;Logger;true;traceEntry;(Supplier[]);;Argument[0];logging;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(EntryMessage);;Argument[0];logging;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(EntryMessage,Object);;Argument[0..1];logging;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(Message,Object);;Argument[0..1];logging;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(Object);;Argument[0];logging;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(String,Object);;Argument[0..1];logging;manual", - // org.apache.logging.log4j.LogBuilder - "org.apache.logging.log4j;LogBuilder;true;log;(CharSequence);;Argument[0];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(Message);;Argument[0];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(Object);;Argument[0];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String);;Argument[0];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object[]);;Argument[0..1];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object);;Argument[0..1];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object);;Argument[0..2];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object);;Argument[0..3];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object);;Argument[0..4];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object);;Argument[0..5];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object);;Argument[0..6];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..8];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..10];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Supplier);;Argument[0..1];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(Supplier);;Argument[0];logging;manual", - // org.apache.commons.logging.Log - "org.apache.commons.logging;Log;true;" + - ["debug", "error", "fatal", "info", "trace", "warn"] + ";;;Argument[0];logging;manual", - // org.jboss.logging.BasicLogger and org.jboss.logging.Logger - // (org.jboss.logging.Logger does not implement BasicLogger in some implementations like JBoss Application Server 4.0.4) - jBossLogger() + ";true;" + ["debug", "error", "fatal", "info", "trace", "warn"] + - [ - ";(Object);;Argument[0];logging;manual", - ";(Object,Throwable);;Argument[0];logging;manual", - ";(Object,Object[]);;Argument[0..1];logging;manual", - ";(Object,Object[],Throwable);;Argument[0..1];logging;manual", - ";(String,Object,Object[],Throwable);;Argument[1..2];logging;manual", - ";(String,Object,Throwable);;Argument[1];logging;manual" - ], - jBossLogger() + ";true;log" + - [ - ";(Level,Object);;Argument[1];logging;manual", - ";(Level,Object,Object[]);;Argument[1..2];logging;manual", - ";(Level,Object,Object[],Throwable);;Argument[1..2];logging;manual", - ";(Level,Object,Throwable);;Argument[1];logging;manual", - ";(Level,String,Object,Throwable);;Argument[2];logging;manual", - ";(String,Level,Object,Object[],Throwable);;Argument[2..3];logging;manual" - ], - jBossLogger() + ";true;" + ["debug", "error", "fatal", "info", "trace", "warn"] + ["f", "v"] - + - [ - ";(String,Object[]);;Argument[0..1];logging;manual", - ";(String,Object);;Argument[0..1];logging;manual", - ";(String,Object,Object);;Argument[0..2];logging;manual", - ";(String,Object,Object,Object);;Argument[0..3];logging;manual", - ";(String,Object,Object,Object,Object);;Argument[0..4];logging;manual", - ";(Throwable,String,Object);;Argument[1..2];logging;manual", - ";(Throwable,String,Object,Object);;Argument[1..3];logging;manual", - ";(Throwable,String,Object,Object,Object);;Argument[0..4];logging;manual" - ], - jBossLogger() + ";true;log" + ["f", "v"] + - [ - ";(Level,String,Object[]);;Argument[1..2];logging;manual", - ";(Level,String,Object);;Argument[1..2];logging;manual", - ";(Level,String,Object,Object);;Argument[1..3];logging;manual", - ";(Level,String,Object,Object,Object);;Argument[1..4];logging;manual", - ";(Level,String,Object,Object,Object,Object);;Argument[1..5];logging;manual", - ";(Level,Throwable,String,Object);;Argument[2..3];logging;manual", - ";(Level,Throwable,String,Object,Object);;Argument[2..4];logging;manual", - ";(Level,Throwable,String,Object,Object,Object);;Argument[1..5];logging;manual", - ";(String,Level,Throwable,String,Object[]);;Argument[3..4];logging;manual", - ";(String,Level,Throwable,String,Object);;Argument[3..4];logging;manual", - ";(String,Level,Throwable,String,Object,Object);;Argument[3..5];logging;manual", - ";(String,Level,Throwable,String,Object,Object,Object);;Argument[3..6];logging;manual" - ], - // org.slf4j.spi.LoggingEventBuilder - "org.slf4j.spi;LoggingEventBuilder;true;log;;;Argument[0];logging;manual", - "org.slf4j.spi;LoggingEventBuilder;true;log;(String,Object);;Argument[0..1];logging;manual", - "org.slf4j.spi;LoggingEventBuilder;true;log;(String,Object[]);;Argument[0..1];logging;manual", - "org.slf4j.spi;LoggingEventBuilder;true;log;(String,Object,Object);;Argument[0..2];logging;manual", - "org.slf4j.spi;LoggingEventBuilder;true;log;(Supplier);;Argument[0];logging;manual", - // org.slf4j.Logger - "org.slf4j;Logger;true;" + ["debug", "error", "info", "trace", "warn"] + - [ - ";(String);;Argument[0];logging;manual", - ";(String,Object);;Argument[0..1];logging;manual", - ";(String,Object[]);;Argument[0..1];logging;manual", - ";(String,Object,Object);;Argument[0..2];logging;manual", - ";(String,Throwable);;Argument[0];logging;manual", - ";(Marker,String);;Argument[1];logging;manual", - ";(Marker,String,Object);;Argument[1..2];logging;manual", - ";(Marker,String,Object[]);;Argument[1..2];logging;manual", - ";(Marker,String,Object,Object);;Argument[1..3];logging;manual", - ";(Marker,String,Object,Object,Object);;Argument[1..4];logging;manual" - ], - // org.scijava.Logger - "org.scijava.log;Logger;true;alwaysLog;(int,Object,Throwable);;Argument[1];logging;manual", - "org.scijava.log;Logger;true;" + ["debug", "error", "info", "trace", "warn"] + - [ - ";(Object);;Argument[0];logging;manual", - ";(Object,Throwable);;Argument[0];logging;manual" - ], "org.scijava.log;Logger;true;log;(int,Object);;Argument[1];logging;manual", - "org.scijava.log;Logger;true;log;(int,Object,Throwable);;Argument[1];logging;manual", - // com.google.common.flogger.LoggingApi - "com.google.common.flogger;LoggingApi;true;logVarargs;;;Argument[0..1];logging;manual", - "com.google.common.flogger;LoggingApi;true;log" + - [ - ";;;Argument[0];logging;manual", ";(String,Object);;Argument[1];logging;manual", - ";(String,Object,Object);;Argument[1..2];logging;manual", - ";(String,Object,Object,Object);;Argument[1..3];logging;manual", - ";(String,Object,Object,Object,Object);;Argument[1..4];logging;manual", - ";(String,Object,Object,Object,Object,Object);;Argument[1..5];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object);;Argument[1..6];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object);;Argument[1..7];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..8];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..9];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..10];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object[]);;Argument[1..11];logging;manual", - ";(String,Object,boolean);;Argument[1];logging;manual", - ";(String,Object,char);;Argument[1];logging;manual", - ";(String,Object,byte);;Argument[1];logging;manual", - ";(String,Object,short);;Argument[1];logging;manual", - ";(String,Object,int);;Argument[1];logging;manual", - ";(String,Object,long);;Argument[1];logging;manual", - ";(String,Object,float);;Argument[1];logging;manual", - ";(String,Object,double);;Argument[1];logging;manual", - ";(String,boolean,Object);;Argument[2];logging;manual", - ";(String,char,Object);;Argument[2];logging;manual", - ";(String,byte,Object);;Argument[2];logging;manual", - ";(String,short,Object);;Argument[2];logging;manual", - ";(String,int,Object);;Argument[2];logging;manual", - ";(String,long,Object);;Argument[2];logging;manual", - ";(String,float,Object);;Argument[2];logging;manual", - ";(String,double,Object);;Argument[2];logging;manual" - ], - // java.lang.System$Logger - "java.lang;System$Logger;true;log;" + - [ - "(Level,Object);;Argument[1]", "(Level,String);;Argument[1]", - "(Level,String,Object[]);;Argument[1..2]", "(Level,String,Throwable);;Argument[1]", - "(Level,String,Supplier);;Argument[1..2]", - "(Level,String,Supplier,Throwable);;Argument[1..2]", - "(Level,ResourceBundle,String,Object[]);;Argument[2..3]", - "(Level,ResourceBundle,String,Throwable);;Argument[2]" - ] + ";logging;manual", - // java.util.logging.Logger - "java.util.logging;Logger;true;" + - ["config", "fine", "finer", "finest", "info", "severe", "warning"] + - ";;;Argument[0];logging;manual", - "java.util.logging;Logger;true;entering;(String,String);;Argument[0..1];logging;manual", - "java.util.logging;Logger;true;entering;(String,String,Object);;Argument[0..2];logging;manual", - "java.util.logging;Logger;true;entering;(String,String,Object[]);;Argument[0..2];logging;manual", - "java.util.logging;Logger;true;exiting;(String,String);;Argument[0..1];logging;manual", - "java.util.logging;Logger;true;exiting;(String,String,Object);;Argument[0..2];logging;manual", - "java.util.logging;Logger;true;log;(Level,String);;Argument[1];logging;manual", - "java.util.logging;Logger;true;log;(Level,String,Object);;Argument[1..2];logging;manual", - "java.util.logging;Logger;true;log;(Level,String,Object[]);;Argument[1..2];logging;manual", - "java.util.logging;Logger;true;log;(Level,String,Throwable);;Argument[1];logging;manual", - "java.util.logging;Logger;true;log;(Level,Supplier);;Argument[1];logging;manual", - "java.util.logging;Logger;true;log;(Level,Throwable,Supplier);;Argument[2];logging;manual", - "java.util.logging;Logger;true;log;(LogRecord);;Argument[0];logging;manual", - "java.util.logging;Logger;true;logp;(Level,String,String,String);;Argument[1..3];logging;manual", - "java.util.logging;Logger;true;logp;(Level,String,String,String,Object);;Argument[1..4];logging;manual", - "java.util.logging;Logger;true;logp;(Level,String,String,String,Object[]);;Argument[1..4];logging;manual", - "java.util.logging;Logger;true;logp;(Level,String,String,String,Throwable);;Argument[1..3];logging;manual", - "java.util.logging;Logger;true;logp;(Level,String,String,Supplier);;Argument[1..3];logging;manual", - "java.util.logging;Logger;true;logp;(Level,String,String,Throwable,Supplier);;Argument[1..2];logging;manual", - "java.util.logging;Logger;true;logp;(Level,String,String,Throwable,Supplier);;Argument[4];logging;manual", - "java.util.logging;Logger;true;logrb;(Level,String,String,ResourceBundle,String,Object[]);;Argument[1..2];logging;manual", - "java.util.logging;Logger;true;logrb;(Level,String,String,ResourceBundle,String,Object[]);;Argument[4..5];logging;manual", - "java.util.logging;Logger;true;logrb;(Level,String,String,ResourceBundle,String,Throwable);;Argument[1..2];logging;manual", - "java.util.logging;Logger;true;logrb;(Level,String,String,ResourceBundle,String,Throwable);;Argument[4];logging;manual", - "java.util.logging;Logger;true;logrb;(Level,String,String,String,String);;Argument[1..4];logging;manual", - "java.util.logging;Logger;true;logrb;(Level,String,String,String,String,Object);;Argument[1..5];logging;manual", - "java.util.logging;Logger;true;logrb;(Level,String,String,String,String,Object[]);;Argument[1..5];logging;manual", - "java.util.logging;Logger;true;logrb;(Level,String,String,String,String,Throwable);;Argument[1..4];logging;manual", - // android.util.Log - "android.util;Log;true;" + ["d", "v", "i", "w", "e", "wtf"] + - ";;;Argument[1];logging;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/MyBatis.qll b/java/ql/lib/semmle/code/java/frameworks/MyBatis.qll index 6c16bb168bb..64b32c78003 100644 --- a/java/ql/lib/semmle/code/java/frameworks/MyBatis.qll +++ b/java/ql/lib/semmle/code/java/frameworks/MyBatis.qll @@ -12,21 +12,6 @@ class MyBatisSqlRunner extends RefType { MyBatisSqlRunner() { this.hasQualifiedName("org.apache.ibatis.jdbc", "SqlRunner") } } -private class SqlSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "org.apache.ibatis.jdbc;SqlRunner;false;delete;(String,Object[]);;Argument[0];sql;manual", - "org.apache.ibatis.jdbc;SqlRunner;false;insert;(String,Object[]);;Argument[0];sql;manual", - "org.apache.ibatis.jdbc;SqlRunner;false;run;(String);;Argument[0];sql;manual", - "org.apache.ibatis.jdbc;SqlRunner;false;selectAll;(String,Object[]);;Argument[0];sql;manual", - "org.apache.ibatis.jdbc;SqlRunner;false;selectOne;(String,Object[]);;Argument[0];sql;manual", - "org.apache.ibatis.jdbc;SqlRunner;false;update;(String,Object[]);;Argument[0];sql;manual" - ] - } -} - /** The class `org.apache.ibatis.session.Configuration`. */ class IbatisConfiguration extends RefType { IbatisConfiguration() { this.hasQualifiedName("org.apache.ibatis.session", "Configuration") } @@ -144,74 +129,3 @@ private class MyBatisProviderStep extends TaintTracking::AdditionalValueStep { ) } } - -private class MyBatisAbstractSqlToStringStep extends SummaryModelCsv { - override predicate row(string row) { - row = "org.apache.ibatis.jdbc;AbstractSQL;true;toString;;;Argument[-1];ReturnValue;taint;manual" - } -} - -private class MyBatisAbstractSqlMethodsStep extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.ibatis.jdbc;AbstractSQL;true;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;WHERE;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;WHERE;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;WHERE;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;WHERE;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;VALUES;(String,String);;Argument[0..1];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;UPDATE;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SET;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SET;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SET;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SET;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SELECT_DISTINCT;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SELECT_DISTINCT;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SELECT_DISTINCT;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SELECT_DISTINCT;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SELECT;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;RIGHT_OUTER_JOIN;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;RIGHT_OUTER_JOIN;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;RIGHT_OUTER_JOIN;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;RIGHT_OUTER_JOIN;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;OUTER_JOIN;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;OUTER_JOIN;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;OUTER_JOIN;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;OUTER_JOIN;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;ORDER_BY;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;ORDER_BY;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;ORDER_BY;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;ORDER_BY;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;OFFSET_ROWS;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;OFFSET;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;LIMIT;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;LEFT_OUTER_JOIN;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;LEFT_OUTER_JOIN;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;LEFT_OUTER_JOIN;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;LEFT_OUTER_JOIN;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;JOIN;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;INTO_VALUES;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;INTO_COLUMNS;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;INSERT_INTO;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;INNER_JOIN;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;INNER_JOIN;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;INNER_JOIN;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;INNER_JOIN;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;HAVING;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;HAVING;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;HAVING;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;HAVING;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;GROUP_BY;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;GROUP_BY;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;GROUP_BY;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;GROUP_BY;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;FROM;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;FROM;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;FROM;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;FROM;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;FETCH_FIRST_ROWS_ONLY;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;DELETE_FROM;(String);;Argument[0];Argument[-1];taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Objects.qll b/java/ql/lib/semmle/code/java/frameworks/Objects.qll deleted file mode 100644 index 1a7bbe8ef17..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/Objects.qll +++ /dev/null @@ -1,18 +0,0 @@ -/** Definitions of taint steps in Objects class of the JDK */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class ObjectsSummaryCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "java.util;Objects;false;requireNonNull;;;Argument[0];ReturnValue;value;manual", - "java.util;Objects;false;requireNonNullElse;;;Argument[0];ReturnValue;value;manual", - "java.util;Objects;false;requireNonNullElse;;;Argument[1];ReturnValue;value;manual", - "java.util;Objects;false;requireNonNullElseGet;;;Argument[0];ReturnValue;value;manual", - "java.util;Objects;false;toString;;;Argument[1];ReturnValue;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/OkHttp.qll b/java/ql/lib/semmle/code/java/frameworks/OkHttp.qll deleted file mode 100644 index f541eb983ee..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/OkHttp.qll +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Provides classes and predicates for working with the OkHttp client. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class OkHttpOpenUrlSinks extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "okhttp3;Request;true;Request;;;Argument[0];open-url;manual", - "okhttp3;Request$Builder;true;url;;;Argument[0];open-url;manual" - ] - } -} - -private class OKHttpSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "okhttp3;HttpUrl;false;parse;;;Argument[0];ReturnValue;taint;manual", - "okhttp3;HttpUrl;false;uri;;;Argument[-1];ReturnValue;taint;manual", - "okhttp3;HttpUrl;false;url;;;Argument[-1];ReturnValue;taint;manual", - "okhttp3;HttpUrl$Builder;false;addEncodedPathSegment;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;addEncodedPathSegment;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;addEncodedPathSegments;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;addEncodedPathSegments;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;addEncodedQueryParameter;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;addEncodedQueryParameter;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;addPathSegment;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;addPathSegment;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;addPathSegments;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;addPathSegments;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;addQueryParameter;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;addQueryParameter;;;Argument[0..1];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "okhttp3;HttpUrl$Builder;false;encodedFragment;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;encodedFragment;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;encodedPassword;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;encodedPath;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;encodedPath;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;encodedQuery;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;encodedQuery;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;encodedUsername;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;fragment;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;fragment;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;host;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;host;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;password;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;port;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;port;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;query;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;query;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;removeAllEncodedQueryParameters;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;removeAllQueryParameters;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;removePathSegment;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;scheme;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;scheme;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;setEncodedPathSegment;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;setEncodedPathSegment;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;setEncodedQueryParameter;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;setEncodedQueryParameter;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;setPathSegment;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;setPathSegment;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;setQueryParameter;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;setQueryParameter;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;username;;;Argument[-1];ReturnValue;value;manual", - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Optional.qll b/java/ql/lib/semmle/code/java/frameworks/Optional.qll deleted file mode 100644 index 7716154a883..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/Optional.qll +++ /dev/null @@ -1,30 +0,0 @@ -/** Definitions related to `java.util.Optional`. */ - -private import semmle.code.java.dataflow.ExternalFlow - -private class OptionalModel extends SummaryModelCsv { - override predicate row(string s) { - s = - [ - "java.util;Optional;false;filter;;;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Optional;false;filter;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util;Optional;false;flatMap;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util;Optional;false;flatMap;;;Argument[0].ReturnValue;ReturnValue;value;manual", - "java.util;Optional;false;get;;;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Optional;false;ifPresent;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util;Optional;false;ifPresentOrElse;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util;Optional;false;map;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util;Optional;false;map;;;Argument[0].ReturnValue;ReturnValue.Element;value;manual", - "java.util;Optional;false;of;;;Argument[0];ReturnValue.Element;value;manual", - "java.util;Optional;false;ofNullable;;;Argument[0];ReturnValue.Element;value;manual", - "java.util;Optional;false;or;;;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Optional;false;or;;;Argument[0].ReturnValue;ReturnValue;value;manual", - "java.util;Optional;false;orElse;;;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Optional;false;orElse;;;Argument[0];ReturnValue;value;manual", - "java.util;Optional;false;orElseGet;;;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Optional;false;orElseGet;;;Argument[0].ReturnValue;ReturnValue;value;manual", - "java.util;Optional;false;orElseThrow;;;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Optional;false;stream;;;Argument[-1].Element;ReturnValue.Element;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/RabbitMQ.qll b/java/ql/lib/semmle/code/java/frameworks/RabbitMQ.qll deleted file mode 100644 index 4f94cd295a8..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/RabbitMQ.qll +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Provides classes and predicates related to RabbitMQ. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -/** - * Defines remote sources in RabbitMQ. - */ -private class RabbitMQSource extends SourceModelCsv { - override predicate row(string row) { - row = - [ - // soruces for RabbitMQ 4.x - "com.rabbitmq.client;Command;true;getContentHeader;();;ReturnValue;remote;manual", - "com.rabbitmq.client;Command;true;getContentBody;();;ReturnValue;remote;manual", - "com.rabbitmq.client;Consumer;true;handleDelivery;(String,Envelope,BasicProperties,byte[]);;Parameter[3];remote;manual", - "com.rabbitmq.client;QueueingConsumer;true;nextDelivery;;;ReturnValue;remote;manual", - "com.rabbitmq.client;RpcServer;true;handleCall;(Delivery,BasicProperties);;Parameter[0];remote;manual", - "com.rabbitmq.client;RpcServer;true;handleCall;(BasicProperties,byte[],BasicProperties);;Parameter[1];remote;manual", - "com.rabbitmq.client;RpcServer;true;handleCall;(byte[],BasicProperties);;Parameter[0];remote;manual", - "com.rabbitmq.client;RpcServer;true;preprocessReplyProperties;(Delivery,Builder);;Parameter[0];remote;manual", - "com.rabbitmq.client;RpcServer;true;postprocessReplyProperties;(Delivery,Builder);;Parameter[0];remote;manual", - "com.rabbitmq.client;RpcServer;true;handleCast;(Delivery);;Parameter[0];remote;manual", - "com.rabbitmq.client;RpcServer;true;handleCast;(BasicProperties,byte[]);;Parameter[1];remote;manual", - "com.rabbitmq.client;RpcServer;true;handleCast;(byte[]);;Parameter[0];remote;manual", - "com.rabbitmq.client;StringRpcServer;true;handleStringCall;;;Parameter[0];remote;manual", - "com.rabbitmq.client;RpcClient;true;doCall;;;ReturnValue;remote;manual", - "com.rabbitmq.client;RpcClient;true;primitiveCall;;;ReturnValue;remote;manual", - "com.rabbitmq.client;RpcClient;true;responseCall;;;ReturnValue;remote;manual", - "com.rabbitmq.client;RpcClient;true;stringCall;(String);;ReturnValue;remote;manual", - "com.rabbitmq.client;RpcClient;true;mapCall;;;ReturnValue;remote;manual", - "com.rabbitmq.client.impl;Frame;true;getInputStream;();;ReturnValue;remote;manual", - "com.rabbitmq.client.impl;Frame;true;getPayload;();;ReturnValue;remote;manual", - "com.rabbitmq.client.impl;FrameHandler;true;readFrame;();;ReturnValue;remote;manual", - ] - } -} - -/** - * Defines flow steps in RabbitMQ. - */ -private class RabbitMQSummaryCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - // flow steps for RabbitMQ 4.x - "com.rabbitmq.client;GetResponse;true;GetResponse;;;Argument[2];Argument[-1];taint;manual", - "com.rabbitmq.client;GetResponse;true;getBody;();;Argument[-1];ReturnValue;taint;manual", - "com.rabbitmq.client;RpcClient$Response;true;getBody;();;Argument[-1];ReturnValue;taint;manual", - "com.rabbitmq.client;QueueingConsumer$Delivery;true;getBody;();;Argument[-1];ReturnValue;taint;manual", - "com.rabbitmq.client.impl;Frame;false;fromBodyFragment;(int,byte[],int,int);;Argument[1];ReturnValue;taint;manual", - "com.rabbitmq.client.impl;Frame;false;readFrom;(DataInputStream);;Argument[0];ReturnValue;taint;manual", - "com.rabbitmq.client.impl;Frame;true;writeTo;(DataOutputStream);;Argument[-1];Argument[0];taint;manual", - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Regex.qll b/java/ql/lib/semmle/code/java/frameworks/Regex.qll index 790255c9703..687e983eab6 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Regex.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Regex.qll @@ -22,20 +22,3 @@ class PatternLiteralField extends Field { this.hasName("LITERAL") } } - -private class RegexModel extends SummaryModelCsv { - override predicate row(string s) { - s = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "java.util.regex;Matcher;false;group;;;Argument[-1];ReturnValue;taint;manual", - "java.util.regex;Matcher;false;replaceAll;;;Argument[-1];ReturnValue;taint;manual", - "java.util.regex;Matcher;false;replaceAll;;;Argument[0];ReturnValue;taint;manual", - "java.util.regex;Matcher;false;replaceFirst;;;Argument[-1];ReturnValue;taint;manual", - "java.util.regex;Matcher;false;replaceFirst;;;Argument[0];ReturnValue;taint;manual", - "java.util.regex;Pattern;false;matcher;;;Argument[0];ReturnValue;taint;manual", - "java.util.regex;Pattern;false;quote;;;Argument[0];ReturnValue;taint;manual", - "java.util.regex;Pattern;false;split;;;Argument[0];ReturnValue;taint;manual", - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Retrofit.qll b/java/ql/lib/semmle/code/java/frameworks/Retrofit.qll deleted file mode 100644 index db79cb84515..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/Retrofit.qll +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Provides classes and predicates for working with the Retrofit API client. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class RetrofitOpenUrlSinks extends SinkModelCsv { - override predicate row(string row) { - row = "retrofit2;Retrofit$Builder;true;baseUrl;;;Argument[0];open-url;manual" - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/SpringJdbc.qll b/java/ql/lib/semmle/code/java/frameworks/SpringJdbc.qll index f0a75c8f3b9..fb729f5c00e 100644 --- a/java/ql/lib/semmle/code/java/frameworks/SpringJdbc.qll +++ b/java/ql/lib/semmle/code/java/frameworks/SpringJdbc.qll @@ -9,45 +9,3 @@ private import semmle.code.java.dataflow.ExternalFlow class JdbcTemplate extends RefType { JdbcTemplate() { this.hasQualifiedName("org.springframework.jdbc.core", "JdbcTemplate") } } - -private class SqlSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "org.springframework.jdbc.core;JdbcTemplate;false;batchUpdate;(String[]);;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;batchUpdate;;;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;execute;;;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;update;;;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;query;;;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;queryForList;;;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;queryForMap;;;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;queryForObject;;;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;queryForRowSet;;;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;queryForStream;;;Argument[0];sql;manual", - "org.springframework.jdbc.object;BatchSqlUpdate;false;BatchSqlUpdate;;;Argument[1];sql;manual", - "org.springframework.jdbc.object;MappingSqlQuery;false;BatchSqlUpdate;;;Argument[1];sql;manual", - "org.springframework.jdbc.object;MappingSqlQueryWithParameters;false;BatchSqlUpdate;;;Argument[1];sql;manual", - "org.springframework.jdbc.object;RdbmsOperation;true;setSql;;;Argument[0];sql;manual", - "org.springframework.jdbc.object;SqlCall;false;SqlCall;;;Argument[1];sql;manual", - "org.springframework.jdbc.object;SqlFunction;false;SqlFunction;;;Argument[1];sql;manual", - "org.springframework.jdbc.object;SqlQuery;false;SqlQuery;;;Argument[1];sql;manual", - "org.springframework.jdbc.object;SqlUpdate;false;SqlUpdate;;;Argument[1];sql;manual", - "org.springframework.jdbc.object;UpdatableSqlQuery;false;UpdatableSqlQuery;;;Argument[1];sql;manual" - ] - } -} - -private class SsrfSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "org.springframework.boot.jdbc;DataSourceBuilder;false;url;(String);;Argument[0];jdbc-url;manual", - "org.springframework.jdbc.datasource;AbstractDriverBasedDataSource;false;setUrl;(String);;Argument[0];jdbc-url;manual", - "org.springframework.jdbc.datasource;DriverManagerDataSource;false;DriverManagerDataSource;(String);;Argument[0];jdbc-url;manual", - "org.springframework.jdbc.datasource;DriverManagerDataSource;false;DriverManagerDataSource;(String,String,String);;Argument[0];jdbc-url;manual", - "org.springframework.jdbc.datasource;DriverManagerDataSource;false;DriverManagerDataSource;(String,Properties);;Argument[0];jdbc-url;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Stream.qll b/java/ql/lib/semmle/code/java/frameworks/Stream.qll index 0c1347044c5..af157d78740 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Stream.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Stream.qll @@ -96,95 +96,3 @@ private class RequiredComponentStackForCollect extends RequiredSummaryComponentS tail = SummaryComponentStack::return() } } - -private class StreamModel extends SummaryModelCsv { - override predicate row(string s) { - s = - [ - "java.util.stream;BaseStream;true;iterator;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;BaseStream;true;onClose;(Runnable);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;BaseStream;true;parallel;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;BaseStream;true;sequential;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;BaseStream;true;spliterator;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;BaseStream;true;unordered;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;allMatch;(Predicate);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;anyMatch;(Predicate);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;Argument[1].Parameter[0];value;manual", - "java.util.stream;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[1].Parameter[0];ReturnValue;value;manual", - "java.util.stream;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[1].Parameter[0];Argument[2].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[2].Parameter[0..1];Argument[1].Parameter[0];value;manual", - "java.util.stream;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[-1].Element;Argument[1].Parameter[1];value;manual", - // collect(Collector collector) is handled separately on a case-by-case basis as it is too complex for MaD - "java.util.stream;Stream;true;concat;(Stream,Stream);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;distinct;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;dropWhile;(Predicate);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;dropWhile;(Predicate);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;filter;(Predicate);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;filter;(Predicate);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;findAny;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;findFirst;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;flatMap;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;flatMap;(Function);;Argument[0].ReturnValue.Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;flatMapToDouble;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;flatMapToInt;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;flatMapToLong;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;forEach;(Consumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;forEachOrdered;(Consumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;generate;(Supplier);;Argument[0].ReturnValue;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;iterate;(Object,Predicate,UnaryOperator);;Argument[0];ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;iterate;(Object,Predicate,UnaryOperator);;Argument[0];Argument[1..2].Parameter[0];value;manual", - "java.util.stream;Stream;true;iterate;(Object,Predicate,UnaryOperator);;Argument[2].ReturnValue;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;iterate;(Object,Predicate,UnaryOperator);;Argument[2].ReturnValue;Argument[1..2].Parameter[0];value;manual", - "java.util.stream;Stream;true;iterate;(Object,UnaryOperator);;Argument[0];ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;iterate;(Object,UnaryOperator);;Argument[0];Argument[1].Parameter[0];value;manual", - "java.util.stream;Stream;true;iterate;(Object,UnaryOperator);;Argument[1].ReturnValue;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;iterate;(Object,UnaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0];value;manual", - "java.util.stream;Stream;true;limit;(long);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;map;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;map;(Function);;Argument[0].ReturnValue;ReturnValue.Element;value;manual", - // Missing for mapMulti(BiConsumer) (not currently supported): - // Argument[0] of Parameter[1] of Argument[0] -> Element of Parameter[1] of Argument[0] - // Element of Parameter[1] of Argument[0] -> Element of ReturnValue - "java.util.stream;Stream;true;mapMulti;(BiConsumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;mapMultiToDouble;(BiConsumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;mapMultiToInt;(BiConsumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;mapMultiToLong;(BiConsumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;mapToDouble;(ToDoubleFunction);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;mapToInt;(ToIntFunction);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;mapToLong;(ToLongFunction);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;max;(Comparator);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;max;(Comparator);;Argument[-1].Element;Argument[0].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;min;(Comparator);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;min;(Comparator);;Argument[-1].Element;Argument[0].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;noneMatch;(Predicate);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;of;(Object);;Argument[0];ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;of;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;ofNullable;(Object);;Argument[0];ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;peek;(Consumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;peek;(Consumer);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;reduce;(BinaryOperator);;Argument[-1].Element;Argument[0].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;reduce;(BinaryOperator);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;Argument[0].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;reduce;(Object,BinaryOperator);;Argument[-1].Element;Argument[1].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];Argument[1].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];ReturnValue;value;manual", - "java.util.stream;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;ReturnValue;value;manual", - "java.util.stream;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[-1].Element;Argument[1].Parameter[1];value;manual", - "java.util.stream;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[1].Parameter[0];value;manual", - "java.util.stream;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[2].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];ReturnValue;value;manual", - "java.util.stream;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1..2].ReturnValue;Argument[1].Parameter[0];value;manual", - "java.util.stream;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1..2].ReturnValue;Argument[2].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1..2].ReturnValue;ReturnValue;value;manual", - "java.util.stream;Stream;true;skip;(long);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;sorted;;;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;sorted;(Comparator);;Argument[-1].Element;Argument[0].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;takeWhile;(Predicate);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;takeWhile;(Predicate);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;toArray;;;Argument[-1].Element;ReturnValue.ArrayElement;value;manual", - "java.util.stream;Stream;true;toList;();;Argument[-1].Element;ReturnValue.Element;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Strings.qll b/java/ql/lib/semmle/code/java/frameworks/Strings.qll deleted file mode 100644 index c09b959254d..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/Strings.qll +++ /dev/null @@ -1,70 +0,0 @@ -/** Definitions of taint steps in String and String-related classes of the JDK */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class StringSummaryCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "java.lang;String;false;concat;(String);;Argument[0];ReturnValue;taint;manual", - "java.lang;String;false;concat;(String);;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;copyValueOf;;;Argument[0];ReturnValue;taint;manual", - "java.lang;String;false;endsWith;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;format;(Locale,String,Object[]);;Argument[1];ReturnValue;taint;manual", - "java.lang;String;false;format;(Locale,String,Object[]);;Argument[2].ArrayElement;ReturnValue;taint;manual", - "java.lang;String;false;format;(String,Object[]);;Argument[0];ReturnValue;taint;manual", - "java.lang;String;false;format;(String,Object[]);;Argument[1].ArrayElement;ReturnValue;taint;manual", - "java.lang;String;false;formatted;(Object[]);;Argument[-1];ReturnValue;taint;manual", - "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;replace;;;Argument[1];ReturnValue;taint;manual", - "java.lang;String;false;replaceAll;;;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;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", - "java.lang;String;false;stripIndent;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;stripLeading;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;stripTrailing;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;substring;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;toCharArray;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;toLowerCase;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;toString;;;Argument[-1];ReturnValue;value;manual", - "java.lang;String;false;toUpperCase;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;translateEscapes;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;trim;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;valueOf;(char);;Argument[0];ReturnValue;taint;manual", - "java.lang;String;false;valueOf;(char[],int,int);;Argument[0];ReturnValue;taint;manual", - "java.lang;String;false;valueOf;(char[]);;Argument[0];ReturnValue;taint;manual", - "java.lang;AbstractStringBuilder;true;AbstractStringBuilder;(String);;Argument[0];Argument[-1];taint;manual", - "java.lang;AbstractStringBuilder;true;append;;;Argument[0];Argument[-1];taint;manual", - "java.lang;AbstractStringBuilder;true;append;;;Argument[-1];ReturnValue;value;manual", - "java.lang;AbstractStringBuilder;true;getChars;;;Argument[-1];Argument[2];taint;manual", - "java.lang;AbstractStringBuilder;true;insert;;;Argument[1];Argument[-1];taint;manual", - "java.lang;AbstractStringBuilder;true;insert;;;Argument[-1];ReturnValue;value;manual", - "java.lang;AbstractStringBuilder;true;replace;;;Argument[-1];ReturnValue;value;manual", - "java.lang;AbstractStringBuilder;true;replace;;;Argument[2];Argument[-1];taint;manual", - "java.lang;AbstractStringBuilder;true;reverse;;;Argument[-1];ReturnValue;value;manual", - "java.lang;AbstractStringBuilder;true;subSequence;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;AbstractStringBuilder;true;substring;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;AbstractStringBuilder;true;toString;;;Argument[-1];ReturnValue;taint;manual", - "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/lib/semmle/code/java/frameworks/Thymeleaf.qll b/java/ql/lib/semmle/code/java/frameworks/Thymeleaf.qll deleted file mode 100644 index 3c550d5441c..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/Thymeleaf.qll +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Provides classes and predicates for working with the Thymeleaf template engine. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class ThymeleafSummaryModels extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.thymeleaf;TemplateSpec;false;TemplateSpec;;;Argument[0];Argument[-1];taint;manual", - "org.thymeleaf;TemplateSpec;false;getTemplate;;;Argument[-1];ReturnValue;taint;manual", - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Android.qll b/java/ql/lib/semmle/code/java/frameworks/android/Android.qll index 30f087408af..7b76302bc05 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Android.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Android.qll @@ -103,74 +103,6 @@ class AndroidContentResolver extends AndroidComponent { } } -private class UriModel extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "android.net;Uri;true;buildUpon;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;false;decode;;;Argument[0];ReturnValue;taint;manual", - "android.net;Uri;false;encode;;;Argument[0];ReturnValue;taint;manual", - "android.net;Uri;false;fromFile;;;Argument[0];ReturnValue;taint;manual", - "android.net;Uri;false;fromParts;;;Argument[0..2];ReturnValue;taint;manual", - "android.net;Uri;true;getAuthority;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getEncodedAuthority;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getEncodedFragment;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getEncodedPath;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getEncodedQuery;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getEncodedSchemeSpecificPart;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getEncodedUserInfo;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getFragment;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getHost;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getLastPathSegment;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getPath;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getPathSegments;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getQuery;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getQueryParameter;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getQueryParameterNames;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getQueryParameters;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getScheme;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getSchemeSpecificPart;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getUserInfo;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;normalizeScheme;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;false;parse;;;Argument[0];ReturnValue;taint;manual", - "android.net;Uri;true;toString;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;false;withAppendedPath;;;Argument[0..1];ReturnValue;taint;manual", - "android.net;Uri;false;writeToParcel;;;Argument[1];Argument[0];taint;manual", - "android.net;Uri$Builder;false;appendEncodedPath;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;appendEncodedPath;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;appendPath;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;appendPath;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;appendQueryParameter;;;Argument[0..1];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;appendQueryParameter;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;authority;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;authority;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri$Builder;false;clearQuery;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;encodedAuthority;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;encodedAuthority;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;encodedFragment;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;encodedFragment;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;encodedOpaquePart;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;encodedOpaquePart;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;encodedPath;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;encodedPath;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;encodedQuery;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;encodedQuery;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;fragment;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;fragment;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;opaquePart;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;opaquePart;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;path;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;path;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;query;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;query;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;scheme;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;scheme;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;toString;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} - /** Interface for classes whose instances can be written to and restored from a Parcel. */ class TypeParcelable extends Interface { TypeParcelable() { this.hasQualifiedName("android.os", "Parcelable") } @@ -185,29 +117,3 @@ class CreateFromParcelMethod extends Method { this.getEnclosingCallable().getDeclaringType().getAnAncestor() instanceof TypeParcelable } } - -private class ParcelPropagationModels extends SummaryModelCsv { - override predicate row(string s) { - // Parcel readers that return their value - s = - "android.os;Parcel;false;read" + - [ - "Array", "ArrayList", "Boolean", "Bundle", "Byte", "Double", "FileDescriptor", "Float", - "HashMap", "Int", "Long", "Parcelable", "ParcelableArray", "PersistableBundle", - "Serializable", "Size", "SizeF", "SparseArray", "SparseBooleanArray", "String", - "StrongBinder", "TypedObject", "Value" - ] + ";;;Argument[-1];ReturnValue;taint;manual" - or - // Parcel readers that write to an existing object - s = - "android.os;Parcel;false;read" + - [ - "BinderArray", "BinderList", "BooleanArray", "ByteArray", "CharArray", "DoubleArray", - "FloatArray", "IntArray", "List", "LongArray", "Map", "ParcelableList", "StringArray", - "StringList", "TypedArray", "TypedList" - ] + ";;;Argument[-1];Argument[0];taint;manual" - or - // One Parcel method that aliases an argument to a return value - s = "android.os;Parcel;false;readParcelableList;;;Argument[0];ReturnValue;value;manual" - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/ContentProviders.qll b/java/ql/lib/semmle/code/java/frameworks/android/ContentProviders.qll index bf47e98b8fb..df51d59063e 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/ContentProviders.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/ContentProviders.qll @@ -9,107 +9,3 @@ private import semmle.code.java.dataflow.ExternalFlow class ContentValues extends Class { ContentValues() { this.hasQualifiedName("android.content", "ContentValues") } } - -private class ContentProviderSourceModels extends SourceModelCsv { - override predicate row(string row) { - row = - [ - // ContentInterface models are here for backwards compatibility (it was removed in API 28) - "android.content;ContentInterface;true;call;(String,String,String,Bundle);;Parameter[0..3];contentprovider;manual", - "android.content;ContentProvider;true;call;(String,String,String,Bundle);;Parameter[0..3];contentprovider;manual", - "android.content;ContentProvider;true;call;(String,String,Bundle);;Parameter[0..2];contentprovider;manual", - "android.content;ContentProvider;true;delete;(Uri,String,String[]);;Parameter[0..2];contentprovider;manual", - "android.content;ContentInterface;true;delete;(Uri,Bundle);;Parameter[0..1];contentprovider;manual", - "android.content;ContentProvider;true;delete;(Uri,Bundle);;Parameter[0..1];contentprovider;manual", - "android.content;ContentInterface;true;getType;(Uri);;Parameter[0];contentprovider;manual", - "android.content;ContentProvider;true;getType;(Uri);;Parameter[0];contentprovider;manual", - "android.content;ContentInterface;true;insert;(Uri,ContentValues,Bundle);;Parameter[0];contentprovider;manual", - "android.content;ContentProvider;true;insert;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider;manual", - "android.content;ContentProvider;true;insert;(Uri,ContentValues);;Parameter[0..1];contentprovider;manual", - "android.content;ContentInterface;true;openAssetFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider;manual", - "android.content;ContentProvider;true;openAssetFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider;manual", - "android.content;ContentProvider;true;openAssetFile;(Uri,String);;Parameter[0];contentprovider;manual", - "android.content;ContentInterface;true;openTypedAssetFile;(Uri,String,Bundle,CancellationSignal);;Parameter[0..2];contentprovider;manual", - "android.content;ContentProvider;true;openTypedAssetFile;(Uri,String,Bundle,CancellationSignal);;Parameter[0..2];contentprovider;manual", - "android.content;ContentProvider;true;openTypedAssetFile;(Uri,String,Bundle);;Parameter[0..2];contentprovider;manual", - "android.content;ContentInterface;true;openFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider;manual", - "android.content;ContentProvider;true;openFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider;manual", - "android.content;ContentProvider;true;openFile;(Uri,String);;Parameter[0];contentprovider;manual", - "android.content;ContentInterface;true;query;(Uri,String[],Bundle,CancellationSignal);;Parameter[0..2];contentprovider;manual", - "android.content;ContentProvider;true;query;(Uri,String[],Bundle,CancellationSignal);;Parameter[0..2];contentprovider;manual", - "android.content;ContentProvider;true;query;(Uri,String[],String,String[],String);;Parameter[0..4];contentprovider;manual", - "android.content;ContentProvider;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Parameter[0..4];contentprovider;manual", - "android.content;ContentInterface;true;update;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider;manual", - "android.content;ContentProvider;true;update;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider;manual", - "android.content;ContentProvider;true;update;(Uri,ContentValues,String,String[]);;Parameter[0..3];contentprovider;manual" - ] - } -} - -private class SummaryModels extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "android.content;ContentValues;false;put;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.content;ContentValues;false;put;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.content;ContentValues;false;putAll;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "android.content;ContentValues;false;putAll;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "android.content;ContentResolver;true;acquireContentProviderClient;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;acquireUnstableContentProviderClient;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;applyBatch;;;Argument[1];ReturnValue;taint;manual", - "android.content;ContentResolver;true;call;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;canonicalize;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;getStreamTypes;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;getType;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;insert;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;query;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;uncanonicalize;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;wrap;;;Argument[0];ReturnValue;taint;manual", - // ContentProviderClient is tainted at its creation, not by its arguments - "android.content;ContentProviderClient;true;applyBatch;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderClient;true;call;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderClient;true;canonicalize;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderClient;true;getLocalContentProvider;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderClient;true;getStreamTypes;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderClient;true;insert;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderClient;true;query;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderClient;true;uncanonicalize;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;apply;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;apply;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;getUri;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;newAssertQuery;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;newCall;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;newDelete;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;newInsert;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;newUpdate;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;resolveExtrasBackReferences;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;resolveSelectionArgsBackReferences;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;resolveValueBackReferences;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation$Builder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderOperation$Builder;false;withExceptionAllowed;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withExpectedCount;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withExtra;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withExtraBackReference;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withExtras;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withSelection;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withSelectionBackReference;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withValue;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withValueBackReference;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withValues;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withYieldAllowed;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderResult;false;ContentProviderResult;(Uri);;Argument[0];Argument[-1].Field[android.content.ContentProviderResult.uri];value;manual", - "android.content;ContentProviderResult;false;ContentProviderResult;(Bundle);;Argument[0];Argument[-1].Field[android.content.ContentProviderResult.extras];value;manual", - "android.content;ContentProviderResult;false;ContentProviderResult;(Throwable);;Argument[0];Argument[-1].Field[android.content.ContentProviderResult.exception];value;manual", - "android.content;ContentProviderResult;false;ContentProviderResult;(Parcel);;Argument[0];Argument[-1];taint;manual", - "android.database;Cursor;true;copyStringToBuffer;;;Argument[-1];Argument[1];taint;manual", - "android.database;Cursor;true;getBlob;;;Argument[-1];ReturnValue;taint;manual", - "android.database;Cursor;true;getColumnName;;;Argument[-1];ReturnValue;taint;manual", - "android.database;Cursor;true;getColumnNames;;;Argument[-1];ReturnValue;taint;manual", - "android.database;Cursor;true;getExtras;;;Argument[-1];ReturnValue;taint;manual", - "android.database;Cursor;true;getNotificationUri;;;Argument[-1];ReturnValue;taint;manual", - "android.database;Cursor;true;getNotificationUris;;;Argument[-1];ReturnValue;taint;manual", - "android.database;Cursor;true;getString;;;Argument[-1];ReturnValue;taint;manual", - "android.database;Cursor;true;respond;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll index 1e6919c023b..7eb088a9514 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll @@ -5,21 +5,6 @@ private import semmle.code.java.security.FileReadWrite private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow -private class ExternalStorageDirSourceModel extends SourceModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "android.content;Context;true;getExternalFilesDir;(String);;ReturnValue;android-external-storage-dir;manual", - "android.content;Context;true;getExternalFilesDirs;(String);;ReturnValue;android-external-storage-dir;manual", - "android.content;Context;true;getExternalCacheDir;();;ReturnValue;android-external-storage-dir;manual", - "android.content;Context;true;getExternalCacheDirs;();;ReturnValue;android-external-storage-dir;manual", - "android.os;Environment;false;getExternalStorageDirectory;();;ReturnValue;android-external-storage-dir;manual", - "android.os;Environment;false;getExternalStoragePublicDirectory;(String);;ReturnValue;android-external-storage-dir;manual", - ] - } -} - private predicate externalStorageFlowStep(DataFlow::Node node1, DataFlow::Node node2) { DataFlow::localFlowStep(node1, node2) or diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Intent.qll b/java/ql/lib/semmle/code/java/frameworks/android/Intent.qll index e37e7f350b8..4f6e9e3f5e4 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Intent.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Intent.qll @@ -421,196 +421,3 @@ private class StartServiceIntentStep extends AdditionalValueStep { ) } } - -private class IntentBundleFlowSteps extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"namespace;type;subtypes;name;signature;ext;input;output;kind" - "android.os;BaseBundle;true;get;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;BaseBundle;true;getString;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;BaseBundle;true;getString;(String,String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;BaseBundle;true;getString;(String,String);;Argument[1];ReturnValue;value;manual", - "android.os;BaseBundle;true;getStringArray;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;BaseBundle;true;keySet;();;Argument[-1].MapKey;ReturnValue.Element;value;manual", - "android.os;BaseBundle;true;putAll;(PersistableBundle);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putAll;(PersistableBundle);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "android.os;BaseBundle;true;putBoolean;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putBooleanArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putDouble;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putDoubleArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putInt;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putIntArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putLong;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putLongArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putString;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putString;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;BaseBundle;true;putStringArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putStringArray;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;false;Bundle;(Bundle);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "android.os;Bundle;false;Bundle;(Bundle);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "android.os;Bundle;false;Bundle;(PersistableBundle);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "android.os;Bundle;false;Bundle;(PersistableBundle);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;clone;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "android.os;Bundle;true;clone;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - // model for Bundle.deepCopy is not fully precise, as some map values aren't copied by value - "android.os;Bundle;true;deepCopy;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "android.os;Bundle;true;deepCopy;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "android.os;Bundle;true;getBinder;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getBundle;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getByteArray;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getCharArray;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getCharSequence;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getCharSequence;(String,CharSequence);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getCharSequence;(String,CharSequence);;Argument[1];ReturnValue;value;manual", - "android.os;Bundle;true;getCharSequenceArray;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getCharSequenceArrayList;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getParcelable;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getParcelableArray;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getParcelableArrayList;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getSerializable;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getSparseParcelableArray;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getStringArrayList;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;putAll;(Bundle);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putAll;(Bundle);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putBinder;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putBinder;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putBundle;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putBundle;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putByte;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putByteArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putByteArray;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putChar;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putCharArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putCharArray;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putCharSequence;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putCharSequence;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putCharSequenceArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putCharSequenceArray;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putCharSequenceArrayList;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putCharSequenceArrayList;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putFloat;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putFloatArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putIntegerArrayList;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putParcelable;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putParcelable;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putParcelableArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putParcelableArray;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putParcelableArrayList;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putParcelableArrayList;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putSerializable;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putSerializable;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putShort;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putShortArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putSize;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putSizeF;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putSparseParcelableArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putSparseParcelableArray;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putStringArrayList;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putStringArrayList;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;readFromParcel;;;Argument[0];Argument[-1].MapKey;taint;manual", - "android.os;Bundle;true;readFromParcel;;;Argument[0];Argument[-1].MapValue;taint;manual", - // currently only the Extras part of the intent and the data field are fully modeled - "android.content;Intent;false;Intent;(Intent);;Argument[0].SyntheticField[android.content.Intent.extras].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;false;Intent;(Intent);;Argument[0].SyntheticField[android.content.Intent.extras].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;false;Intent;(String,Uri);;Argument[1];Argument[-1].SyntheticField[android.content.Intent.data];value;manual", - "android.content;Intent;false;Intent;(String,Uri,Context,Class);;Argument[1];Argument[-1].SyntheticField[android.content.Intent.data];value;manual", - "android.content;Intent;true;addCategory;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;addFlags;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;false;createChooser;;;Argument[0..2];ReturnValue.SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;getBundleExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getByteArrayExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getCharArrayExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getCharSequenceArrayExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getCharSequenceArrayListExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getCharSequenceExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getData;;;Argument[-1].SyntheticField[android.content.Intent.data];ReturnValue;value;manual", - "android.content;Intent;true;getDataString;;;Argument[-1].SyntheticField[android.content.Intent.data];ReturnValue;taint;manual", - "android.content;Intent;true;getExtras;();;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", - "android.content;Intent;false;getIntent;;;Argument[0];ReturnValue.SyntheticField[android.content.Intent.data];taint;manual", - "android.content;Intent;false;getIntentOld;;;Argument[0];ReturnValue.SyntheticField[android.content.Intent.data];taint;manual", - "android.content;Intent;true;getParcelableArrayExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getParcelableArrayListExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getParcelableExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getSerializableExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getStringArrayExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getStringArrayListExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getStringExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;false;parseUri;;;Argument[0];ReturnValue.SyntheticField[android.content.Intent.data];taint;manual", - "android.content;Intent;true;putCharSequenceArrayListExtra;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;putCharSequenceArrayListExtra;;;Argument[1];Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;putCharSequenceArrayListExtra;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;putExtra;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;putExtra;;;Argument[1];Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;putExtra;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;putExtras;(Bundle);;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;putExtras;(Bundle);;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;putExtras;(Bundle);;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;putExtras;(Intent);;Argument[0].SyntheticField[android.content.Intent.extras].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;putExtras;(Intent);;Argument[0].SyntheticField[android.content.Intent.extras].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;putExtras;(Intent);;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;putIntegerArrayListExtra;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;putIntegerArrayListExtra;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;putParcelableArrayListExtra;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;putParcelableArrayListExtra;;;Argument[1];Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;putParcelableArrayListExtra;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;putStringArrayListExtra;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;putStringArrayListExtra;;;Argument[1];Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;putStringArrayListExtra;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;replaceExtras;(Bundle);;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;replaceExtras;(Bundle);;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;replaceExtras;(Bundle);;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;replaceExtras;(Intent);;Argument[0].SyntheticField[android.content.Intent.extras].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;replaceExtras;(Intent);;Argument[0].SyntheticField[android.content.Intent.extras].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;replaceExtras;(Intent);;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setAction;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setClass;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setClassName;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setComponent;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setData;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setData;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.data];value;manual", - "android.content;Intent;true;setDataAndNormalize;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setDataAndNormalize;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.data];value;manual", - "android.content;Intent;true;setDataAndType;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setDataAndType;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.data];value;manual", - "android.content;Intent;true;setDataAndTypeAndNormalize;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setDataAndTypeAndNormalize;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.data];value;manual", - "android.content;Intent;true;setFlags;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setIdentifier;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setPackage;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setType;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setTypeAndNormalize;;;Argument[-1];ReturnValue;value;manual" - ] - } -} - -private class IntentComponentTaintSteps extends SummaryModelCsv { - override predicate row(string s) { - s = - [ - "android.content;Intent;true;Intent;(Intent);;Argument[0];Argument[-1];taint;manual", - "android.content;Intent;true;Intent;(Context,Class);;Argument[1];Argument[-1];taint;manual", - "android.content;Intent;true;Intent;(String,Uri,Context,Class);;Argument[3];Argument[-1];taint;manual", - "android.content;Intent;true;getIntent;(String);;Argument[0];ReturnValue;taint;manual", - "android.content;Intent;true;getIntentOld;(String);;Argument[0];ReturnValue;taint;manual", - "android.content;Intent;true;parseUri;(String,int);;Argument[0];ReturnValue;taint;manual", - "android.content;Intent;true;setPackage;;;Argument[0];Argument[-1];taint;manual", - "android.content;Intent;true;setClass;;;Argument[1];Argument[-1];taint;manual", - "android.content;Intent;true;setClassName;(Context,String);;Argument[1];Argument[-1];taint;manual", - "android.content;Intent;true;setClassName;(String,String);;Argument[0..1];Argument[-1];taint;manual", - "android.content;Intent;true;setComponent;;;Argument[0];Argument[-1];taint;manual", - "android.content;ComponentName;false;ComponentName;(String,String);;Argument[0..1];Argument[-1];taint;manual", - "android.content;ComponentName;false;ComponentName;(Context,String);;Argument[1];Argument[-1];taint;manual", - "android.content;ComponentName;false;ComponentName;(Context,Class);;Argument[1];Argument[-1];taint;manual", - "android.content;ComponentName;false;ComponentName;(Parcel);;Argument[0];Argument[-1];taint;manual", - "android.content;ComponentName;false;createRelative;(String,String);;Argument[0..1];ReturnValue;taint;manual", - "android.content;ComponentName;false;createRelative;(Context,String);;Argument[1];ReturnValue;taint;manual", - "android.content;ComponentName;false;flattenToShortString;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ComponentName;false;flattenToString;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ComponentName;false;getClassName;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ComponentName;false;getPackageName;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ComponentName;false;getShortClassName;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ComponentName;false;unflattenFromString;;;Argument[0];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Notifications.qll b/java/ql/lib/semmle/code/java/frameworks/android/Notifications.qll deleted file mode 100644 index 0f69f0bbe1d..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/android/Notifications.qll +++ /dev/null @@ -1,101 +0,0 @@ -/** Provides classes and predicates related to Android notifications. */ - -import java -private import semmle.code.java.dataflow.DataFlow -private import semmle.code.java.dataflow.ExternalFlow -private import semmle.code.java.dataflow.FlowSteps - -private class NotificationBuildersSummaryModels extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "android.app;Notification$Action;true;Action;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "android.app;Notification$Action;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", - "android.app;Notification$Action$Builder;true;Builder;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "android.app;Notification$Action$Builder;true;Builder;(Icon,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "android.app;Notification$Action$Builder;true;Builder;(Action);;Argument[0];Argument[-1];taint;manual", - "android.app;Notification$Action$Builder;true;addExtras;;;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.app;Notification$Action$Builder;true;addExtras;;;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.app;Notification$Action$Builder;true;build;;;Argument[-1];ReturnValue;taint;manual", - "android.app;Notification$Action$Builder;true;build;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue.SyntheticField[android.content.Intent.extras];value;manual", - "android.app;Notification$Action$Builder;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", - "androidx.core.app;NotificationCompat$Action;true;Action;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Action;true;Action;(IconCompat,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Action;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", - "androidx.core.app;NotificationCompat$Action$Builder;true;Builder;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Action$Builder;true;Builder;(IconCompat,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Action$Builder;true;Builder;(Action);;Argument[0];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Action$Builder;true;addExtras;;;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "androidx.core.app;NotificationCompat$Action$Builder;true;addExtras;;;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "androidx.core.app;NotificationCompat$Action$Builder;true;build;;;Argument[-1];ReturnValue;taint;manual", - "androidx.core.app;NotificationCompat$Action$Builder;true;build;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue.SyntheticField[android.content.Intent.extras];value;manual", - "androidx.core.app;NotificationCompat$Action$Builder;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", - "android.app;Notification$Builder;true;addAction;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "android.app;Notification$Builder;true;addAction;(Action);;Argument[0];Argument[-1];taint;manual", - "android.app;Notification$Builder;true;addExtras;;;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.app;Notification$Builder;true;addExtras;;;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.app;Notification$Builder;true;build;;;Argument[-1];ReturnValue;taint;manual", - "android.app;Notification$Builder;true;build;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue.Field[android.app.Notification.extras];value;manual", - "android.app;Notification$Builder;true;setContentIntent;;;Argument[0];Argument[-1];taint;manual", - "android.app;Notification$Builder;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", - "android.app;Notification$Builder;true;recoverBuilder;;;Argument[1];ReturnValue;taint;manual", - "android.app;Notification$Builder;true;setActions;;;Argument[0].ArrayElement;Argument[-1];taint;manual", - "android.app;Notification$Builder;true;setExtras;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras];value;manual", - "android.app;Notification$Builder;true;setDeleteIntent;;;Argument[0];Argument[-1];taint;manual", - "android.app;Notification$Builder;true;setPublicVersion;;;Argument[0];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Builder;true;addAction;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Builder;true;addAction;(Action);;Argument[0];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Builder;true;addExtras;;;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "androidx.core.app;NotificationCompat$Builder;true;addExtras;;;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "androidx.core.app;NotificationCompat$Builder;true;build;;;Argument[-1];ReturnValue;taint;manual", - "androidx.core.app;NotificationCompat$Builder;true;build;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue.Field[android.app.Notification.extras];value;manual", - "androidx.core.app;NotificationCompat$Builder;true;setContentIntent;;;Argument[0];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Builder;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", - "androidx.core.app;NotificationCompat$Builder;true;setExtras;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras];value;manual", - "androidx.core.app;NotificationCompat$Builder;true;setDeleteIntent;;;Argument[0];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Builder;true;setPublicVersion;;;Argument[0];Argument[-1];taint;manual", - "android.app;Notification$Style;true;build;;;Argument[-1];ReturnValue;taint;manual", - "android.app;Notification$BigPictureStyle;true;BigPictureStyle;(Builder);;Argument[0];Argument[-1];taint;manual", - "android.app;Notification$BigTextStyle;true;BigTextStyle;(Builder);;Argument[0];Argument[-1];taint;manual", - "android.app;Notification$InboxStyle;true;InboxStyle;(Builder);;Argument[0];Argument[-1];taint;manual", - "android.app;Notification$MediaStyle;true;MediaStyle;(Builder);;Argument[0];Argument[-1];taint;manual", - // Fluent models - ["android.app;Notification", "androidx.core.app;NotificationCompat"] + - "$Action$Builder;true;" + - [ - "addExtras", "addRemoteInput", "extend", "setAllowGeneratedReplies", - "setAuthenticationRequired", "setContextual", "setSemanticAction" - ] + ";;;Argument[-1];ReturnValue;value;manual", - ["android.app;Notification", "androidx.core.app;NotificationCompat"] + "$Builder;true;" + - [ - "addAction", "addExtras", "addPerson", "extend", "setActions", "setAutoCancel", - "setBadgeIconType", "setBubbleMetadata", "setCategory", "setChannelId", - "setChronometerCountDown", "setColor", "setColorized", "setContent", "setContentInfo", - "setContentIntent", "setContentText", "setContentTitle", "setCustomBigContentView", - "setCustomHeadsUpContentView", "setDefaults", "setDeleteIntent", "setExtras", "setFlag", - "setForegroundServiceBehavior", "setFullScreenIntent", "setGroup", - "setGroupAlertBehavior", "setGroupSummary", "setLargeIcon", "setLights", "setLocalOnly", - "setLocusId", "setNumber", "setOngoing", "setOnlyAlertOnce", "setPriority", - "setProgress", "setPublicVersion", "setRemoteInputHistory", "setSettingsText", - "setShortcutId", "setShowWhen", "setSmallIcon", "setSortKey", "setSound", "setStyle", - "setSubText", "setTicker", "setTimeoutAfter", "setUsesChronometer", "setVibrate", - "setVisibility", "setWhen" - ] + ";;;Argument[-1];ReturnValue;value;manual", - ["android.app;Notification", "androidx.core.app;NotificationCompat"] + - "$BigPictureStyle;true;" + - [ - "bigLargeIcon", "bigPicture", "setBigContentTitle", "setContentDescription", - "setSummaryText", "showBigPictureWhenCollapsed" - ] + ";;;Argument[-1];ReturnValue;value;manual", - ["android.app;Notification", "androidx.core.app;NotificationCompat"] + "$BigTextStyle;true;" - + ["bigText", "setBigContentTitle", "setSummaryText"] + - ";;;Argument[-1];ReturnValue;value;manual", - ["android.app;Notification", "androidx.core.app;NotificationCompat"] + "$InboxStyle;true;" + - ["addLine", "setBigContentTitle", "setSummaryText"] + - ";;;Argument[-1];ReturnValue;value;manual", - "android.app;Notification$MediaStyle;true;" + - ["setMediaSession", "setShowActionsInCompactView"] + - ";;;Argument[-1];ReturnValue;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/SQLite.qll b/java/ql/lib/semmle/code/java/frameworks/android/SQLite.qll index 5f1c1b19171..eb6765de9e4 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/SQLite.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/SQLite.qll @@ -41,138 +41,3 @@ class TypeSQLiteOpenHelper extends Class { class TypeSQLiteStatement extends Class { TypeSQLiteStatement() { this.hasQualifiedName("android.database.sqlite", "SQLiteStatement") } } - -private class SQLiteSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "android.database.sqlite;SQLiteDatabase;false;compileStatement;(String);;Argument[0];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;execSQL;(String);;Argument[0];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;execSQL;(String,Object[]);;Argument[0];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;execPerConnectionSQL;(String,Object[]);;Argument[0];sql;manual", - // query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) - // query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal) - // query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) - // query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) - // queryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal) - // queryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) - // Each String / String[] arg except for selectionArgs is a sink - "android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String,String);;Argument[0];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String,String);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String,String);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String,String);;Argument[4..7];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String);;Argument[0..2];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String);;Argument[4..6];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String);;Argument[3];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String);;Argument[5..8];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[3];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[5..8];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String);;Argument[3];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String);;Argument[4];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String);;Argument[6..9];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[3];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[4];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[6..9];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;rawQuery;(String,String[]);;Argument[0];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;rawQuery;(String,String[],CancellationSignal);;Argument[0];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;rawQueryWithFactory;(CursorFactory,String,String[],String);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;rawQueryWithFactory;(CursorFactory,String,String[],String,CancellationSignal);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;delete;(String,String,String[]);;Argument[0..1];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;update;(String,ContentValues,String,String[]);;Argument[0];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;update;(String,ContentValues,String,String[]);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;updateWithOnConflict;(String,ContentValues,String,String[],int);;Argument[0];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;updateWithOnConflict;(String,ContentValues,String,String[],int);;Argument[2];sql;manual", - "android.database;DatabaseUtils;false;longForQuery;(SQLiteDatabase,String,String[]);;Argument[1];sql;manual", - "android.database;DatabaseUtils;false;stringForQuery;(SQLiteDatabase,String,String[]);;Argument[1];sql;manual", - "android.database;DatabaseUtils;false;blobFileDescriptorForQuery;(SQLiteDatabase,String,String[]);;Argument[1];sql;manual", - "android.database;DatabaseUtils;false;createDbFromSqlStatements;(Context,String,int,String);;Argument[3];sql;manual", - "android.database;DatabaseUtils;false;queryNumEntries;(SQLiteDatabase,String);;Argument[1];sql;manual", - "android.database;DatabaseUtils;false;queryNumEntries;(SQLiteDatabase,String,String);;Argument[1..2];sql;manual", - "android.database;DatabaseUtils;false;queryNumEntries;(SQLiteDatabase,String,String,String[]);;Argument[1..2];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;delete;(SQLiteDatabase,String,String[]);;Argument[-1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;delete;(SQLiteDatabase,String,String[]);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;insert;(SQLiteDatabase,ContentValues);;Argument[-1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;update;(SQLiteDatabase,ContentValues,String,String[]);;Argument[-1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;update;(SQLiteDatabase,ContentValues,String,String[]);;Argument[2];sql;manual", - // query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder) - // query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit) - // query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit, CancellationSignal cancellationSignal) - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String);;Argument[-1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String);;Argument[4..6];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String);;Argument[-1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String);;Argument[4..7];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[-1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[4..7];sql;manual", - "android.content;ContentProvider;true;delete;(Uri,String,String[]);;Argument[1];sql;manual", - "android.content;ContentProvider;true;update;(Uri,ContentValues,String,String[]);;Argument[2];sql;manual", - "android.content;ContentProvider;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Argument[2];sql;manual", - "android.content;ContentProvider;true;query;(Uri,String[],String,String[],String);;Argument[2];sql;manual", - "android.content;ContentResolver;true;delete;(Uri,String,String[]);;Argument[1];sql;manual", - "android.content;ContentResolver;true;update;(Uri,ContentValues,String,String[]);;Argument[2];sql;manual", - "android.content;ContentResolver;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Argument[2];sql;manual", - "android.content;ContentResolver;true;query;(Uri,String[],String,String[],String);;Argument[2];sql;manual" - ] - } -} - -private class SqlFlowStep extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - // buildQuery(String[] projectionIn, String selection, String groupBy, String having, String sortOrder, String limit) - // buildQuery(String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit) - // buildUnionQuery(String[] subQueries, String sortOrder, String limit) - "android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String,String,String,String);;Argument[-1];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String,String,String,String);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String,String,String,String);;Argument[1..5];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String[],String,String,String,String);;Argument[-1];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String[],String,String,String,String);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String[],String,String,String,String);;Argument[1];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String[],String,String,String,String);;Argument[3..6];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionQuery;(String[],String,String);;Argument[-1];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionQuery;(String[],String,String);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionQuery;(String[],String,String);;Argument[1..2];ReturnValue;taint;manual", - // buildUnionSubQuery(String typeDiscriminatorColumn, String[] unionColumns, Set columnsPresentInTable, int computedColumnsOffset, String typeDiscriminatorValue, String selection, String[] selectionArgs, String groupBy, String having) - // buildUnionSubQuery(String typeDiscriminatorColumn, String[] unionColumns, Set columnsPresentInTable, int computedColumnsOffset, String typeDiscriminatorValue, String selection, String groupBy, String having) - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String[],String,String);;Argument[-1..0];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String[],String,String);;Argument[1].ArrayElement;ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String[],String,String);;Argument[2].Element;ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String[],String,String);;Argument[4..5];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String[],String,String);;Argument[7..8];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String,String);;Argument[-1..0];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String,String);;Argument[1].ArrayElement;ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String,String);;Argument[2].Element;ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String,String);;Argument[4..7];ReturnValue;taint;manual", - // static buildQueryString(boolean distinct, String tables, String[] columns, String where, String groupBy, String having, String orderBy, String limit) - "android.database.sqlite;SQLiteQueryBuilder;true;buildQueryString;(boolean,String,String[],String,String,String,String,String);;Argument[1];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildQueryString;(boolean,String,String[],String,String,String,String,String);;Argument[2].ArrayElement;ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildQueryString;(boolean,String,String[],String,String,String,String,String);;Argument[3..7];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;setProjectionMap;(Map);;Argument[0].MapKey;Argument[-1];taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;setProjectionMap;(Map);;Argument[0].MapValue;Argument[-1];taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;setTables;(String);;Argument[0];Argument[-1];taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;appendWhere;(CharSequence);;Argument[0];Argument[-1];taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;appendWhereStandalone;(CharSequence);;Argument[0];Argument[-1];taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;appendColumns;(StringBuilder,String[]);;Argument[1].ArrayElement;Argument[0];taint;manual", - "android.database;DatabaseUtils;false;appendSelectionArgs;(String[],String[]);;Argument[0..1].ArrayElement;ReturnValue.ArrayElement;taint;manual", - "android.database;DatabaseUtils;false;concatenateWhere;(String,String);;Argument[0..1];ReturnValue;taint;manual", - "android.content;ContentProvider;true;query;(Uri,String[],String,String[],String);;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProvider;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;query;(Uri,String[],String,String[],String);;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Argument[0];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/SharedPreferences.qll b/java/ql/lib/semmle/code/java/frameworks/android/SharedPreferences.qll index 8a5c455fedd..99131155151 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/SharedPreferences.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/SharedPreferences.qll @@ -56,19 +56,3 @@ class StoreSharedPreferenceMethod extends Method { this.hasName(["commit", "apply"]) } } - -private class SharedPreferencesSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "android.content;SharedPreferences$Editor;true;clear;;;Argument[-1];ReturnValue;value;manual", - "android.content;SharedPreferences$Editor;true;putBoolean;;;Argument[-1];ReturnValue;value;manual", - "android.content;SharedPreferences$Editor;true;putFloat;;;Argument[-1];ReturnValue;value;manual", - "android.content;SharedPreferences$Editor;true;putInt;;;Argument[-1];ReturnValue;value;manual", - "android.content;SharedPreferences$Editor;true;putLong;;;Argument[-1];ReturnValue;value;manual", - "android.content;SharedPreferences$Editor;true;putString;;;Argument[-1];ReturnValue;value;manual", - "android.content;SharedPreferences$Editor;true;putStringSet;;;Argument[-1];ReturnValue;value;manual", - "android.content;SharedPreferences$Editor;true;remove;;;Argument[-1];ReturnValue;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Slice.qll b/java/ql/lib/semmle/code/java/frameworks/android/Slice.qll index b787f0ad282..393a543bbfb 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Slice.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Slice.qll @@ -39,87 +39,3 @@ private class SliceActionsInheritTaint extends DataFlow::SyntheticFieldContent, TaintInheritingContent { SliceActionsInheritTaint() { this.getField() = "androidx.slice.Slice.action" } } - -private class SliceBuildersSummaryModels extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "androidx.slice.builders;ListBuilder;true;addAction;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;addGridRow;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;addInputRange;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;addRange;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;addRating;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;addRow;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;addSelection;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;setHeader;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;setSeeMoreAction;(PendingIntent);;Argument[0];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;setSeeMoreRow;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;build;;;Argument[-1].SyntheticField[androidx.slice.Slice.action];ReturnValue;taint;manual", - "androidx.slice.builders;ListBuilder$HeaderBuilder;true;setPrimaryAction;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$InputRangeBuilder;true;addEndItem;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$InputRangeBuilder;true;setInputAction;(PendingIntent);;Argument[0];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$InputRangeBuilder;true;setPrimaryAction;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$RangeBuilder;true;setPrimaryAction;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$RatingBuilder;true;setInputAction;(PendingIntent);;Argument[0];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$RatingBuilder;true;setPrimaryAction;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$RowBuilder;true;addEndItem;(SliceAction,boolean);;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$RowBuilder;true;addEndItem;(SliceAction);;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$RowBuilder;true;setPrimaryAction;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$RowBuilder;true;setTitleItem;(SliceAction,boolean);;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$RowBuilder;true;setTitleItem;(SliceAction);;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;SliceAction;true;create;(PendingIntent,IconCompat,int,CharSequence);;Argument[0];ReturnValue.SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;SliceAction;true;createDeeplink;(PendingIntent,IconCompat,int,CharSequence);;Argument[0];ReturnValue.SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;SliceAction;true;createToggle;(PendingIntent,CharSequence,boolean);;Argument[0];ReturnValue.SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;SliceAction;true;getAction;;;Argument[-1].SyntheticField[androidx.slice.Slice.action];ReturnValue;taint;manual", - // Fluent models - "androidx.slice.builders;ListBuilder;true;" + - [ - "addAction", "addGridRow", "addInputRange", "addRange", "addRating", "addRow", - "addSelection", "setAccentColor", "setHeader", "setHostExtras", "setIsError", - "setKeywords", "setLayoutDirection", "setSeeMoreAction", "setSeeMoreRow" - ] + ";;;Argument[-1];ReturnValue;value;manual", - "androidx.slice.builders;ListBuilder$HeaderBuilder;true;" + - [ - "setContentDescription", "setLayoutDirection", "setPrimaryAction", "setSubtitle", - "setSummary", "setTitle" - ] + ";;;Argument[-1];ReturnValue;value;manual", - "androidx.slice.builders;ListBuilder$InputRangeBuilder;true;" + - [ - "addEndItem", "setContentDescription", "setInputAction", "setLayoutDirection", "setMax", - "setMin", "setPrimaryAction", "setSubtitle", "setThumb", "setTitle", "setTitleItem", - "setValue" - ] + ";;;Argument[-1];ReturnValue;value;manual", - "androidx.slice.builders;ListBuilder$RangeBuilder;true;" + - [ - "setContentDescription", "setMax", "setMode", "setPrimaryAction", "setSubtitle", - "setTitle", "setTitleItem", "setValue" - ] + ";;;Argument[-1];ReturnValue;value;manual", - "androidx.slice.builders;ListBuilder$RatingBuilder;true;" + - [ - "setContentDescription", "setInputAction", "setMax", "setMin", "setPrimaryAction", - "setSubtitle", "setTitle", "setTitleItem", "setValue" - ] + ";;;Argument[-1];ReturnValue;value;manual", - "androidx.slice.builders;ListBuilder$RowBuilder;true;" + - [ - "addEndItem", "setContentDescription", "setEndOfSection", "setLayoutDirection", - "setPrimaryAction", "setSubtitle", "setTitle", "setTitleItem" - ] + ";;;Argument[-1];ReturnValue;value;manual", - "androidx.slice.builders;SliceAction;true;" + - ["setChecked", "setContentDescription", "setPriority"] + - ";;;Argument[-1];ReturnValue;value;manual" - ] - } -} - -private class SliceProviderSourceModels extends SourceModelCsv { - override predicate row(string row) { - row = - [ - "androidx.slice;SliceProvider;true;onBindSlice;;;Parameter[0];contentprovider;manual", - "androidx.slice;SliceProvider;true;onCreatePermissionRequest;;;Parameter[0];contentprovider;manual", - "androidx.slice;SliceProvider;true;onMapIntentToUri;;;Parameter[0];contentprovider;manual", - "androidx.slice;SliceProvider;true;onSlicePinned;;;Parameter[0];contentprovider;manual", - "androidx.slice;SliceProvider;true;onSliceUnpinned;;;Parameter[0];contentprovider;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll b/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll index e66852e8e2e..81c34179c15 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll @@ -4,12 +4,6 @@ import java private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSources -private class AndroidWidgetSourceModels extends SourceModelCsv { - override predicate row(string row) { - row = "android.widget;EditText;true;getText;;;ReturnValue;android-widget;manual" - } -} - private class DefaultAndroidWidgetSources extends RemoteFlowSource { DefaultAndroidWidgetSources() { sourceNode(this, "android-widget") } @@ -35,9 +29,3 @@ private class EditableToStringStep extends AdditionalTaintStep { ) } } - -private class AndroidWidgetSummaryModels extends SummaryModelCsv { - override predicate row(string row) { - row = "android.widget;EditText;true;getText;;;Argument[-1];ReturnValue;taint;manual" - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/XssSinks.qll b/java/ql/lib/semmle/code/java/frameworks/android/XssSinks.qll deleted file mode 100644 index c324d22a605..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/android/XssSinks.qll +++ /dev/null @@ -1,16 +0,0 @@ -/** Provides XSS sink models relating to the `android.webkit.WebView` class. */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -/** CSV sink models representing methods susceptible to XSS attacks. */ -private class DefaultXssSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "android.webkit;WebView;false;loadData;;;Argument[0];xss;manual", - "android.webkit;WebView;false;loadDataWithBaseURL;;;Argument[1];xss;manual", - "android.webkit;WebView;false;evaluateJavascript;;;Argument[0];xss;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/Collections.qll b/java/ql/lib/semmle/code/java/frameworks/apache/Collections.qll index 4eb7f644233..6f8158b6c66 100644 --- a/java/ql/lib/semmle/code/java/frameworks/apache/Collections.qll +++ b/java/ql/lib/semmle/code/java/frameworks/apache/Collections.qll @@ -29,1163 +29,3 @@ class MethodApacheCollectionsIsNotEmpty extends Method { this.hasName("isNotEmpty") } } - -/** - * Value-propagating models for classes in the package `org.apache.commons.collections4`. - */ -private class ApacheCollectionsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should model things relating to Closure, Factory, Transformer, FluentIterable.forEach, FluentIterable.transform - ";ArrayStack;true;peek;;;Argument[-1].Element;ReturnValue;value;manual", - ";ArrayStack;true;pop;;;Argument[-1].Element;ReturnValue;value;manual", - ";ArrayStack;true;push;;;Argument[0];Argument[-1].Element;value;manual", - ";ArrayStack;true;push;;;Argument[0];ReturnValue;value;manual", - ";Bag;true;add;;;Argument[0];Argument[-1].Element;value;manual", - ";Bag;true;uniqueSet;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";BidiMap;true;getKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - ";BidiMap;true;removeValue;;;Argument[-1].MapKey;ReturnValue;value;manual", - ";BidiMap;true;inverseBidiMap;;;Argument[-1].MapKey;ReturnValue.MapValue;value;manual", - ";BidiMap;true;inverseBidiMap;;;Argument[-1].MapValue;ReturnValue.MapKey;value;manual", - ";FluentIterable;true;append;(Object[]);;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;append;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - ";FluentIterable;true;append;(Iterable);;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;append;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;asEnumeration;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;collate;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;collate;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;copyInto;;;Argument[-1].Element;Argument[0].Element;value;manual", - ";FluentIterable;true;eval;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;filter;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;get;;;Argument[-1].Element;ReturnValue;value;manual", - ";FluentIterable;true;limit;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;loop;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;of;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;of;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - ";FluentIterable;true;of;(Object);;Argument[0];ReturnValue.Element;value;manual", - ";FluentIterable;true;reverse;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;skip;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;toArray;;;Argument[-1].Element;ReturnValue.ArrayElement;value;manual", - ";FluentIterable;true;toList;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;unique;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;unmodifiable;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;zip;(Iterable);;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;zip;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;zip;(Iterable[]);;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;zip;(Iterable[]);;Argument[0].ArrayElement.Element;ReturnValue.Element;value;manual", - ";Get;true;entrySet;;;Argument[-1].MapKey;ReturnValue.Element.MapKey;value;manual", - ";Get;true;entrySet;;;Argument[-1].MapValue;ReturnValue.Element.MapValue;value;manual", - ";Get;true;get;;;Argument[-1].MapValue;ReturnValue;value;manual", - ";Get;true;keySet;();;Argument[-1].MapKey;ReturnValue.Element;value;manual", - ";Get;true;values;();;Argument[-1].MapValue;ReturnValue.Element;value;manual", - ";Get;true;remove;(Object);;Argument[-1].MapValue;ReturnValue;value;manual", - ";IterableGet;true;mapIterator;;;Argument[-1].MapKey;ReturnValue.Element;value;manual", - ";IterableGet;true;mapIterator;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - ";KeyValue;true;getKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - ";KeyValue;true;getValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - // Note that MapIterator implements Iterator, so it iterates over the keys of the map. - // In order for the models of Iterator to work we have to use Element instead of MapKey for key data. - ";MapIterator;true;getKey;;;Argument[-1].Element;ReturnValue;value;manual", - ";MapIterator;true;getValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - ";MapIterator;true;setValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - ";MapIterator;true;setValue;;;Argument[0];Argument[-1].MapValue;value;manual", - ";MultiMap;true;get;;;Argument[-1].MapValue.Element;ReturnValue.Element;value;manual", - ";MultiMap;true;put;;;Argument[0];Argument[-1].MapKey;value;manual", - ";MultiMap;true;put;;;Argument[1];Argument[-1].MapValue.Element;value;manual", - ";MultiMap;true;values;;;Argument[-1].MapValue.Element;ReturnValue.Element;value;manual", - ";MultiSet$Entry;true;getElement;;;Argument[-1].Element;ReturnValue;value;manual", - ";MultiSet;true;add;;;Argument[0];Argument[-1].Element;value;manual", - ";MultiSet;true;uniqueSet;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";MultiSet;true;entrySet;;;Argument[-1].Element;ReturnValue.Element.Element;value;manual", - ";MultiValuedMap;true;asMap;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - ";MultiValuedMap;true;asMap;;;Argument[-1].MapValue.Element;ReturnValue.MapValue.Element;value;manual", - ";MultiValuedMap;true;entries;;;Argument[-1].MapKey;ReturnValue.Element.MapKey;value;manual", - ";MultiValuedMap;true;entries;;;Argument[-1].MapValue.Element;ReturnValue.Element.MapValue;value;manual", - ";MultiValuedMap;true;get;;;Argument[-1].MapValue.Element;ReturnValue.Element;value;manual", - ";MultiValuedMap;true;keys;;;Argument[-1].MapKey;ReturnValue.Element;value;manual", - ";MultiValuedMap;true;keySet;;;Argument[-1].MapKey;ReturnValue.Element;value;manual", - ";MultiValuedMap;true;mapIterator;;;Argument[-1].MapKey;ReturnValue.Element;value;manual", - ";MultiValuedMap;true;mapIterator;;;Argument[-1].MapValue.Element;ReturnValue.MapValue;value;manual", - ";MultiValuedMap;true;put;;;Argument[0];Argument[-1].MapKey;value;manual", - ";MultiValuedMap;true;put;;;Argument[1];Argument[-1].MapValue.Element;value;manual", - ";MultiValuedMap;true;putAll;(Object,Iterable);;Argument[0];Argument[-1].MapKey;value;manual", - ";MultiValuedMap;true;putAll;(Object,Iterable);;Argument[1].Element;Argument[-1].MapValue.Element;value;manual", - ";MultiValuedMap;true;putAll;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ";MultiValuedMap;true;putAll;(Map);;Argument[0].MapValue;Argument[-1].MapValue.Element;value;manual", - ";MultiValuedMap;true;putAll;(MultiValuedMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ";MultiValuedMap;true;putAll;(MultiValuedMap);;Argument[0].MapValue.Element;Argument[-1].MapValue.Element;value;manual", - ";MultiValuedMap;true;remove;;;Argument[-1].MapValue.Element;ReturnValue.Element;value;manual", - ";MultiValuedMap;true;values;;;Argument[-1].MapValue.Element;ReturnValue.Element;value;manual", - ";OrderedIterator;true;previous;;;Argument[-1].Element;ReturnValue;value;manual", - ";OrderedMap;true;firstKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - ";OrderedMap;true;lastKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - ";OrderedMap;true;nextKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - ";OrderedMap;true;previousKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - ";Put;true;put;;;Argument[-1].MapValue;ReturnValue;value;manual", - ";Put;true;put;;;Argument[0];Argument[-1].MapKey;value;manual", - ";Put;true;put;;;Argument[1];Argument[-1].MapValue;value;manual", - ";Put;true;putAll;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ";Put;true;putAll;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ";SortedBag;true;first;;;Argument[-1].Element;ReturnValue;value;manual", - ";SortedBag;true;last;;;Argument[-1].Element;ReturnValue;value;manual", - ";Trie;true;prefixMap;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - ";Trie;true;prefixMap;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} - -// Note that when lambdas are supported we should model the package `org.apache.commons.collections4.functors`, -// and when more general callable flow is supported we should model the package -// `org.apache.commons.collections4.sequence`. -/** - * Value-propagating models for classes in the package `org.apache.commons.collections4.keyvalue`. - */ -private class ApacheKeyValueModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ".keyvalue;AbstractKeyValue;true;AbstractKeyValue;;;Argument[0];Argument[-1].MapKey;value;manual", - ".keyvalue;AbstractKeyValue;true;AbstractKeyValue;;;Argument[1];Argument[-1].MapValue;value;manual", - ".keyvalue;AbstractKeyValue;true;setKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - ".keyvalue;AbstractKeyValue;true;setKey;;;Argument[0];Argument[-1].MapKey;value;manual", - ".keyvalue;AbstractKeyValue;true;setValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - ".keyvalue;AbstractKeyValue;true;setValue;;;Argument[0];Argument[-1].MapValue;value;manual", - ".keyvalue;AbstractMapEntry;true;AbstractMapEntry;;;Argument[0];Argument[-1].MapKey;value;manual", - ".keyvalue;AbstractMapEntry;true;AbstractMapEntry;;;Argument[1];Argument[-1].MapValue;value;manual", - ".keyvalue;AbstractMapEntryDecorator;true;AbstractMapEntryDecorator;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".keyvalue;AbstractMapEntryDecorator;true;AbstractMapEntryDecorator;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".keyvalue;AbstractMapEntryDecorator;true;getMapEntry;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - ".keyvalue;AbstractMapEntryDecorator;true;getMapEntry;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - ".keyvalue;DefaultKeyValue;true;DefaultKeyValue;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - ".keyvalue;DefaultKeyValue;true;DefaultKeyValue;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - ".keyvalue;DefaultKeyValue;true;DefaultKeyValue;(KeyValue);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".keyvalue;DefaultKeyValue;true;DefaultKeyValue;(KeyValue);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".keyvalue;DefaultKeyValue;true;DefaultKeyValue;(Entry);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".keyvalue;DefaultKeyValue;true;DefaultKeyValue;(Entry);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".keyvalue;DefaultKeyValue;true;toMapEntry;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - ".keyvalue;DefaultKeyValue;true;toMapEntry;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - ".keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - ".keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - ".keyvalue;DefaultMapEntry;true;DefaultMapEntry;(KeyValue);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".keyvalue;DefaultMapEntry;true;DefaultMapEntry;(KeyValue);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Entry);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Entry);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object[]);;Argument[0].ArrayElement;Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object[],boolean);;Argument[0].ArrayElement;Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object);;Argument[0];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object);;Argument[1];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object);;Argument[0];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object);;Argument[1];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object);;Argument[2];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object);;Argument[0];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object);;Argument[1];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object);;Argument[2];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object);;Argument[3];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object,Object);;Argument[0];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object,Object);;Argument[1];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object,Object);;Argument[2];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object,Object);;Argument[3];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object,Object);;Argument[4];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;getKeys;;;Argument[-1].Element;ReturnValue.ArrayElement;value;manual", - ".keyvalue;MultiKey;true;getKey;;;Argument[-1].Element;ReturnValue;value;manual", - ".keyvalue;TiedMapEntry;true;TiedMapEntry;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".keyvalue;TiedMapEntry;true;TiedMapEntry;;;Argument[1];Argument[-1].MapKey;value;manual", - ".keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - ".keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - ".keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(KeyValue);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(KeyValue);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(Entry);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(Entry);;Argument[0].MapValue;Argument[-1].MapValue;value;manual" - ] - } -} - -/** - * Value-propagating models for classes in the package `org.apache.commons.collections4.bag`. - */ -private class ApacheBagModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformedBag, TransformedSortedBag - ".bag;AbstractBagDecorator;true;AbstractBagDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".bag;AbstractMapBag;true;AbstractMapBag;;;Argument[0].MapKey;Argument[-1].Element;value;manual", - ".bag;AbstractMapBag;true;getMap;;;Argument[-1].Element;ReturnValue.MapKey;value;manual", - ".bag;AbstractSortedBagDecorator;true;AbstractSortedBagDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".bag;CollectionBag;true;CollectionBag;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".bag;CollectionBag;true;collectionBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;CollectionSortedBag;true;CollectionSortedBag;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".bag;CollectionSortedBag;true;collectionSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;HashBag;true;HashBag;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".bag;PredicatedBag;true;predicatedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;PredicatedSortedBag;true;predicatedSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;SynchronizedBag;true;synchronizedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;SynchronizedSortedBag;true;synchronizedSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;TransformedBag;true;transformedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;TransformedSortedBag;true;transformedSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;TreeBag;true;TreeBag;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - ".bag;UnmodifiableBag;true;unmodifiableBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;UnmodifiableSortedBag;true;unmodifiableSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for classes in the package `org.apache.commons.collections4.bidimap`. - */ -private class ApacheBidiMapModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ".bidimap;AbstractBidiMapDecorator;true;AbstractBidiMapDecorator;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".bidimap;AbstractBidiMapDecorator;true;AbstractBidiMapDecorator;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;Argument[1].MapKey;Argument[-1].MapValue;value;manual", - ".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;Argument[1].MapValue;Argument[-1].MapKey;value;manual", - ".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;Argument[2].MapKey;Argument[-1].MapValue;value;manual", - ".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;Argument[2].MapValue;Argument[-1].MapKey;value;manual", - ".bidimap;AbstractOrderedBidiMapDecorator;true;AbstractOrderedBidiMapDecorator;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".bidimap;AbstractOrderedBidiMapDecorator;true;AbstractOrderedBidiMapDecorator;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".bidimap;AbstractSortedBidiMapDecorator;true;AbstractSortedBidiMapDecorator;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".bidimap;AbstractSortedBidiMapDecorator;true;AbstractSortedBidiMapDecorator;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".bidimap;DualHashBidiMap;true;DualHashBidiMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".bidimap;DualHashBidiMap;true;DualHashBidiMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".bidimap;DualLinkedHashBidiMap;true;DualLinkedHashBidiMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".bidimap;DualLinkedHashBidiMap;true;DualLinkedHashBidiMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".bidimap;DualTreeBidiMap;true;DualTreeBidiMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".bidimap;DualTreeBidiMap;true;DualTreeBidiMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".bidimap;DualTreeBidiMap;true;inverseOrderedBidiMap;;;Argument[-1].MapKey;ReturnValue.MapValue;value;manual", - ".bidimap;DualTreeBidiMap;true;inverseOrderedBidiMap;;;Argument[-1].MapValue;ReturnValue.MapKey;value;manual", - ".bidimap;DualTreeBidiMap;true;inverseSortedBidiMap;;;Argument[-1].MapKey;ReturnValue.MapValue;value;manual", - ".bidimap;DualTreeBidiMap;true;inverseSortedBidiMap;;;Argument[-1].MapValue;ReturnValue.MapKey;value;manual", - ".bidimap;TreeBidiMap;true;TreeBidiMap;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".bidimap;TreeBidiMap;true;TreeBidiMap;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".bidimap;UnmodifiableBidiMap;true;unmodifiableBidiMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".bidimap;UnmodifiableBidiMap;true;unmodifiableBidiMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".bidimap;UnmodifiableOrderedBidiMap;true;unmodifiableOrderedBidiMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".bidimap;UnmodifiableOrderedBidiMap;true;unmodifiableOrderedBidiMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".bidimap;UnmodifiableOrderedBidiMap;true;inverseOrderedBidiMap;;;Argument[-1].MapKey;ReturnValue.MapValue;value;manual", - ".bidimap;UnmodifiableOrderedBidiMap;true;inverseOrderedBidiMap;;;Argument[-1].MapValue;ReturnValue.MapKey;value;manual", - ".bidimap;UnmodifiableSortedBidiMap;true;unmodifiableSortedBidiMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".bidimap;UnmodifiableSortedBidiMap;true;unmodifiableSortedBidiMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} - -/** - * Value-propagating models for classes in the package `org.apache.commons.collections4.collection`. - */ -private class ApacheCollectionModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformedCollection - ".collection;AbstractCollectionDecorator;true;AbstractCollectionDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".collection;AbstractCollectionDecorator;true;decorated;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;AbstractCollectionDecorator;true;setCollection;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection$CollectionMutator;true;add;;;Argument[2];Argument[0].Element;value;manual", - ".collection;CompositeCollection$CollectionMutator;true;add;;;Argument[2];Argument[1].Element.Element;value;manual", - ".collection;CompositeCollection$CollectionMutator;true;addAll;;;Argument[2].Element;Argument[0].Element;value;manual", - ".collection;CompositeCollection$CollectionMutator;true;addAll;;;Argument[2].Element;Argument[1].Element.Element;value;manual", - ".collection;CompositeCollection;true;CompositeCollection;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection;true;CompositeCollection;(Collection,Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection;true;CompositeCollection;(Collection,Collection);;Argument[1].Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection;true;CompositeCollection;(Collection[]);;Argument[0].ArrayElement.Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection;true;addComposited;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection;true;addComposited;(Collection,Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection;true;addComposited;(Collection,Collection);;Argument[1].Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection;true;addComposited;(Collection[]);;Argument[0].ArrayElement.Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection;true;toCollection;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;CompositeCollection;true;getCollections;;;Argument[-1].Element;ReturnValue.Element.Element;value;manual", - ".collection;IndexedCollection;true;IndexedCollection;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".collection;IndexedCollection;true;uniqueIndexedCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;IndexedCollection;true;nonUniqueIndexedCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;IndexedCollection;true;get;;;Argument[-1].Element;ReturnValue;value;manual", - ".collection;IndexedCollection;true;values;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;add;;;Argument[0];Argument[-1].Element;value;manual", - ".collection;PredicatedCollection$Builder;true;addAll;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedList;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedSet;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedMultiSet;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedMultiSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedBag;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedQueue;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedQueue;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;rejectedElements;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection;true;predicatedCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;SynchronizedCollection;true;synchronizedCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;TransformedCollection;true;transformingCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;UnmodifiableBoundedCollection;true;unmodifiableBoundedCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;UnmodifiableCollection;true;unmodifiableCollection;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.iterators`. - */ -private class ApacheIteratorsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformIterator - ".iterators;AbstractIteratorDecorator;true;AbstractIteratorDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;AbstractListIteratorDecorator;true;AbstractListIteratorDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;AbstractListIteratorDecorator;true;getListIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".iterators;AbstractMapIteratorDecorator;true;AbstractMapIteratorDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;AbstractMapIteratorDecorator;true;AbstractMapIteratorDecorator;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".iterators;AbstractMapIteratorDecorator;true;getMapIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".iterators;AbstractMapIteratorDecorator;true;getMapIterator;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - ".iterators;AbstractOrderedMapIteratorDecorator;true;AbstractOrderedMapIteratorDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;AbstractOrderedMapIteratorDecorator;true;AbstractOrderedMapIteratorDecorator;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".iterators;AbstractOrderedMapIteratorDecorator;true;getOrderedMapIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".iterators;AbstractOrderedMapIteratorDecorator;true;getOrderedMapIterator;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - ".iterators;AbstractUntypedIteratorDecorator;true;AbstractUntypedIteratorDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;AbstractUntypedIteratorDecorator;true;getIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".iterators;ArrayIterator;true;ArrayIterator;;;Argument[0].ArrayElement;Argument[-1].Element;value;manual", - ".iterators;ArrayIterator;true;getArray;;;Argument[-1].Element;ReturnValue.ArrayElement;value;manual", - ".iterators;ArrayListIterator;true;ArrayListIterator;;;Argument[0].ArrayElement;Argument[-1].Element;value;manual", - ".iterators;BoundedIterator;true;BoundedIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;CollatingIterator;true;CollatingIterator;(Comparator,Iterator,Iterator);;Argument[1].Element;Argument[-1].Element;value;manual", - ".iterators;CollatingIterator;true;CollatingIterator;(Comparator,Iterator,Iterator);;Argument[2].Element;Argument[-1].Element;value;manual", - ".iterators;CollatingIterator;true;CollatingIterator;(Comparator,Iterator[]);;Argument[1].ArrayElement.Element;Argument[-1].Element;value;manual", - ".iterators;CollatingIterator;true;CollatingIterator;(Comparator,Collection);;Argument[1].Element.Element;Argument[-1].Element;value;manual", - ".iterators;CollatingIterator;true;addIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;CollatingIterator;true;setIterator;;;Argument[1].Element;Argument[-1].Element;value;manual", - ".iterators;CollatingIterator;true;getIterators;;;Argument[-1].Element;ReturnValue.Element.Element;value;manual", - ".iterators;EnumerationIterator;true;EnumerationIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;EnumerationIterator;true;getEnumeration;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".iterators;EnumerationIterator;true;setEnumeration;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;FilterIterator;true;FilterIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;FilterIterator;true;getIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".iterators;FilterIterator;true;setIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;FilterListIterator;true;FilterListIterator;(ListIterator);;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;FilterListIterator;true;FilterListIterator;(ListIterator,Predicate);;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;FilterListIterator;true;getListIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".iterators;FilterListIterator;true;setListIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;IteratorChain;true;IteratorChain;(Iterator);;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;IteratorChain;true;IteratorChain;(Iterator,Iterator);;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;IteratorChain;true;IteratorChain;(Iterator,Iterator);;Argument[1].Element;Argument[-1].Element;value;manual", - ".iterators;IteratorChain;true;IteratorChain;(Iterator[]);;Argument[0].ArrayElement.Element;Argument[-1].Element;value;manual", - ".iterators;IteratorChain;true;IteratorChain;(Collection);;Argument[0].Element.Element;Argument[-1].Element;value;manual", - ".iterators;IteratorChain;true;addIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;IteratorEnumeration;true;IteratorEnumeration;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;IteratorEnumeration;true;getIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".iterators;IteratorEnumeration;true;setIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;IteratorIterable;true;IteratorIterable;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;ListIteratorWrapper;true;ListIteratorWrapper;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;LoopingIterator;true;LoopingIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;LoopingListIterator;true;LoopingListIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;ObjectArrayIterator;true;ObjectArrayIterator;;;Argument[0].ArrayElement;Argument[-1].Element;value;manual", - ".iterators;ObjectArrayIterator;true;getArray;;;Argument[-1].Element;ReturnValue.ArrayElement;value;manual", - ".iterators;ObjectArrayListIterator;true;ObjectArrayListIterator;;;Argument[0].ArrayElement;Argument[-1].Element;value;manual", - ".iterators;PeekingIterator;true;PeekingIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;PeekingIterator;true;peekingIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".iterators;PeekingIterator;true;peek;;;Argument[-1].Element;ReturnValue;value;manual", - ".iterators;PeekingIterator;true;element;;;Argument[-1].Element;ReturnValue;value;manual", - ".iterators;PermutationIterator;true;PermutationIterator;;;Argument[0].Element;Argument[-1].Element.Element;value;manual", - ".iterators;PushbackIterator;true;PushbackIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;PushbackIterator;true;pushbackIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".iterators;PushbackIterator;true;pushback;;;Argument[0];Argument[-1].Element;value;manual", - ".iterators;ReverseListIterator;true;ReverseListIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;SingletonIterator;true;SingletonIterator;;;Argument[0];Argument[-1].Element;value;manual", - ".iterators;SingletonListIterator;true;SingletonListIterator;;;Argument[0];Argument[-1].Element;value;manual", - ".iterators;SkippingIterator;true;SkippingIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;UniqueFilterIterator;true;UniqueFilterIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;UnmodifiableIterator;true;unmodifiableIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".iterators;UnmodifiableListIterator;true;umodifiableListIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".iterators;UnmodifiableMapIterator;true;unmodifiableMapIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".iterators;UnmodifiableMapIterator;true;unmodifiableMapIterator;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".iterators;UnmodifiableOrderedMapIterator;true;unmodifiableOrderedMapIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".iterators;UnmodifiableOrderedMapIterator;true;unmodifiableOrderedMapIterator;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".iterators;ZippingIterator;true;ZippingIterator;(Iterator[]);;Argument[0].ArrayElement.Element;Argument[-1].Element;value;manual", - ".iterators;ZippingIterator;true;ZippingIterator;(Iterator,Iterator);;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;ZippingIterator;true;ZippingIterator;(Iterator,Iterator);;Argument[1].Element;Argument[-1].Element;value;manual", - ".iterators;ZippingIterator;true;ZippingIterator;(Iterator,Iterator,Iterator);;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;ZippingIterator;true;ZippingIterator;(Iterator,Iterator,Iterator);;Argument[1].Element;Argument[-1].Element;value;manual", - ".iterators;ZippingIterator;true;ZippingIterator;(Iterator,Iterator,Iterator);;Argument[2].Element;Argument[-1].Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.list`. - */ -private class ApacheListModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformedList - ".list;AbstractLinkedList;true;AbstractLinkedList;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".list;AbstractLinkedList;true;getFirst;;;Argument[-1].Element;ReturnValue;value;manual", - ".list;AbstractLinkedList;true;getLast;;;Argument[-1].Element;ReturnValue;value;manual", - ".list;AbstractLinkedList;true;addFirst;;;Argument[0];Argument[-1].Element;value;manual", - ".list;AbstractLinkedList;true;addLast;;;Argument[0];Argument[-1].Element;value;manual", - ".list;AbstractLinkedList;true;removeFirst;;;Argument[-1].Element;ReturnValue;value;manual", - ".list;AbstractLinkedList;true;removeLast;;;Argument[-1].Element;ReturnValue;value;manual", - ".list;AbstractListDecorator;true;AbstractListDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".list;AbstractSerializableListDecorator;true;AbstractSerializableListDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".list;CursorableLinkedList;true;CursorableLinkedList;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".list;CursorableLinkedList;true;cursor;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".list;FixedSizeList;true;fixedSizeList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".list;GrowthList;true;growthList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".list;LazyList;true;lazyList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".list;NodeCachingLinkedList;true;NodeCachingLinkedList;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - ".list;PredicatedList;true;predicatedList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".list;SetUniqueList;true;setUniqueList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".list;SetUniqueList;true;asSet;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".list;TransformedList;true;transformingList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".list;TreeList;true;TreeList;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".list;UnmodifiableList;true;UnmodifiableList;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".list;UnmodifiableList;true;unmodifiableList;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.map`. - */ -private class ApacheMapModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for DefaultedMap, LazyMap, TransformedMap, TransformedSortedMap - ".map;AbstractHashedMap;true;AbstractHashedMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;AbstractHashedMap;true;AbstractHashedMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;AbstractLinkedMap;true;AbstractLinkedMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;AbstractLinkedMap;true;AbstractLinkedMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;AbstractMapDecorator;true;AbstractMapDecorator;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;AbstractMapDecorator;true;AbstractMapDecorator;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;AbstractMapDecorator;true;decorated;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - ".map;AbstractMapDecorator;true;decorated;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - ".map;AbstractOrderedMapDecorator;true;AbstractOrderedMapDecorator;(OrderedMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;AbstractOrderedMapDecorator;true;AbstractOrderedMapDecorator;(OrderedMap);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;AbstractSortedMapDecorator;true;AbstractSortedMapDecorator;(SortedMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;AbstractSortedMapDecorator;true;AbstractSortedMapDecorator;(SortedMap);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;CaseInsensitiveMap;true;CaseInsensitiveMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;CaseInsensitiveMap;true;CaseInsensitiveMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map,Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map,Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map,Map);;Argument[1].MapKey;Argument[-1].MapKey;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map,Map);;Argument[1].MapValue;Argument[-1].MapValue;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map,Map,MapMutator);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map,Map,MapMutator);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map,Map,MapMutator);;Argument[1].MapKey;Argument[-1].MapKey;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map,Map,MapMutator);;Argument[1].MapValue;Argument[-1].MapValue;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map[]);;Argument[0].ArrayElement.MapKey;Argument[-1].MapKey;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map[]);;Argument[0].ArrayElement.MapValue;Argument[-1].MapValue;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map[],MapMutator);;Argument[0].ArrayElement.MapKey;Argument[-1].MapKey;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map[],MapMutator);;Argument[0].ArrayElement.MapValue;Argument[-1].MapValue;value;manual", - ".map;CompositeMap;true;addComposited;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;CompositeMap;true;addComposited;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;CompositeMap;true;removeComposited;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - ".map;CompositeMap;true;removeComposited;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - ".map;CompositeMap;true;removeComposited;;;Argument[0];ReturnValue;value;manual", - ".map;DefaultedMap;true;DefaultedMap;(Object);;Argument[0];Argument[-1].MapValue;value;manual", - ".map;DefaultedMap;true;defaultedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;DefaultedMap;true;defaultedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;DefaultedMap;true;defaultedMap;(Map,Object);;Argument[1];ReturnValue.MapValue;value;manual", - ".map;EntrySetToMapIteratorAdapter;true;EntrySetToMapIteratorAdapter;;;Argument[0].Element.MapKey;Argument[-1].Element;value;manual", - ".map;EntrySetToMapIteratorAdapter;true;EntrySetToMapIteratorAdapter;;;Argument[0].Element.MapValue;Argument[-1].MapValue;value;manual", - ".map;FixedSizeMap;true;fixedSizeMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;FixedSizeMap;true;fixedSizeMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;FixedSizeSortedMap;true;fixedSizeSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;FixedSizeSortedMap;true;fixedSizeSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;Flat3Map;true;Flat3Map;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;Flat3Map;true;Flat3Map;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;HashedMap;true;HashedMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;HashedMap;true;HashedMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;LazyMap;true;lazyMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;LazyMap;true;lazyMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;LazySortedMap;true;lazySortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;LazySortedMap;true;lazySortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;LinkedMap;true;LinkedMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;LinkedMap;true;LinkedMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;LinkedMap;true;get;(int);;Argument[-1].MapKey;ReturnValue;value;manual", - ".map;LinkedMap;true;getValue;(int);;Argument[-1].MapValue;ReturnValue;value;manual", - ".map;LinkedMap;true;remove;(int);;Argument[-1].MapValue;ReturnValue;value;manual", - ".map;LinkedMap;true;asList;;;Argument[-1].MapKey;ReturnValue.Element;value;manual", - ".map;ListOrderedMap;true;listOrderedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;ListOrderedMap;true;listOrderedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;ListOrderedMap;true;putAll;;;Argument[1].MapKey;Argument[-1].MapKey;value;manual", - ".map;ListOrderedMap;true;putAll;;;Argument[1].MapValue;Argument[-1].MapValue;value;manual", - ".map;ListOrderedMap;true;keyList;;;Argument[-1].MapKey;ReturnValue.Element;value;manual", - ".map;ListOrderedMap;true;valueList;;;Argument[-1].MapValue;ReturnValue.Element;value;manual", - ".map;ListOrderedMap;true;get;(int);;Argument[-1].MapKey;ReturnValue;value;manual", - ".map;ListOrderedMap;true;getValue;(int);;Argument[-1].MapValue;ReturnValue;value;manual", - ".map;ListOrderedMap;true;setValue;;;Argument[1];Argument[-1].MapValue;value;manual", - ".map;ListOrderedMap;true;put;;;Argument[1];Argument[-1].MapKey;value;manual", - ".map;ListOrderedMap;true;put;;;Argument[2];Argument[-1].MapValue;value;manual", - ".map;ListOrderedMap;true;remove;(int);;Argument[-1].MapValue;ReturnValue;value;manual", - ".map;ListOrderedMap;true;asList;;;Argument[-1].MapKey;ReturnValue.Element;value;manual", - ".map;LRUMap;true;LRUMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;LRUMap;true;LRUMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;LRUMap;true;LRUMap;(Map,boolean);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;LRUMap;true;LRUMap;(Map,boolean);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;LRUMap;true;get;(Object,boolean);;Argument[0].MapValue;ReturnValue;value;manual", - ".map;MultiKeyMap;true;get;;;Argument[-1].MapValue;ReturnValue;value;manual", - ".map;MultiKeyMap;true;put;;;Argument[-1].MapValue;ReturnValue;value;manual", - ".map;MultiKeyMap;true;put;(Object,Object,Object);;Argument[0..1];Argument[-1].MapKey.Element;value;manual", - ".map;MultiKeyMap;true;put;(Object,Object,Object,Object);;Argument[0..2];Argument[-1].MapKey.Element;value;manual", - ".map;MultiKeyMap;true;put;(Object,Object,Object,Object,Object);;Argument[0..3];Argument[-1].MapKey.Element;value;manual", - ".map;MultiKeyMap;true;put;(Object,Object,Object,Object,Object,Object);;Argument[0..4];Argument[-1].MapKey.Element;value;manual", - ".map;MultiKeyMap;true;put;(Object,Object,Object);;Argument[2];Argument[-1].MapValue;value;manual", - ".map;MultiKeyMap;true;put;(Object,Object,Object,Object);;Argument[3];Argument[-1].MapValue;value;manual", - ".map;MultiKeyMap;true;put;(Object,Object,Object,Object,Object);;Argument[4];Argument[-1].MapValue;value;manual", - ".map;MultiKeyMap;true;put;(Object,Object,Object,Object,Object,Object);;Argument[5];Argument[-1].MapValue;value;manual", - ".map;MultiKeyMap;true;removeMultiKey;;;Argument[-1].MapValue;ReturnValue;value;manual", - ".map;MultiValueMap;true;multiValueMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;MultiValueMap;true;multiValueMap;;;Argument[0].MapValue.Element;ReturnValue.MapValue.Element;value;manual", - ".map;MultiValueMap;true;getCollection;;;Argument[-1].MapValue.Element;ReturnValue.Element;value;manual", - ".map;MultiValueMap;true;putAll;(Map);;Argument[0].MapValue;Argument[-1].MapValue.Element;value;manual", - ".map;MultiValueMap;true;putAll;(Map);;Argument[0].MapValue.Element;Argument[-1].MapValue.Element;value;manual", - ".map;MultiValueMap;true;values;;;Argument[-1].MapValue.Element;ReturnValue.Element;value;manual", - ".map;MultiValueMap;true;putAll;(Object,Collection);;Argument[0];Argument[-1].MapKey;value;manual", - ".map;MultiValueMap;true;putAll;(Object,Collection);;Argument[1].Element;Argument[-1].MapValue.Element;value;manual", - ".map;MultiValueMap;true;iterator;(Object);;Argument[-1].MapValue.Element;ReturnValue.Element;value;manual", - ".map;MultiValueMap;true;iterator;();;Argument[-1].MapKey;ReturnValue.Element.MapKey;value;manual", - ".map;MultiValueMap;true;iterator;();;Argument[-1].MapValue.Element;ReturnValue.Element.MapValue;value;manual", - ".map;PassiveExpiringMap;true;PassiveExpiringMap;(ExpirationPolicy,Map);;Argument[1].MapKey;Argument[-1].MapKey;value;manual", - ".map;PassiveExpiringMap;true;PassiveExpiringMap;(ExpirationPolicy,Map);;Argument[1].MapValue;Argument[-1].MapValue;value;manual", - ".map;PassiveExpiringMap;true;PassiveExpiringMap;(long,Map);;Argument[1].MapKey;Argument[-1].MapKey;value;manual", - ".map;PassiveExpiringMap;true;PassiveExpiringMap;(long,Map);;Argument[1].MapValue;Argument[-1].MapValue;value;manual", - ".map;PassiveExpiringMap;true;PassiveExpiringMap;(long,TimeUnit,Map);;Argument[2].MapKey;Argument[-1].MapKey;value;manual", - ".map;PassiveExpiringMap;true;PassiveExpiringMap;(long,TimeUnit,Map);;Argument[2].MapValue;Argument[-1].MapValue;value;manual", - ".map;PassiveExpiringMap;true;PassiveExpiringMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;PassiveExpiringMap;true;PassiveExpiringMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;PredicatedMap;true;predicatedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;PredicatedMap;true;predicatedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;PredicatedSortedMap;true;predicatedSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;PredicatedSortedMap;true;predicatedSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;SingletonMap;true;SingletonMap;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - ".map;SingletonMap;true;SingletonMap;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - ".map;SingletonMap;true;SingletonMap;(KeyValue);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;SingletonMap;true;SingletonMap;(KeyValue);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;SingletonMap;true;SingletonMap;(Entry);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;SingletonMap;true;SingletonMap;(Entry);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;SingletonMap;true;SingletonMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;SingletonMap;true;SingletonMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;SingletonMap;true;setValue;;;Argument[0];Argument[-1].MapValue;value;manual", - ".map;TransformedMap;true;transformingMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;TransformedMap;true;transformingMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;TransformedSortedMap;true;transformingSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;TransformedSortedMap;true;transformingSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;UnmodifiableEntrySet;true;unmodifiableEntrySet;;;Argument[0].Element.MapKey;ReturnValue.Element.MapKey;value;manual", - ".map;UnmodifiableEntrySet;true;unmodifiableEntrySet;;;Argument[0].Element.MapValue;ReturnValue.Element.MapValue;value;manual", - ".map;UnmodifiableMap;true;unmodifiableMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;UnmodifiableMap;true;unmodifiableMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;UnmodifiableOrderedMap;true;unmodifiableOrderedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;UnmodifiableOrderedMap;true;unmodifiableOrderedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;UnmodifiableSortedMap;true;unmodifiableSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;UnmodifiableSortedMap;true;unmodifiableSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.multimap`. - */ -private class ApacheMultiMapModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformedMultiValuedMap - ".multimap;ArrayListValuedHashMap;true;ArrayListValuedHashMap;(MultiValuedMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".multimap;ArrayListValuedHashMap;true;ArrayListValuedHashMap;(MultiValuedMap);;Argument[0].MapValue.Element;Argument[-1].MapValue.Element;value;manual", - ".multimap;ArrayListValuedHashMap;true;ArrayListValuedHashMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".multimap;ArrayListValuedHashMap;true;ArrayListValuedHashMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue.Element;value;manual", - ".multimap;HashSetValuedHashMap;true;HashSetValuedHashMap;(MultiValuedMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".multimap;HashSetValuedHashMap;true;HashSetValuedHashMap;(MultiValuedMap);;Argument[0].MapValue.Element;Argument[-1].MapValue.Element;value;manual", - ".multimap;HashSetValuedHashMap;true;HashSetValuedHashMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".multimap;HashSetValuedHashMap;true;HashSetValuedHashMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue.Element;value;manual", - ".multimap;TransformedMultiValuedMap;true;transformingMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".multimap;TransformedMultiValuedMap;true;transformingMap;;;Argument[0].MapValue.Element;ReturnValue.MapValue.Element;value;manual", - ".multimap;UnmodifiableMultiValuedMap;true;unmodifiableMultiValuedMap;(MultiValuedMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".multimap;UnmodifiableMultiValuedMap;true;unmodifiableMultiValuedMap;(MultiValuedMap);;Argument[0].MapValue.Element;ReturnValue.MapValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.multiset`. - */ -private class ApacheMultiSetModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ".multiset;HashMultiSet;true;HashMultiSet;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".multiset;PredicatedMultiSet;true;predicatedMultiSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".multiset;SynchronizedMultiSet;true;synchronizedMultiSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".multiset;UnmodifiableMultiSet;true;unmodifiableMultiSet;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.properties`. - */ -private class ApachePropertiesModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ".properties;AbstractPropertiesFactory;true;load;(ClassLoader,String);;Argument[1];ReturnValue;taint;manual", - ".properties;AbstractPropertiesFactory;true;load;(File);;Argument[0];ReturnValue;taint;manual", - ".properties;AbstractPropertiesFactory;true;load;(InputStream);;Argument[0];ReturnValue;taint;manual", - ".properties;AbstractPropertiesFactory;true;load;(Path);;Argument[0];ReturnValue;taint;manual", - ".properties;AbstractPropertiesFactory;true;load;(Reader);;Argument[0];ReturnValue;taint;manual", - ".properties;AbstractPropertiesFactory;true;load;(String);;Argument[0];ReturnValue;taint;manual", - ".properties;AbstractPropertiesFactory;true;load;(URI);;Argument[0];ReturnValue;taint;manual", - ".properties;AbstractPropertiesFactory;true;load;(URL);;Argument[0];ReturnValue;taint;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.queue`. - */ -private class ApacheQueueModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformedQueue - ".queue;CircularFifoQueue;true;CircularFifoQueue;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - ".queue;CircularFifoQueue;true;get;;;Argument[-1].Element;ReturnValue;value;manual", - ".queue;PredicatedQueue;true;predicatedQueue;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".queue;SynchronizedQueue;true;synchronizedQueue;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".queue;TransformedQueue;true;transformingQueue;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".queue;UnmodifiableQueue;true;unmodifiableQueue;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.set`. - */ -private class ApacheSetModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformedNavigableSet - ".set;AbstractNavigableSetDecorator;true;AbstractNavigableSetDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".set;AbstractSetDecorator;true;AbstractSetDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".set;AbstractSortedSetDecorator;true;AbstractSortedSetDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".set;CompositeSet$SetMutator;true;add;;;Argument[2];Argument[0].Element;value;manual", - ".set;CompositeSet$SetMutator;true;add;;;Argument[2];Argument[1].Element.Element;value;manual", - ".set;CompositeSet$SetMutator;true;addAll;;;Argument[2].Element;Argument[0].Element;value;manual", - ".set;CompositeSet$SetMutator;true;addAll;;;Argument[2].Element;Argument[1].Element.Element;value;manual", - ".set;CompositeSet;true;CompositeSet;(Set);;Argument[0].Element;Argument[-1].Element;value;manual", - ".set;CompositeSet;true;CompositeSet;(Set[]);;Argument[0].ArrayElement.Element;Argument[-1].Element;value;manual", - ".set;CompositeSet;true;addComposited;(Set);;Argument[0].Element;Argument[-1].Element;value;manual", - ".set;CompositeSet;true;addComposited;(Set,Set);;Argument[0].Element;Argument[-1].Element;value;manual", - ".set;CompositeSet;true;addComposited;(Set,Set);;Argument[1].Element;Argument[-1].Element;value;manual", - ".set;CompositeSet;true;addComposited;(Set[]);;Argument[0].ArrayElement.Element;Argument[-1].Element;value;manual", - ".set;CompositeSet;true;toSet;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".set;CompositeSet;true;getSets;;;Argument[-1].Element;ReturnValue.Element.Element;value;manual", - ".set;ListOrderedSet;true;listOrderedSet;(Set);;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;ListOrderedSet;true;listOrderedSet;(List);;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;ListOrderedSet;true;asList;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".set;ListOrderedSet;true;get;;;Argument[-1].Element;ReturnValue;value;manual", - ".set;ListOrderedSet;true;add;;;Argument[1];Argument[-1].Element;value;manual", - ".set;ListOrderedSet;true;addAll;;;Argument[1].Element;Argument[-1].Element;value;manual", - ".set;MapBackedSet;true;mapBackedSet;;;Argument[0].MapKey;ReturnValue.Element;value;manual", - ".set;PredicatedNavigableSet;true;predicatedNavigableSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;PredicatedSet;true;predicatedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;PredicatedSortedSet;true;predicatedSortedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;TransformedNavigableSet;true;transformingNavigableSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;TransformedSet;true;transformingSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;TransformedSortedSet;true;transformingSortedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;UnmodifiableNavigableSet;true;unmodifiableNavigableSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;UnmodifiableSet;true;unmodifiableSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;UnmodifiableSortedSet;true;unmodifiableSortedSet;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.splitmap`. - */ -private class ApacheSplitMapModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformedSplitMap - ".splitmap;AbstractIterableGetMapDecorator;true;AbstractIterableGetMapDecorator;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".splitmap;AbstractIterableGetMapDecorator;true;AbstractIterableGetMapDecorator;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".splitmap;TransformedSplitMap;true;transformingMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".splitmap;TransformedSplitMap;true;transformingMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.trie`. - */ -private class ApacheTrieModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformedSplitMap - ".trie;PatriciaTrie;true;PatriciaTrie;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".trie;PatriciaTrie;true;PatriciaTrie;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".trie;AbstractPatriciaTrie;true;select;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - ".trie;AbstractPatriciaTrie;true;select;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - ".trie;AbstractPatriciaTrie;true;selectKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - ".trie;AbstractPatriciaTrie;true;selectValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - ".trie;UnmodifiableTrie;true;unmodifiableTrie;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".trie;UnmodifiableTrie;true;unmodifiableTrie;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.MapUtils`. - */ -private class ApacheMapUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for populateMap - ";MapUtils;true;emptyIfNull;;;Argument[0];ReturnValue;value;manual", - ";MapUtils;true;fixedSizeMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;fixedSizeMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;fixedSizeSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;fixedSizeSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;getMap;;;Argument[0].MapValue;ReturnValue;value;manual", - ";MapUtils;true;getMap;;;Argument[2];ReturnValue;value;manual", - ";MapUtils;true;getObject;;;Argument[0].MapValue;ReturnValue;value;manual", - ";MapUtils;true;getObject;;;Argument[2];ReturnValue;value;manual", - ";MapUtils;true;getString;;;Argument[0].MapValue;ReturnValue;value;manual", - ";MapUtils;true;getString;;;Argument[2];ReturnValue;value;manual", - ";MapUtils;true;invertMap;;;Argument[0].MapKey;ReturnValue.MapValue;value;manual", - ";MapUtils;true;invertMap;;;Argument[0].MapValue;ReturnValue.MapKey;value;manual", - ";MapUtils;true;iterableMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;iterableMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;iterableSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;iterableSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;lazyMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;lazyMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;lazySortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;lazySortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;multiValueMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;multiValueMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;orderedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;orderedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;populateMap;(Map,Iterable,Transformer);;Argument[1].Element;Argument[0].MapValue;value;manual", - ";MapUtils;true;populateMap;(MultiMap,Iterable,Transformer);;Argument[1].Element;Argument[0].MapValue.Element;value;manual", - ";MapUtils;true;predicatedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;predicatedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;predicatedSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;predicatedSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement;Argument[0].MapKey;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement;ReturnValue.MapKey;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement;Argument[0].MapValue;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement;ReturnValue.MapValue;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement.ArrayElement;Argument[0].MapKey;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement.ArrayElement;ReturnValue.MapKey;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement.ArrayElement;Argument[0].MapValue;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement.ArrayElement;ReturnValue.MapValue;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement.MapKey;Argument[0].MapKey;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement.MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement.MapValue;Argument[0].MapValue;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement.MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;safeAddToMap;;;Argument[1];Argument[0].MapKey;value;manual", - ";MapUtils;true;safeAddToMap;;;Argument[2];Argument[0].MapValue;value;manual", - ";MapUtils;true;synchronizedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;synchronizedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;synchronizedSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;synchronizedSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;toMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;toMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;transformedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;transformedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;transformedSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;transformedSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;unmodifiableMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;unmodifiableMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;unmodifiableSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;unmodifiableSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.CollectionUtils`. - */ -private class ApacheCollectionUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have a model for collect, forAllButLastDo, forAllDo, transform - ";CollectionUtils;true;addAll;(Collection,Object[]);;Argument[1].ArrayElement;Argument[0].Element;value;manual", - ";CollectionUtils;true;addAll;(Collection,Enumeration);;Argument[1].Element;Argument[0].Element;value;manual", - ";CollectionUtils;true;addAll;(Collection,Iterable);;Argument[1].Element;Argument[0].Element;value;manual", - ";CollectionUtils;true;addAll;(Collection,Iterator);;Argument[1].Element;Argument[0].Element;value;manual", - ";CollectionUtils;true;addIgnoreNull;;;Argument[1];Argument[0].Element;value;manual", - ";CollectionUtils;true;collate;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;collate;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;disjunction;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;disjunction;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;emptyIfNull;;;Argument[0];ReturnValue;value;manual", - ";CollectionUtils;true;extractSingleton;;;Argument[0].Element;ReturnValue;value;manual", - ";CollectionUtils;true;find;;;Argument[0].Element;ReturnValue;value;manual", - ";CollectionUtils;true;get;(Iterator,int);;Argument[0].Element;ReturnValue;value;manual", - ";CollectionUtils;true;get;(Iterable,int);;Argument[0].Element;ReturnValue;value;manual", - ";CollectionUtils;true;get;(Map,int);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";CollectionUtils;true;get;(Map,int);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";CollectionUtils;true;get;(Object,int);;Argument[0].ArrayElement;ReturnValue;value;manual", - ";CollectionUtils;true;get;(Object,int);;Argument[0].Element;ReturnValue;value;manual", - ";CollectionUtils;true;get;(Object,int);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";CollectionUtils;true;get;(Object,int);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";CollectionUtils;true;getCardinalityMap;;;Argument[0].Element;ReturnValue.MapKey;value;manual", - ";CollectionUtils;true;intersection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;intersection;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;permutations;;;Argument[0].Element;ReturnValue.Element.Element;value;manual", - ";CollectionUtils;true;predicatedCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;removeAll;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;retainAll;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;select;(Iterable,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;select;(Iterable,Predicate,Collection);;Argument[0].Element;Argument[2].Element;value;manual", - ";CollectionUtils;true;select;(Iterable,Predicate,Collection);;Argument[2];ReturnValue;value;manual", - ";CollectionUtils;true;select;(Iterable,Predicate,Collection,Collection);;Argument[0].Element;Argument[2].Element;value;manual", - ";CollectionUtils;true;select;(Iterable,Predicate,Collection,Collection);;Argument[0].Element;Argument[3].Element;value;manual", - ";CollectionUtils;true;select;(Iterable,Predicate,Collection,Collection);;Argument[2];ReturnValue;value;manual", - ";CollectionUtils;true;selectRejected;(Iterable,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;selectRejected;(Iterable,Predicate,Collection);;Argument[0].Element;Argument[2].Element;value;manual", - ";CollectionUtils;true;selectRejected;(Iterable,Predicate,Collection);;Argument[2];ReturnValue;value;manual", - ";CollectionUtils;true;subtract;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;synchronizedCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - // Note that `CollectionUtils.transformingCollection` does not transform existing list elements - ";CollectionUtils;true;transformingCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;union;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;union;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;unmodifiableCollection;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.ListUtils`. - */ -private class ApacheListUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";ListUtils;true;defaultIfNull;;;Argument[0];ReturnValue;value;manual", - ";ListUtils;true;defaultIfNull;;;Argument[1];ReturnValue;value;manual", - ";ListUtils;true;emptyIfNull;;;Argument[0];ReturnValue;value;manual", - ";ListUtils;true;fixedSizeList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;intersection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;intersection;;;Argument[1].Element;ReturnValue.Element;value;manual", - // Note that `ListUtils.lazyList` does not transform existing list elements - ";ListUtils;true;lazyList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;longestCommonSubsequence;(CharSequence,CharSequence);;Argument[0];ReturnValue;taint;manual", - ";ListUtils;true;longestCommonSubsequence;(CharSequence,CharSequence);;Argument[1];ReturnValue;taint;manual", - ";ListUtils;true;longestCommonSubsequence;(List,List);;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;longestCommonSubsequence;(List,List);;Argument[1].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;longestCommonSubsequence;(List,List,Equator);;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;longestCommonSubsequence;(List,List,Equator);;Argument[1].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;partition;;;Argument[0].Element;ReturnValue.Element.Element;value;manual", - ";ListUtils;true;predicatedList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;removeAll;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;retainAll;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;select;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;selectRejected;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;subtract;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;sum;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;sum;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;synchronizedList;;;Argument[0].Element;ReturnValue.Element;value;manual", - // Note that `ListUtils.transformedList` does not transform existing list elements - ";ListUtils;true;transformedList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;union;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;union;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;unmodifiableList;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.IteratorUtils`. - */ -private class ApacheIteratorUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have a model for forEach, forEachButLast, transformedIterator - ";IteratorUtils;true;arrayIterator;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - ";IteratorUtils;true;arrayListIterator;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - ";IteratorUtils;true;asEnumeration;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;asIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;asIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;asMultipleUseIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;boundedIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;chainedIterator;(Collection);;Argument[0].Element.Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;chainedIterator;(Iterator[]);;Argument[0].ArrayElement.Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;chainedIterator;(Iterator,Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;chainedIterator;(Iterator,Iterator);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;collatedIterator;(Comparator,Collection);;Argument[1].Element.Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;collatedIterator;(Comparator,Iterator[]);;Argument[1].ArrayElement.Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;collatedIterator;(Comparator,Iterator,Iterator);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;collatedIterator;(Comparator,Iterator,Iterator);;Argument[2].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;filteredIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;filteredListIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;find;;;Argument[0].Element;ReturnValue;value;manual", - ";IteratorUtils;true;first;;;Argument[0].Element;ReturnValue;value;manual", - ";IteratorUtils;true;forEachButLast;;;Argument[0].Element;ReturnValue;value;manual", - ";IteratorUtils;true;get;;;Argument[0].Element;ReturnValue;value;manual", - ";IteratorUtils;true;getIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;getIterator;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - ";IteratorUtils;true;getIterator;;;Argument[0];ReturnValue.Element;value;manual", - ";IteratorUtils;true;getIterator;;;Argument[0].MapValue;ReturnValue.Element;value;manual", - ";IteratorUtils;true;loopingIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;loopingListIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;peekingIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;pushbackIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;singletonIterator;;;Argument[0];ReturnValue.Element;value;manual", - ";IteratorUtils;true;singletonListIterator;;;Argument[0];ReturnValue.Element;value;manual", - ";IteratorUtils;true;skippingIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;toArray;;;Argument[0].Element;ReturnValue.ArrayElement;value;manual", - ";IteratorUtils;true;toList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;toListIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;toString;;;Argument[2];ReturnValue;taint;manual", - ";IteratorUtils;true;toString;;;Argument[3];ReturnValue;taint;manual", - ";IteratorUtils;true;toString;;;Argument[4];ReturnValue;taint;manual", - ";IteratorUtils;true;unmodifiableIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;unmodifiableListIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;unmodifiableMapIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;unmodifiableMapIterator;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";IteratorUtils;true;zippingIterator;(Iterator[]);;Argument[0].ArrayElement.Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;zippingIterator;(Iterator,Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;zippingIterator;(Iterator,Iterator);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;zippingIterator;(Iterator,Iterator,Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;zippingIterator;(Iterator,Iterator,Iterator);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;zippingIterator;(Iterator,Iterator,Iterator);;Argument[2].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.IterableUtils`. - */ -private class ApacheIterableUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - // Note that when lambdas are supported we should have a model for forEach, forEachButLast, transformedIterable - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";IterableUtils;true;boundedIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable[]);;Argument[0].ArrayElement.Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable,Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable,Iterable);;Argument[2].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable,Iterable,Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable,Iterable,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable,Iterable,Iterable);;Argument[2].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable,Iterable,Iterable);;Argument[3].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;collatedIterable;(Comparator,Iterable,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;collatedIterable;(Comparator,Iterable,Iterable);;Argument[2].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;collatedIterable;(Iterable,Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;collatedIterable;(Iterable,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;emptyIfNull;;;Argument[0];ReturnValue;value;manual", - ";IterableUtils;true;filteredIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;find;;;Argument[0].Element;ReturnValue;value;manual", - ";IterableUtils;true;first;;;Argument[0].Element;ReturnValue;value;manual", - ";IterableUtils;true;forEachButLast;;;Argument[0].Element;ReturnValue;value;manual", - ";IterableUtils;true;get;;;Argument[0].Element;ReturnValue;value;manual", - ";IterableUtils;true;loopingIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;partition;;;Argument[0].Element;ReturnValue.Element.Element;value;manual", - ";IterableUtils;true;reversedIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;skippingIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;toList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;toString;;;Argument[2];ReturnValue;taint;manual", - ";IterableUtils;true;toString;;;Argument[3];ReturnValue;taint;manual", - ";IterableUtils;true;toString;;;Argument[4];ReturnValue;taint;manual", - ";IterableUtils;true;uniqueIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;unmodifiableIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;zippingIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;zippingIterable;(Iterable,Iterable[]);;Argument[1].ArrayElement.Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;zippingIterable;(Iterable,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.EnumerationUtils`. - */ -private class ApacheEnumerationUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";EnumerationUtils;true;get;;;Argument[0].Element;ReturnValue;value;manual", - ";EnumerationUtils;true;toList;(Enumeration);;Argument[0].Element;ReturnValue.Element;value;manual", - ";EnumerationUtils;true;toList;(StringTokenizer);;Argument[0];ReturnValue.Element;taint;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.MultiMapUtils`. - */ -private class ApacheMultiMapUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";MultiMapUtils;true;emptyIfNull;;;Argument[0];ReturnValue;value;manual", - ";MultiMapUtils;true;getCollection;;;Argument[0].MapValue;ReturnValue;value;manual", - ";MultiMapUtils;true;getValuesAsBag;;;Argument[0].MapValue.Element;ReturnValue.Element;value;manual", - ";MultiMapUtils;true;getValuesAsList;;;Argument[0].MapValue.Element;ReturnValue.Element;value;manual", - ";MultiMapUtils;true;getValuesAsSet;;;Argument[0].MapValue.Element;ReturnValue.Element;value;manual", - ";MultiMapUtils;true;transformedMultiValuedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MultiMapUtils;true;transformedMultiValuedMap;;;Argument[0].MapValue.Element;ReturnValue.MapValue.Element;value;manual", - ";MultiMapUtils;true;unmodifiableMultiValuedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MultiMapUtils;true;unmodifiableMultiValuedMap;;;Argument[0].MapValue.Element;ReturnValue.MapValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.MultiSetUtils`. - */ -private class ApacheMultiSetUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";MultiSetUtils;true;predicatedMultiSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";MultiSetUtils;true;synchronizedMultiSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";MultiSetUtils;true;unmodifiableMultiSet;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.QueueUtils`. - */ -private class ApacheQueueUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";QueueUtils;true;predicatedQueue;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";QueueUtils;true;synchronizedQueue;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";QueueUtils;true;transformingQueue;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";QueueUtils;true;unmodifiableQueue;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the classes `org.apache.commons.collections4.SetUtils` - * and `org.apache.commons.collections4.SetUtils$SetView`. - */ -private class ApacheSetUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";SetUtils$SetView;true;copyInto;;;Argument[-1].Element;Argument[0].Element;value;manual", - ";SetUtils$SetView;true;createIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";SetUtils$SetView;true;toSet;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;difference;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;disjunction;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;disjunction;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;emptyIfNull;;;Argument[0];ReturnValue;value;manual", - ";SetUtils;true;hashSet;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - ";SetUtils;true;intersection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;intersection;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;orderedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;predicatedNavigableSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;predicatedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;predicatedSortedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;synchronizedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;synchronizedSortedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;transformedNavigableSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;transformedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;transformedSortedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;union;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;union;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;unmodifiableNavigableSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;unmodifiableSet;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - ";SetUtils;true;unmodifiableSet;(Set);;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;unmodifiableSortedSet;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.SplitMapUtils`. - */ -private class ApacheSplitMapUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";SplitMapUtils;true;readableMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";SplitMapUtils;true;readableMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";SplitMapUtils;true;writableMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";SplitMapUtils;true;writableMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.TrieUtils`. - */ -private class ApacheTrieUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";TrieUtils;true;unmodifiableTrie;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";TrieUtils;true;unmodifiableTrie;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.BagUtils`. - */ -private class ApacheBagUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";BagUtils;true;collectionBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";BagUtils;true;predicatedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";BagUtils;true;predicatedSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";BagUtils;true;synchronizedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";BagUtils;true;synchronizedSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";BagUtils;true;transformingBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";BagUtils;true;transformingSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";BagUtils;true;unmodifiableBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";BagUtils;true;unmodifiableSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/IO.qll b/java/ql/lib/semmle/code/java/frameworks/apache/IO.qll deleted file mode 100644 index 997bffb9110..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/apache/IO.qll +++ /dev/null @@ -1,23 +0,0 @@ -/** Custom definitions related to the Apache Commons IO library. */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class ApacheCommonsIOCustomSummaryCsv extends SummaryModelCsv { - /** - * Models that are not yet auto generated or where the generated summaries will - * be ignored. - * Note that if a callable has any handwritten summary, all generated summaries - * will be ignored for that callable. - */ - override predicate row(string row) { - row = - [ - "org.apache.commons.io;IOUtils;false;toBufferedInputStream;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.io;IOUtils;true;writeLines;(Collection,String,Writer);;Argument[0].Element;Argument[2];taint;manual", - "org.apache.commons.io;IOUtils;true;writeLines;(Collection,String,Writer);;Argument[1];Argument[2];taint;manual", - "org.apache.commons.io;IOUtils;true;toByteArray;(Reader);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.io;IOUtils;true;toByteArray;(Reader,String);;Argument[0];ReturnValue;taint;manual", - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/Lang.qll b/java/ql/lib/semmle/code/java/frameworks/apache/Lang.qll index 84db672e935..ea04948d9bc 100644 --- a/java/ql/lib/semmle/code/java/frameworks/apache/Lang.qll +++ b/java/ql/lib/semmle/code/java/frameworks/apache/Lang.qll @@ -1,8 +1,6 @@ /** Definitions related to the Apache Commons Lang library. */ import java -import Lang2Generated -import Lang3Generated private import semmle.code.java.dataflow.FlowSteps private import semmle.code.java.dataflow.ExternalFlow diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/Lang2Generated.qll b/java/ql/lib/semmle/code/java/frameworks/apache/Lang2Generated.qll deleted file mode 100644 index 3d9c8116c59..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/apache/Lang2Generated.qll +++ /dev/null @@ -1,284 +0,0 @@ -/** Definitions related to the Apache Commons Lang 2 library. */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class ApacheCommonsLangModel extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.commons.text;StrBuilder;false;append;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;append;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;append;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(char[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.CharSequence,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.CharSequence);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.String,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.StringBuilder,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.nio.CharBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.nio.CharBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(org.apache.commons.text.StrBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendAll;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;appendAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendAll;(Iterable);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendAll;(Iterator);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendAll;(Object[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendFixedWidthPadRight;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(char[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.StringBuilder,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(org.apache.commons.text.StrBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendNewLine;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendNull;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendPadding;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendSeparator;(java.lang.String,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendSeparator;(java.lang.String,java.lang.String);;Argument[0..1];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendSeparator;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendTo;;;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendWithSeparators;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendWithSeparators;(Iterable,String);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendWithSeparators;(Iterator,String);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendWithSeparators;(Object[],String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;asReader;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;asTokenizer;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;delete;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;deleteAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;deleteCharAt;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;deleteFirst;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;ensureCapacity;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;getChars;(char[]);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;StrBuilder;false;getChars;(char[]);;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;getChars;(int,int,char[],int);;Argument[-1];Argument[2];taint;manual", - "org.apache.commons.text;StrBuilder;false;insert;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;insert;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;insert;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;leftString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;midString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;minimizeCapacity;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;readFrom;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;replace;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;replace;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;replace;(int,int,java.lang.String);;Argument[2];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;replace;(org.apache.commons.text.StrMatcher,java.lang.String,int,int,int);;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;replaceAll;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;replaceAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;replaceAll;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;replaceFirst;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;reverse;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;rightString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;setCharAt;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;setLength;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;setNewLineText;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;setNullText;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;StrBuilder;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;subSequence;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;substring;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;toCharArray;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;toStringBuffer;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;toStringBuilder;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;trim;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(char[],int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.CharSequence,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.CharSequence);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;Argument[1].MapValue;ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map);;Argument[1].MapValue;ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;Argument[1].MapValue;ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.String,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.StringBuffer,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.StringBuffer);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(org.apache.commons.text.TextStringBuilder,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(org.apache.commons.text.TextStringBuilder);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replaceIn;(java.lang.StringBuffer,int,int);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replaceIn;(java.lang.StringBuffer);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replaceIn;(java.lang.StringBuilder,int,int);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replaceIn;(java.lang.StringBuilder);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replaceIn;(org.apache.commons.text.TextStringBuilder,int,int);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replaceIn;(org.apache.commons.text.TextStringBuilder);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;StringSubstitutor;false;setVariableResolver;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StringSubstitutor;false;StringSubstitutor;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StringSubstitutor;false;StringSubstitutor;;;Argument[0].MapValue;Argument[-1];taint;manual", - "org.apache.commons.text;StringTokenizer;false;clone;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;getContent;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;getCSVInstance;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;getTokenArray;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;getTokenList;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;getTSVInstance;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;next;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;nextToken;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;previous;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;previousToken;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;reset;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StringTokenizer;false;reset;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;StringTokenizer;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StringTokenizer;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;clone;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;getContent;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;getCSVInstance;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;getTokenArray;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;getTokenList;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;getTSVInstance;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;next;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;nextToken;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;previous;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;previousToken;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;reset;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrTokenizer;false;reset;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;StrTokenizer;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrTokenizer;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(char[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.CharSequence,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.CharSequence);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.StringBuilder,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.nio.CharBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.nio.CharBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(org.apache.commons.text.TextStringBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendAll;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendAll;(Iterable);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendAll;(Iterator);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendAll;(Object[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadLeft;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadRight;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(char[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.StringBuilder,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(org.apache.commons.text.TextStringBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendNewLine;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendNull;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendPadding;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendSeparator;(java.lang.String,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendSeparator;(java.lang.String,java.lang.String);;Argument[0..1];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendSeparator;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendTo;;;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;(Iterable,String);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;(Iterator,String);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;(Object[],String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;asReader;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;asTokenizer;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;delete;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;deleteAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;deleteCharAt;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;deleteFirst;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;ensureCapacity;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;getChars;(char[]);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;getChars;(char[]);;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;getChars;(int,int,char[],int);;Argument[-1];Argument[2];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;insert;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;insert;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;insert;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;leftString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;midString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;minimizeCapacity;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;readFrom;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;replace;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;replace;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;replace;(int,int,java.lang.String);;Argument[2];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;replace;(org.apache.commons.text.matcher.StringMatcher,java.lang.String,int,int,int);;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;replaceAll;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;replaceAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;replaceAll;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;replaceFirst;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;reverse;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;rightString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;setCharAt;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;setLength;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;setNewLineText;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;setNullText;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;subSequence;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;substring;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;TextStringBuilder;(java.lang.CharSequence);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;TextStringBuilder;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;toCharArray;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;toStringBuffer;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;toStringBuilder;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;trim;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;WordUtils;false;abbreviate;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;abbreviate;;;Argument[3];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;capitalize;(java.lang.String,char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;capitalize;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;capitalizeFully;(java.lang.String,char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;capitalizeFully;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;initials;(java.lang.String,char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;initials;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;swapCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;uncapitalize;(java.lang.String,char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;uncapitalize;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;wrap;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;wrap;(java.lang.String,int,java.lang.String,boolean,java.lang.String);;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;wrap;(java.lang.String,int,java.lang.String,boolean);;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.text.lookup;StringLookup;true;lookup;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text.lookup;StringLookupFactory;false;mapStringLookup;;;Argument[0].MapValue;ReturnValue;taint;manual", - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/Lang3Generated.qll b/java/ql/lib/semmle/code/java/frameworks/apache/Lang3Generated.qll deleted file mode 100644 index 532bb20619e..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/apache/Lang3Generated.qll +++ /dev/null @@ -1,436 +0,0 @@ -/** Definitions related to the Apache Commons Lang 3 library. */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class ApacheCommonsLang3Model extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.commons.lang3;ArrayUtils;false;add;;;Argument[2];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(boolean[],boolean);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(byte[],byte);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(char[],char);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(double[],double);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(float[],float);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(int[],int);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(java.lang.Object[],java.lang.Object);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(long[],long);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(short[],short);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;addAll;;;Argument[0..1].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;addFirst;;;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;addFirst;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;clone;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;get;;;Argument[0].ArrayElement;ReturnValue;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;get;(java.lang.Object[],int,java.lang.Object);;Argument[2];ReturnValue;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;insert;;;Argument[1..2].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;nullToEmpty;(java.lang.Object[],java.lang.Class);;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;nullToEmpty;(java.lang.String[]);;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;remove;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;removeAll;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;removeAllOccurences;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;removeAllOccurrences;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;removeElement;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;removeElements;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;subarray;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;toArray;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;toMap;;;Argument[0].ArrayElement.ArrayElement;ReturnValue.MapKey;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;toMap;;;Argument[0].ArrayElement.ArrayElement;ReturnValue.MapValue;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;toMap;;;Argument[0].ArrayElement.MapKey;ReturnValue.MapKey;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;toMap;;;Argument[0].ArrayElement.MapValue;ReturnValue.MapValue;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;toObject;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;toPrimitive;;;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;toPrimitive;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;clone;;;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;cloneIfPossible;;;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;CONST_BYTE;;;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;CONST_SHORT;;;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;CONST;;;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;defaultIfNull;;;Argument[0..1];ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;firstNonNull;;;Argument[0].ArrayElement;ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;getIfNull;;;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;max;;;Argument[0].ArrayElement;ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;median;;;Argument[0].ArrayElement;ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;min;;;Argument[0].ArrayElement;ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;mode;;;Argument[0].ArrayElement;ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;requireNonEmpty;;;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;toString;(Object,String);;Argument[1];ReturnValue;value;manual", - "org.apache.commons.lang3;RegExUtils;false;removeAll;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;RegExUtils;false;removeFirst;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;RegExUtils;false;removePattern;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;RegExUtils;false;replaceAll;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;RegExUtils;false;replaceAll;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;RegExUtils;false;replaceFirst;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;RegExUtils;false;replaceFirst;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;RegExUtils;false;replacePattern;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;RegExUtils;false;replacePattern;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringEscapeUtils;false;escapeJson;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;abbreviate;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;abbreviate;(java.lang.String,java.lang.String,int,int);;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;abbreviate;(java.lang.String,java.lang.String,int);;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;abbreviateMiddle;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;abbreviateMiddle;;;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;appendIfMissing;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;appendIfMissing;;;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;appendIfMissingIgnoreCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;appendIfMissingIgnoreCase;;;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;capitalize;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;center;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;center;(java.lang.String,int,java.lang.String);;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;chomp;(java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;chomp;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;chop;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;defaultIfBlank;;;Argument[0..1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;defaultIfEmpty;;;Argument[0..1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;defaultString;;;Argument[0..1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;deleteWhitespace;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;difference;;;Argument[0..1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;firstNonBlank;;;Argument[0].ArrayElement;ReturnValue;value;manual", - "org.apache.commons.lang3;StringUtils;false;firstNonEmpty;;;Argument[0].ArrayElement;ReturnValue;value;manual", - "org.apache.commons.lang3;StringUtils;false;getBytes;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;getCommonPrefix;;;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;getDigits;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;getIfBlank;;;Argument[0..1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;getIfEmpty;;;Argument[0..1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(char[],char,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(char[],char);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Iterable,char);;Argument[0].Element;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Iterable,java.lang.String);;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Iterable,java.lang.String);;Argument[0].Element;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],char,int,int);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],char);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String,int,int);;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String,int,int);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String);;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[]);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.util.Iterator,char);;Argument[0].Element;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.util.Iterator,java.lang.String);;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.util.Iterator,java.lang.String);;Argument[0].Element;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.util.List,char,int,int);;Argument[0].Element;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.util.List,java.lang.String,int,int);;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.util.List,java.lang.String,int,int);;Argument[0].Element;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;joinWith;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;joinWith;;;Argument[1].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;left;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;leftPad;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;leftPad;(java.lang.String,int,java.lang.String);;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;lowerCase;(java.lang.String,java.util.Locale);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;lowerCase;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;mid;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;normalizeSpace;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;overlay;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;overlay;;;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;prependIfMissing;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;prependIfMissing;;;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;prependIfMissingIgnoreCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;prependIfMissingIgnoreCase;;;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;remove;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;removeAll;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;removeEnd;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;removeEndIgnoreCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;removeFirst;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;removeIgnoreCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;removePattern;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;removeStart;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;removeStartIgnoreCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;repeat;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;repeat;(java.lang.String,java.lang.String,int);;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replace;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replace;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceAll;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceAll;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceChars;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceChars;(java.lang.String,java.lang.String,java.lang.String);;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceEach;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceEach;;;Argument[2].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceEachRepeatedly;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceEachRepeatedly;;;Argument[2].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceFirst;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceFirst;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceIgnoreCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceIgnoreCase;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceOnce;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceOnce;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceOnceIgnoreCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceOnceIgnoreCase;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replacePattern;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replacePattern;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;reverse;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;reverseDelimited;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;right;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;rightPad;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;rightPad;(java.lang.String,int,java.lang.String);;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;rotate;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;split;(java.lang.String,char);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;split;(java.lang.String,java.lang.String,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;split;(java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;split;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;splitByCharacterType;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;splitByCharacterTypeCamelCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;splitByWholeSeparator;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;splitByWholeSeparatorPreserveAllTokens;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;splitPreserveAllTokens;(java.lang.String,char);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;splitPreserveAllTokens;(java.lang.String,java.lang.String,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;splitPreserveAllTokens;(java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;splitPreserveAllTokens;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;strip;(java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;strip;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;stripAccents;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;stripAll;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;taint;manual", - "org.apache.commons.lang3;StringUtils;false;stripEnd;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;stripStart;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;stripToEmpty;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;stripToNull;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;substring;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;substringAfter;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;substringAfterLast;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;substringBefore;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;substringBeforeLast;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;substringBetween;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;substringsBetween;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;swapCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;toCodePoints;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;toEncodedString;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;toRootLowerCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;toRootUpperCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;toString;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;trim;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;trimToEmpty;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;trimToNull;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;truncate;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;uncapitalize;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;unwrap;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;upperCase;(java.lang.String,java.util.Locale);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;upperCase;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;valueOf;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;wrap;(java.lang.String,char);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;wrap;(java.lang.String,java.lang.String);;Argument[0..1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;wrapIfMissing;(java.lang.String,char);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;wrapIfMissing;(java.lang.String,java.lang.String);;Argument[0..1];ReturnValue;taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,boolean);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object);;Argument[0..1];Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;appendAsObjectToString;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;appendSuper;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;appendSuper;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;appendToString;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;appendToString;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;getStringBuffer;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.mutable;Mutable;true;getValue;;;Argument[-1].SyntheticField[org.apache.commons.lang3.mutable.MutableObject.value];ReturnValue;value;manual", - "org.apache.commons.lang3.mutable;MutableObject;false;MutableObject;;;Argument[0];Argument[-1].SyntheticField[org.apache.commons.lang3.mutable.MutableObject.value];value;manual", - "org.apache.commons.lang3.mutable;Mutable;true;setValue;;;Argument[0];Argument[-1].SyntheticField[org.apache.commons.lang3.mutable.MutableObject.value];value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(char[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.CharSequence,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.CharSequence);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.StringBuilder,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.nio.CharBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.nio.CharBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(org.apache.commons.lang3.text.StrBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendAll;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendAll;(Iterable);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendAll;(Iterator);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendAll;(Object[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadRight;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(char[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.StringBuilder,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(org.apache.commons.lang3.text.StrBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendNewLine;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendNull;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendPadding;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendSeparator;(java.lang.String,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendSeparator;(java.lang.String,java.lang.String);;Argument[0..1];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendSeparator;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendTo;;;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;(Iterable,String);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;(Iterator,String);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;(Object[],String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;asReader;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;asTokenizer;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;delete;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;deleteAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;deleteCharAt;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;deleteFirst;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;ensureCapacity;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;getChars;(char[]);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;getChars;(char[]);;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;getChars;(int,int,char[],int);;Argument[-1];Argument[2];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;insert;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;insert;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;insert;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;leftString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;midString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;minimizeCapacity;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;readFrom;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replace;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replace;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replace;(int,int,java.lang.String);;Argument[2];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replace;(org.apache.commons.lang3.text.StrMatcher,java.lang.String,int,int,int);;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replaceAll;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replaceAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replaceAll;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replaceFirst;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;reverse;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;rightString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;setCharAt;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;setLength;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;setNewLineText;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;setNullText;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;StrBuilder;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;subSequence;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;substring;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;toCharArray;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;toStringBuffer;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;toStringBuilder;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;trim;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrLookup;false;lookup;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrLookup;false;mapLookup;;;Argument[0].MapValue;ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(char[],int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.CharSequence,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.CharSequence);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;Argument[1].MapValue;ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map);;Argument[1].MapValue;ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;Argument[1].MapValue;ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.String,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.StringBuffer,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.StringBuffer);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(org.apache.commons.lang3.text.StrBuilder,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(org.apache.commons.lang3.text.StrBuilder);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(java.lang.StringBuffer,int,int);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(java.lang.StringBuffer);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(java.lang.StringBuilder,int,int);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(java.lang.StringBuilder);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(org.apache.commons.lang3.text.StrBuilder,int,int);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(org.apache.commons.lang3.text.StrBuilder);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;setVariableResolver;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;StrSubstitutor;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;StrSubstitutor;;;Argument[0].MapValue;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;clone;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;getContent;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;getCSVInstance;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;getTokenArray;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;getTokenList;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;getTSVInstance;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;next;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;nextToken;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;previous;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;previousToken;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;reset;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;reset;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;StrTokenizer;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;capitalize;(java.lang.String,char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;capitalize;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;capitalizeFully;(java.lang.String,char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;capitalizeFully;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;initials;(java.lang.String,char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;initials;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;swapCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;uncapitalize;(java.lang.String,char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;uncapitalize;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;wrap;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;wrap;(java.lang.String,int,java.lang.String,boolean,java.lang.String);;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;wrap;(java.lang.String,int,java.lang.String,boolean);;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3.tuple;ImmutablePair;false;ImmutablePair;(java.lang.Object,java.lang.Object);;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.left];value;manual", - "org.apache.commons.lang3.tuple;ImmutablePair;false;ImmutablePair;(java.lang.Object,java.lang.Object);;Argument[1];Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.right];value;manual", - "org.apache.commons.lang3.tuple;ImmutablePair;false;left;;;Argument[0];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.left];value;manual", - "org.apache.commons.lang3.tuple;ImmutablePair;false;of;(java.lang.Object,java.lang.Object);;Argument[0];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.left];value;manual", - "org.apache.commons.lang3.tuple;ImmutablePair;false;of;(java.lang.Object,java.lang.Object);;Argument[1];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.right];value;manual", - "org.apache.commons.lang3.tuple;ImmutablePair;false;right;;;Argument[0];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.right];value;manual", - "org.apache.commons.lang3.tuple;ImmutableTriple;false;ImmutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.left];value;manual", - "org.apache.commons.lang3.tuple;ImmutableTriple;false;ImmutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle];value;manual", - "org.apache.commons.lang3.tuple;ImmutableTriple;false;ImmutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.right];value;manual", - "org.apache.commons.lang3.tuple;ImmutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.left];value;manual", - "org.apache.commons.lang3.tuple;ImmutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle];value;manual", - "org.apache.commons.lang3.tuple;ImmutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.right];value;manual", - "org.apache.commons.lang3.tuple;MutablePair;false;MutablePair;(java.lang.Object,java.lang.Object);;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.left];value;manual", - "org.apache.commons.lang3.tuple;MutablePair;false;MutablePair;(java.lang.Object,java.lang.Object);;Argument[1];Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right];value;manual", - "org.apache.commons.lang3.tuple;MutablePair;false;of;(java.lang.Object,java.lang.Object);;Argument[0];ReturnValue.Field[org.apache.commons.lang3.tuple.MutablePair.left];value;manual", - "org.apache.commons.lang3.tuple;MutablePair;false;of;(java.lang.Object,java.lang.Object);;Argument[1];ReturnValue.Field[org.apache.commons.lang3.tuple.MutablePair.right];value;manual", - "org.apache.commons.lang3.tuple;MutablePair;false;setLeft;;;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.left];value;manual", - "org.apache.commons.lang3.tuple;MutablePair;false;setRight;;;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right];value;manual", - "org.apache.commons.lang3.tuple;MutablePair;false;setValue;;;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;MutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.left];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;MutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.middle];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;MutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.right];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];ReturnValue.Field[org.apache.commons.lang3.tuple.MutableTriple.left];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];ReturnValue.Field[org.apache.commons.lang3.tuple.MutableTriple.middle];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];ReturnValue.Field[org.apache.commons.lang3.tuple.MutableTriple.right];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;setLeft;;;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.left];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;setMiddle;;;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.middle];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;setRight;;;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.right];value;manual", - "org.apache.commons.lang3.tuple;Pair;true;getKey;;;Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.left];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Pair;true;getKey;;;Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.left];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Pair;true;getLeft;;;Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.left];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Pair;true;getLeft;;;Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.left];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Pair;true;getRight;;;Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.right];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Pair;true;getRight;;;Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Pair;true;getValue;;;Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.right];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Pair;true;getValue;;;Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Pair;false;of;(java.lang.Object,java.lang.Object);;Argument[0];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.left];value;manual", - "org.apache.commons.lang3.tuple;Pair;false;of;(java.lang.Object,java.lang.Object);;Argument[1];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.right];value;manual", - "org.apache.commons.lang3.tuple;Triple;true;getLeft;;;Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.left];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Triple;true;getMiddle;;;Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Triple;true;getRight;;;Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.right];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Triple;true;getLeft;;;Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.left];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Triple;true;getMiddle;;;Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.middle];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Triple;true;getRight;;;Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.right];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Triple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.left];value;manual", - "org.apache.commons.lang3.tuple;Triple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle];value;manual", - "org.apache.commons.lang3.tuple;Triple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.right];value;manual", - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/guava/Base.qll b/java/ql/lib/semmle/code/java/frameworks/guava/Base.qll deleted file mode 100644 index 424dade4291..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/guava/Base.qll +++ /dev/null @@ -1,98 +0,0 @@ -/** Definitions of flow steps through utility methods of `com.google.common.base`. */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class GuavaBaseCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "com.google.common.base;Strings;false;emptyToNull;(String);;Argument[0];ReturnValue;value;manual", - "com.google.common.base;Strings;false;nullToEmpty;(String);;Argument[0];ReturnValue;value;manual", - "com.google.common.base;Strings;false;padStart;(String,int,char);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Strings;false;padEnd;(String,int,char);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Strings;false;repeat;(String,int);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Strings;false;lenientFormat;(String,Object[]);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Strings;false;lenientFormat;(String,Object[]);;Argument[1].ArrayElement;ReturnValue;taint;manual", - "com.google.common.base;Joiner;false;on;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Joiner;false;skipNulls;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.base;Joiner;false;useForNull;(String);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.base;Joiner;false;useForNull;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Joiner;false;withKeyValueSeparator;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Joiner;false;withKeyValueSeparator;(String);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.base;Joiner;false;withKeyValueSeparator;(char);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.base;Joiner;false;appendTo;(Appendable,Object,Object,Object[]);;Argument[1..2];Argument[0];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(Appendable,Object,Object,Object[]);;Argument[3].ArrayElement;Argument[0];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(Appendable,Iterable);;Argument[1].Element;Argument[-1];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(Appendable,Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(Appendable,Iterator);;Argument[1].Element;Argument[-1];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(StringBuilder,Object,Object,Object[]);;Argument[1..2];Argument[0];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(StringBuilder,Object,Object,Object[]);;Argument[3].ArrayElement;Argument[0];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(StringBuilder,Iterable);;Argument[1].Element;Argument[-1];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(StringBuilder,Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(StringBuilder,Iterator);;Argument[1].Element;Argument[-1];taint;manual", - "com.google.common.base;Joiner;false;appendTo;;;Argument[-1];Argument[0];taint;manual", - "com.google.common.base;Joiner;false;appendTo;;;Argument[0];ReturnValue;value;manual", - "com.google.common.base;Joiner;false;join;;;Argument[-1..2];ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;useForNull;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;useForNull;(String);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;appendTo;;;Argument[1];Argument[0];taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;appendTo;;;Argument[0];ReturnValue;value;manual", - "com.google.common.base;Joiner$MapJoiner;false;join;;;Argument[-1];ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;join;(Iterable);;Argument[0].Element.MapKey;ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;join;(Iterable);;Argument[0].Element.MapValue;ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;join;(Iterator);;Argument[0].Element.MapKey;ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;join;(Iterator);;Argument[0].Element.MapValue;ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;join;(Map);;Argument[0].MapKey;ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;join;(Map);;Argument[0].MapValue;ReturnValue;taint;manual", - "com.google.common.base;Splitter;false;split;(CharSequence);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Splitter;false;splitToList;(CharSequence);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Splitter;false;splitToStream;(CharSequence);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Splitter$MapSplitter;false;split;(CharSequence);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Preconditions;false;checkNotNull;;;Argument[0];ReturnValue;value;manual", - "com.google.common.base;Verify;false;verifyNotNull;;;Argument[0];ReturnValue;value;manual", - "com.google.common.base;Ascii;false;toLowerCase;(CharSequence);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Ascii;false;toLowerCase;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Ascii;false;toUpperCase;(CharSequence);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Ascii;false;toUpperCase;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Ascii;false;truncate;(CharSequence,int,String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Ascii;false;truncate;(CharSequence,int,String);;Argument[2];ReturnValue;taint;manual", - "com.google.common.base;CaseFormat;true;to;(CaseFormat,String);;Argument[1];ReturnValue;taint;manual", - "com.google.common.base;Converter;true;apply;(Object);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Converter;true;convert;(Object);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Converter;true;convertAll;(Iterable);;Argument[0].Element;ReturnValue.Element;taint;manual", - "com.google.common.base;Supplier;true;get;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.base;Suppliers;false;ofInstance;(Object);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Suppliers;false;memoize;(Supplier);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Suppliers;false;memoizeWithExpiration;(Supplier,long,TimeUnit);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Suppliers;false;synchronizedSupplier;(Supplier);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Optional;true;fromJavaUtil;(Optional);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.base;Optional;true;fromNullable;(Object);;Argument[0];ReturnValue.Element;value;manual", - "com.google.common.base;Optional;true;get;();;Argument[-1].Element;ReturnValue;value;manual", - "com.google.common.base;Optional;true;asSet;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "com.google.common.base;Optional;true;of;(Object);;Argument[0];ReturnValue.Element;value;manual", - "com.google.common.base;Optional;true;or;(Optional);;Argument[-1..0].Element;ReturnValue.Element;value;manual", - "com.google.common.base;Optional;true;or;(Supplier);;Argument[-1].Element;ReturnValue;value;manual", - "com.google.common.base;Optional;true;or;(Supplier);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Optional;true;or;(Object);;Argument[-1].Element;ReturnValue;value;manual", - "com.google.common.base;Optional;true;or;(Object);;Argument[0];ReturnValue;value;manual", - "com.google.common.base;Optional;true;orNull;();;Argument[-1].Element;ReturnValue;value;manual", - "com.google.common.base;Optional;true;presentInstances;(Iterable);;Argument[0].Element.Element;ReturnValue.Element;value;manual", - "com.google.common.base;Optional;true;toJavaUtil;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "com.google.common.base;Optional;true;toJavaUtil;(Optional);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.base;MoreObjects;false;firstNonNull;(Object,Object);;Argument[0..1];ReturnValue;value;manual", - "com.google.common.base;MoreObjects;false;toStringHelper;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;add;;;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;add;;;Argument[0];Argument[-1];taint;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;add;;;Argument[-1];ReturnValue;value;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;add;(String,Object);;Argument[1];ReturnValue;taint;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;add;(String,Object);;Argument[1];Argument[-1];taint;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;addValue;;;Argument[-1];ReturnValue;value;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;addValue;(Object);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;addValue;(Object);;Argument[0];Argument[-1];taint;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;omitNullValues;();;Argument[-1];ReturnValue;value;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;toString;();;Argument[-1];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/guava/Cache.qll b/java/ql/lib/semmle/code/java/frameworks/guava/Cache.qll deleted file mode 100644 index d1f8cf4f776..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/guava/Cache.qll +++ /dev/null @@ -1,32 +0,0 @@ -/** Flow steps through methods of `com.google.common.cache` */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class GuavaBaseCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "com.google.common.cache;Cache;true;asMap;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.cache;Cache;true;asMap;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - // lambda flow from Argument[1] not implemented - "com.google.common.cache;Cache;true;get;(Object,Callable);;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.cache;Cache;true;getIfPresent;(Object);;Argument[-1].MapValue;ReturnValue;value;manual", - // the true flow to MapKey of ReturnValue for getAllPresent is the intersection of the these inputs, but intersections cannot be modeled fully accurately. - "com.google.common.cache;Cache;true;getAllPresent;(Iterable);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.cache;Cache;true;getAllPresent;(Iterable);;Argument[0].Element;ReturnValue.MapKey;value;manual", - "com.google.common.cache;Cache;true;getAllPresent;(Iterable);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.cache;Cache;true;put;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.cache;Cache;true;put;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "com.google.common.cache;Cache;true;putAll;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "com.google.common.cache;Cache;true;putAll;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.cache;LoadingCache;true;get;(Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.cache;LoadingCache;true;getUnchecked;(Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.cache;LoadingCache;true;apply;(Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.cache;LoadingCache;true;getAll;(Iterable);;Argument[0].Element;ReturnValue.MapKey;value;manual", - "com.google.common.cache;LoadingCache;true;getAll;(Iterable);;Argument[0].Element;Argument[-1].MapKey;value;manual", - "com.google.common.cache;LoadingCache;true;getAll;(Iterable);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/guava/Collections.qll b/java/ql/lib/semmle/code/java/frameworks/guava/Collections.qll index feb27d22ec0..c20bafb36de 100644 --- a/java/ql/lib/semmle/code/java/frameworks/guava/Collections.qll +++ b/java/ql/lib/semmle/code/java/frameworks/guava/Collections.qll @@ -8,571 +8,6 @@ private import semmle.code.java.Collections private string guavaCollectPackage() { result = "com.google.common.collect" } -private class GuavaCollectCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - // Methods depending on lambda flow are not currently modeled - // Methods depending on stronger aliasing properties than we support are also not modeled. - "com.google.common.collect;ArrayListMultimap;true;create;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ArrayListMultimap;true;create;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ArrayTable;true;create;(Iterable,Iterable);;Argument[0].Element;ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;ArrayTable;true;create;(Iterable,Iterable);;Argument[1].Element;ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;ArrayTable;true;create;(Table);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ArrayTable;true;create;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;ArrayTable;true;create;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;BiMap;true;forcePut;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.collect;BiMap;true;forcePut;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "com.google.common.collect;BiMap;true;inverse;();;Argument[-1].MapKey;ReturnValue.MapValue;value;manual", - "com.google.common.collect;BiMap;true;inverse;();;Argument[-1].MapValue;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ClassToInstanceMap;true;getInstance;(Class);;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.collect;ClassToInstanceMap;true;putInstance;(Class,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "com.google.common.collect;ClassToInstanceMap;true;putInstance;(Class,Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.collect;Collections2;false;filter;(Collection,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Collections2;false;orderedPermutations;(Iterable);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Collections2;false;orderedPermutations;(Iterable,Comparator);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Collections2;false;permutations;(Collection);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;ConcurrentHashMultiset;true;create;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;HashBasedTable;true;create;(Table);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;HashBasedTable;true;create;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;HashBasedTable;true;create;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;HashBiMap;true;create;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;HashBiMap;true;create;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;HashMultimap;true;create;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;HashMultimap;true;create;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;HashMultiset;true;create;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[0];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[1];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[2];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[3];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[4];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[5];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[6];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[7];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[8];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[9];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableClassToInstanceMap;true;copyOf;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableClassToInstanceMap;true;copyOf;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableClassToInstanceMap;true;of;(Class,Object);;Argument[0];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableClassToInstanceMap;true;of;(Class,Object);;Argument[1];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableCollection$Builder;true;add;(Object);;Argument[0];Argument[-1].Element;value;manual", - "com.google.common.collect;ImmutableCollection$Builder;true;add;(Object[]);;Argument[0].ArrayElement;Argument[-1].Element;value;manual", - "com.google.common.collect;ImmutableCollection$Builder;true;add;;;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableCollection$Builder;true;addAll;(Iterable);;Argument[0].Element;Argument[-1].Element;value;manual", - "com.google.common.collect;ImmutableCollection$Builder;true;addAll;(Iterator);;Argument[0].Element;Argument[-1].Element;value;manual", - "com.google.common.collect;ImmutableCollection$Builder;true;addAll;;;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableCollection$Builder;true;build;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableCollection;true;asList;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;copyOf;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;copyOf;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;copyOf;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;copyOf;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;of;;;Argument[0..11];ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;of;;;Argument[12].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;reverse;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;sortedCopyOf;(Comparator,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;sortedCopyOf;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[0];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[1];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[2];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[3];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[4];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[5];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[6];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[7];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[8];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[9];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;build;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;build;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;orderEntriesByValue;(Comparator);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;put;(Entry);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;put;(Entry);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;put;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;put;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;put;;;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;putAll;(Iterable);;Argument[0].Element.MapKey;Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;putAll;(Iterable);;Argument[0].Element.MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;putAll;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;putAll;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;putAll;;;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableMap;true;copyOf;(Iterable);;Argument[0].Element.MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMap;true;copyOf;(Iterable);;Argument[0].Element.MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMap;true;copyOf;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMap;true;copyOf;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[0];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[1];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[2];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[3];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[4];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[5];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[6];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[7];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[8];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[9];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;build;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;build;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;orderKeysBy;(Comparator);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;orderValuesBy;(Comparator);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;put;(Entry);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;put;(Entry);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;put;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;put;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;put;;;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;(Iterable);;Argument[0].Element.MapKey;Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;(Iterable);;Argument[0].Element.MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;(Multimap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;(Multimap);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;(Object,Iterable);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;(Object,Iterable);;Argument[1].Element;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;(Object,Object[]);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;(Object,Object[]);;Argument[1].ArrayElement;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;;;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableMultimap;true;copyOf;(Iterable);;Argument[0].Element.MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap;true;copyOf;(Iterable);;Argument[0].Element.MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap;true;copyOf;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap;true;copyOf;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap;true;inverse;();;Argument[-1].MapKey;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap;true;inverse;();;Argument[-1].MapValue;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[0];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[1];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[2];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[3];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[4];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[5];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[6];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[7];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[8];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[9];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultiset$Builder;true;addCopies;(Object,int);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableMultiset$Builder;true;addCopies;(Object,int);;Argument[0];Argument[-1].Element;value;manual", - "com.google.common.collect;ImmutableMultiset$Builder;true;setCount;(Object,int);;Argument[0];Argument[-1].Element;value;manual", - "com.google.common.collect;ImmutableMultiset;true;copyOf;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableMultiset;true;copyOf;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableMultiset;true;copyOf;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableMultiset;true;of;;;Argument[0..5];ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableMultiset;true;of;;;Argument[6].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSet;true;copyOf;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSet;true;copyOf;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSet;true;copyOf;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSet;true;copyOf;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSet;true;of;;;Argument[0..5];ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSet;true;of;;;Argument[6].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[0];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[1];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[2];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[3];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[4];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[5];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[6];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[7];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[8];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[9];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOf;(Iterable);;Argument[0].Element.MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOf;(Iterable);;Argument[0].Element.MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOf;(Iterable,Comparator);;Argument[0].Element.MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOf;(Iterable,Comparator);;Argument[0].Element.MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOf;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOf;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOf;(Map,Comparator);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOf;(Map,Comparator);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOfSorted;(SortedMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOfSorted;(SortedMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[0];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[1];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[2];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[3];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[4];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[5];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[6];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[7];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[8];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[9];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMultiset;true;copyOf;(Comparable[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedMultiset;true;copyOf;(Comparator,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedMultiset;true;copyOf;(Comparator,Iterator);;Argument[1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedMultiset;true;copyOf;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedMultiset;true;copyOf;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedMultiset;true;copyOfSorted;(SortedMultiset);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedMultiset;true;of;;;Argument[0..5];ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedMultiset;true;of;;;Argument[6].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;copyOf;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;copyOf;(Comparable[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;copyOf;(Comparator,Collection);;Argument[1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;copyOf;(Comparator,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;copyOf;(Comparator,Iterator);;Argument[1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;copyOf;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;copyOf;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;copyOfSorted;(SortedSet);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;of;;;Argument[0..5];ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;of;;;Argument[6].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;build;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;build;();;Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;build;();;Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;orderColumnsBy;(Comparator);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;orderRowsBy;(Comparator);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;put;(Cell);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;put;(Cell);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;put;(Cell);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;put;(Cell);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;put;(Object,Object,Object);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;put;(Object,Object,Object);;Argument[0];Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;put;(Object,Object,Object);;Argument[1];Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;put;(Object,Object,Object);;Argument[2];Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;putAll;(Table);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;putAll;(Table);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;putAll;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;putAll;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;ImmutableTable;true;copyOf;(Table);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableTable;true;copyOf;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;ImmutableTable;true;copyOf;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;ImmutableTable;true;of;(Object,Object,Object);;Argument[0];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;ImmutableTable;true;of;(Object,Object,Object);;Argument[1];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;ImmutableTable;true;of;(Object,Object,Object);;Argument[2];ReturnValue.MapValue;value;manual", - "com.google.common.collect;Iterables;false;addAll;(Collection,Iterable);;Argument[1].Element;Argument[0].Element;value;manual", - "com.google.common.collect;Iterables;false;concat;(Iterable);;Argument[0].Element.Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;concat;(Iterable,Iterable);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;concat;(Iterable,Iterable,Iterable);;Argument[0..2].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;concat;(Iterable,Iterable,Iterable,Iterable);;Argument[0..3].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;concat;(Iterable[]);;Argument[0].ArrayElement.Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;consumingIterable;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;cycle;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;cycle;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;filter;(Iterable,Class);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;filter;(Iterable,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;find;(Iterable,Predicate);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;find;(Iterable,Predicate,Object);;Argument[2];ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;find;(Iterable,Predicate,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;get;(Iterable,int);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;get;(Iterable,int,Object);;Argument[2];ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;get;(Iterable,int,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;getLast;(Iterable);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;getLast;(Iterable,Object);;Argument[1];ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;getLast;(Iterable,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;getOnlyElement;(Iterable);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;getOnlyElement;(Iterable,Object);;Argument[1];ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;getOnlyElement;(Iterable,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;limit;(Iterable,int);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;mergeSorted;(Iterable,Comparator);;Argument[0].Element.Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;paddedPartition;(Iterable,int);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Iterables;false;partition;(Iterable,int);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Iterables;false;skip;(Iterable,int);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;toArray;(Iterable,Class);;Argument[0].Element;ReturnValue.ArrayElement;value;manual", - //"com.google.common.collect;Iterables;false;toString;(Iterable);;Element of Argument[0];ReturnValue;taint;manual", - "com.google.common.collect;Iterables;false;tryFind;(Iterable,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;unmodifiableIterable;(ImmutableCollection);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;unmodifiableIterable;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;addAll;(Collection,Iterator);;Argument[1].Element;Argument[0].Element;value;manual", - "com.google.common.collect;Iterators;false;asEnumeration;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;concat;(Iterator);;Argument[0].Element.Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;concat;(Iterator,Iterator);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;concat;(Iterator,Iterator,Iterator);;Argument[0..2].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;concat;(Iterator,Iterator,Iterator,Iterator);;Argument[0..3].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;concat;(Iterator[]);;Argument[0].ArrayElement.Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;consumingIterator;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;cycle;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;cycle;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;filter;(Iterator,Class);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;filter;(Iterator,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;find;(Iterator,Predicate);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;find;(Iterator,Predicate,Object);;Argument[2];ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;find;(Iterator,Predicate,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;forArray;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;forEnumeration;(Enumeration);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;get;(Iterator,int);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;get;(Iterator,int,Object);;Argument[2];ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;get;(Iterator,int,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;getLast;(Iterator);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;getLast;(Iterator,Object);;Argument[1];ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;getLast;(Iterator,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;getNext;(Iterator,Object);;Argument[1];ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;getNext;(Iterator,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;getOnlyElement;(Iterator);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;getOnlyElement;(Iterator,Object);;Argument[1];ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;getOnlyElement;(Iterator,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;limit;(Iterator,int);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;mergeSorted;(Iterable,Comparator);;Argument[0].Element.Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;paddedPartition;(Iterator,int);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Iterators;false;partition;(Iterator,int);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Iterators;false;peekingIterator;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;peekingIterator;(PeekingIterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;singletonIterator;(Object);;Argument[0];ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;toArray;(Iterator,Class);;Argument[0].Element;ReturnValue.ArrayElement;value;manual", - "com.google.common.collect;Iterators;false;tryFind;(Iterator,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;unmodifiableIterator;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;unmodifiableIterator;(UnmodifiableIterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;LinkedHashMultimap;true;create;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;LinkedHashMultimap;true;create;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;LinkedHashMultiset;true;create;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;LinkedListMultimap;true;create;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;LinkedListMultimap;true;create;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Lists;false;asList;(Object,Object,Object[]);;Argument[0..1];ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;asList;(Object,Object,Object[]);;Argument[2].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;asList;(Object,Object[]);;Argument[0];ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;asList;(Object,Object[]);;Argument[1].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;cartesianProduct;(List);;Argument[0].Element.Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Lists;false;cartesianProduct;(List[]);;Argument[0].ArrayElement.Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Lists;false;charactersOf;(CharSequence);;Argument[0];ReturnValue.Element;taint;manual", - "com.google.common.collect;Lists;false;charactersOf;(String);;Argument[0];ReturnValue.Element;taint;manual", - "com.google.common.collect;Lists;false;newArrayList;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;newArrayList;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;newArrayList;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;newCopyOnWriteArrayList;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;newLinkedList;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;partition;(List,int);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Lists;false;reverse;(List);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;MapDifference$ValueDifference;true;leftValue;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left];ReturnValue;value;manual", - "com.google.common.collect;MapDifference$ValueDifference;true;rightValue;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right];ReturnValue;value;manual", - "com.google.common.collect;MapDifference;true;entriesDiffering;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;MapDifference;true;entriesDiffering;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;MapDifference;true;entriesDiffering;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapValue;ReturnValue.MapValue.SyntheticField[com.google.common.collect.MapDifference.left];value;manual", - "com.google.common.collect;MapDifference;true;entriesDiffering;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapValue;ReturnValue.MapValue.SyntheticField[com.google.common.collect.MapDifference.right];value;manual", - "com.google.common.collect;MapDifference;true;entriesInCommon;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;MapDifference;true;entriesInCommon;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;MapDifference;true;entriesInCommon;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;MapDifference;true;entriesInCommon;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;MapDifference;true;entriesOnlyOnLeft;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;MapDifference;true;entriesOnlyOnLeft;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;MapDifference;true;entriesOnlyOnRight;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;MapDifference;true;entriesOnlyOnRight;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;asMap;(NavigableSet,Function);;Argument[0].Element;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;asMap;(Set,Function);;Argument[0].Element;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;asMap;(SortedSet,Function);;Argument[0].Element;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;difference;(Map,Map);;Argument[0].MapKey;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapKey;value;manual", - "com.google.common.collect;Maps;false;difference;(Map,Map);;Argument[1].MapKey;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapKey;value;manual", - "com.google.common.collect;Maps;false;difference;(Map,Map);;Argument[0].MapValue;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapValue;value;manual", - "com.google.common.collect;Maps;false;difference;(Map,Map);;Argument[1].MapValue;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapValue;value;manual", - "com.google.common.collect;Maps;false;difference;(Map,Map,Equivalence);;Argument[0].MapKey;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapKey;value;manual", - "com.google.common.collect;Maps;false;difference;(Map,Map,Equivalence);;Argument[1].MapKey;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapKey;value;manual", - "com.google.common.collect;Maps;false;difference;(Map,Map,Equivalence);;Argument[0].MapValue;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapValue;value;manual", - "com.google.common.collect;Maps;false;difference;(Map,Map,Equivalence);;Argument[1].MapValue;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapValue;value;manual", - "com.google.common.collect;Maps;false;difference;(SortedMap,Map);;Argument[0].MapKey;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapKey;value;manual", - "com.google.common.collect;Maps;false;difference;(SortedMap,Map);;Argument[1].MapKey;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapKey;value;manual", - "com.google.common.collect;Maps;false;difference;(SortedMap,Map);;Argument[0].MapValue;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapValue;value;manual", - "com.google.common.collect;Maps;false;difference;(SortedMap,Map);;Argument[1].MapValue;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapValue;value;manual", - "com.google.common.collect;Maps;false;filterEntries;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;filterKeys;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;filterValues;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;fromProperties;(Properties);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;fromProperties;(Properties);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;immutableEntry;(Object,Object);;Argument[0];ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;immutableEntry;(Object,Object);;Argument[1];ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;immutableEnumMap;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;newEnumMap;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;newHashMap;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;newHashMap;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;newLinkedHashMap;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;newLinkedHashMap;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;newTreeMap;(SortedMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;newTreeMap;(SortedMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;subMap;(NavigableMap,Range);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;subMap;(NavigableMap,Range);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;synchronizedBiMap;(BiMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;synchronizedBiMap;(BiMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;synchronizedNavigableMap;(NavigableMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;synchronizedNavigableMap;(NavigableMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;toMap;(Iterable,Function);;Argument[0].Element;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;toMap;(Iterator,Function);;Argument[0].Element;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;transformValues;(Map,Function);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;transformValues;(NavigableMap,Function);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;transformValues;(SortedMap,Function);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;uniqueIndex;(Iterable,Function);;Argument[0].Element;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;uniqueIndex;(Iterator,Function);;Argument[0].Element;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;unmodifiableBiMap;(BiMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;unmodifiableBiMap;(BiMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;unmodifiableNavigableMap;(NavigableMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;unmodifiableNavigableMap;(NavigableMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimap;true;asMap;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimap;true;asMap;();;Argument[-1].MapValue;ReturnValue.MapValue.Element;value;manual", - "com.google.common.collect;Multimap;true;entries;();;Argument[-1].MapKey;ReturnValue.Element.MapKey;value;manual", - "com.google.common.collect;Multimap;true;entries;();;Argument[-1].MapValue;ReturnValue.Element.MapValue;value;manual", - "com.google.common.collect;Multimap;true;get;(Object);;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "com.google.common.collect;Multimap;true;keySet;();;Argument[-1].MapKey;ReturnValue.Element;value;manual", - "com.google.common.collect;Multimap;true;keys;();;Argument[-1].MapKey;ReturnValue.Element;value;manual", - "com.google.common.collect;Multimap;true;put;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.collect;Multimap;true;put;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "com.google.common.collect;Multimap;true;putAll;(Multimap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "com.google.common.collect;Multimap;true;putAll;(Multimap);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;Multimap;true;putAll;(Object,Iterable);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.collect;Multimap;true;putAll;(Object,Iterable);;Argument[1].Element;Argument[-1].MapValue;value;manual", - "com.google.common.collect;Multimap;true;removeAll;(Object);;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "com.google.common.collect;Multimap;true;replaceValues;(Object,Iterable);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.collect;Multimap;true;replaceValues;(Object,Iterable);;Argument[1].Element;Argument[-1].MapValue;value;manual", - "com.google.common.collect;Multimap;true;replaceValues;(Object,Iterable);;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "com.google.common.collect;Multimap;true;values;();;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "com.google.common.collect;Multimaps;false;asMap;(ListMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;asMap;(ListMultimap);;Argument[0].MapValue;ReturnValue.MapValue.Element;value;manual", - "com.google.common.collect;Multimaps;false;asMap;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;asMap;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue.Element;value;manual", - "com.google.common.collect;Multimaps;false;asMap;(SetMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;asMap;(SetMultimap);;Argument[0].MapValue;ReturnValue.MapValue.Element;value;manual", - "com.google.common.collect;Multimaps;false;asMap;(SortedSetMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;asMap;(SortedSetMultimap);;Argument[0].MapValue;ReturnValue.MapValue.Element;value;manual", - "com.google.common.collect;Multimaps;false;filterEntries;(Multimap,Predicate);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;filterEntries;(Multimap,Predicate);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;filterEntries;(SetMultimap,Predicate);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;filterEntries;(SetMultimap,Predicate);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;filterKeys;(Multimap,Predicate);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;filterKeys;(Multimap,Predicate);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;filterKeys;(SetMultimap,Predicate);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;filterKeys;(SetMultimap,Predicate);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;filterValues;(Multimap,Predicate);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;filterValues;(Multimap,Predicate);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;filterValues;(SetMultimap,Predicate);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;filterValues;(SetMultimap,Predicate);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;forMap;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;forMap;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;index;(Iterable,Function);;Argument[0].Element;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;index;(Iterator,Function);;Argument[0].Element;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;invertFrom;(Multimap,Multimap);;Argument[1];ReturnValue;value;manual", - "com.google.common.collect;Multimaps;false;invertFrom;(Multimap,Multimap);;Argument[0].MapKey;Argument[1].MapValue;value;manual", - "com.google.common.collect;Multimaps;false;invertFrom;(Multimap,Multimap);;Argument[0].MapValue;Argument[1].MapKey;value;manual", - "com.google.common.collect;Multimaps;false;newListMultimap;(Map,Supplier);;Argument[0].MapValue.Element;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;newListMultimap;(Map,Supplier);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;newMultimap;(Map,Supplier);;Argument[0].MapValue.Element;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;newMultimap;(Map,Supplier);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;newSetMultimap;(Map,Supplier);;Argument[0].MapValue.Element;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;newSetMultimap;(Map,Supplier);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;newSortedSetMultimap;(Map,Supplier);;Argument[0].MapValue.Element;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;newSortedSetMultimap;(Map,Supplier);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;synchronizedListMultimap;(ListMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;synchronizedListMultimap;(ListMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;synchronizedMultimap;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;synchronizedMultimap;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;synchronizedSetMultimap;(SetMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;synchronizedSetMultimap;(SetMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;synchronizedSortedSetMultimap;(SortedSetMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;synchronizedSortedSetMultimap;(SortedSetMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;transformValues;(ListMultimap,Function);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;transformValues;(Multimap,Function);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableListMultimap;(ImmutableListMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableListMultimap;(ImmutableListMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableListMultimap;(ListMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableListMultimap;(ListMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableMultimap;(ImmutableMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableMultimap;(ImmutableMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableMultimap;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableMultimap;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableSetMultimap;(ImmutableSetMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableSetMultimap;(ImmutableSetMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableSetMultimap;(SetMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableSetMultimap;(SetMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableSortedSetMultimap;(SortedSetMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableSortedSetMultimap;(SortedSetMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multiset$Entry;true;getElement;();;Argument[-1].Element;ReturnValue;value;manual", - "com.google.common.collect;Multiset;true;add;(Object,int);;Argument[0];Argument[-1].Element;value;manual", - "com.google.common.collect;Multiset;true;elementSet;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multiset;true;entrySet;();;Argument[-1].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Multiset;true;setCount;(Object,int);;Argument[0];Argument[-1].Element;value;manual", - "com.google.common.collect;Multiset;true;setCount;(Object,int,int);;Argument[0];Argument[-1].Element;value;manual", - "com.google.common.collect;Multisets;false;copyHighestCountFirst;(Multiset);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;difference;(Multiset,Multiset);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;filter;(Multiset,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;immutableEntry;(Object,int);;Argument[0];ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;intersection;(Multiset,Multiset);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;sum;(Multiset,Multiset);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;union;(Multiset,Multiset);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;unmodifiableMultiset;(ImmutableMultiset);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;unmodifiableMultiset;(Multiset);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;unmodifiableSortedMultiset;(SortedMultiset);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;MutableClassToInstanceMap;true;create;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;MutableClassToInstanceMap;true;create;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ObjectArrays;false;concat;(Object,Object[]);;Argument[0];ReturnValue.ArrayElement;value;manual", - "com.google.common.collect;ObjectArrays;false;concat;(Object,Object[]);;Argument[1].ArrayElement;ReturnValue.ArrayElement;value;manual", - "com.google.common.collect;ObjectArrays;false;concat;(Object[],Object);;Argument[1];ReturnValue.ArrayElement;value;manual", - "com.google.common.collect;ObjectArrays;false;concat;(Object[],Object);;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "com.google.common.collect;ObjectArrays;false;concat;(Object[],Object[],Class);;Argument[0..1].ArrayElement;ReturnValue.ArrayElement;value;manual", - "com.google.common.collect;Queues;false;drain;(BlockingQueue,Collection,int,Duration);;Argument[0].Element;Argument[1].Element;value;manual", - "com.google.common.collect;Queues;false;drain;(BlockingQueue,Collection,int,long,TimeUnit);;Argument[0].Element;Argument[1].Element;value;manual", - "com.google.common.collect;Queues;false;newArrayDeque;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Queues;false;newConcurrentLinkedQueue;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Queues;false;newLinkedBlockingDeque;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Queues;false;newLinkedBlockingQueue;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Queues;false;newPriorityBlockingQueue;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Queues;false;newPriorityQueue;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Queues;false;synchronizedDeque;(Deque);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Queues;false;synchronizedQueue;(Queue);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets$SetView;true;copyInto;(Set);;Argument[-1].Element;Argument[0].Element;value;manual", - "com.google.common.collect;Sets$SetView;true;immutableCopy;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;cartesianProduct;(List);;Argument[0].Element.Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Sets;false;cartesianProduct;(Set[]);;Argument[0].ArrayElement.Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Sets;false;combinations;(Set,int);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Sets;false;difference;(Set,Set);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;filter;(NavigableSet,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;filter;(Set,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;filter;(SortedSet,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;intersection;(Set,Set);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newConcurrentHashSet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newCopyOnWriteArraySet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newHashSet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newHashSet;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newHashSet;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newLinkedHashSet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newSetFromMap;(Map);;Argument[0].MapKey;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newTreeSet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;powerSet;(Set);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Sets;false;subSet;(NavigableSet,Range);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;symmetricDifference;(Set,Set);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;synchronizedNavigableSet;(NavigableSet);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;union;(Set,Set);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;unmodifiableNavigableSet;(NavigableSet);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Table$Cell;true;getColumnKey;();;Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue;value;manual", - "com.google.common.collect;Table$Cell;true;getRowKey;();;Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue;value;manual", - "com.google.common.collect;Table$Cell;true;getValue;();;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.collect;Table;true;cellSet;();;Argument[-1].MapValue;ReturnValue.Element.MapValue;value;manual", - "com.google.common.collect;Table;true;cellSet;();;Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.Element.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Table;true;cellSet;();;Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.Element.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Table;true;column;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Table;true;column;(Object);;Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.MapKey;value;manual", - "com.google.common.collect;Table;true;columnKeySet;();;Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.Element;value;manual", - "com.google.common.collect;Table;true;columnMap;();;Argument[-1].MapValue;ReturnValue.MapValue.MapValue;value;manual", - "com.google.common.collect;Table;true;columnMap;();;Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.MapKey;value;manual", - "com.google.common.collect;Table;true;columnMap;();;Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.MapValue.MapKey;value;manual", - "com.google.common.collect;Table;true;get;(Object,Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.collect;Table;true;put;(Object,Object,Object);;Argument[0];Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Table;true;put;(Object,Object,Object);;Argument[1];Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Table;true;put;(Object,Object,Object);;Argument[2];Argument[-1].MapValue;value;manual", - "com.google.common.collect;Table;true;putAll;(Table);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;Table;true;putAll;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Table;true;putAll;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Table;true;remove;(Object,Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.collect;Table;true;row;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Table;true;row;(Object);;Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.MapKey;value;manual", - "com.google.common.collect;Table;true;rowKeySet;();;Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.Element;value;manual", - "com.google.common.collect;Table;true;rowMap;();;Argument[-1].MapValue;ReturnValue.MapValue.MapValue;value;manual", - "com.google.common.collect;Table;true;rowMap;();;Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.MapValue.MapKey;value;manual", - "com.google.common.collect;Table;true;rowMap;();;Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.MapKey;value;manual", - "com.google.common.collect;Table;true;values;();;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "com.google.common.collect;Tables;false;immutableCell;(Object,Object,Object);;Argument[0];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Tables;false;immutableCell;(Object,Object,Object);;Argument[1];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Tables;false;immutableCell;(Object,Object,Object);;Argument[2];ReturnValue.MapValue;value;manual", - "com.google.common.collect;Tables;false;newCustomTable;(Map,Supplier);;Argument[0].MapKey;ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Tables;false;newCustomTable;(Map,Supplier);;Argument[0].MapValue.MapKey;ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Tables;false;newCustomTable;(Map,Supplier);;Argument[0].MapValue.MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Tables;false;synchronizedTable;(Table);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Tables;false;synchronizedTable;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Tables;false;synchronizedTable;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Tables;false;transformValues;(Table,Function);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Tables;false;transformValues;(Table,Function);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Tables;false;transpose;(Table);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Tables;false;transpose;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Tables;false;transpose;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Tables;false;unmodifiableRowSortedTable;(RowSortedTable);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Tables;false;unmodifiableRowSortedTable;(RowSortedTable);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Tables;false;unmodifiableRowSortedTable;(RowSortedTable);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Tables;false;unmodifiableTable;(Table);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Tables;false;unmodifiableTable;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Tables;false;unmodifiableTable;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;TreeBasedTable;true;create;(TreeBasedTable);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;TreeBasedTable;true;create;(TreeBasedTable);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;TreeBasedTable;true;create;(TreeBasedTable);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;TreeMultimap;true;create;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;TreeMultimap;true;create;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;TreeMultiset;true;create;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - /** * A reference type that extends a parameterization of `com.google.common.collect.Multimap`. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/guava/Guava.qll b/java/ql/lib/semmle/code/java/frameworks/guava/Guava.qll index d7a4ab959df..5dd8aaa18ee 100644 --- a/java/ql/lib/semmle/code/java/frameworks/guava/Guava.qll +++ b/java/ql/lib/semmle/code/java/frameworks/guava/Guava.qll @@ -3,7 +3,4 @@ */ import java -import Base import Collections -import IO -import Cache diff --git a/java/ql/lib/semmle/code/java/frameworks/guava/IO.qll b/java/ql/lib/semmle/code/java/frameworks/guava/IO.qll deleted file mode 100644 index 59fc0113e10..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/guava/IO.qll +++ /dev/null @@ -1,101 +0,0 @@ -/** Definitions of taint steps in the IO package of the Guava framework */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class GuavaIoCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "com.google.common.io;BaseEncoding;true;decode;(CharSequence);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;decodingStream;(Reader);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;decodingSource;(CharSource);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;encode;(byte[]);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;encode;(byte[],int,int);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;withSeparator;(String,int);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;decode;(CharSequence);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;decodingStream;(Reader);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;decodingSource;(CharSource);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;encode;(byte[]);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;upperCase;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;lowerCase;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;withPadChar;(char);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;omitPadding;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;encode;(byte[],int,int);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;asCharSource;(Charset);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;concat;(ByteSource[]);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;concat;(Iterable);;Argument[0].Element;ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;concat;(Iterator);;Argument[0].Element;ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;copyTo;(OutputStream);;Argument[-1];Argument[0];taint;manual", - "com.google.common.io;ByteSource;true;openStream;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;openBufferedStream;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;read;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;slice;(long,long);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;wrap;(byte[]);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;ByteStreams;false;copy;(InputStream,OutputStream);;Argument[0];Argument[1];taint;manual", - "com.google.common.io;ByteStreams;false;copy;(ReadableByteChannel,WritableByteChannel);;Argument[0];Argument[1];taint;manual", - "com.google.common.io;ByteStreams;false;limit;(InputStream,long);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;ByteStreams;false;newDataInput;(byte[]);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;ByteStreams;false;newDataInput;(byte[],int);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;ByteStreams;false;newDataInput;(ByteArrayInputStream);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;ByteStreams;false;newDataOutput;(ByteArrayOutputStream);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;ByteStreams;false;read;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint;manual", - "com.google.common.io;ByteStreams;false;readFully;(InputStream,byte[]);;Argument[0];Argument[1];taint;manual", - "com.google.common.io;ByteStreams;false;readFully;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint;manual", - "com.google.common.io;ByteStreams;false;toByteArray;(InputStream);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;asByteSource;(Charset);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;concat;(CharSource[]);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;concat;(Iterable);;Argument[0].Element;ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;concat;(Iterator);;Argument[0].Element;ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;copyTo;(Appendable);;Argument[-1];Argument[0];taint;manual", - "com.google.common.io;CharSource;true;openStream;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;openBufferedStream;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;read;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;readFirstLine;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;readLines;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;lines;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;wrap;(CharSequence);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;CharStreams;false;copy;(Readable,Appendable);;Argument[0];Argument[1];taint;manual", - "com.google.common.io;CharStreams;false;readLines;(Readable);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;CharStreams;false;toString;(Readable);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;Closer;true;register;;;Argument[0];ReturnValue;value;manual", - "com.google.common.io;Files;false;getFileExtension;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;Files;false;getNameWithoutExtension;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;Files;false;simplifyPath;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;MoreFiles;false;getFileExtension;(Path);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;MoreFiles;false;getNameWithoutExtension;(Path);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;LineReader;false;LineReader;(Readable);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;LineReader;true;readLine;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;toByteArray;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;write;(byte[]);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;write;(byte[],int,int);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;write;(int);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeByte;(int);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeBytes;(String);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeChar;(int);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeChars;(String);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeDouble;(double);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeFloat;(float);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeInt;(int);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeLong;(long);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeShort;(int);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeUTF;(String);;Argument[0];Argument[-1];taint;manual" - ] - } -} - -private class GuavaIoSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; kind` - "com.google.common.io;Resources;false;asByteSource;(URL);;Argument[0];url-open-stream;manual", - "com.google.common.io;Resources;false;asCharSource;(URL,Charset);;Argument[0];url-open-stream;manual", - "com.google.common.io;Resources;false;copy;(URL,OutputStream);;Argument[0];url-open-stream;manual", - "com.google.common.io;Resources;false;readLines;;;Argument[0];url-open-stream;manual", - "com.google.common.io;Resources;false;toByteArray;(URL);;Argument[0];url-open-stream;manual", - "com.google.common.io;Resources;false;toString;(URL,Charset);;Argument[0];url-open-stream;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/jOOQ.qll b/java/ql/lib/semmle/code/java/frameworks/jOOQ.qll index 20a7303dd76..c109b980508 100644 --- a/java/ql/lib/semmle/code/java/frameworks/jOOQ.qll +++ b/java/ql/lib/semmle/code/java/frameworks/jOOQ.qll @@ -22,9 +22,3 @@ predicate jOOQSqlMethod(Method m) { m.getAnAnnotation() instanceof PlainSqlType and m.getParameterType(0) instanceof TypeString } - -private class SqlSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = "org.jooq;PlainSQL;false;;;Annotated;Argument[0];sql;manual" - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll b/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll index 400f96598c1..7499e26450c 100644 --- a/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll +++ b/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll @@ -282,18 +282,3 @@ class JacksonMixedInCallable extends Callable { ) } } - -private class JacksonModel extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "com.fasterxml.jackson.databind;ObjectMapper;true;valueToTree;;;Argument[0];ReturnValue;taint;manual", - "com.fasterxml.jackson.databind;ObjectMapper;true;valueToTree;;;Argument[0].MapValue;ReturnValue;taint;manual", - "com.fasterxml.jackson.databind;ObjectMapper;true;valueToTree;;;Argument[0].MapValue.Element;ReturnValue;taint;manual", - "com.fasterxml.jackson.databind;ObjectMapper;true;convertValue;;;Argument[0];ReturnValue;taint;manual", - "com.fasterxml.jackson.databind;ObjectMapper;false;createParser;;;Argument[0];ReturnValue;taint;manual", - "com.fasterxml.jackson.databind;ObjectReader;false;createParser;;;Argument[0];ReturnValue;taint;manual", - "com.fasterxml.jackson.core;JsonFactory;false;createParser;;;Argument[0];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/jsf/JSFRenderer.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/jsf/JSFRenderer.qll index 9efa891676b..17eec30769a 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/jsf/JSFRenderer.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/jsf/JSFRenderer.qll @@ -12,22 +12,6 @@ class FacesContext extends RefType { } } -private class ExternalContextSource extends SourceModelCsv { - override predicate row(string row) { - row = - ["javax.", "jakarta."] + - [ - "faces.context;ExternalContext;true;getRequestParameterMap;();;ReturnValue;remote;manual", - "faces.context;ExternalContext;true;getRequestParameterNames;();;ReturnValue;remote;manual", - "faces.context;ExternalContext;true;getRequestParameterValuesMap;();;ReturnValue;remote;manual", - "faces.context;ExternalContext;true;getRequestPathInfo;();;ReturnValue;remote;manual", - "faces.context;ExternalContext;true;getRequestCookieMap;();;ReturnValue;remote;manual", - "faces.context;ExternalContext;true;getRequestHeaderMap;();;ReturnValue;remote;manual", - "faces.context;ExternalContext;true;getRequestHeaderValuesMap;();;ReturnValue;remote;manual" - ] - } -} - /** * The method `getResponseWriter()` declared in JSF `ExternalContext`. */ @@ -49,15 +33,3 @@ class FacesGetResponseStreamMethod extends Method { this.getNumberOfParameters() = 0 } } - -private class ExternalContextXssSink extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "javax.faces.context;ResponseWriter;true;write;;;Argument[0];xss;manual", - "javax.faces.context;ResponseStream;true;write;;;Argument[0];xss;manual", - "jakarta.faces.context;ResponseWriter;true;write;;;Argument[0];xss;manual", - "jakarta.faces.context;ResponseStream;true;write;;;Argument[0];xss;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/kotlin/StdLib.qll b/java/ql/lib/semmle/code/java/frameworks/kotlin/StdLib.qll deleted file mode 100644 index 3d70961cf37..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/kotlin/StdLib.qll +++ /dev/null @@ -1,14 +0,0 @@ -/** Definitions of taint steps in the KotlinStdLib framework */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class KotlinStdLibSummaryCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "kotlin.jvm.internal;ArrayIteratorKt;false;iterator;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "kotlin.collections;ArraysKt;false;withIndex;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/ratpack/Ratpack.qll b/java/ql/lib/semmle/code/java/frameworks/ratpack/Ratpack.qll deleted file mode 100644 index 772ea3866e5..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/ratpack/Ratpack.qll +++ /dev/null @@ -1,135 +0,0 @@ -/** - * Provides classes and predicates related to `ratpack.*`. - */ - -import java -private import semmle.code.java.dataflow.DataFlow -private import semmle.code.java.dataflow.FlowSteps -private import semmle.code.java.dataflow.ExternalFlow - -/** - * Ratpack methods that access user-supplied request data. - */ -private class RatpackHttpSource extends SourceModelCsv { - override predicate row(string row) { - row = - ["ratpack.http;", "ratpack.core.http;"] + - [ - "Request;true;getContentLength;;;ReturnValue;remote;manual", - "Request;true;getCookies;;;ReturnValue;remote;manual", - "Request;true;oneCookie;;;ReturnValue;remote;manual", - "Request;true;getHeaders;;;ReturnValue;remote;manual", - "Request;true;getPath;;;ReturnValue;remote;manual", - "Request;true;getQuery;;;ReturnValue;remote;manual", - "Request;true;getQueryParams;;;ReturnValue;remote;manual", - "Request;true;getRawUri;;;ReturnValue;remote;manual", - "Request;true;getUri;;;ReturnValue;remote;manual", - "Request;true;getBody;;;ReturnValue;remote;manual" - ] - or - // All Context#parse methods that return a Promise are remote flow sources. - row = - ["ratpack.handling;", "ratpack.core.handling;"] + "Context;true;parse;" + - [ - "(java.lang.Class);", "(com.google.common.reflect.TypeToken);", - "(java.lang.Class,java.lang.Object);", - "(com.google.common.reflect.TypeToken,java.lang.Object);", "(ratpack.core.parse.Parse);", - "(ratpack.parse.Parse);" - ] + ";ReturnValue;remote;manual" - } -} - -/** - * Ratpack methods that propagate user-supplied request data as tainted. - */ -private class RatpackModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["ratpack.http;", "ratpack.core.http;"] + - [ - "TypedData;true;getBuffer;;;Argument[-1];ReturnValue;taint;manual", - "TypedData;true;getBytes;;;Argument[-1];ReturnValue;taint;manual", - "TypedData;true;getContentType;;;Argument[-1];ReturnValue;taint;manual", - "TypedData;true;getInputStream;;;Argument[-1];ReturnValue;taint;manual", - "TypedData;true;getText;;;Argument[-1];ReturnValue;taint;manual", - "TypedData;true;writeTo;;;Argument[-1];Argument[0];taint;manual", - "Headers;true;get;;;Argument[-1];ReturnValue;taint;manual", - "Headers;true;getAll;;;Argument[-1];ReturnValue;taint;manual", - "Headers;true;getNames;;;Argument[-1];ReturnValue;taint;manual", - "Headers;true;asMultiValueMap;;;Argument[-1];ReturnValue;taint;manual" - ] - or - row = - ["ratpack.form;", "ratpack.core.form;"] + - [ - "UploadedFile;true;getFileName;;;Argument[-1];ReturnValue;taint;manual", - "Form;true;file;;;Argument[-1];ReturnValue;taint;manual", - "Form;true;files;;;Argument[-1];ReturnValue;taint;manual" - ] - or - row = - ["ratpack.handling;", "ratpack.core.handling;"] + - [ - "Context;true;parse;(ratpack.http.TypedData,ratpack.parse.Parse);;Argument[0];ReturnValue;taint;manual", - "Context;true;parse;(ratpack.core.http.TypedData,ratpack.core.parse.Parse);;Argument[0];ReturnValue;taint;manual", - "Context;true;parse;(ratpack.core.http.TypedData,ratpack.core.parse.Parse);;Argument[0];ReturnValue.MapKey;taint;manual", - "Context;true;parse;(ratpack.core.http.TypedData,ratpack.core.parse.Parse);;Argument[0];ReturnValue.MapValue;taint;manual" - ] - or - row = - ["ratpack.util;", "ratpack.func;"] + - [ - "MultiValueMap;true;getAll;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "MultiValueMap;true;getAll;();;Argument[-1].MapValue;ReturnValue.MapValue.Element;value;manual", - "MultiValueMap;true;getAll;(Object);;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "MultiValueMap;true;asMultimap;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "MultiValueMap;true;asMultimap;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual" - ] - or - exists(string left, string right | - left = "Field[ratpack.func.Pair.left]" and - right = "Field[ratpack.func.Pair.right]" - | - row = - ["ratpack.util;", "ratpack.func;"] + "Pair;true;" + - [ - "of;;;Argument[0];ReturnValue." + left + ";value;manual", - "of;;;Argument[1];ReturnValue." + right + ";value;manual", - "pair;;;Argument[0];ReturnValue." + left + ";value;manual", - "pair;;;Argument[1];ReturnValue." + right + ";value;manual", - "left;();;Argument[-1]." + left + ";ReturnValue;value;manual", - "right;();;Argument[-1]." + right + ";ReturnValue;value;manual", - "getLeft;;;Argument[-1]." + left + ";ReturnValue;value;manual", - "getRight;;;Argument[-1]." + right + ";ReturnValue;value;manual", - "left;(Object);;Argument[0];ReturnValue." + left + ";value;manual", - "left;(Object);;Argument[-1]." + right + ";ReturnValue." + right + ";value;manual", - "right;(Object);;Argument[0];ReturnValue." + right + ";value;manual", - "right;(Object);;Argument[-1]." + left + ";ReturnValue." + left + ";value;manual", - "pushLeft;(Object);;Argument[-1];ReturnValue." + right + ";value;manual", - "pushRight;(Object);;Argument[-1];ReturnValue." + left + ";value;manual", - "pushLeft;(Object);;Argument[0];ReturnValue." + left + ";value;manual", - "pushRight;(Object);;Argument[0];ReturnValue." + right + ";value;manual", - // `nestLeft` Pair.nestLeft(C) -> Pair, B> - "nestLeft;(Object);;Argument[0];ReturnValue." + left + "." + left + ";value;manual", - "nestLeft;(Object);;Argument[-1]." + left + ";ReturnValue." + left + "." + right + - ";value;manual", - "nestLeft;(Object);;Argument[-1]." + right + ";ReturnValue." + right + ";value;manual", - // `nestRight` Pair.nestRight(C) -> Pair> - "nestRight;(Object);;Argument[0];ReturnValue." + right + "." + left + ";value;manual", - "nestRight;(Object);;Argument[-1]." + left + ";ReturnValue." + left + ";value;manual", - "nestRight;(Object);;Argument[-1]." + right + ";ReturnValue." + right + "." + right + - ";value;manual", - // `mapLeft` & `mapRight` map over their respective fields - "mapLeft;;;Argument[-1]." + left + ";Argument[0].Parameter[0];value;manual", - "mapLeft;;;Argument[-1]." + right + ";ReturnValue." + right + ";value;manual", - "mapRight;;;Argument[-1]." + right + ";Argument[0].Parameter[0];value;manual", - "mapRight;;;Argument[-1]." + left + ";ReturnValue." + left + ";value;manual", - "mapLeft;;;Argument[0].ReturnValue;ReturnValue." + left + ";value;manual", - "mapRight;;;Argument[0].ReturnValue;ReturnValue." + right + ";value;manual", - // `map` maps over the `Pair` - "map;;;Argument[-1];Argument[0].Parameter[0];value;manual", - "map;;;Argument[0].ReturnValue;ReturnValue;value;manual" - ] - ) - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/ratpack/RatpackExec.qll b/java/ql/lib/semmle/code/java/frameworks/ratpack/RatpackExec.qll index 8f619d4a104..079cb44eb5d 100644 --- a/java/ql/lib/semmle/code/java/frameworks/ratpack/RatpackExec.qll +++ b/java/ql/lib/semmle/code/java/frameworks/ratpack/RatpackExec.qll @@ -7,102 +7,6 @@ private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.FlowSteps private import semmle.code.java.dataflow.ExternalFlow -/** - * Model for Ratpack `Promise` methods. - */ -private class RatpackExecModel extends SummaryModelCsv { - override predicate row(string row) { - //"namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind", - row = - "ratpack.exec;Promise;true;" + - [ - // `Promise` creation methods - "value;;;Argument[0];ReturnValue.Element;value;manual", - "flatten;;;Argument[0].ReturnValue.Element;ReturnValue.Element;value;manual", - "sync;;;Argument[0].ReturnValue;ReturnValue.Element;value;manual", - // `Promise` value transformation methods - "map;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "map;;;Argument[0].ReturnValue;ReturnValue.Element;value;manual", - "blockingMap;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "blockingMap;;;Argument[0].ReturnValue;ReturnValue.Element;value;manual", - "mapError;;;Argument[1].ReturnValue;ReturnValue.Element;value;manual", - // `apply` passes the qualifier to the function as the first argument - "apply;;;Argument[-1].Element;Argument[0].Parameter[0].Element;value;manual", - "apply;;;Argument[0].ReturnValue.Element;ReturnValue.Element;value;manual", - // `Promise` termination method - "then;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - // 'next' accesses qualifier the 'Promise' value and also returns the qualifier - "next;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "nextOp;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "flatOp;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - // `nextOpIf` accesses qualifier the 'Promise' value and also returns the qualifier - "nextOpIf;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "nextOpIf;;;Argument[-1].Element;Argument[1].Parameter[0];value;manual", - // 'cacheIf' accesses qualifier the 'Promise' value and also returns the qualifier - "cacheIf;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - // 'route' accesses qualifier the 'Promise' value, and conditionally returns the qualifier or - // the result of the second argument - "route;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "route;;;Argument[-1].Element;Argument[1].Parameter[0];value;manual", - "route;;;Argument[-1];ReturnValue;value;manual", - // `flatMap` type methods return their returned `Promise` - "flatMap;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "flatMap;;;Argument[0].ReturnValue.Element;ReturnValue.Element;value;manual", - "flatMapError;;;Argument[1].ReturnValue.Element;ReturnValue.Element;value;manual", - // `blockingOp` passes the value to the argument - "blockingOp;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - // `replace` returns the passed `Promise` - "replace;;;Argument[0].Element;ReturnValue.Element;value;manual", - // `mapIf` methods conditionally map their values, or return themselves - "mapIf;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "mapIf;;;Argument[-1].Element;Argument[1].Parameter[0];value;manual", - "mapIf;;;Argument[-1].Element;Argument[2].Parameter[0];value;manual", - "mapIf;;;Argument[1].ReturnValue;ReturnValue.Element;value;manual", - "mapIf;;;Argument[2].ReturnValue;ReturnValue.Element;value;manual", - // `wiretap` wraps the qualifier `Promise` value in a `Result` and passes it to the argument - "wiretap;;;Argument[-1].Element;Argument[0].Parameter[0].Element;value;manual" - ] - or - exists(string left, string right | - left = "Field[ratpack.func.Pair.left]" and - right = "Field[ratpack.func.Pair.right]" - | - row = - "ratpack.exec;Promise;true;" + - [ - // `left`, `right`, `flatLeft`, `flatRight` all pass the qualifier `Promise` element as the other `Pair` field - "left;;;Argument[-1].Element;ReturnValue.Element." + right + ";value;manual", - "right;;;Argument[-1].Element;ReturnValue.Element." + left + ";value;manual", - "flatLeft;;;Argument[-1].Element;ReturnValue.Element." + right + ";value;manual", - "flatRight;;;Argument[-1].Element;ReturnValue.Element." + left + ";value;manual", - // `left` and `right` taking a `Promise` create a `Promise` of the `Pair` - "left;(Promise);;Argument[0].Element;ReturnValue.Element." + left + ";value;manual", - "right;(Promise);;Argument[0].Element;ReturnValue.Element." + right + ";value;manual", - // `left` and `right` taking a `Function` pass the qualifier element then create a `Pair` with the returned value - "left;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "flatLeft;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "right;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "flatRight;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "left;(Function);;Argument[0].ReturnValue;ReturnValue.Element." + left + ";value;manual", - "flatLeft;(Function);;Argument[0].ReturnValue.Element;ReturnValue.Element." + left + - ";value;manual", - "right;(Function);;Argument[0].ReturnValue;ReturnValue.Element." + right + - ";value;manual", - "flatRight;(Function);;Argument[0].ReturnValue.Element;ReturnValue.Element." + right + - ";value;manual" - ] - ) - or - row = - "ratpack.exec;Result;true;" + - [ - "success;;;Argument[0];ReturnValue.Element;value;manual", - "getValue;;;Argument[-1].Element;ReturnValue;value;manual", - "getValueOrThrow;;;Argument[-1].Element;ReturnValue;value;manual" - ] - } -} - /** A reference type that extends a parameterization the Promise type. */ private class RatpackPromise extends RefType { RatpackPromise() { diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/Spring.qll b/java/ql/lib/semmle/code/java/frameworks/spring/Spring.qll index fd3008e5f00..2b09288610e 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/Spring.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/Spring.qll @@ -6,14 +6,10 @@ import semmle.code.java.frameworks.spring.SpringAttribute import semmle.code.java.frameworks.spring.SpringAutowire import semmle.code.java.frameworks.spring.SpringBean import semmle.code.java.frameworks.spring.SpringBeanFile -import semmle.code.java.frameworks.spring.SpringBeans import semmle.code.java.frameworks.spring.SpringBeanRefType -import semmle.code.java.frameworks.spring.SpringCache -import semmle.code.java.frameworks.spring.SpringContext import semmle.code.java.frameworks.spring.SpringComponentScan import semmle.code.java.frameworks.spring.SpringConstructorArg import semmle.code.java.frameworks.spring.SpringController -import semmle.code.java.frameworks.spring.SpringData import semmle.code.java.frameworks.spring.SpringDescription import semmle.code.java.frameworks.spring.SpringEntry import semmle.code.java.frameworks.spring.SpringFlex @@ -36,12 +32,7 @@ import semmle.code.java.frameworks.spring.SpringQualifier import semmle.code.java.frameworks.spring.SpringRef import semmle.code.java.frameworks.spring.SpringReplacedMethod import semmle.code.java.frameworks.spring.SpringSet -import semmle.code.java.frameworks.spring.SpringUi -import semmle.code.java.frameworks.spring.SpringUtil -import semmle.code.java.frameworks.spring.SpringValidation import semmle.code.java.frameworks.spring.SpringValue -import semmle.code.java.frameworks.spring.SpringWebMultipart -import semmle.code.java.frameworks.spring.SpringWebUtil import semmle.code.java.frameworks.spring.SpringXMLElement import semmle.code.java.frameworks.spring.metrics.MetricSpringBean import semmle.code.java.frameworks.spring.metrics.MetricSpringBeanFile diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringBeans.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringBeans.qll deleted file mode 100644 index 63671f21855..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringBeans.qll +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Provides classes and predicates for working with Spring classes and interfaces from - * `org.springframework.beans`. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -/** - * Provides models for the `org.springframework.beans` package. - */ -private class FlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.beans;PropertyValue;false;PropertyValue;(String,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.beans;PropertyValue;false;PropertyValue;(String,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "org.springframework.beans;PropertyValue;false;PropertyValue;(PropertyValue);;Argument[0];Argument[-1];value;manual", - "org.springframework.beans;PropertyValue;false;PropertyValue;(PropertyValue,Object);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.beans;PropertyValue;false;PropertyValue;(PropertyValue,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "org.springframework.beans;PropertyValue;false;getName;;;Argument[-1].MapKey;ReturnValue;value;manual", - "org.springframework.beans;PropertyValue;false;getValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - "org.springframework.beans;PropertyValues;true;getPropertyValue;;;Argument[-1].Element;ReturnValue;value;manual", - "org.springframework.beans;PropertyValues;true;getPropertyValues;;;Argument[-1].Element;ReturnValue.ArrayElement;value;manual", - "org.springframework.beans;MutablePropertyValues;true;MutablePropertyValues;(List);;Argument[0].Element;Argument[-1].Element;value;manual", - "org.springframework.beans;MutablePropertyValues;true;MutablePropertyValues;(Map);;Argument[0].MapKey;Argument[-1].Element.MapKey;value;manual", - "org.springframework.beans;MutablePropertyValues;true;MutablePropertyValues;(Map);;Argument[0].MapValue;Argument[-1].Element.MapValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;MutablePropertyValues;(PropertyValues);;Argument[0].Element;Argument[-1].Element;value;manual", - "org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[0];Argument[-1].Element.MapKey;value;manual", - "org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[-1];ReturnValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[1];Argument[-1].Element.MapValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(PropertyValue);;Argument[0];Argument[-1].Element;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(PropertyValue);;Argument[-1];ReturnValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(String,Object);;Argument[0];Argument[-1].Element.MapKey;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(String,Object);;Argument[1];Argument[-1].Element.MapValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(Map);;Argument[0].MapKey;Argument[-1].Element.MapKey;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(Map);;Argument[0].MapValue;Argument[-1].Element.MapValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(Map);;Argument[-1];ReturnValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(PropertyValues);;Argument[0].Element;Argument[-1].Element;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(PropertyValues);;Argument[-1];ReturnValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;get;;;Argument[-1].Element.MapValue;ReturnValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;getPropertyValue;;;Argument[-1].Element;ReturnValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;getPropertyValueList;;;Argument[-1].Element;ReturnValue.Element;value;manual", - "org.springframework.beans;MutablePropertyValues;true;getPropertyValues;;;Argument[-1].Element;ReturnValue.ArrayElement;value;manual", - "org.springframework.beans;MutablePropertyValues;true;setPropertyValueAt;;;Argument[0];Argument[-1].Element;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringCache.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringCache.qll deleted file mode 100644 index 007ce0d9d71..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringCache.qll +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Provides models for the `org.springframework.cache` package. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class FlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.cache;Cache$ValueRetrievalException;false;ValueRetrievalException;;;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.cache;Cache$ValueRetrievalException;false;getKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - "org.springframework.cache;Cache$ValueWrapper;true;get;;;Argument[-1].MapValue;ReturnValue;value;manual", - "org.springframework.cache;Cache;true;get;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "org.springframework.cache;Cache;true;get;(Object,Callable);;Argument[-1].MapValue;ReturnValue;value;manual", - "org.springframework.cache;Cache;true;get;(Object,Class);;Argument[-1].MapValue;ReturnValue;value;manual", - "org.springframework.cache;Cache;true;getNativeCache;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.cache;Cache;true;getNativeCache;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "org.springframework.cache;Cache;true;put;;;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.cache;Cache;true;put;;;Argument[1];Argument[-1].MapValue;value;manual", - "org.springframework.cache;Cache;true;putIfAbsent;;;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.cache;Cache;true;putIfAbsent;;;Argument[1];Argument[-1].MapValue;value;manual", - "org.springframework.cache;Cache;true;putIfAbsent;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringContext.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringContext.qll deleted file mode 100644 index 3860a5457cd..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringContext.qll +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Provides models for the `org.springframework.context` package. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class StringSummaryCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "org.springframework.context;MessageSource;true;getMessage;(String,Object[],String,Locale);;Argument[1].ArrayElement;ReturnValue;taint;manual", - "org.springframework.context;MessageSource;true;getMessage;(String,Object[],String,Locale);;Argument[2];ReturnValue;taint;manual", - "org.springframework.context;MessageSource;true;getMessage;(String,Object[],Locale);;Argument[1].ArrayElement;ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringData.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringData.qll deleted file mode 100644 index 52c8579b4c7..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringData.qll +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Provides classes and predicates for working with Spring classes and interfaces from - * `org.springframework.data`. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -/** - * Provides models for the `org.springframework.data` package. - */ -private class FlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - "org.springframework.data.repository;CrudRepository;true;save;;;Argument[0];ReturnValue;value;manual" - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringHttp.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringHttp.qll index 2114b4fcc75..6f4eedf0f36 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringHttp.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringHttp.qll @@ -43,107 +43,6 @@ class SpringHttpHeaders extends Class { SpringHttpHeaders() { this.hasQualifiedName("org.springframework.http", "HttpHeaders") } } -private class UrlOpenSink extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.http;RequestEntity;false;get;;;Argument[0];open-url;manual", - "org.springframework.http;RequestEntity;false;post;;;Argument[0];open-url;manual", - "org.springframework.http;RequestEntity;false;head;;;Argument[0];open-url;manual", - "org.springframework.http;RequestEntity;false;delete;;;Argument[0];open-url;manual", - "org.springframework.http;RequestEntity;false;options;;;Argument[0];open-url;manual", - "org.springframework.http;RequestEntity;false;patch;;;Argument[0];open-url;manual", - "org.springframework.http;RequestEntity;false;put;;;Argument[0];open-url;manual", - "org.springframework.http;RequestEntity;false;method;;;Argument[1];open-url;manual", - "org.springframework.http;RequestEntity;false;RequestEntity;(HttpMethod,URI);;Argument[1];open-url;manual", - "org.springframework.http;RequestEntity;false;RequestEntity;(MultiValueMap,HttpMethod,URI);;Argument[2];open-url;manual", - "org.springframework.http;RequestEntity;false;RequestEntity;(Object,HttpMethod,URI);;Argument[2];open-url;manual", - "org.springframework.http;RequestEntity;false;RequestEntity;(Object,HttpMethod,URI,Type);;Argument[2];open-url;manual", - "org.springframework.http;RequestEntity;false;RequestEntity;(Object,MultiValueMap,HttpMethod,URI);;Argument[3];open-url;manual", - "org.springframework.http;RequestEntity;false;RequestEntity;(Object,MultiValueMap,HttpMethod,URI,Type);;Argument[3];open-url;manual" - ] - } -} - -private class SpringHttpFlowStep extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - "org.springframework.http;HttpEntity;true;HttpEntity;(Object);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;HttpEntity;true;HttpEntity;(Object,MultiValueMap);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;HttpEntity;true;HttpEntity;(Object,MultiValueMap);;Argument[1].MapKey;Argument[-1];taint;manual", - "org.springframework.http;HttpEntity;true;HttpEntity;(Object,MultiValueMap);;Argument[1].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.http;HttpEntity;true;HttpEntity;(MultiValueMap);;Argument[0].MapKey;Argument[-1];taint;manual", - "org.springframework.http;HttpEntity;true;HttpEntity;(MultiValueMap);;Argument[0].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.http;HttpEntity;true;getBody;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpEntity;true;getHeaders;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,HttpStatus);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,HttpStatus);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,HttpStatus);;Argument[1].MapKey;Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,HttpStatus);;Argument[1].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(MultiValueMap,HttpStatus);;Argument[0].MapKey;Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(MultiValueMap,HttpStatus);;Argument[0].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,int);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,int);;Argument[1].MapKey;Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,int);;Argument[1].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;of;(Optional);;Argument[0].Element;ReturnValue;taint;manual", - "org.springframework.http;ResponseEntity;true;ok;(Object);;Argument[0];ReturnValue;taint;manual", - "org.springframework.http;ResponseEntity;true;created;(URI);;Argument[0];ReturnValue;taint;manual", - "org.springframework.http;ResponseEntity$BodyBuilder;true;contentLength;(long);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$BodyBuilder;true;contentType;(MediaType);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$BodyBuilder;true;body;(Object);;Argument[-1..0];ReturnValue;taint;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;allow;(HttpMethod[]);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;eTag;(String);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;eTag;(String);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;header;(String,String[]);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;header;(String,String[]);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;header;(String,String[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;headers;(Consumer);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;headers;(HttpHeaders);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;headers;(HttpHeaders);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;lastModified;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;location;(URI);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;location;(URI);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;varyBy;(String[]);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;build;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;RequestEntity;true;getUrl;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;HttpHeaders;(MultiValueMap);;Argument[0].MapKey;Argument[-1];taint;manual", - "org.springframework.http;HttpHeaders;true;HttpHeaders;(MultiValueMap);;Argument[0].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.http;HttpHeaders;true;get;(Object);;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getAccessControlAllowHeaders;();;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getAccessControlAllowOrigin;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getAccessControlExposeHeaders;();;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getAccessControlRequestHeaders;();;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getCacheControl;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getConnection;();;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getETag;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getETagValuesAsList;(String);;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getFieldValues;(String);;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getFirst;(String);;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getIfMatch;();;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getIfNoneMatch;();;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getHost;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getLocation;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getOrEmpty;(Object);;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getOrigin;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getPragma;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getUpgrade;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getValuesAsList;(String);;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getVary;();;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;add;(String,String);;Argument[0..1];Argument[-1];taint;manual", - "org.springframework.http;HttpHeaders;true;set;(String,String);;Argument[0..1];Argument[-1];taint;manual", - "org.springframework.http;HttpHeaders;true;addAll;(MultiValueMap);;Argument[0].MapKey;Argument[-1];taint;manual", - "org.springframework.http;HttpHeaders;true;addAll;(MultiValueMap);;Argument[0].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.http;HttpHeaders;true;addAll;(String,List);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;HttpHeaders;true;addAll;(String,List);;Argument[1].Element;Argument[-1];taint;manual", - "org.springframework.http;HttpHeaders;true;formatHeaders;(MultiValueMap);;Argument[0].MapKey;ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;formatHeaders;(MultiValueMap);;Argument[0].MapValue.Element;ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;encodeBasicAuth;(String,String,Charset);;Argument[0..1];ReturnValue;taint;manual" - ] - } -} - private predicate specifiesContentType(SpringRequestMappingMethod method) { exists(method.getAProducesExpr()) } diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringUi.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringUi.qll deleted file mode 100644 index e8ade8aa432..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringUi.qll +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Provides models for the `org.springframework.ui` package. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class FlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.ui;Model;true;addAllAttributes;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.ui;Model;true;addAllAttributes;(Collection);;Argument[0].Element;Argument[-1].MapValue;value;manual", - "org.springframework.ui;Model;true;addAllAttributes;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.ui;Model;true;addAllAttributes;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "org.springframework.ui;Model;true;addAttribute;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.ui;Model;true;addAttribute;(Object);;Argument[0];Argument[-1].MapValue;value;manual", - "org.springframework.ui;Model;true;addAttribute;(String,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.ui;Model;true;addAttribute;(String,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "org.springframework.ui;Model;true;asMap;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.ui;Model;true;asMap;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "org.springframework.ui;Model;true;getAttribute;;;Argument[-1].MapValue;ReturnValue;value;manual", - "org.springframework.ui;Model;true;mergeAttributes;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.ui;Model;true;mergeAttributes;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.ui;Model;true;mergeAttributes;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "org.springframework.ui;ModelMap;false;ModelMap;(Object);;Argument[0];Argument[-1].MapValue;value;manual", - "org.springframework.ui;ModelMap;false;ModelMap;(String,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.ui;ModelMap;false;ModelMap;(String,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "org.springframework.ui;ModelMap;false;addAllAttributes;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.ui;ModelMap;false;addAllAttributes;(Collection);;Argument[0].Element;Argument[-1].MapValue;value;manual", - "org.springframework.ui;ModelMap;false;addAllAttributes;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.ui;ModelMap;false;addAllAttributes;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "org.springframework.ui;ModelMap;false;addAttribute;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.ui;ModelMap;false;addAttribute;(Object);;Argument[0];Argument[-1].MapValue;value;manual", - "org.springframework.ui;ModelMap;false;addAttribute;(String,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.ui;ModelMap;false;addAttribute;(String,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "org.springframework.ui;ModelMap;false;getAttribute;;;Argument[-1].MapValue;ReturnValue;value;manual", - "org.springframework.ui;ModelMap;false;mergeAttributes;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.ui;ModelMap;false;mergeAttributes;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.ui;ModelMap;false;mergeAttributes;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "org.springframework.ui;ConcurrentModel;false;ConcurrentModel;(Object);;Argument[0];Argument[-1].MapValue;value;manual", - "org.springframework.ui;ConcurrentModel;false;ConcurrentModel;(String,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.ui;ConcurrentModel;false;ConcurrentModel;(String,Object);;Argument[1];Argument[-1].MapValue;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringUtil.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringUtil.qll deleted file mode 100644 index 7c78c6b7afc..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringUtil.qll +++ /dev/null @@ -1,153 +0,0 @@ -/** - * Provides models for the `org.springframework.util` package. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class FlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.util;AntPathMatcher;false;combine;;;Argument[0..1];ReturnValue;taint;manual", - "org.springframework.util;AntPathMatcher;false;doMatch;;;Argument[1];Argument[3].MapValue;taint;manual", - "org.springframework.util;AntPathMatcher;false;extractPathWithinPattern;;;Argument[1];ReturnValue;taint;manual", - "org.springframework.util;AntPathMatcher;false;extractUriTemplateVariables;;;Argument[1];ReturnValue.MapValue;taint;manual", - "org.springframework.util;AntPathMatcher;false;tokenizePath;;;Argument[0];ReturnValue.ArrayElement;taint;manual", - "org.springframework.util;AntPathMatcher;false;tokenizePattern;;;Argument[0];ReturnValue.ArrayElement;taint;manual", - "org.springframework.util;AutoPopulatingList;false;AutoPopulatingList;(java.util.List,org.springframework.util.AutoPopulatingList.ElementFactory);;Argument[0].Element;Argument[-1].Element;value;manual", - "org.springframework.util;AutoPopulatingList;false;AutoPopulatingList;(java.util.List,java.lang.Class);;Argument[0].Element;Argument[-1].Element;value;manual", - "org.springframework.util;Base64Utils;false;decode;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;Base64Utils;false;decodeFromString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;Base64Utils;false;decodeFromUrlSafeString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;Base64Utils;false;decodeUrlSafe;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;Base64Utils;false;encode;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;Base64Utils;false;encodeToString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;Base64Utils;false;encodeToUrlSafeString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;Base64Utils;false;encodeUrlSafe;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;CollectionUtils;false;arrayToList;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "org.springframework.util;CollectionUtils;false;findFirstMatch;;;Argument[0].Element;ReturnValue;value;manual", - "org.springframework.util;CollectionUtils;false;findValueOfType;;;Argument[0].Element;ReturnValue;value;manual", - "org.springframework.util;CollectionUtils;false;firstElement;;;Argument[0].Element;ReturnValue;value;manual", - "org.springframework.util;CollectionUtils;false;lastElement;;;Argument[0].Element;ReturnValue;value;manual", - "org.springframework.util;CollectionUtils;false;mergeArrayIntoCollection;;;Argument[0].ArrayElement;Argument[1].Element;value;manual", - "org.springframework.util;CollectionUtils;false;mergePropertiesIntoMap;;;Argument[0].MapKey;Argument[1].MapKey;value;manual", - "org.springframework.util;CollectionUtils;false;mergePropertiesIntoMap;;;Argument[0].MapValue;Argument[1].MapValue;value;manual", - "org.springframework.util;CollectionUtils;false;toArray;;;Argument[0].Element;ReturnValue.ArrayElement;value;manual", - "org.springframework.util;CollectionUtils;false;toIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - "org.springframework.util;CollectionUtils;false;toMultiValueMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.util;CollectionUtils;false;toMultiValueMap;;;Argument[0].MapValue.Element;ReturnValue.MapValue.Element;value;manual", - "org.springframework.util;CollectionUtils;false;unmodifiableMultiValueMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.util;CollectionUtils;false;unmodifiableMultiValueMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "org.springframework.util;CompositeIterator;false;add;;;Argument[0].Element;Argument[-1].Element;value;manual", - "org.springframework.util;ConcurrentReferenceHashMap;false;getReference;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.util;ConcurrentReferenceHashMap;false;getReference;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "org.springframework.util;ConcurrentReferenceHashMap;false;getSegment;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.util;ConcurrentReferenceHashMap;false;getSegment;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "org.springframework.util;FastByteArrayOutputStream;false;getInputStream;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.util;FastByteArrayOutputStream;false;toByteArray;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.util;FastByteArrayOutputStream;false;write;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.util;FastByteArrayOutputStream;false;writeTo;;;Argument[-1];Argument[0];taint;manual", - "org.springframework.util;FileCopyUtils;false;copy;;;Argument[0];Argument[1];taint;manual", - "org.springframework.util;FileCopyUtils;false;copyToByteArray;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;FileCopyUtils;false;copyToString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;FileSystemUtils;false;copyRecursively;(java.io.File,java.io.File);;Argument[0];Argument[1];taint;manual", - "org.springframework.util;LinkedMultiValueMap;false;LinkedMultiValueMap;(java.util.Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.util;LinkedMultiValueMap;false;LinkedMultiValueMap;(java.util.Map);;Argument[0].MapValue.Element;Argument[-1].MapValue.Element;value;manual", - "org.springframework.util;LinkedMultiValueMap;false;deepCopy;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.util;LinkedMultiValueMap;false;deepCopy;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "org.springframework.util;MultiValueMap;true;add;;;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.util;MultiValueMap;true;add;;;Argument[1];Argument[-1].MapValue.Element;value;manual", - "org.springframework.util;MultiValueMap;true;addAll;(java.lang.Object,java.util.List);;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.util;MultiValueMap;true;addAll;(java.lang.Object,java.util.List);;Argument[1].Element;Argument[-1].MapValue.Element;value;manual", - "org.springframework.util;MultiValueMap;true;addAll;(org.springframework.util.MultiValueMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.util;MultiValueMap;true;addAll;(org.springframework.util.MultiValueMap);;Argument[0].MapValue.Element;Argument[-1].MapValue.Element;value;manual", - "org.springframework.util;MultiValueMap;true;addIfAbsent;;;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.util;MultiValueMap;true;addIfAbsent;;;Argument[1];Argument[-1].MapValue.Element;value;manual", - "org.springframework.util;MultiValueMap;true;getFirst;;;Argument[-1].MapValue.Element;ReturnValue;value;manual", - "org.springframework.util;MultiValueMap;true;set;;;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.util;MultiValueMap;true;set;;;Argument[1];Argument[-1].MapValue.Element;value;manual", - "org.springframework.util;MultiValueMap;true;setAll;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.util;MultiValueMap;true;setAll;;;Argument[0].MapValue;Argument[-1].MapValue.Element;value;manual", - "org.springframework.util;MultiValueMap;true;toSingleValueMap;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.util;MultiValueMap;true;toSingleValueMap;;;Argument[-1].MapValue.Element;ReturnValue.MapValue;value;manual", - "org.springframework.util;MultiValueMapAdapter;false;MultiValueMapAdapter;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.util;MultiValueMapAdapter;false;MultiValueMapAdapter;;;Argument[0].MapValue.Element;Argument[-1].MapValue.Element;value;manual", - "org.springframework.util;ObjectUtils;false;addObjectToArray;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.springframework.util;ObjectUtils;false;addObjectToArray;;;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.springframework.util;ObjectUtils;false;toObjectArray;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.springframework.util;ObjectUtils;false;unwrapOptional;;;Argument[0].Element;ReturnValue;value;manual", - "org.springframework.util;PropertiesPersister;true;load;;;Argument[1];Argument[0];taint;manual", - "org.springframework.util;PropertiesPersister;true;loadFromXml;;;Argument[1];Argument[0];taint;manual", - "org.springframework.util;PropertiesPersister;true;store;;;Argument[0];Argument[1];taint;manual", - "org.springframework.util;PropertiesPersister;true;store;;;Argument[2];Argument[1];taint;manual", - "org.springframework.util;PropertiesPersister;true;storeToXml;;;Argument[0];Argument[1];taint;manual", - "org.springframework.util;PropertiesPersister;true;storeToXml;;;Argument[2];Argument[1];taint;manual", - "org.springframework.util;PropertyPlaceholderHelper;false;PropertyPlaceholderHelper;;;Argument[0..1];Argument[-1];taint;manual", - "org.springframework.util;PropertyPlaceholderHelper;false;parseStringValue;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;PropertyPlaceholderHelper;false;replacePlaceholders;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;PropertyPlaceholderHelper;false;replacePlaceholders;(java.lang.String,java.util.Properties);;Argument[1].MapValue;ReturnValue;taint;manual", - "org.springframework.util;ResourceUtils;false;extractArchiveURL;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;ResourceUtils;false;extractJarFileURL;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;ResourceUtils;false;getFile;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;ResourceUtils;false;getURL;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;ResourceUtils;false;toURI;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;RouteMatcher;true;combine;;;Argument[0..1];ReturnValue;taint;manual", - "org.springframework.util;RouteMatcher;true;matchAndExtract;;;Argument[0];ReturnValue.MapKey;taint;manual", - "org.springframework.util;RouteMatcher;true;matchAndExtract;;;Argument[1];ReturnValue.MapValue;taint;manual", - "org.springframework.util;RouteMatcher;true;parseRoute;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;SerializationUtils;false;deserialize;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;SerializationUtils;false;serialize;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StreamUtils;false;copy;(byte[],java.io.OutputStream);;Argument[0];Argument[1];taint;manual", - "org.springframework.util;StreamUtils;false;copy;(java.io.InputStream,java.io.OutputStream);;Argument[0];Argument[1];taint;manual", - "org.springframework.util;StreamUtils;false;copy;(java.lang.String,java.nio.charset.Charset,java.io.OutputStream);;Argument[0];Argument[2];taint;manual", - "org.springframework.util;StreamUtils;false;copyRange;;;Argument[0];Argument[1];taint;manual", - "org.springframework.util;StreamUtils;false;copyToByteArray;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StreamUtils;false;copyToString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;addStringToArray;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.springframework.util;StringUtils;false;addStringToArray;;;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.springframework.util;StringUtils;false;applyRelativePath;;;Argument[0..1];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;arrayToCommaDelimitedString;;;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;arrayToDelimitedString;;;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;arrayToDelimitedString;;;Argument[1];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;capitalize;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;cleanPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;collectionToCommaDelimitedString;;;Argument[0].Element;ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;collectionToDelimitedString;;;Argument[0].Element;ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;collectionToDelimitedString;;;Argument[1..3];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;commaDelimitedListToSet;;;Argument[0];ReturnValue.Element;taint;manual", - "org.springframework.util;StringUtils;false;commaDelimitedListToStringArray;;;Argument[0];ReturnValue.ArrayElement;taint;manual", - "org.springframework.util;StringUtils;false;concatenateStringArrays;;;Argument[0..1].ArrayElement;ReturnValue.ArrayElement;taint;manual", - "org.springframework.util;StringUtils;false;delete;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;deleteAny;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;delimitedListToStringArray;;;Argument[0];ReturnValue.ArrayElement;taint;manual", - "org.springframework.util;StringUtils;false;getFilename;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;getFilenameExtension;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;mergeStringArrays;;;Argument[0..1].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.springframework.util;StringUtils;false;quote;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;quoteIfString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;removeDuplicateStrings;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.springframework.util;StringUtils;false;replace;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;replace;;;Argument[2];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;sortStringArray;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.springframework.util;StringUtils;false;split;;;Argument[0];ReturnValue.ArrayElement;taint;manual", - "org.springframework.util;StringUtils;false;splitArrayElementsIntoProperties;;;Argument[0].ArrayElement;ReturnValue.MapKey;taint;manual", - "org.springframework.util;StringUtils;false;splitArrayElementsIntoProperties;;;Argument[0].ArrayElement;ReturnValue.MapValue;taint;manual", - "org.springframework.util;StringUtils;false;stripFilenameExtension;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;tokenizeToStringArray;;;Argument[0];ReturnValue.ArrayElement;taint;manual", - "org.springframework.util;StringUtils;false;toStringArray;;;Argument[0].Element;ReturnValue.ArrayElement;value;manual", - "org.springframework.util;StringUtils;false;trimAllWhitespace;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;trimArrayElements;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;taint;manual", - "org.springframework.util;StringUtils;false;trimLeadingCharacter;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;trimLeadingWhitespace;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;trimTrailingCharacter;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;trimTrailingWhitespace;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;trimWhitespace;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;uncapitalize;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;unqualify;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;uriDecode;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringValueResolver;false;resolveStringValue;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;SystemPropertyUtils;false;resolvePlaceholders;;;Argument[0];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringValidation.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringValidation.qll deleted file mode 100644 index 2dcf184de84..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringValidation.qll +++ /dev/null @@ -1,25 +0,0 @@ -/** Definitions of flow steps through utility methods of `org.springframework.validation.Errors`. */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class SpringValidationErrorModel extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.validation;Errors;true;addAllErrors;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.validation;Errors;true;getAllErrors;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.validation;Errors;true;getFieldError;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.validation;Errors;true;getFieldErrors;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.validation;Errors;true;getGlobalError;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.validation;Errors;true;getGlobalErrors;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.validation;Errors;true;reject;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.validation;Errors;true;reject;;;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.springframework.validation;Errors;true;reject;;;Argument[2];Argument[-1];taint;manual", - "org.springframework.validation;Errors;true;rejectValue;;;Argument[1];Argument[-1];taint;manual", - "org.springframework.validation;Errors;true;rejectValue;;;Argument[3];Argument[-1];taint;manual", - "org.springframework.validation;Errors;true;rejectValue;(java.lang.String,java.lang.String,java.lang.Object[],java.lang.String);;Argument[2].ArrayElement;Argument[-1];taint;manual", - "org.springframework.validation;Errors;true;rejectValue;(java.lang.String,java.lang.String,java.lang.String);;Argument[2];Argument[-1];taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll index 9744c323e36..955cb9e4131 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll @@ -28,26 +28,3 @@ class SpringWebClient extends Interface { this.hasQualifiedName("org.springframework.web.reactive.function.client", "WebClient") } } - -private class UrlOpenSink extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.web.client;RestTemplate;false;delete;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;doExecute;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;exchange;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;execute;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;getForEntity;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;getForObject;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;headForHeaders;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;optionsForAllow;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;patchForObject;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;postForEntity;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;postForLocation;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;postForObject;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;put;;;Argument[0];open-url;manual", - "org.springframework.web.reactive.function.client;WebClient;false;create;;;Argument[0];open-url;manual", - "org.springframework.web.reactive.function.client;WebClient$Builder;false;baseUrl;;;Argument[0];open-url;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebMultipart.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebMultipart.qll deleted file mode 100644 index 43acaceda76..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebMultipart.qll +++ /dev/null @@ -1,25 +0,0 @@ -/** Provides models of taint flow in `org.springframework.web.multipart` */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class FlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.web.multipart;MultipartFile;true;getBytes;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.multipart;MultipartFile;true;getInputStream;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.multipart;MultipartFile;true;getName;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.multipart;MultipartFile;true;getOriginalFilename;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.multipart;MultipartFile;true;getResource;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.multipart;MultipartHttpServletRequest;true;getMultipartHeaders;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.multipart;MultipartHttpServletRequest;true;getRequestHeaders;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.multipart;MultipartRequest;true;getFile;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.multipart;MultipartRequest;true;getFileMap;;;Argument[-1];ReturnValue.MapValue;taint;manual", - "org.springframework.web.multipart;MultipartRequest;true;getFileNames;;;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.web.multipart;MultipartRequest;true;getFiles;;;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.web.multipart;MultipartRequest;true;getMultiFileMap;;;Argument[-1];ReturnValue.MapValue;taint;manual", - "org.springframework.web.multipart;MultipartResolver;true;resolveMultipart;;;Argument[0];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebUtil.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebUtil.qll deleted file mode 100644 index 4f855eedbae..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebUtil.qll +++ /dev/null @@ -1,176 +0,0 @@ -/** Provides models of taint flow in `org.springframework.web.util` */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class FlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.web.util;UriBuilder;true;build;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriBuilder;true;build;(Map);;Argument[0].MapValue;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;build;(Map);;Argument[0].MapValue;ReturnValue;taint;manual", - "org.springframework.web.util;UriBuilder;true;build;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.springframework.web.util;UriBuilder;true;fragment;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;fragment;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;host;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;host;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;path;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;path;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;pathSegment;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;pathSegment;;;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;port;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;port;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;query;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;query;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;queryParam;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;queryParam;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;queryParam;(String,Collection);;Argument[1].Element;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;queryParam;(String,Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;queryParamIfPresent;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;queryParamIfPresent;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;queryParamIfPresent;;;Argument[1].Element;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;queryParams;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;queryParams;;;Argument[0].MapKey;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;queryParams;;;Argument[0].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;replacePath;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;replacePath;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;replaceQuery;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;replaceQuery;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;replaceQueryParam;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;replaceQueryParam;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;replaceQueryParam;(String,Collection);;Argument[1].Element;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;replaceQueryParam;(String,Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;replaceQueryParams;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;replaceQueryParams;;;Argument[0].MapKey;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;replaceQueryParams;;;Argument[0].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;scheme;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;scheme;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;userInfo;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;userInfo;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilderFactory;true;builder;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriBuilderFactory;true;uriString;;;Argument[-1..0];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents$UriTemplateVariables;true;getValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - "org.springframework.web.util;UriTemplateHandler;true;expand;;;Argument[-1..0];ReturnValue;taint;manual", - "org.springframework.web.util;UriTemplateHandler;true;expand;(String,Map);;Argument[1].MapValue;ReturnValue;taint;manual", - "org.springframework.web.util;UriTemplateHandler;true;expand;(String,Object[]);;Argument[1].ArrayElement;ReturnValue;taint;manual", - "org.springframework.web.util;AbstractUriTemplateHandler;true;getBaseUrl;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;AbstractUriTemplateHandler;true;setBaseUrl;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;AbstractUriTemplateHandler;true;setDefaultUriVariables;;;Argument[0];Argument[-1];taint;manual", - // writing to a `Request` or `Response` currently doesn't propagate taint to the object itself. - "org.springframework.web.util;ContentCachingRequestWrapper;false;ContentCachingRequestWrapper;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;ContentCachingRequestWrapper;false;getContentAsByteArray;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;ContentCachingResponseWrapper;false;ContentCachingResponseWrapper;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;ContentCachingResponseWrapper;false;getContentAsByteArray;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;ContentCachingResponseWrapper;false;getContentInputStream;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;DefaultUriBuilderFactory;false;DefaultUriBuilderFactory;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;DefaultUriBuilderFactory;false;builder;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;DefaultUriBuilderFactory;false;getDefaultUriVariables;;;Argument[-1];ReturnValue.MapValue;taint;manual", - "org.springframework.web.util;DefaultUriBuilderFactory;false;setDefaultUriVariables;;;Argument[0].MapValue;Argument[-1];taint;manual", - "org.springframework.web.util;DefaultUriBuilderFactory;false;uriString;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;HtmlUtils;false;htmlEscape;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;HtmlUtils;false;htmlEscapeDecimal;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;HtmlUtils;false;htmlEscapeHex;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;HtmlUtils;false;htmlUnescape;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;ServletContextPropertyUtils;false;resolvePlaceholders;;;Argument[0..1];ReturnValue;taint;manual", - "org.springframework.web.util;ServletRequestPathUtils;false;getCachedPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;ServletRequestPathUtils;false;getCachedPathValue;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;ServletRequestPathUtils;false;getParsedRequestPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;ServletRequestPathUtils;false;parseAndCache;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;ServletRequestPathUtils;false;setParsedRequestPath;;;Argument[0];Argument[1];taint;manual", - "org.springframework.web.util;UriComponents;false;UriComponents;;;Argument[0..1];Argument[-1];taint;manual", - "org.springframework.web.util;UriComponents;false;copyToUriComponentsBuilder;;;Argument[-1];Argument[0];taint;manual", - "org.springframework.web.util;UriComponents;false;encode;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;expand;(Map);;Argument[0].MapValue;ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;expand;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;expand;(UriTemplateVariables);;Argument[0].MapValue;ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;getFragment;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;getHost;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;getPath;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;getPathSegments;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;getQuery;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;getQueryParams;;;Argument[-1];ReturnValue.MapKey;taint;manual", - "org.springframework.web.util;UriComponents;false;getQueryParams;;;Argument[-1];ReturnValue.MapValue.Element;taint;manual", - "org.springframework.web.util;UriComponents;false;getScheme;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;getSchemeSpecificPart;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;getUserInfo;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;toUri;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;toUriString;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;normalize;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;buildAndExpand;(Map);;Argument[0].MapValue;ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;buildAndExpand;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;cloneBuilder;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriComponentsBuilder;false;encode;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriComponentsBuilder;false;fromHttpRequest;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;fromHttpUrl;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;fromOriginHeader;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;fromPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;fromUri;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;fromUriString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;parseForwardedFor;;;Argument[0..1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;schemeSpecificPart;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriComponentsBuilder;false;schemeSpecificPart;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;toUriString;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;uri;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriComponentsBuilder;false;uri;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;uriComponents;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriComponentsBuilder;false;uriComponents;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;uriVariables;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriComponentsBuilder;false;uriVariables;;;Argument[0].MapValue;Argument[-1];taint;manual", - "org.springframework.web.util;UriTemplate;false;expand;(Map);;Argument[0].MapValue;ReturnValue;taint;manual", - "org.springframework.web.util;UriTemplate;false;expand;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.springframework.web.util;UriTemplate;false;getVariableNames;;;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.web.util;UriTemplate;false;match;;;Argument[0];ReturnValue.MapValue;taint;manual", - "org.springframework.web.util;UriTemplate;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;decode;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encode;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeAuthority;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeFragment;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeHost;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodePath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodePathSegment;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodePort;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeQuery;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeQueryParam;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeQueryParams;;;Argument[0].MapKey;ReturnValue.MapKey;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeQueryParams;;;Argument[0].MapValue;ReturnValue.MapValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeScheme;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeUriVariables;(Map);;Argument[0].MapValue;ReturnValue.MapValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeUriVariables;(Map);;Argument[0].MapKey;ReturnValue.MapKey;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeUriVariables;(Object[]);;Argument[0].ArrayElement;ReturnValue.ArrayElement;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeUserInfo;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;extractFileExtension;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;decodeMatrixVariables;;;Argument[1].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.web.util;UrlPathHelper;false;decodeMatrixVariables;;;Argument[1].MapValue;ReturnValue.MapValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;decodePathVariables;;;Argument[1].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.web.util;UrlPathHelper;false;decodePathVariables;;;Argument[1].MapValue;ReturnValue.MapValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;decodeRequestString;;;Argument[1];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getContextPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getOriginatingContextPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getOriginatingQueryString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getOriginatingRequestUri;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getPathWithinApplication;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getPathWithinServletMapping;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getRequestUri;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getResolvedLookupPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getServletPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;removeSemicolonContent;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;resolveAndCacheLookupPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;WebUtils;false;findParameterValue;(Map,String);;Argument[0].MapValue;ReturnValue;value;manual", - "org.springframework.web.util;WebUtils;false;findParameterValue;(ServletRequest,String);;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;WebUtils;false;getCookie;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;WebUtils;false;getNativeRequest;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;WebUtils;false;getNativeResponse;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;WebUtils;false;getParametersStartingWith;;;Argument[0];ReturnValue.MapKey;taint;manual", - "org.springframework.web.util;WebUtils;false;getParametersStartingWith;;;Argument[0];ReturnValue.MapValue;taint;manual", - "org.springframework.web.util;WebUtils;false;getRealPath;;;Argument[0..1];ReturnValue;taint;manual", - "org.springframework.web.util;WebUtils;false;getRequiredSessionAttribute;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;WebUtils;false;getSessionAttribute;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;WebUtils;false;parseMatrixVariables;;;Argument[0];ReturnValue.MapKey;taint;manual", - "org.springframework.web.util;WebUtils;false;parseMatrixVariables;;;Argument[0];ReturnValue.MapValue;taint;manual", - "org.springframework.web.util;WebUtils;false;setSessionAttribute;;;Argument[2];Argument[0];taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll b/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll index 8936de5a923..5a913ccdef8 100644 --- a/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll +++ b/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll @@ -6,7 +6,6 @@ import java import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.DataFlow2 -private import RegexFlowModels private import semmle.code.java.security.SecurityTests private class ExploitableStringLiteral extends StringLiteral { diff --git a/java/ql/lib/semmle/code/java/regex/RegexFlowModels.qll b/java/ql/lib/semmle/code/java/regex/RegexFlowModels.qll deleted file mode 100644 index 20ba2c14dc8..00000000000 --- a/java/ql/lib/semmle/code/java/regex/RegexFlowModels.qll +++ /dev/null @@ -1,38 +0,0 @@ -/** Definitions of data flow steps for determining flow of regular expressions. */ - -import java -import semmle.code.java.dataflow.ExternalFlow - -private class RegexSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"namespace;type;subtypes;name;signature;ext;input;kind" - "java.util.regex;Matcher;false;matches;();;Argument[-1];regex-use[f];manual", - "java.util.regex;Pattern;false;asMatchPredicate;();;Argument[-1];regex-use[f];manual", - "java.util.regex;Pattern;false;compile;(String);;Argument[0];regex-use[];manual", - "java.util.regex;Pattern;false;compile;(String,int);;Argument[0];regex-use[];manual", - "java.util.regex;Pattern;false;matcher;(CharSequence);;Argument[-1];regex-use[0];manual", - "java.util.regex;Pattern;false;matches;(String,CharSequence);;Argument[0];regex-use[f1];manual", - "java.util.regex;Pattern;false;split;(CharSequence);;Argument[-1];regex-use[0];manual", - "java.util.regex;Pattern;false;split;(CharSequence,int);;Argument[-1];regex-use[0];manual", - "java.util.regex;Pattern;false;splitAsStream;(CharSequence);;Argument[-1];regex-use[0];manual", - "java.util.function;Predicate;false;test;(Object);;Argument[-1];regex-use[0];manual", - "java.lang;String;false;matches;(String);;Argument[0];regex-use[f-1];manual", - "java.lang;String;false;split;(String);;Argument[0];regex-use[-1];manual", - "java.lang;String;false;split;(String,int);;Argument[0];regex-use[-1];manual", - "java.lang;String;false;replaceAll;(String,String);;Argument[0];regex-use[-1];manual", - "java.lang;String;false;replaceFirst;(String,String);;Argument[0];regex-use[-1];manual", - "com.google.common.base;Splitter;false;onPattern;(String);;Argument[0];regex-use[];manual", - "com.google.common.base;Splitter;false;split;(CharSequence);;Argument[-1];regex-use[0];manual", - "com.google.common.base;Splitter;false;splitToList;(CharSequence);;Argument[-1];regex-use[0];manual", - "com.google.common.base;Splitter$MapSplitter;false;split;(CharSequence);;Argument[-1];regex-use[0];manual", - "org.apache.commons.lang3;RegExUtils;false;removeAll;(String,String);;Argument[1];regex-use;manual", - "org.apache.commons.lang3;RegExUtils;false;removeFirst;(String,String);;Argument[1];regex-use;manual", - "org.apache.commons.lang3;RegExUtils;false;removePattern;(String,String);;Argument[1];regex-use;manual", - "org.apache.commons.lang3;RegExUtils;false;replaceAll;(String,String,String);;Argument[1];regex-use;manual", - "org.apache.commons.lang3;RegExUtils;false;replaceFirst;(String,String,String);;Argument[1];regex-use;manual", - "org.apache.commons.lang3;RegExUtils;false;replacePattern;(String,String,String);;Argument[1];regex-use;manual", - ] - } -} diff --git a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll index 5252bbfa627..993c2941733 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll @@ -28,37 +28,6 @@ class IntentRedirectionAdditionalTaintStep extends Unit { abstract predicate step(DataFlow::Node node1, DataFlow::Node node2); } -private class DefaultIntentRedirectionSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "android.app;Activity;true;bindService;;;Argument[0];intent-start;manual", - "android.app;Activity;true;bindServiceAsUser;;;Argument[0];intent-start;manual", - "android.app;Activity;true;startActivityAsCaller;;;Argument[0];intent-start;manual", - "android.app;Activity;true;startActivityForResult;(Intent,int);;Argument[0];intent-start;manual", - "android.app;Activity;true;startActivityForResult;(Intent,int,Bundle);;Argument[0];intent-start;manual", - "android.app;Activity;true;startActivityForResult;(String,Intent,int,Bundle);;Argument[1];intent-start;manual", - "android.app;Activity;true;startActivityForResultAsUser;;;Argument[0];intent-start;manual", - "android.content;Context;true;startActivities;;;Argument[0];intent-start;manual", - "android.content;Context;true;startActivity;;;Argument[0];intent-start;manual", - "android.content;Context;true;startActivityAsUser;;;Argument[0];intent-start;manual", - "android.content;Context;true;startActivityFromChild;;;Argument[1];intent-start;manual", - "android.content;Context;true;startActivityFromFragment;;;Argument[1];intent-start;manual", - "android.content;Context;true;startActivityIfNeeded;;;Argument[0];intent-start;manual", - "android.content;Context;true;startForegroundService;;;Argument[0];intent-start;manual", - "android.content;Context;true;startService;;;Argument[0];intent-start;manual", - "android.content;Context;true;startServiceAsUser;;;Argument[0];intent-start;manual", - "android.content;Context;true;sendBroadcast;;;Argument[0];intent-start;manual", - "android.content;Context;true;sendBroadcastAsUser;;;Argument[0];intent-start;manual", - "android.content;Context;true;sendBroadcastWithMultiplePermissions;;;Argument[0];intent-start;manual", - "android.content;Context;true;sendStickyBroadcast;;;Argument[0];intent-start;manual", - "android.content;Context;true;sendStickyBroadcastAsUser;;;Argument[0];intent-start;manual", - "android.content;Context;true;sendStickyOrderedBroadcast;;;Argument[0];intent-start;manual", - "android.content;Context;true;sendStickyOrderedBroadcastAsUser;;;Argument[0];intent-start;manual" - ] - } -} - /** Default sink for Intent redirection vulnerabilities. */ private class DefaultIntentRedirectionSink extends IntentRedirectionSink { DefaultIntentRedirectionSink() { sinkNode(this, "intent-start") } diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll index 5b836e4c01f..89cc7ac021b 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll @@ -7,7 +7,6 @@ import java import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.security.CleartextStorageQuery -import semmle.code.java.security.Files import semmle.code.xml.AndroidManifest private class AndroidFilesystemCleartextStorageSink extends CleartextStorageSink { diff --git a/java/ql/lib/semmle/code/java/security/Files.qll b/java/ql/lib/semmle/code/java/security/Files.qll deleted file mode 100644 index 52ea86bc5b7..00000000000 --- a/java/ql/lib/semmle/code/java/security/Files.qll +++ /dev/null @@ -1,100 +0,0 @@ -/** Provides classes and predicates to work with File objects. */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class CreateFileSinkModels extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "java.io;FileOutputStream;false;FileOutputStream;;;Argument[0];create-file;manual", - "java.io;RandomAccessFile;false;RandomAccessFile;;;Argument[0];create-file;manual", - "java.io;FileWriter;false;FileWriter;;;Argument[0];create-file;manual", - "java.io;PrintStream;false;PrintStream;(File);;Argument[0];create-file;manual", - "java.io;PrintStream;false;PrintStream;(File,String);;Argument[0];create-file;manual", - "java.io;PrintStream;false;PrintStream;(File,Charset);;Argument[0];create-file;manual", - "java.io;PrintStream;false;PrintStream;(String);;Argument[0];create-file;manual", - "java.io;PrintStream;false;PrintStream;(String,String);;Argument[0];create-file;manual", - "java.io;PrintStream;false;PrintStream;(String,Charset);;Argument[0];create-file;manual", - "java.io;PrintWriter;false;PrintWriter;(File);;Argument[0];create-file;manual", - "java.io;PrintWriter;false;PrintWriter;(File,String);;Argument[0];create-file;manual", - "java.io;PrintWriter;false;PrintWriter;(File,Charset);;Argument[0];create-file;manual", - "java.io;PrintWriter;false;PrintWriter;(String);;Argument[0];create-file;manual", - "java.io;PrintWriter;false;PrintWriter;(String,String);;Argument[0];create-file;manual", - "java.io;PrintWriter;false;PrintWriter;(String,Charset);;Argument[0];create-file;manual", - "java.nio.file;Files;false;copy;;;Argument[1];create-file;manual", - "java.nio.file;Files;false;createDirectories;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;createDirectory;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;createFile;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;createLink;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;createSymbolicLink;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;createTempDirectory;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;createTempFile;(Path,String,String,FileAttribute[]);;Argument[0];create-file;manual", - "java.nio.file;Files;false;move;;;Argument[1];create-file;manual", - "java.nio.file;Files;false;newBufferedWriter;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;newOutputStream;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;write;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;writeString;;;Argument[0];create-file;manual" - ] - } -} - -private class WriteFileSinkModels extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "java.io;FileOutputStream;false;write;;;Argument[0];write-file;manual", - "java.io;RandomAccessFile;false;write;;;Argument[0];write-file;manual", - "java.io;RandomAccessFile;false;writeBytes;;;Argument[0];write-file;manual", - "java.io;RandomAccessFile;false;writeChars;;;Argument[0];write-file;manual", - "java.io;RandomAccessFile;false;writeUTF;;;Argument[0];write-file;manual", - "java.io;Writer;true;append;;;Argument[0];write-file;manual", - "java.io;Writer;true;write;;;Argument[0];write-file;manual", - "java.io;PrintStream;true;append;;;Argument[0];write-file;manual", - "java.io;PrintStream;true;format;(String,Object[]);;Argument[0..1];write-file;manual", - "java.io;PrintStream;true;format;(Locale,String,Object[]);;Argument[1..2];write-file;manual", - "java.io;PrintStream;true;print;;;Argument[0];write-file;manual", - "java.io;PrintStream;true;printf;(String,Object[]);;Argument[0..1];write-file;manual", - "java.io;PrintStream;true;printf;(Locale,String,Object[]);;Argument[1..2];write-file;manual", - "java.io;PrintStream;true;println;;;Argument[0];write-file;manual", - "java.io;PrintStream;true;write;;;Argument[0];write-file;manual", - "java.io;PrintStream;true;writeBytes;;;Argument[0];write-file;manual", - "java.io;PrintWriter;false;format;(String,Object[]);;Argument[0..1];write-file;manual", - "java.io;PrintWriter;false;format;(Locale,String,Object[]);;Argument[1..2];write-file;manual", - "java.io;PrintWriter;false;print;;;Argument[0];write-file;manual", - "java.io;PrintWriter;false;printf;(String,Object[]);;Argument[0..1];write-file;manual", - "java.io;PrintWriter;false;printf;(Locale,String,Object[]);;Argument[1..2];write-file;manual", - "java.io;PrintWriter;false;println;;;Argument[0];write-file;manual", - "java.nio.file;Files;false;write;;;Argument[1];write-file;manual", - "java.nio.file;Files;false;writeString;;;Argument[1];write-file;manual" - ] - } -} - -private class FileSummaryModels extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "java.io;File;false;File;;;Argument[0];Argument[-1];taint;manual", - "java.io;File;false;File;;;Argument[1];Argument[-1];taint;manual", - "java.io;File;true;getAbsoluteFile;;;Argument[-1];ReturnValue;taint;manual", - "java.io;File;true;getAbsolutePath;;;Argument[-1];ReturnValue;taint;manual", - "java.io;File;true;getCanonicalFile;;;Argument[-1];ReturnValue;taint;manual", - "java.io;File;true;getCanonicalPath;;;Argument[-1];ReturnValue;taint;manual", - "java.io;File;true;toPath;;;Argument[-1];ReturnValue;taint;manual", - "java.io;File;true;toString;;;Argument[-1];ReturnValue;taint;manual", - "java.io;File;true;toURI;;;Argument[-1];ReturnValue;taint;manual", - "java.nio.file;Path;true;getParent;;;Argument[-1];ReturnValue;taint;manual", - "java.nio.file;Path;true;normalize;;;Argument[-1];ReturnValue;taint;manual", - "java.nio.file;Path;true;resolve;;;Argument[-1..0];ReturnValue;taint;manual", - "java.nio.file;Path;true;toAbsolutePath;;;Argument[-1];ReturnValue;taint;manual", - "java.nio.file;Path;false;toFile;;;Argument[-1];ReturnValue;taint;manual", - "java.nio.file;Path;true;toString;;;Argument[-1];ReturnValue;taint;manual", - "java.nio.file;Path;true;toUri;;;Argument[-1];ReturnValue;taint;manual", - "java.nio.file;Paths;true;get;;;Argument[0];ReturnValue;taint;manual", - "java.nio.file;Paths;true;get;;;Argument[1].ArrayElement;ReturnValue;taint;manual", - "java.nio.file;FileSystem;true;getPath;;;Argument[0];ReturnValue;taint;manual", - "java.nio.file;FileSystem;true;getRootDirectories;;;Argument[0];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/security/FragmentInjection.qll b/java/ql/lib/semmle/code/java/security/FragmentInjection.qll index 78cc2690bec..046993f6658 100644 --- a/java/ql/lib/semmle/code/java/security/FragmentInjection.qll +++ b/java/ql/lib/semmle/code/java/security/FragmentInjection.qll @@ -43,22 +43,6 @@ class FragmentInjectionAdditionalTaintStep extends Unit { abstract predicate step(DataFlow::Node n1, DataFlow::Node n2); } -private class FragmentInjectionSinkModels extends SinkModelCsv { - override predicate row(string row) { - row = - ["android.app", "android.support.v4.app", "androidx.fragment.app"] + - ";FragmentTransaction;true;" + - [ - "add;(Class,Bundle,String);;Argument[0]", "add;(Fragment,String);;Argument[0]", - "add;(int,Class,Bundle);;Argument[1]", "add;(int,Fragment);;Argument[1]", - "add;(int,Class,Bundle,String);;Argument[1]", "add;(int,Fragment,String);;Argument[1]", - "attach;(Fragment);;Argument[0]", "replace;(int,Class,Bundle);;Argument[1]", - "replace;(int,Fragment);;Argument[1]", "replace;(int,Class,Bundle,String);;Argument[1]", - "replace;(int,Fragment,String);;Argument[1]", - ] + ";fragment-injection;manual" - } -} - private class DefaultFragmentInjectionSink extends FragmentInjectionSink { DefaultFragmentInjectionSink() { sinkNode(this, "fragment-injection") } } diff --git a/java/ql/lib/semmle/code/java/security/GroovyInjection.qll b/java/ql/lib/semmle/code/java/security/GroovyInjection.qll index b735e28cd32..54ea8afce91 100644 --- a/java/ql/lib/semmle/code/java/security/GroovyInjection.qll +++ b/java/ql/lib/semmle/code/java/security/GroovyInjection.qll @@ -24,47 +24,6 @@ private class DefaultGroovyInjectionSink extends GroovyInjectionSink { DefaultGroovyInjectionSink() { sinkNode(this, "groovy") } } -private class DefaultGroovyInjectionSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - // Signatures are specified to exclude sinks of the type `File` - "groovy.lang;GroovyShell;false;evaluate;(GroovyCodeSource);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;evaluate;(Reader);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;evaluate;(Reader,String);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;evaluate;(String);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;evaluate;(String,String);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;evaluate;(String,String,String);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;evaluate;(URI);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;parse;(Reader);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;parse;(Reader,String);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;parse;(String);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;parse;(String,String);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;parse;(URI);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;run;(GroovyCodeSource,String[]);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;run;(GroovyCodeSource,List);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;run;(Reader,String,String[]);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;run;(Reader,String,List);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;run;(String,String,String[]);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;run;(String,String,List);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;run;(URI,String[]);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;run;(URI,List);;Argument[0];groovy;manual", - "groovy.util;Eval;false;me;(String);;Argument[0];groovy;manual", - "groovy.util;Eval;false;me;(String,Object,String);;Argument[2];groovy;manual", - "groovy.util;Eval;false;x;(Object,String);;Argument[1];groovy;manual", - "groovy.util;Eval;false;xy;(Object,Object,String);;Argument[2];groovy;manual", - "groovy.util;Eval;false;xyz;(Object,Object,Object,String);;Argument[3];groovy;manual", - "groovy.lang;GroovyClassLoader;false;parseClass;(GroovyCodeSource);;Argument[0];groovy;manual", - "groovy.lang;GroovyClassLoader;false;parseClass;(GroovyCodeSource,boolean);;Argument[0];groovy;manual", - "groovy.lang;GroovyClassLoader;false;parseClass;(InputStream,String);;Argument[0];groovy;manual", - "groovy.lang;GroovyClassLoader;false;parseClass;(Reader,String);;Argument[0];groovy;manual", - "groovy.lang;GroovyClassLoader;false;parseClass;(String);;Argument[0];groovy;manual", - "groovy.lang;GroovyClassLoader;false;parseClass;(String,String);;Argument[0];groovy;manual", - "org.codehaus.groovy.control;CompilationUnit;false;compile;;;Argument[-1];groovy;manual" - ] - } -} - /** A set of additional taint steps to consider when taint tracking Groovy related data flows. */ private class DefaultGroovyInjectionAdditionalTaintStep extends GroovyInjectionAdditionalTaintStep { override predicate step(DataFlow::Node node1, DataFlow::Node node2) { diff --git a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll index bbfafc2d9c4..308b8037554 100644 --- a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll +++ b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll @@ -94,39 +94,6 @@ private class MutablePendingIntentFlowStep extends ImplicitPendingIntentAddition } } -private class PendingIntentSentSinkModels extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "androidx.slice;SliceProvider;true;onBindSlice;;;ReturnValue;pending-intent-sent;manual", - "androidx.slice;SliceProvider;true;onCreatePermissionRequest;;;ReturnValue;pending-intent-sent;manual", - "android.app;NotificationManager;true;notify;(int,Notification);;Argument[1];pending-intent-sent;manual", - "android.app;NotificationManager;true;notify;(String,int,Notification);;Argument[2];pending-intent-sent;manual", - "android.app;NotificationManager;true;notifyAsPackage;(String,String,int,Notification);;Argument[3];pending-intent-sent;manual", - "android.app;NotificationManager;true;notifyAsUser;(String,int,Notification,UserHandle);;Argument[2];pending-intent-sent;manual", - "androidx.core.app;NotificationManagerCompat;true;notify;(int,Notification);;Argument[1];pending-intent-sent;manual", - "androidx.core.app;NotificationManagerCompat;true;notify;(String,int,Notification);;Argument[2];pending-intent-sent;manual", - "android.app;PendingIntent;false;send;(Context,int,Intent,OnFinished,Handler,String,Bundle);;Argument[2];pending-intent-sent;manual", - "android.app;PendingIntent;false;send;(Context,int,Intent,OnFinished,Handler,String);;Argument[2];pending-intent-sent;manual", - "android.app;PendingIntent;false;send;(Context,int,Intent,OnFinished,Handler);;Argument[2];pending-intent-sent;manual", - "android.app;PendingIntent;false;send;(Context,int,Intent);;Argument[2];pending-intent-sent;manual", - "android.app;Activity;true;setResult;(int,Intent);;Argument[1];pending-intent-sent;manual", - "android.app;AlarmManager;true;set;(int,long,PendingIntent);;Argument[2];pending-intent-sent;manual", - "android.app;AlarmManager;true;setAlarmClock;;;Argument[1];pending-intent-sent;manual", - "android.app;AlarmManager;true;setAndAllowWhileIdle;;;Argument[2];pending-intent-sent;manual", - "android.app;AlarmManager;true;setExact;(int,long,PendingIntent);;Argument[2];pending-intent-sent;manual", - "android.app;AlarmManager;true;setExactAndAllowWhileIdle;;;Argument[2];pending-intent-sent;manual", - "android.app;AlarmManager;true;setInexactRepeating;;;Argument[3];pending-intent-sent;manual", - "android.app;AlarmManager;true;setRepeating;;;Argument[3];pending-intent-sent;manual", - "android.app;AlarmManager;true;setWindow;(int,long,long,PendingIntent);;Argument[3];pending-intent-sent;manual", - "androidx.core.app;AlarmManagerCompat;true;setAlarmClock;;;Argument[2..3];pending-intent-sent;manual", - "androidx.core.app;AlarmManagerCompat;true;setAndAllowWhileIdle;;;Argument[3];pending-intent-sent;manual", - "androidx.core.app;AlarmManagerCompat;true;setExact;;;Argument[3];pending-intent-sent;manual", - "androidx.core.app;AlarmManagerCompat;true;setExactAndAllowWhileIdle;;;Argument[3];pending-intent-sent;manual", - ] - } -} - /** * Holds if taint can flow from `source` to `sink` in one local step, * including bitwise operations. diff --git a/java/ql/lib/semmle/code/java/security/InformationLeak.qll b/java/ql/lib/semmle/code/java/security/InformationLeak.qll index c3a4d0d286c..8fe7d215165 100644 --- a/java/ql/lib/semmle/code/java/security/InformationLeak.qll +++ b/java/ql/lib/semmle/code/java/security/InformationLeak.qll @@ -5,14 +5,6 @@ import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.security.XSS -/** CSV sink models representing methods not susceptible to XSS but outputing to an HTTP response body. */ -private class DefaultInformationLeakSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - "javax.servlet.http;HttpServletResponse;false;sendError;(int,String);;Argument[1];information-leak;manual" - } -} - /** A sink that represent a method that outputs data to an HTTP response. */ abstract class InformationLeakSink extends DataFlow::Node { } diff --git a/java/ql/lib/semmle/code/java/security/JexlInjectionSinkModels.qll b/java/ql/lib/semmle/code/java/security/JexlInjectionSinkModels.qll deleted file mode 100644 index ed722c2f18a..00000000000 --- a/java/ql/lib/semmle/code/java/security/JexlInjectionSinkModels.qll +++ /dev/null @@ -1,43 +0,0 @@ -/** Provides sink models relating to Expression Language (JEXL) injection vulnerabilities. */ - -private import semmle.code.java.dataflow.ExternalFlow - -private class DefaultJexlInjectionSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - // JEXL2 - "org.apache.commons.jexl2;JexlEngine;false;getProperty;(JexlContext,Object,String);;Argument[2];jexl;manual", - "org.apache.commons.jexl2;JexlEngine;false;getProperty;(Object,String);;Argument[1];jexl;manual", - "org.apache.commons.jexl2;JexlEngine;false;setProperty;(JexlContext,Object,String,Object);;Argument[2];jexl;manual", - "org.apache.commons.jexl2;JexlEngine;false;setProperty;(Object,String,Object);;Argument[1];jexl;manual", - "org.apache.commons.jexl2;Expression;false;evaluate;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;Expression;false;callable;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;JexlExpression;false;evaluate;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;JexlExpression;false;callable;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;Script;false;execute;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;Script;false;callable;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;JexlScript;false;execute;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;JexlScript;false;callable;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;UnifiedJEXL$Expression;false;evaluate;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;UnifiedJEXL$Expression;false;prepare;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;UnifiedJEXL$Template;false;evaluate;;;Argument[-1];jexl;manual", - // JEXL3 - "org.apache.commons.jexl3;JexlEngine;false;getProperty;(JexlContext,Object,String);;Argument[2];jexl;manual", - "org.apache.commons.jexl3;JexlEngine;false;getProperty;(Object,String);;Argument[1];jexl;manual", - "org.apache.commons.jexl3;JexlEngine;false;setProperty;(JexlContext,Object,String);;Argument[2];jexl;manual", - "org.apache.commons.jexl3;JexlEngine;false;setProperty;(Object,String,Object);;Argument[1];jexl;manual", - "org.apache.commons.jexl3;Expression;false;evaluate;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;Expression;false;callable;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;JexlExpression;false;evaluate;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;JexlExpression;false;callable;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;Script;false;execute;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;Script;false;callable;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;JexlScript;false;execute;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;JexlScript;false;callable;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;JxltEngine$Expression;false;evaluate;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;JxltEngine$Expression;false;prepare;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;JxltEngine$Template;false;evaluate;;;Argument[-1];jexl;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/security/JndiInjection.qll b/java/ql/lib/semmle/code/java/security/JndiInjection.qll index 9dca731af80..cacf725cc99 100644 --- a/java/ql/lib/semmle/code/java/security/JndiInjection.qll +++ b/java/ql/lib/semmle/code/java/security/JndiInjection.qll @@ -72,62 +72,6 @@ private class ProviderUrlJndiInjectionSink extends JndiInjectionSink, DataFlow:: } } -/** CSV sink models representing methods susceptible to JNDI injection attacks. */ -private class DefaultJndiInjectionSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "javax.naming;Context;true;lookup;;;Argument[0];jndi-injection;manual", - "javax.naming;Context;true;lookupLink;;;Argument[0];jndi-injection;manual", - "javax.naming;Context;true;rename;;;Argument[0];jndi-injection;manual", - "javax.naming;Context;true;list;;;Argument[0];jndi-injection;manual", - "javax.naming;Context;true;listBindings;;;Argument[0];jndi-injection;manual", - "javax.naming;InitialContext;true;doLookup;;;Argument[0];jndi-injection;manual", - "javax.management.remote;JMXConnector;true;connect;;;Argument[-1];jndi-injection;manual", - "javax.management.remote;JMXConnectorFactory;false;connect;;;Argument[0];jndi-injection;manual", - // Spring - "org.springframework.jndi;JndiTemplate;false;lookup;;;Argument[0];jndi-injection;manual", - // spring-ldap 1.2.x and newer - "org.springframework.ldap.core;LdapOperations;true;lookup;(Name);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;lookup;(Name,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;lookup;(Name,String[],ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;lookup;(String);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;lookup;(String,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;lookup;(String,String[],ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;lookupContext;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;findByDn;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;rename;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;list;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;listBindings;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;search;(Name,String,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;search;(Name,String,int,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;search;(Name,String,int,String[],ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;search;(String,String,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;search;(String,String,int,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;search;(String,String,int,String[],ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;searchForObject;(Name,String,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;searchForObject;(String,String,ContextMapper);;Argument[0];jndi-injection;manual", - // spring-ldap 1.1.x - "org.springframework.ldap;LdapOperations;true;lookup;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;lookupContext;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;findByDn;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;rename;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;list;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;listBindings;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;search;(Name,String,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;search;(Name,String,int,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;search;(Name,String,int,String[],ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;search;(String,String,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;search;(String,String,int,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;search;(String,String,int,String[],ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;searchForObject;(Name,String,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;searchForObject;(String,String,ContextMapper);;Argument[0];jndi-injection;manual", - // Shiro - "org.apache.shiro.jndi;JndiTemplate;false;lookup;;;Argument[0];jndi-injection;manual" - ] - } -} - /** A set of additional taint steps to consider when taint tracking JNDI injection related data flows. */ private class DefaultJndiInjectionAdditionalTaintStep extends JndiInjectionAdditionalTaintStep { override predicate step(DataFlow::Node node1, DataFlow::Node node2) { diff --git a/java/ql/lib/semmle/code/java/security/LdapInjection.qll b/java/ql/lib/semmle/code/java/security/LdapInjection.qll index 35c59279f4e..d78bd2f7ae1 100644 --- a/java/ql/lib/semmle/code/java/security/LdapInjection.qll +++ b/java/ql/lib/semmle/code/java/security/LdapInjection.qll @@ -32,53 +32,6 @@ private class DefaultLdapInjectionSink extends LdapInjectionSink { DefaultLdapInjectionSink() { sinkNode(this, "ldap") } } -private class DefaultLdapInjectionSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - // jndi - "javax.naming.directory;DirContext;true;search;;;Argument[0..1];ldap;manual", - // apache - "org.apache.directory.ldap.client.api;LdapConnection;true;search;;;Argument[0..2];ldap;manual", - // UnboundID: search - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(ReadOnlySearchRequest);;Argument[0];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(SearchRequest);;Argument[0];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(SearchResultListener,String,SearchScope,DereferencePolicy,int,int,boolean,Filter,String[]);;Argument[0..7];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(SearchResultListener,String,SearchScope,DereferencePolicy,int,int,boolean,String,String[]);;Argument[0..7];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(SearchResultListener,String,SearchScope,Filter,String[]);;Argument[0..3];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(SearchResultListener,String,SearchScope,String,String[]);;Argument[0..3];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(String,SearchScope,DereferencePolicy,int,int,boolean,Filter,String[]);;Argument[0..6];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(String,SearchScope,DereferencePolicy,int,int,boolean,String,String[]);;Argument[0..6];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(String,SearchScope,Filter,String[]);;Argument[0..2];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(String,SearchScope,String,String[]);;Argument[0..2];ldap;manual", - // UnboundID: searchForEntry - "com.unboundid.ldap.sdk;LDAPConnection;false;searchForEntry;(ReadOnlySearchRequest);;Argument[0];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;searchForEntry;(SearchRequest);;Argument[0];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;searchForEntry;(String,SearchScope,DereferencePolicy,int,boolean,Filter,String[]);;Argument[0..5];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;searchForEntry;(String,SearchScope,DereferencePolicy,int,boolean,String,String[]);;Argument[0..5];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;searchForEntry;(String,SearchScope,Filter,String[]);;Argument[0..2];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;searchForEntry;(String,SearchScope,String,String[]);;Argument[0..2];ldap;manual", - // UnboundID: asyncSearch - "com.unboundid.ldap.sdk;LDAPConnection;false;asyncSearch;;;Argument[0];ldap;manual", - // Spring - "org.springframework.ldap.core;LdapTemplate;false;find;;;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;findOne;;;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;search;;;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;searchForContext;;;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;searchForObject;;;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(LdapQuery,String);;Argument[0];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(Name,String,String);;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(Name,String,String,AuthenticatedLdapEntryContextCallback);;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(Name,String,String,AuthenticatedLdapEntryContextCallback,AuthenticationErrorCallback);;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(Name,String,String,AuthenticationErrorCallback);;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(String,String,String);;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(String,String,String,AuthenticatedLdapEntryContextCallback);;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(String,String,String,AuthenticatedLdapEntryContextCallback,AuthenticationErrorCallback);;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(String,String,String,AuthenticationErrorCallback);;Argument[0..1];ldap;manual" - ] - } -} - /** A sanitizer that clears the taint on (boxed) primitive types. */ private class DefaultLdapSanitizer extends LdapInjectionSanitizer { DefaultLdapSanitizer() { diff --git a/java/ql/lib/semmle/code/java/security/MvelInjection.qll b/java/ql/lib/semmle/code/java/security/MvelInjection.qll index 167b21edae6..a0ada3d91a1 100644 --- a/java/ql/lib/semmle/code/java/security/MvelInjection.qll +++ b/java/ql/lib/semmle/code/java/security/MvelInjection.qll @@ -28,31 +28,6 @@ private class DefaultMvelEvaluationSink extends MvelEvaluationSink { DefaultMvelEvaluationSink() { sinkNode(this, "mvel") } } -private class DefaulMvelEvaluationSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "javax.script;CompiledScript;false;eval;;;Argument[-1];mvel;manual", - "org.mvel2;MVEL;false;eval;;;Argument[0];mvel;manual", - "org.mvel2;MVEL;false;executeExpression;;;Argument[0];mvel;manual", - "org.mvel2;MVEL;false;evalToBoolean;;;Argument[0];mvel;manual", - "org.mvel2;MVEL;false;evalToString;;;Argument[0];mvel;manual", - "org.mvel2;MVEL;false;executeAllExpression;;;Argument[0];mvel;manual", - "org.mvel2;MVEL;false;executeSetExpression;;;Argument[0];mvel;manual", - "org.mvel2;MVELRuntime;false;execute;;;Argument[1];mvel;manual", - "org.mvel2.templates;TemplateRuntime;false;eval;;;Argument[0];mvel;manual", - "org.mvel2.templates;TemplateRuntime;false;execute;;;Argument[0];mvel;manual", - "org.mvel2.jsr223;MvelScriptEngine;false;eval;;;Argument[0];mvel;manual", - "org.mvel2.jsr223;MvelScriptEngine;false;evaluate;;;Argument[0];mvel;manual", - "org.mvel2.jsr223;MvelCompiledScript;false;eval;;;Argument[-1];mvel;manual", - "org.mvel2.compiler;ExecutableStatement;false;getValue;;;Argument[-1];mvel;manual", - "org.mvel2.compiler;CompiledExpression;false;getDirectValue;;;Argument[-1];mvel;manual", - "org.mvel2.compiler;CompiledAccExpression;false;getValue;;;Argument[-1];mvel;manual", - "org.mvel2.compiler;Accessor;false;getValue;;;Argument[-1];mvel;manual" - ] - } -} - /** A default sanitizer that considers numeric and boolean typed data safe for building MVEL expressions */ private class DefaultMvelInjectionSanitizer extends MvelInjectionSanitizer { DefaultMvelInjectionSanitizer() { diff --git a/java/ql/lib/semmle/code/java/security/OgnlInjection.qll b/java/ql/lib/semmle/code/java/security/OgnlInjection.qll index 1ebede55b78..aa10de4d3c1 100644 --- a/java/ql/lib/semmle/code/java/security/OgnlInjection.qll +++ b/java/ql/lib/semmle/code/java/security/OgnlInjection.qll @@ -25,29 +25,6 @@ class OgnlInjectionAdditionalTaintStep extends Unit { abstract predicate step(DataFlow::Node node1, DataFlow::Node node2); } -private class DefaultOgnlInjectionSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.commons.ognl;Ognl;false;getValue;;;Argument[0];ognl-injection;manual", - "org.apache.commons.ognl;Ognl;false;setValue;;;Argument[0];ognl-injection;manual", - "org.apache.commons.ognl;Node;true;getValue;;;Argument[-1];ognl-injection;manual", - "org.apache.commons.ognl;Node;true;setValue;;;Argument[-1];ognl-injection;manual", - "org.apache.commons.ognl.enhance;ExpressionAccessor;true;get;;;Argument[-1];ognl-injection;manual", - "org.apache.commons.ognl.enhance;ExpressionAccessor;true;set;;;Argument[-1];ognl-injection;manual", - "ognl;Ognl;false;getValue;;;Argument[0];ognl-injection;manual", - "ognl;Ognl;false;setValue;;;Argument[0];ognl-injection;manual", - "ognl;Node;false;getValue;;;Argument[-1];ognl-injection;manual", - "ognl;Node;false;setValue;;;Argument[-1];ognl-injection;manual", - "ognl.enhance;ExpressionAccessor;true;get;;;Argument[-1];ognl-injection;manual", - "ognl.enhance;ExpressionAccessor;true;set;;;Argument[-1];ognl-injection;manual", - "com.opensymphony.xwork2.ognl;OgnlUtil;false;getValue;;;Argument[0];ognl-injection;manual", - "com.opensymphony.xwork2.ognl;OgnlUtil;false;setValue;;;Argument[0];ognl-injection;manual", - "com.opensymphony.xwork2.ognl;OgnlUtil;false;callMethod;;;Argument[0];ognl-injection;manual" - ] - } -} - private class DefaultOgnlInjectionSink extends OgnlInjectionSink { DefaultOgnlInjectionSink() { sinkNode(this, "ognl-injection") } } diff --git a/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll b/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll index d59e6c877c3..e99b8d363ff 100644 --- a/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll +++ b/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll @@ -14,18 +14,6 @@ private class DefaultHeaderSplittingSink extends HeaderSplittingSink { DefaultHeaderSplittingSink() { sinkNode(this, "header-splitting") } } -private class HeaderSplittingSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "javax.servlet.http;HttpServletResponse;false;addCookie;;;Argument[0];header-splitting;manual", - "javax.servlet.http;HttpServletResponse;false;addHeader;;;Argument[0..1];header-splitting;manual", - "javax.servlet.http;HttpServletResponse;false;setHeader;;;Argument[0..1];header-splitting;manual", - "javax.ws.rs.core;ResponseBuilder;false;header;;;Argument[1];header-splitting;manual" - ] - } -} - /** A source that introduces data considered safe to use by a header splitting source. */ abstract class SafeHeaderSplittingSource extends DataFlow::Node { SafeHeaderSplittingSource() { this instanceof RemoteFlowSource } diff --git a/java/ql/lib/semmle/code/java/security/TemplateInjection.qll b/java/ql/lib/semmle/code/java/security/TemplateInjection.qll index 079ef551bb3..ce2bd9d217d 100644 --- a/java/ql/lib/semmle/code/java/security/TemplateInjection.qll +++ b/java/ql/lib/semmle/code/java/security/TemplateInjection.qll @@ -76,33 +76,3 @@ private class DefaultTemplateInjectionSanitizer extends TemplateInjectionSanitiz this.getType() instanceof NumericType } } - -private class TemplateInjectionSinkModels extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "freemarker.template;Template;true;Template;(String,Reader);;Argument[1];ssti;manual", - "freemarker.template;Template;true;Template;(String,Reader,Configuration);;Argument[1];ssti;manual", - "freemarker.template;Template;true;Template;(String,Reader,Configuration,String);;Argument[1];ssti;manual", - "freemarker.template;Template;true;Template;(String,String,Reader,Configuration);;Argument[2];ssti;manual", - "freemarker.template;Template;true;Template;(String,String,Reader,Configuration,String);;Argument[2];ssti;manual", - "freemarker.template;Template;true;Template;(String,String,Reader,Configuration,ParserConfiguration,String);;Argument[2];ssti;manual", - "freemarker.template;Template;true;Template;(String,String,Configuration);;Argument[1];ssti;manual", - "freemarker.cache;StringTemplateLoader;true;putTemplate;;;Argument[1];ssti;manual", - "com.mitchellbosecke.pebble;PebbleEngine;true;getTemplate;;;Argument[0];ssti;manual", - "com.mitchellbosecke.pebble;PebbleEngine;true;getLiteralTemplate;;;Argument[0];ssti;manual", - "com.hubspot.jinjava;Jinjava;true;renderForResult;;;Argument[0];ssti;manual", - "com.hubspot.jinjava;Jinjava;true;render;;;Argument[0];ssti;manual", - "org.thymeleaf;ITemplateEngine;true;process;;;Argument[0];ssti;manual", - "org.thymeleaf;ITemplateEngine;true;processThrottled;;;Argument[0];ssti;manual", - "org.apache.velocity.app;Velocity;true;evaluate;;;Argument[3];ssti;manual", - "org.apache.velocity.app;Velocity;true;mergeTemplate;;;Argument[2];ssti;manual", - "org.apache.velocity.app;VelocityEngine;true;evaluate;;;Argument[3];ssti;manual", - "org.apache.velocity.app;VelocityEngine;true;mergeTemplate;;;Argument[2];ssti;manual", - "org.apache.velocity.runtime.resource.util;StringResourceRepository;true;putStringResource;;;Argument[1];ssti;manual", - "org.apache.velocity.runtime;RuntimeServices;true;evaluate;;;Argument[3];ssti;manual", - "org.apache.velocity.runtime;RuntimeServices;true;parse;;;Argument[0];ssti;manual", - "org.apache.velocity.runtime;RuntimeSingleton;true;parse;;;Argument[0];ssti;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/security/XPath.qll b/java/ql/lib/semmle/code/java/security/XPath.qll index 2122093a05c..c8b1077990d 100644 --- a/java/ql/lib/semmle/code/java/security/XPath.qll +++ b/java/ql/lib/semmle/code/java/security/XPath.qll @@ -10,38 +10,6 @@ private import semmle.code.java.dataflow.ExternalFlow */ abstract class XPathInjectionSink extends DataFlow::Node { } -/** CSV sink models representing methods susceptible to XPath Injection attacks. */ -private class DefaultXPathInjectionSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "javax.xml.xpath;XPath;true;evaluate;;;Argument[0];xpath;manual", - "javax.xml.xpath;XPath;true;evaluateExpression;;;Argument[0];xpath;manual", - "javax.xml.xpath;XPath;true;compile;;;Argument[0];xpath;manual", - "org.dom4j;Node;true;selectObject;;;Argument[0];xpath;manual", - "org.dom4j;Node;true;selectNodes;;;Argument[0..1];xpath;manual", - "org.dom4j;Node;true;selectSingleNode;;;Argument[0];xpath;manual", - "org.dom4j;Node;true;numberValueOf;;;Argument[0];xpath;manual", - "org.dom4j;Node;true;valueOf;;;Argument[0];xpath;manual", - "org.dom4j;Node;true;matches;;;Argument[0];xpath;manual", - "org.dom4j;Node;true;createXPath;;;Argument[0];xpath;manual", - "org.dom4j;DocumentFactory;true;createPattern;;;Argument[0];xpath;manual", - "org.dom4j;DocumentFactory;true;createXPath;;;Argument[0];xpath;manual", - "org.dom4j;DocumentFactory;true;createXPathFilter;;;Argument[0];xpath;manual", - "org.dom4j;DocumentHelper;false;createPattern;;;Argument[0];xpath;manual", - "org.dom4j;DocumentHelper;false;createXPath;;;Argument[0];xpath;manual", - "org.dom4j;DocumentHelper;false;createXPathFilter;;;Argument[0];xpath;manual", - "org.dom4j;DocumentHelper;false;selectNodes;;;Argument[0];xpath;manual", - "org.dom4j;DocumentHelper;false;sort;;;Argument[1];xpath;manual", - "org.dom4j.tree;AbstractNode;true;createXPathFilter;;;Argument[0];xpath;manual", - "org.dom4j.tree;AbstractNode;true;createPattern;;;Argument[0];xpath;manual", - "org.dom4j.util;ProxyDocumentFactory;true;createPattern;;;Argument[0];xpath;manual", - "org.dom4j.util;ProxyDocumentFactory;true;createXPath;;;Argument[0];xpath;manual", - "org.dom4j.util;ProxyDocumentFactory;true;createXPathFilter;;;Argument[0];xpath;manual" - ] - } -} - /** A default sink representing methods susceptible to XPath Injection attacks. */ private class DefaultXPathInjectionSink extends XPathInjectionSink { DefaultXPathInjectionSink() { diff --git a/java/ql/lib/semmle/code/java/security/XsltInjection.qll b/java/ql/lib/semmle/code/java/security/XsltInjection.qll index 570a7575af3..f6953a09539 100644 --- a/java/ql/lib/semmle/code/java/security/XsltInjection.qll +++ b/java/ql/lib/semmle/code/java/security/XsltInjection.qll @@ -15,20 +15,6 @@ private class DefaultXsltInjectionSink extends XsltInjectionSink { DefaultXsltInjectionSink() { sinkNode(this, "xslt") } } -private class DefaultXsltInjectionSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "javax.xml.transform;Transformer;false;transform;;;Argument[-1];xslt;manual", - "net.sf.saxon.s9api;XsltTransformer;false;transform;;;Argument[-1];xslt;manual", - "net.sf.saxon.s9api;Xslt30Transformer;false;transform;;;Argument[-1];xslt;manual", - "net.sf.saxon.s9api;Xslt30Transformer;false;applyTemplates;;;Argument[-1];xslt;manual", - "net.sf.saxon.s9api;Xslt30Transformer;false;callFunction;;;Argument[-1];xslt;manual", - "net.sf.saxon.s9api;Xslt30Transformer;false;callTemplate;;;Argument[-1];xslt;manual" - ] - } -} - /** * A unit class for adding additional taint steps. * diff --git a/java/ql/lib/semmle/code/java/security/regexp/RegexInjection.qll b/java/ql/lib/semmle/code/java/security/regexp/RegexInjection.qll index 3c1e2e98229..7b96ad6e198 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/RegexInjection.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/RegexInjection.qll @@ -2,8 +2,8 @@ import java private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.frameworks.Regex -private import semmle.code.java.regex.RegexFlowModels /** A data flow sink for untrusted user input used to construct regular expressions. */ abstract class RegexInjectionSink extends DataFlow::ExprNode { } From 2d309bb8f82d443d629df231c7cf705dc4dca0c7 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 17 Nov 2022 11:29:18 +0100 Subject: [PATCH 567/796] Java: Include the library query pack to get the data extensions included. --- java/ql/integration-tests/all-platforms/kotlin/qlpack.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/java/ql/integration-tests/all-platforms/kotlin/qlpack.yml b/java/ql/integration-tests/all-platforms/kotlin/qlpack.yml index 2d76cd00707..9ead02fc564 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/qlpack.yml +++ b/java/ql/integration-tests/all-platforms/kotlin/qlpack.yml @@ -1,4 +1,4 @@ -libraryPathDependencies: - - codeql-java - - codeql/java-tests - - codeql/java-queries +dependencies: + codeql/java-all: '*' + codeql/java-tests: '*' + codeql/java-queries: '*' From 157a2280887ce196287c6d361a852423d8a25b7a Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 17 Nov 2022 15:06:04 +0100 Subject: [PATCH 568/796] Java: Add query packs with names to enable dependency resolution. --- .../kotlin/default-parameter-mad-flow/qlpack.yml | 5 +++++ .../kotlin/gradle_kotlinx_serialization/qlpack.yml | 5 +++++ .../kotlin/kotlin-interface-inherited-default/qlpack.yml | 5 +++++ .../kotlin/kotlin_java_static_fields/qlpack.yml | 5 +++++ .../linux-only/kotlin/custom_plugin/qlpack.yml | 3 +++ 5 files changed, 23 insertions(+) create mode 100644 java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/qlpack.yml create mode 100644 java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/qlpack.yml create mode 100644 java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/qlpack.yml create mode 100644 java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/qlpack.yml create mode 100644 java/ql/integration-tests/linux-only/kotlin/custom_plugin/qlpack.yml diff --git a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/qlpack.yml b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/qlpack.yml new file mode 100644 index 00000000000..b8fa32c9094 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/qlpack.yml @@ -0,0 +1,5 @@ +name: integrationtest-default-parameter-mad-flow +dependencies: + codeql/java-all: '*' + codeql/java-tests: '*' + codeql/java-queries: '*' diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/qlpack.yml b/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/qlpack.yml new file mode 100644 index 00000000000..8b18f2ea94a --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/qlpack.yml @@ -0,0 +1,5 @@ +name: integrationtest-gradle-kotlinx-serialization +dependencies: + codeql/java-all: '*' + codeql/java-tests: '*' + codeql/java-queries: '*' diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/qlpack.yml b/java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/qlpack.yml new file mode 100644 index 00000000000..814d1059ed5 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/qlpack.yml @@ -0,0 +1,5 @@ +name: integrationtest-kotlin-interface-inherited-default +dependencies: + codeql/java-all: '*' + codeql/java-tests: '*' + codeql/java-queries: '*' diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/qlpack.yml b/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/qlpack.yml new file mode 100644 index 00000000000..ecc3ee3e4ff --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/qlpack.yml @@ -0,0 +1,5 @@ +name: integrationtest-kotlin-java-static-fields +dependencies: + codeql/java-all: '*' + codeql/java-tests: '*' + codeql/java-queries: '*' diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/qlpack.yml b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/qlpack.yml new file mode 100644 index 00000000000..e2f6b6de7ba --- /dev/null +++ b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/qlpack.yml @@ -0,0 +1,3 @@ +name: integrationtest-custom-plugin +dependencies: + codeql/java-all: '*' From 9c93402b260c9d2827b27f01d626de08347054c2 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 21 Nov 2022 13:31:31 +0100 Subject: [PATCH 569/796] Java: Convert integration test to use data extensions instead of inlined models. --- .../ext/test.model.yml | 28 +++++++++++++ .../default-parameter-mad-flow/qlpack.yml | 2 + .../kotlin/default-parameter-mad-flow/test.ql | 39 ------------------- 3 files changed, 30 insertions(+), 39 deletions(-) create mode 100644 java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/ext/test.model.yml diff --git a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/ext/test.model.yml b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/ext/test.model.yml new file mode 100644 index 00000000000..19ee05fc65f --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/ext/test.model.yml @@ -0,0 +1,28 @@ +extensions: + - addsTo: + pack: integrationtest-default-parameter-mad-flow + extensible: extSummaryModel + data: + - ["", "ConstructorWithDefaults", True, "ConstructorWithDefaults", "(int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["", "LibKt", True, "topLevelWithDefaults", "(int,int)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["", "LibKt", True, "extensionWithDefaults", "(String,int,int)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["", "LibClass", True, "memberWithDefaults", "(int,int)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["", "LibClass", True, "extensionMemberWithDefaults", "(String,int,int)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["", "LibClass", True, "multiParameterTest", "(int,int,int,int)", "", "Argument[0..1]", "ReturnValue", "value", "manual"] + - ["", "LibClass", True, "multiParameterExtensionTest", "(int,int,int,int)", "", "Argument[0, 1]", "ReturnValue", "value", "manual"] + - addsTo: + pack: integrationtest-default-parameter-mad-flow + extensible: extSourceModel + data: + - ["", "LibKt", True, "topLevelArgSource", "(SomeToken,int)", "", "Argument[0]", "kotlinMadFlowTest", "manual"] + - ["", "LibKt", True, "extensionArgSource", "(String,SomeToken,int)", "", "Argument[1]", "kotlinMadFlowTest", "manual"] + - ["", "SourceClass", True, "memberArgSource", "(SomeToken,int)", "", "Argument[0]", "kotlinMadFlowTest", "manual"] + - addsTo: + pack: integrationtest-default-parameter-mad-flow + extensible: extSinkModel + data: + - ["", "SinkClass", True, "SinkClass", "(int,int)", "", "Argument[0]", "kotlinMadFlowTest", "manual"] + - ["", "LibKt", True, "topLevelSink", "(int,int)", "", "Argument[0]", "kotlinMadFlowTest", "manual"] + - ["", "LibKt", True, "extensionSink", "(String,int,int)", "", "Argument[1]", "kotlinMadFlowTest", "manual"] + - ["", "SinkClass", True, "memberSink", "(int,int)", "", "Argument[0]", "kotlinMadFlowTest", "manual"] + - ["", "SinkClass", True, "extensionMemberSink", "(String,int,int)", "", "Argument[1]", "kotlinMadFlowTest", "manual"] diff --git a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/qlpack.yml b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/qlpack.yml index b8fa32c9094..f1e981e8791 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/qlpack.yml +++ b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/qlpack.yml @@ -3,3 +3,5 @@ dependencies: codeql/java-all: '*' codeql/java-tests: '*' codeql/java-queries: '*' +dataExtensions: + ext/*.model.yml diff --git a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql index b9b4423d94a..702b137fad7 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql +++ b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql @@ -3,45 +3,6 @@ import semmle.code.java.dataflow.TaintTracking import TestUtilities.InlineExpectationsTest private import semmle.code.java.dataflow.ExternalFlow -private class Models extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - ";ConstructorWithDefaults;true;ConstructorWithDefaults;(int,int);;Argument[0];Argument[-1];taint;manual", - ";LibKt;true;topLevelWithDefaults;(int,int);;Argument[0];ReturnValue;value;manual", - ";LibKt;true;extensionWithDefaults;(String,int,int);;Argument[1];ReturnValue;value;manual", - ";LibClass;true;memberWithDefaults;(int,int);;Argument[0];ReturnValue;value;manual", - ";LibClass;true;extensionMemberWithDefaults;(String,int,int);;Argument[1];ReturnValue;value;manual", - ";LibClass;true;multiParameterTest;(int,int,int,int);;Argument[0..1];ReturnValue;value;manual", - ";LibClass;true;multiParameterExtensionTest;(int,int,int,int);;Argument[0, 1];ReturnValue;value;manual", - ] - } -} - -private class SourceModels extends SourceModelCsv { - override predicate row(string row) { - row = - [ - ";LibKt;true;topLevelArgSource;(SomeToken,int);;Argument[0];kotlinMadFlowTest;manual", - ";LibKt;true;extensionArgSource;(String,SomeToken,int);;Argument[1];kotlinMadFlowTest;manual", - ";SourceClass;true;memberArgSource;(SomeToken,int);;Argument[0];kotlinMadFlowTest;manual" - ] - } -} - -private class SinkModels extends SinkModelCsv { - override predicate row(string row) { - row = - [ - ";SinkClass;true;SinkClass;(int,int);;Argument[0];kotlinMadFlowTest;manual", - ";LibKt;true;topLevelSink;(int,int);;Argument[0];kotlinMadFlowTest;manual", - ";LibKt;true;extensionSink;(String,int,int);;Argument[1];kotlinMadFlowTest;manual", - ";SinkClass;true;memberSink;(int,int);;Argument[0];kotlinMadFlowTest;manual", - ";SinkClass;true;extensionMemberSink;(String,int,int);;Argument[1];kotlinMadFlowTest;manual" - ] - } -} - class Config extends TaintTracking::Configuration { Config() { this = "Config" } From d7aafbfe6403da8b0fdb5fd2baf54d0e4262f216 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 21 Nov 2022 13:36:30 +0100 Subject: [PATCH 570/796] Java: Add model generator script that emits data extensions. --- .../GenerateFlowModelExtensions.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100755 java/ql/src/utils/model-generator/GenerateFlowModelExtensions.py diff --git a/java/ql/src/utils/model-generator/GenerateFlowModelExtensions.py b/java/ql/src/utils/model-generator/GenerateFlowModelExtensions.py new file mode 100755 index 00000000000..3dd1003bbdd --- /dev/null +++ b/java/ql/src/utils/model-generator/GenerateFlowModelExtensions.py @@ -0,0 +1,15 @@ +#!/usr/bin/python3 + +import sys +import os.path +import subprocess + +# Add Model as Data script directory to sys.path. +gitroot = subprocess.check_output(["git", "rev-parse", "--show-toplevel"]).decode("utf-8").strip() +madpath = os.path.join(gitroot, "misc/scripts/models-as-data/") +sys.path.append(madpath) + +import generate_flow_model_extensions as model + +language = "java" +model.Generator.make(language).run() \ No newline at end of file From 805430983c671e3ed768d914f7efc3d3452121c6 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 21 Nov 2022 13:52:51 +0100 Subject: [PATCH 571/796] Java: Convert commons-io to data extensions. --- .../generated/org.apache.commons.io.model.yml | 1433 +++++++++++++++++ .../dataflow/internal/NegativeSummary.qll | 9 - .../java/frameworks/GeneratedNegative.qll | 8 - .../java/frameworks/apache/IOGenerated.qll | 684 -------- .../frameworks/apache/NegativeIOGenerated.qll | 765 --------- .../semmle/code/java/frameworks/generated.qll | 1 - .../src/Telemetry/UnsupportedExternalAPIs.ql | 1 - .../external-models/negativesummaries.ql | 1 - 8 files changed, 1433 insertions(+), 1469 deletions(-) create mode 100644 java/ql/lib/ext/generated/org.apache.commons.io.model.yml delete mode 100644 java/ql/lib/semmle/code/java/dataflow/internal/NegativeSummary.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/GeneratedNegative.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/apache/IOGenerated.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/apache/NegativeIOGenerated.qll diff --git a/java/ql/lib/ext/generated/org.apache.commons.io.model.yml b/java/ql/lib/ext/generated/org.apache.commons.io.model.yml new file mode 100644 index 00000000000..f7af89c8a1b --- /dev/null +++ b/java/ql/lib/ext/generated/org.apache.commons.io.model.yml @@ -0,0 +1,1433 @@ + +# THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. +# Definitions of taint steps in the org.apache.commons.io framework. + +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["org.apache.commons.io.file", "PathFilter", true, "accept", "(Path,BasicFileAttributes)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFile", "(URL,Path,CopyOption[])", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFile", "(URL,Path,CopyOption[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFileToDirectory", "(Path,Path,CopyOption[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFileToDirectory", "(URL,Path,CopyOption[])", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFileToDirectory", "(URL,Path,CopyOption[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "newOutputStream", "(Path,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "writeString", "(Path,CharSequence,Charset,OpenOption[])", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "filter", "(IOFileFilter,File[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "filterList", "(IOFileFilter,File[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "filterSet", "(IOFileFilter,File[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io.input", "Tailer$Tailable", true, "getRandomAccess", "(String)", "", "Argument[-1]", "create-file", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(URL)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "writeTo", "(OutputStream)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,Charset,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,CharsetEncoder)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,CharsetEncoder,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,String,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,Charset,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,CharsetEncoder)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,CharsetEncoder,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,String,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,Charset,boolean,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,String,boolean,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,boolean,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(String,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(String,boolean,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "XmlStreamWriter", "(File)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "XmlStreamWriter", "(File,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File,FileFilter)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File,FileFilter,boolean)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File,FileFilter,boolean,CopyOption[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File,boolean)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectoryToDirectory", "(File,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFile", "(File,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFile", "(File,File,CopyOption[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFile", "(File,File,boolean)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFile", "(File,File,boolean,CopyOption[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFileToDirectory", "(File,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFileToDirectory", "(File,File,boolean)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyInputStreamToFile", "(InputStream,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyToDirectory", "(File,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyToDirectory", "(Iterable,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyToFile", "(InputStream,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File,int,int)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File,int,int)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveDirectory", "(File,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveDirectoryToDirectory", "(File,File,boolean)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveFile", "(File,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveFile", "(File,File,CopyOption[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveFileToDirectory", "(File,File,boolean)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveToDirectory", "(File,File,boolean)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "newOutputStream", "(File,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "openOutputStream", "(File)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "openOutputStream", "(File,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "touch", "(File)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,Charset,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,String,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeByteArrayToFile", "(File,byte[])", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeByteArrayToFile", "(File,byte[],boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeByteArrayToFile", "(File,byte[],int,int)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeByteArrayToFile", "(File,byte[],int,int,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,Collection)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,Collection,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,Collection,String,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,Collection,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,String,Collection)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,String,Collection,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,String,Collection,String,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,String,Collection,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,Charset,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,String,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(URL,File)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(URL,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(URL,OutputStream)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toByteArray", "(URI)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toByteArray", "(URL)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URI)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URI,Charset)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URI,String)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URL)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URL,Charset)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URL,String)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "RandomAccessFileMode", false, "create", "(File)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "RandomAccessFileMode", false, "create", "(Path)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "RandomAccessFileMode", false, "create", "(String)", "", "Argument[0]", "create-file", "generated"] + + + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["org.apache.commons.io.charset", "CharsetDecoders", true, "toCharsetDecoder", "(CharsetDecoder)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.charset", "CharsetEncoders", true, "toCharsetEncoder", "(CharsetEncoder)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.comparator", "CompositeFileComparator", true, "CompositeFileComparator", "(Comparator[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.comparator", "CompositeFileComparator", true, "CompositeFileComparator", "(Iterable)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.comparator", "CompositeFileComparator", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file.spi", "FileSystemProviders", true, "getFileSystemProvider", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file.spi", "FileSystemProviders", true, "getFileSystemProvider", "(URI)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file.spi", "FileSystemProviders", true, "getFileSystemProvider", "(URL)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "AccumulatorPathVisitor", "(PathCounters)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "AccumulatorPathVisitor", "(PathCounters,PathFilter,PathFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "AccumulatorPathVisitor", "(PathCounters,PathFilter,PathFilter)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "AccumulatorPathVisitor", "(PathCounters,PathFilter,PathFilter)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "getDirList", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "getFileList", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "withBigIntegerCounters", "(PathFilter,PathFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "withBigIntegerCounters", "(PathFilter,PathFilter)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "withLongCounters", "(PathFilter,PathFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "withLongCounters", "(PathFilter,PathFilter)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "CleaningPathVisitor", true, "CleaningPathVisitor", "(PathCounters,DeleteOption[],String[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CleaningPathVisitor", true, "CleaningPathVisitor", "(PathCounters,DeleteOption[],String[])", "", "Argument[2].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CleaningPathVisitor", true, "CleaningPathVisitor", "(PathCounters,String[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CleaningPathVisitor", true, "CleaningPathVisitor", "(PathCounters,String[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,Path,Path,CopyOption[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,Path,Path,CopyOption[])", "", "Argument[1].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,Path,Path,CopyOption[])", "", "Argument[2].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,Path,Path,CopyOption[])", "", "Argument[3].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[])", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[])", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[])", "", "Argument[3].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[])", "", "Argument[4].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[])", "", "Argument[5].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "getCopyOptions", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "getSourceDirectory", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "getTargetDirectory", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "Counters$PathCounters", true, "getByteCounter", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "Counters$PathCounters", true, "getDirectoryCounter", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "Counters$PathCounters", true, "getFileCounter", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "CountingPathVisitor", true, "CountingPathVisitor", "(PathCounters)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CountingPathVisitor", true, "CountingPathVisitor", "(PathCounters,PathFilter,PathFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CountingPathVisitor", true, "CountingPathVisitor", "(PathCounters,PathFilter,PathFilter)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CountingPathVisitor", true, "CountingPathVisitor", "(PathCounters,PathFilter,PathFilter)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CountingPathVisitor", true, "getPathCounters", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", true, "DeletingPathVisitor", "(PathCounters,DeleteOption[],String[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", true, "DeletingPathVisitor", "(PathCounters,DeleteOption[],String[])", "", "Argument[2].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", true, "DeletingPathVisitor", "(PathCounters,LinkOption[],DeleteOption[],String[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", true, "DeletingPathVisitor", "(PathCounters,LinkOption[],DeleteOption[],String[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", true, "DeletingPathVisitor", "(PathCounters,LinkOption[],DeleteOption[],String[])", "", "Argument[3].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", true, "DeletingPathVisitor", "(PathCounters,String[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", true, "DeletingPathVisitor", "(PathCounters,String[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "DirectoryStreamFilter", true, "DirectoryStreamFilter", "(PathFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "DirectoryStreamFilter", true, "getPathFilter", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFile", "(URL,Path,CopyOption[])", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFileToDirectory", "(URL,Path,CopyOption[])", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "setReadOnly", "(Path,boolean,LinkOption[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "visitFileTree", "(FileVisitor,Path)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "visitFileTree", "(FileVisitor,Path,Set,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "visitFileTree", "(FileVisitor,String,String[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "visitFileTree", "(FileVisitor,URI)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "writeString", "(Path,CharSequence,Charset,OpenOption[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", true, "AgeFileFilter", "(Instant)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", true, "AgeFileFilter", "(Instant,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AndFileFilter", true, "AndFileFilter", "(IOFileFilter,IOFileFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AndFileFilter", true, "AndFileFilter", "(IOFileFilter,IOFileFilter)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AndFileFilter", true, "AndFileFilter", "(IOFileFilter[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AndFileFilter", true, "AndFileFilter", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AndFileFilter", true, "addFileFilter", "(IOFileFilter[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AndFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "ConditionalFileFilter", true, "addFileFilter", "(IOFileFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "ConditionalFileFilter", true, "getFileFilters", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "ConditionalFileFilter", true, "setFileFilters", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "DelegateFileFilter", true, "DelegateFileFilter", "(FileFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "DelegateFileFilter", true, "DelegateFileFilter", "(FilenameFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "DelegateFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileEqualsFileFilter", true, "FileEqualsFileFilter", "(File)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "and", "(IOFileFilter[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "andFileFilter", "(IOFileFilter,IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "andFileFilter", "(IOFileFilter,IOFileFilter)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "asFileFilter", "(FileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "asFileFilter", "(FilenameFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "magicNumberFileFilter", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "magicNumberFileFilter", "(String,long)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "magicNumberFileFilter", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "magicNumberFileFilter", "(byte[],long)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "makeCVSAware", "(IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "makeDirectoryOnly", "(IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "makeFileOnly", "(IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "makeSVNAware", "(IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "nameFileFilter", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "nameFileFilter", "(String,IOCase)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "notFileFilter", "(IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "or", "(IOFileFilter[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "orFileFilter", "(IOFileFilter,IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "orFileFilter", "(IOFileFilter,IOFileFilter)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "prefixFileFilter", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "prefixFileFilter", "(String,IOCase)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "suffixFileFilter", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "suffixFileFilter", "(String,IOCase)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "toList", "(IOFileFilter[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "IOFileFilter", true, "and", "(IOFileFilter)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "IOFileFilter", true, "and", "(IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "IOFileFilter", true, "negate", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "IOFileFilter", true, "or", "(IOFileFilter)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "IOFileFilter", true, "or", "(IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "MagicNumberFileFilter", true, "MagicNumberFileFilter", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "MagicNumberFileFilter", true, "MagicNumberFileFilter", "(String,long)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "MagicNumberFileFilter", true, "MagicNumberFileFilter", "(byte[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "MagicNumberFileFilter", true, "MagicNumberFileFilter", "(byte[],long)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "MagicNumberFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NameFileFilter", true, "NameFileFilter", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NameFileFilter", true, "NameFileFilter", "(List,IOCase)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NameFileFilter", true, "NameFileFilter", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NameFileFilter", true, "NameFileFilter", "(String,IOCase)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NameFileFilter", true, "NameFileFilter", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NameFileFilter", true, "NameFileFilter", "(String[],IOCase)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NameFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NotFileFilter", true, "NotFileFilter", "(IOFileFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NotFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "OrFileFilter", true, "OrFileFilter", "(IOFileFilter,IOFileFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "OrFileFilter", true, "OrFileFilter", "(IOFileFilter,IOFileFilter)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "OrFileFilter", true, "OrFileFilter", "(IOFileFilter[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "OrFileFilter", true, "OrFileFilter", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "OrFileFilter", true, "addFileFilter", "(IOFileFilter[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "OrFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PathEqualsFileFilter", true, "PathEqualsFileFilter", "(Path)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PathVisitorFileFilter", true, "PathVisitorFileFilter", "(PathVisitor)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PrefixFileFilter", true, "PrefixFileFilter", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PrefixFileFilter", true, "PrefixFileFilter", "(List,IOCase)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PrefixFileFilter", true, "PrefixFileFilter", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PrefixFileFilter", true, "PrefixFileFilter", "(String,IOCase)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PrefixFileFilter", true, "PrefixFileFilter", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PrefixFileFilter", true, "PrefixFileFilter", "(String[],IOCase)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PrefixFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "RegexFileFilter", true, "RegexFileFilter", "(Pattern)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "RegexFileFilter", true, "RegexFileFilter", "(Pattern,Function)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "RegexFileFilter", true, "RegexFileFilter", "(Pattern,Function)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "RegexFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "SuffixFileFilter", true, "SuffixFileFilter", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "SuffixFileFilter", true, "SuffixFileFilter", "(List,IOCase)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "SuffixFileFilter", true, "SuffixFileFilter", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "SuffixFileFilter", true, "SuffixFileFilter", "(String,IOCase)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "SuffixFileFilter", true, "SuffixFileFilter", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "SuffixFileFilter", true, "SuffixFileFilter", "(String[],IOCase)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "SuffixFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFileFilter", true, "WildcardFileFilter", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFileFilter", true, "WildcardFileFilter", "(List,IOCase)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFileFilter", true, "WildcardFileFilter", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFileFilter", true, "WildcardFileFilter", "(String,IOCase)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFileFilter", true, "WildcardFileFilter", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFileFilter", true, "WildcardFileFilter", "(String[],IOCase)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFilter", true, "WildcardFilter", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFilter", true, "WildcardFilter", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFilter", true, "WildcardFilter", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularBufferInputStream", true, "CircularBufferInputStream", "(InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularBufferInputStream", true, "CircularBufferInputStream", "(InputStream,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input.buffer", "PeekableInputStream", true, "PeekableInputStream", "(InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input.buffer", "PeekableInputStream", true, "PeekableInputStream", "(InputStream,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "BOMInputStream", true, "BOMInputStream", "(InputStream,ByteOrderMark[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "BOMInputStream", true, "BOMInputStream", "(InputStream,boolean,ByteOrderMark[])", "", "Argument[2].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "BOMInputStream", true, "getBOM", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "BOMInputStream", true, "getBOMCharsetName", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "BoundedInputStream", true, "BoundedInputStream", "(InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "BoundedInputStream", true, "BoundedInputStream", "(InputStream,long)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "BoundedReader", true, "BoundedReader", "(Reader,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "BrokenInputStream", true, "BrokenInputStream", "(Supplier)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "BrokenReader", true, "BrokenReader", "(Supplier)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "CharSequenceReader", true, "CharSequenceReader", "(CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "CharSequenceReader", true, "CharSequenceReader", "(CharSequence,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "CharSequenceReader", true, "CharSequenceReader", "(CharSequence,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "CharSequenceReader", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "CharacterFilterReader", true, "CharacterFilterReader", "(Reader,IntPredicate)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "CircularInputStream", true, "CircularInputStream", "(byte[],long)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ClassLoaderObjectInputStream", true, "ClassLoaderObjectInputStream", "(ClassLoader,InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ClassLoaderObjectInputStream", true, "ClassLoaderObjectInputStream", "(ClassLoader,InputStream)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "CloseShieldInputStream", true, "wrap", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "InfiniteCircularInputStream", true, "InfiniteCircularInputStream", "(byte[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "MessageDigestCalculatingInputStream$MessageDigestMaintainingObserver", true, "MessageDigestMaintainingObserver", "(MessageDigest)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "MessageDigestCalculatingInputStream", true, "MessageDigestCalculatingInputStream", "(InputStream,MessageDigest)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "MessageDigestCalculatingInputStream", true, "getMessageDigest", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream", true, "ObservableInputStream", "(InputStream,Observer[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream", true, "add", "(Observer)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream", true, "getObservers", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "RandomAccessFileInputStream", true, "RandomAccessFileInputStream", "(RandomAccessFile)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "RandomAccessFileInputStream", true, "RandomAccessFileInputStream", "(RandomAccessFile,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "RandomAccessFileInputStream", true, "getRandomAccessFile", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "ReadAheadInputStream", true, "ReadAheadInputStream", "(InputStream,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReadAheadInputStream", true, "ReadAheadInputStream", "(InputStream,int,ExecutorService)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReadAheadInputStream", true, "ReadAheadInputStream", "(InputStream,int,ExecutorService)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader,Charset)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader,Charset,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader,CharsetEncoder)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader,CharsetEncoder)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader,CharsetEncoder,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader,CharsetEncoder,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", true, "readLine", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", true, "readLines", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", true, "toString", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "SequenceReader", true, "SequenceReader", "(Iterable)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "SequenceReader", true, "SequenceReader", "(Reader[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "Builder", "(File,TailerListener)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "Builder", "(File,TailerListener)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "Builder", "(Path,TailerListener)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "Builder", "(Path,TailerListener)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "Builder", "(Tailable,TailerListener)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "Builder", "(Tailable,TailerListener)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "build", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "withBufferSize", "(int)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "withCharset", "(Charset)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "withDelayDuration", "(Duration)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "withDelayDuration", "(Duration)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "withReOpen", "(boolean)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "withStartThread", "(boolean)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "withTailFromEnd", "(boolean)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,Charset,TailerListener,long,boolean,boolean,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,Charset,TailerListener,long,boolean,boolean,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long,boolean,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long,boolean,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long,boolean,boolean,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long,boolean,boolean,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long,boolean,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long,boolean,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,Charset,TailerListener,long,boolean,boolean,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,Charset,TailerListener,long,boolean,boolean,int)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long,boolean)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long,boolean,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long,boolean,boolean)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long,boolean,boolean,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long,boolean,boolean,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long,boolean,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long,boolean,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "getDelayDuration", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "getFile", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "getTailable", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "TeeInputStream", true, "TeeInputStream", "(InputStream,OutputStream)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "TeeInputStream", true, "TeeInputStream", "(InputStream,OutputStream,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "TeeReader", true, "TeeReader", "(Reader,Writer)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "TeeReader", true, "TeeReader", "(Reader,Writer,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "TimestampedObserver", true, "getCloseInstant", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "TimestampedObserver", true, "getOpenInstant", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "TimestampedObserver", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "UncheckedBufferedReader", true, "UncheckedBufferedReader", "(Reader)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "UncheckedBufferedReader", true, "UncheckedBufferedReader", "(Reader,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "UncheckedBufferedReader", true, "on", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "UncheckedFilterInputStream", true, "on", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "UnixLineEndingInputStream", true, "UnixLineEndingInputStream", "(InputStream,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "UnsynchronizedByteArrayInputStream", true, "UnsynchronizedByteArrayInputStream", "(byte[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "UnsynchronizedByteArrayInputStream", true, "UnsynchronizedByteArrayInputStream", "(byte[],int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "UnsynchronizedByteArrayInputStream", true, "UnsynchronizedByteArrayInputStream", "(byte[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "WindowsLineEndingInputStream", true, "WindowsLineEndingInputStream", "(InputStream,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,String,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,String,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,String,boolean,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,String,boolean,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,String,boolean,String)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,boolean,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,boolean,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(URLConnection,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "getDefaultEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "getEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "XmlStreamReaderException", "(String,String,String,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "XmlStreamReaderException", "(String,String,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "XmlStreamReaderException", "(String,String,String,String)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "XmlStreamReaderException", "(String,String,String,String,String,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "XmlStreamReaderException", "(String,String,String,String,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "XmlStreamReaderException", "(String,String,String,String,String,String)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "XmlStreamReaderException", "(String,String,String,String,String,String)", "", "Argument[4]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "XmlStreamReaderException", "(String,String,String,String,String,String)", "", "Argument[5]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "getBomEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "getContentTypeEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "getContentTypeMime", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "getXmlEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "getXmlGuessEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", false, "FileAlterationMonitor", "(long,Collection)", "", "Argument[1].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", false, "FileAlterationMonitor", "(long,FileAlterationObserver[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", false, "addObserver", "(FileAlterationObserver)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", false, "getObservers", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", false, "setThreadFactory", "(ThreadFactory)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(File)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(File,FileFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(File,FileFilter)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(File,FileFilter,IOCase)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(File,FileFilter,IOCase)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(String,FileFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(String,FileFilter)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(String,FileFilter,IOCase)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(String,FileFilter,IOCase)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "addListener", "(FileAlterationListener)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "getDirectory", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "getFileFilter", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "getListeners", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "FileEntry", "(File)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "FileEntry", "(FileEntry,File)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "FileEntry", "(FileEntry,File)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "getChildren", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "getFile", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "getLastModifiedFileTime", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "getName", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "getParent", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "newChildInstance", "(File)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "newChildInstance", "(File)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "setChildren", "(FileEntry[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "setLastModified", "(FileTime)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "setName", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", true, "toByteArray", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", true, "toString", "(Charset)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", true, "toString", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", true, "write", "(InputStream)", "", "Argument[-1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", true, "write", "(InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", true, "writeTo", "(OutputStream)", "", "Argument[-1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io.output", "AppendableOutputStream", true, "AppendableOutputStream", "(Appendable)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "AppendableOutputStream", true, "getAppendable", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "AppendableWriter", true, "AppendableWriter", "(Appendable)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "AppendableWriter", true, "getAppendable", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "BrokenOutputStream", true, "BrokenOutputStream", "(Supplier)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "BrokenWriter", true, "BrokenWriter", "(Supplier)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "ChunkedOutputStream", true, "ChunkedOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "ChunkedOutputStream", true, "ChunkedOutputStream", "(OutputStream,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "CloseShieldOutputStream", true, "CloseShieldOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "CloseShieldOutputStream", true, "wrap", "(OutputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "CountingOutputStream", true, "CountingOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "DeferredFileOutputStream", "(int,File)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "DeferredFileOutputStream", "(int,String,String,File)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "DeferredFileOutputStream", "(int,String,String,File)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "DeferredFileOutputStream", "(int,String,String,File)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "DeferredFileOutputStream", "(int,int,File)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "DeferredFileOutputStream", "(int,int,String,String,File)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "DeferredFileOutputStream", "(int,int,String,String,File)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "DeferredFileOutputStream", "(int,int,String,String,File)", "", "Argument[4]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "getData", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "getFile", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "writeTo", "(OutputStream)", "", "Argument[-1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,Charset,boolean,String)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,String,boolean,String)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,boolean,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(String,boolean,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "ProxyCollectionWriter", true, "ProxyCollectionWriter", "(Collection)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "ProxyCollectionWriter", true, "ProxyCollectionWriter", "(Writer[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "ProxyOutputStream", true, "ProxyOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "StringBuilderWriter", true, "StringBuilderWriter", "(StringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "StringBuilderWriter", true, "getBuilder", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "StringBuilderWriter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "TaggedOutputStream", true, "TaggedOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "TeeOutputStream", true, "TeeOutputStream", "(OutputStream,OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "TeeOutputStream", true, "TeeOutputStream", "(OutputStream,OutputStream)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "TeeWriter", true, "TeeWriter", "(Collection)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "TeeWriter", true, "TeeWriter", "(Writer[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "ThresholdingOutputStream", true, "ThresholdingOutputStream", "(int,IOConsumer,IOFunction)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "ThresholdingOutputStream", true, "ThresholdingOutputStream", "(int,IOConsumer,IOFunction)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "UncheckedAppendable", true, "on", "(Appendable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "UncheckedFilterOutputStream", true, "UncheckedFilterOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "UncheckedFilterOutputStream", true, "on", "(OutputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer,Charset)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer,Charset,int,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer,CharsetDecoder)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer,CharsetDecoder)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer,CharsetDecoder,int,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer,CharsetDecoder,int,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer,String,int,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "XmlStreamWriter", "(File,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "XmlStreamWriter", "(OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "XmlStreamWriter", "(OutputStream,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "XmlStreamWriter", "(OutputStream,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "getDefaultEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "getEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "ValidatingObjectInputStream", "(InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "accept", "(ClassNameMatcher)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "accept", "(ClassNameMatcher)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "accept", "(Class[])", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "accept", "(Pattern)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "accept", "(String[])", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "reject", "(ClassNameMatcher)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "reject", "(ClassNameMatcher)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "reject", "(Class[])", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "reject", "(Pattern)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "reject", "(String[])", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io", "ByteOrderMark", true, "ByteOrderMark", "(String,int[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io", "ByteOrderMark", true, "getCharsetName", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "ByteOrderMark", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "CopyUtils", true, "copy", "(InputStream,OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "CopyUtils", true, "copy", "(InputStream,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "CopyUtils", true, "copy", "(InputStream,Writer,String)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "CopyUtils", true, "copy", "(Reader,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "CopyUtils", true, "copy", "(String,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "CopyUtils", true, "copy", "(byte[],OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "CopyUtils", true, "copy", "(byte[],Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "CopyUtils", true, "copy", "(byte[],Writer,String)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "DirectoryWalker$CancelException", true, "CancelException", "(File,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io", "DirectoryWalker$CancelException", true, "CancelException", "(String,File,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io", "DirectoryWalker$CancelException", true, "getFile", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileCleaningTracker", true, "getDeleteFailures", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileDeleteStrategy", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileSystem", false, "normalizeSeparators", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileSystem", false, "toLegalFileName", "(String,char)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "checksum", "(File,Checksum)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "convertFileCollectionToFileArray", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "delete", "(File)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "getFile", "(File,String[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "getFile", "(File,String[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "getFile", "(String[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "toURLs", "(File[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "concat", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "concat", "(String,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "getBaseName", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "getExtension", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "getFullPath", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "getFullPathNoEndSeparator", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "getName", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "getPath", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "getPathNoEndSeparator", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "getPrefix", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "normalize", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "normalize", "(String,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "normalizeNoEndSeparator", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "normalizeNoEndSeparator", "(String,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "removeExtension", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "separatorsToSystem", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "separatorsToUnix", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "separatorsToWindows", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOExceptionList", true, "IOExceptionList", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io", "IOExceptionList", true, "IOExceptionList", "(String,List)", "", "Argument[1].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io", "IOExceptionList", true, "getCause", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOExceptionList", true, "getCauseList", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOExceptionList", true, "getCauseList", "(Class)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "buffer", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "buffer", "(InputStream,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "buffer", "(OutputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "buffer", "(OutputStream,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "buffer", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "buffer", "(Reader,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "buffer", "(Writer)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "buffer", "(Writer,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(InputStream,OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(InputStream,OutputStream,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(InputStream,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(InputStream,Writer,Charset)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(InputStream,Writer,String)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(Reader,Appendable)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(Reader,Appendable,CharBuffer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(Reader,Appendable,CharBuffer)", "", "Argument[0]", "Argument[2]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(Reader,Appendable,CharBuffer)", "", "Argument[2]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(Reader,Appendable,CharBuffer)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(Reader,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,byte[])", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,byte[])", "", "Argument[0]", "Argument[2]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,byte[])", "", "Argument[2]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,byte[])", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,long,long)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,long,long,byte[])", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,long,long,byte[])", "", "Argument[0]", "Argument[4]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,long,long,byte[])", "", "Argument[4]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,long,long,byte[])", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,char[])", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,char[])", "", "Argument[0]", "Argument[2]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,char[])", "", "Argument[2]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,char[])", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,long,long)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,long,long,char[])", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,long,long,char[])", "", "Argument[0]", "Argument[4]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,long,long,char[])", "", "Argument[4]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,long,long,char[])", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "lineIterator", "(InputStream,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "lineIterator", "(InputStream,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "lineIterator", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(InputStream,byte[])", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(InputStream,byte[])", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(InputStream,byte[],int,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(InputStream,byte[],int,int)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(ReadableByteChannel,ByteBuffer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(Reader,char[])", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(Reader,char[])", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(Reader,char[],int,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(Reader,char[],int,int)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(InputStream,byte[])", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(InputStream,byte[])", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(InputStream,byte[],int,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(InputStream,byte[],int,int)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(InputStream,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(ReadableByteChannel,ByteBuffer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(Reader,char[])", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(Reader,char[])", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(Reader,char[],int,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(Reader,char[],int,int)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readLines", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readLines", "(InputStream,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readLines", "(InputStream,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readLines", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toBufferedReader", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toBufferedReader", "(Reader,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toByteArray", "(InputStream,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toByteArray", "(InputStream,long)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toByteArray", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toCharArray", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toCharArray", "(InputStream,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toCharArray", "(InputStream,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toCharArray", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toInputStream", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toInputStream", "(CharSequence,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toInputStream", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toInputStream", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toInputStream", "(String,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toInputStream", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(InputStream,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(InputStream,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(byte[],String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "write", "(CharSequence,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "write", "(String,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "write", "(StringBuffer,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "write", "(byte[],OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "write", "(byte[],Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "write", "(byte[],Writer,Charset)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "write", "(byte[],Writer,String)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "write", "(char[],Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "writeChunked", "(byte[],OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "writeChunked", "(char[],Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "writeLines", "(Collection,String,OutputStream)", "", "Argument[1]", "Argument[2]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "writeLines", "(Collection,String,OutputStream,Charset)", "", "Argument[1]", "Argument[2]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "writeLines", "(Collection,String,OutputStream,String)", "", "Argument[1]", "Argument[2]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "writeLines", "(Collection,String,Writer)", "", "Argument[1]", "Argument[2]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "writer", "(Appendable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "LineIterator", true, "LineIterator", "(Reader)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io", "LineIterator", true, "nextLine", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "TaggedIOException", true, "TaggedIOException", "(IOException,Serializable)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io", "TaggedIOException", true, "getTag", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "UncheckedIO", true, "apply", "(IOFunction,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "UncheckedIO", true, "apply", "(IOTriFunction,Object,Object,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + + - addsTo: + pack: codeql/java-all + extensible: extNegativeSummaryModel + data: + - ["org.apache.commons.io.charset", "CharsetDecoders", "CharsetDecoders", "()", "generated"] + - ["org.apache.commons.io.charset", "CharsetEncoders", "CharsetEncoders", "()", "generated"] + - ["org.apache.commons.io.comparator", "DefaultFileComparator", "DefaultFileComparator", "()", "generated"] + - ["org.apache.commons.io.comparator", "DirectoryFileComparator", "DirectoryFileComparator", "()", "generated"] + - ["org.apache.commons.io.comparator", "ExtensionFileComparator", "ExtensionFileComparator", "()", "generated"] + - ["org.apache.commons.io.comparator", "ExtensionFileComparator", "ExtensionFileComparator", "(IOCase)", "generated"] + - ["org.apache.commons.io.comparator", "ExtensionFileComparator", "toString", "()", "generated"] + - ["org.apache.commons.io.comparator", "LastModifiedFileComparator", "LastModifiedFileComparator", "()", "generated"] + - ["org.apache.commons.io.comparator", "NameFileComparator", "NameFileComparator", "()", "generated"] + - ["org.apache.commons.io.comparator", "NameFileComparator", "NameFileComparator", "(IOCase)", "generated"] + - ["org.apache.commons.io.comparator", "NameFileComparator", "toString", "()", "generated"] + - ["org.apache.commons.io.comparator", "PathFileComparator", "PathFileComparator", "()", "generated"] + - ["org.apache.commons.io.comparator", "PathFileComparator", "PathFileComparator", "(IOCase)", "generated"] + - ["org.apache.commons.io.comparator", "PathFileComparator", "toString", "()", "generated"] + - ["org.apache.commons.io.comparator", "SizeFileComparator", "SizeFileComparator", "()", "generated"] + - ["org.apache.commons.io.comparator", "SizeFileComparator", "SizeFileComparator", "(boolean)", "generated"] + - ["org.apache.commons.io.comparator", "SizeFileComparator", "toString", "()", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "minusMillis", "(FileTime,long)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "minusNanos", "(FileTime,long)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "minusSeconds", "(FileTime,long)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "now", "()", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "ntfsTimeToDate", "(long)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "ntfsTimeToFileTime", "(long)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "plusMillis", "(FileTime,long)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "plusNanos", "(FileTime,long)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "plusSeconds", "(FileTime,long)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "setLastModifiedTime", "(Path)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "toDate", "(FileTime)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "toFileTime", "(Date)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "toNtfsTime", "(Date)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "toNtfsTime", "(FileTime)", "generated"] + - ["org.apache.commons.io.file.spi", "FileSystemProviders", "getFileSystemProvider", "(Path)", "generated"] + - ["org.apache.commons.io.file.spi", "FileSystemProviders", "installed", "()", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", "AccumulatorPathVisitor", "()", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", "relativizeDirectories", "(Path,boolean,Comparator)", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", "relativizeFiles", "(Path,boolean,Comparator)", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", "withBigIntegerCounters", "()", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", "withLongCounters", "()", "generated"] + - ["org.apache.commons.io.file", "CleaningPathVisitor", "withBigIntegerCounters", "()", "generated"] + - ["org.apache.commons.io.file", "CleaningPathVisitor", "withLongCounters", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$Counter", "add", "(long)", "generated"] + - ["org.apache.commons.io.file", "Counters$Counter", "get", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$Counter", "getBigInteger", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$Counter", "getLong", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$Counter", "increment", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$Counter", "reset", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$PathCounters", "getByteCounter", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$PathCounters", "getDirectoryCounter", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$PathCounters", "getFileCounter", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$PathCounters", "reset", "()", "generated"] + - ["org.apache.commons.io.file", "Counters", "Counters", "()", "generated"] + - ["org.apache.commons.io.file", "Counters", "bigIntegerCounter", "()", "generated"] + - ["org.apache.commons.io.file", "Counters", "bigIntegerPathCounters", "()", "generated"] + - ["org.apache.commons.io.file", "Counters", "longCounter", "()", "generated"] + - ["org.apache.commons.io.file", "Counters", "longPathCounters", "()", "generated"] + - ["org.apache.commons.io.file", "Counters", "noopCounter", "()", "generated"] + - ["org.apache.commons.io.file", "Counters", "noopPathCounters", "()", "generated"] + - ["org.apache.commons.io.file", "CountingPathVisitor", "toString", "()", "generated"] + - ["org.apache.commons.io.file", "CountingPathVisitor", "withBigIntegerCounters", "()", "generated"] + - ["org.apache.commons.io.file", "CountingPathVisitor", "withLongCounters", "()", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", "withBigIntegerCounters", "()", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", "withLongCounters", "()", "generated"] + - ["org.apache.commons.io.file", "NoopPathVisitor", "NoopPathVisitor", "()", "generated"] + - ["org.apache.commons.io.file", "PathFilter", "accept", "(Path,BasicFileAttributes)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "cleanDirectory", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "cleanDirectory", "(Path,DeleteOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "copyDirectory", "(Path,Path,CopyOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "copyFileToDirectory", "(Path,Path,CopyOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "countDirectory", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "countDirectoryAsBigInteger", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "createParentDirectories", "(Path,FileAttribute[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "createParentDirectories", "(Path,LinkOption,FileAttribute[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "current", "()", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "delete", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "delete", "(Path,DeleteOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "delete", "(Path,LinkOption[],DeleteOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "deleteDirectory", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "deleteDirectory", "(Path,DeleteOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "deleteDirectory", "(Path,LinkOption[],DeleteOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "deleteFile", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "deleteFile", "(Path,DeleteOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "deleteFile", "(Path,LinkOption[],DeleteOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "directoryAndFileContentEquals", "(Path,Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "directoryAndFileContentEquals", "(Path,Path,LinkOption[],OpenOption[],FileVisitOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "directoryContentEquals", "(Path,Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "directoryContentEquals", "(Path,Path,int,LinkOption[],FileVisitOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "fileContentEquals", "(Path,Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "fileContentEquals", "(Path,Path,LinkOption[],OpenOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "filter", "(PathFilter,Path[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "getAclEntryList", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "getAclFileAttributeView", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "getDosFileAttributeView", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "getPosixFileAttributeView", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "getTempDirectory", "()", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isDirectory", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isEmpty", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isEmptyDirectory", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isEmptyFile", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isNewer", "(Path,ChronoZonedDateTime,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isNewer", "(Path,FileTime,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isNewer", "(Path,Instant,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isNewer", "(Path,Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isNewer", "(Path,long,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isOlder", "(Path,FileTime,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isOlder", "(Path,Instant,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isOlder", "(Path,Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isOlder", "(Path,long,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isPosix", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isRegularFile", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "newDirectoryStream", "(Path,PathFilter)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "newOutputStream", "(Path,boolean)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "noFollowLinkOptionArray", "()", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "readAttributes", "(Path,Class,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "readBasicFileAttributes", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "readBasicFileAttributes", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "readBasicFileAttributesUnchecked", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "readDosFileAttributes", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "readOsFileAttributes", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "readPosixFileAttributes", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "readString", "(Path,Charset)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "setLastModifiedTime", "(Path,Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "sizeOf", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "sizeOfAsBigInteger", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "sizeOfDirectory", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "sizeOfDirectoryAsBigInteger", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "waitFor", "(Path,Duration,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "walk", "(Path,PathFilter,int,boolean,FileVisitOption[])", "generated"] + - ["org.apache.commons.io.file", "StandardDeleteOption", "overrideReadOnly", "(DeleteOption[])", "generated"] + - ["org.apache.commons.io.filefilter", "AbstractFileFilter", "AbstractFileFilter", "()", "generated"] + - ["org.apache.commons.io.filefilter", "AbstractFileFilter", "toString", "()", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", "AgeFileFilter", "(Date)", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", "AgeFileFilter", "(Date,boolean)", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", "AgeFileFilter", "(File)", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", "AgeFileFilter", "(File,boolean)", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", "AgeFileFilter", "(long)", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", "AgeFileFilter", "(long,boolean)", "generated"] + - ["org.apache.commons.io.filefilter", "AndFileFilter", "AndFileFilter", "()", "generated"] + - ["org.apache.commons.io.filefilter", "ConditionalFileFilter", "addFileFilter", "(IOFileFilter)", "generated"] + - ["org.apache.commons.io.filefilter", "ConditionalFileFilter", "getFileFilters", "()", "generated"] + - ["org.apache.commons.io.filefilter", "ConditionalFileFilter", "removeFileFilter", "(IOFileFilter)", "generated"] + - ["org.apache.commons.io.filefilter", "ConditionalFileFilter", "setFileFilters", "(List)", "generated"] + - ["org.apache.commons.io.filefilter", "FalseFileFilter", "toString", "()", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "FileFilterUtils", "()", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "ageFileFilter", "(Date)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "ageFileFilter", "(Date,boolean)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "ageFileFilter", "(File)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "ageFileFilter", "(File,boolean)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "ageFileFilter", "(long)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "ageFileFilter", "(long,boolean)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "directoryFileFilter", "()", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "falseFileFilter", "()", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "fileFileFilter", "()", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "filter", "(IOFileFilter,File[])", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "filter", "(IOFileFilter,Iterable)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "filterList", "(IOFileFilter,File[])", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "filterList", "(IOFileFilter,Iterable)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "filterSet", "(IOFileFilter,File[])", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "filterSet", "(IOFileFilter,Iterable)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "sizeFileFilter", "(long)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "sizeFileFilter", "(long,boolean)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "sizeRangeFileFilter", "(long,long)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "trueFileFilter", "()", "generated"] + - ["org.apache.commons.io.filefilter", "IOFileFilter", "and", "(IOFileFilter)", "generated"] + - ["org.apache.commons.io.filefilter", "IOFileFilter", "negate", "()", "generated"] + - ["org.apache.commons.io.filefilter", "IOFileFilter", "or", "(IOFileFilter)", "generated"] + - ["org.apache.commons.io.filefilter", "OrFileFilter", "OrFileFilter", "()", "generated"] + - ["org.apache.commons.io.filefilter", "RegexFileFilter", "RegexFileFilter", "(String)", "generated"] + - ["org.apache.commons.io.filefilter", "RegexFileFilter", "RegexFileFilter", "(String,IOCase)", "generated"] + - ["org.apache.commons.io.filefilter", "RegexFileFilter", "RegexFileFilter", "(String,int)", "generated"] + - ["org.apache.commons.io.filefilter", "SizeFileFilter", "SizeFileFilter", "(long)", "generated"] + - ["org.apache.commons.io.filefilter", "SizeFileFilter", "SizeFileFilter", "(long,boolean)", "generated"] + - ["org.apache.commons.io.filefilter", "SizeFileFilter", "toString", "()", "generated"] + - ["org.apache.commons.io.filefilter", "SymbolicLinkFileFilter", "SymbolicLinkFileFilter", "(FileVisitResult,FileVisitResult)", "generated"] + - ["org.apache.commons.io.filefilter", "TrueFileFilter", "toString", "()", "generated"] + - ["org.apache.commons.io.function", "IOBiConsumer", "accept", "(Object,Object)", "generated"] + - ["org.apache.commons.io.function", "IOBiConsumer", "andThen", "(IOBiConsumer)", "generated"] + - ["org.apache.commons.io.function", "IOBiFunction", "andThen", "(Function)", "generated"] + - ["org.apache.commons.io.function", "IOBiFunction", "andThen", "(IOFunction)", "generated"] + - ["org.apache.commons.io.function", "IOBiFunction", "apply", "(Object,Object)", "generated"] + - ["org.apache.commons.io.function", "IOConsumer", "accept", "(Object)", "generated"] + - ["org.apache.commons.io.function", "IOConsumer", "andThen", "(IOConsumer)", "generated"] + - ["org.apache.commons.io.function", "IOConsumer", "forEach", "(Object[],IOConsumer)", "generated"] + - ["org.apache.commons.io.function", "IOConsumer", "forEachIndexed", "(Stream,IOConsumer)", "generated"] + - ["org.apache.commons.io.function", "IOConsumer", "noop", "()", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "andThen", "(Consumer)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "andThen", "(Function)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "andThen", "(IOConsumer)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "andThen", "(IOFunction)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "apply", "(Object)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "compose", "(Function)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "compose", "(IOFunction)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "compose", "(IOSupplier)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "compose", "(Supplier)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "identity", "()", "generated"] + - ["org.apache.commons.io.function", "IORunnable", "run", "()", "generated"] + - ["org.apache.commons.io.function", "IOSupplier", "get", "()", "generated"] + - ["org.apache.commons.io.function", "IOTriFunction", "andThen", "(Function)", "generated"] + - ["org.apache.commons.io.function", "IOTriFunction", "andThen", "(IOFunction)", "generated"] + - ["org.apache.commons.io.function", "IOTriFunction", "apply", "(Object,Object,Object)", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "CircularByteBuffer", "()", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "CircularByteBuffer", "(int)", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "add", "(byte)", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "add", "(byte[],int,int)", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "clear", "()", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "getCurrentNumberOfBytes", "()", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "getSpace", "()", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "hasBytes", "()", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "hasSpace", "()", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "hasSpace", "(int)", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "peek", "(byte[],int,int)", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "read", "()", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "read", "(byte[],int,int)", "generated"] + - ["org.apache.commons.io.input.buffer", "PeekableInputStream", "peek", "(byte[])", "generated"] + - ["org.apache.commons.io.input.buffer", "PeekableInputStream", "peek", "(byte[],int,int)", "generated"] + - ["org.apache.commons.io.input", "AutoCloseInputStream", "AutoCloseInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "BOMInputStream", "BOMInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "BOMInputStream", "BOMInputStream", "(InputStream,boolean)", "generated"] + - ["org.apache.commons.io.input", "BOMInputStream", "hasBOM", "()", "generated"] + - ["org.apache.commons.io.input", "BOMInputStream", "hasBOM", "(ByteOrderMark)", "generated"] + - ["org.apache.commons.io.input", "BoundedInputStream", "isPropagateClose", "()", "generated"] + - ["org.apache.commons.io.input", "BoundedInputStream", "setPropagateClose", "(boolean)", "generated"] + - ["org.apache.commons.io.input", "BoundedInputStream", "toString", "()", "generated"] + - ["org.apache.commons.io.input", "BrokenInputStream", "BrokenInputStream", "()", "generated"] + - ["org.apache.commons.io.input", "BrokenInputStream", "BrokenInputStream", "(IOException)", "generated"] + - ["org.apache.commons.io.input", "BrokenReader", "BrokenReader", "()", "generated"] + - ["org.apache.commons.io.input", "BrokenReader", "BrokenReader", "(IOException)", "generated"] + - ["org.apache.commons.io.input", "BufferedFileChannelInputStream", "BufferedFileChannelInputStream", "(File)", "generated"] + - ["org.apache.commons.io.input", "BufferedFileChannelInputStream", "BufferedFileChannelInputStream", "(File,int)", "generated"] + - ["org.apache.commons.io.input", "BufferedFileChannelInputStream", "BufferedFileChannelInputStream", "(Path)", "generated"] + - ["org.apache.commons.io.input", "BufferedFileChannelInputStream", "BufferedFileChannelInputStream", "(Path,int)", "generated"] + - ["org.apache.commons.io.input", "CharSequenceInputStream", "CharSequenceInputStream", "(CharSequence,Charset)", "generated"] + - ["org.apache.commons.io.input", "CharSequenceInputStream", "CharSequenceInputStream", "(CharSequence,Charset,int)", "generated"] + - ["org.apache.commons.io.input", "CharSequenceInputStream", "CharSequenceInputStream", "(CharSequence,String)", "generated"] + - ["org.apache.commons.io.input", "CharSequenceInputStream", "CharSequenceInputStream", "(CharSequence,String,int)", "generated"] + - ["org.apache.commons.io.input", "CharacterFilterReader", "CharacterFilterReader", "(Reader,int)", "generated"] + - ["org.apache.commons.io.input", "CharacterSetFilterReader", "CharacterSetFilterReader", "(Reader,Integer[])", "generated"] + - ["org.apache.commons.io.input", "CharacterSetFilterReader", "CharacterSetFilterReader", "(Reader,Set)", "generated"] + - ["org.apache.commons.io.input", "CloseShieldInputStream", "CloseShieldInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "CloseShieldReader", "CloseShieldReader", "(Reader)", "generated"] + - ["org.apache.commons.io.input", "CloseShieldReader", "wrap", "(Reader)", "generated"] + - ["org.apache.commons.io.input", "ClosedInputStream", "ClosedInputStream", "()", "generated"] + - ["org.apache.commons.io.input", "ClosedReader", "ClosedReader", "()", "generated"] + - ["org.apache.commons.io.input", "CountingInputStream", "CountingInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "CountingInputStream", "getByteCount", "()", "generated"] + - ["org.apache.commons.io.input", "CountingInputStream", "getCount", "()", "generated"] + - ["org.apache.commons.io.input", "CountingInputStream", "resetByteCount", "()", "generated"] + - ["org.apache.commons.io.input", "CountingInputStream", "resetCount", "()", "generated"] + - ["org.apache.commons.io.input", "DemuxInputStream", "DemuxInputStream", "()", "generated"] + - ["org.apache.commons.io.input", "DemuxInputStream", "bindStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "MarkShieldInputStream", "MarkShieldInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "MemoryMappedFileInputStream", "MemoryMappedFileInputStream", "(Path)", "generated"] + - ["org.apache.commons.io.input", "MemoryMappedFileInputStream", "MemoryMappedFileInputStream", "(Path,int)", "generated"] + - ["org.apache.commons.io.input", "MessageDigestCalculatingInputStream", "MessageDigestCalculatingInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "MessageDigestCalculatingInputStream", "MessageDigestCalculatingInputStream", "(InputStream,String)", "generated"] + - ["org.apache.commons.io.input", "NullInputStream", "NullInputStream", "()", "generated"] + - ["org.apache.commons.io.input", "NullInputStream", "NullInputStream", "(long)", "generated"] + - ["org.apache.commons.io.input", "NullInputStream", "NullInputStream", "(long,boolean,boolean)", "generated"] + - ["org.apache.commons.io.input", "NullInputStream", "getPosition", "()", "generated"] + - ["org.apache.commons.io.input", "NullInputStream", "getSize", "()", "generated"] + - ["org.apache.commons.io.input", "NullReader", "NullReader", "()", "generated"] + - ["org.apache.commons.io.input", "NullReader", "NullReader", "(long)", "generated"] + - ["org.apache.commons.io.input", "NullReader", "NullReader", "(long,boolean,boolean)", "generated"] + - ["org.apache.commons.io.input", "NullReader", "getPosition", "()", "generated"] + - ["org.apache.commons.io.input", "NullReader", "getSize", "()", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream$Observer", "Observer", "()", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream$Observer", "closed", "()", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream$Observer", "data", "(byte[],int,int)", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream$Observer", "data", "(int)", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream$Observer", "error", "(IOException)", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream$Observer", "finished", "()", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream", "ObservableInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream", "consume", "()", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream", "remove", "(Observer)", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream", "removeAllObservers", "()", "generated"] + - ["org.apache.commons.io.input", "ProxyInputStream", "ProxyInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "ProxyReader", "ProxyReader", "(Reader)", "generated"] + - ["org.apache.commons.io.input", "QueueInputStream", "QueueInputStream", "()", "generated"] + - ["org.apache.commons.io.input", "QueueInputStream", "QueueInputStream", "(BlockingQueue)", "generated"] + - ["org.apache.commons.io.input", "QueueInputStream", "newQueueOutputStream", "()", "generated"] + - ["org.apache.commons.io.input", "RandomAccessFileInputStream", "availableLong", "()", "generated"] + - ["org.apache.commons.io.input", "RandomAccessFileInputStream", "isCloseOnClose", "()", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", "ReversedLinesFileReader", "(File)", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", "ReversedLinesFileReader", "(File,Charset)", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", "ReversedLinesFileReader", "(File,int,Charset)", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", "ReversedLinesFileReader", "(File,int,String)", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", "ReversedLinesFileReader", "(Path,Charset)", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", "ReversedLinesFileReader", "(Path,int,Charset)", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", "ReversedLinesFileReader", "(Path,int,String)", "generated"] + - ["org.apache.commons.io.input", "SwappedDataInputStream", "SwappedDataInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "TaggedInputStream", "TaggedInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "TaggedInputStream", "isCauseOf", "(Throwable)", "generated"] + - ["org.apache.commons.io.input", "TaggedInputStream", "throwIfCauseOf", "(Throwable)", "generated"] + - ["org.apache.commons.io.input", "TaggedReader", "TaggedReader", "(Reader)", "generated"] + - ["org.apache.commons.io.input", "TaggedReader", "isCauseOf", "(Throwable)", "generated"] + - ["org.apache.commons.io.input", "TaggedReader", "throwIfCauseOf", "(Throwable)", "generated"] + - ["org.apache.commons.io.input", "Tailer$RandomAccessResourceBridge", "getPointer", "()", "generated"] + - ["org.apache.commons.io.input", "Tailer$RandomAccessResourceBridge", "read", "(byte[])", "generated"] + - ["org.apache.commons.io.input", "Tailer$RandomAccessResourceBridge", "seek", "(long)", "generated"] + - ["org.apache.commons.io.input", "Tailer$Tailable", "getRandomAccess", "(String)", "generated"] + - ["org.apache.commons.io.input", "Tailer$Tailable", "isNewer", "(FileTime)", "generated"] + - ["org.apache.commons.io.input", "Tailer$Tailable", "lastModifiedFileTime", "()", "generated"] + - ["org.apache.commons.io.input", "Tailer$Tailable", "size", "()", "generated"] + - ["org.apache.commons.io.input", "Tailer", "getDelay", "()", "generated"] + - ["org.apache.commons.io.input", "Tailer", "stop", "()", "generated"] + - ["org.apache.commons.io.input", "TailerListener", "fileNotFound", "()", "generated"] + - ["org.apache.commons.io.input", "TailerListener", "fileRotated", "()", "generated"] + - ["org.apache.commons.io.input", "TailerListener", "handle", "(Exception)", "generated"] + - ["org.apache.commons.io.input", "TailerListener", "handle", "(String)", "generated"] + - ["org.apache.commons.io.input", "TailerListener", "init", "(Tailer)", "generated"] + - ["org.apache.commons.io.input", "TailerListenerAdapter", "TailerListenerAdapter", "()", "generated"] + - ["org.apache.commons.io.input", "TailerListenerAdapter", "endOfFileReached", "()", "generated"] + - ["org.apache.commons.io.input", "TimestampedObserver", "TimestampedObserver", "()", "generated"] + - ["org.apache.commons.io.input", "TimestampedObserver", "getOpenToCloseDuration", "()", "generated"] + - ["org.apache.commons.io.input", "TimestampedObserver", "getOpenToNowDuration", "()", "generated"] + - ["org.apache.commons.io.input", "UncheckedFilterInputStream", "UncheckedFilterInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "UncheckedFilterReader", "UncheckedFilterReader", "(Reader)", "generated"] + - ["org.apache.commons.io.input", "UncheckedFilterReader", "on", "(Reader)", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", "XmlStreamReader", "(File)", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", "XmlStreamReader", "(Path)", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", "XmlStreamReader", "(URL)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListener", "onDirectoryChange", "(File)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListener", "onDirectoryCreate", "(File)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListener", "onDirectoryDelete", "(File)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListener", "onFileChange", "(File)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListener", "onFileCreate", "(File)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListener", "onFileDelete", "(File)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListener", "onStart", "(FileAlterationObserver)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListener", "onStop", "(FileAlterationObserver)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListenerAdaptor", "FileAlterationListenerAdaptor", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", "FileAlterationMonitor", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", "FileAlterationMonitor", "(long)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", "getInterval", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", "removeObserver", "(FileAlterationObserver)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", "start", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", "stop", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", "stop", "(long)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", "checkAndNotify", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", "destroy", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", "initialize", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", "removeListener", "(FileAlterationListener)", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "getLastModified", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "getLength", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "getLevel", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "isDirectory", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "isExists", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "refresh", "(File)", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "setDirectory", "(boolean)", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "setExists", "(boolean)", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "setLastModified", "(long)", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "setLength", "(long)", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", "AbstractByteArrayOutputStream", "()", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", "reset", "()", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", "size", "()", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", "toByteArray", "()", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", "toInputStream", "()", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", "write", "(InputStream)", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", "writeTo", "(OutputStream)", "generated"] + - ["org.apache.commons.io.output", "BrokenOutputStream", "BrokenOutputStream", "()", "generated"] + - ["org.apache.commons.io.output", "BrokenOutputStream", "BrokenOutputStream", "(IOException)", "generated"] + - ["org.apache.commons.io.output", "BrokenWriter", "BrokenWriter", "()", "generated"] + - ["org.apache.commons.io.output", "BrokenWriter", "BrokenWriter", "(IOException)", "generated"] + - ["org.apache.commons.io.output", "ByteArrayOutputStream", "ByteArrayOutputStream", "()", "generated"] + - ["org.apache.commons.io.output", "ByteArrayOutputStream", "ByteArrayOutputStream", "(int)", "generated"] + - ["org.apache.commons.io.output", "ByteArrayOutputStream", "toBufferedInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.output", "ByteArrayOutputStream", "toBufferedInputStream", "(InputStream,int)", "generated"] + - ["org.apache.commons.io.output", "ChunkedWriter", "ChunkedWriter", "(Writer)", "generated"] + - ["org.apache.commons.io.output", "ChunkedWriter", "ChunkedWriter", "(Writer,int)", "generated"] + - ["org.apache.commons.io.output", "CloseShieldWriter", "CloseShieldWriter", "(Writer)", "generated"] + - ["org.apache.commons.io.output", "CloseShieldWriter", "wrap", "(Writer)", "generated"] + - ["org.apache.commons.io.output", "ClosedOutputStream", "ClosedOutputStream", "()", "generated"] + - ["org.apache.commons.io.output", "ClosedWriter", "ClosedWriter", "()", "generated"] + - ["org.apache.commons.io.output", "CountingOutputStream", "getByteCount", "()", "generated"] + - ["org.apache.commons.io.output", "CountingOutputStream", "getCount", "()", "generated"] + - ["org.apache.commons.io.output", "CountingOutputStream", "resetByteCount", "()", "generated"] + - ["org.apache.commons.io.output", "CountingOutputStream", "resetCount", "()", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", "isInMemory", "()", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", "toInputStream", "()", "generated"] + - ["org.apache.commons.io.output", "DemuxOutputStream", "DemuxOutputStream", "()", "generated"] + - ["org.apache.commons.io.output", "DemuxOutputStream", "bindStream", "(OutputStream)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(File,Charset)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(File,Charset,boolean)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(File,CharsetEncoder)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(File,CharsetEncoder,boolean)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(File,String)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(File,String,boolean)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(String,Charset)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(String,Charset,boolean)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(String,CharsetEncoder)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(String,CharsetEncoder,boolean)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(String,String)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(String,String,boolean)", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", "LockableFileWriter", "(File)", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", "LockableFileWriter", "(File,Charset)", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", "LockableFileWriter", "(File,String)", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", "LockableFileWriter", "(File,boolean)", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", "LockableFileWriter", "(String)", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", "LockableFileWriter", "(String,boolean)", "generated"] + - ["org.apache.commons.io.output", "NullOutputStream", "NullOutputStream", "()", "generated"] + - ["org.apache.commons.io.output", "NullPrintStream", "NullPrintStream", "()", "generated"] + - ["org.apache.commons.io.output", "NullWriter", "NullWriter", "()", "generated"] + - ["org.apache.commons.io.output", "ProxyWriter", "ProxyWriter", "(Writer)", "generated"] + - ["org.apache.commons.io.output", "QueueOutputStream", "QueueOutputStream", "()", "generated"] + - ["org.apache.commons.io.output", "QueueOutputStream", "QueueOutputStream", "(BlockingQueue)", "generated"] + - ["org.apache.commons.io.output", "QueueOutputStream", "newQueueInputStream", "()", "generated"] + - ["org.apache.commons.io.output", "StringBuilderWriter", "StringBuilderWriter", "()", "generated"] + - ["org.apache.commons.io.output", "StringBuilderWriter", "StringBuilderWriter", "(int)", "generated"] + - ["org.apache.commons.io.output", "TaggedOutputStream", "isCauseOf", "(Exception)", "generated"] + - ["org.apache.commons.io.output", "TaggedOutputStream", "throwIfCauseOf", "(Exception)", "generated"] + - ["org.apache.commons.io.output", "TaggedWriter", "TaggedWriter", "(Writer)", "generated"] + - ["org.apache.commons.io.output", "TaggedWriter", "isCauseOf", "(Exception)", "generated"] + - ["org.apache.commons.io.output", "TaggedWriter", "throwIfCauseOf", "(Exception)", "generated"] + - ["org.apache.commons.io.output", "ThresholdingOutputStream", "ThresholdingOutputStream", "(int)", "generated"] + - ["org.apache.commons.io.output", "ThresholdingOutputStream", "getByteCount", "()", "generated"] + - ["org.apache.commons.io.output", "ThresholdingOutputStream", "getThreshold", "()", "generated"] + - ["org.apache.commons.io.output", "ThresholdingOutputStream", "isThresholdExceeded", "()", "generated"] + - ["org.apache.commons.io.output", "UncheckedFilterWriter", "on", "(Writer)", "generated"] + - ["org.apache.commons.io.output", "UnsynchronizedByteArrayOutputStream", "UnsynchronizedByteArrayOutputStream", "()", "generated"] + - ["org.apache.commons.io.output", "UnsynchronizedByteArrayOutputStream", "UnsynchronizedByteArrayOutputStream", "(int)", "generated"] + - ["org.apache.commons.io.output", "UnsynchronizedByteArrayOutputStream", "toBufferedInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.output", "UnsynchronizedByteArrayOutputStream", "toBufferedInputStream", "(InputStream,int)", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", "XmlStreamWriter", "(File)", "generated"] + - ["org.apache.commons.io.serialization", "ClassNameMatcher", "matches", "(String)", "generated"] + - ["org.apache.commons.io", "ByteOrderMark", "get", "(int)", "generated"] + - ["org.apache.commons.io", "ByteOrderMark", "getBytes", "()", "generated"] + - ["org.apache.commons.io", "ByteOrderMark", "length", "()", "generated"] + - ["org.apache.commons.io", "ByteOrderParser", "parseByteOrder", "(String)", "generated"] + - ["org.apache.commons.io", "Charsets", "Charsets", "()", "generated"] + - ["org.apache.commons.io", "Charsets", "requiredCharsets", "()", "generated"] + - ["org.apache.commons.io", "Charsets", "toCharset", "(Charset)", "generated"] + - ["org.apache.commons.io", "Charsets", "toCharset", "(String)", "generated"] + - ["org.apache.commons.io", "CopyUtils", "CopyUtils", "()", "generated"] + - ["org.apache.commons.io", "CopyUtils", "copy", "(Reader,OutputStream)", "generated"] + - ["org.apache.commons.io", "CopyUtils", "copy", "(Reader,OutputStream,String)", "generated"] + - ["org.apache.commons.io", "CopyUtils", "copy", "(String,OutputStream)", "generated"] + - ["org.apache.commons.io", "CopyUtils", "copy", "(String,OutputStream,String)", "generated"] + - ["org.apache.commons.io", "DirectoryWalker$CancelException", "getDepth", "()", "generated"] + - ["org.apache.commons.io", "EndianUtils", "EndianUtils", "()", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedDouble", "(InputStream)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedDouble", "(byte[],int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedFloat", "(InputStream)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedFloat", "(byte[],int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedInteger", "(InputStream)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedInteger", "(byte[],int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedLong", "(InputStream)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedLong", "(byte[],int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedShort", "(InputStream)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedShort", "(byte[],int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedUnsignedInteger", "(InputStream)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedUnsignedInteger", "(byte[],int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedUnsignedShort", "(InputStream)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedUnsignedShort", "(byte[],int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "swapDouble", "(double)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "swapFloat", "(float)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "swapInteger", "(int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "swapLong", "(long)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "swapShort", "(short)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedDouble", "(OutputStream,double)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedDouble", "(byte[],int,double)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedFloat", "(OutputStream,float)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedFloat", "(byte[],int,float)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedInteger", "(OutputStream,int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedInteger", "(byte[],int,int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedLong", "(OutputStream,long)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedLong", "(byte[],int,long)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedShort", "(OutputStream,short)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedShort", "(byte[],int,short)", "generated"] + - ["org.apache.commons.io", "FileCleaner", "FileCleaner", "()", "generated"] + - ["org.apache.commons.io", "FileCleaner", "exitWhenFinished", "()", "generated"] + - ["org.apache.commons.io", "FileCleaner", "getInstance", "()", "generated"] + - ["org.apache.commons.io", "FileCleaner", "getTrackCount", "()", "generated"] + - ["org.apache.commons.io", "FileCleaner", "track", "(File,Object)", "generated"] + - ["org.apache.commons.io", "FileCleaner", "track", "(File,Object,FileDeleteStrategy)", "generated"] + - ["org.apache.commons.io", "FileCleaner", "track", "(String,Object)", "generated"] + - ["org.apache.commons.io", "FileCleaner", "track", "(String,Object,FileDeleteStrategy)", "generated"] + - ["org.apache.commons.io", "FileCleaningTracker", "FileCleaningTracker", "()", "generated"] + - ["org.apache.commons.io", "FileCleaningTracker", "exitWhenFinished", "()", "generated"] + - ["org.apache.commons.io", "FileCleaningTracker", "getTrackCount", "()", "generated"] + - ["org.apache.commons.io", "FileCleaningTracker", "track", "(File,Object)", "generated"] + - ["org.apache.commons.io", "FileCleaningTracker", "track", "(File,Object,FileDeleteStrategy)", "generated"] + - ["org.apache.commons.io", "FileCleaningTracker", "track", "(String,Object)", "generated"] + - ["org.apache.commons.io", "FileCleaningTracker", "track", "(String,Object,FileDeleteStrategy)", "generated"] + - ["org.apache.commons.io", "FileDeleteStrategy", "delete", "(File)", "generated"] + - ["org.apache.commons.io", "FileDeleteStrategy", "deleteQuietly", "(File)", "generated"] + - ["org.apache.commons.io", "FileExistsException", "FileExistsException", "()", "generated"] + - ["org.apache.commons.io", "FileExistsException", "FileExistsException", "(File)", "generated"] + - ["org.apache.commons.io", "FileExistsException", "FileExistsException", "(String)", "generated"] + - ["org.apache.commons.io", "FileSystem", "getCurrent", "()", "generated"] + - ["org.apache.commons.io", "FileSystem", "getIllegalFileNameChars", "()", "generated"] + - ["org.apache.commons.io", "FileSystem", "getMaxFileNameLength", "()", "generated"] + - ["org.apache.commons.io", "FileSystem", "getMaxPathLength", "()", "generated"] + - ["org.apache.commons.io", "FileSystem", "getNameSeparator", "()", "generated"] + - ["org.apache.commons.io", "FileSystem", "getReservedFileNames", "()", "generated"] + - ["org.apache.commons.io", "FileSystem", "isCasePreserving", "()", "generated"] + - ["org.apache.commons.io", "FileSystem", "isCaseSensitive", "()", "generated"] + - ["org.apache.commons.io", "FileSystem", "isLegalFileName", "(CharSequence)", "generated"] + - ["org.apache.commons.io", "FileSystem", "isReservedFileName", "(CharSequence)", "generated"] + - ["org.apache.commons.io", "FileSystem", "supportsDriveLetter", "()", "generated"] + - ["org.apache.commons.io", "FileSystemUtils", "FileSystemUtils", "()", "generated"] + - ["org.apache.commons.io", "FileSystemUtils", "freeSpace", "(String)", "generated"] + - ["org.apache.commons.io", "FileSystemUtils", "freeSpaceKb", "()", "generated"] + - ["org.apache.commons.io", "FileSystemUtils", "freeSpaceKb", "(String)", "generated"] + - ["org.apache.commons.io", "FileSystemUtils", "freeSpaceKb", "(String,long)", "generated"] + - ["org.apache.commons.io", "FileSystemUtils", "freeSpaceKb", "(long)", "generated"] + - ["org.apache.commons.io", "FileUtils", "FileUtils", "()", "generated"] + - ["org.apache.commons.io", "FileUtils", "byteCountToDisplaySize", "(BigInteger)", "generated"] + - ["org.apache.commons.io", "FileUtils", "byteCountToDisplaySize", "(Number)", "generated"] + - ["org.apache.commons.io", "FileUtils", "byteCountToDisplaySize", "(long)", "generated"] + - ["org.apache.commons.io", "FileUtils", "checksumCRC32", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "cleanDirectory", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "contentEquals", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "contentEqualsIgnoreEOL", "(File,File,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyDirectory", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyDirectory", "(File,File,FileFilter)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyDirectory", "(File,File,FileFilter,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyDirectory", "(File,File,FileFilter,boolean,CopyOption[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyDirectory", "(File,File,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyDirectoryToDirectory", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyFile", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyFile", "(File,File,CopyOption[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyFile", "(File,File,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyFile", "(File,File,boolean,CopyOption[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyFile", "(File,OutputStream)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyFileToDirectory", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyFileToDirectory", "(File,File,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyInputStreamToFile", "(InputStream,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyToDirectory", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyToDirectory", "(Iterable,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyToFile", "(InputStream,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyURLToFile", "(URL,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyURLToFile", "(URL,File,int,int)", "generated"] + - ["org.apache.commons.io", "FileUtils", "createParentDirectories", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "current", "()", "generated"] + - ["org.apache.commons.io", "FileUtils", "deleteDirectory", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "deleteQuietly", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "directoryContains", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "forceDelete", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "forceDeleteOnExit", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "forceMkdir", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "forceMkdirParent", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "getTempDirectory", "()", "generated"] + - ["org.apache.commons.io", "FileUtils", "getTempDirectoryPath", "()", "generated"] + - ["org.apache.commons.io", "FileUtils", "getUserDirectory", "()", "generated"] + - ["org.apache.commons.io", "FileUtils", "getUserDirectoryPath", "()", "generated"] + - ["org.apache.commons.io", "FileUtils", "isDirectory", "(File,LinkOption[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "isEmptyDirectory", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,ChronoLocalDate)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,ChronoLocalDate,LocalTime)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,ChronoLocalDateTime)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,ChronoLocalDateTime,ZoneId)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,ChronoZonedDateTime)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,Date)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,FileTime)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,Instant)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,long)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,ChronoLocalDate)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,ChronoLocalDate,LocalTime)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,ChronoLocalDateTime)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,ChronoLocalDateTime,ZoneId)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,ChronoZonedDateTime)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,Date)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,FileTime)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,Instant)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,long)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isRegularFile", "(File,LinkOption[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "isSymlink", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "iterateFiles", "(File,IOFileFilter,IOFileFilter)", "generated"] + - ["org.apache.commons.io", "FileUtils", "iterateFiles", "(File,String[],boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "iterateFilesAndDirs", "(File,IOFileFilter,IOFileFilter)", "generated"] + - ["org.apache.commons.io", "FileUtils", "lastModified", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "lastModifiedFileTime", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "lastModifiedUnchecked", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "lineIterator", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "lineIterator", "(File,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "listFiles", "(File,IOFileFilter,IOFileFilter)", "generated"] + - ["org.apache.commons.io", "FileUtils", "listFiles", "(File,String[],boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "listFilesAndDirs", "(File,IOFileFilter,IOFileFilter)", "generated"] + - ["org.apache.commons.io", "FileUtils", "moveDirectory", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "moveDirectoryToDirectory", "(File,File,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "moveFile", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "moveFile", "(File,File,CopyOption[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "moveFileToDirectory", "(File,File,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "moveToDirectory", "(File,File,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "newOutputStream", "(File,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "openInputStream", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "openOutputStream", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "openOutputStream", "(File,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "readFileToByteArray", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "readFileToString", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "readFileToString", "(File,Charset)", "generated"] + - ["org.apache.commons.io", "FileUtils", "readFileToString", "(File,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "readLines", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "readLines", "(File,Charset)", "generated"] + - ["org.apache.commons.io", "FileUtils", "readLines", "(File,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "sizeOf", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "sizeOfAsBigInteger", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "sizeOfDirectory", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "sizeOfDirectoryAsBigInteger", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "streamFiles", "(File,boolean,String[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "toFile", "(URL)", "generated"] + - ["org.apache.commons.io", "FileUtils", "toFiles", "(URL[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "touch", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "waitFor", "(File,int)", "generated"] + - ["org.apache.commons.io", "FileUtils", "write", "(File,CharSequence)", "generated"] + - ["org.apache.commons.io", "FileUtils", "write", "(File,CharSequence,Charset)", "generated"] + - ["org.apache.commons.io", "FileUtils", "write", "(File,CharSequence,Charset,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "write", "(File,CharSequence,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "write", "(File,CharSequence,String,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "write", "(File,CharSequence,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeByteArrayToFile", "(File,byte[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeByteArrayToFile", "(File,byte[],boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeByteArrayToFile", "(File,byte[],int,int)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeByteArrayToFile", "(File,byte[],int,int,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeLines", "(File,Collection)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeLines", "(File,Collection,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeLines", "(File,Collection,String,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeLines", "(File,Collection,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeLines", "(File,String,Collection)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeLines", "(File,String,Collection,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeLines", "(File,String,Collection,String,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeLines", "(File,String,Collection,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeStringToFile", "(File,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeStringToFile", "(File,String,Charset)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeStringToFile", "(File,String,Charset,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeStringToFile", "(File,String,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeStringToFile", "(File,String,String,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeStringToFile", "(File,String,boolean)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "FilenameUtils", "()", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "directoryContains", "(String,String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "equals", "(String,String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "equals", "(String,String,boolean,IOCase)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "equalsNormalized", "(String,String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "equalsNormalizedOnSystem", "(String,String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "equalsOnSystem", "(String,String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "getPrefixLength", "(String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "indexOfExtension", "(String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "indexOfLastSeparator", "(String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "isExtension", "(String,Collection)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "isExtension", "(String,String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "isExtension", "(String,String[])", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "wildcardMatch", "(String,String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "wildcardMatch", "(String,String,IOCase)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "wildcardMatchOnSystem", "(String,String)", "generated"] + - ["org.apache.commons.io", "HexDump", "HexDump", "()", "generated"] + - ["org.apache.commons.io", "HexDump", "dump", "(byte[],long,OutputStream,int)", "generated"] + - ["org.apache.commons.io", "IOCase", "checkCompareTo", "(String,String)", "generated"] + - ["org.apache.commons.io", "IOCase", "checkEndsWith", "(String,String)", "generated"] + - ["org.apache.commons.io", "IOCase", "checkEquals", "(String,String)", "generated"] + - ["org.apache.commons.io", "IOCase", "checkIndexOf", "(String,int,String)", "generated"] + - ["org.apache.commons.io", "IOCase", "checkRegionMatches", "(String,int,String)", "generated"] + - ["org.apache.commons.io", "IOCase", "checkStartsWith", "(String,String)", "generated"] + - ["org.apache.commons.io", "IOCase", "forName", "(String)", "generated"] + - ["org.apache.commons.io", "IOCase", "getName", "()", "generated"] + - ["org.apache.commons.io", "IOCase", "isCaseSensitive", "()", "generated"] + - ["org.apache.commons.io", "IOCase", "isCaseSensitive", "(IOCase)", "generated"] + - ["org.apache.commons.io", "IOCase", "toString", "()", "generated"] + - ["org.apache.commons.io", "IOCase", "value", "(IOCase,IOCase)", "generated"] + - ["org.apache.commons.io", "IOExceptionList", "checkEmpty", "(List,Object)", "generated"] + - ["org.apache.commons.io", "IOExceptionList", "getCause", "(int,Class)", "generated"] + - ["org.apache.commons.io", "IOExceptionWithCause", "IOExceptionWithCause", "(String,Throwable)", "generated"] + - ["org.apache.commons.io", "IOExceptionWithCause", "IOExceptionWithCause", "(Throwable)", "generated"] + - ["org.apache.commons.io", "IOIndexedException", "IOIndexedException", "(int,Throwable)", "generated"] + - ["org.apache.commons.io", "IOIndexedException", "getIndex", "()", "generated"] + - ["org.apache.commons.io", "IOUtils", "IOUtils", "()", "generated"] + - ["org.apache.commons.io", "IOUtils", "byteArray", "()", "generated"] + - ["org.apache.commons.io", "IOUtils", "byteArray", "(int)", "generated"] + - ["org.apache.commons.io", "IOUtils", "close", "(Closeable)", "generated"] + - ["org.apache.commons.io", "IOUtils", "close", "(Closeable,IOConsumer)", "generated"] + - ["org.apache.commons.io", "IOUtils", "close", "(Closeable[])", "generated"] + - ["org.apache.commons.io", "IOUtils", "close", "(URLConnection)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(Closeable)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(Closeable,Consumer)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(Closeable[])", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(InputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(OutputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(Reader)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(Selector)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(ServerSocket)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(Socket)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(Writer)", "generated"] + - ["org.apache.commons.io", "IOUtils", "consume", "(InputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "contentEquals", "(InputStream,InputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "contentEquals", "(Reader,Reader)", "generated"] + - ["org.apache.commons.io", "IOUtils", "contentEqualsIgnoreEOL", "(Reader,Reader)", "generated"] + - ["org.apache.commons.io", "IOUtils", "copy", "(ByteArrayOutputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "copy", "(Reader,OutputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "copy", "(Reader,OutputStream,Charset)", "generated"] + - ["org.apache.commons.io", "IOUtils", "copy", "(Reader,OutputStream,String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "copy", "(URL,File)", "generated"] + - ["org.apache.commons.io", "IOUtils", "copy", "(URL,OutputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "length", "(CharSequence)", "generated"] + - ["org.apache.commons.io", "IOUtils", "length", "(Object[])", "generated"] + - ["org.apache.commons.io", "IOUtils", "length", "(byte[])", "generated"] + - ["org.apache.commons.io", "IOUtils", "length", "(char[])", "generated"] + - ["org.apache.commons.io", "IOUtils", "resourceToByteArray", "(String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "resourceToByteArray", "(String,ClassLoader)", "generated"] + - ["org.apache.commons.io", "IOUtils", "resourceToString", "(String,Charset)", "generated"] + - ["org.apache.commons.io", "IOUtils", "resourceToString", "(String,Charset,ClassLoader)", "generated"] + - ["org.apache.commons.io", "IOUtils", "resourceToURL", "(String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "resourceToURL", "(String,ClassLoader)", "generated"] + - ["org.apache.commons.io", "IOUtils", "skip", "(InputStream,long)", "generated"] + - ["org.apache.commons.io", "IOUtils", "skip", "(ReadableByteChannel,long)", "generated"] + - ["org.apache.commons.io", "IOUtils", "skip", "(Reader,long)", "generated"] + - ["org.apache.commons.io", "IOUtils", "skipFully", "(InputStream,long)", "generated"] + - ["org.apache.commons.io", "IOUtils", "skipFully", "(ReadableByteChannel,long)", "generated"] + - ["org.apache.commons.io", "IOUtils", "skipFully", "(Reader,long)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toBufferedInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toBufferedInputStream", "(InputStream,int)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toByteArray", "(InputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toByteArray", "(Reader)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toByteArray", "(Reader,Charset)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toByteArray", "(Reader,String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toByteArray", "(URI)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toByteArray", "(URL)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toByteArray", "(URLConnection)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toString", "(URI)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toString", "(URI,Charset)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toString", "(URI,String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toString", "(URL)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toString", "(URL,Charset)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toString", "(URL,String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(CharSequence,OutputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(CharSequence,OutputStream,Charset)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(CharSequence,OutputStream,String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(String,OutputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(String,OutputStream,Charset)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(String,OutputStream,String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(StringBuffer,OutputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(StringBuffer,OutputStream,String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(char[],OutputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(char[],OutputStream,Charset)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(char[],OutputStream,String)", "generated"] + - ["org.apache.commons.io", "LineIterator", "closeQuietly", "(LineIterator)", "generated"] + - ["org.apache.commons.io", "RandomAccessFileMode", "create", "(File)", "generated"] + - ["org.apache.commons.io", "RandomAccessFileMode", "create", "(Path)", "generated"] + - ["org.apache.commons.io", "RandomAccessFileMode", "create", "(String)", "generated"] + - ["org.apache.commons.io", "RandomAccessFileMode", "toString", "()", "generated"] + - ["org.apache.commons.io", "StandardLineSeparator", "getBytes", "(Charset)", "generated"] + - ["org.apache.commons.io", "StandardLineSeparator", "getString", "()", "generated"] + - ["org.apache.commons.io", "TaggedIOException", "isTaggedWith", "(Throwable,Object)", "generated"] + - ["org.apache.commons.io", "TaggedIOException", "throwCauseIfTaggedWith", "(Throwable,Object)", "generated"] + - ["org.apache.commons.io", "UncheckedIO", "UncheckedIO", "()", "generated"] + - ["org.apache.commons.io", "UncheckedIO", "accept", "(IOConsumer,Object)", "generated"] + - ["org.apache.commons.io", "UncheckedIO", "apply", "(IOBiFunction,Object,Object)", "generated"] + - ["org.apache.commons.io", "UncheckedIO", "get", "(IOSupplier)", "generated"] + - ["org.apache.commons.io", "UncheckedIO", "run", "(IORunnable)", "generated"] + - ["org.apache.commons.io", "UncheckedIOExceptions", "UncheckedIOExceptions", "()", "generated"] + - ["org.apache.commons.io", "UncheckedIOExceptions", "create", "(Object)", "generated"] + - ["org.apache.commons.io", "UncheckedIOExceptions", "wrap", "(IOException,Object)", "generated"] + + \ No newline at end of file diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/NegativeSummary.qll b/java/ql/lib/semmle/code/java/dataflow/internal/NegativeSummary.qll deleted file mode 100644 index e7b6b7b8838..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/NegativeSummary.qll +++ /dev/null @@ -1,9 +0,0 @@ -/** Provides modules for importing negative summaries. */ - -/** - * A module importing the frameworks that provide external flow data, - * ensuring that they are visible to the taint tracking / data flow library. - */ -private module Frameworks { - private import semmle.code.java.frameworks.GeneratedNegative -} diff --git a/java/ql/lib/semmle/code/java/frameworks/GeneratedNegative.qll b/java/ql/lib/semmle/code/java/frameworks/GeneratedNegative.qll deleted file mode 100644 index c12c6c3be16..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/GeneratedNegative.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** Provides a module for importing negative models. */ - -/** - * A module importing all generated negative Models as Data models. - */ -private module GeneratedFrameworks { - private import apache.NegativeIOGenerated -} diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/IOGenerated.qll b/java/ql/lib/semmle/code/java/frameworks/apache/IOGenerated.qll deleted file mode 100644 index db1ed1bea58..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/apache/IOGenerated.qll +++ /dev/null @@ -1,684 +0,0 @@ -/** - * THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. - * Definitions of taint steps in the IOGenerated framework. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class IOGeneratedSinksCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.commons.io.file;PathFilter;true;accept;(Path,BasicFileAttributes);;Argument[0];create-file;generated", - "org.apache.commons.io.file;PathUtils;false;copyFile;(URL,Path,CopyOption[]);;Argument[0];open-url;generated", - "org.apache.commons.io.file;PathUtils;false;copyFile;(URL,Path,CopyOption[]);;Argument[1];create-file;generated", - "org.apache.commons.io.file;PathUtils;false;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[1];create-file;generated", - "org.apache.commons.io.file;PathUtils;false;copyFileToDirectory;(URL,Path,CopyOption[]);;Argument[0];open-url;generated", - "org.apache.commons.io.file;PathUtils;false;copyFileToDirectory;(URL,Path,CopyOption[]);;Argument[1];create-file;generated", - "org.apache.commons.io.file;PathUtils;false;newOutputStream;(Path,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.file;PathUtils;false;writeString;(Path,CharSequence,Charset,OpenOption[]);;Argument[0];create-file;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;filter;(IOFileFilter,File[]);;Argument[1];create-file;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;filterList;(IOFileFilter,File[]);;Argument[1];create-file;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;filterSet;(IOFileFilter,File[]);;Argument[1];create-file;generated", - "org.apache.commons.io.input;Tailer$Tailable;true;getRandomAccess;(String);;Argument[-1];create-file;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(URL);;Argument[0];open-url;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;writeTo;(OutputStream);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(File,Charset);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(File,Charset,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(File,CharsetEncoder);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(File,CharsetEncoder,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(File,String);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(File,String,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(String,Charset);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(String,Charset,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(String,CharsetEncoder);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(String,CharsetEncoder,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(String,String);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(String,String,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,Charset);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,Charset,boolean,String);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,String);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,String,boolean,String);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,boolean,String);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(String);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(String,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(String,boolean,String);;Argument[0];create-file;generated", - "org.apache.commons.io.output;XmlStreamWriter;true;XmlStreamWriter;(File);;Argument[0];create-file;generated", - "org.apache.commons.io.output;XmlStreamWriter;true;XmlStreamWriter;(File,String);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyDirectory;(File,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyDirectory;(File,File,FileFilter);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyDirectory;(File,File,FileFilter,boolean);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyDirectory;(File,File,FileFilter,boolean,CopyOption[]);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyDirectory;(File,File,boolean);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyDirectoryToDirectory;(File,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyFile;(File,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyFile;(File,File,CopyOption[]);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyFile;(File,File,boolean);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyFile;(File,File,boolean,CopyOption[]);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyFileToDirectory;(File,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyFileToDirectory;(File,File,boolean);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyInputStreamToFile;(InputStream,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyToDirectory;(File,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyToDirectory;(Iterable,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyToFile;(InputStream,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyURLToFile;(URL,File);;Argument[0];open-url;generated", - "org.apache.commons.io;FileUtils;true;copyURLToFile;(URL,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyURLToFile;(URL,File,int,int);;Argument[0];open-url;generated", - "org.apache.commons.io;FileUtils;true;copyURLToFile;(URL,File,int,int);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;moveDirectory;(File,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;moveDirectoryToDirectory;(File,File,boolean);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;moveFile;(File,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;moveFile;(File,File,CopyOption[]);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;moveFileToDirectory;(File,File,boolean);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;moveToDirectory;(File,File,boolean);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;newOutputStream;(File,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;openOutputStream;(File);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;openOutputStream;(File,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;touch;(File);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;write;(File,CharSequence);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;write;(File,CharSequence,Charset);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;write;(File,CharSequence,Charset,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;write;(File,CharSequence,String);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;write;(File,CharSequence,String,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;write;(File,CharSequence,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeByteArrayToFile;(File,byte[]);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeByteArrayToFile;(File,byte[],boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeByteArrayToFile;(File,byte[],int,int);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeByteArrayToFile;(File,byte[],int,int,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeLines;(File,Collection);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeLines;(File,Collection,String);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeLines;(File,Collection,String,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeLines;(File,Collection,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeLines;(File,String,Collection);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeLines;(File,String,Collection,String);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeLines;(File,String,Collection,String,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeLines;(File,String,Collection,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeStringToFile;(File,String);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeStringToFile;(File,String,Charset);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeStringToFile;(File,String,Charset,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeStringToFile;(File,String,String);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeStringToFile;(File,String,String,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeStringToFile;(File,String,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;IOUtils;true;copy;(URL,File);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;copy;(URL,File);;Argument[1];create-file;generated", - "org.apache.commons.io;IOUtils;true;copy;(URL,OutputStream);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;toByteArray;(URI);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;toByteArray;(URL);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;toString;(URI);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;toString;(URI,Charset);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;toString;(URI,String);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;toString;(URL);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;toString;(URL,Charset);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;toString;(URL,String);;Argument[0];open-url;generated", - "org.apache.commons.io;RandomAccessFileMode;false;create;(File);;Argument[0];create-file;generated", - "org.apache.commons.io;RandomAccessFileMode;false;create;(Path);;Argument[0];create-file;generated", - "org.apache.commons.io;RandomAccessFileMode;false;create;(String);;Argument[0];create-file;generated" - ] - } -} - -private class IOGeneratedSummaryCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.commons.io.charset;CharsetDecoders;true;toCharsetDecoder;(CharsetDecoder);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.charset;CharsetEncoders;true;toCharsetEncoder;(CharsetEncoder);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.comparator;CompositeFileComparator;true;CompositeFileComparator;(Comparator[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.comparator;CompositeFileComparator;true;CompositeFileComparator;(Iterable);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.comparator;CompositeFileComparator;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file.spi;FileSystemProviders;true;getFileSystemProvider;(String);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file.spi;FileSystemProviders;true;getFileSystemProvider;(URI);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file.spi;FileSystemProviders;true;getFileSystemProvider;(URL);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;AccumulatorPathVisitor;(PathCounters);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;AccumulatorPathVisitor;(PathCounters,PathFilter,PathFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;AccumulatorPathVisitor;(PathCounters,PathFilter,PathFilter);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;AccumulatorPathVisitor;(PathCounters,PathFilter,PathFilter);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;getDirList;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;getFileList;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;withBigIntegerCounters;(PathFilter,PathFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;withBigIntegerCounters;(PathFilter,PathFilter);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;withLongCounters;(PathFilter,PathFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;withLongCounters;(PathFilter,PathFilter);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.file;CleaningPathVisitor;true;CleaningPathVisitor;(PathCounters,DeleteOption[],String[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;CleaningPathVisitor;true;CleaningPathVisitor;(PathCounters,DeleteOption[],String[]);;Argument[2].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.file;CleaningPathVisitor;true;CleaningPathVisitor;(PathCounters,String[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;CleaningPathVisitor;true;CleaningPathVisitor;(PathCounters,String[]);;Argument[1].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,Path,Path,CopyOption[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,Path,Path,CopyOption[]);;Argument[1].Element;Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,Path,Path,CopyOption[]);;Argument[2].Element;Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,Path,Path,CopyOption[]);;Argument[3].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[]);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[]);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[]);;Argument[3].Element;Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[]);;Argument[4].Element;Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[]);;Argument[5].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;getCopyOptions;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;getSourceDirectory;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;getTargetDirectory;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;Counters$PathCounters;true;getByteCounter;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;Counters$PathCounters;true;getDirectoryCounter;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;Counters$PathCounters;true;getFileCounter;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;CountingPathVisitor;true;CountingPathVisitor;(PathCounters);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;CountingPathVisitor;true;CountingPathVisitor;(PathCounters,PathFilter,PathFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;CountingPathVisitor;true;CountingPathVisitor;(PathCounters,PathFilter,PathFilter);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.file;CountingPathVisitor;true;CountingPathVisitor;(PathCounters,PathFilter,PathFilter);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.file;CountingPathVisitor;true;getPathCounters;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;DeletingPathVisitor;true;DeletingPathVisitor;(PathCounters,DeleteOption[],String[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;DeletingPathVisitor;true;DeletingPathVisitor;(PathCounters,DeleteOption[],String[]);;Argument[2].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.file;DeletingPathVisitor;true;DeletingPathVisitor;(PathCounters,LinkOption[],DeleteOption[],String[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;DeletingPathVisitor;true;DeletingPathVisitor;(PathCounters,LinkOption[],DeleteOption[],String[]);;Argument[1].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.file;DeletingPathVisitor;true;DeletingPathVisitor;(PathCounters,LinkOption[],DeleteOption[],String[]);;Argument[3].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.file;DeletingPathVisitor;true;DeletingPathVisitor;(PathCounters,String[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;DeletingPathVisitor;true;DeletingPathVisitor;(PathCounters,String[]);;Argument[1].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.file;DirectoryStreamFilter;true;DirectoryStreamFilter;(PathFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;DirectoryStreamFilter;true;getPathFilter;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;PathUtils;false;copyFile;(URL,Path,CopyOption[]);;Argument[1].Element;ReturnValue;taint;generated", - "org.apache.commons.io.file;PathUtils;false;copyFileToDirectory;(URL,Path,CopyOption[]);;Argument[1].Element;ReturnValue;taint;generated", - "org.apache.commons.io.file;PathUtils;false;setReadOnly;(Path,boolean,LinkOption[]);;Argument[0].Element;ReturnValue;taint;generated", - "org.apache.commons.io.file;PathUtils;false;visitFileTree;(FileVisitor,Path);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.file;PathUtils;false;visitFileTree;(FileVisitor,Path,Set,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.file;PathUtils;false;visitFileTree;(FileVisitor,String,String[]);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.file;PathUtils;false;visitFileTree;(FileVisitor,URI);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.file;PathUtils;false;writeString;(Path,CharSequence,Charset,OpenOption[]);;Argument[0].Element;ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;AgeFileFilter;true;AgeFileFilter;(Instant);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;AgeFileFilter;true;AgeFileFilter;(Instant,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;AgeFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;AndFileFilter;true;AndFileFilter;(IOFileFilter,IOFileFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;AndFileFilter;true;AndFileFilter;(IOFileFilter,IOFileFilter);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;AndFileFilter;true;AndFileFilter;(IOFileFilter[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;AndFileFilter;true;AndFileFilter;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;AndFileFilter;true;addFileFilter;(IOFileFilter[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;AndFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;ConditionalFileFilter;true;addFileFilter;(IOFileFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;ConditionalFileFilter;true;getFileFilters;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;ConditionalFileFilter;true;setFileFilters;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;DelegateFileFilter;true;DelegateFileFilter;(FileFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;DelegateFileFilter;true;DelegateFileFilter;(FilenameFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;DelegateFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileEqualsFileFilter;true;FileEqualsFileFilter;(File);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;and;(IOFileFilter[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;andFileFilter;(IOFileFilter,IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;andFileFilter;(IOFileFilter,IOFileFilter);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;asFileFilter;(FileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;asFileFilter;(FilenameFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;magicNumberFileFilter;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;magicNumberFileFilter;(String,long);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;magicNumberFileFilter;(byte[]);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;magicNumberFileFilter;(byte[],long);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;makeCVSAware;(IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;makeDirectoryOnly;(IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;makeFileOnly;(IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;makeSVNAware;(IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;nameFileFilter;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;nameFileFilter;(String,IOCase);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;notFileFilter;(IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;or;(IOFileFilter[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;orFileFilter;(IOFileFilter,IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;orFileFilter;(IOFileFilter,IOFileFilter);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;prefixFileFilter;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;prefixFileFilter;(String,IOCase);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;suffixFileFilter;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;suffixFileFilter;(String,IOCase);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;toList;(IOFileFilter[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;IOFileFilter;true;and;(IOFileFilter);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;IOFileFilter;true;and;(IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;IOFileFilter;true;negate;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;IOFileFilter;true;or;(IOFileFilter);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;IOFileFilter;true;or;(IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;MagicNumberFileFilter;true;MagicNumberFileFilter;(String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;MagicNumberFileFilter;true;MagicNumberFileFilter;(String,long);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;MagicNumberFileFilter;true;MagicNumberFileFilter;(byte[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;MagicNumberFileFilter;true;MagicNumberFileFilter;(byte[],long);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;MagicNumberFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;NameFileFilter;true;NameFileFilter;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;NameFileFilter;true;NameFileFilter;(List,IOCase);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;NameFileFilter;true;NameFileFilter;(String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;NameFileFilter;true;NameFileFilter;(String,IOCase);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;NameFileFilter;true;NameFileFilter;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;NameFileFilter;true;NameFileFilter;(String[],IOCase);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;NameFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;NotFileFilter;true;NotFileFilter;(IOFileFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;NotFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;OrFileFilter;true;OrFileFilter;(IOFileFilter,IOFileFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;OrFileFilter;true;OrFileFilter;(IOFileFilter,IOFileFilter);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;OrFileFilter;true;OrFileFilter;(IOFileFilter[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;OrFileFilter;true;OrFileFilter;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;OrFileFilter;true;addFileFilter;(IOFileFilter[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;OrFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;PathEqualsFileFilter;true;PathEqualsFileFilter;(Path);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;PathVisitorFileFilter;true;PathVisitorFileFilter;(PathVisitor);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;PrefixFileFilter;true;PrefixFileFilter;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;PrefixFileFilter;true;PrefixFileFilter;(List,IOCase);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;PrefixFileFilter;true;PrefixFileFilter;(String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;PrefixFileFilter;true;PrefixFileFilter;(String,IOCase);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;PrefixFileFilter;true;PrefixFileFilter;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;PrefixFileFilter;true;PrefixFileFilter;(String[],IOCase);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;PrefixFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;RegexFileFilter;true;RegexFileFilter;(Pattern);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;RegexFileFilter;true;RegexFileFilter;(Pattern,Function);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;RegexFileFilter;true;RegexFileFilter;(Pattern,Function);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;RegexFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;SuffixFileFilter;true;SuffixFileFilter;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;SuffixFileFilter;true;SuffixFileFilter;(List,IOCase);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;SuffixFileFilter;true;SuffixFileFilter;(String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;SuffixFileFilter;true;SuffixFileFilter;(String,IOCase);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;SuffixFileFilter;true;SuffixFileFilter;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;SuffixFileFilter;true;SuffixFileFilter;(String[],IOCase);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;SuffixFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;WildcardFileFilter;true;WildcardFileFilter;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;WildcardFileFilter;true;WildcardFileFilter;(List,IOCase);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;WildcardFileFilter;true;WildcardFileFilter;(String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;WildcardFileFilter;true;WildcardFileFilter;(String,IOCase);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;WildcardFileFilter;true;WildcardFileFilter;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;WildcardFileFilter;true;WildcardFileFilter;(String[],IOCase);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;WildcardFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;WildcardFilter;true;WildcardFilter;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;WildcardFilter;true;WildcardFilter;(String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;WildcardFilter;true;WildcardFilter;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.input.buffer;CircularBufferInputStream;true;CircularBufferInputStream;(InputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input.buffer;CircularBufferInputStream;true;CircularBufferInputStream;(InputStream,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input.buffer;PeekableInputStream;true;PeekableInputStream;(InputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input.buffer;PeekableInputStream;true;PeekableInputStream;(InputStream,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;BOMInputStream;true;BOMInputStream;(InputStream,ByteOrderMark[]);;Argument[1].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.input;BOMInputStream;true;BOMInputStream;(InputStream,boolean,ByteOrderMark[]);;Argument[2].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.input;BOMInputStream;true;getBOM;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;BOMInputStream;true;getBOMCharsetName;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;BoundedInputStream;true;BoundedInputStream;(InputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;BoundedInputStream;true;BoundedInputStream;(InputStream,long);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;BoundedReader;true;BoundedReader;(Reader,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;BrokenInputStream;true;BrokenInputStream;(Supplier);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;BrokenReader;true;BrokenReader;(Supplier);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;CharSequenceReader;true;CharSequenceReader;(CharSequence);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;CharSequenceReader;true;CharSequenceReader;(CharSequence,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;CharSequenceReader;true;CharSequenceReader;(CharSequence,int,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;CharSequenceReader;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;CharacterFilterReader;true;CharacterFilterReader;(Reader,IntPredicate);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;CircularInputStream;true;CircularInputStream;(byte[],long);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ClassLoaderObjectInputStream;true;ClassLoaderObjectInputStream;(ClassLoader,InputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ClassLoaderObjectInputStream;true;ClassLoaderObjectInputStream;(ClassLoader,InputStream);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;CloseShieldInputStream;true;wrap;(InputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;InfiniteCircularInputStream;true;InfiniteCircularInputStream;(byte[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;MessageDigestCalculatingInputStream$MessageDigestMaintainingObserver;true;MessageDigestMaintainingObserver;(MessageDigest);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;MessageDigestCalculatingInputStream;true;MessageDigestCalculatingInputStream;(InputStream,MessageDigest);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;MessageDigestCalculatingInputStream;true;getMessageDigest;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;ObservableInputStream;true;ObservableInputStream;(InputStream,Observer[]);;Argument[1].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.input;ObservableInputStream;true;add;(Observer);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ObservableInputStream;true;getObservers;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;RandomAccessFileInputStream;true;RandomAccessFileInputStream;(RandomAccessFile);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;RandomAccessFileInputStream;true;RandomAccessFileInputStream;(RandomAccessFile,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;RandomAccessFileInputStream;true;getRandomAccessFile;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;ReadAheadInputStream;true;ReadAheadInputStream;(InputStream,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReadAheadInputStream;true;ReadAheadInputStream;(InputStream,int,ExecutorService);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReadAheadInputStream;true;ReadAheadInputStream;(InputStream,int,ExecutorService);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader,Charset);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader,Charset,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader,CharsetEncoder);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader,CharsetEncoder);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader,CharsetEncoder,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader,CharsetEncoder,int);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader,String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader,String,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReversedLinesFileReader;true;readLine;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;ReversedLinesFileReader;true;readLines;(int);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;ReversedLinesFileReader;true;toString;(int);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;SequenceReader;true;SequenceReader;(Iterable);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.input;SequenceReader;true;SequenceReader;(Reader[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;Builder;(File,TailerListener);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;Builder;(File,TailerListener);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;Builder;(Path,TailerListener);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;Builder;(Path,TailerListener);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;Builder;(Tailable,TailerListener);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;Builder;(Tailable,TailerListener);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;build;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;withBufferSize;(int);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.input;Tailer$Builder;true;withCharset;(Charset);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.input;Tailer$Builder;true;withDelayDuration;(Duration);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.input;Tailer$Builder;true;withDelayDuration;(Duration);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;withReOpen;(boolean);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.input;Tailer$Builder;true;withStartThread;(boolean);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.input;Tailer$Builder;true;withTailFromEnd;(boolean);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,Charset,TailerListener,long,boolean,boolean,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,Charset,TailerListener,long,boolean,boolean,int);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long,boolean);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long,boolean,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long,boolean,boolean);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long,boolean,boolean,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long,boolean,boolean,int);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long,boolean,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long,boolean,int);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,Charset,TailerListener,long,boolean,boolean,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,Charset,TailerListener,long,boolean,boolean,int);;Argument[2];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long,boolean);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long,boolean);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long,boolean,boolean);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long,boolean,boolean);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long,boolean,boolean,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long,boolean,boolean,int);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long,boolean,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long,boolean,int);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;getDelayDuration;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;getFile;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;getTailable;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;TeeInputStream;true;TeeInputStream;(InputStream,OutputStream);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;TeeInputStream;true;TeeInputStream;(InputStream,OutputStream,boolean);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;TeeReader;true;TeeReader;(Reader,Writer);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;TeeReader;true;TeeReader;(Reader,Writer,boolean);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;TimestampedObserver;true;getCloseInstant;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;TimestampedObserver;true;getOpenInstant;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;TimestampedObserver;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;UncheckedBufferedReader;true;UncheckedBufferedReader;(Reader);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;UncheckedBufferedReader;true;UncheckedBufferedReader;(Reader,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;UncheckedBufferedReader;true;on;(Reader);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;UncheckedFilterInputStream;true;on;(InputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;UnixLineEndingInputStream;true;UnixLineEndingInputStream;(InputStream,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;UnsynchronizedByteArrayInputStream;true;UnsynchronizedByteArrayInputStream;(byte[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;UnsynchronizedByteArrayInputStream;true;UnsynchronizedByteArrayInputStream;(byte[],int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;UnsynchronizedByteArrayInputStream;true;UnsynchronizedByteArrayInputStream;(byte[],int,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;WindowsLineEndingInputStream;true;WindowsLineEndingInputStream;(InputStream,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,String);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,String,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,String,boolean);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,String,boolean,String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,String,boolean,String);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,String,boolean,String);;Argument[3];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,boolean,String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,boolean,String);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(URLConnection,String);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;getDefaultEncoding;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;getEncoding;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;XmlStreamReaderException;(String,String,String,String);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;XmlStreamReaderException;(String,String,String,String);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;XmlStreamReaderException;(String,String,String,String);;Argument[3];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;XmlStreamReaderException;(String,String,String,String,String,String);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;XmlStreamReaderException;(String,String,String,String,String,String);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;XmlStreamReaderException;(String,String,String,String,String,String);;Argument[3];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;XmlStreamReaderException;(String,String,String,String,String,String);;Argument[4];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;XmlStreamReaderException;(String,String,String,String,String,String);;Argument[5];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;getBomEncoding;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;getContentTypeEncoding;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;getContentTypeMime;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;getXmlEncoding;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;getXmlGuessEncoding;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;false;FileAlterationMonitor;(long,Collection);;Argument[1].Element;Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;false;FileAlterationMonitor;(long,FileAlterationObserver[]);;Argument[1].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;false;addObserver;(FileAlterationObserver);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;false;getObservers;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;false;setThreadFactory;(ThreadFactory);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(File);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(File,FileFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(File,FileFilter);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(File,FileFilter,IOCase);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(File,FileFilter,IOCase);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(String,FileFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(String,FileFilter);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(String,FileFilter,IOCase);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(String,FileFilter,IOCase);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;addListener;(FileAlterationListener);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;getDirectory;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;getFileFilter;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;getListeners;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;FileEntry;(File);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;FileEntry;(FileEntry,File);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;FileEntry;(FileEntry,File);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;getChildren;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;getFile;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;getLastModifiedFileTime;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;getName;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;getParent;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;newChildInstance;(File);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;newChildInstance;(File);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;setChildren;(FileEntry[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;setLastModified;(FileTime);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;setName;(String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;true;toByteArray;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;true;toString;(Charset);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;true;toString;(String);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;true;write;(InputStream);;Argument[-1];Argument[0];taint;generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;true;write;(InputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;true;writeTo;(OutputStream);;Argument[-1];Argument[0];taint;generated", - "org.apache.commons.io.output;AppendableOutputStream;true;AppendableOutputStream;(Appendable);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;AppendableOutputStream;true;getAppendable;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;AppendableWriter;true;AppendableWriter;(Appendable);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;AppendableWriter;true;getAppendable;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;BrokenOutputStream;true;BrokenOutputStream;(Supplier);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;BrokenWriter;true;BrokenWriter;(Supplier);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;ChunkedOutputStream;true;ChunkedOutputStream;(OutputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;ChunkedOutputStream;true;ChunkedOutputStream;(OutputStream,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;CloseShieldOutputStream;true;CloseShieldOutputStream;(OutputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;CloseShieldOutputStream;true;wrap;(OutputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.output;CountingOutputStream;true;CountingOutputStream;(OutputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;DeferredFileOutputStream;(int,File);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;DeferredFileOutputStream;(int,String,String,File);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;DeferredFileOutputStream;(int,String,String,File);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;DeferredFileOutputStream;(int,String,String,File);;Argument[3];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;DeferredFileOutputStream;(int,int,File);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;DeferredFileOutputStream;(int,int,String,String,File);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;DeferredFileOutputStream;(int,int,String,String,File);;Argument[3];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;DeferredFileOutputStream;(int,int,String,String,File);;Argument[4];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;getData;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;getFile;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;writeTo;(OutputStream);;Argument[-1];Argument[0];taint;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,Charset,boolean,String);;Argument[3];Argument[-1];taint;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,String,boolean,String);;Argument[3];Argument[-1];taint;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,boolean,String);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(String,boolean,String);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.output;ProxyCollectionWriter;true;ProxyCollectionWriter;(Collection);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.output;ProxyCollectionWriter;true;ProxyCollectionWriter;(Writer[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.output;ProxyOutputStream;true;ProxyOutputStream;(OutputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;StringBuilderWriter;true;StringBuilderWriter;(StringBuilder);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;StringBuilderWriter;true;getBuilder;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;StringBuilderWriter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;TaggedOutputStream;true;TaggedOutputStream;(OutputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;TeeOutputStream;true;TeeOutputStream;(OutputStream,OutputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;TeeOutputStream;true;TeeOutputStream;(OutputStream,OutputStream);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.output;TeeWriter;true;TeeWriter;(Collection);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.output;TeeWriter;true;TeeWriter;(Writer[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.output;ThresholdingOutputStream;true;ThresholdingOutputStream;(int,IOConsumer,IOFunction);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.output;ThresholdingOutputStream;true;ThresholdingOutputStream;(int,IOConsumer,IOFunction);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.output;UncheckedAppendable;true;on;(Appendable);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.output;UncheckedFilterOutputStream;true;UncheckedFilterOutputStream;(OutputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;UncheckedFilterOutputStream;true;on;(OutputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer,Charset);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer,Charset,int,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer,CharsetDecoder);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer,CharsetDecoder);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer,CharsetDecoder,int,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer,CharsetDecoder,int,boolean);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer,String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer,String,int,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;XmlStreamWriter;true;XmlStreamWriter;(File,String);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.output;XmlStreamWriter;true;XmlStreamWriter;(OutputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;XmlStreamWriter;true;XmlStreamWriter;(OutputStream,String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;XmlStreamWriter;true;XmlStreamWriter;(OutputStream,String);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.output;XmlStreamWriter;true;getDefaultEncoding;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;XmlStreamWriter;true;getEncoding;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;ValidatingObjectInputStream;(InputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;accept;(ClassNameMatcher);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;accept;(ClassNameMatcher);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;accept;(Class[]);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;accept;(Pattern);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;accept;(String[]);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;reject;(ClassNameMatcher);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;reject;(ClassNameMatcher);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;reject;(Class[]);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;reject;(Pattern);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;reject;(String[]);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io;ByteOrderMark;true;ByteOrderMark;(String,int[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io;ByteOrderMark;true;getCharsetName;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;ByteOrderMark;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;CopyUtils;true;copy;(InputStream,OutputStream);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;CopyUtils;true;copy;(InputStream,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;CopyUtils;true;copy;(InputStream,Writer,String);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;CopyUtils;true;copy;(Reader,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;CopyUtils;true;copy;(String,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;CopyUtils;true;copy;(byte[],OutputStream);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;CopyUtils;true;copy;(byte[],Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;CopyUtils;true;copy;(byte[],Writer,String);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;DirectoryWalker$CancelException;true;CancelException;(File,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io;DirectoryWalker$CancelException;true;CancelException;(String,File,int);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io;DirectoryWalker$CancelException;true;getFile;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;FileCleaningTracker;true;getDeleteFailures;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;FileDeleteStrategy;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;FileSystem;false;normalizeSeparators;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FileSystem;false;toLegalFileName;(String,char);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FileUtils;true;checksum;(File,Checksum);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io;FileUtils;true;convertFileCollectionToFileArray;(Collection);;Argument[0].Element;ReturnValue;taint;generated", - "org.apache.commons.io;FileUtils;true;delete;(File);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FileUtils;true;getFile;(File,String[]);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FileUtils;true;getFile;(File,String[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "org.apache.commons.io;FileUtils;true;getFile;(String[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "org.apache.commons.io;FileUtils;true;toURLs;(File[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;concat;(String,String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;concat;(String,String);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;getBaseName;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;getExtension;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;getFullPath;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;getFullPathNoEndSeparator;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;getName;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;getPath;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;getPathNoEndSeparator;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;getPrefix;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;normalize;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;normalize;(String,boolean);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;normalizeNoEndSeparator;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;normalizeNoEndSeparator;(String,boolean);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;removeExtension;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;separatorsToSystem;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;separatorsToUnix;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;separatorsToWindows;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOExceptionList;true;IOExceptionList;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io;IOExceptionList;true;IOExceptionList;(String,List);;Argument[1].Element;Argument[-1];taint;generated", - "org.apache.commons.io;IOExceptionList;true;getCause;(int);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;IOExceptionList;true;getCauseList;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;IOExceptionList;true;getCauseList;(Class);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;buffer;(InputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;buffer;(InputStream,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;buffer;(OutputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;buffer;(OutputStream,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;buffer;(Reader);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;buffer;(Reader,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;buffer;(Writer);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;buffer;(Writer,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(InputStream,OutputStream);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(InputStream,OutputStream,int);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(InputStream,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(InputStream,Writer,Charset);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(InputStream,Writer,String);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(Reader,Appendable);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(Reader,Appendable,CharBuffer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(Reader,Appendable,CharBuffer);;Argument[0];Argument[2];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(Reader,Appendable,CharBuffer);;Argument[2];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(Reader,Appendable,CharBuffer);;Argument[2];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(Reader,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,byte[]);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,byte[]);;Argument[0];Argument[2];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,byte[]);;Argument[2];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,byte[]);;Argument[2];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,long,long);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,long,long,byte[]);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,long,long,byte[]);;Argument[0];Argument[4];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,long,long,byte[]);;Argument[4];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,long,long,byte[]);;Argument[4];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,char[]);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,char[]);;Argument[0];Argument[2];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,char[]);;Argument[2];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,char[]);;Argument[2];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,long,long);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,long,long,char[]);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,long,long,char[]);;Argument[0];Argument[4];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,long,long,char[]);;Argument[4];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,long,long,char[]);;Argument[4];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;lineIterator;(InputStream,Charset);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;lineIterator;(InputStream,String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;lineIterator;(Reader);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;read;(InputStream,byte[]);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;read;(InputStream,byte[]);;Argument[1];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;read;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;read;(InputStream,byte[],int,int);;Argument[1];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;read;(ReadableByteChannel,ByteBuffer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;read;(Reader,char[]);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;read;(Reader,char[]);;Argument[1];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;read;(Reader,char[],int,int);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;read;(Reader,char[],int,int);;Argument[1];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(InputStream,byte[]);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(InputStream,byte[]);;Argument[1];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(InputStream,byte[],int,int);;Argument[1];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(InputStream,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(ReadableByteChannel,ByteBuffer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(Reader,char[]);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(Reader,char[]);;Argument[1];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(Reader,char[],int,int);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(Reader,char[],int,int);;Argument[1];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;readLines;(InputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;readLines;(InputStream,Charset);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;readLines;(InputStream,String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;readLines;(Reader);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toBufferedReader;(Reader);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toBufferedReader;(Reader,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toByteArray;(InputStream,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toByteArray;(InputStream,long);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toByteArray;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toCharArray;(InputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toCharArray;(InputStream,Charset);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toCharArray;(InputStream,String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toCharArray;(Reader);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toInputStream;(CharSequence);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toInputStream;(CharSequence,Charset);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toInputStream;(CharSequence,String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toInputStream;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toInputStream;(String,Charset);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toInputStream;(String,String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toString;(InputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toString;(InputStream,Charset);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toString;(InputStream,String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toString;(Reader);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toString;(byte[]);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toString;(byte[],String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;write;(CharSequence,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;write;(String,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;write;(StringBuffer,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;write;(byte[],OutputStream);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;write;(byte[],Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;write;(byte[],Writer,Charset);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;write;(byte[],Writer,String);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;write;(char[],Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;writeChunked;(byte[],OutputStream);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;writeChunked;(char[],Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;writeLines;(Collection,String,OutputStream);;Argument[1];Argument[2];taint;generated", - "org.apache.commons.io;IOUtils;true;writeLines;(Collection,String,OutputStream,Charset);;Argument[1];Argument[2];taint;generated", - "org.apache.commons.io;IOUtils;true;writeLines;(Collection,String,OutputStream,String);;Argument[1];Argument[2];taint;generated", - "org.apache.commons.io;IOUtils;true;writeLines;(Collection,String,Writer);;Argument[1];Argument[2];taint;generated", - "org.apache.commons.io;IOUtils;true;writer;(Appendable);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;LineIterator;true;LineIterator;(Reader);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io;LineIterator;true;nextLine;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;TaggedIOException;true;TaggedIOException;(IOException,Serializable);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io;TaggedIOException;true;getTag;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;UncheckedIO;true;apply;(IOFunction,Object);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io;UncheckedIO;true;apply;(IOTriFunction,Object,Object,Object);;Argument[1];ReturnValue;taint;generated" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/NegativeIOGenerated.qll b/java/ql/lib/semmle/code/java/frameworks/apache/NegativeIOGenerated.qll deleted file mode 100644 index 8c2e0684942..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/apache/NegativeIOGenerated.qll +++ /dev/null @@ -1,765 +0,0 @@ -/** - * THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. - * Definitions of negative summaries in the IOGenerated framework. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class IOGeneratedNegativesummaryCsv extends NegativeSummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.commons.io.charset;CharsetDecoders;CharsetDecoders;();generated", - "org.apache.commons.io.charset;CharsetEncoders;CharsetEncoders;();generated", - "org.apache.commons.io.comparator;DefaultFileComparator;DefaultFileComparator;();generated", - "org.apache.commons.io.comparator;DirectoryFileComparator;DirectoryFileComparator;();generated", - "org.apache.commons.io.comparator;ExtensionFileComparator;ExtensionFileComparator;();generated", - "org.apache.commons.io.comparator;ExtensionFileComparator;ExtensionFileComparator;(IOCase);generated", - "org.apache.commons.io.comparator;ExtensionFileComparator;toString;();generated", - "org.apache.commons.io.comparator;LastModifiedFileComparator;LastModifiedFileComparator;();generated", - "org.apache.commons.io.comparator;NameFileComparator;NameFileComparator;();generated", - "org.apache.commons.io.comparator;NameFileComparator;NameFileComparator;(IOCase);generated", - "org.apache.commons.io.comparator;NameFileComparator;toString;();generated", - "org.apache.commons.io.comparator;PathFileComparator;PathFileComparator;();generated", - "org.apache.commons.io.comparator;PathFileComparator;PathFileComparator;(IOCase);generated", - "org.apache.commons.io.comparator;PathFileComparator;toString;();generated", - "org.apache.commons.io.comparator;SizeFileComparator;SizeFileComparator;();generated", - "org.apache.commons.io.comparator;SizeFileComparator;SizeFileComparator;(boolean);generated", - "org.apache.commons.io.comparator;SizeFileComparator;toString;();generated", - "org.apache.commons.io.file.attribute;FileTimes;minusMillis;(FileTime,long);generated", - "org.apache.commons.io.file.attribute;FileTimes;minusNanos;(FileTime,long);generated", - "org.apache.commons.io.file.attribute;FileTimes;minusSeconds;(FileTime,long);generated", - "org.apache.commons.io.file.attribute;FileTimes;now;();generated", - "org.apache.commons.io.file.attribute;FileTimes;ntfsTimeToDate;(long);generated", - "org.apache.commons.io.file.attribute;FileTimes;ntfsTimeToFileTime;(long);generated", - "org.apache.commons.io.file.attribute;FileTimes;plusMillis;(FileTime,long);generated", - "org.apache.commons.io.file.attribute;FileTimes;plusNanos;(FileTime,long);generated", - "org.apache.commons.io.file.attribute;FileTimes;plusSeconds;(FileTime,long);generated", - "org.apache.commons.io.file.attribute;FileTimes;setLastModifiedTime;(Path);generated", - "org.apache.commons.io.file.attribute;FileTimes;toDate;(FileTime);generated", - "org.apache.commons.io.file.attribute;FileTimes;toFileTime;(Date);generated", - "org.apache.commons.io.file.attribute;FileTimes;toNtfsTime;(Date);generated", - "org.apache.commons.io.file.attribute;FileTimes;toNtfsTime;(FileTime);generated", - "org.apache.commons.io.file.spi;FileSystemProviders;getFileSystemProvider;(Path);generated", - "org.apache.commons.io.file.spi;FileSystemProviders;installed;();generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;AccumulatorPathVisitor;();generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;relativizeDirectories;(Path,boolean,Comparator);generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;relativizeFiles;(Path,boolean,Comparator);generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;withBigIntegerCounters;();generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;withLongCounters;();generated", - "org.apache.commons.io.file;CleaningPathVisitor;withBigIntegerCounters;();generated", - "org.apache.commons.io.file;CleaningPathVisitor;withLongCounters;();generated", - "org.apache.commons.io.file;Counters$Counter;add;(long);generated", - "org.apache.commons.io.file;Counters$Counter;get;();generated", - "org.apache.commons.io.file;Counters$Counter;getBigInteger;();generated", - "org.apache.commons.io.file;Counters$Counter;getLong;();generated", - "org.apache.commons.io.file;Counters$Counter;increment;();generated", - "org.apache.commons.io.file;Counters$Counter;reset;();generated", - "org.apache.commons.io.file;Counters$PathCounters;getByteCounter;();generated", - "org.apache.commons.io.file;Counters$PathCounters;getDirectoryCounter;();generated", - "org.apache.commons.io.file;Counters$PathCounters;getFileCounter;();generated", - "org.apache.commons.io.file;Counters$PathCounters;reset;();generated", - "org.apache.commons.io.file;Counters;Counters;();generated", - "org.apache.commons.io.file;Counters;bigIntegerCounter;();generated", - "org.apache.commons.io.file;Counters;bigIntegerPathCounters;();generated", - "org.apache.commons.io.file;Counters;longCounter;();generated", - "org.apache.commons.io.file;Counters;longPathCounters;();generated", - "org.apache.commons.io.file;Counters;noopCounter;();generated", - "org.apache.commons.io.file;Counters;noopPathCounters;();generated", - "org.apache.commons.io.file;CountingPathVisitor;toString;();generated", - "org.apache.commons.io.file;CountingPathVisitor;withBigIntegerCounters;();generated", - "org.apache.commons.io.file;CountingPathVisitor;withLongCounters;();generated", - "org.apache.commons.io.file;DeletingPathVisitor;withBigIntegerCounters;();generated", - "org.apache.commons.io.file;DeletingPathVisitor;withLongCounters;();generated", - "org.apache.commons.io.file;NoopPathVisitor;NoopPathVisitor;();generated", - "org.apache.commons.io.file;PathFilter;accept;(Path,BasicFileAttributes);generated", - "org.apache.commons.io.file;PathUtils;cleanDirectory;(Path);generated", - "org.apache.commons.io.file;PathUtils;cleanDirectory;(Path,DeleteOption[]);generated", - "org.apache.commons.io.file;PathUtils;copyDirectory;(Path,Path,CopyOption[]);generated", - "org.apache.commons.io.file;PathUtils;copyFileToDirectory;(Path,Path,CopyOption[]);generated", - "org.apache.commons.io.file;PathUtils;countDirectory;(Path);generated", - "org.apache.commons.io.file;PathUtils;countDirectoryAsBigInteger;(Path);generated", - "org.apache.commons.io.file;PathUtils;createParentDirectories;(Path,FileAttribute[]);generated", - "org.apache.commons.io.file;PathUtils;createParentDirectories;(Path,LinkOption,FileAttribute[]);generated", - "org.apache.commons.io.file;PathUtils;current;();generated", - "org.apache.commons.io.file;PathUtils;delete;(Path);generated", - "org.apache.commons.io.file;PathUtils;delete;(Path,DeleteOption[]);generated", - "org.apache.commons.io.file;PathUtils;delete;(Path,LinkOption[],DeleteOption[]);generated", - "org.apache.commons.io.file;PathUtils;deleteDirectory;(Path);generated", - "org.apache.commons.io.file;PathUtils;deleteDirectory;(Path,DeleteOption[]);generated", - "org.apache.commons.io.file;PathUtils;deleteDirectory;(Path,LinkOption[],DeleteOption[]);generated", - "org.apache.commons.io.file;PathUtils;deleteFile;(Path);generated", - "org.apache.commons.io.file;PathUtils;deleteFile;(Path,DeleteOption[]);generated", - "org.apache.commons.io.file;PathUtils;deleteFile;(Path,LinkOption[],DeleteOption[]);generated", - "org.apache.commons.io.file;PathUtils;directoryAndFileContentEquals;(Path,Path);generated", - "org.apache.commons.io.file;PathUtils;directoryAndFileContentEquals;(Path,Path,LinkOption[],OpenOption[],FileVisitOption[]);generated", - "org.apache.commons.io.file;PathUtils;directoryContentEquals;(Path,Path);generated", - "org.apache.commons.io.file;PathUtils;directoryContentEquals;(Path,Path,int,LinkOption[],FileVisitOption[]);generated", - "org.apache.commons.io.file;PathUtils;fileContentEquals;(Path,Path);generated", - "org.apache.commons.io.file;PathUtils;fileContentEquals;(Path,Path,LinkOption[],OpenOption[]);generated", - "org.apache.commons.io.file;PathUtils;filter;(PathFilter,Path[]);generated", - "org.apache.commons.io.file;PathUtils;getAclEntryList;(Path);generated", - "org.apache.commons.io.file;PathUtils;getAclFileAttributeView;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;getDosFileAttributeView;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;getPosixFileAttributeView;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;getTempDirectory;();generated", - "org.apache.commons.io.file;PathUtils;isDirectory;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isEmpty;(Path);generated", - "org.apache.commons.io.file;PathUtils;isEmptyDirectory;(Path);generated", - "org.apache.commons.io.file;PathUtils;isEmptyFile;(Path);generated", - "org.apache.commons.io.file;PathUtils;isNewer;(Path,ChronoZonedDateTime,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isNewer;(Path,FileTime,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isNewer;(Path,Instant,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isNewer;(Path,Path);generated", - "org.apache.commons.io.file;PathUtils;isNewer;(Path,long,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isOlder;(Path,FileTime,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isOlder;(Path,Instant,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isOlder;(Path,Path);generated", - "org.apache.commons.io.file;PathUtils;isOlder;(Path,long,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isPosix;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isRegularFile;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;newDirectoryStream;(Path,PathFilter);generated", - "org.apache.commons.io.file;PathUtils;newOutputStream;(Path,boolean);generated", - "org.apache.commons.io.file;PathUtils;noFollowLinkOptionArray;();generated", - "org.apache.commons.io.file;PathUtils;readAttributes;(Path,Class,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;readBasicFileAttributes;(Path);generated", - "org.apache.commons.io.file;PathUtils;readBasicFileAttributes;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;readBasicFileAttributesUnchecked;(Path);generated", - "org.apache.commons.io.file;PathUtils;readDosFileAttributes;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;readOsFileAttributes;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;readPosixFileAttributes;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;readString;(Path,Charset);generated", - "org.apache.commons.io.file;PathUtils;setLastModifiedTime;(Path,Path);generated", - "org.apache.commons.io.file;PathUtils;sizeOf;(Path);generated", - "org.apache.commons.io.file;PathUtils;sizeOfAsBigInteger;(Path);generated", - "org.apache.commons.io.file;PathUtils;sizeOfDirectory;(Path);generated", - "org.apache.commons.io.file;PathUtils;sizeOfDirectoryAsBigInteger;(Path);generated", - "org.apache.commons.io.file;PathUtils;waitFor;(Path,Duration,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;walk;(Path,PathFilter,int,boolean,FileVisitOption[]);generated", - "org.apache.commons.io.file;StandardDeleteOption;overrideReadOnly;(DeleteOption[]);generated", - "org.apache.commons.io.filefilter;AbstractFileFilter;AbstractFileFilter;();generated", - "org.apache.commons.io.filefilter;AbstractFileFilter;toString;();generated", - "org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(Date);generated", - "org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(Date,boolean);generated", - "org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(File);generated", - "org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(File,boolean);generated", - "org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(long);generated", - "org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(long,boolean);generated", - "org.apache.commons.io.filefilter;AndFileFilter;AndFileFilter;();generated", - "org.apache.commons.io.filefilter;ConditionalFileFilter;addFileFilter;(IOFileFilter);generated", - "org.apache.commons.io.filefilter;ConditionalFileFilter;getFileFilters;();generated", - "org.apache.commons.io.filefilter;ConditionalFileFilter;removeFileFilter;(IOFileFilter);generated", - "org.apache.commons.io.filefilter;ConditionalFileFilter;setFileFilters;(List);generated", - "org.apache.commons.io.filefilter;FalseFileFilter;toString;();generated", - "org.apache.commons.io.filefilter;FileFilterUtils;FileFilterUtils;();generated", - "org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(Date);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(Date,boolean);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(File);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(File,boolean);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(long);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(long,boolean);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;directoryFileFilter;();generated", - "org.apache.commons.io.filefilter;FileFilterUtils;falseFileFilter;();generated", - "org.apache.commons.io.filefilter;FileFilterUtils;fileFileFilter;();generated", - "org.apache.commons.io.filefilter;FileFilterUtils;filter;(IOFileFilter,File[]);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;filter;(IOFileFilter,Iterable);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;filterList;(IOFileFilter,File[]);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;filterList;(IOFileFilter,Iterable);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;filterSet;(IOFileFilter,File[]);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;filterSet;(IOFileFilter,Iterable);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;sizeFileFilter;(long);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;sizeFileFilter;(long,boolean);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;sizeRangeFileFilter;(long,long);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;trueFileFilter;();generated", - "org.apache.commons.io.filefilter;IOFileFilter;and;(IOFileFilter);generated", - "org.apache.commons.io.filefilter;IOFileFilter;negate;();generated", - "org.apache.commons.io.filefilter;IOFileFilter;or;(IOFileFilter);generated", - "org.apache.commons.io.filefilter;OrFileFilter;OrFileFilter;();generated", - "org.apache.commons.io.filefilter;RegexFileFilter;RegexFileFilter;(String);generated", - "org.apache.commons.io.filefilter;RegexFileFilter;RegexFileFilter;(String,IOCase);generated", - "org.apache.commons.io.filefilter;RegexFileFilter;RegexFileFilter;(String,int);generated", - "org.apache.commons.io.filefilter;SizeFileFilter;SizeFileFilter;(long);generated", - "org.apache.commons.io.filefilter;SizeFileFilter;SizeFileFilter;(long,boolean);generated", - "org.apache.commons.io.filefilter;SizeFileFilter;toString;();generated", - "org.apache.commons.io.filefilter;SymbolicLinkFileFilter;SymbolicLinkFileFilter;(FileVisitResult,FileVisitResult);generated", - "org.apache.commons.io.filefilter;TrueFileFilter;toString;();generated", - "org.apache.commons.io.function;IOBiConsumer;accept;(Object,Object);generated", - "org.apache.commons.io.function;IOBiConsumer;andThen;(IOBiConsumer);generated", - "org.apache.commons.io.function;IOBiFunction;andThen;(Function);generated", - "org.apache.commons.io.function;IOBiFunction;andThen;(IOFunction);generated", - "org.apache.commons.io.function;IOBiFunction;apply;(Object,Object);generated", - "org.apache.commons.io.function;IOConsumer;accept;(Object);generated", - "org.apache.commons.io.function;IOConsumer;andThen;(IOConsumer);generated", - "org.apache.commons.io.function;IOConsumer;forEach;(Object[],IOConsumer);generated", - "org.apache.commons.io.function;IOConsumer;forEachIndexed;(Stream,IOConsumer);generated", - "org.apache.commons.io.function;IOConsumer;noop;();generated", - "org.apache.commons.io.function;IOFunction;andThen;(Consumer);generated", - "org.apache.commons.io.function;IOFunction;andThen;(Function);generated", - "org.apache.commons.io.function;IOFunction;andThen;(IOConsumer);generated", - "org.apache.commons.io.function;IOFunction;andThen;(IOFunction);generated", - "org.apache.commons.io.function;IOFunction;apply;(Object);generated", - "org.apache.commons.io.function;IOFunction;compose;(Function);generated", - "org.apache.commons.io.function;IOFunction;compose;(IOFunction);generated", - "org.apache.commons.io.function;IOFunction;compose;(IOSupplier);generated", - "org.apache.commons.io.function;IOFunction;compose;(Supplier);generated", - "org.apache.commons.io.function;IOFunction;identity;();generated", - "org.apache.commons.io.function;IORunnable;run;();generated", - "org.apache.commons.io.function;IOSupplier;get;();generated", - "org.apache.commons.io.function;IOTriFunction;andThen;(Function);generated", - "org.apache.commons.io.function;IOTriFunction;andThen;(IOFunction);generated", - "org.apache.commons.io.function;IOTriFunction;apply;(Object,Object,Object);generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;CircularByteBuffer;();generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;CircularByteBuffer;(int);generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;add;(byte);generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;add;(byte[],int,int);generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;clear;();generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;getCurrentNumberOfBytes;();generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;getSpace;();generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;hasBytes;();generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;hasSpace;();generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;hasSpace;(int);generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;peek;(byte[],int,int);generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;read;();generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;read;(byte[],int,int);generated", - "org.apache.commons.io.input.buffer;PeekableInputStream;peek;(byte[]);generated", - "org.apache.commons.io.input.buffer;PeekableInputStream;peek;(byte[],int,int);generated", - "org.apache.commons.io.input;AutoCloseInputStream;AutoCloseInputStream;(InputStream);generated", - "org.apache.commons.io.input;BOMInputStream;BOMInputStream;(InputStream);generated", - "org.apache.commons.io.input;BOMInputStream;BOMInputStream;(InputStream,boolean);generated", - "org.apache.commons.io.input;BOMInputStream;hasBOM;();generated", - "org.apache.commons.io.input;BOMInputStream;hasBOM;(ByteOrderMark);generated", - "org.apache.commons.io.input;BoundedInputStream;isPropagateClose;();generated", - "org.apache.commons.io.input;BoundedInputStream;setPropagateClose;(boolean);generated", - "org.apache.commons.io.input;BoundedInputStream;toString;();generated", - "org.apache.commons.io.input;BrokenInputStream;BrokenInputStream;();generated", - "org.apache.commons.io.input;BrokenInputStream;BrokenInputStream;(IOException);generated", - "org.apache.commons.io.input;BrokenReader;BrokenReader;();generated", - "org.apache.commons.io.input;BrokenReader;BrokenReader;(IOException);generated", - "org.apache.commons.io.input;BufferedFileChannelInputStream;BufferedFileChannelInputStream;(File);generated", - "org.apache.commons.io.input;BufferedFileChannelInputStream;BufferedFileChannelInputStream;(File,int);generated", - "org.apache.commons.io.input;BufferedFileChannelInputStream;BufferedFileChannelInputStream;(Path);generated", - "org.apache.commons.io.input;BufferedFileChannelInputStream;BufferedFileChannelInputStream;(Path,int);generated", - "org.apache.commons.io.input;CharSequenceInputStream;CharSequenceInputStream;(CharSequence,Charset);generated", - "org.apache.commons.io.input;CharSequenceInputStream;CharSequenceInputStream;(CharSequence,Charset,int);generated", - "org.apache.commons.io.input;CharSequenceInputStream;CharSequenceInputStream;(CharSequence,String);generated", - "org.apache.commons.io.input;CharSequenceInputStream;CharSequenceInputStream;(CharSequence,String,int);generated", - "org.apache.commons.io.input;CharacterFilterReader;CharacterFilterReader;(Reader,int);generated", - "org.apache.commons.io.input;CharacterSetFilterReader;CharacterSetFilterReader;(Reader,Integer[]);generated", - "org.apache.commons.io.input;CharacterSetFilterReader;CharacterSetFilterReader;(Reader,Set);generated", - "org.apache.commons.io.input;CloseShieldInputStream;CloseShieldInputStream;(InputStream);generated", - "org.apache.commons.io.input;CloseShieldReader;CloseShieldReader;(Reader);generated", - "org.apache.commons.io.input;CloseShieldReader;wrap;(Reader);generated", - "org.apache.commons.io.input;ClosedInputStream;ClosedInputStream;();generated", - "org.apache.commons.io.input;ClosedReader;ClosedReader;();generated", - "org.apache.commons.io.input;CountingInputStream;CountingInputStream;(InputStream);generated", - "org.apache.commons.io.input;CountingInputStream;getByteCount;();generated", - "org.apache.commons.io.input;CountingInputStream;getCount;();generated", - "org.apache.commons.io.input;CountingInputStream;resetByteCount;();generated", - "org.apache.commons.io.input;CountingInputStream;resetCount;();generated", - "org.apache.commons.io.input;DemuxInputStream;DemuxInputStream;();generated", - "org.apache.commons.io.input;DemuxInputStream;bindStream;(InputStream);generated", - "org.apache.commons.io.input;MarkShieldInputStream;MarkShieldInputStream;(InputStream);generated", - "org.apache.commons.io.input;MemoryMappedFileInputStream;MemoryMappedFileInputStream;(Path);generated", - "org.apache.commons.io.input;MemoryMappedFileInputStream;MemoryMappedFileInputStream;(Path,int);generated", - "org.apache.commons.io.input;MessageDigestCalculatingInputStream;MessageDigestCalculatingInputStream;(InputStream);generated", - "org.apache.commons.io.input;MessageDigestCalculatingInputStream;MessageDigestCalculatingInputStream;(InputStream,String);generated", - "org.apache.commons.io.input;NullInputStream;NullInputStream;();generated", - "org.apache.commons.io.input;NullInputStream;NullInputStream;(long);generated", - "org.apache.commons.io.input;NullInputStream;NullInputStream;(long,boolean,boolean);generated", - "org.apache.commons.io.input;NullInputStream;getPosition;();generated", - "org.apache.commons.io.input;NullInputStream;getSize;();generated", - "org.apache.commons.io.input;NullReader;NullReader;();generated", - "org.apache.commons.io.input;NullReader;NullReader;(long);generated", - "org.apache.commons.io.input;NullReader;NullReader;(long,boolean,boolean);generated", - "org.apache.commons.io.input;NullReader;getPosition;();generated", - "org.apache.commons.io.input;NullReader;getSize;();generated", - "org.apache.commons.io.input;ObservableInputStream$Observer;Observer;();generated", - "org.apache.commons.io.input;ObservableInputStream$Observer;closed;();generated", - "org.apache.commons.io.input;ObservableInputStream$Observer;data;(byte[],int,int);generated", - "org.apache.commons.io.input;ObservableInputStream$Observer;data;(int);generated", - "org.apache.commons.io.input;ObservableInputStream$Observer;error;(IOException);generated", - "org.apache.commons.io.input;ObservableInputStream$Observer;finished;();generated", - "org.apache.commons.io.input;ObservableInputStream;ObservableInputStream;(InputStream);generated", - "org.apache.commons.io.input;ObservableInputStream;consume;();generated", - "org.apache.commons.io.input;ObservableInputStream;remove;(Observer);generated", - "org.apache.commons.io.input;ObservableInputStream;removeAllObservers;();generated", - "org.apache.commons.io.input;ProxyInputStream;ProxyInputStream;(InputStream);generated", - "org.apache.commons.io.input;ProxyReader;ProxyReader;(Reader);generated", - "org.apache.commons.io.input;QueueInputStream;QueueInputStream;();generated", - "org.apache.commons.io.input;QueueInputStream;QueueInputStream;(BlockingQueue);generated", - "org.apache.commons.io.input;QueueInputStream;newQueueOutputStream;();generated", - "org.apache.commons.io.input;RandomAccessFileInputStream;availableLong;();generated", - "org.apache.commons.io.input;RandomAccessFileInputStream;isCloseOnClose;();generated", - "org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(File);generated", - "org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(File,Charset);generated", - "org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(File,int,Charset);generated", - "org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(File,int,String);generated", - "org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(Path,Charset);generated", - "org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(Path,int,Charset);generated", - "org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(Path,int,String);generated", - "org.apache.commons.io.input;SwappedDataInputStream;SwappedDataInputStream;(InputStream);generated", - "org.apache.commons.io.input;TaggedInputStream;TaggedInputStream;(InputStream);generated", - "org.apache.commons.io.input;TaggedInputStream;isCauseOf;(Throwable);generated", - "org.apache.commons.io.input;TaggedInputStream;throwIfCauseOf;(Throwable);generated", - "org.apache.commons.io.input;TaggedReader;TaggedReader;(Reader);generated", - "org.apache.commons.io.input;TaggedReader;isCauseOf;(Throwable);generated", - "org.apache.commons.io.input;TaggedReader;throwIfCauseOf;(Throwable);generated", - "org.apache.commons.io.input;Tailer$RandomAccessResourceBridge;getPointer;();generated", - "org.apache.commons.io.input;Tailer$RandomAccessResourceBridge;read;(byte[]);generated", - "org.apache.commons.io.input;Tailer$RandomAccessResourceBridge;seek;(long);generated", - "org.apache.commons.io.input;Tailer$Tailable;getRandomAccess;(String);generated", - "org.apache.commons.io.input;Tailer$Tailable;isNewer;(FileTime);generated", - "org.apache.commons.io.input;Tailer$Tailable;lastModifiedFileTime;();generated", - "org.apache.commons.io.input;Tailer$Tailable;size;();generated", - "org.apache.commons.io.input;Tailer;getDelay;();generated", - "org.apache.commons.io.input;Tailer;stop;();generated", - "org.apache.commons.io.input;TailerListener;fileNotFound;();generated", - "org.apache.commons.io.input;TailerListener;fileRotated;();generated", - "org.apache.commons.io.input;TailerListener;handle;(Exception);generated", - "org.apache.commons.io.input;TailerListener;handle;(String);generated", - "org.apache.commons.io.input;TailerListener;init;(Tailer);generated", - "org.apache.commons.io.input;TailerListenerAdapter;TailerListenerAdapter;();generated", - "org.apache.commons.io.input;TailerListenerAdapter;endOfFileReached;();generated", - "org.apache.commons.io.input;TimestampedObserver;TimestampedObserver;();generated", - "org.apache.commons.io.input;TimestampedObserver;getOpenToCloseDuration;();generated", - "org.apache.commons.io.input;TimestampedObserver;getOpenToNowDuration;();generated", - "org.apache.commons.io.input;UncheckedFilterInputStream;UncheckedFilterInputStream;(InputStream);generated", - "org.apache.commons.io.input;UncheckedFilterReader;UncheckedFilterReader;(Reader);generated", - "org.apache.commons.io.input;UncheckedFilterReader;on;(Reader);generated", - "org.apache.commons.io.input;XmlStreamReader;XmlStreamReader;(File);generated", - "org.apache.commons.io.input;XmlStreamReader;XmlStreamReader;(Path);generated", - "org.apache.commons.io.input;XmlStreamReader;XmlStreamReader;(URL);generated", - "org.apache.commons.io.monitor;FileAlterationListener;onDirectoryChange;(File);generated", - "org.apache.commons.io.monitor;FileAlterationListener;onDirectoryCreate;(File);generated", - "org.apache.commons.io.monitor;FileAlterationListener;onDirectoryDelete;(File);generated", - "org.apache.commons.io.monitor;FileAlterationListener;onFileChange;(File);generated", - "org.apache.commons.io.monitor;FileAlterationListener;onFileCreate;(File);generated", - "org.apache.commons.io.monitor;FileAlterationListener;onFileDelete;(File);generated", - "org.apache.commons.io.monitor;FileAlterationListener;onStart;(FileAlterationObserver);generated", - "org.apache.commons.io.monitor;FileAlterationListener;onStop;(FileAlterationObserver);generated", - "org.apache.commons.io.monitor;FileAlterationListenerAdaptor;FileAlterationListenerAdaptor;();generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;FileAlterationMonitor;();generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;FileAlterationMonitor;(long);generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;getInterval;();generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;removeObserver;(FileAlterationObserver);generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;start;();generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;stop;();generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;stop;(long);generated", - "org.apache.commons.io.monitor;FileAlterationObserver;checkAndNotify;();generated", - "org.apache.commons.io.monitor;FileAlterationObserver;destroy;();generated", - "org.apache.commons.io.monitor;FileAlterationObserver;initialize;();generated", - "org.apache.commons.io.monitor;FileAlterationObserver;removeListener;(FileAlterationListener);generated", - "org.apache.commons.io.monitor;FileEntry;getLastModified;();generated", - "org.apache.commons.io.monitor;FileEntry;getLength;();generated", - "org.apache.commons.io.monitor;FileEntry;getLevel;();generated", - "org.apache.commons.io.monitor;FileEntry;isDirectory;();generated", - "org.apache.commons.io.monitor;FileEntry;isExists;();generated", - "org.apache.commons.io.monitor;FileEntry;refresh;(File);generated", - "org.apache.commons.io.monitor;FileEntry;setDirectory;(boolean);generated", - "org.apache.commons.io.monitor;FileEntry;setExists;(boolean);generated", - "org.apache.commons.io.monitor;FileEntry;setLastModified;(long);generated", - "org.apache.commons.io.monitor;FileEntry;setLength;(long);generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;AbstractByteArrayOutputStream;();generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;reset;();generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;size;();generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;toByteArray;();generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;toInputStream;();generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;write;(InputStream);generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;writeTo;(OutputStream);generated", - "org.apache.commons.io.output;BrokenOutputStream;BrokenOutputStream;();generated", - "org.apache.commons.io.output;BrokenOutputStream;BrokenOutputStream;(IOException);generated", - "org.apache.commons.io.output;BrokenWriter;BrokenWriter;();generated", - "org.apache.commons.io.output;BrokenWriter;BrokenWriter;(IOException);generated", - "org.apache.commons.io.output;ByteArrayOutputStream;ByteArrayOutputStream;();generated", - "org.apache.commons.io.output;ByteArrayOutputStream;ByteArrayOutputStream;(int);generated", - "org.apache.commons.io.output;ByteArrayOutputStream;toBufferedInputStream;(InputStream);generated", - "org.apache.commons.io.output;ByteArrayOutputStream;toBufferedInputStream;(InputStream,int);generated", - "org.apache.commons.io.output;ChunkedWriter;ChunkedWriter;(Writer);generated", - "org.apache.commons.io.output;ChunkedWriter;ChunkedWriter;(Writer,int);generated", - "org.apache.commons.io.output;CloseShieldWriter;CloseShieldWriter;(Writer);generated", - "org.apache.commons.io.output;CloseShieldWriter;wrap;(Writer);generated", - "org.apache.commons.io.output;ClosedOutputStream;ClosedOutputStream;();generated", - "org.apache.commons.io.output;ClosedWriter;ClosedWriter;();generated", - "org.apache.commons.io.output;CountingOutputStream;getByteCount;();generated", - "org.apache.commons.io.output;CountingOutputStream;getCount;();generated", - "org.apache.commons.io.output;CountingOutputStream;resetByteCount;();generated", - "org.apache.commons.io.output;CountingOutputStream;resetCount;();generated", - "org.apache.commons.io.output;DeferredFileOutputStream;isInMemory;();generated", - "org.apache.commons.io.output;DeferredFileOutputStream;toInputStream;();generated", - "org.apache.commons.io.output;DemuxOutputStream;DemuxOutputStream;();generated", - "org.apache.commons.io.output;DemuxOutputStream;bindStream;(OutputStream);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,Charset);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,Charset,boolean);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,CharsetEncoder);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,CharsetEncoder,boolean);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,String);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,String,boolean);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,Charset);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,Charset,boolean);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,CharsetEncoder);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,CharsetEncoder,boolean);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,String);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,String,boolean);generated", - "org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(File);generated", - "org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(File,Charset);generated", - "org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(File,String);generated", - "org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(File,boolean);generated", - "org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(String);generated", - "org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(String,boolean);generated", - "org.apache.commons.io.output;NullOutputStream;NullOutputStream;();generated", - "org.apache.commons.io.output;NullPrintStream;NullPrintStream;();generated", - "org.apache.commons.io.output;NullWriter;NullWriter;();generated", - "org.apache.commons.io.output;ProxyWriter;ProxyWriter;(Writer);generated", - "org.apache.commons.io.output;QueueOutputStream;QueueOutputStream;();generated", - "org.apache.commons.io.output;QueueOutputStream;QueueOutputStream;(BlockingQueue);generated", - "org.apache.commons.io.output;QueueOutputStream;newQueueInputStream;();generated", - "org.apache.commons.io.output;StringBuilderWriter;StringBuilderWriter;();generated", - "org.apache.commons.io.output;StringBuilderWriter;StringBuilderWriter;(int);generated", - "org.apache.commons.io.output;TaggedOutputStream;isCauseOf;(Exception);generated", - "org.apache.commons.io.output;TaggedOutputStream;throwIfCauseOf;(Exception);generated", - "org.apache.commons.io.output;TaggedWriter;TaggedWriter;(Writer);generated", - "org.apache.commons.io.output;TaggedWriter;isCauseOf;(Exception);generated", - "org.apache.commons.io.output;TaggedWriter;throwIfCauseOf;(Exception);generated", - "org.apache.commons.io.output;ThresholdingOutputStream;ThresholdingOutputStream;(int);generated", - "org.apache.commons.io.output;ThresholdingOutputStream;getByteCount;();generated", - "org.apache.commons.io.output;ThresholdingOutputStream;getThreshold;();generated", - "org.apache.commons.io.output;ThresholdingOutputStream;isThresholdExceeded;();generated", - "org.apache.commons.io.output;UncheckedFilterWriter;on;(Writer);generated", - "org.apache.commons.io.output;UnsynchronizedByteArrayOutputStream;UnsynchronizedByteArrayOutputStream;();generated", - "org.apache.commons.io.output;UnsynchronizedByteArrayOutputStream;UnsynchronizedByteArrayOutputStream;(int);generated", - "org.apache.commons.io.output;UnsynchronizedByteArrayOutputStream;toBufferedInputStream;(InputStream);generated", - "org.apache.commons.io.output;UnsynchronizedByteArrayOutputStream;toBufferedInputStream;(InputStream,int);generated", - "org.apache.commons.io.output;XmlStreamWriter;XmlStreamWriter;(File);generated", - "org.apache.commons.io.serialization;ClassNameMatcher;matches;(String);generated", - "org.apache.commons.io;ByteOrderMark;get;(int);generated", - "org.apache.commons.io;ByteOrderMark;getBytes;();generated", - "org.apache.commons.io;ByteOrderMark;length;();generated", - "org.apache.commons.io;ByteOrderParser;parseByteOrder;(String);generated", - "org.apache.commons.io;Charsets;Charsets;();generated", - "org.apache.commons.io;Charsets;requiredCharsets;();generated", - "org.apache.commons.io;Charsets;toCharset;(Charset);generated", - "org.apache.commons.io;Charsets;toCharset;(String);generated", - "org.apache.commons.io;CopyUtils;CopyUtils;();generated", - "org.apache.commons.io;CopyUtils;copy;(Reader,OutputStream);generated", - "org.apache.commons.io;CopyUtils;copy;(Reader,OutputStream,String);generated", - "org.apache.commons.io;CopyUtils;copy;(String,OutputStream);generated", - "org.apache.commons.io;CopyUtils;copy;(String,OutputStream,String);generated", - "org.apache.commons.io;DirectoryWalker$CancelException;getDepth;();generated", - "org.apache.commons.io;EndianUtils;EndianUtils;();generated", - "org.apache.commons.io;EndianUtils;readSwappedDouble;(InputStream);generated", - "org.apache.commons.io;EndianUtils;readSwappedDouble;(byte[],int);generated", - "org.apache.commons.io;EndianUtils;readSwappedFloat;(InputStream);generated", - "org.apache.commons.io;EndianUtils;readSwappedFloat;(byte[],int);generated", - "org.apache.commons.io;EndianUtils;readSwappedInteger;(InputStream);generated", - "org.apache.commons.io;EndianUtils;readSwappedInteger;(byte[],int);generated", - "org.apache.commons.io;EndianUtils;readSwappedLong;(InputStream);generated", - "org.apache.commons.io;EndianUtils;readSwappedLong;(byte[],int);generated", - "org.apache.commons.io;EndianUtils;readSwappedShort;(InputStream);generated", - "org.apache.commons.io;EndianUtils;readSwappedShort;(byte[],int);generated", - "org.apache.commons.io;EndianUtils;readSwappedUnsignedInteger;(InputStream);generated", - "org.apache.commons.io;EndianUtils;readSwappedUnsignedInteger;(byte[],int);generated", - "org.apache.commons.io;EndianUtils;readSwappedUnsignedShort;(InputStream);generated", - "org.apache.commons.io;EndianUtils;readSwappedUnsignedShort;(byte[],int);generated", - "org.apache.commons.io;EndianUtils;swapDouble;(double);generated", - "org.apache.commons.io;EndianUtils;swapFloat;(float);generated", - "org.apache.commons.io;EndianUtils;swapInteger;(int);generated", - "org.apache.commons.io;EndianUtils;swapLong;(long);generated", - "org.apache.commons.io;EndianUtils;swapShort;(short);generated", - "org.apache.commons.io;EndianUtils;writeSwappedDouble;(OutputStream,double);generated", - "org.apache.commons.io;EndianUtils;writeSwappedDouble;(byte[],int,double);generated", - "org.apache.commons.io;EndianUtils;writeSwappedFloat;(OutputStream,float);generated", - "org.apache.commons.io;EndianUtils;writeSwappedFloat;(byte[],int,float);generated", - "org.apache.commons.io;EndianUtils;writeSwappedInteger;(OutputStream,int);generated", - "org.apache.commons.io;EndianUtils;writeSwappedInteger;(byte[],int,int);generated", - "org.apache.commons.io;EndianUtils;writeSwappedLong;(OutputStream,long);generated", - "org.apache.commons.io;EndianUtils;writeSwappedLong;(byte[],int,long);generated", - "org.apache.commons.io;EndianUtils;writeSwappedShort;(OutputStream,short);generated", - "org.apache.commons.io;EndianUtils;writeSwappedShort;(byte[],int,short);generated", - "org.apache.commons.io;FileCleaner;FileCleaner;();generated", - "org.apache.commons.io;FileCleaner;exitWhenFinished;();generated", - "org.apache.commons.io;FileCleaner;getInstance;();generated", - "org.apache.commons.io;FileCleaner;getTrackCount;();generated", - "org.apache.commons.io;FileCleaner;track;(File,Object);generated", - "org.apache.commons.io;FileCleaner;track;(File,Object,FileDeleteStrategy);generated", - "org.apache.commons.io;FileCleaner;track;(String,Object);generated", - "org.apache.commons.io;FileCleaner;track;(String,Object,FileDeleteStrategy);generated", - "org.apache.commons.io;FileCleaningTracker;FileCleaningTracker;();generated", - "org.apache.commons.io;FileCleaningTracker;exitWhenFinished;();generated", - "org.apache.commons.io;FileCleaningTracker;getTrackCount;();generated", - "org.apache.commons.io;FileCleaningTracker;track;(File,Object);generated", - "org.apache.commons.io;FileCleaningTracker;track;(File,Object,FileDeleteStrategy);generated", - "org.apache.commons.io;FileCleaningTracker;track;(String,Object);generated", - "org.apache.commons.io;FileCleaningTracker;track;(String,Object,FileDeleteStrategy);generated", - "org.apache.commons.io;FileDeleteStrategy;delete;(File);generated", - "org.apache.commons.io;FileDeleteStrategy;deleteQuietly;(File);generated", - "org.apache.commons.io;FileExistsException;FileExistsException;();generated", - "org.apache.commons.io;FileExistsException;FileExistsException;(File);generated", - "org.apache.commons.io;FileExistsException;FileExistsException;(String);generated", - "org.apache.commons.io;FileSystem;getCurrent;();generated", - "org.apache.commons.io;FileSystem;getIllegalFileNameChars;();generated", - "org.apache.commons.io;FileSystem;getMaxFileNameLength;();generated", - "org.apache.commons.io;FileSystem;getMaxPathLength;();generated", - "org.apache.commons.io;FileSystem;getNameSeparator;();generated", - "org.apache.commons.io;FileSystem;getReservedFileNames;();generated", - "org.apache.commons.io;FileSystem;isCasePreserving;();generated", - "org.apache.commons.io;FileSystem;isCaseSensitive;();generated", - "org.apache.commons.io;FileSystem;isLegalFileName;(CharSequence);generated", - "org.apache.commons.io;FileSystem;isReservedFileName;(CharSequence);generated", - "org.apache.commons.io;FileSystem;supportsDriveLetter;();generated", - "org.apache.commons.io;FileSystemUtils;FileSystemUtils;();generated", - "org.apache.commons.io;FileSystemUtils;freeSpace;(String);generated", - "org.apache.commons.io;FileSystemUtils;freeSpaceKb;();generated", - "org.apache.commons.io;FileSystemUtils;freeSpaceKb;(String);generated", - "org.apache.commons.io;FileSystemUtils;freeSpaceKb;(String,long);generated", - "org.apache.commons.io;FileSystemUtils;freeSpaceKb;(long);generated", - "org.apache.commons.io;FileUtils;FileUtils;();generated", - "org.apache.commons.io;FileUtils;byteCountToDisplaySize;(BigInteger);generated", - "org.apache.commons.io;FileUtils;byteCountToDisplaySize;(Number);generated", - "org.apache.commons.io;FileUtils;byteCountToDisplaySize;(long);generated", - "org.apache.commons.io;FileUtils;checksumCRC32;(File);generated", - "org.apache.commons.io;FileUtils;cleanDirectory;(File);generated", - "org.apache.commons.io;FileUtils;contentEquals;(File,File);generated", - "org.apache.commons.io;FileUtils;contentEqualsIgnoreEOL;(File,File,String);generated", - "org.apache.commons.io;FileUtils;copyDirectory;(File,File);generated", - "org.apache.commons.io;FileUtils;copyDirectory;(File,File,FileFilter);generated", - "org.apache.commons.io;FileUtils;copyDirectory;(File,File,FileFilter,boolean);generated", - "org.apache.commons.io;FileUtils;copyDirectory;(File,File,FileFilter,boolean,CopyOption[]);generated", - "org.apache.commons.io;FileUtils;copyDirectory;(File,File,boolean);generated", - "org.apache.commons.io;FileUtils;copyDirectoryToDirectory;(File,File);generated", - "org.apache.commons.io;FileUtils;copyFile;(File,File);generated", - "org.apache.commons.io;FileUtils;copyFile;(File,File,CopyOption[]);generated", - "org.apache.commons.io;FileUtils;copyFile;(File,File,boolean);generated", - "org.apache.commons.io;FileUtils;copyFile;(File,File,boolean,CopyOption[]);generated", - "org.apache.commons.io;FileUtils;copyFile;(File,OutputStream);generated", - "org.apache.commons.io;FileUtils;copyFileToDirectory;(File,File);generated", - "org.apache.commons.io;FileUtils;copyFileToDirectory;(File,File,boolean);generated", - "org.apache.commons.io;FileUtils;copyInputStreamToFile;(InputStream,File);generated", - "org.apache.commons.io;FileUtils;copyToDirectory;(File,File);generated", - "org.apache.commons.io;FileUtils;copyToDirectory;(Iterable,File);generated", - "org.apache.commons.io;FileUtils;copyToFile;(InputStream,File);generated", - "org.apache.commons.io;FileUtils;copyURLToFile;(URL,File);generated", - "org.apache.commons.io;FileUtils;copyURLToFile;(URL,File,int,int);generated", - "org.apache.commons.io;FileUtils;createParentDirectories;(File);generated", - "org.apache.commons.io;FileUtils;current;();generated", - "org.apache.commons.io;FileUtils;deleteDirectory;(File);generated", - "org.apache.commons.io;FileUtils;deleteQuietly;(File);generated", - "org.apache.commons.io;FileUtils;directoryContains;(File,File);generated", - "org.apache.commons.io;FileUtils;forceDelete;(File);generated", - "org.apache.commons.io;FileUtils;forceDeleteOnExit;(File);generated", - "org.apache.commons.io;FileUtils;forceMkdir;(File);generated", - "org.apache.commons.io;FileUtils;forceMkdirParent;(File);generated", - "org.apache.commons.io;FileUtils;getTempDirectory;();generated", - "org.apache.commons.io;FileUtils;getTempDirectoryPath;();generated", - "org.apache.commons.io;FileUtils;getUserDirectory;();generated", - "org.apache.commons.io;FileUtils;getUserDirectoryPath;();generated", - "org.apache.commons.io;FileUtils;isDirectory;(File,LinkOption[]);generated", - "org.apache.commons.io;FileUtils;isEmptyDirectory;(File);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,ChronoLocalDate);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,ChronoLocalDate,LocalTime);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,ChronoLocalDateTime);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,ChronoLocalDateTime,ZoneId);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,ChronoZonedDateTime);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,Date);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,File);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,FileTime);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,Instant);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,long);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,ChronoLocalDate);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,ChronoLocalDate,LocalTime);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,ChronoLocalDateTime);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,ChronoLocalDateTime,ZoneId);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,ChronoZonedDateTime);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,Date);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,File);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,FileTime);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,Instant);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,long);generated", - "org.apache.commons.io;FileUtils;isRegularFile;(File,LinkOption[]);generated", - "org.apache.commons.io;FileUtils;isSymlink;(File);generated", - "org.apache.commons.io;FileUtils;iterateFiles;(File,IOFileFilter,IOFileFilter);generated", - "org.apache.commons.io;FileUtils;iterateFiles;(File,String[],boolean);generated", - "org.apache.commons.io;FileUtils;iterateFilesAndDirs;(File,IOFileFilter,IOFileFilter);generated", - "org.apache.commons.io;FileUtils;lastModified;(File);generated", - "org.apache.commons.io;FileUtils;lastModifiedFileTime;(File);generated", - "org.apache.commons.io;FileUtils;lastModifiedUnchecked;(File);generated", - "org.apache.commons.io;FileUtils;lineIterator;(File);generated", - "org.apache.commons.io;FileUtils;lineIterator;(File,String);generated", - "org.apache.commons.io;FileUtils;listFiles;(File,IOFileFilter,IOFileFilter);generated", - "org.apache.commons.io;FileUtils;listFiles;(File,String[],boolean);generated", - "org.apache.commons.io;FileUtils;listFilesAndDirs;(File,IOFileFilter,IOFileFilter);generated", - "org.apache.commons.io;FileUtils;moveDirectory;(File,File);generated", - "org.apache.commons.io;FileUtils;moveDirectoryToDirectory;(File,File,boolean);generated", - "org.apache.commons.io;FileUtils;moveFile;(File,File);generated", - "org.apache.commons.io;FileUtils;moveFile;(File,File,CopyOption[]);generated", - "org.apache.commons.io;FileUtils;moveFileToDirectory;(File,File,boolean);generated", - "org.apache.commons.io;FileUtils;moveToDirectory;(File,File,boolean);generated", - "org.apache.commons.io;FileUtils;newOutputStream;(File,boolean);generated", - "org.apache.commons.io;FileUtils;openInputStream;(File);generated", - "org.apache.commons.io;FileUtils;openOutputStream;(File);generated", - "org.apache.commons.io;FileUtils;openOutputStream;(File,boolean);generated", - "org.apache.commons.io;FileUtils;readFileToByteArray;(File);generated", - "org.apache.commons.io;FileUtils;readFileToString;(File);generated", - "org.apache.commons.io;FileUtils;readFileToString;(File,Charset);generated", - "org.apache.commons.io;FileUtils;readFileToString;(File,String);generated", - "org.apache.commons.io;FileUtils;readLines;(File);generated", - "org.apache.commons.io;FileUtils;readLines;(File,Charset);generated", - "org.apache.commons.io;FileUtils;readLines;(File,String);generated", - "org.apache.commons.io;FileUtils;sizeOf;(File);generated", - "org.apache.commons.io;FileUtils;sizeOfAsBigInteger;(File);generated", - "org.apache.commons.io;FileUtils;sizeOfDirectory;(File);generated", - "org.apache.commons.io;FileUtils;sizeOfDirectoryAsBigInteger;(File);generated", - "org.apache.commons.io;FileUtils;streamFiles;(File,boolean,String[]);generated", - "org.apache.commons.io;FileUtils;toFile;(URL);generated", - "org.apache.commons.io;FileUtils;toFiles;(URL[]);generated", - "org.apache.commons.io;FileUtils;touch;(File);generated", - "org.apache.commons.io;FileUtils;waitFor;(File,int);generated", - "org.apache.commons.io;FileUtils;write;(File,CharSequence);generated", - "org.apache.commons.io;FileUtils;write;(File,CharSequence,Charset);generated", - "org.apache.commons.io;FileUtils;write;(File,CharSequence,Charset,boolean);generated", - "org.apache.commons.io;FileUtils;write;(File,CharSequence,String);generated", - "org.apache.commons.io;FileUtils;write;(File,CharSequence,String,boolean);generated", - "org.apache.commons.io;FileUtils;write;(File,CharSequence,boolean);generated", - "org.apache.commons.io;FileUtils;writeByteArrayToFile;(File,byte[]);generated", - "org.apache.commons.io;FileUtils;writeByteArrayToFile;(File,byte[],boolean);generated", - "org.apache.commons.io;FileUtils;writeByteArrayToFile;(File,byte[],int,int);generated", - "org.apache.commons.io;FileUtils;writeByteArrayToFile;(File,byte[],int,int,boolean);generated", - "org.apache.commons.io;FileUtils;writeLines;(File,Collection);generated", - "org.apache.commons.io;FileUtils;writeLines;(File,Collection,String);generated", - "org.apache.commons.io;FileUtils;writeLines;(File,Collection,String,boolean);generated", - "org.apache.commons.io;FileUtils;writeLines;(File,Collection,boolean);generated", - "org.apache.commons.io;FileUtils;writeLines;(File,String,Collection);generated", - "org.apache.commons.io;FileUtils;writeLines;(File,String,Collection,String);generated", - "org.apache.commons.io;FileUtils;writeLines;(File,String,Collection,String,boolean);generated", - "org.apache.commons.io;FileUtils;writeLines;(File,String,Collection,boolean);generated", - "org.apache.commons.io;FileUtils;writeStringToFile;(File,String);generated", - "org.apache.commons.io;FileUtils;writeStringToFile;(File,String,Charset);generated", - "org.apache.commons.io;FileUtils;writeStringToFile;(File,String,Charset,boolean);generated", - "org.apache.commons.io;FileUtils;writeStringToFile;(File,String,String);generated", - "org.apache.commons.io;FileUtils;writeStringToFile;(File,String,String,boolean);generated", - "org.apache.commons.io;FileUtils;writeStringToFile;(File,String,boolean);generated", - "org.apache.commons.io;FilenameUtils;FilenameUtils;();generated", - "org.apache.commons.io;FilenameUtils;directoryContains;(String,String);generated", - "org.apache.commons.io;FilenameUtils;equals;(String,String);generated", - "org.apache.commons.io;FilenameUtils;equals;(String,String,boolean,IOCase);generated", - "org.apache.commons.io;FilenameUtils;equalsNormalized;(String,String);generated", - "org.apache.commons.io;FilenameUtils;equalsNormalizedOnSystem;(String,String);generated", - "org.apache.commons.io;FilenameUtils;equalsOnSystem;(String,String);generated", - "org.apache.commons.io;FilenameUtils;getPrefixLength;(String);generated", - "org.apache.commons.io;FilenameUtils;indexOfExtension;(String);generated", - "org.apache.commons.io;FilenameUtils;indexOfLastSeparator;(String);generated", - "org.apache.commons.io;FilenameUtils;isExtension;(String,Collection);generated", - "org.apache.commons.io;FilenameUtils;isExtension;(String,String);generated", - "org.apache.commons.io;FilenameUtils;isExtension;(String,String[]);generated", - "org.apache.commons.io;FilenameUtils;wildcardMatch;(String,String);generated", - "org.apache.commons.io;FilenameUtils;wildcardMatch;(String,String,IOCase);generated", - "org.apache.commons.io;FilenameUtils;wildcardMatchOnSystem;(String,String);generated", - "org.apache.commons.io;HexDump;HexDump;();generated", - "org.apache.commons.io;HexDump;dump;(byte[],long,OutputStream,int);generated", - "org.apache.commons.io;IOCase;checkCompareTo;(String,String);generated", - "org.apache.commons.io;IOCase;checkEndsWith;(String,String);generated", - "org.apache.commons.io;IOCase;checkEquals;(String,String);generated", - "org.apache.commons.io;IOCase;checkIndexOf;(String,int,String);generated", - "org.apache.commons.io;IOCase;checkRegionMatches;(String,int,String);generated", - "org.apache.commons.io;IOCase;checkStartsWith;(String,String);generated", - "org.apache.commons.io;IOCase;forName;(String);generated", - "org.apache.commons.io;IOCase;getName;();generated", - "org.apache.commons.io;IOCase;isCaseSensitive;();generated", - "org.apache.commons.io;IOCase;isCaseSensitive;(IOCase);generated", - "org.apache.commons.io;IOCase;toString;();generated", - "org.apache.commons.io;IOCase;value;(IOCase,IOCase);generated", - "org.apache.commons.io;IOExceptionList;checkEmpty;(List,Object);generated", - "org.apache.commons.io;IOExceptionList;getCause;(int,Class);generated", - "org.apache.commons.io;IOExceptionWithCause;IOExceptionWithCause;(String,Throwable);generated", - "org.apache.commons.io;IOExceptionWithCause;IOExceptionWithCause;(Throwable);generated", - "org.apache.commons.io;IOIndexedException;IOIndexedException;(int,Throwable);generated", - "org.apache.commons.io;IOIndexedException;getIndex;();generated", - "org.apache.commons.io;IOUtils;IOUtils;();generated", - "org.apache.commons.io;IOUtils;byteArray;();generated", - "org.apache.commons.io;IOUtils;byteArray;(int);generated", - "org.apache.commons.io;IOUtils;close;(Closeable);generated", - "org.apache.commons.io;IOUtils;close;(Closeable,IOConsumer);generated", - "org.apache.commons.io;IOUtils;close;(Closeable[]);generated", - "org.apache.commons.io;IOUtils;close;(URLConnection);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(Closeable);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(Closeable,Consumer);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(Closeable[]);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(InputStream);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(OutputStream);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(Reader);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(Selector);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(ServerSocket);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(Socket);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(Writer);generated", - "org.apache.commons.io;IOUtils;consume;(InputStream);generated", - "org.apache.commons.io;IOUtils;contentEquals;(InputStream,InputStream);generated", - "org.apache.commons.io;IOUtils;contentEquals;(Reader,Reader);generated", - "org.apache.commons.io;IOUtils;contentEqualsIgnoreEOL;(Reader,Reader);generated", - "org.apache.commons.io;IOUtils;copy;(ByteArrayOutputStream);generated", - "org.apache.commons.io;IOUtils;copy;(Reader,OutputStream);generated", - "org.apache.commons.io;IOUtils;copy;(Reader,OutputStream,Charset);generated", - "org.apache.commons.io;IOUtils;copy;(Reader,OutputStream,String);generated", - "org.apache.commons.io;IOUtils;copy;(URL,File);generated", - "org.apache.commons.io;IOUtils;copy;(URL,OutputStream);generated", - "org.apache.commons.io;IOUtils;length;(CharSequence);generated", - "org.apache.commons.io;IOUtils;length;(Object[]);generated", - "org.apache.commons.io;IOUtils;length;(byte[]);generated", - "org.apache.commons.io;IOUtils;length;(char[]);generated", - "org.apache.commons.io;IOUtils;resourceToByteArray;(String);generated", - "org.apache.commons.io;IOUtils;resourceToByteArray;(String,ClassLoader);generated", - "org.apache.commons.io;IOUtils;resourceToString;(String,Charset);generated", - "org.apache.commons.io;IOUtils;resourceToString;(String,Charset,ClassLoader);generated", - "org.apache.commons.io;IOUtils;resourceToURL;(String);generated", - "org.apache.commons.io;IOUtils;resourceToURL;(String,ClassLoader);generated", - "org.apache.commons.io;IOUtils;skip;(InputStream,long);generated", - "org.apache.commons.io;IOUtils;skip;(ReadableByteChannel,long);generated", - "org.apache.commons.io;IOUtils;skip;(Reader,long);generated", - "org.apache.commons.io;IOUtils;skipFully;(InputStream,long);generated", - "org.apache.commons.io;IOUtils;skipFully;(ReadableByteChannel,long);generated", - "org.apache.commons.io;IOUtils;skipFully;(Reader,long);generated", - "org.apache.commons.io;IOUtils;toBufferedInputStream;(InputStream);generated", - "org.apache.commons.io;IOUtils;toBufferedInputStream;(InputStream,int);generated", - "org.apache.commons.io;IOUtils;toByteArray;(InputStream);generated", - "org.apache.commons.io;IOUtils;toByteArray;(Reader);generated", - "org.apache.commons.io;IOUtils;toByteArray;(Reader,Charset);generated", - "org.apache.commons.io;IOUtils;toByteArray;(Reader,String);generated", - "org.apache.commons.io;IOUtils;toByteArray;(URI);generated", - "org.apache.commons.io;IOUtils;toByteArray;(URL);generated", - "org.apache.commons.io;IOUtils;toByteArray;(URLConnection);generated", - "org.apache.commons.io;IOUtils;toString;(URI);generated", - "org.apache.commons.io;IOUtils;toString;(URI,Charset);generated", - "org.apache.commons.io;IOUtils;toString;(URI,String);generated", - "org.apache.commons.io;IOUtils;toString;(URL);generated", - "org.apache.commons.io;IOUtils;toString;(URL,Charset);generated", - "org.apache.commons.io;IOUtils;toString;(URL,String);generated", - "org.apache.commons.io;IOUtils;write;(CharSequence,OutputStream);generated", - "org.apache.commons.io;IOUtils;write;(CharSequence,OutputStream,Charset);generated", - "org.apache.commons.io;IOUtils;write;(CharSequence,OutputStream,String);generated", - "org.apache.commons.io;IOUtils;write;(String,OutputStream);generated", - "org.apache.commons.io;IOUtils;write;(String,OutputStream,Charset);generated", - "org.apache.commons.io;IOUtils;write;(String,OutputStream,String);generated", - "org.apache.commons.io;IOUtils;write;(StringBuffer,OutputStream);generated", - "org.apache.commons.io;IOUtils;write;(StringBuffer,OutputStream,String);generated", - "org.apache.commons.io;IOUtils;write;(char[],OutputStream);generated", - "org.apache.commons.io;IOUtils;write;(char[],OutputStream,Charset);generated", - "org.apache.commons.io;IOUtils;write;(char[],OutputStream,String);generated", - "org.apache.commons.io;LineIterator;closeQuietly;(LineIterator);generated", - "org.apache.commons.io;RandomAccessFileMode;create;(File);generated", - "org.apache.commons.io;RandomAccessFileMode;create;(Path);generated", - "org.apache.commons.io;RandomAccessFileMode;create;(String);generated", - "org.apache.commons.io;RandomAccessFileMode;toString;();generated", - "org.apache.commons.io;StandardLineSeparator;getBytes;(Charset);generated", - "org.apache.commons.io;StandardLineSeparator;getString;();generated", - "org.apache.commons.io;TaggedIOException;isTaggedWith;(Throwable,Object);generated", - "org.apache.commons.io;TaggedIOException;throwCauseIfTaggedWith;(Throwable,Object);generated", - "org.apache.commons.io;UncheckedIO;UncheckedIO;();generated", - "org.apache.commons.io;UncheckedIO;accept;(IOConsumer,Object);generated", - "org.apache.commons.io;UncheckedIO;apply;(IOBiFunction,Object,Object);generated", - "org.apache.commons.io;UncheckedIO;get;(IOSupplier);generated", - "org.apache.commons.io;UncheckedIO;run;(IORunnable);generated", - "org.apache.commons.io;UncheckedIOExceptions;UncheckedIOExceptions;();generated", - "org.apache.commons.io;UncheckedIOExceptions;create;(Object);generated", - "org.apache.commons.io;UncheckedIOExceptions;wrap;(IOException,Object);generated" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/generated.qll b/java/ql/lib/semmle/code/java/frameworks/generated.qll index 7a16e24890e..cc088532c6d 100644 --- a/java/ql/lib/semmle/code/java/frameworks/generated.qll +++ b/java/ql/lib/semmle/code/java/frameworks/generated.qll @@ -5,6 +5,5 @@ import java private module GeneratedFrameworks { - private import apache.IOGenerated private import kotlin.StdLibGenerated } diff --git a/java/ql/src/Telemetry/UnsupportedExternalAPIs.ql b/java/ql/src/Telemetry/UnsupportedExternalAPIs.ql index 16871f87a53..b1721972dd3 100644 --- a/java/ql/src/Telemetry/UnsupportedExternalAPIs.ql +++ b/java/ql/src/Telemetry/UnsupportedExternalAPIs.ql @@ -8,7 +8,6 @@ import java import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl -import semmle.code.java.dataflow.internal.NegativeSummary import ExternalApi private predicate relevant(ExternalApi api) { diff --git a/java/ql/test/library-tests/dataflow/external-models/negativesummaries.ql b/java/ql/test/library-tests/dataflow/external-models/negativesummaries.ql index b1e104a0fcd..32e2c4bc5cc 100644 --- a/java/ql/test/library-tests/dataflow/external-models/negativesummaries.ql +++ b/java/ql/test/library-tests/dataflow/external-models/negativesummaries.ql @@ -5,4 +5,3 @@ import java import semmle.code.java.dataflow.ExternalFlow import ModelValidation -import semmle.code.java.dataflow.internal.NegativeSummary From b61f515af26764d67158c201e0c78eb3cd5e909f Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 21 Nov 2022 15:37:13 +0100 Subject: [PATCH 572/796] Jave: Make support for query specific models. --- java/ql/lib/ext/experimental/dummy.model.yml | 15 ++++ java/ql/lib/qlpack.yml | 1 + .../code/java/dataflow/ExternalFlow.qll | 80 +++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 java/ql/lib/ext/experimental/dummy.model.yml diff --git a/java/ql/lib/ext/experimental/dummy.model.yml b/java/ql/lib/ext/experimental/dummy.model.yml new file mode 100644 index 00000000000..d1521d27a9c --- /dev/null +++ b/java/ql/lib/ext/experimental/dummy.model.yml @@ -0,0 +1,15 @@ +# Define the extensible prediactes related to experimental queries +# to at least be empty. +extensions: + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSourceModel + data: [] + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSinkModel + data: [] + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSummaryModel + data: [] diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index ed5323ebe4a..3dd389eb958 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -10,3 +10,4 @@ dependencies: dataExtensions: - ext/*.model.yml - ext/generated/*.model.yml + - ext/experimental/*.model.yml diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index b9688809c45..866e3f5687f 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -194,6 +194,77 @@ private predicate negativeSummaryModelInternal(string row) { any(NegativeSummaryModelCsvInternal s).row(row) } +/** + * Holds if an experimental source model exists for the given parameters. + * This is only for experimental queries. + */ +extensible predicate extExperimentalSourceModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string output, string kind, string provenance, string filter +); + +/** + * Holds if an experimental sink model exists for the given parameters. + * This is only for experimental queries. + */ +extensible predicate extExperimentalSinkModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string input, string kind, string provenance, string filter +); + +/** + * Holds if an experimental summary model exists for the given parameters. + * This is only for experimental queries. + */ +extensible predicate extExperimentalSummaryModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string input, string output, string kind, string provenance, string filter +); + +/** + * A class for activating additional model rows. + * + * Extend this class to include experimental model rows with `this` name + * in data flow analysis. + */ +abstract class ActiveExperimentalModels extends string { + bindingset[this] + ActiveExperimentalModels() { any() } + + /** + * Holds if an experimental source model exists for the given parameters. + */ + predicate sourceModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string output, string kind, string provenance + ) { + extExperimentalSourceModel(package, type, subtypes, name, signature, ext, output, kind, + provenance, this) + } + + /** + * Holds if an experimental sink model exists for the given parameters. + */ + predicate sinkModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string output, string kind, string provenance + ) { + extExperimentalSinkModel(package, type, subtypes, name, signature, ext, output, kind, + provenance, this) + } + + /** + * Holds if an experimental summary model exists for the given parameters. + */ + predicate summaryModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string input, string output, string kind, string provenance + ) { + extExperimentalSummaryModel(package, type, subtypes, name, signature, ext, input, output, kind, + provenance, this) + } +} + /** * Holds if a source model exists for the given parameters. */ @@ -222,6 +293,9 @@ predicate sourceModel( ) or extSourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance) + or + any(ActiveExperimentalModels q) + .sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance) } /** Holds if a sink model exists for the given parameters. */ @@ -250,6 +324,9 @@ predicate sinkModel( ) or extSinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance) + or + any(ActiveExperimentalModels q) + .sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance) } /** Holds if a summary model exists for the given parameters. */ @@ -279,6 +356,9 @@ predicate summaryModel( ) or extSummaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) + or + any(ActiveExperimentalModels q) + .summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) } /** Holds if a summary model exists indicating there is no flow for the given parameters. */ From 665d40dc4be8904dac81b8e92bf627a999ad440d Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 21 Nov 2022 15:44:12 +0100 Subject: [PATCH 573/796] Java: Convert file-path-injection to data extensions. --- .../experimental/com.jfinal.core.model.yml | 28 +++++++++++++++++++ .../Security/CWE/CWE-073/FilePathInjection.ql | 5 ++++ .../Security/CWE/CWE-073/JFinalController.qll | 21 -------------- 3 files changed, 33 insertions(+), 21 deletions(-) create mode 100644 java/ql/lib/ext/experimental/com.jfinal.core.model.yml diff --git a/java/ql/lib/ext/experimental/com.jfinal.core.model.yml b/java/ql/lib/ext/experimental/com.jfinal.core.model.yml new file mode 100644 index 00000000000..078e86a4817 --- /dev/null +++ b/java/ql/lib/ext/experimental/com.jfinal.core.model.yml @@ -0,0 +1,28 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSourceModel + data: + - ["com.jfinal.core", "Controller", True, "get", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getBoolean", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getCookie", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getCookieObject", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getCookieObjects", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getCookieToInt", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getCookieToLong", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getDate", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getFile", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getFiles", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getHeader", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getInt", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getKv", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getLong", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getPara", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getParaMap", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getParaToBoolean", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getParaToDate", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getParaToInt", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getParaToLong", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getParaValues", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getParaValuesToInt", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getParaValuesToLong", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] diff --git a/java/ql/src/experimental/Security/CWE/CWE-073/FilePathInjection.ql b/java/ql/src/experimental/Security/CWE/CWE-073/FilePathInjection.ql index fff9a3b3613..9c976c8dce7 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-073/FilePathInjection.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-073/FilePathInjection.ql @@ -12,12 +12,17 @@ */ import java +import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.PathCreation import JFinalController import semmle.code.java.security.PathSanitizer import DataFlow::PathGraph +private class ActivateModels extends ActiveExperimentalModels { + ActivateModels() { this = "file-path-injection" } +} + /** A complementary sanitizer that protects against path traversal using path normalization. */ class PathNormalizeSanitizer extends MethodAccess { PathNormalizeSanitizer() { diff --git a/java/ql/src/experimental/Security/CWE/CWE-073/JFinalController.qll b/java/ql/src/experimental/Security/CWE/CWE-073/JFinalController.qll index df3b77cddaa..94cd966da9d 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-073/JFinalController.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-073/JFinalController.qll @@ -61,24 +61,3 @@ private class SetToGetAttributeStep extends AdditionalValueStep { ) } } - -/** Remote flow source models relating to `JFinal`. */ -private class JFinalControllerSource extends SourceModelCsv { - override predicate row(string row) { - row = - [ - "com.jfinal.core;Controller;true;getCookie" + ["", "Object", "Objects", "ToInt", "ToLong"] + - ";;;ReturnValue;remote;manual", - "com.jfinal.core;Controller;true;getFile" + ["", "s"] + ";;;ReturnValue;remote;manual", - "com.jfinal.core;Controller;true;getHeader;;;ReturnValue;remote;manual", - "com.jfinal.core;Controller;true;getKv;;;ReturnValue;remote;manual", - "com.jfinal.core;Controller;true;getPara" + - [ - "", "Map", "ToBoolean", "ToDate", "ToInt", "ToLong", "Values", "ValuesToInt", - "ValuesToLong" - ] + ";;;ReturnValue;remote;manual", - "com.jfinal.core;Controller;true;get" + ["", "Int", "Long", "Boolean", "Date"] + - ";;;ReturnValue;remote;manual" - ] - } -} From 5c15ad412c7406edb9acbd264229b14b8782d67a Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 22 Nov 2022 08:52:11 +0100 Subject: [PATCH 574/796] Java: Convert log4j-injection to data extensions. --- ...org.apache.logging.log4j.message.model.yml | 9 + .../org.apache.logging.log4j.model.yml | 362 ++++++++++++++++++ .../CWE/CWE-020/Log4jJndiInjection.ql | 155 +------- 3 files changed, 373 insertions(+), 153 deletions(-) create mode 100644 java/ql/lib/ext/experimental/org.apache.logging.log4j.message.model.yml create mode 100644 java/ql/lib/ext/experimental/org.apache.logging.log4j.model.yml diff --git a/java/ql/lib/ext/experimental/org.apache.logging.log4j.message.model.yml b/java/ql/lib/ext/experimental/org.apache.logging.log4j.message.model.yml new file mode 100644 index 00000000000..16b401d219d --- /dev/null +++ b/java/ql/lib/ext/experimental/org.apache.logging.log4j.message.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSummaryModel + data: + - ["org.apache.logging.log4j.message", "MapMessage", True, "put", "", "", "Argument[1]", "Argument[-1]", "taint", "manual", "log4j-injection"] + - ["org.apache.logging.log4j.message", "MapMessage", True, "putAll", "", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual", "log4j-injection"] + - ["org.apache.logging.log4j.message", "MapMessage", True, "with", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "log4j-injection"] + - ["org.apache.logging.log4j.message", "MapMessage", True, "with", "", "", "Argument[1]", "Argument[-1]", "taint", "manual", "log4j-injection"] diff --git a/java/ql/lib/ext/experimental/org.apache.logging.log4j.model.yml b/java/ql/lib/ext/experimental/org.apache.logging.log4j.model.yml new file mode 100644 index 00000000000..3c8a2867a65 --- /dev/null +++ b/java/ql/lib/ext/experimental/org.apache.logging.log4j.model.yml @@ -0,0 +1,362 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSinkModel + data: + - ["org.apache.logging.log4j", "CloseableThreadContext", False, "put", "", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "CloseableThreadContext", False, "putAll", "", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "CloseableThreadContext$Instance", False, "put", "", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "CloseableThreadContext$Instance", False, "putAll", "", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(CharSequence)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Message)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Object)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object)", "", "Argument[0..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object)", "", "Argument[0..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object[])", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Supplier[])", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Supplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(CharSequence)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(CharSequence,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,CharSequence)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Message)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,MessageSupplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Object)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Object,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object[])", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Supplier)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Supplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Message)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Message,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(MessageSupplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(MessageSupplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Object)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object)", "", "Argument[0..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object)", "", "Argument[0..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object[])", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Supplier)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Supplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Supplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "entry", "(Object[])", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(CharSequence)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(CharSequence,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,CharSequence)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Message)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,MessageSupplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Object)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Object,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object[])", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Supplier)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Supplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Message)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Message,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(MessageSupplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(MessageSupplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Object)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Object,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object)", "", "Argument[0..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object)", "", "Argument[0..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object[])", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Supplier)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Supplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Supplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(CharSequence)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(CharSequence,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,CharSequence)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Message)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,MessageSupplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Object)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Object,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object[])", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Supplier)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Supplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Message)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Message,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(MessageSupplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(MessageSupplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Object)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Object,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object)", "", "Argument[0..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object)", "", "Argument[0..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object[])", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Supplier)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Supplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Supplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(CharSequence)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(CharSequence,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,CharSequence)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Message)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,MessageSupplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Object)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Object,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object[])", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Supplier)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Supplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Message)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Message,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(MessageSupplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(MessageSupplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Object)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Object,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object)", "", "Argument[0..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object)", "", "Argument[0..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object[])", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Supplier)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Supplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Supplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,CharSequence)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,CharSequence,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,CharSequence)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,CharSequence,Throwable)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Message)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,MessageSupplier)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,MessageSupplier,Throwable)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Object)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Object,Throwable)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object)", "", "Argument[2..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object)", "", "Argument[2..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object)", "", "Argument[2..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object)", "", "Argument[2..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object)", "", "Argument[2..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[2..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..11]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..12]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object[])", "", "Argument[2..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Supplier)", "", "Argument[2..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Throwable)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Supplier)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Supplier,Throwable)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Message)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Message,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,MessageSupplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,MessageSupplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Object)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Object,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object)", "", "Argument[1..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object[])", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Supplier)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Supplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Supplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "logMessage", "(Level,Marker,String,StackTraceElement,Message,Throwable)", "", "Argument[4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "printf", "(Level,Marker,String,Object[])", "", "Argument[2..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "printf", "(Level,String,Object[])", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(CharSequence)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(CharSequence,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,CharSequence)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Message)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,MessageSupplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Object)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Object,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object[])", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Supplier)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Supplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Message)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Message,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(MessageSupplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(MessageSupplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Object)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object)", "", "Argument[0..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object)", "", "Argument[0..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object[])", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Supplier)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Supplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Supplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(CharSequence)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(CharSequence,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,CharSequence)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Message)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,MessageSupplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Object)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Object,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object[])", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Supplier)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Supplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Message)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Message,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(MessageSupplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(MessageSupplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Object)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object)", "", "Argument[0..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object)", "", "Argument[0..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object[])", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Supplier)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Supplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Supplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "ThreadContext", False, "put", "", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "ThreadContext", False, "putAll", "", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "ThreadContext", False, "putIfNull", "", "", "Argument[1]", "log4j", "manual", "log4j-injection"] diff --git a/java/ql/src/experimental/Security/CWE/CWE-020/Log4jJndiInjection.ql b/java/ql/src/experimental/Security/CWE/CWE-020/Log4jJndiInjection.ql index 7b70a2e47d9..369833a4df2 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-020/Log4jJndiInjection.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-020/Log4jJndiInjection.ql @@ -19,159 +19,8 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.dataflow.ExternalFlow import DataFlow::PathGraph -private class Log4jLoggingSinkModels extends SinkModelCsv { - override predicate row(string row) { - row = - [ - // org.apache.logging.log4j.Logger - "org.apache.logging.log4j;Logger;true;" + - ["debug", "error", "fatal", "info", "trace", "warn"] + - [ - ";(CharSequence);;Argument[0];log4j;manual", - ";(CharSequence,Throwable);;Argument[0];log4j;manual", - ";(Marker,CharSequence);;Argument[1];log4j;manual", - ";(Marker,CharSequence,Throwable);;Argument[1];log4j;manual", - ";(Marker,Message);;Argument[1];log4j;manual", - ";(Marker,MessageSupplier);;Argument[1];log4j;manual", - ";(Marker,MessageSupplier);;Argument[1];log4j;manual", - ";(Marker,MessageSupplier,Throwable);;Argument[1];log4j;manual", - ";(Marker,Object);;Argument[1];log4j;manual", - ";(Marker,Object,Throwable);;Argument[1];log4j;manual", - ";(Marker,String);;Argument[1];log4j;manual", - ";(Marker,String,Object[]);;Argument[1..2];log4j;manual", - ";(Marker,String,Object);;Argument[1..2];log4j;manual", - ";(Marker,String,Object,Object);;Argument[1..3];log4j;manual", - ";(Marker,String,Object,Object,Object);;Argument[1..4];log4j;manual", - ";(Marker,String,Object,Object,Object,Object);;Argument[1..5];log4j;manual", - ";(Marker,String,Object,Object,Object,Object,Object);;Argument[1..6];log4j;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object);;Argument[1..7];log4j;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object,Object);;Argument[1..8];log4j;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..9];log4j;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..10];log4j;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..11];log4j;manual", - ";(Marker,String,Supplier);;Argument[1..2];log4j;manual", - ";(Marker,String,Throwable);;Argument[1];log4j;manual", - ";(Marker,Supplier);;Argument[1];log4j;manual", - ";(Marker,Supplier,Throwable);;Argument[1];log4j;manual", - ";(MessageSupplier);;Argument[0];log4j;manual", - ";(MessageSupplier,Throwable);;Argument[0];log4j;manual", - ";(Message);;Argument[0];log4j;manual", - ";(Message,Throwable);;Argument[0];log4j;manual", ";(Object);;Argument[0];log4j;manual", - ";(Object,Throwable);;Argument[0];log4j;manual", ";(String);;Argument[0];log4j;manual", - ";(String,Object[]);;Argument[0..1];log4j;manual", - ";(String,Object);;Argument[0..1];log4j;manual", - ";(String,Object,Object);;Argument[0..2];log4j;manual", - ";(String,Object,Object,Object);;Argument[0..3];log4j;manual", - ";(String,Object,Object,Object,Object);;Argument[0..4];log4j;manual", - ";(String,Object,Object,Object,Object,Object);;Argument[0..5];log4j;manual", - ";(String,Object,Object,Object,Object,Object,Object);;Argument[0..6];log4j;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];log4j;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..8];log4j;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];log4j;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..10];log4j;manual", - ";(String,Supplier);;Argument[0..1];log4j;manual", - ";(String,Throwable);;Argument[0];log4j;manual", - ";(Supplier);;Argument[0];log4j;manual", - ";(Supplier,Throwable);;Argument[0];log4j;manual" - ], - "org.apache.logging.log4j;Logger;true;log" + - [ - ";(Level,CharSequence);;Argument[1];log4j;manual", - ";(Level,CharSequence,Throwable);;Argument[1];log4j;manual", - ";(Level,Marker,CharSequence);;Argument[2];log4j;manual", - ";(Level,Marker,CharSequence,Throwable);;Argument[2];log4j;manual", - ";(Level,Marker,Message);;Argument[2];log4j;manual", - ";(Level,Marker,MessageSupplier);;Argument[2];log4j;manual", - ";(Level,Marker,MessageSupplier);;Argument[2];log4j;manual", - ";(Level,Marker,MessageSupplier,Throwable);;Argument[2];log4j;manual", - ";(Level,Marker,Object);;Argument[2];log4j;manual", - ";(Level,Marker,Object,Throwable);;Argument[2];log4j;manual", - ";(Level,Marker,String);;Argument[2];log4j;manual", - ";(Level,Marker,String,Object[]);;Argument[2..3];log4j;manual", - ";(Level,Marker,String,Object);;Argument[2..3];log4j;manual", - ";(Level,Marker,String,Object,Object);;Argument[2..4];log4j;manual", - ";(Level,Marker,String,Object,Object,Object);;Argument[2..5];log4j;manual", - ";(Level,Marker,String,Object,Object,Object,Object);;Argument[2..6];log4j;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object);;Argument[2..7];log4j;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object);;Argument[2..8];log4j;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object);;Argument[2..9];log4j;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2..10];log4j;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2..11];log4j;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2..12];log4j;manual", - ";(Level,Marker,String,Supplier);;Argument[2..3];log4j;manual", - ";(Level,Marker,String,Throwable);;Argument[2];log4j;manual", - ";(Level,Marker,Supplier);;Argument[2];log4j;manual", - ";(Level,Marker,Supplier,Throwable);;Argument[2];log4j;manual", - ";(Level,Message);;Argument[1];log4j;manual", - ";(Level,MessageSupplier);;Argument[1];log4j;manual", - ";(Level,MessageSupplier,Throwable);;Argument[1];log4j;manual", - ";(Level,Message);;Argument[1];log4j;manual", - ";(Level,Message,Throwable);;Argument[1];log4j;manual", - ";(Level,Object);;Argument[1];log4j;manual", - ";(Level,Object);;Argument[1];log4j;manual", - ";(Level,String);;Argument[1];log4j;manual", - ";(Level,Object,Throwable);;Argument[1];log4j;manual", - ";(Level,String);;Argument[1];log4j;manual", - ";(Level,String,Object[]);;Argument[1..2];log4j;manual", - ";(Level,String,Object);;Argument[1..2];log4j;manual", - ";(Level,String,Object,Object);;Argument[1..3];log4j;manual", - ";(Level,String,Object,Object,Object);;Argument[1..4];log4j;manual", - ";(Level,String,Object,Object,Object,Object);;Argument[1..5];log4j;manual", - ";(Level,String,Object,Object,Object,Object,Object);;Argument[1..6];log4j;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object);;Argument[1..7];log4j;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object,Object);;Argument[1..8];log4j;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..9];log4j;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..10];log4j;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..11];log4j;manual", - ";(Level,String,Supplier);;Argument[1..2];log4j;manual", - ";(Level,String,Throwable);;Argument[1];log4j;manual", - ";(Level,Supplier);;Argument[1];log4j;manual", - ";(Level,Supplier,Throwable);;Argument[1];log4j;manual" - ], "org.apache.logging.log4j;Logger;true;entry;(Object[]);;Argument[0];log4j;manual", - "org.apache.logging.log4j;Logger;true;logMessage;(Level,Marker,String,StackTraceElement,Message,Throwable);;Argument[4];log4j;manual", - "org.apache.logging.log4j;Logger;true;printf;(Level,Marker,String,Object[]);;Argument[2..3];log4j;manual", - "org.apache.logging.log4j;Logger;true;printf;(Level,String,Object[]);;Argument[1..2];log4j;manual", - // org.apache.logging.log4j.LogBuilder - "org.apache.logging.log4j;LogBuilder;true;log;(CharSequence);;Argument[0];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(Message);;Argument[0];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(Object);;Argument[0];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String);;Argument[0];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object[]);;Argument[0..1];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object);;Argument[0..1];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object);;Argument[0..2];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object);;Argument[0..3];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object);;Argument[0..4];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object);;Argument[0..5];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object);;Argument[0..6];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..8];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..10];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Supplier[]);;Argument[0..1];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(Supplier);;Argument[0];log4j;manual", - // org.apache.logging.log4j.ThreadContext - "org.apache.logging.log4j;ThreadContext;false;put;;;Argument[1];log4j;manual", - "org.apache.logging.log4j;ThreadContext;false;putIfNull;;;Argument[1];log4j;manual", - "org.apache.logging.log4j;ThreadContext;false;putAll;;;Argument[0];log4j;manual", - // org.apache.logging.log4j.CloseableThreadContext - "org.apache.logging.log4j;CloseableThreadContext;false;put;;;Argument[1];log4j;manual", - "org.apache.logging.log4j;CloseableThreadContext;false;putAll;;;Argument[0];log4j;manual", - "org.apache.logging.log4j;CloseableThreadContext$Instance;false;put;;;Argument[1];log4j;manual", - "org.apache.logging.log4j;CloseableThreadContext$Instance;false;putAll;;;Argument[0];log4j;manual", - ] - } -} - -class Log4jInjectionSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.logging.log4j.message;MapMessage;true;with;;;Argument[1];Argument[-1];taint;manual", - "org.apache.logging.log4j.message;MapMessage;true;with;;;Argument[-1];ReturnValue;value;manual", - "org.apache.logging.log4j.message;MapMessage;true;put;;;Argument[1];Argument[-1];taint;manual", - "org.apache.logging.log4j.message;MapMessage;true;putAll;;;Argument[0].MapValue;Argument[-1];taint;manual", - ] - } +private class ActivateModels extends ActiveExperimentalModels { + ActivateModels() { this = "log4j-injection" } } /** A data flow sink for unvalidated user input that is used to log messages. */ From ab12b6cc2b60e8c524bf2f900dce9028dd850f04 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 22 Nov 2022 09:35:52 +0100 Subject: [PATCH 575/796] Java: Convert android-web-resource-response to data extensions. --- .../lib/ext/experimental/android.webkit.model.yml | 6 ++++++ java/ql/lib/ext/experimental/java.io.model.yml | 6 ++++++ .../CWE/CWE-200/AndroidWebResourceResponse.qll | 15 ++++----------- 3 files changed, 16 insertions(+), 11 deletions(-) create mode 100644 java/ql/lib/ext/experimental/android.webkit.model.yml create mode 100644 java/ql/lib/ext/experimental/java.io.model.yml diff --git a/java/ql/lib/ext/experimental/android.webkit.model.yml b/java/ql/lib/ext/experimental/android.webkit.model.yml new file mode 100644 index 00000000000..dc2a4b95b64 --- /dev/null +++ b/java/ql/lib/ext/experimental/android.webkit.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSummaryModel + data: + - ["android.webkit", "WebResourceRequest", False, "getUrl", "", "", "Argument[-1]", "ReturnValue", "taint", "manual", "android-web-resource-response"] diff --git a/java/ql/lib/ext/experimental/java.io.model.yml b/java/ql/lib/ext/experimental/java.io.model.yml new file mode 100644 index 00000000000..1b4fd419994 --- /dev/null +++ b/java/ql/lib/ext/experimental/java.io.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSummaryModel + data: + - ["java.io", "FileInputStream", True, "FileInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual", "android-web-resource-response"] diff --git a/java/ql/src/experimental/Security/CWE/CWE-200/AndroidWebResourceResponse.qll b/java/ql/src/experimental/Security/CWE/CWE-200/AndroidWebResourceResponse.qll index 44e0d7fd96f..bd177b30213 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-200/AndroidWebResourceResponse.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-200/AndroidWebResourceResponse.qll @@ -6,6 +6,10 @@ private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSteps private import semmle.code.java.frameworks.android.WebView +private class ActivateModels extends ActiveExperimentalModels { + ActivateModels() { this = "android-web-resource-response" } +} + /** * The Android class `android.webkit.WebResourceRequest` for handling web requests. */ @@ -68,14 +72,3 @@ private class FetchUrlStep extends AdditionalValueStep { ) } } - -/** Value/taint steps relating to url loading and file reading in an Android application. */ -private class LoadUrlSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "java.io;FileInputStream;true;FileInputStream;;;Argument[0];Argument[-1];taint;manual", - "android.webkit;WebResourceRequest;false;getUrl;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} From 07578f11d44e99624f8a9e6cdebe9371f5eb2004 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 22 Nov 2022 09:58:45 +0100 Subject: [PATCH 576/796] Java: Convert hardcoded-jwt-key models to data extensions. --- .../com.auth0.jwt.interfaces.model.yml | 19 ++++++++++++++++ .../Security/CWE/CWE-321/HardcodedJwtKey.qll | 22 ++++--------------- 2 files changed, 23 insertions(+), 18 deletions(-) create mode 100644 java/ql/lib/ext/experimental/com.auth0.jwt.interfaces.model.yml diff --git a/java/ql/lib/ext/experimental/com.auth0.jwt.interfaces.model.yml b/java/ql/lib/ext/experimental/com.auth0.jwt.interfaces.model.yml new file mode 100644 index 00000000000..3a4e6a42701 --- /dev/null +++ b/java/ql/lib/ext/experimental/com.auth0.jwt.interfaces.model.yml @@ -0,0 +1,19 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSummaryModel + data: + - ["com.auth0.jwt.interfaces", "Verification", True, "acceptExpiresAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "acceptIssuedAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "acceptLeeway", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "acceptNotBefore", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "ignoreIssuedAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "withAnyOfAudience", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "withArrayClaim", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "withAudience", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "withClaim", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "withClaimPresence", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "withIssuer", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "withJWTId", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "withSubject", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] diff --git a/java/ql/src/experimental/Security/CWE/CWE-321/HardcodedJwtKey.qll b/java/ql/src/experimental/Security/CWE/CWE-321/HardcodedJwtKey.qll index b16142f3856..09db11dd40b 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-321/HardcodedJwtKey.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-321/HardcodedJwtKey.qll @@ -6,6 +6,10 @@ import java private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSources +private class ActivateModels extends ActiveExperimentalModels { + ActivateModels() { this = "hardcoded-jwt-key" } +} + /** The class `com.auth0.jwt.JWT`. */ class Jwt extends RefType { Jwt() { this.hasQualifiedName("com.auth0.jwt", "JWT") } @@ -125,21 +129,3 @@ class HardcodedJwtKeyConfiguration extends TaintTracking::Configuration { ) } } - -/** Taint model related to verifying JWT tokens. */ -private class VerificationFlowStep extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "com.auth0.jwt.interfaces;Verification;true;build;;;Argument[-1];ReturnValue;taint;manual", - "com.auth0.jwt.interfaces;Verification;true;" + - ["acceptLeeway", "acceptExpiresAt", "acceptNotBefore", "acceptIssuedAt", "ignoreIssuedAt"] - + ";;;Argument[-1];ReturnValue;value;manual", - "com.auth0.jwt.interfaces;Verification;true;with" + - [ - "Issuer", "Subject", "Audience", "AnyOfAudience", "ClaimPresence", "Claim", - "ArrayClaim", "JWTId" - ] + ";;;Argument[-1];ReturnValue;value;manual" - ] - } -} From aed5ee4edccf2222967a9f31eea75c0a8b123f9b Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 22 Nov 2022 10:09:54 +0100 Subject: [PATCH 577/796] Java: Convert thread-resource-abuse to data extensions. --- .../lib/ext/experimental/java.lang.model.yml | 12 ++++++++++ .../java.util.concurrent.model.yml | 6 +++++ .../CWE/CWE-400/ThreadResourceAbuse.qll | 22 ++----------------- 3 files changed, 20 insertions(+), 20 deletions(-) create mode 100644 java/ql/lib/ext/experimental/java.lang.model.yml create mode 100644 java/ql/lib/ext/experimental/java.util.concurrent.model.yml diff --git a/java/ql/lib/ext/experimental/java.lang.model.yml b/java/ql/lib/ext/experimental/java.lang.model.yml new file mode 100644 index 00000000000..0622356da8e --- /dev/null +++ b/java/ql/lib/ext/experimental/java.lang.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSinkModel + data: + - ["java.lang", "Thread", True, "sleep", "", "", "Argument[0]", "thread-pause", "manual", "thread-resource-abuse"] + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSummaryModel + data: + - ["java.lang", "Math", False, "max", "", "", "Argument[0..1]", "ReturnValue", "value", "manual", "thread-resource-abuse"] + - ["java.lang", "Math", False, "min", "", "", "Argument[0..1]", "ReturnValue", "value", "manual", "thread-resource-abuse"] diff --git a/java/ql/lib/ext/experimental/java.util.concurrent.model.yml b/java/ql/lib/ext/experimental/java.util.concurrent.model.yml new file mode 100644 index 00000000000..0f86bfe4ae5 --- /dev/null +++ b/java/ql/lib/ext/experimental/java.util.concurrent.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSinkModel + data: + - ["java.util.concurrent", "TimeUnit", True, "sleep", "", "", "Argument[0]", "thread-pause", "manual", "thread-resource-abuse"] diff --git a/java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.qll b/java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.qll index e4dd7458951..3201f9483e4 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.qll @@ -6,26 +6,8 @@ private import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.dataflow.FlowSteps import semmle.code.java.controlflow.Guards -/** `java.lang.Math` data model for value comparison in the new CSV format. */ -private class MathCompDataModel extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "java.lang;Math;false;min;;;Argument[0..1];ReturnValue;value;manual", - "java.lang;Math;false;max;;;Argument[0..1];ReturnValue;value;manual" - ] - } -} - -/** Thread pause data model in the new CSV format. */ -private class PauseThreadDataModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "java.lang;Thread;true;sleep;;;Argument[0];thread-pause;manual", - "java.util.concurrent;TimeUnit;true;sleep;;;Argument[0];thread-pause;manual" - ] - } +private class ActivateModels extends ActiveExperimentalModels { + ActivateModels() { this = "thread-resource-abuse" } } /** A sink representing methods pausing a thread. */ From 91840c613e52e1130be2514ab54dd0510b699ef1 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 22 Nov 2022 10:34:17 +0100 Subject: [PATCH 578/796] Java: Convert unsafe-url-forward to data extensions. --- ...ndertow.server.handlers.resource.model.yml | 8 +++ .../jakarta.servlet.http.model.yml | 6 +++ .../ext/experimental/java.nio.file.model.yml | 9 ++++ .../java.util.concurrent.model.yml | 1 + .../experimental/javax.servlet.http.model.yml | 6 +++ .../org.springframework.core.io.model.yml | 16 ++++++ .../Security/CWE/CWE-552/UnsafeUrlForward.qll | 53 ++----------------- 7 files changed, 50 insertions(+), 49 deletions(-) create mode 100644 java/ql/lib/ext/experimental/io.undertow.server.handlers.resource.model.yml create mode 100644 java/ql/lib/ext/experimental/jakarta.servlet.http.model.yml create mode 100644 java/ql/lib/ext/experimental/java.nio.file.model.yml create mode 100644 java/ql/lib/ext/experimental/javax.servlet.http.model.yml create mode 100644 java/ql/lib/ext/experimental/org.springframework.core.io.model.yml diff --git a/java/ql/lib/ext/experimental/io.undertow.server.handlers.resource.model.yml b/java/ql/lib/ext/experimental/io.undertow.server.handlers.resource.model.yml new file mode 100644 index 00000000000..222a144acaf --- /dev/null +++ b/java/ql/lib/ext/experimental/io.undertow.server.handlers.resource.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSummaryModel + data: + - ["io.undertow.server.handlers.resource", "Resource", True, "getFile", "", "", "Argument[-1]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] + - ["io.undertow.server.handlers.resource", "Resource", True, "getFilePath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] + - ["io.undertow.server.handlers.resource", "Resource", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] diff --git a/java/ql/lib/ext/experimental/jakarta.servlet.http.model.yml b/java/ql/lib/ext/experimental/jakarta.servlet.http.model.yml new file mode 100644 index 00000000000..17737495c06 --- /dev/null +++ b/java/ql/lib/ext/experimental/jakarta.servlet.http.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSourceModel + data: + - ["jakarta.servlet.http", "HttpServletRequest", True, "getServletPath", "", "", "ReturnValue", "remote", "manual", "unsafe-url-forward"] diff --git a/java/ql/lib/ext/experimental/java.nio.file.model.yml b/java/ql/lib/ext/experimental/java.nio.file.model.yml new file mode 100644 index 00000000000..990a632fae4 --- /dev/null +++ b/java/ql/lib/ext/experimental/java.nio.file.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSummaryModel + data: + - ["java.nio.file", "Path", True, "normalize", "", "", "Argument[-1]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] + - ["java.nio.file", "Path", True, "resolve", "", "", "Argument[-1..0]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] + - ["java.nio.file", "Path", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] + - ["java.nio.file", "Paths", True, "get", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] diff --git a/java/ql/lib/ext/experimental/java.util.concurrent.model.yml b/java/ql/lib/ext/experimental/java.util.concurrent.model.yml index 0f86bfe4ae5..fbbee520183 100644 --- a/java/ql/lib/ext/experimental/java.util.concurrent.model.yml +++ b/java/ql/lib/ext/experimental/java.util.concurrent.model.yml @@ -4,3 +4,4 @@ extensions: extensible: extExperimentalSinkModel data: - ["java.util.concurrent", "TimeUnit", True, "sleep", "", "", "Argument[0]", "thread-pause", "manual", "thread-resource-abuse"] + - ["java.util.concurrent", "TimeUnit", True, "sleep", "", "", "Argument[0]", "thread-pause", "manual", "unsafe-url-forward"] diff --git a/java/ql/lib/ext/experimental/javax.servlet.http.model.yml b/java/ql/lib/ext/experimental/javax.servlet.http.model.yml new file mode 100644 index 00000000000..c4f359c0904 --- /dev/null +++ b/java/ql/lib/ext/experimental/javax.servlet.http.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSourceModel + data: + - ["javax.servlet.http", "HttpServletRequest", True, "getServletPath", "", "", "ReturnValue", "remote", "manual", "unsafe-url-forward"] diff --git a/java/ql/lib/ext/experimental/org.springframework.core.io.model.yml b/java/ql/lib/ext/experimental/org.springframework.core.io.model.yml new file mode 100644 index 00000000000..8fc74cd24db --- /dev/null +++ b/java/ql/lib/ext/experimental/org.springframework.core.io.model.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSinkModel + data: + - ["org.springframework.core.io", "ClassPathResource", True, "getFilename", "", "", "Argument[-1]", "get-resource", "manual", "unsafe-url-forward"] + - ["org.springframework.core.io", "ClassPathResource", True, "getPath", "", "", "Argument[-1]", "get-resource", "manual", "unsafe-url-forward"] + - ["org.springframework.core.io", "ClassPathResource", True, "getURL", "", "", "Argument[-1]", "get-resource", "manual", "unsafe-url-forward"] + - ["org.springframework.core.io", "ClassPathResource", True, "resolveURL", "", "", "Argument[-1]", "get-resource", "manual", "unsafe-url-forward"] + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSummaryModel + data: + - ["org.springframework.core.io", "ClassPathResource", False, "ClassPathResource", "", "", "Argument[0]", "Argument[-1]", "taint", "manual", "unsafe-url-forward"] + - ["org.springframework.core.io", "Resource", True, "createRelative", "", "", "Argument[0]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] + - ["org.springframework.core.io", "ResourceLoader", True, "getResource", "", "", "Argument[0]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] diff --git a/java/ql/src/experimental/Security/CWE/CWE-552/UnsafeUrlForward.qll b/java/ql/src/experimental/Security/CWE/CWE-552/UnsafeUrlForward.qll index aa2999a9955..bff6a0a3893 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-552/UnsafeUrlForward.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-552/UnsafeUrlForward.qll @@ -6,6 +6,10 @@ private import semmle.code.java.dataflow.StringPrefixes private import semmle.code.java.frameworks.javaee.ejb.EJBRestrictions private import experimental.semmle.code.java.frameworks.SpringResource +private class ActiveModels extends ActiveExperimentalModels { + ActiveModels() { this = "unsafe-url-forward" } +} + /** A sink for unsafe URL forward vulnerabilities. */ abstract class UnsafeUrlForwardSink extends DataFlow::Node { } @@ -161,52 +165,3 @@ private class SpringUrlForwardSink extends UnsafeUrlForwardSink { this.asExpr() = any(ForwardPrefix fp).getAnAppendedExpression() } } - -/** Source model of remote flow source from `getServletPath`. */ -private class ServletGetPathSource extends SourceModelCsv { - override predicate row(string row) { - row = - [ - "javax.servlet.http;HttpServletRequest;true;getServletPath;;;ReturnValue;remote;manual", - "jakarta.servlet.http;HttpServletRequest;true;getServletPath;;;ReturnValue;remote;manual" - ] - } -} - -/** Taint model related to `java.nio.file.Path` and `io.undertow.server.handlers.resource.Resource`. */ -private class FilePathFlowStep extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "java.nio.file;Paths;true;get;;;Argument[0..1];ReturnValue;taint;manual", - "java.nio.file;Path;true;resolve;;;Argument[-1..0];ReturnValue;taint;manual", - "java.nio.file;Path;true;normalize;;;Argument[-1];ReturnValue;taint;manual", - "java.nio.file;Path;true;toString;;;Argument[-1];ReturnValue;taint;manual", - "io.undertow.server.handlers.resource;Resource;true;getFile;;;Argument[-1];ReturnValue;taint;manual", - "io.undertow.server.handlers.resource;Resource;true;getFilePath;;;Argument[-1];ReturnValue;taint;manual", - "io.undertow.server.handlers.resource;Resource;true;getPath;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} - -/** Taint models related to resource loading in Spring. */ -private class LoadSpringResourceFlowStep extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.core.io;ClassPathResource;false;ClassPathResource;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.core.io;ResourceLoader;true;getResource;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.core.io;Resource;true;createRelative;;;Argument[0];ReturnValue;taint;manual" - ] - } -} - -/** Sink models for methods that load Spring resources. */ -private class SpringResourceCsvSink extends SinkModelCsv { - override predicate row(string row) { - row = - // Get spring resource - "org.springframework.core.io;ClassPathResource;true;" + - ["getFilename", "getPath", "getURL", "resolveURL"] + ";;;Argument[-1];get-resource;manual" - } -} From b96540c9376d269c8cadeaae58ef06c668cd2001 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 22 Nov 2022 11:00:21 +0100 Subject: [PATCH 579/796] Java: Convert permissve-dot-regex-query to data extensions. --- .../experimental/javax.servlet.http.model.yml | 10 ++++++++++ .../CWE/CWE-625/PermissiveDotRegexQuery.qll | 18 ++++-------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/java/ql/lib/ext/experimental/javax.servlet.http.model.yml b/java/ql/lib/ext/experimental/javax.servlet.http.model.yml index c4f359c0904..04098f85f5d 100644 --- a/java/ql/lib/ext/experimental/javax.servlet.http.model.yml +++ b/java/ql/lib/ext/experimental/javax.servlet.http.model.yml @@ -4,3 +4,13 @@ extensions: extensible: extExperimentalSourceModel data: - ["javax.servlet.http", "HttpServletRequest", True, "getServletPath", "", "", "ReturnValue", "remote", "manual", "unsafe-url-forward"] + - addsTo: + pack: codeql/java-all + extensible: extExperimentalSourceModel + data: + - ["javax.servlet.http", "HttpServletRequest", False, "getPathInfo", "()", "", "ReturnValue", "uri-path", "manual", "permissive-dot-regex-query"] + - ["javax.servlet.http", "HttpServletRequest", False, "getPathTranslated", "()", "", "ReturnValue", "uri-path", "manual", "permissive-dot-regex-query"] + - ["javax.servlet.http", "HttpServletRequest", False, "getRequestURI", "()", "", "ReturnValue", "uri-path", "manual", "permissive-dot-regex-query"] + - ["javax.servlet.http", "HttpServletRequest", False, "getRequestURL", "()", "", "ReturnValue", "uri-path", "manual", "permissive-dot-regex-query"] + - ["javax.servlet.http", "HttpServletRequest", False, "getServletPath", "()", "", "ReturnValue", "uri-path", "manual", "permissive-dot-regex-query"] + diff --git a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegexQuery.qll b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegexQuery.qll index 21a44ebbb8f..e1c802c0245 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegexQuery.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegexQuery.qll @@ -8,6 +8,10 @@ import semmle.code.java.controlflow.Guards import semmle.code.java.security.UrlRedirect import Regex +private class ActivateModels extends ActiveExperimentalModels { + ActivateModels() { this = "permissive-dot-regex-query" } +} + /** A string that ends with `.*` not prefixed with `\`. */ private class PermissiveDotStr extends StringLiteral { PermissiveDotStr() { @@ -19,20 +23,6 @@ private class PermissiveDotStr extends StringLiteral { } } -/** Remote flow sources obtained from the URI of a servlet request. */ -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" - ] - } -} - /** The qualifier of a request dispatch method call. */ private class UrlDispatchSink extends UrlRedirectSink { UrlDispatchSink() { From 74f02cf8551628f3593c606b46305d8a28a055f1 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 22 Nov 2022 13:56:29 +0100 Subject: [PATCH 580/796] Java: Allow empty package name in model definitions. --- java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 866e3f5687f..186c7ed168d 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -549,7 +549,7 @@ module ModelValidation { ext = "" and pred = "negative summary" | - not package.regexpMatch("[a-zA-Z0-9_\\.]+") and + not package.regexpMatch("[a-zA-Z0-9_\\.]*") and result = "Dubious package \"" + package + "\" in " + pred + " model." or not type.regexpMatch("[a-zA-Z0-9_\\$<>]+") and From 43a63d63735b30f9cc371153fdb308b3f7271b53 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 22 Nov 2022 14:49:52 +0100 Subject: [PATCH 581/796] Java: Convert all models to data extensions in testcases. --- java/ql/test/ext/test.model.yml | 145 ++++++++++++++++++ .../dataflow/notnullexpr/test.ql | 6 - .../library-tests/dataflow/whenexpr/test.ql | 6 - .../dataflow/callback-dispatch/test.ql | 20 --- .../dataflow/collections/containerflow.ql | 11 -- .../dataflow/external-models/sinks.ql | 14 -- .../dataflow/external-models/srcs.ql | 25 --- .../dataflow/external-models/steps.ql | 17 -- .../dataflow/synth-global/test.ql | 13 -- .../content-provider-summaries/test.ql | 13 -- .../frameworks/android/intent/test.ql | 13 -- .../frameworks/android/notification/test.ql | 10 -- .../frameworks/apache-collections/test.ql | 11 -- .../guava/generated/collect/test.ql | 12 -- .../library-tests/frameworks/stream/test.ql | 7 - java/ql/test/library-tests/optional/test.ql | 6 - java/ql/test/qlpack.yml | 2 + 17 files changed, 147 insertions(+), 184 deletions(-) create mode 100644 java/ql/test/ext/test.model.yml diff --git a/java/ql/test/ext/test.model.yml b/java/ql/test/ext/test.model.yml new file mode 100644 index 00000000000..319ee2b834e --- /dev/null +++ b/java/ql/test/ext/test.model.yml @@ -0,0 +1,145 @@ +extensions: + # Model(s) for Kotlin - dataflow/notnullexpr and dataflow/whenexpr test cases. + - addsTo: + pack: codeql/java-tests + extensible: extSummaryModel + data: + - ["", "Uri", False, "getQueryParameter", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + + # Model(s) for Java - dataflow/callback-dispatch test case. + - addsTo: + pack: codeql/java-tests + extensible: extSummaryModel + data: + - ["my.callback.qltest", "A", False, "applyConsumer1", "(Object,Consumer1)", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] + - ["my.callback.qltest", "A", False, "applyConsumer1Field1Field2", "(A,A,Consumer1)", "", "Argument[0].Field[my.callback.qltest.A.field1]", "Argument[2].Parameter[0]", "value", "manual"] + - ["my.callback.qltest", "A", False, "applyConsumer1Field1Field2", "(A,A,Consumer1)", "", "Argument[1].Field[my.callback.qltest.A.field2]", "Argument[2].Parameter[0]", "value", "manual"] + - ["my.callback.qltest", "A", False, "applyConsumer2", "(Object,Consumer2)", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] + - ["my.callback.qltest", "A", False, "applyConsumer3", "(Object,Consumer3)", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] + - ["my.callback.qltest", "A", False, "applyConsumer3_ret_postup", "(Consumer3)", "", "Argument[0].Parameter[0]", "ReturnValue", "value", "manual"] + - ["my.callback.qltest", "A", False, "forEach", "(Object[],Consumer3)", "", "Argument[0].ArrayElement", "Argument[1].Parameter[0]", "value", "manual"] + - ["my.callback.qltest", "A", False, "applyProducer1", "(Producer1)", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] + - ["my.callback.qltest", "A", False, "produceConsume", "(Producer1,Consumer3)", "", "Argument[0].ReturnValue", "Argument[1].Parameter[0]", "value", "manual"] + - ["my.callback.qltest", "A", False, "produceConsume", "(Producer1,Consumer3)", "", "Argument[1].Parameter[0]", "ReturnValue", "value", "manual"] + - ["my.callback.qltest", "A", False, "applyConverter1", "(Object,Converter1)", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] + - ["my.callback.qltest", "A", False, "applyConverter1", "(Object,Converter1)", "", "Argument[1].ReturnValue", "ReturnValue", "value", "manual"] + + # Model(s) for Java - dataflow/collections test case. + - addsTo: + pack: codeql/java-tests + extensible: extSummaryModel + data: + - ["", "B", False, "readElement", "(Spliterator)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["", "B", False, "readElement", "(Stream)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + + # Model(s) for Java - dataflow/external-models test cases. + - addsTo: + pack: codeql/java-tests + extensible: extSourceModel + data: + - ["my.qltest", "A", False, "src1", "()", "", "ReturnValue", "qltest", "manual"] + - ["my.qltest", "A", False, "src1", "(String)", "", "ReturnValue", "qltest", "manual"] + - ["my.qltest", "A", False, "src1", "(java.lang.String)", "", "ReturnValue", "qltest-alt", "manual"] + - ["my.qltest", "A", False, "src1", "", "", "ReturnValue", "qltest-all-overloads", "manual"] + - ["my.qltest", "A", False, "src2", "()", "", "ReturnValue", "qltest", "manual"] + - ["my.qltest", "A", False, "src3", "()", "", "ReturnValue", "qltest", "manual"] + - ["my.qltest", "A", True, "src2", "()", "", "ReturnValue", "qltest-w-subtypes", "manual"] + - ["my.qltest", "A", True, "src3", "()", "", "ReturnValue", "qltest-w-subtypes", "manual"] + - ["my.qltest", "A", False, "srcArg", "(Object)", "", "Argument[0]", "qltest-argnum", "manual"] + - ["my.qltest", "A", False, "srcArg", "(Object)", "", "Argument", "qltest-argany", "manual"] + - ["my.qltest", "A$Handler", True, "handle", "(Object)", "", "Parameter[0]", "qltest-param-override", "manual"] + - ["my.qltest", "A$Tag", False, "", "", "Annotated", "ReturnValue", "qltest-retval", "manual"] + - ["my.qltest", "A$Tag", False, "", "", "Annotated", "Parameter", "qltest-param", "manual"] + - ["my.qltest", "A$Tag", False, "", "", "Annotated", "", "qltest-nospec", "manual"] + - ["my.qltest", "A", False, "srcTwoArg", "(String,String)", "", "ReturnValue", "qltest-shortsig", "manual"] + - ["my.qltest", "A", False, "srcTwoArg", "(java.lang.String,java.lang.String)", "", "ReturnValue", "qltest-longsig", "manual"] + - addsTo: + pack: codeql/java-tests + extensible: extSinkModel + data: + - ["my.qltest", "B", False, "sink1", "(Object)", "", "Argument[0]", "qltest", "manual"] + - ["my.qltest", "B", False, "sinkMethod", "()", "", "ReturnValue", "qltest", "manual"] + - ["my.qltest", "B$Tag", False, "", "", "Annotated", "ReturnValue", "qltest-retval", "manual"] + - ["my.qltest", "B$Tag", False, "", "", "Annotated", "Argument", "qltest-arg", "manual"] + - ["my.qltest", "B$Tag", False, "", "", "Annotated", "", "qltest-nospec", "manual"] + - addsTo: + pack: codeql/java-tests + extensible: extSummaryModel + data: + - ["my.qltest", "C", False, "stepArgRes", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["my.qltest", "C", False, "stepArgArg", "(Object,Object)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["my.qltest", "C", False, "stepArgQual", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["my.qltest", "C", False, "stepQualRes", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["my.qltest", "C", False, "stepQualArg", "(Object)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["my.qltest", "C", False, "stepArgResGenerated", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["my.qltest", "C", False, "stepArgResGeneratedIgnored", "(Object,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["my.qltest", "C", False, "stepArgResGeneratedIgnored", "(Object,Object)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + + # Model(s) for Java - dataflow/synth-global test case. + - addsTo: + pack: codeql/java-tests + extensible: extSummaryModel + data: + - ["my.qltest.synth", "A", False, "storeInArray", "(String)", "", "Argument[0]", "SyntheticGlobal[db1].ArrayElement", "value", "manual"] + - ["my.qltest.synth", "A", False, "storeTaintInArray", "(String)", "", "Argument[0]", "SyntheticGlobal[db1].ArrayElement", "taint", "manual"] + - ["my.qltest.synth", "A", False, "storeValue", "(String)", "", "Argument[0]", "SyntheticGlobal[db1]", "value", "manual"] + - ["my.qltest.synth", "A", False, "readValue", "()", "", "SyntheticGlobal[db1]", "ReturnValue", "value", "manual"] + - ["my.qltest.synth", "A", False, "readArray", "()", "", "SyntheticGlobal[db1].ArrayElement", "ReturnValue", "value", "manual"] + + # Model(s) for Java - frameworks/android/content-provider-summaries test case. + - addsTo: + pack: codeql/java-tests + extensible: extSummaryModel + data: + - ["generatedtest", "Test", False, "newWithMapValueDefault", "(Object)", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] + - ["generatedtest", "Test", False, "newWithMapKeyDefault", "(Object)", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["generatedtest", "Test", False, "getMapValueDefault", "(Object)", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["generatedtest", "Test", False, "getMapKeyDefault", "(Object)", "", "Argument[0].MapKey", "ReturnValue", "value", "manual"] + + # Model(s) for Java - frameworks/android/intent test case. + - addsTo: + pack: codeql/java-tests + extensible: extSummaryModel + data: + - ["generatedtest", "Test", False, "newBundleWithMapValue", "(Object)", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] + - ["generatedtest", "Test", False, "newPersistableBundleWithMapValue", "(Object)", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] + - ["generatedtest", "Test", False, "getMapValue", "(BaseBundle)", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["generatedtest", "Test", False, "newWithIntent_extras", "(Bundle)", "", "Argument[0]", "ReturnValue.SyntheticField[android.content.Intent.extras]", "value", "manual"] + + # Model(s) for Java - frameworks/android/notification test case. + - addsTo: + pack: codeql/java-tests + extensible: extSummaryModel + data: + - ["generatedtest", "Test", False, "getMapKeyDefault", "(Bundle)", "", "Argument[0].MapKey", "ReturnValue", "value", "manual"] + + # Model(s) for Java - frameworks/apache-collections test case. + - addsTo: + pack: codeql/java-tests + extensible: extSummaryModel + data: + - ["generatedtest", "Test", False, "newRBWithMapValue", "", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] + - ["generatedtest", "Test", False, "newRBWithMapKey", "", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + + # Model(s) for Java - frameworks/guave/generated/collect test case. + - addsTo: + pack: codeql/java-tests + extensible: extSummaryModel + data: + - ["generatedtest", "Test", False, "newWithElementDefault", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["generatedtest", "Test", False, "newWithMapKeyDefault", "(Object)", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["generatedtest", "Test", False, "newWithMapValueDefault", "(Object)", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] + + # Model(s) for Java - frameworks/stream test case. + - addsTo: + pack: codeql/java-tests + extensible: extSummaryModel + data: + - ["generatedtest", "Test", False, "getElementSpliterator", "(Spliterator)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + + # Model(s) for Java - frameworks/stream test case. + - addsTo: + pack: codeql/java-tests + extensible: extSummaryModel + data: + - ["generatedtest", "Test", False, "getStreamElement", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ql b/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ql index 1bb9801bc64..6e97f945f13 100644 --- a/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ql +++ b/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ql @@ -2,12 +2,6 @@ import java import semmle.code.java.dataflow.TaintTracking import semmle.code.java.dataflow.ExternalFlow -class Step extends SummaryModelCsv { - override predicate row(string row) { - row = ";Uri;false;getQueryParameter;;;Argument[-1];ReturnValue;taint;manual" - } -} - class Conf extends TaintTracking::Configuration { Conf() { this = "qltest:notNullExprFlow" } diff --git a/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ql b/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ql index 1bb9801bc64..6e97f945f13 100644 --- a/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ql +++ b/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ql @@ -2,12 +2,6 @@ import java import semmle.code.java.dataflow.TaintTracking import semmle.code.java.dataflow.ExternalFlow -class Step extends SummaryModelCsv { - override predicate row(string row) { - row = ";Uri;false;getQueryParameter;;;Argument[-1];ReturnValue;taint;manual" - } -} - class Conf extends TaintTracking::Configuration { Conf() { this = "qltest:notNullExprFlow" } diff --git a/java/ql/test/library-tests/dataflow/callback-dispatch/test.ql b/java/ql/test/library-tests/dataflow/callback-dispatch/test.ql index 4771031581f..09366857c0b 100644 --- a/java/ql/test/library-tests/dataflow/callback-dispatch/test.ql +++ b/java/ql/test/library-tests/dataflow/callback-dispatch/test.ql @@ -3,26 +3,6 @@ import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.ExternalFlow import TestUtilities.InlineExpectationsTest -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "my.callback.qltest;A;false;applyConsumer1;(Object,Consumer1);;Argument[0];Argument[1].Parameter[0];value;manual", - "my.callback.qltest;A;false;applyConsumer1Field1Field2;(A,A,Consumer1);;Argument[0].Field[my.callback.qltest.A.field1];Argument[2].Parameter[0];value;manual", - "my.callback.qltest;A;false;applyConsumer1Field1Field2;(A,A,Consumer1);;Argument[1].Field[my.callback.qltest.A.field2];Argument[2].Parameter[0];value;manual", - "my.callback.qltest;A;false;applyConsumer2;(Object,Consumer2);;Argument[0];Argument[1].Parameter[0];value;manual", - "my.callback.qltest;A;false;applyConsumer3;(Object,Consumer3);;Argument[0];Argument[1].Parameter[0];value;manual", - "my.callback.qltest;A;false;applyConsumer3_ret_postup;(Consumer3);;Argument[0].Parameter[0];ReturnValue;value;manual", - "my.callback.qltest;A;false;forEach;(Object[],Consumer3);;Argument[0].ArrayElement;Argument[1].Parameter[0];value;manual", - "my.callback.qltest;A;false;applyProducer1;(Producer1);;Argument[0].ReturnValue;ReturnValue;value;manual", - "my.callback.qltest;A;false;produceConsume;(Producer1,Consumer3);;Argument[0].ReturnValue;Argument[1].Parameter[0];value;manual", - "my.callback.qltest;A;false;produceConsume;(Producer1,Consumer3);;Argument[1].Parameter[0];ReturnValue;value;manual", - "my.callback.qltest;A;false;applyConverter1;(Object,Converter1);;Argument[0];Argument[1].Parameter[0];value;manual", - "my.callback.qltest;A;false;applyConverter1;(Object,Converter1);;Argument[1].ReturnValue;ReturnValue;value;manual" - ] - } -} - class Conf extends DataFlow::Configuration { Conf() { this = "qltest:callback-dispatch" } diff --git a/java/ql/test/library-tests/dataflow/collections/containerflow.ql b/java/ql/test/library-tests/dataflow/collections/containerflow.ql index 12f7a3ffd22..fc596462aef 100644 --- a/java/ql/test/library-tests/dataflow/collections/containerflow.ql +++ b/java/ql/test/library-tests/dataflow/collections/containerflow.ql @@ -3,17 +3,6 @@ import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.ExternalFlow import TestUtilities.InlineFlowTest -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - ";B;false;readElement;(Spliterator);;Argument[0].Element;ReturnValue;value;manual", - ";B;false;readElement;(Stream);;Argument[0].Element;ReturnValue;value;manual" - ] - } -} - class HasFlowTest extends InlineFlowTest { override DataFlow::Configuration getTaintFlowConfig() { none() } } diff --git a/java/ql/test/library-tests/dataflow/external-models/sinks.ql b/java/ql/test/library-tests/dataflow/external-models/sinks.ql index aa1b3a549f3..5da8f29ff4c 100644 --- a/java/ql/test/library-tests/dataflow/external-models/sinks.ql +++ b/java/ql/test/library-tests/dataflow/external-models/sinks.ql @@ -3,20 +3,6 @@ import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.ExternalFlow import ModelValidation -class SinkModelTest extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; kind` - "my.qltest;B;false;sink1;(Object);;Argument[0];qltest;manual", - "my.qltest;B;false;sinkMethod;();;ReturnValue;qltest;manual", - "my.qltest;B$Tag;false;;;Annotated;ReturnValue;qltest-retval;manual", - "my.qltest;B$Tag;false;;;Annotated;Argument;qltest-arg;manual", - "my.qltest;B$Tag;false;;;Annotated;;qltest-nospec;manual" - ] - } -} - from DataFlow::Node node, string kind where sinkNode(node, kind) select node, kind diff --git a/java/ql/test/library-tests/dataflow/external-models/srcs.ql b/java/ql/test/library-tests/dataflow/external-models/srcs.ql index 08b13328fa4..655fee35611 100644 --- a/java/ql/test/library-tests/dataflow/external-models/srcs.ql +++ b/java/ql/test/library-tests/dataflow/external-models/srcs.ql @@ -3,31 +3,6 @@ import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.ExternalFlow import ModelValidation -class SourceModelTest extends SourceModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; output; kind` - "my.qltest;A;false;src1;();;ReturnValue;qltest;manual", - "my.qltest;A;false;src1;(String);;ReturnValue;qltest;manual", - "my.qltest;A;false;src1;(java.lang.String);;ReturnValue;qltest-alt;manual", - "my.qltest;A;false;src1;;;ReturnValue;qltest-all-overloads;manual", - "my.qltest;A;false;src2;();;ReturnValue;qltest;manual", - "my.qltest;A;false;src3;();;ReturnValue;qltest;manual", - "my.qltest;A;true;src2;();;ReturnValue;qltest-w-subtypes;manual", - "my.qltest;A;true;src3;();;ReturnValue;qltest-w-subtypes;manual", - "my.qltest;A;false;srcArg;(Object);;Argument[0];qltest-argnum;manual", - "my.qltest;A;false;srcArg;(Object);;Argument;qltest-argany;manual", - "my.qltest;A$Handler;true;handle;(Object);;Parameter[0];qltest-param-override;manual", - "my.qltest;A$Tag;false;;;Annotated;ReturnValue;qltest-retval;manual", - "my.qltest;A$Tag;false;;;Annotated;Parameter;qltest-param;manual", - "my.qltest;A$Tag;false;;;Annotated;;qltest-nospec;manual", - "my.qltest;A;false;srcTwoArg;(String,String);;ReturnValue;qltest-shortsig;manual", - "my.qltest;A;false;srcTwoArg;(java.lang.String,java.lang.String);;ReturnValue;qltest-longsig;manual" - ] - } -} - from DataFlow::Node node, string kind where sourceNode(node, kind) select node, kind diff --git a/java/ql/test/library-tests/dataflow/external-models/steps.ql b/java/ql/test/library-tests/dataflow/external-models/steps.ql index 7875763f5e8..e57c4d54b17 100644 --- a/java/ql/test/library-tests/dataflow/external-models/steps.ql +++ b/java/ql/test/library-tests/dataflow/external-models/steps.ql @@ -4,23 +4,6 @@ import semmle.code.java.dataflow.ExternalFlow import ModelValidation import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "my.qltest;C;false;stepArgRes;(Object);;Argument[0];ReturnValue;taint;manual", - "my.qltest;C;false;stepArgArg;(Object,Object);;Argument[0];Argument[1];taint;manual", - "my.qltest;C;false;stepArgQual;(Object);;Argument[0];Argument[-1];taint;manual", - "my.qltest;C;false;stepQualRes;();;Argument[-1];ReturnValue;taint;manual", - "my.qltest;C;false;stepQualArg;(Object);;Argument[-1];Argument[0];taint;manual", - "my.qltest;C;false;stepArgResGenerated;(Object);;Argument[0];ReturnValue;taint;generated", - "my.qltest;C;false;stepArgResGeneratedIgnored;(Object,Object);;Argument[0];ReturnValue;taint;generated", - "my.qltest;C;false;stepArgResGeneratedIgnored;(Object,Object);;Argument[1];ReturnValue;taint;manual", - ] - } -} - from DataFlow::Node node1, DataFlow::Node node2 where FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(node1, node2, _) select node1, node2 diff --git a/java/ql/test/library-tests/dataflow/synth-global/test.ql b/java/ql/test/library-tests/dataflow/synth-global/test.ql index de3866636c0..0d9f2265afc 100644 --- a/java/ql/test/library-tests/dataflow/synth-global/test.ql +++ b/java/ql/test/library-tests/dataflow/synth-global/test.ql @@ -1,16 +1,3 @@ import java import TestUtilities.InlineFlowTest import ModelValidation - -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "my.qltest.synth;A;false;storeInArray;(String);;Argument[0];SyntheticGlobal[db1].ArrayElement;value;manual", - "my.qltest.synth;A;false;storeTaintInArray;(String);;Argument[0];SyntheticGlobal[db1].ArrayElement;taint;manual", - "my.qltest.synth;A;false;storeValue;(String);;Argument[0];SyntheticGlobal[db1];value;manual", - "my.qltest.synth;A;false;readValue;();;SyntheticGlobal[db1];ReturnValue;value;manual", - "my.qltest.synth;A;false;readArray;();;SyntheticGlobal[db1].ArrayElement;ReturnValue;value;manual", - ] - } -} diff --git a/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ql b/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ql index 2fa9dc00fd8..5d91e4e8e26 100644 --- a/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ql +++ b/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ql @@ -1,15 +1,2 @@ import java import TestUtilities.InlineFlowTest - -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - "generatedtest;Test;false;newWithMapValueDefault;(Object);;Argument[0];ReturnValue.MapValue;value;manual", - "generatedtest;Test;false;newWithMapKeyDefault;(Object);;Argument[0];ReturnValue.MapKey;value;manual", - "generatedtest;Test;false;getMapValueDefault;(Object);;Argument[0].MapValue;ReturnValue;value;manual", - "generatedtest;Test;false;getMapKeyDefault;(Object);;Argument[0].MapKey;ReturnValue;value;manual" - ] - } -} diff --git a/java/ql/test/library-tests/frameworks/android/intent/test.ql b/java/ql/test/library-tests/frameworks/android/intent/test.ql index a11619fb013..5d91e4e8e26 100644 --- a/java/ql/test/library-tests/frameworks/android/intent/test.ql +++ b/java/ql/test/library-tests/frameworks/android/intent/test.ql @@ -1,15 +1,2 @@ import java import TestUtilities.InlineFlowTest - -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - "generatedtest;Test;false;newBundleWithMapValue;(Object);;Argument[0];ReturnValue.MapValue;value;manual", - "generatedtest;Test;false;newPersistableBundleWithMapValue;(Object);;Argument[0];ReturnValue.MapValue;value;manual", - "generatedtest;Test;false;getMapValue;(BaseBundle);;Argument[0].MapValue;ReturnValue;value;manual", - "generatedtest;Test;false;newWithIntent_extras;(Bundle);;Argument[0];ReturnValue.SyntheticField[android.content.Intent.extras];value;manual" - ] - } -} diff --git a/java/ql/test/library-tests/frameworks/android/notification/test.ql b/java/ql/test/library-tests/frameworks/android/notification/test.ql index d0dffb02d6b..f0a60550d4d 100644 --- a/java/ql/test/library-tests/frameworks/android/notification/test.ql +++ b/java/ql/test/library-tests/frameworks/android/notification/test.ql @@ -1,13 +1,3 @@ import java import semmle.code.java.frameworks.android.Intent import TestUtilities.InlineFlowTest - -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - "generatedtest;Test;false;getMapKeyDefault;(Bundle);;Argument[0].MapKey;ReturnValue;value;manual" - ] - } -} diff --git a/java/ql/test/library-tests/frameworks/apache-collections/test.ql b/java/ql/test/library-tests/frameworks/apache-collections/test.ql index fae8e0bdd77..5d91e4e8e26 100644 --- a/java/ql/test/library-tests/frameworks/apache-collections/test.ql +++ b/java/ql/test/library-tests/frameworks/apache-collections/test.ql @@ -1,13 +1,2 @@ import java import TestUtilities.InlineFlowTest - -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - "generatedtest;Test;false;newRBWithMapValue;;;Argument[0];ReturnValue.MapValue;value;manual", - "generatedtest;Test;false;newRBWithMapKey;;;Argument[0];ReturnValue.MapKey;value;manual" - ] - } -} diff --git a/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ql b/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ql index dfafbea561f..5d91e4e8e26 100644 --- a/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ql +++ b/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ql @@ -1,14 +1,2 @@ import java import TestUtilities.InlineFlowTest - -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - "generatedtest;Test;false;newWithElementDefault;(Object);;Argument[0];ReturnValue.Element;value;manual", - "generatedtest;Test;false;newWithMapKeyDefault;(Object);;Argument[0];ReturnValue.MapKey;value;manual", - "generatedtest;Test;false;newWithMapValueDefault;(Object);;Argument[0];ReturnValue.MapValue;value;manual" - ] - } -} diff --git a/java/ql/test/library-tests/frameworks/stream/test.ql b/java/ql/test/library-tests/frameworks/stream/test.ql index adfc47bd521..5d91e4e8e26 100644 --- a/java/ql/test/library-tests/frameworks/stream/test.ql +++ b/java/ql/test/library-tests/frameworks/stream/test.ql @@ -1,9 +1,2 @@ import java import TestUtilities.InlineFlowTest - -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - "generatedtest;Test;false;getElementSpliterator;(Spliterator);;Argument[0].Element;ReturnValue;value;manual" - } -} diff --git a/java/ql/test/library-tests/optional/test.ql b/java/ql/test/library-tests/optional/test.ql index b0d5ab16112..5d91e4e8e26 100644 --- a/java/ql/test/library-tests/optional/test.ql +++ b/java/ql/test/library-tests/optional/test.ql @@ -1,8 +1,2 @@ import java import TestUtilities.InlineFlowTest - -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = "generatedtest;Test;false;getStreamElement;;;Argument[0].Element;ReturnValue;value;manual" - } -} diff --git a/java/ql/test/qlpack.yml b/java/ql/test/qlpack.yml index d1fe5254a38..76f524125f5 100644 --- a/java/ql/test/qlpack.yml +++ b/java/ql/test/qlpack.yml @@ -5,3 +5,5 @@ dependencies: codeql/java-queries: ${workspace} extractor: java tests: . +dataExtensions: + - ext/*.model.yml From d7e656a32ac223d3cbce1bab93b3a25164751576 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 23 Nov 2022 10:15:49 +0100 Subject: [PATCH 582/796] Java: Add change note. --- java/ql/lib/change-notes/2022-11-23-mad-data-extensions.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2022-11-23-mad-data-extensions.md diff --git a/java/ql/lib/change-notes/2022-11-23-mad-data-extensions.md b/java/ql/lib/change-notes/2022-11-23-mad-data-extensions.md new file mode 100644 index 00000000000..6e897ed60c2 --- /dev/null +++ b/java/ql/lib/change-notes/2022-11-23-mad-data-extensions.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Models as Data models for Java are defined as data extensions instead of being inlined in the code. New models should be added in the `lib/ext` folder. \ No newline at end of file From 3971cbf294c2e77f49a176e4c3a1e90432399c06 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 28 Nov 2022 11:25:37 +0000 Subject: [PATCH 583/796] Swift: Extend the taint test with WKUserScript. --- .../dataflow/taint/LocalTaint.expected | 2 +- .../dataflow/taint/Taint.expected | 544 +++++++++--------- .../dataflow/taint/webview.swift | 107 ++-- 3 files changed, 347 insertions(+), 306 deletions(-) diff --git a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected index 8ba56979b65..297f5f4382d 100644 --- a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected @@ -165,4 +165,4 @@ | url.swift:100:12:100:54 | ...! | url.swift:100:12:100:56 | .standardizedFileURL | | url.swift:101:15:101:57 | ...! | url.swift:101:15:101:59 | .user | | url.swift:102:15:102:57 | ...! | url.swift:102:15:102:59 | .password | -| webview.swift:52:11:52:18 | call to source() | webview.swift:52:10:52:41 | .body | +| webview.swift:77:11:77:18 | call to source() | webview.swift:77:10:77:41 | .body | diff --git a/swift/ql/test/library-tests/dataflow/taint/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/Taint.expected index 37d4e5dda85..1eb4db5261b 100644 --- a/swift/ql/test/library-tests/dataflow/taint/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/Taint.expected @@ -410,126 +410,126 @@ edges | url.swift:117:28:117:28 | tainted : | url.swift:117:16:117:35 | call to init(string:) : | | url.swift:120:46:120:46 | urlTainted : | url.swift:43:2:46:55 | [summary param] 0 in dataTask(with:completionHandler:) : | | url.swift:120:61:120:61 | data : | url.swift:121:15:121:19 | ...! | -| webview.swift:16:5:16:39 | [summary param] 0 in init(object:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(object:in:) : | -| webview.swift:17:5:17:38 | [summary param] 0 in init(bool:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bool:in:) : | -| webview.swift:18:5:18:42 | [summary param] 0 in init(double:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(double:in:) : | -| webview.swift:19:5:19:40 | [summary param] 0 in init(int32:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(int32:in:) : | -| webview.swift:20:5:20:42 | [summary param] 0 in init(uInt32:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(uInt32:in:) : | -| webview.swift:21:5:21:42 | [summary param] 0 in init(point:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(point:in:) : | -| webview.swift:22:5:22:42 | [summary param] 0 in init(range:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(range:in:) : | -| webview.swift:23:5:23:40 | [summary param] 0 in init(rect:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(rect:in:) : | -| webview.swift:24:5:24:40 | [summary param] 0 in init(size:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(size:in:) : | -| webview.swift:25:5:25:41 | [summary param] this in toObject() : | file://:0:0:0:0 | [summary] to write: return (return) in toObject() : | -| webview.swift:26:5:26:55 | [summary param] this in toObjectOf(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in toObjectOf(_:) : | -| webview.swift:27:5:27:42 | [summary param] this in toBool() : | file://:0:0:0:0 | [summary] to write: return (return) in toBool() : | -| webview.swift:28:5:28:44 | [summary param] this in toDouble() : | file://:0:0:0:0 | [summary] to write: return (return) in toDouble() : | -| webview.swift:29:5:29:40 | [summary param] this in toInt32() : | file://:0:0:0:0 | [summary] to write: return (return) in toInt32() : | -| webview.swift:30:5:30:42 | [summary param] this in toUInt32() : | file://:0:0:0:0 | [summary] to write: return (return) in toUInt32() : | -| webview.swift:31:5:31:62 | [summary param] this in toNumber() : | file://:0:0:0:0 | [summary] to write: return (return) in toNumber() : | -| webview.swift:32:5:32:44 | [summary param] this in toString() : | file://:0:0:0:0 | [summary] to write: return (return) in toString() : | -| webview.swift:33:5:33:44 | [summary param] this in toDate() : | file://:0:0:0:0 | [summary] to write: return (return) in toDate() : | -| webview.swift:34:5:34:44 | [summary param] this in toArray() : | file://:0:0:0:0 | [summary] to write: return (return) in toArray() : | -| webview.swift:35:5:35:65 | [summary param] this in toDictionary() : | file://:0:0:0:0 | [summary] to write: return (return) in toDictionary() : | -| webview.swift:36:5:36:50 | [summary param] this in toPoint() : | file://:0:0:0:0 | [summary] to write: return (return) in toPoint() : | -| webview.swift:37:5:37:50 | [summary param] this in toRange() : | file://:0:0:0:0 | [summary] to write: return (return) in toRange() : | -| webview.swift:38:5:38:47 | [summary param] this in toRect() : | file://:0:0:0:0 | [summary] to write: return (return) in toRect() : | -| webview.swift:39:5:39:47 | [summary param] this in toSize() : | file://:0:0:0:0 | [summary] to write: return (return) in toSize() : | -| webview.swift:40:5:40:84 | [summary param] this in atIndex(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in atIndex(_:) : | -| webview.swift:41:5:41:53 | [summary param] 1 in defineProperty(_:descriptor:) : | file://:0:0:0:0 | [summary] to write: argument this in defineProperty(_:descriptor:) : | -| webview.swift:42:5:42:89 | [summary param] this in forProperty(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in forProperty(_:) : | -| webview.swift:43:5:43:38 | [summary param] 0 in setValue(_:at:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:at:) : | -| webview.swift:44:5:44:48 | [summary param] 0 in setValue(_:forProperty:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:forProperty:) : | -| webview.swift:52:11:52:18 | call to source() : | webview.swift:52:10:52:41 | .body | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:59:10:59:10 | source : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:60:10:60:10 | source : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:61:10:61:10 | source : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:62:10:62:10 | source : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:63:10:63:10 | source : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:64:10:64:10 | source : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:65:10:65:10 | source : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:66:10:66:10 | source : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:67:10:67:10 | source : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:68:10:68:10 | source : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:69:10:69:10 | source : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:70:10:70:10 | source : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:71:10:71:10 | source : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:72:10:72:10 | source : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:73:10:73:10 | source : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:74:10:74:10 | source : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:75:10:75:10 | source : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:78:26:78:26 | s : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:79:24:79:24 | s : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:80:26:80:26 | s : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:81:25:81:25 | s : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:82:26:82:26 | s : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:83:25:83:25 | s : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:84:25:84:25 | s : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:85:24:85:24 | s : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:86:24:86:24 | s : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:89:39:89:39 | s : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:93:17:93:17 | s : | -| webview.swift:56:13:56:20 | call to source() : | webview.swift:97:17:97:17 | s : | -| webview.swift:59:10:59:10 | source : | webview.swift:25:5:25:41 | [summary param] this in toObject() : | -| webview.swift:59:10:59:10 | source : | webview.swift:59:10:59:26 | call to toObject() | -| webview.swift:60:10:60:10 | source : | webview.swift:26:5:26:55 | [summary param] this in toObjectOf(_:) : | -| webview.swift:60:10:60:10 | source : | webview.swift:60:10:60:41 | call to toObjectOf(_:) | -| webview.swift:61:10:61:10 | source : | webview.swift:27:5:27:42 | [summary param] this in toBool() : | -| webview.swift:61:10:61:10 | source : | webview.swift:61:10:61:24 | call to toBool() | -| webview.swift:62:10:62:10 | source : | webview.swift:28:5:28:44 | [summary param] this in toDouble() : | -| webview.swift:62:10:62:10 | source : | webview.swift:62:10:62:26 | call to toDouble() | -| webview.swift:63:10:63:10 | source : | webview.swift:29:5:29:40 | [summary param] this in toInt32() : | -| webview.swift:63:10:63:10 | source : | webview.swift:63:10:63:25 | call to toInt32() | -| webview.swift:64:10:64:10 | source : | webview.swift:30:5:30:42 | [summary param] this in toUInt32() : | -| webview.swift:64:10:64:10 | source : | webview.swift:64:10:64:26 | call to toUInt32() | -| webview.swift:65:10:65:10 | source : | webview.swift:31:5:31:62 | [summary param] this in toNumber() : | -| webview.swift:65:10:65:10 | source : | webview.swift:65:10:65:26 | call to toNumber() | -| webview.swift:66:10:66:10 | source : | webview.swift:32:5:32:44 | [summary param] this in toString() : | -| webview.swift:66:10:66:10 | source : | webview.swift:66:10:66:26 | call to toString() | -| webview.swift:67:10:67:10 | source : | webview.swift:33:5:33:44 | [summary param] this in toDate() : | -| webview.swift:67:10:67:10 | source : | webview.swift:67:10:67:24 | call to toDate() | -| webview.swift:68:10:68:10 | source : | webview.swift:34:5:34:44 | [summary param] this in toArray() : | -| webview.swift:68:10:68:10 | source : | webview.swift:68:10:68:25 | call to toArray() | -| webview.swift:69:10:69:10 | source : | webview.swift:35:5:35:65 | [summary param] this in toDictionary() : | -| webview.swift:69:10:69:10 | source : | webview.swift:69:10:69:30 | call to toDictionary() | -| webview.swift:70:10:70:10 | source : | webview.swift:36:5:36:50 | [summary param] this in toPoint() : | -| webview.swift:70:10:70:10 | source : | webview.swift:70:10:70:25 | call to toPoint() | -| webview.swift:71:10:71:10 | source : | webview.swift:37:5:37:50 | [summary param] this in toRange() : | -| webview.swift:71:10:71:10 | source : | webview.swift:71:10:71:25 | call to toRange() | -| webview.swift:72:10:72:10 | source : | webview.swift:38:5:38:47 | [summary param] this in toRect() : | -| webview.swift:72:10:72:10 | source : | webview.swift:72:10:72:24 | call to toRect() | -| webview.swift:73:10:73:10 | source : | webview.swift:39:5:39:47 | [summary param] this in toSize() : | -| webview.swift:73:10:73:10 | source : | webview.swift:73:10:73:24 | call to toSize() | -| webview.swift:74:10:74:10 | source : | webview.swift:40:5:40:84 | [summary param] this in atIndex(_:) : | -| webview.swift:74:10:74:10 | source : | webview.swift:74:10:74:26 | call to atIndex(_:) | -| webview.swift:75:10:75:10 | source : | webview.swift:42:5:42:89 | [summary param] this in forProperty(_:) : | -| webview.swift:75:10:75:10 | source : | webview.swift:75:10:75:31 | call to forProperty(_:) | -| webview.swift:78:26:78:26 | s : | webview.swift:16:5:16:39 | [summary param] 0 in init(object:in:) : | -| webview.swift:78:26:78:26 | s : | webview.swift:78:10:78:47 | call to init(object:in:) | -| webview.swift:79:24:79:24 | s : | webview.swift:17:5:17:38 | [summary param] 0 in init(bool:in:) : | -| webview.swift:79:24:79:24 | s : | webview.swift:79:10:79:47 | call to init(bool:in:) | -| webview.swift:80:26:80:26 | s : | webview.swift:18:5:18:42 | [summary param] 0 in init(double:in:) : | -| webview.swift:80:26:80:26 | s : | webview.swift:80:10:80:51 | call to init(double:in:) | -| webview.swift:81:25:81:25 | s : | webview.swift:19:5:19:40 | [summary param] 0 in init(int32:in:) : | -| webview.swift:81:25:81:25 | s : | webview.swift:81:10:81:49 | call to init(int32:in:) | -| webview.swift:82:26:82:26 | s : | webview.swift:20:5:20:42 | [summary param] 0 in init(uInt32:in:) : | -| webview.swift:82:26:82:26 | s : | webview.swift:82:10:82:51 | call to init(uInt32:in:) | -| webview.swift:83:25:83:25 | s : | webview.swift:21:5:21:42 | [summary param] 0 in init(point:in:) : | -| webview.swift:83:25:83:25 | s : | webview.swift:83:10:83:51 | call to init(point:in:) | -| webview.swift:84:25:84:25 | s : | webview.swift:22:5:22:42 | [summary param] 0 in init(range:in:) : | -| webview.swift:84:25:84:25 | s : | webview.swift:84:10:84:51 | call to init(range:in:) | -| webview.swift:85:24:85:24 | s : | webview.swift:23:5:23:40 | [summary param] 0 in init(rect:in:) : | -| webview.swift:85:24:85:24 | s : | webview.swift:85:10:85:49 | call to init(rect:in:) | -| webview.swift:86:24:86:24 | s : | webview.swift:24:5:24:40 | [summary param] 0 in init(size:in:) : | -| webview.swift:86:24:86:24 | s : | webview.swift:86:10:86:49 | call to init(size:in:) | -| webview.swift:89:5:89:5 | [post] v1 : | webview.swift:90:10:90:10 | v1 | -| webview.swift:89:39:89:39 | s : | webview.swift:41:5:41:53 | [summary param] 1 in defineProperty(_:descriptor:) : | -| webview.swift:89:39:89:39 | s : | webview.swift:89:5:89:5 | [post] v1 : | -| webview.swift:93:5:93:5 | [post] v2 : | webview.swift:94:10:94:10 | v2 | -| webview.swift:93:17:93:17 | s : | webview.swift:43:5:43:38 | [summary param] 0 in setValue(_:at:) : | -| webview.swift:93:17:93:17 | s : | webview.swift:93:5:93:5 | [post] v2 : | -| webview.swift:97:5:97:5 | [post] v3 : | webview.swift:98:10:98:10 | v3 | -| webview.swift:97:17:97:17 | s : | webview.swift:44:5:44:48 | [summary param] 0 in setValue(_:forProperty:) : | -| webview.swift:97:17:97:17 | s : | webview.swift:97:5:97:5 | [post] v3 : | +| webview.swift:27:5:27:39 | [summary param] 0 in init(object:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(object:in:) : | +| webview.swift:28:5:28:38 | [summary param] 0 in init(bool:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bool:in:) : | +| webview.swift:29:5:29:42 | [summary param] 0 in init(double:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(double:in:) : | +| webview.swift:30:5:30:40 | [summary param] 0 in init(int32:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(int32:in:) : | +| webview.swift:31:5:31:42 | [summary param] 0 in init(uInt32:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(uInt32:in:) : | +| webview.swift:32:5:32:42 | [summary param] 0 in init(point:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(point:in:) : | +| webview.swift:33:5:33:42 | [summary param] 0 in init(range:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(range:in:) : | +| webview.swift:34:5:34:40 | [summary param] 0 in init(rect:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(rect:in:) : | +| webview.swift:35:5:35:40 | [summary param] 0 in init(size:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(size:in:) : | +| webview.swift:36:5:36:41 | [summary param] this in toObject() : | file://:0:0:0:0 | [summary] to write: return (return) in toObject() : | +| webview.swift:37:5:37:55 | [summary param] this in toObjectOf(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in toObjectOf(_:) : | +| webview.swift:38:5:38:42 | [summary param] this in toBool() : | file://:0:0:0:0 | [summary] to write: return (return) in toBool() : | +| webview.swift:39:5:39:44 | [summary param] this in toDouble() : | file://:0:0:0:0 | [summary] to write: return (return) in toDouble() : | +| webview.swift:40:5:40:40 | [summary param] this in toInt32() : | file://:0:0:0:0 | [summary] to write: return (return) in toInt32() : | +| webview.swift:41:5:41:42 | [summary param] this in toUInt32() : | file://:0:0:0:0 | [summary] to write: return (return) in toUInt32() : | +| webview.swift:42:5:42:62 | [summary param] this in toNumber() : | file://:0:0:0:0 | [summary] to write: return (return) in toNumber() : | +| webview.swift:43:5:43:44 | [summary param] this in toString() : | file://:0:0:0:0 | [summary] to write: return (return) in toString() : | +| webview.swift:44:5:44:44 | [summary param] this in toDate() : | file://:0:0:0:0 | [summary] to write: return (return) in toDate() : | +| webview.swift:45:5:45:44 | [summary param] this in toArray() : | file://:0:0:0:0 | [summary] to write: return (return) in toArray() : | +| webview.swift:46:5:46:65 | [summary param] this in toDictionary() : | file://:0:0:0:0 | [summary] to write: return (return) in toDictionary() : | +| webview.swift:47:5:47:50 | [summary param] this in toPoint() : | file://:0:0:0:0 | [summary] to write: return (return) in toPoint() : | +| webview.swift:48:5:48:50 | [summary param] this in toRange() : | file://:0:0:0:0 | [summary] to write: return (return) in toRange() : | +| webview.swift:49:5:49:47 | [summary param] this in toRect() : | file://:0:0:0:0 | [summary] to write: return (return) in toRect() : | +| webview.swift:50:5:50:47 | [summary param] this in toSize() : | file://:0:0:0:0 | [summary] to write: return (return) in toSize() : | +| webview.swift:51:5:51:84 | [summary param] this in atIndex(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in atIndex(_:) : | +| webview.swift:52:5:52:53 | [summary param] 1 in defineProperty(_:descriptor:) : | file://:0:0:0:0 | [summary] to write: argument this in defineProperty(_:descriptor:) : | +| webview.swift:53:5:53:89 | [summary param] this in forProperty(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in forProperty(_:) : | +| webview.swift:54:5:54:38 | [summary param] 0 in setValue(_:at:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:at:) : | +| webview.swift:55:5:55:48 | [summary param] 0 in setValue(_:forProperty:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:forProperty:) : | +| webview.swift:77:11:77:18 | call to source() : | webview.swift:77:10:77:41 | .body | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:84:10:84:10 | source : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:85:10:85:10 | source : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:86:10:86:10 | source : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:87:10:87:10 | source : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:88:10:88:10 | source : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:89:10:89:10 | source : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:90:10:90:10 | source : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:91:10:91:10 | source : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:92:10:92:10 | source : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:93:10:93:10 | source : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:94:10:94:10 | source : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:95:10:95:10 | source : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:96:10:96:10 | source : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:97:10:97:10 | source : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:98:10:98:10 | source : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:99:10:99:10 | source : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:100:10:100:10 | source : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:103:26:103:26 | s : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:104:24:104:24 | s : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:105:26:105:26 | s : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:106:25:106:25 | s : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:107:26:107:26 | s : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:108:25:108:25 | s : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:109:25:109:25 | s : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:110:24:110:24 | s : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:111:24:111:24 | s : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:114:39:114:39 | s : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:118:17:118:17 | s : | +| webview.swift:81:13:81:20 | call to source() : | webview.swift:122:17:122:17 | s : | +| webview.swift:84:10:84:10 | source : | webview.swift:36:5:36:41 | [summary param] this in toObject() : | +| webview.swift:84:10:84:10 | source : | webview.swift:84:10:84:26 | call to toObject() | +| webview.swift:85:10:85:10 | source : | webview.swift:37:5:37:55 | [summary param] this in toObjectOf(_:) : | +| webview.swift:85:10:85:10 | source : | webview.swift:85:10:85:41 | call to toObjectOf(_:) | +| webview.swift:86:10:86:10 | source : | webview.swift:38:5:38:42 | [summary param] this in toBool() : | +| webview.swift:86:10:86:10 | source : | webview.swift:86:10:86:24 | call to toBool() | +| webview.swift:87:10:87:10 | source : | webview.swift:39:5:39:44 | [summary param] this in toDouble() : | +| webview.swift:87:10:87:10 | source : | webview.swift:87:10:87:26 | call to toDouble() | +| webview.swift:88:10:88:10 | source : | webview.swift:40:5:40:40 | [summary param] this in toInt32() : | +| webview.swift:88:10:88:10 | source : | webview.swift:88:10:88:25 | call to toInt32() | +| webview.swift:89:10:89:10 | source : | webview.swift:41:5:41:42 | [summary param] this in toUInt32() : | +| webview.swift:89:10:89:10 | source : | webview.swift:89:10:89:26 | call to toUInt32() | +| webview.swift:90:10:90:10 | source : | webview.swift:42:5:42:62 | [summary param] this in toNumber() : | +| webview.swift:90:10:90:10 | source : | webview.swift:90:10:90:26 | call to toNumber() | +| webview.swift:91:10:91:10 | source : | webview.swift:43:5:43:44 | [summary param] this in toString() : | +| webview.swift:91:10:91:10 | source : | webview.swift:91:10:91:26 | call to toString() | +| webview.swift:92:10:92:10 | source : | webview.swift:44:5:44:44 | [summary param] this in toDate() : | +| webview.swift:92:10:92:10 | source : | webview.swift:92:10:92:24 | call to toDate() | +| webview.swift:93:10:93:10 | source : | webview.swift:45:5:45:44 | [summary param] this in toArray() : | +| webview.swift:93:10:93:10 | source : | webview.swift:93:10:93:25 | call to toArray() | +| webview.swift:94:10:94:10 | source : | webview.swift:46:5:46:65 | [summary param] this in toDictionary() : | +| webview.swift:94:10:94:10 | source : | webview.swift:94:10:94:30 | call to toDictionary() | +| webview.swift:95:10:95:10 | source : | webview.swift:47:5:47:50 | [summary param] this in toPoint() : | +| webview.swift:95:10:95:10 | source : | webview.swift:95:10:95:25 | call to toPoint() | +| webview.swift:96:10:96:10 | source : | webview.swift:48:5:48:50 | [summary param] this in toRange() : | +| webview.swift:96:10:96:10 | source : | webview.swift:96:10:96:25 | call to toRange() | +| webview.swift:97:10:97:10 | source : | webview.swift:49:5:49:47 | [summary param] this in toRect() : | +| webview.swift:97:10:97:10 | source : | webview.swift:97:10:97:24 | call to toRect() | +| webview.swift:98:10:98:10 | source : | webview.swift:50:5:50:47 | [summary param] this in toSize() : | +| webview.swift:98:10:98:10 | source : | webview.swift:98:10:98:24 | call to toSize() | +| webview.swift:99:10:99:10 | source : | webview.swift:51:5:51:84 | [summary param] this in atIndex(_:) : | +| webview.swift:99:10:99:10 | source : | webview.swift:99:10:99:26 | call to atIndex(_:) | +| webview.swift:100:10:100:10 | source : | webview.swift:53:5:53:89 | [summary param] this in forProperty(_:) : | +| webview.swift:100:10:100:10 | source : | webview.swift:100:10:100:31 | call to forProperty(_:) | +| webview.swift:103:26:103:26 | s : | webview.swift:27:5:27:39 | [summary param] 0 in init(object:in:) : | +| webview.swift:103:26:103:26 | s : | webview.swift:103:10:103:47 | call to init(object:in:) | +| webview.swift:104:24:104:24 | s : | webview.swift:28:5:28:38 | [summary param] 0 in init(bool:in:) : | +| webview.swift:104:24:104:24 | s : | webview.swift:104:10:104:47 | call to init(bool:in:) | +| webview.swift:105:26:105:26 | s : | webview.swift:29:5:29:42 | [summary param] 0 in init(double:in:) : | +| webview.swift:105:26:105:26 | s : | webview.swift:105:10:105:51 | call to init(double:in:) | +| webview.swift:106:25:106:25 | s : | webview.swift:30:5:30:40 | [summary param] 0 in init(int32:in:) : | +| webview.swift:106:25:106:25 | s : | webview.swift:106:10:106:49 | call to init(int32:in:) | +| webview.swift:107:26:107:26 | s : | webview.swift:31:5:31:42 | [summary param] 0 in init(uInt32:in:) : | +| webview.swift:107:26:107:26 | s : | webview.swift:107:10:107:51 | call to init(uInt32:in:) | +| webview.swift:108:25:108:25 | s : | webview.swift:32:5:32:42 | [summary param] 0 in init(point:in:) : | +| webview.swift:108:25:108:25 | s : | webview.swift:108:10:108:51 | call to init(point:in:) | +| webview.swift:109:25:109:25 | s : | webview.swift:33:5:33:42 | [summary param] 0 in init(range:in:) : | +| webview.swift:109:25:109:25 | s : | webview.swift:109:10:109:51 | call to init(range:in:) | +| webview.swift:110:24:110:24 | s : | webview.swift:34:5:34:40 | [summary param] 0 in init(rect:in:) : | +| webview.swift:110:24:110:24 | s : | webview.swift:110:10:110:49 | call to init(rect:in:) | +| webview.swift:111:24:111:24 | s : | webview.swift:35:5:35:40 | [summary param] 0 in init(size:in:) : | +| webview.swift:111:24:111:24 | s : | webview.swift:111:10:111:49 | call to init(size:in:) | +| webview.swift:114:5:114:5 | [post] v1 : | webview.swift:115:10:115:10 | v1 | +| webview.swift:114:39:114:39 | s : | webview.swift:52:5:52:53 | [summary param] 1 in defineProperty(_:descriptor:) : | +| webview.swift:114:39:114:39 | s : | webview.swift:114:5:114:5 | [post] v1 : | +| webview.swift:118:5:118:5 | [post] v2 : | webview.swift:119:10:119:10 | v2 | +| webview.swift:118:17:118:17 | s : | webview.swift:54:5:54:38 | [summary param] 0 in setValue(_:at:) : | +| webview.swift:118:17:118:17 | s : | webview.swift:118:5:118:5 | [post] v2 : | +| webview.swift:122:5:122:5 | [post] v3 : | webview.swift:123:10:123:10 | v3 | +| webview.swift:122:17:122:17 | s : | webview.swift:55:5:55:48 | [summary param] 0 in setValue(_:forProperty:) : | +| webview.swift:122:17:122:17 | s : | webview.swift:122:5:122:5 | [post] v3 : | nodes | data.swift:25:2:25:66 | [summary param] 0 in init(base64Encoded:options:) : | semmle.label | [summary param] 0 in init(base64Encoded:options:) : | | data.swift:26:2:26:61 | [summary param] 0 in init(buffer:) : | semmle.label | [summary param] 0 in init(buffer:) : | @@ -1023,99 +1023,99 @@ nodes | url.swift:120:46:120:46 | urlTainted : | semmle.label | urlTainted : | | url.swift:120:61:120:61 | data : | semmle.label | data : | | url.swift:121:15:121:19 | ...! | semmle.label | ...! | -| webview.swift:16:5:16:39 | [summary param] 0 in init(object:in:) : | semmle.label | [summary param] 0 in init(object:in:) : | -| webview.swift:17:5:17:38 | [summary param] 0 in init(bool:in:) : | semmle.label | [summary param] 0 in init(bool:in:) : | -| webview.swift:18:5:18:42 | [summary param] 0 in init(double:in:) : | semmle.label | [summary param] 0 in init(double:in:) : | -| webview.swift:19:5:19:40 | [summary param] 0 in init(int32:in:) : | semmle.label | [summary param] 0 in init(int32:in:) : | -| webview.swift:20:5:20:42 | [summary param] 0 in init(uInt32:in:) : | semmle.label | [summary param] 0 in init(uInt32:in:) : | -| webview.swift:21:5:21:42 | [summary param] 0 in init(point:in:) : | semmle.label | [summary param] 0 in init(point:in:) : | -| webview.swift:22:5:22:42 | [summary param] 0 in init(range:in:) : | semmle.label | [summary param] 0 in init(range:in:) : | -| webview.swift:23:5:23:40 | [summary param] 0 in init(rect:in:) : | semmle.label | [summary param] 0 in init(rect:in:) : | -| webview.swift:24:5:24:40 | [summary param] 0 in init(size:in:) : | semmle.label | [summary param] 0 in init(size:in:) : | -| webview.swift:25:5:25:41 | [summary param] this in toObject() : | semmle.label | [summary param] this in toObject() : | -| webview.swift:26:5:26:55 | [summary param] this in toObjectOf(_:) : | semmle.label | [summary param] this in toObjectOf(_:) : | -| webview.swift:27:5:27:42 | [summary param] this in toBool() : | semmle.label | [summary param] this in toBool() : | -| webview.swift:28:5:28:44 | [summary param] this in toDouble() : | semmle.label | [summary param] this in toDouble() : | -| webview.swift:29:5:29:40 | [summary param] this in toInt32() : | semmle.label | [summary param] this in toInt32() : | -| webview.swift:30:5:30:42 | [summary param] this in toUInt32() : | semmle.label | [summary param] this in toUInt32() : | -| webview.swift:31:5:31:62 | [summary param] this in toNumber() : | semmle.label | [summary param] this in toNumber() : | -| webview.swift:32:5:32:44 | [summary param] this in toString() : | semmle.label | [summary param] this in toString() : | -| webview.swift:33:5:33:44 | [summary param] this in toDate() : | semmle.label | [summary param] this in toDate() : | -| webview.swift:34:5:34:44 | [summary param] this in toArray() : | semmle.label | [summary param] this in toArray() : | -| webview.swift:35:5:35:65 | [summary param] this in toDictionary() : | semmle.label | [summary param] this in toDictionary() : | -| webview.swift:36:5:36:50 | [summary param] this in toPoint() : | semmle.label | [summary param] this in toPoint() : | -| webview.swift:37:5:37:50 | [summary param] this in toRange() : | semmle.label | [summary param] this in toRange() : | -| webview.swift:38:5:38:47 | [summary param] this in toRect() : | semmle.label | [summary param] this in toRect() : | -| webview.swift:39:5:39:47 | [summary param] this in toSize() : | semmle.label | [summary param] this in toSize() : | -| webview.swift:40:5:40:84 | [summary param] this in atIndex(_:) : | semmle.label | [summary param] this in atIndex(_:) : | -| webview.swift:41:5:41:53 | [summary param] 1 in defineProperty(_:descriptor:) : | semmle.label | [summary param] 1 in defineProperty(_:descriptor:) : | -| webview.swift:42:5:42:89 | [summary param] this in forProperty(_:) : | semmle.label | [summary param] this in forProperty(_:) : | -| webview.swift:43:5:43:38 | [summary param] 0 in setValue(_:at:) : | semmle.label | [summary param] 0 in setValue(_:at:) : | -| webview.swift:44:5:44:48 | [summary param] 0 in setValue(_:forProperty:) : | semmle.label | [summary param] 0 in setValue(_:forProperty:) : | -| webview.swift:52:10:52:41 | .body | semmle.label | .body | -| webview.swift:52:11:52:18 | call to source() : | semmle.label | call to source() : | -| webview.swift:56:13:56:20 | call to source() : | semmle.label | call to source() : | -| webview.swift:59:10:59:10 | source : | semmle.label | source : | -| webview.swift:59:10:59:26 | call to toObject() | semmle.label | call to toObject() | -| webview.swift:60:10:60:10 | source : | semmle.label | source : | -| webview.swift:60:10:60:41 | call to toObjectOf(_:) | semmle.label | call to toObjectOf(_:) | -| webview.swift:61:10:61:10 | source : | semmle.label | source : | -| webview.swift:61:10:61:24 | call to toBool() | semmle.label | call to toBool() | -| webview.swift:62:10:62:10 | source : | semmle.label | source : | -| webview.swift:62:10:62:26 | call to toDouble() | semmle.label | call to toDouble() | -| webview.swift:63:10:63:10 | source : | semmle.label | source : | -| webview.swift:63:10:63:25 | call to toInt32() | semmle.label | call to toInt32() | -| webview.swift:64:10:64:10 | source : | semmle.label | source : | -| webview.swift:64:10:64:26 | call to toUInt32() | semmle.label | call to toUInt32() | -| webview.swift:65:10:65:10 | source : | semmle.label | source : | -| webview.swift:65:10:65:26 | call to toNumber() | semmle.label | call to toNumber() | -| webview.swift:66:10:66:10 | source : | semmle.label | source : | -| webview.swift:66:10:66:26 | call to toString() | semmle.label | call to toString() | -| webview.swift:67:10:67:10 | source : | semmle.label | source : | -| webview.swift:67:10:67:24 | call to toDate() | semmle.label | call to toDate() | -| webview.swift:68:10:68:10 | source : | semmle.label | source : | -| webview.swift:68:10:68:25 | call to toArray() | semmle.label | call to toArray() | -| webview.swift:69:10:69:10 | source : | semmle.label | source : | -| webview.swift:69:10:69:30 | call to toDictionary() | semmle.label | call to toDictionary() | -| webview.swift:70:10:70:10 | source : | semmle.label | source : | -| webview.swift:70:10:70:25 | call to toPoint() | semmle.label | call to toPoint() | -| webview.swift:71:10:71:10 | source : | semmle.label | source : | -| webview.swift:71:10:71:25 | call to toRange() | semmle.label | call to toRange() | -| webview.swift:72:10:72:10 | source : | semmle.label | source : | -| webview.swift:72:10:72:24 | call to toRect() | semmle.label | call to toRect() | -| webview.swift:73:10:73:10 | source : | semmle.label | source : | -| webview.swift:73:10:73:24 | call to toSize() | semmle.label | call to toSize() | -| webview.swift:74:10:74:10 | source : | semmle.label | source : | -| webview.swift:74:10:74:26 | call to atIndex(_:) | semmle.label | call to atIndex(_:) | -| webview.swift:75:10:75:10 | source : | semmle.label | source : | -| webview.swift:75:10:75:31 | call to forProperty(_:) | semmle.label | call to forProperty(_:) | -| webview.swift:78:10:78:47 | call to init(object:in:) | semmle.label | call to init(object:in:) | -| webview.swift:78:26:78:26 | s : | semmle.label | s : | -| webview.swift:79:10:79:47 | call to init(bool:in:) | semmle.label | call to init(bool:in:) | -| webview.swift:79:24:79:24 | s : | semmle.label | s : | -| webview.swift:80:10:80:51 | call to init(double:in:) | semmle.label | call to init(double:in:) | -| webview.swift:80:26:80:26 | s : | semmle.label | s : | -| webview.swift:81:10:81:49 | call to init(int32:in:) | semmle.label | call to init(int32:in:) | -| webview.swift:81:25:81:25 | s : | semmle.label | s : | -| webview.swift:82:10:82:51 | call to init(uInt32:in:) | semmle.label | call to init(uInt32:in:) | -| webview.swift:82:26:82:26 | s : | semmle.label | s : | -| webview.swift:83:10:83:51 | call to init(point:in:) | semmle.label | call to init(point:in:) | -| webview.swift:83:25:83:25 | s : | semmle.label | s : | -| webview.swift:84:10:84:51 | call to init(range:in:) | semmle.label | call to init(range:in:) | -| webview.swift:84:25:84:25 | s : | semmle.label | s : | -| webview.swift:85:10:85:49 | call to init(rect:in:) | semmle.label | call to init(rect:in:) | -| webview.swift:85:24:85:24 | s : | semmle.label | s : | -| webview.swift:86:10:86:49 | call to init(size:in:) | semmle.label | call to init(size:in:) | -| webview.swift:86:24:86:24 | s : | semmle.label | s : | -| webview.swift:89:5:89:5 | [post] v1 : | semmle.label | [post] v1 : | -| webview.swift:89:39:89:39 | s : | semmle.label | s : | -| webview.swift:90:10:90:10 | v1 | semmle.label | v1 | -| webview.swift:93:5:93:5 | [post] v2 : | semmle.label | [post] v2 : | -| webview.swift:93:17:93:17 | s : | semmle.label | s : | -| webview.swift:94:10:94:10 | v2 | semmle.label | v2 | -| webview.swift:97:5:97:5 | [post] v3 : | semmle.label | [post] v3 : | -| webview.swift:97:17:97:17 | s : | semmle.label | s : | -| webview.swift:98:10:98:10 | v3 | semmle.label | v3 | +| webview.swift:27:5:27:39 | [summary param] 0 in init(object:in:) : | semmle.label | [summary param] 0 in init(object:in:) : | +| webview.swift:28:5:28:38 | [summary param] 0 in init(bool:in:) : | semmle.label | [summary param] 0 in init(bool:in:) : | +| webview.swift:29:5:29:42 | [summary param] 0 in init(double:in:) : | semmle.label | [summary param] 0 in init(double:in:) : | +| webview.swift:30:5:30:40 | [summary param] 0 in init(int32:in:) : | semmle.label | [summary param] 0 in init(int32:in:) : | +| webview.swift:31:5:31:42 | [summary param] 0 in init(uInt32:in:) : | semmle.label | [summary param] 0 in init(uInt32:in:) : | +| webview.swift:32:5:32:42 | [summary param] 0 in init(point:in:) : | semmle.label | [summary param] 0 in init(point:in:) : | +| webview.swift:33:5:33:42 | [summary param] 0 in init(range:in:) : | semmle.label | [summary param] 0 in init(range:in:) : | +| webview.swift:34:5:34:40 | [summary param] 0 in init(rect:in:) : | semmle.label | [summary param] 0 in init(rect:in:) : | +| webview.swift:35:5:35:40 | [summary param] 0 in init(size:in:) : | semmle.label | [summary param] 0 in init(size:in:) : | +| webview.swift:36:5:36:41 | [summary param] this in toObject() : | semmle.label | [summary param] this in toObject() : | +| webview.swift:37:5:37:55 | [summary param] this in toObjectOf(_:) : | semmle.label | [summary param] this in toObjectOf(_:) : | +| webview.swift:38:5:38:42 | [summary param] this in toBool() : | semmle.label | [summary param] this in toBool() : | +| webview.swift:39:5:39:44 | [summary param] this in toDouble() : | semmle.label | [summary param] this in toDouble() : | +| webview.swift:40:5:40:40 | [summary param] this in toInt32() : | semmle.label | [summary param] this in toInt32() : | +| webview.swift:41:5:41:42 | [summary param] this in toUInt32() : | semmle.label | [summary param] this in toUInt32() : | +| webview.swift:42:5:42:62 | [summary param] this in toNumber() : | semmle.label | [summary param] this in toNumber() : | +| webview.swift:43:5:43:44 | [summary param] this in toString() : | semmle.label | [summary param] this in toString() : | +| webview.swift:44:5:44:44 | [summary param] this in toDate() : | semmle.label | [summary param] this in toDate() : | +| webview.swift:45:5:45:44 | [summary param] this in toArray() : | semmle.label | [summary param] this in toArray() : | +| webview.swift:46:5:46:65 | [summary param] this in toDictionary() : | semmle.label | [summary param] this in toDictionary() : | +| webview.swift:47:5:47:50 | [summary param] this in toPoint() : | semmle.label | [summary param] this in toPoint() : | +| webview.swift:48:5:48:50 | [summary param] this in toRange() : | semmle.label | [summary param] this in toRange() : | +| webview.swift:49:5:49:47 | [summary param] this in toRect() : | semmle.label | [summary param] this in toRect() : | +| webview.swift:50:5:50:47 | [summary param] this in toSize() : | semmle.label | [summary param] this in toSize() : | +| webview.swift:51:5:51:84 | [summary param] this in atIndex(_:) : | semmle.label | [summary param] this in atIndex(_:) : | +| webview.swift:52:5:52:53 | [summary param] 1 in defineProperty(_:descriptor:) : | semmle.label | [summary param] 1 in defineProperty(_:descriptor:) : | +| webview.swift:53:5:53:89 | [summary param] this in forProperty(_:) : | semmle.label | [summary param] this in forProperty(_:) : | +| webview.swift:54:5:54:38 | [summary param] 0 in setValue(_:at:) : | semmle.label | [summary param] 0 in setValue(_:at:) : | +| webview.swift:55:5:55:48 | [summary param] 0 in setValue(_:forProperty:) : | semmle.label | [summary param] 0 in setValue(_:forProperty:) : | +| webview.swift:77:10:77:41 | .body | semmle.label | .body | +| webview.swift:77:11:77:18 | call to source() : | semmle.label | call to source() : | +| webview.swift:81:13:81:20 | call to source() : | semmle.label | call to source() : | +| webview.swift:84:10:84:10 | source : | semmle.label | source : | +| webview.swift:84:10:84:26 | call to toObject() | semmle.label | call to toObject() | +| webview.swift:85:10:85:10 | source : | semmle.label | source : | +| webview.swift:85:10:85:41 | call to toObjectOf(_:) | semmle.label | call to toObjectOf(_:) | +| webview.swift:86:10:86:10 | source : | semmle.label | source : | +| webview.swift:86:10:86:24 | call to toBool() | semmle.label | call to toBool() | +| webview.swift:87:10:87:10 | source : | semmle.label | source : | +| webview.swift:87:10:87:26 | call to toDouble() | semmle.label | call to toDouble() | +| webview.swift:88:10:88:10 | source : | semmle.label | source : | +| webview.swift:88:10:88:25 | call to toInt32() | semmle.label | call to toInt32() | +| webview.swift:89:10:89:10 | source : | semmle.label | source : | +| webview.swift:89:10:89:26 | call to toUInt32() | semmle.label | call to toUInt32() | +| webview.swift:90:10:90:10 | source : | semmle.label | source : | +| webview.swift:90:10:90:26 | call to toNumber() | semmle.label | call to toNumber() | +| webview.swift:91:10:91:10 | source : | semmle.label | source : | +| webview.swift:91:10:91:26 | call to toString() | semmle.label | call to toString() | +| webview.swift:92:10:92:10 | source : | semmle.label | source : | +| webview.swift:92:10:92:24 | call to toDate() | semmle.label | call to toDate() | +| webview.swift:93:10:93:10 | source : | semmle.label | source : | +| webview.swift:93:10:93:25 | call to toArray() | semmle.label | call to toArray() | +| webview.swift:94:10:94:10 | source : | semmle.label | source : | +| webview.swift:94:10:94:30 | call to toDictionary() | semmle.label | call to toDictionary() | +| webview.swift:95:10:95:10 | source : | semmle.label | source : | +| webview.swift:95:10:95:25 | call to toPoint() | semmle.label | call to toPoint() | +| webview.swift:96:10:96:10 | source : | semmle.label | source : | +| webview.swift:96:10:96:25 | call to toRange() | semmle.label | call to toRange() | +| webview.swift:97:10:97:10 | source : | semmle.label | source : | +| webview.swift:97:10:97:24 | call to toRect() | semmle.label | call to toRect() | +| webview.swift:98:10:98:10 | source : | semmle.label | source : | +| webview.swift:98:10:98:24 | call to toSize() | semmle.label | call to toSize() | +| webview.swift:99:10:99:10 | source : | semmle.label | source : | +| webview.swift:99:10:99:26 | call to atIndex(_:) | semmle.label | call to atIndex(_:) | +| webview.swift:100:10:100:10 | source : | semmle.label | source : | +| webview.swift:100:10:100:31 | call to forProperty(_:) | semmle.label | call to forProperty(_:) | +| webview.swift:103:10:103:47 | call to init(object:in:) | semmle.label | call to init(object:in:) | +| webview.swift:103:26:103:26 | s : | semmle.label | s : | +| webview.swift:104:10:104:47 | call to init(bool:in:) | semmle.label | call to init(bool:in:) | +| webview.swift:104:24:104:24 | s : | semmle.label | s : | +| webview.swift:105:10:105:51 | call to init(double:in:) | semmle.label | call to init(double:in:) | +| webview.swift:105:26:105:26 | s : | semmle.label | s : | +| webview.swift:106:10:106:49 | call to init(int32:in:) | semmle.label | call to init(int32:in:) | +| webview.swift:106:25:106:25 | s : | semmle.label | s : | +| webview.swift:107:10:107:51 | call to init(uInt32:in:) | semmle.label | call to init(uInt32:in:) | +| webview.swift:107:26:107:26 | s : | semmle.label | s : | +| webview.swift:108:10:108:51 | call to init(point:in:) | semmle.label | call to init(point:in:) | +| webview.swift:108:25:108:25 | s : | semmle.label | s : | +| webview.swift:109:10:109:51 | call to init(range:in:) | semmle.label | call to init(range:in:) | +| webview.swift:109:25:109:25 | s : | semmle.label | s : | +| webview.swift:110:10:110:49 | call to init(rect:in:) | semmle.label | call to init(rect:in:) | +| webview.swift:110:24:110:24 | s : | semmle.label | s : | +| webview.swift:111:10:111:49 | call to init(size:in:) | semmle.label | call to init(size:in:) | +| webview.swift:111:24:111:24 | s : | semmle.label | s : | +| webview.swift:114:5:114:5 | [post] v1 : | semmle.label | [post] v1 : | +| webview.swift:114:39:114:39 | s : | semmle.label | s : | +| webview.swift:115:10:115:10 | v1 | semmle.label | v1 | +| webview.swift:118:5:118:5 | [post] v2 : | semmle.label | [post] v2 : | +| webview.swift:118:17:118:17 | s : | semmle.label | s : | +| webview.swift:119:10:119:10 | v2 | semmle.label | v2 | +| webview.swift:122:5:122:5 | [post] v3 : | semmle.label | [post] v3 : | +| webview.swift:122:17:122:17 | s : | semmle.label | s : | +| webview.swift:123:10:123:10 | v3 | semmle.label | v3 | subpaths | data.swift:89:41:89:48 | call to source() : | data.swift:25:2:25:66 | [summary param] 0 in init(base64Encoded:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | data.swift:89:21:89:71 | call to init(base64Encoded:options:) : | | data.swift:93:34:93:41 | call to source() : | data.swift:26:2:26:61 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | data.swift:93:21:93:73 | call to init(buffer:) : | @@ -1206,35 +1206,35 @@ subpaths | url.swift:101:46:101:46 | urlTainted : | url.swift:9:2:9:43 | [summary param] 1 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | url.swift:101:15:101:56 | call to init(string:relativeTo:) : | | url.swift:102:46:102:46 | urlTainted : | url.swift:9:2:9:43 | [summary param] 1 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | url.swift:102:15:102:56 | call to init(string:relativeTo:) : | | url.swift:117:28:117:28 | tainted : | url.swift:8:2:8:25 | [summary param] 0 in init(string:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | url.swift:117:16:117:35 | call to init(string:) : | -| webview.swift:59:10:59:10 | source : | webview.swift:25:5:25:41 | [summary param] this in toObject() : | file://:0:0:0:0 | [summary] to write: return (return) in toObject() : | webview.swift:59:10:59:26 | call to toObject() | -| webview.swift:60:10:60:10 | source : | webview.swift:26:5:26:55 | [summary param] this in toObjectOf(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in toObjectOf(_:) : | webview.swift:60:10:60:41 | call to toObjectOf(_:) | -| webview.swift:61:10:61:10 | source : | webview.swift:27:5:27:42 | [summary param] this in toBool() : | file://:0:0:0:0 | [summary] to write: return (return) in toBool() : | webview.swift:61:10:61:24 | call to toBool() | -| webview.swift:62:10:62:10 | source : | webview.swift:28:5:28:44 | [summary param] this in toDouble() : | file://:0:0:0:0 | [summary] to write: return (return) in toDouble() : | webview.swift:62:10:62:26 | call to toDouble() | -| webview.swift:63:10:63:10 | source : | webview.swift:29:5:29:40 | [summary param] this in toInt32() : | file://:0:0:0:0 | [summary] to write: return (return) in toInt32() : | webview.swift:63:10:63:25 | call to toInt32() | -| webview.swift:64:10:64:10 | source : | webview.swift:30:5:30:42 | [summary param] this in toUInt32() : | file://:0:0:0:0 | [summary] to write: return (return) in toUInt32() : | webview.swift:64:10:64:26 | call to toUInt32() | -| webview.swift:65:10:65:10 | source : | webview.swift:31:5:31:62 | [summary param] this in toNumber() : | file://:0:0:0:0 | [summary] to write: return (return) in toNumber() : | webview.swift:65:10:65:26 | call to toNumber() | -| webview.swift:66:10:66:10 | source : | webview.swift:32:5:32:44 | [summary param] this in toString() : | file://:0:0:0:0 | [summary] to write: return (return) in toString() : | webview.swift:66:10:66:26 | call to toString() | -| webview.swift:67:10:67:10 | source : | webview.swift:33:5:33:44 | [summary param] this in toDate() : | file://:0:0:0:0 | [summary] to write: return (return) in toDate() : | webview.swift:67:10:67:24 | call to toDate() | -| webview.swift:68:10:68:10 | source : | webview.swift:34:5:34:44 | [summary param] this in toArray() : | file://:0:0:0:0 | [summary] to write: return (return) in toArray() : | webview.swift:68:10:68:25 | call to toArray() | -| webview.swift:69:10:69:10 | source : | webview.swift:35:5:35:65 | [summary param] this in toDictionary() : | file://:0:0:0:0 | [summary] to write: return (return) in toDictionary() : | webview.swift:69:10:69:30 | call to toDictionary() | -| webview.swift:70:10:70:10 | source : | webview.swift:36:5:36:50 | [summary param] this in toPoint() : | file://:0:0:0:0 | [summary] to write: return (return) in toPoint() : | webview.swift:70:10:70:25 | call to toPoint() | -| webview.swift:71:10:71:10 | source : | webview.swift:37:5:37:50 | [summary param] this in toRange() : | file://:0:0:0:0 | [summary] to write: return (return) in toRange() : | webview.swift:71:10:71:25 | call to toRange() | -| webview.swift:72:10:72:10 | source : | webview.swift:38:5:38:47 | [summary param] this in toRect() : | file://:0:0:0:0 | [summary] to write: return (return) in toRect() : | webview.swift:72:10:72:24 | call to toRect() | -| webview.swift:73:10:73:10 | source : | webview.swift:39:5:39:47 | [summary param] this in toSize() : | file://:0:0:0:0 | [summary] to write: return (return) in toSize() : | webview.swift:73:10:73:24 | call to toSize() | -| webview.swift:74:10:74:10 | source : | webview.swift:40:5:40:84 | [summary param] this in atIndex(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in atIndex(_:) : | webview.swift:74:10:74:26 | call to atIndex(_:) | -| webview.swift:75:10:75:10 | source : | webview.swift:42:5:42:89 | [summary param] this in forProperty(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in forProperty(_:) : | webview.swift:75:10:75:31 | call to forProperty(_:) | -| webview.swift:78:26:78:26 | s : | webview.swift:16:5:16:39 | [summary param] 0 in init(object:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(object:in:) : | webview.swift:78:10:78:47 | call to init(object:in:) | -| webview.swift:79:24:79:24 | s : | webview.swift:17:5:17:38 | [summary param] 0 in init(bool:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bool:in:) : | webview.swift:79:10:79:47 | call to init(bool:in:) | -| webview.swift:80:26:80:26 | s : | webview.swift:18:5:18:42 | [summary param] 0 in init(double:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(double:in:) : | webview.swift:80:10:80:51 | call to init(double:in:) | -| webview.swift:81:25:81:25 | s : | webview.swift:19:5:19:40 | [summary param] 0 in init(int32:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(int32:in:) : | webview.swift:81:10:81:49 | call to init(int32:in:) | -| webview.swift:82:26:82:26 | s : | webview.swift:20:5:20:42 | [summary param] 0 in init(uInt32:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(uInt32:in:) : | webview.swift:82:10:82:51 | call to init(uInt32:in:) | -| webview.swift:83:25:83:25 | s : | webview.swift:21:5:21:42 | [summary param] 0 in init(point:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(point:in:) : | webview.swift:83:10:83:51 | call to init(point:in:) | -| webview.swift:84:25:84:25 | s : | webview.swift:22:5:22:42 | [summary param] 0 in init(range:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(range:in:) : | webview.swift:84:10:84:51 | call to init(range:in:) | -| webview.swift:85:24:85:24 | s : | webview.swift:23:5:23:40 | [summary param] 0 in init(rect:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(rect:in:) : | webview.swift:85:10:85:49 | call to init(rect:in:) | -| webview.swift:86:24:86:24 | s : | webview.swift:24:5:24:40 | [summary param] 0 in init(size:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(size:in:) : | webview.swift:86:10:86:49 | call to init(size:in:) | -| webview.swift:89:39:89:39 | s : | webview.swift:41:5:41:53 | [summary param] 1 in defineProperty(_:descriptor:) : | file://:0:0:0:0 | [summary] to write: argument this in defineProperty(_:descriptor:) : | webview.swift:89:5:89:5 | [post] v1 : | -| webview.swift:93:17:93:17 | s : | webview.swift:43:5:43:38 | [summary param] 0 in setValue(_:at:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:at:) : | webview.swift:93:5:93:5 | [post] v2 : | -| webview.swift:97:17:97:17 | s : | webview.swift:44:5:44:48 | [summary param] 0 in setValue(_:forProperty:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:forProperty:) : | webview.swift:97:5:97:5 | [post] v3 : | +| webview.swift:84:10:84:10 | source : | webview.swift:36:5:36:41 | [summary param] this in toObject() : | file://:0:0:0:0 | [summary] to write: return (return) in toObject() : | webview.swift:84:10:84:26 | call to toObject() | +| webview.swift:85:10:85:10 | source : | webview.swift:37:5:37:55 | [summary param] this in toObjectOf(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in toObjectOf(_:) : | webview.swift:85:10:85:41 | call to toObjectOf(_:) | +| webview.swift:86:10:86:10 | source : | webview.swift:38:5:38:42 | [summary param] this in toBool() : | file://:0:0:0:0 | [summary] to write: return (return) in toBool() : | webview.swift:86:10:86:24 | call to toBool() | +| webview.swift:87:10:87:10 | source : | webview.swift:39:5:39:44 | [summary param] this in toDouble() : | file://:0:0:0:0 | [summary] to write: return (return) in toDouble() : | webview.swift:87:10:87:26 | call to toDouble() | +| webview.swift:88:10:88:10 | source : | webview.swift:40:5:40:40 | [summary param] this in toInt32() : | file://:0:0:0:0 | [summary] to write: return (return) in toInt32() : | webview.swift:88:10:88:25 | call to toInt32() | +| webview.swift:89:10:89:10 | source : | webview.swift:41:5:41:42 | [summary param] this in toUInt32() : | file://:0:0:0:0 | [summary] to write: return (return) in toUInt32() : | webview.swift:89:10:89:26 | call to toUInt32() | +| webview.swift:90:10:90:10 | source : | webview.swift:42:5:42:62 | [summary param] this in toNumber() : | file://:0:0:0:0 | [summary] to write: return (return) in toNumber() : | webview.swift:90:10:90:26 | call to toNumber() | +| webview.swift:91:10:91:10 | source : | webview.swift:43:5:43:44 | [summary param] this in toString() : | file://:0:0:0:0 | [summary] to write: return (return) in toString() : | webview.swift:91:10:91:26 | call to toString() | +| webview.swift:92:10:92:10 | source : | webview.swift:44:5:44:44 | [summary param] this in toDate() : | file://:0:0:0:0 | [summary] to write: return (return) in toDate() : | webview.swift:92:10:92:24 | call to toDate() | +| webview.swift:93:10:93:10 | source : | webview.swift:45:5:45:44 | [summary param] this in toArray() : | file://:0:0:0:0 | [summary] to write: return (return) in toArray() : | webview.swift:93:10:93:25 | call to toArray() | +| webview.swift:94:10:94:10 | source : | webview.swift:46:5:46:65 | [summary param] this in toDictionary() : | file://:0:0:0:0 | [summary] to write: return (return) in toDictionary() : | webview.swift:94:10:94:30 | call to toDictionary() | +| webview.swift:95:10:95:10 | source : | webview.swift:47:5:47:50 | [summary param] this in toPoint() : | file://:0:0:0:0 | [summary] to write: return (return) in toPoint() : | webview.swift:95:10:95:25 | call to toPoint() | +| webview.swift:96:10:96:10 | source : | webview.swift:48:5:48:50 | [summary param] this in toRange() : | file://:0:0:0:0 | [summary] to write: return (return) in toRange() : | webview.swift:96:10:96:25 | call to toRange() | +| webview.swift:97:10:97:10 | source : | webview.swift:49:5:49:47 | [summary param] this in toRect() : | file://:0:0:0:0 | [summary] to write: return (return) in toRect() : | webview.swift:97:10:97:24 | call to toRect() | +| webview.swift:98:10:98:10 | source : | webview.swift:50:5:50:47 | [summary param] this in toSize() : | file://:0:0:0:0 | [summary] to write: return (return) in toSize() : | webview.swift:98:10:98:24 | call to toSize() | +| webview.swift:99:10:99:10 | source : | webview.swift:51:5:51:84 | [summary param] this in atIndex(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in atIndex(_:) : | webview.swift:99:10:99:26 | call to atIndex(_:) | +| webview.swift:100:10:100:10 | source : | webview.swift:53:5:53:89 | [summary param] this in forProperty(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in forProperty(_:) : | webview.swift:100:10:100:31 | call to forProperty(_:) | +| webview.swift:103:26:103:26 | s : | webview.swift:27:5:27:39 | [summary param] 0 in init(object:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(object:in:) : | webview.swift:103:10:103:47 | call to init(object:in:) | +| webview.swift:104:24:104:24 | s : | webview.swift:28:5:28:38 | [summary param] 0 in init(bool:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(bool:in:) : | webview.swift:104:10:104:47 | call to init(bool:in:) | +| webview.swift:105:26:105:26 | s : | webview.swift:29:5:29:42 | [summary param] 0 in init(double:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(double:in:) : | webview.swift:105:10:105:51 | call to init(double:in:) | +| webview.swift:106:25:106:25 | s : | webview.swift:30:5:30:40 | [summary param] 0 in init(int32:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(int32:in:) : | webview.swift:106:10:106:49 | call to init(int32:in:) | +| webview.swift:107:26:107:26 | s : | webview.swift:31:5:31:42 | [summary param] 0 in init(uInt32:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(uInt32:in:) : | webview.swift:107:10:107:51 | call to init(uInt32:in:) | +| webview.swift:108:25:108:25 | s : | webview.swift:32:5:32:42 | [summary param] 0 in init(point:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(point:in:) : | webview.swift:108:10:108:51 | call to init(point:in:) | +| webview.swift:109:25:109:25 | s : | webview.swift:33:5:33:42 | [summary param] 0 in init(range:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(range:in:) : | webview.swift:109:10:109:51 | call to init(range:in:) | +| webview.swift:110:24:110:24 | s : | webview.swift:34:5:34:40 | [summary param] 0 in init(rect:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(rect:in:) : | webview.swift:110:10:110:49 | call to init(rect:in:) | +| webview.swift:111:24:111:24 | s : | webview.swift:35:5:35:40 | [summary param] 0 in init(size:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(size:in:) : | webview.swift:111:10:111:49 | call to init(size:in:) | +| webview.swift:114:39:114:39 | s : | webview.swift:52:5:52:53 | [summary param] 1 in defineProperty(_:descriptor:) : | file://:0:0:0:0 | [summary] to write: argument this in defineProperty(_:descriptor:) : | webview.swift:114:5:114:5 | [post] v1 : | +| webview.swift:118:17:118:17 | s : | webview.swift:54:5:54:38 | [summary param] 0 in setValue(_:at:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:at:) : | webview.swift:118:5:118:5 | [post] v2 : | +| webview.swift:122:17:122:17 | s : | webview.swift:55:5:55:48 | [summary param] 0 in setValue(_:forProperty:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:forProperty:) : | webview.swift:122:5:122:5 | [post] v3 : | #select | data.swift:90:12:90:12 | dataTainted3 | data.swift:89:41:89:48 | call to source() : | data.swift:90:12:90:12 | dataTainted3 | result | | data.swift:94:12:94:12 | dataTainted4 | data.swift:93:34:93:41 | call to source() : | data.swift:94:12:94:12 | dataTainted4 | result | @@ -1359,33 +1359,33 @@ subpaths | url.swift:102:15:102:67 | ...! | url.swift:57:16:57:23 | call to source() : | url.swift:102:15:102:67 | ...! | result | | url.swift:118:12:118:12 | ...! | url.swift:57:16:57:23 | call to source() : | url.swift:118:12:118:12 | ...! | result | | url.swift:121:15:121:19 | ...! | url.swift:57:16:57:23 | call to source() : | url.swift:121:15:121:19 | ...! | result | -| webview.swift:52:10:52:41 | .body | webview.swift:52:11:52:18 | call to source() : | webview.swift:52:10:52:41 | .body | result | -| webview.swift:59:10:59:26 | call to toObject() | webview.swift:56:13:56:20 | call to source() : | webview.swift:59:10:59:26 | call to toObject() | result | -| webview.swift:60:10:60:41 | call to toObjectOf(_:) | webview.swift:56:13:56:20 | call to source() : | webview.swift:60:10:60:41 | call to toObjectOf(_:) | result | -| webview.swift:61:10:61:24 | call to toBool() | webview.swift:56:13:56:20 | call to source() : | webview.swift:61:10:61:24 | call to toBool() | result | -| webview.swift:62:10:62:26 | call to toDouble() | webview.swift:56:13:56:20 | call to source() : | webview.swift:62:10:62:26 | call to toDouble() | result | -| webview.swift:63:10:63:25 | call to toInt32() | webview.swift:56:13:56:20 | call to source() : | webview.swift:63:10:63:25 | call to toInt32() | result | -| webview.swift:64:10:64:26 | call to toUInt32() | webview.swift:56:13:56:20 | call to source() : | webview.swift:64:10:64:26 | call to toUInt32() | result | -| webview.swift:65:10:65:26 | call to toNumber() | webview.swift:56:13:56:20 | call to source() : | webview.swift:65:10:65:26 | call to toNumber() | result | -| webview.swift:66:10:66:26 | call to toString() | webview.swift:56:13:56:20 | call to source() : | webview.swift:66:10:66:26 | call to toString() | result | -| webview.swift:67:10:67:24 | call to toDate() | webview.swift:56:13:56:20 | call to source() : | webview.swift:67:10:67:24 | call to toDate() | result | -| webview.swift:68:10:68:25 | call to toArray() | webview.swift:56:13:56:20 | call to source() : | webview.swift:68:10:68:25 | call to toArray() | result | -| webview.swift:69:10:69:30 | call to toDictionary() | webview.swift:56:13:56:20 | call to source() : | webview.swift:69:10:69:30 | call to toDictionary() | result | -| webview.swift:70:10:70:25 | call to toPoint() | webview.swift:56:13:56:20 | call to source() : | webview.swift:70:10:70:25 | call to toPoint() | result | -| webview.swift:71:10:71:25 | call to toRange() | webview.swift:56:13:56:20 | call to source() : | webview.swift:71:10:71:25 | call to toRange() | result | -| webview.swift:72:10:72:24 | call to toRect() | webview.swift:56:13:56:20 | call to source() : | webview.swift:72:10:72:24 | call to toRect() | result | -| webview.swift:73:10:73:24 | call to toSize() | webview.swift:56:13:56:20 | call to source() : | webview.swift:73:10:73:24 | call to toSize() | result | -| webview.swift:74:10:74:26 | call to atIndex(_:) | webview.swift:56:13:56:20 | call to source() : | webview.swift:74:10:74:26 | call to atIndex(_:) | result | -| webview.swift:75:10:75:31 | call to forProperty(_:) | webview.swift:56:13:56:20 | call to source() : | webview.swift:75:10:75:31 | call to forProperty(_:) | result | -| webview.swift:78:10:78:47 | call to init(object:in:) | webview.swift:56:13:56:20 | call to source() : | webview.swift:78:10:78:47 | call to init(object:in:) | result | -| webview.swift:79:10:79:47 | call to init(bool:in:) | webview.swift:56:13:56:20 | call to source() : | webview.swift:79:10:79:47 | call to init(bool:in:) | result | -| webview.swift:80:10:80:51 | call to init(double:in:) | webview.swift:56:13:56:20 | call to source() : | webview.swift:80:10:80:51 | call to init(double:in:) | result | -| webview.swift:81:10:81:49 | call to init(int32:in:) | webview.swift:56:13:56:20 | call to source() : | webview.swift:81:10:81:49 | call to init(int32:in:) | result | -| webview.swift:82:10:82:51 | call to init(uInt32:in:) | webview.swift:56:13:56:20 | call to source() : | webview.swift:82:10:82:51 | call to init(uInt32:in:) | result | -| webview.swift:83:10:83:51 | call to init(point:in:) | webview.swift:56:13:56:20 | call to source() : | webview.swift:83:10:83:51 | call to init(point:in:) | result | -| webview.swift:84:10:84:51 | call to init(range:in:) | webview.swift:56:13:56:20 | call to source() : | webview.swift:84:10:84:51 | call to init(range:in:) | result | -| webview.swift:85:10:85:49 | call to init(rect:in:) | webview.swift:56:13:56:20 | call to source() : | webview.swift:85:10:85:49 | call to init(rect:in:) | result | -| webview.swift:86:10:86:49 | call to init(size:in:) | webview.swift:56:13:56:20 | call to source() : | webview.swift:86:10:86:49 | call to init(size:in:) | result | -| webview.swift:90:10:90:10 | v1 | webview.swift:56:13:56:20 | call to source() : | webview.swift:90:10:90:10 | v1 | result | -| webview.swift:94:10:94:10 | v2 | webview.swift:56:13:56:20 | call to source() : | webview.swift:94:10:94:10 | v2 | result | -| webview.swift:98:10:98:10 | v3 | webview.swift:56:13:56:20 | call to source() : | webview.swift:98:10:98:10 | v3 | result | +| webview.swift:77:10:77:41 | .body | webview.swift:77:11:77:18 | call to source() : | webview.swift:77:10:77:41 | .body | result | +| webview.swift:84:10:84:26 | call to toObject() | webview.swift:81:13:81:20 | call to source() : | webview.swift:84:10:84:26 | call to toObject() | result | +| webview.swift:85:10:85:41 | call to toObjectOf(_:) | webview.swift:81:13:81:20 | call to source() : | webview.swift:85:10:85:41 | call to toObjectOf(_:) | result | +| webview.swift:86:10:86:24 | call to toBool() | webview.swift:81:13:81:20 | call to source() : | webview.swift:86:10:86:24 | call to toBool() | result | +| webview.swift:87:10:87:26 | call to toDouble() | webview.swift:81:13:81:20 | call to source() : | webview.swift:87:10:87:26 | call to toDouble() | result | +| webview.swift:88:10:88:25 | call to toInt32() | webview.swift:81:13:81:20 | call to source() : | webview.swift:88:10:88:25 | call to toInt32() | result | +| webview.swift:89:10:89:26 | call to toUInt32() | webview.swift:81:13:81:20 | call to source() : | webview.swift:89:10:89:26 | call to toUInt32() | result | +| webview.swift:90:10:90:26 | call to toNumber() | webview.swift:81:13:81:20 | call to source() : | webview.swift:90:10:90:26 | call to toNumber() | result | +| webview.swift:91:10:91:26 | call to toString() | webview.swift:81:13:81:20 | call to source() : | webview.swift:91:10:91:26 | call to toString() | result | +| webview.swift:92:10:92:24 | call to toDate() | webview.swift:81:13:81:20 | call to source() : | webview.swift:92:10:92:24 | call to toDate() | result | +| webview.swift:93:10:93:25 | call to toArray() | webview.swift:81:13:81:20 | call to source() : | webview.swift:93:10:93:25 | call to toArray() | result | +| webview.swift:94:10:94:30 | call to toDictionary() | webview.swift:81:13:81:20 | call to source() : | webview.swift:94:10:94:30 | call to toDictionary() | result | +| webview.swift:95:10:95:25 | call to toPoint() | webview.swift:81:13:81:20 | call to source() : | webview.swift:95:10:95:25 | call to toPoint() | result | +| webview.swift:96:10:96:25 | call to toRange() | webview.swift:81:13:81:20 | call to source() : | webview.swift:96:10:96:25 | call to toRange() | result | +| webview.swift:97:10:97:24 | call to toRect() | webview.swift:81:13:81:20 | call to source() : | webview.swift:97:10:97:24 | call to toRect() | result | +| webview.swift:98:10:98:24 | call to toSize() | webview.swift:81:13:81:20 | call to source() : | webview.swift:98:10:98:24 | call to toSize() | result | +| webview.swift:99:10:99:26 | call to atIndex(_:) | webview.swift:81:13:81:20 | call to source() : | webview.swift:99:10:99:26 | call to atIndex(_:) | result | +| webview.swift:100:10:100:31 | call to forProperty(_:) | webview.swift:81:13:81:20 | call to source() : | webview.swift:100:10:100:31 | call to forProperty(_:) | result | +| webview.swift:103:10:103:47 | call to init(object:in:) | webview.swift:81:13:81:20 | call to source() : | webview.swift:103:10:103:47 | call to init(object:in:) | result | +| webview.swift:104:10:104:47 | call to init(bool:in:) | webview.swift:81:13:81:20 | call to source() : | webview.swift:104:10:104:47 | call to init(bool:in:) | result | +| webview.swift:105:10:105:51 | call to init(double:in:) | webview.swift:81:13:81:20 | call to source() : | webview.swift:105:10:105:51 | call to init(double:in:) | result | +| webview.swift:106:10:106:49 | call to init(int32:in:) | webview.swift:81:13:81:20 | call to source() : | webview.swift:106:10:106:49 | call to init(int32:in:) | result | +| webview.swift:107:10:107:51 | call to init(uInt32:in:) | webview.swift:81:13:81:20 | call to source() : | webview.swift:107:10:107:51 | call to init(uInt32:in:) | result | +| webview.swift:108:10:108:51 | call to init(point:in:) | webview.swift:81:13:81:20 | call to source() : | webview.swift:108:10:108:51 | call to init(point:in:) | result | +| webview.swift:109:10:109:51 | call to init(range:in:) | webview.swift:81:13:81:20 | call to source() : | webview.swift:109:10:109:51 | call to init(range:in:) | result | +| webview.swift:110:10:110:49 | call to init(rect:in:) | webview.swift:81:13:81:20 | call to source() : | webview.swift:110:10:110:49 | call to init(rect:in:) | result | +| webview.swift:111:10:111:49 | call to init(size:in:) | webview.swift:81:13:81:20 | call to source() : | webview.swift:111:10:111:49 | call to init(size:in:) | result | +| webview.swift:115:10:115:10 | v1 | webview.swift:81:13:81:20 | call to source() : | webview.swift:115:10:115:10 | v1 | result | +| webview.swift:119:10:119:10 | v2 | webview.swift:81:13:81:20 | call to source() : | webview.swift:119:10:119:10 | v2 | result | +| webview.swift:123:10:123:10 | v3 | webview.swift:81:13:81:20 | call to source() : | webview.swift:123:10:123:10 | v3 | result | diff --git a/swift/ql/test/library-tests/dataflow/taint/webview.swift b/swift/ql/test/library-tests/dataflow/taint/webview.swift index f0a7f77d12f..803415ae2a8 100644 --- a/swift/ql/test/library-tests/dataflow/taint/webview.swift +++ b/swift/ql/test/library-tests/dataflow/taint/webview.swift @@ -1,17 +1,28 @@ // --- stubs --- -class WKScriptMessage { + +class NSObject {} + +class WKScriptMessage : NSObject { open var body: Any { get { return "" } } } + class NSNumber { init(value: Int) {} } + class Date {} + class CGPoint {} + class NSRange {} + class CGRect {} + class CGSize{} + class JSContext {} + class JSValue { init(object: Any, in: JSContext) {} init(bool: Bool, in: JSContext) {} @@ -44,56 +55,86 @@ class JSValue { func setValue(_: Any!, forProperty: Any!) {} } +enum WKUserScriptInjectionTime : Int { + case atDocumentStart = 0 +} + +class WKContentWorld : NSObject {} + +class WKUserScript : NSObject { + init(source: String, injectionTime: WKUserScriptInjectionTime, forMainFrameOnly: Bool) {} + init(source: String, injectionTime: WKUserScriptInjectionTime, forMainFrameOnly: Bool, in contentWorld: WKContentWorld) {} + + var source: String { get { return "" } } +} + // --- tests --- + func source() -> Any { return "" } func sink(_: Any) {} func testInheritBodyTaint() { - sink((source() as! WKScriptMessage).body) // $ tainted=52 + sink((source() as! WKScriptMessage).body) // $ tainted=77 } func testJsValue() { let s = source() - + let source = s as! JSValue - sink(source.toObject() as Any) // $ tainted=56 - sink(source.toObjectOf(NSNumber.self) as Any) // $ tainted=56 - sink(source.toBool()) // $ tainted=56 - sink(source.toDouble()) // $ tainted=56 - sink(source.toInt32()) // $ tainted=56 - sink(source.toUInt32()) // $ tainted=56 - sink(source.toNumber() as Any) // $ tainted=56 - sink(source.toString() as Any) // $ tainted=56 - sink(source.toDate() as Any) // $ tainted=56 - sink(source.toArray() as Any) // $ tainted=56 - sink(source.toDictionary() as Any) // $ tainted=56 - sink(source.toPoint()) // $ tainted=56 - sink(source.toRange()) // $ tainted=56 - sink(source.toRect()) // $ tainted=56 - sink(source.toSize()) // $ tainted=56 - sink(source.atIndex(0) as Any) // $ tainted=56 - sink(source.forProperty("") as Any) // $ tainted=56 + sink(source.toObject() as Any) // $ tainted=81 + sink(source.toObjectOf(NSNumber.self) as Any) // $ tainted=81 + sink(source.toBool()) // $ tainted=81 + sink(source.toDouble()) // $ tainted=81 + sink(source.toInt32()) // $ tainted=81 + sink(source.toUInt32()) // $ tainted=81 + sink(source.toNumber() as Any) // $ tainted=81 + sink(source.toString() as Any) // $ tainted=81 + sink(source.toDate() as Any) // $ tainted=81 + sink(source.toArray() as Any) // $ tainted=81 + sink(source.toDictionary() as Any) // $ tainted=81 + sink(source.toPoint()) // $ tainted=81 + sink(source.toRange()) // $ tainted=81 + sink(source.toRect()) // $ tainted=81 + sink(source.toSize()) // $ tainted=81 + sink(source.atIndex(0) as Any) // $ tainted=81 + sink(source.forProperty("") as Any) // $ tainted=81 let context = JSContext() - sink(JSValue(object: s as Any, in: context)) // $ tainted=56 - sink(JSValue(bool: s as! Bool, in: context)) // $ tainted=56 - sink(JSValue(double: s as! Double, in: context)) // $ tainted=56 - sink(JSValue(int32: s as! Int32, in: context)) // $ tainted=56 - sink(JSValue(uInt32: s as! UInt32, in: context)) // $ tainted=56 - sink(JSValue(point: s as! CGPoint, in: context)) // $ tainted=56 - sink(JSValue(range: s as! NSRange, in: context)) // $ tainted=56 - sink(JSValue(rect: s as! CGRect, in: context)) // $ tainted=56 - sink(JSValue(size: s as! CGSize, in: context)) // $ tainted=56 - + sink(JSValue(object: s as Any, in: context)) // $ tainted=81 + sink(JSValue(bool: s as! Bool, in: context)) // $ tainted=81 + sink(JSValue(double: s as! Double, in: context)) // $ tainted=81 + sink(JSValue(int32: s as! Int32, in: context)) // $ tainted=81 + sink(JSValue(uInt32: s as! UInt32, in: context)) // $ tainted=81 + sink(JSValue(point: s as! CGPoint, in: context)) // $ tainted=81 + sink(JSValue(range: s as! NSRange, in: context)) // $ tainted=81 + sink(JSValue(rect: s as! CGRect, in: context)) // $ tainted=81 + sink(JSValue(size: s as! CGSize, in: context)) // $ tainted=81 + let v1 = JSValue(object: "", in: context) v1.defineProperty("", descriptor: s as Any) - sink(v1) // $ tainted=56 + sink(v1) // $ tainted=81 let v2 = JSValue(object: "", in: context) v2.setValue(s as Any, at: 0) - sink(v2) // $ tainted=56 + sink(v2) // $ tainted=81 let v3 = JSValue(object: "", in: context) v3.setValue(s as Any, forProperty: "") - sink(v3) // $ tainted=56 + sink(v3) // $ tainted=81 +} + +func testWKUserScript() { + let atStart = WKUserScriptInjectionTime.atDocumentStart + let a = WKUserScript(source: "abc", injectionTime: atStart, forMainFrameOnly: false) + sink(a) + sink(a.source) + + let b = WKUserScript(source: source() as! String, injectionTime: atStart, forMainFrameOnly: false) + sink(b) // $ MISSING: tainted=132 + sink(b.source) // $ MISSING: tainted=132 + + let world = WKContentWorld() + let c = WKUserScript(source: source() as! String, injectionTime: atStart, forMainFrameOnly: false, in: world) + sink(c) // $ MISSING: tainted=137 + sink(c.source) // $ MISSING: tainted=137 } From 1e63893411544df87370f5544da0720a743cf5e9 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 28 Nov 2022 13:12:24 +0100 Subject: [PATCH 584/796] C#: Add integration test that checks whether env vars are passed through autobuilder --- .../posix-only/inherit-env-vars/Program.cs | 1 + .../posix-only/inherit-env-vars/build.sh | 2 ++ .../posix-only/inherit-env-vars/proj.csproj.no_auto | 10 ++++++++++ .../posix-only/inherit-env-vars/test.py | 6 ++++++ 4 files changed, 19 insertions(+) create mode 100644 csharp/ql/integration-tests/posix-only/inherit-env-vars/Program.cs create mode 100644 csharp/ql/integration-tests/posix-only/inherit-env-vars/build.sh create mode 100644 csharp/ql/integration-tests/posix-only/inherit-env-vars/proj.csproj.no_auto create mode 100644 csharp/ql/integration-tests/posix-only/inherit-env-vars/test.py diff --git a/csharp/ql/integration-tests/posix-only/inherit-env-vars/Program.cs b/csharp/ql/integration-tests/posix-only/inherit-env-vars/Program.cs new file mode 100644 index 00000000000..e9708d0b5d2 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/inherit-env-vars/Program.cs @@ -0,0 +1 @@ +Console.WriteLine(args[0]); diff --git a/csharp/ql/integration-tests/posix-only/inherit-env-vars/build.sh b/csharp/ql/integration-tests/posix-only/inherit-env-vars/build.sh new file mode 100644 index 00000000000..e0f0c8dccd3 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/inherit-env-vars/build.sh @@ -0,0 +1,2 @@ +cp $PROJECT_TO_BUILD temp.csproj +dotnet build temp.csproj diff --git a/csharp/ql/integration-tests/posix-only/inherit-env-vars/proj.csproj.no_auto b/csharp/ql/integration-tests/posix-only/inherit-env-vars/proj.csproj.no_auto new file mode 100644 index 00000000000..74abf5c9766 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/inherit-env-vars/proj.csproj.no_auto @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/csharp/ql/integration-tests/posix-only/inherit-env-vars/test.py b/csharp/ql/integration-tests/posix-only/inherit-env-vars/test.py new file mode 100644 index 00000000000..1b49fb18519 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/inherit-env-vars/test.py @@ -0,0 +1,6 @@ +from create_database_utils import * +import os + +os.environ["PROJECT_TO_BUILD"] = "proj.csproj.no_auto" + +run_codeql_database_create([], test_db="default-db", db=None, lang="csharp") From 7863bc2c99a7419b95d1d6ebc2388c3b396db6c3 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 28 Nov 2022 12:14:36 +0000 Subject: [PATCH 585/796] Kotlin: Accept test output --- .../reflection/reflection.expected | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/java/ql/test/kotlin/library-tests/reflection/reflection.expected b/java/ql/test/kotlin/library-tests/reflection/reflection.expected index e6a864b11a4..4fe78050665 100644 --- a/java/ql/test/kotlin/library-tests/reflection/reflection.expected +++ b/java/ql/test/kotlin/library-tests/reflection/reflection.expected @@ -282,23 +282,58 @@ compGenerated | file:///LongRange.class:0:0:0:0 | forEach | Forwarder for a Kotlin class inheriting an interface default method | | file:///LongRange.class:0:0:0:0 | spliterator | Forwarder for a Kotlin class inheriting an interface default method | | file:///String.class:0:0:0:0 | isEmpty | Forwarder for a Kotlin class inheriting an interface default method | +| reflection.kt:7:49:7:54 | new Function2(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:10:38:10:42 | new KProperty1(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:14:38:14:44 | new Function1(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:15:35:15:41 | new KProperty0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:17:45:17:49 | new KMutableProperty1(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:21:44:21:50 | new Function2(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:22:42:22:48 | new KMutableProperty0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:24:46:24:64 | new Function1,Boolean>(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:33:9:33:23 | getP0 | Default property accessor | | reflection.kt:34:9:34:23 | getP1 | Default property accessor | | reflection.kt:34:9:34:23 | setP1 | Default property accessor | +| reflection.kt:50:13:50:28 | new KProperty1(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:51:13:51:28 | new KProperty0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:60:17:60:32 | new Function2,Integer,String>(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:61:17:61:34 | new Function1(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:62:17:62:34 | new Function1,String>(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:63:17:63:36 | new Function0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:64:17:64:34 | new Function1,String>(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:65:17:65:36 | new Function0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:67:17:67:32 | new KMutableProperty1,Integer>(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:68:17:68:34 | new KMutableProperty0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:70:17:70:30 | new KProperty0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:71:17:71:34 | new KProperty0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:72:17:72:35 | new KMutableProperty0(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:83:17:83:28 | getValue | Default property accessor | +| reflection.kt:90:18:90:24 | new Function1>(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:97:14:97:21 | new Function1>(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:98:14:98:17 | new Function1(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:99:14:99:29 | new Function1>(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:105:18:105:31 | getProp1 | Default property accessor | | reflection.kt:105:18:105:31 | setProp1 | Default property accessor | +| reflection.kt:109:17:109:27 | new KMutableProperty0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:115:9:115:27 | | The class around a local function, a lambda, or a function reference | +| reflection.kt:116:40:116:44 | new Function1(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:126:9:126:13 | | Declaring classes of adapter functions in Kotlin | +| reflection.kt:126:9:126:13 | new Function0(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:131:1:131:50 | takesOptionalParam$default | Forwarder for Kotlin calls that need default arguments filling in | | reflection.kt:134:21:134:40 | | Declaring classes of adapter functions in Kotlin | +| reflection.kt:134:21:134:40 | new Function1(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:140:5:140:54 | takesOptionalParam$default | Forwarder for Kotlin calls that need default arguments filling in | | reflection.kt:144:21:144:41 | | Declaring classes of adapter functions in Kotlin | +| reflection.kt:144:21:144:41 | new Function1(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:145:32:145:70 | | Declaring classes of adapter functions in Kotlin | +| reflection.kt:145:32:145:70 | new Function2(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:150:1:150:60 | extTakesOptionalParam$default | Forwarder for Kotlin calls that need default arguments filling in | | reflection.kt:153:21:153:44 | | Declaring classes of adapter functions in Kotlin | +| reflection.kt:153:21:153:44 | new Function1(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:154:33:154:61 | | Declaring classes of adapter functions in Kotlin | +| reflection.kt:154:33:154:61 | new Function2(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:157:1:157:49 | ConstructorOptional | Forwarder for Kotlin calls that need default arguments filling in | | reflection.kt:162:25:162:45 | | Declaring classes of adapter functions in Kotlin | +| reflection.kt:162:25:162:45 | new Function1(...) { ... } | The class around a local function, a lambda, or a function reference | propertyReferenceOverrides | reflection.kt:10:38:10:42 | ...::... | reflection.kt:10:38:10:42 | get | kotlin.reflect.KProperty1.get(Reflection.C) | | reflection.kt:10:38:10:42 | ...::... | reflection.kt:10:38:10:42 | invoke | kotlin.jvm.functions.Function1.invoke(Reflection.C) | From a32363de79b4c60b4a52706a0f9fc1b959995a82 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 28 Nov 2022 12:14:50 +0000 Subject: [PATCH 586/796] Kotlin: Avoid giving a single class 2 compiler-generated kinds --- .../src/main/kotlin/KotlinFileExtractor.kt | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 3d9b4ad37ce..bca94f95114 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -1507,14 +1507,15 @@ open class KotlinFileExtractor( } is IrFunction -> { if (s.isLocalFunction()) { - val classId = extractGeneratedClass(s, listOf(pluginContext.irBuiltIns.anyType)) + val compilerGeneratedKind = if (s.origin == IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE) { + CompilerGeneratedKinds.DECLARING_CLASSES_OF_ADAPTER_FUNCTIONS + } else { + null + } + val classId = extractGeneratedClass(s, listOf(pluginContext.irBuiltIns.anyType), compilerGeneratedKind = compilerGeneratedKind) extractLocalTypeDeclStmt(classId, s, callable, parent, idx) val ids = getLocallyVisibleFunctionLabels(s) tw.writeKtLocalFunction(ids.function) - - if (s.origin == IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE) { - tw.writeCompiler_generated(classId, CompilerGeneratedKinds.DECLARING_CLASSES_OF_ADAPTER_FUNCTIONS.kind) - } } else { logger.errorElement("Expected to find local function", s) } @@ -4685,7 +4686,7 @@ open class KotlinFileExtractor( val baseClass = pluginContext.referenceClass(FqName("kotlin.jvm.internal.FunctionReference"))?.owner?.typeWith() ?: pluginContext.irBuiltIns.anyType - val classId = extractGeneratedClass(ids, listOf(baseClass, fnInterfaceType), locId, functionReferenceExpr, declarationParent, { it.valueParameters.size == 1 }) { + val classId = extractGeneratedClass(ids, listOf(baseClass, fnInterfaceType), locId, functionReferenceExpr, declarationParent, null, { it.valueParameters.size == 1 }) { // The argument to FunctionReference's constructor is the function arity. extractConstantInteger(type.arguments.size - 1, locId, it, 0, ids.constructor, it) } @@ -5389,14 +5390,15 @@ open class KotlinFileExtractor( locId: Label, elementToReportOn: IrElement, declarationParent: IrDeclarationParent, + compilerGeneratedKind: CompilerGeneratedKinds? = null, superConstructorSelector: (IrFunction) -> Boolean = { it.valueParameters.isEmpty() }, - extractSuperconstructorArgs: (Label) -> Unit = {} + extractSuperconstructorArgs: (Label) -> Unit = {}, ): Label { // Write class val id = ids.type.javaResult.id.cast() val pkgId = extractPackage("") tw.writeClasses(id, "", pkgId, id) - tw.writeCompiler_generated(id, CompilerGeneratedKinds.CALLABLE_CLASS.kind) + tw.writeCompiler_generated(id, (compilerGeneratedKind ?: CompilerGeneratedKinds.CALLABLE_CLASS).kind) tw.writeHasLocation(id, locId) // Extract constructor @@ -5443,11 +5445,15 @@ open class KotlinFileExtractor( /** * Extracts the class around a local function or a lambda. The superclass must have a no-arg constructor. */ - private fun extractGeneratedClass(localFunction: IrFunction, superTypes: List) : Label { + private fun extractGeneratedClass( + localFunction: IrFunction, + superTypes: List, + compilerGeneratedKind: CompilerGeneratedKinds? = null + ) : Label { with("generated class", localFunction) { val ids = getLocallyVisibleFunctionLabels(localFunction) - val id = extractGeneratedClass(ids, superTypes, tw.getLocation(localFunction), localFunction, localFunction.parent) + val id = extractGeneratedClass(ids, superTypes, tw.getLocation(localFunction), localFunction, localFunction.parent, compilerGeneratedKind = compilerGeneratedKind) // Extract local function as a member extractFunction(localFunction, id, extractBody = true, extractMethodAndParameterTypeAccesses = true, null, listOf()) From 116d9667e714edee3f766401f10eb764ab4af28d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 28 Nov 2022 12:15:38 +0000 Subject: [PATCH 587/796] Swift: Remove special case from query. --- .../queries/Security/CWE-094/UnsafeJsEval.ql | 11 ----------- .../Security/CWE-094/UnsafeJsEval.expected | 18 ------------------ 2 files changed, 29 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql index e5764416d27..f7c2a3569b7 100644 --- a/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql +++ b/swift/ql/src/queries/Security/CWE-094/UnsafeJsEval.ql @@ -97,17 +97,6 @@ class UnsafeJsEvalConfig extends TaintTracking::Configuration { // TODO: convert to new taint flow models override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { exists(Argument arg | - arg = - any(CallExpr ce | - ce.getStaticTarget() - .(MethodDecl) - .hasQualifiedName("WKUserScript", - [ - "init(source:injectionTime:forMainFrameOnly:)", - "init(source:injectionTime:forMainFrameOnly:in:)" - ]) - ).getArgument(0) - or arg = any(CallExpr ce | ce.getStaticTarget().(MethodDecl).hasQualifiedName("String", "init(decoding:as:)") diff --git a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected index e6b4fb45005..9736090e8e3 100644 --- a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected +++ b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected @@ -6,21 +6,15 @@ edges | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | UnsafeJsEval.swift:205:7:205:7 | remoteString : | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | UnsafeJsEval.swift:211:24:211:37 | .utf8 : | -| UnsafeJsEval.swift:204:7:204:66 | try! ... : | UnsafeJsEval.swift:265:13:265:13 | string : | -| UnsafeJsEval.swift:204:7:204:66 | try! ... : | UnsafeJsEval.swift:268:13:268:13 | string : | | UnsafeJsEval.swift:204:7:204:66 | try! ... : | UnsafeJsEval.swift:276:13:276:13 | string : | | UnsafeJsEval.swift:204:7:204:66 | try! ... : | UnsafeJsEval.swift:279:13:279:13 | string : | | UnsafeJsEval.swift:204:7:204:66 | try! ... : | UnsafeJsEval.swift:285:13:285:13 | string : | | UnsafeJsEval.swift:204:7:204:66 | try! ... : | UnsafeJsEval.swift:299:13:299:13 | string : | | UnsafeJsEval.swift:204:12:204:66 | call to init(contentsOf:) : | UnsafeJsEval.swift:204:7:204:66 | try! ... : | -| UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:265:13:265:13 | string : | -| UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:268:13:268:13 | string : | | UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:276:13:276:13 | string : | | UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:279:13:279:13 | string : | | UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:285:13:285:13 | string : | | UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:299:13:299:13 | string : | -| UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:265:13:265:13 | string : | -| UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:268:13:268:13 | string : | | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:276:13:276:13 | string : | | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:279:13:279:13 | string : | | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:285:13:285:13 | string : | @@ -28,14 +22,10 @@ edges | UnsafeJsEval.swift:211:19:211:41 | call to init(_:) : | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | | UnsafeJsEval.swift:211:24:211:37 | .utf8 : | UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in init(_:) : | | UnsafeJsEval.swift:211:24:211:37 | .utf8 : | UnsafeJsEval.swift:211:19:211:41 | call to init(_:) : | -| UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:265:13:265:13 | string : | -| UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:268:13:268:13 | string : | | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:276:13:276:13 | string : | | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:279:13:279:13 | string : | | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:285:13:285:13 | string : | | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:299:13:299:13 | string : | -| UnsafeJsEval.swift:265:13:265:13 | string : | UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | -| UnsafeJsEval.swift:268:13:268:13 | string : | UnsafeJsEval.swift:269:22:269:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | | UnsafeJsEval.swift:276:13:276:13 | string : | UnsafeJsEval.swift:277:26:277:26 | string | | UnsafeJsEval.swift:279:13:279:13 | string : | UnsafeJsEval.swift:280:26:280:26 | string | | UnsafeJsEval.swift:285:13:285:13 | string : | UnsafeJsEval.swift:286:3:286:10 | .utf16 : | @@ -68,10 +58,6 @@ nodes | UnsafeJsEval.swift:211:19:211:41 | call to init(_:) : | semmle.label | call to init(_:) : | | UnsafeJsEval.swift:211:24:211:37 | .utf8 : | semmle.label | .utf8 : | | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | semmle.label | call to init(decoding:as:) : | -| UnsafeJsEval.swift:265:13:265:13 | string : | semmle.label | string : | -| UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | semmle.label | call to init(source:injectionTime:forMainFrameOnly:) | -| UnsafeJsEval.swift:268:13:268:13 | string : | semmle.label | string : | -| UnsafeJsEval.swift:269:22:269:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | semmle.label | call to init(source:injectionTime:forMainFrameOnly:in:) | | UnsafeJsEval.swift:276:13:276:13 | string : | semmle.label | string : | | UnsafeJsEval.swift:277:26:277:26 | string | semmle.label | string | | UnsafeJsEval.swift:279:13:279:13 | string : | semmle.label | string : | @@ -94,10 +80,6 @@ subpaths | UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) : | UnsafeJsEval.swift:124:21:124:42 | string : | UnsafeJsEval.swift:124:70:124:70 | string : | UnsafeJsEval.swift:287:16:287:98 | call to JSStringRetain(_:) : | | UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) : | UnsafeJsEval.swift:124:21:124:42 | string : | UnsafeJsEval.swift:124:70:124:70 | string : | UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) : | #select -| UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | Evaluation of uncontrolled JavaScript from a remote source. | -| UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:204:12:204:66 | call to init(contentsOf:) : | UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | Evaluation of uncontrolled JavaScript from a remote source. | -| UnsafeJsEval.swift:269:22:269:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:269:22:269:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | Evaluation of uncontrolled JavaScript from a remote source. | -| UnsafeJsEval.swift:269:22:269:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | UnsafeJsEval.swift:204:12:204:66 | call to init(contentsOf:) : | UnsafeJsEval.swift:269:22:269:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | Evaluation of uncontrolled JavaScript from a remote source. | | UnsafeJsEval.swift:277:26:277:26 | string | UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:277:26:277:26 | string | Evaluation of uncontrolled JavaScript from a remote source. | | UnsafeJsEval.swift:277:26:277:26 | string | UnsafeJsEval.swift:204:12:204:66 | call to init(contentsOf:) : | UnsafeJsEval.swift:277:26:277:26 | string | Evaluation of uncontrolled JavaScript from a remote source. | | UnsafeJsEval.swift:280:26:280:26 | string | UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:280:26:280:26 | string | Evaluation of uncontrolled JavaScript from a remote source. | From ffbd20145004c334c9c0b81dcf0ea63c0bc3204b Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 28 Nov 2022 12:07:21 +0000 Subject: [PATCH 588/796] Swift: Implement basic model of WKUserScript. --- .../frameworks/StandardLibrary/WebView.qll | 13 ++++++++ .../dataflow/taint/Taint.expected | 22 +++++++++++++ .../dataflow/taint/webview.swift | 4 +-- .../Security/CWE-094/UnsafeJsEval.expected | 32 +++++++++++++++++++ 4 files changed, 69 insertions(+), 2 deletions(-) diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/WebView.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/WebView.qll index 84a965cba31..a7179ad3d19 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/WebView.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/WebView.qll @@ -131,3 +131,16 @@ private class JsExportedSource extends RemoteFlowSource { override string getSourceType() { result = "Member of a type exposed through JSExport" } } + +/** + * A model for `WKUserScript` summaries. + */ +private class WKUserScriptSummaries extends SummaryModelCsv { + override predicate row(string row) { + row = + [ + ";WKUserScript;true;init(source:injectionTime:forMainFrameOnly:);;;Argument[0];ReturnValue;taint", + ";WKUserScript;true;init(source:injectionTime:forMainFrameOnly:in:);;;Argument[0];ReturnValue;taint" + ] + } +} diff --git a/swift/ql/test/library-tests/dataflow/taint/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/Taint.expected index 1eb4db5261b..fc06d87ca7a 100644 --- a/swift/ql/test/library-tests/dataflow/taint/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/Taint.expected @@ -439,6 +439,8 @@ edges | webview.swift:53:5:53:89 | [summary param] this in forProperty(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in forProperty(_:) : | | webview.swift:54:5:54:38 | [summary param] 0 in setValue(_:at:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:at:) : | | webview.swift:55:5:55:48 | [summary param] 0 in setValue(_:forProperty:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:forProperty:) : | +| webview.swift:65:5:65:93 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:) : | +| webview.swift:66:5:66:126 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:in:) : | | webview.swift:77:11:77:18 | call to source() : | webview.swift:77:10:77:41 | .body | | webview.swift:81:13:81:20 | call to source() : | webview.swift:84:10:84:10 | source : | | webview.swift:81:13:81:20 | call to source() : | webview.swift:85:10:85:10 | source : | @@ -530,6 +532,12 @@ edges | webview.swift:122:5:122:5 | [post] v3 : | webview.swift:123:10:123:10 | v3 | | webview.swift:122:17:122:17 | s : | webview.swift:55:5:55:48 | [summary param] 0 in setValue(_:forProperty:) : | | webview.swift:122:17:122:17 | s : | webview.swift:122:5:122:5 | [post] v3 : | +| webview.swift:132:13:132:102 | call to init(source:injectionTime:forMainFrameOnly:) : | webview.swift:133:10:133:10 | b | +| webview.swift:132:34:132:41 | call to source() : | webview.swift:65:5:65:93 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:) : | +| webview.swift:132:34:132:41 | call to source() : | webview.swift:132:13:132:102 | call to init(source:injectionTime:forMainFrameOnly:) : | +| webview.swift:137:13:137:113 | call to init(source:injectionTime:forMainFrameOnly:in:) : | webview.swift:138:10:138:10 | c | +| webview.swift:137:34:137:41 | call to source() : | webview.swift:66:5:66:126 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:in:) : | +| webview.swift:137:34:137:41 | call to source() : | webview.swift:137:13:137:113 | call to init(source:injectionTime:forMainFrameOnly:in:) : | nodes | data.swift:25:2:25:66 | [summary param] 0 in init(base64Encoded:options:) : | semmle.label | [summary param] 0 in init(base64Encoded:options:) : | | data.swift:26:2:26:61 | [summary param] 0 in init(buffer:) : | semmle.label | [summary param] 0 in init(buffer:) : | @@ -752,6 +760,8 @@ nodes | file://:0:0:0:0 | [summary] to write: return (return) in init(rect:in:) : | semmle.label | [summary] to write: return (return) in init(rect:in:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(referencing:) : | semmle.label | [summary] to write: return (return) in init(referencing:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(size:in:) : | semmle.label | [summary] to write: return (return) in init(size:in:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:) : | semmle.label | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:in:) : | semmle.label | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:in:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | semmle.label | [summary] to write: return (return) in init(string:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | semmle.label | [summary] to write: return (return) in init(string:relativeTo:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | semmle.label | [summary] to write: return (return) in init(string:relativeTo:) : | @@ -1052,6 +1062,8 @@ nodes | webview.swift:53:5:53:89 | [summary param] this in forProperty(_:) : | semmle.label | [summary param] this in forProperty(_:) : | | webview.swift:54:5:54:38 | [summary param] 0 in setValue(_:at:) : | semmle.label | [summary param] 0 in setValue(_:at:) : | | webview.swift:55:5:55:48 | [summary param] 0 in setValue(_:forProperty:) : | semmle.label | [summary param] 0 in setValue(_:forProperty:) : | +| webview.swift:65:5:65:93 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:) : | semmle.label | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:) : | +| webview.swift:66:5:66:126 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:in:) : | semmle.label | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:in:) : | | webview.swift:77:10:77:41 | .body | semmle.label | .body | | webview.swift:77:11:77:18 | call to source() : | semmle.label | call to source() : | | webview.swift:81:13:81:20 | call to source() : | semmle.label | call to source() : | @@ -1116,6 +1128,12 @@ nodes | webview.swift:122:5:122:5 | [post] v3 : | semmle.label | [post] v3 : | | webview.swift:122:17:122:17 | s : | semmle.label | s : | | webview.swift:123:10:123:10 | v3 | semmle.label | v3 | +| webview.swift:132:13:132:102 | call to init(source:injectionTime:forMainFrameOnly:) : | semmle.label | call to init(source:injectionTime:forMainFrameOnly:) : | +| webview.swift:132:34:132:41 | call to source() : | semmle.label | call to source() : | +| webview.swift:133:10:133:10 | b | semmle.label | b | +| webview.swift:137:13:137:113 | call to init(source:injectionTime:forMainFrameOnly:in:) : | semmle.label | call to init(source:injectionTime:forMainFrameOnly:in:) : | +| webview.swift:137:34:137:41 | call to source() : | semmle.label | call to source() : | +| webview.swift:138:10:138:10 | c | semmle.label | c | subpaths | data.swift:89:41:89:48 | call to source() : | data.swift:25:2:25:66 | [summary param] 0 in init(base64Encoded:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | data.swift:89:21:89:71 | call to init(base64Encoded:options:) : | | data.swift:93:34:93:41 | call to source() : | data.swift:26:2:26:61 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | data.swift:93:21:93:73 | call to init(buffer:) : | @@ -1235,6 +1253,8 @@ subpaths | webview.swift:114:39:114:39 | s : | webview.swift:52:5:52:53 | [summary param] 1 in defineProperty(_:descriptor:) : | file://:0:0:0:0 | [summary] to write: argument this in defineProperty(_:descriptor:) : | webview.swift:114:5:114:5 | [post] v1 : | | webview.swift:118:17:118:17 | s : | webview.swift:54:5:54:38 | [summary param] 0 in setValue(_:at:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:at:) : | webview.swift:118:5:118:5 | [post] v2 : | | webview.swift:122:17:122:17 | s : | webview.swift:55:5:55:48 | [summary param] 0 in setValue(_:forProperty:) : | file://:0:0:0:0 | [summary] to write: argument this in setValue(_:forProperty:) : | webview.swift:122:5:122:5 | [post] v3 : | +| webview.swift:132:34:132:41 | call to source() : | webview.swift:65:5:65:93 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:) : | webview.swift:132:13:132:102 | call to init(source:injectionTime:forMainFrameOnly:) : | +| webview.swift:137:34:137:41 | call to source() : | webview.swift:66:5:66:126 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:in:) : | webview.swift:137:13:137:113 | call to init(source:injectionTime:forMainFrameOnly:in:) : | #select | data.swift:90:12:90:12 | dataTainted3 | data.swift:89:41:89:48 | call to source() : | data.swift:90:12:90:12 | dataTainted3 | result | | data.swift:94:12:94:12 | dataTainted4 | data.swift:93:34:93:41 | call to source() : | data.swift:94:12:94:12 | dataTainted4 | result | @@ -1389,3 +1409,5 @@ subpaths | webview.swift:115:10:115:10 | v1 | webview.swift:81:13:81:20 | call to source() : | webview.swift:115:10:115:10 | v1 | result | | webview.swift:119:10:119:10 | v2 | webview.swift:81:13:81:20 | call to source() : | webview.swift:119:10:119:10 | v2 | result | | webview.swift:123:10:123:10 | v3 | webview.swift:81:13:81:20 | call to source() : | webview.swift:123:10:123:10 | v3 | result | +| webview.swift:133:10:133:10 | b | webview.swift:132:34:132:41 | call to source() : | webview.swift:133:10:133:10 | b | result | +| webview.swift:138:10:138:10 | c | webview.swift:137:34:137:41 | call to source() : | webview.swift:138:10:138:10 | c | result | diff --git a/swift/ql/test/library-tests/dataflow/taint/webview.swift b/swift/ql/test/library-tests/dataflow/taint/webview.swift index 803415ae2a8..473f0d6f917 100644 --- a/swift/ql/test/library-tests/dataflow/taint/webview.swift +++ b/swift/ql/test/library-tests/dataflow/taint/webview.swift @@ -130,11 +130,11 @@ func testWKUserScript() { sink(a.source) let b = WKUserScript(source: source() as! String, injectionTime: atStart, forMainFrameOnly: false) - sink(b) // $ MISSING: tainted=132 + sink(b) // $ tainted=132 sink(b.source) // $ MISSING: tainted=132 let world = WKContentWorld() let c = WKUserScript(source: source() as! String, injectionTime: atStart, forMainFrameOnly: false, in: world) - sink(c) // $ MISSING: tainted=137 + sink(c) // $ tainted=137 sink(c.source) // $ MISSING: tainted=137 } diff --git a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected index 9736090e8e3..0030af81b05 100644 --- a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected +++ b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected @@ -1,4 +1,6 @@ edges +| UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:) : | +| UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:in:) : | | UnsafeJsEval.swift:124:21:124:42 | string : | UnsafeJsEval.swift:124:70:124:70 | string : | | UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | | UnsafeJsEval.swift:165:10:165:37 | try ... : | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | @@ -6,15 +8,21 @@ edges | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | UnsafeJsEval.swift:205:7:205:7 | remoteString : | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() : | UnsafeJsEval.swift:211:24:211:37 | .utf8 : | +| UnsafeJsEval.swift:204:7:204:66 | try! ... : | UnsafeJsEval.swift:265:13:265:13 | string : | +| UnsafeJsEval.swift:204:7:204:66 | try! ... : | UnsafeJsEval.swift:268:13:268:13 | string : | | UnsafeJsEval.swift:204:7:204:66 | try! ... : | UnsafeJsEval.swift:276:13:276:13 | string : | | UnsafeJsEval.swift:204:7:204:66 | try! ... : | UnsafeJsEval.swift:279:13:279:13 | string : | | UnsafeJsEval.swift:204:7:204:66 | try! ... : | UnsafeJsEval.swift:285:13:285:13 | string : | | UnsafeJsEval.swift:204:7:204:66 | try! ... : | UnsafeJsEval.swift:299:13:299:13 | string : | | UnsafeJsEval.swift:204:12:204:66 | call to init(contentsOf:) : | UnsafeJsEval.swift:204:7:204:66 | try! ... : | +| UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:265:13:265:13 | string : | +| UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:268:13:268:13 | string : | | UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:276:13:276:13 | string : | | UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:279:13:279:13 | string : | | UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:285:13:285:13 | string : | | UnsafeJsEval.swift:205:7:205:7 | remoteString : | UnsafeJsEval.swift:299:13:299:13 | string : | +| UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:265:13:265:13 | string : | +| UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:268:13:268:13 | string : | | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:276:13:276:13 | string : | | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:279:13:279:13 | string : | | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... : | UnsafeJsEval.swift:285:13:285:13 | string : | @@ -22,10 +30,18 @@ edges | UnsafeJsEval.swift:211:19:211:41 | call to init(_:) : | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | | UnsafeJsEval.swift:211:24:211:37 | .utf8 : | UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in init(_:) : | | UnsafeJsEval.swift:211:24:211:37 | .utf8 : | UnsafeJsEval.swift:211:19:211:41 | call to init(_:) : | +| UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:265:13:265:13 | string : | +| UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:268:13:268:13 | string : | | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:276:13:276:13 | string : | | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:279:13:279:13 | string : | | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:285:13:285:13 | string : | | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | UnsafeJsEval.swift:299:13:299:13 | string : | +| UnsafeJsEval.swift:265:13:265:13 | string : | UnsafeJsEval.swift:266:43:266:43 | string : | +| UnsafeJsEval.swift:266:43:266:43 | string : | UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:) : | +| UnsafeJsEval.swift:266:43:266:43 | string : | UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | +| UnsafeJsEval.swift:268:13:268:13 | string : | UnsafeJsEval.swift:269:43:269:43 | string : | +| UnsafeJsEval.swift:269:43:269:43 | string : | UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:in:) : | +| UnsafeJsEval.swift:269:43:269:43 | string : | UnsafeJsEval.swift:269:22:269:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | | UnsafeJsEval.swift:276:13:276:13 | string : | UnsafeJsEval.swift:277:26:277:26 | string | | UnsafeJsEval.swift:279:13:279:13 | string : | UnsafeJsEval.swift:280:26:280:26 | string | | UnsafeJsEval.swift:285:13:285:13 | string : | UnsafeJsEval.swift:286:3:286:10 | .utf16 : | @@ -45,6 +61,8 @@ edges | UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) : | UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) : | | UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) : | UnsafeJsEval.swift:305:17:305:17 | jsstr | nodes +| UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:) : | semmle.label | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:) : | +| UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:in:) : | semmle.label | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:in:) : | | UnsafeJsEval.swift:124:21:124:42 | string : | semmle.label | string : | | UnsafeJsEval.swift:124:70:124:70 | string : | semmle.label | string : | | UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in init(_:) : | semmle.label | [summary param] 0 in init(_:) : | @@ -58,6 +76,12 @@ nodes | UnsafeJsEval.swift:211:19:211:41 | call to init(_:) : | semmle.label | call to init(_:) : | | UnsafeJsEval.swift:211:24:211:37 | .utf8 : | semmle.label | .utf8 : | | UnsafeJsEval.swift:214:7:214:49 | call to init(decoding:as:) : | semmle.label | call to init(decoding:as:) : | +| UnsafeJsEval.swift:265:13:265:13 | string : | semmle.label | string : | +| UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | semmle.label | call to init(source:injectionTime:forMainFrameOnly:) | +| UnsafeJsEval.swift:266:43:266:43 | string : | semmle.label | string : | +| UnsafeJsEval.swift:268:13:268:13 | string : | semmle.label | string : | +| UnsafeJsEval.swift:269:22:269:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | semmle.label | call to init(source:injectionTime:forMainFrameOnly:in:) | +| UnsafeJsEval.swift:269:43:269:43 | string : | semmle.label | string : | | UnsafeJsEval.swift:276:13:276:13 | string : | semmle.label | string : | | UnsafeJsEval.swift:277:26:277:26 | string | semmle.label | string | | UnsafeJsEval.swift:279:13:279:13 | string : | semmle.label | string : | @@ -75,11 +99,19 @@ nodes | UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) : | semmle.label | call to JSStringCreateWithUTF8CString(_:) : | | UnsafeJsEval.swift:305:17:305:17 | jsstr | semmle.label | jsstr | | file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | semmle.label | [summary] to write: return (return) in init(_:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:) : | semmle.label | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:in:) : | semmle.label | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:in:) : | subpaths | UnsafeJsEval.swift:211:24:211:37 | .utf8 : | UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | UnsafeJsEval.swift:211:19:211:41 | call to init(_:) : | +| UnsafeJsEval.swift:266:43:266:43 | string : | UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:) : | UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | +| UnsafeJsEval.swift:269:43:269:43 | string : | UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:in:) : | UnsafeJsEval.swift:269:22:269:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | | UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) : | UnsafeJsEval.swift:124:21:124:42 | string : | UnsafeJsEval.swift:124:70:124:70 | string : | UnsafeJsEval.swift:287:16:287:98 | call to JSStringRetain(_:) : | | UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) : | UnsafeJsEval.swift:124:21:124:42 | string : | UnsafeJsEval.swift:124:70:124:70 | string : | UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) : | #select +| UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | Evaluation of uncontrolled JavaScript from a remote source. | +| UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:204:12:204:66 | call to init(contentsOf:) : | UnsafeJsEval.swift:266:22:266:107 | call to init(source:injectionTime:forMainFrameOnly:) | Evaluation of uncontrolled JavaScript from a remote source. | +| UnsafeJsEval.swift:269:22:269:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:269:22:269:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | Evaluation of uncontrolled JavaScript from a remote source. | +| UnsafeJsEval.swift:269:22:269:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | UnsafeJsEval.swift:204:12:204:66 | call to init(contentsOf:) : | UnsafeJsEval.swift:269:22:269:124 | call to init(source:injectionTime:forMainFrameOnly:in:) | Evaluation of uncontrolled JavaScript from a remote source. | | UnsafeJsEval.swift:277:26:277:26 | string | UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:277:26:277:26 | string | Evaluation of uncontrolled JavaScript from a remote source. | | UnsafeJsEval.swift:277:26:277:26 | string | UnsafeJsEval.swift:204:12:204:66 | call to init(contentsOf:) : | UnsafeJsEval.swift:277:26:277:26 | string | Evaluation of uncontrolled JavaScript from a remote source. | | UnsafeJsEval.swift:280:26:280:26 | string | UnsafeJsEval.swift:165:14:165:37 | call to init(contentsOf:) : | UnsafeJsEval.swift:280:26:280:26 | string | Evaluation of uncontrolled JavaScript from a remote source. | From 30468dd419f3bf01d5988aa633dcc486a0adcd99 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 28 Nov 2022 12:27:33 +0000 Subject: [PATCH 589/796] Swift: Implement field content as well. --- .../swift/frameworks/StandardLibrary/WebView.qll | 13 +++++++++++++ .../dataflow/taint/LocalTaint.expected | 3 +++ .../library-tests/dataflow/taint/Taint.expected | 6 ++++++ .../test/library-tests/dataflow/taint/webview.swift | 4 ++-- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/WebView.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/WebView.qll index a7179ad3d19..b16c6aba370 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/WebView.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/WebView.qll @@ -144,3 +144,16 @@ private class WKUserScriptSummaries extends SummaryModelCsv { ] } } + +/** + * A content implying that, if a `WKUserScript` is tainted, its `source` field is tainted. + */ +private class WKUserScriptInheritsTaint extends TaintInheritingContent, + DataFlow::Content::FieldContent { + WKUserScriptInheritsTaint() { + exists(FieldDecl f | this.getField() = f | + f.getEnclosingDecl().(ClassOrStructDecl).getName() = "WKUserScript" and + f.getName() = "source" + ) + } +} diff --git a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected index 297f5f4382d..3e594f2d7a8 100644 --- a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected @@ -166,3 +166,6 @@ | url.swift:101:15:101:57 | ...! | url.swift:101:15:101:59 | .user | | url.swift:102:15:102:57 | ...! | url.swift:102:15:102:59 | .password | | webview.swift:77:11:77:18 | call to source() | webview.swift:77:10:77:41 | .body | +| webview.swift:130:10:130:10 | a | webview.swift:130:10:130:12 | .source | +| webview.swift:134:10:134:10 | b | webview.swift:134:10:134:12 | .source | +| webview.swift:139:10:139:10 | c | webview.swift:139:10:139:12 | .source | diff --git a/swift/ql/test/library-tests/dataflow/taint/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/Taint.expected index fc06d87ca7a..b72d5905fd7 100644 --- a/swift/ql/test/library-tests/dataflow/taint/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/Taint.expected @@ -533,9 +533,11 @@ edges | webview.swift:122:17:122:17 | s : | webview.swift:55:5:55:48 | [summary param] 0 in setValue(_:forProperty:) : | | webview.swift:122:17:122:17 | s : | webview.swift:122:5:122:5 | [post] v3 : | | webview.swift:132:13:132:102 | call to init(source:injectionTime:forMainFrameOnly:) : | webview.swift:133:10:133:10 | b | +| webview.swift:132:13:132:102 | call to init(source:injectionTime:forMainFrameOnly:) : | webview.swift:134:10:134:12 | .source | | webview.swift:132:34:132:41 | call to source() : | webview.swift:65:5:65:93 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:) : | | webview.swift:132:34:132:41 | call to source() : | webview.swift:132:13:132:102 | call to init(source:injectionTime:forMainFrameOnly:) : | | webview.swift:137:13:137:113 | call to init(source:injectionTime:forMainFrameOnly:in:) : | webview.swift:138:10:138:10 | c | +| webview.swift:137:13:137:113 | call to init(source:injectionTime:forMainFrameOnly:in:) : | webview.swift:139:10:139:12 | .source | | webview.swift:137:34:137:41 | call to source() : | webview.swift:66:5:66:126 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:in:) : | | webview.swift:137:34:137:41 | call to source() : | webview.swift:137:13:137:113 | call to init(source:injectionTime:forMainFrameOnly:in:) : | nodes @@ -1131,9 +1133,11 @@ nodes | webview.swift:132:13:132:102 | call to init(source:injectionTime:forMainFrameOnly:) : | semmle.label | call to init(source:injectionTime:forMainFrameOnly:) : | | webview.swift:132:34:132:41 | call to source() : | semmle.label | call to source() : | | webview.swift:133:10:133:10 | b | semmle.label | b | +| webview.swift:134:10:134:12 | .source | semmle.label | .source | | webview.swift:137:13:137:113 | call to init(source:injectionTime:forMainFrameOnly:in:) : | semmle.label | call to init(source:injectionTime:forMainFrameOnly:in:) : | | webview.swift:137:34:137:41 | call to source() : | semmle.label | call to source() : | | webview.swift:138:10:138:10 | c | semmle.label | c | +| webview.swift:139:10:139:12 | .source | semmle.label | .source | subpaths | data.swift:89:41:89:48 | call to source() : | data.swift:25:2:25:66 | [summary param] 0 in init(base64Encoded:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | data.swift:89:21:89:71 | call to init(base64Encoded:options:) : | | data.swift:93:34:93:41 | call to source() : | data.swift:26:2:26:61 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | data.swift:93:21:93:73 | call to init(buffer:) : | @@ -1410,4 +1414,6 @@ subpaths | webview.swift:119:10:119:10 | v2 | webview.swift:81:13:81:20 | call to source() : | webview.swift:119:10:119:10 | v2 | result | | webview.swift:123:10:123:10 | v3 | webview.swift:81:13:81:20 | call to source() : | webview.swift:123:10:123:10 | v3 | result | | webview.swift:133:10:133:10 | b | webview.swift:132:34:132:41 | call to source() : | webview.swift:133:10:133:10 | b | result | +| webview.swift:134:10:134:12 | .source | webview.swift:132:34:132:41 | call to source() : | webview.swift:134:10:134:12 | .source | result | | webview.swift:138:10:138:10 | c | webview.swift:137:34:137:41 | call to source() : | webview.swift:138:10:138:10 | c | result | +| webview.swift:139:10:139:12 | .source | webview.swift:137:34:137:41 | call to source() : | webview.swift:139:10:139:12 | .source | result | diff --git a/swift/ql/test/library-tests/dataflow/taint/webview.swift b/swift/ql/test/library-tests/dataflow/taint/webview.swift index 473f0d6f917..a656d600de7 100644 --- a/swift/ql/test/library-tests/dataflow/taint/webview.swift +++ b/swift/ql/test/library-tests/dataflow/taint/webview.swift @@ -131,10 +131,10 @@ func testWKUserScript() { let b = WKUserScript(source: source() as! String, injectionTime: atStart, forMainFrameOnly: false) sink(b) // $ tainted=132 - sink(b.source) // $ MISSING: tainted=132 + sink(b.source) // $ tainted=132 let world = WKContentWorld() let c = WKUserScript(source: source() as! String, injectionTime: atStart, forMainFrameOnly: false, in: world) sink(c) // $ tainted=137 - sink(c.source) // $ MISSING: tainted=137 + sink(c.source) // $ tainted=137 } From 76afc2dcc3ebf367e6bd02f72681bf184f94ce97 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 28 Nov 2022 14:00:43 +0100 Subject: [PATCH 590/796] JS: Fix formatting and rephrase comment --- .../data/internal/ApiGraphModelsSpecific.qll | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll index df8710c37e2..9ebbe4099db 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll @@ -32,12 +32,11 @@ import JS::DataFlow as DataFlow private import AccessPathSyntax /** - * Holds if `rawType` represents the JavaScript npm `package` with type `qualifiedName`. - * The `qualifiedName` is everything after the first ".". - * So e.g. `rawType = "foo.bar"` will parse to `package = "foo" and qualifiedName = "bar"`. - * `package´ can be enclosed in single-quotes if the package name includes dots, - * e.g. `'my.package'.type` parses to `package = "my.package" and qualifiedName = "type"`. - */ + * Holds if `rawType` represents the JavaScript type `qualifiedName` from the given NPM `package`. + * + * Type names have form `package.type` or just `package` if referring to the package export + * object. If `package` contains a `.` character it must be enclosed in single quotes, such as `'package'.type`. + */ bindingset[rawType] predicate parseTypeString(string rawType, string package, string qualifiedName) { exists(string regexp | From 751ffbd9c898f301c341e9abee4ace799b3eff49 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 28 Nov 2022 14:44:07 +0100 Subject: [PATCH 591/796] use different keys for different caches --- swift/actions/run-integration-tests/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/actions/run-integration-tests/action.yml b/swift/actions/run-integration-tests/action.yml index 6e190693a55..00ef006ea09 100644 --- a/swift/actions/run-integration-tests/action.yml +++ b/swift/actions/run-integration-tests/action.yml @@ -20,7 +20,7 @@ runs: - id: query-cache uses: ./.github/actions/cache-query-compilation with: - key: swift-qltest + key: swift-integration - name: Run integration tests shell: bash run: | From d2824413db9596ce2699f08cbe8ebd4754f28b4b Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 28 Nov 2022 14:44:34 +0100 Subject: [PATCH 592/796] skip the only remaining macos job running on main --- .github/workflows/swift.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index 2baae15f270..4871442d4b7 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -35,6 +35,7 @@ jobs: # not using a matrix as you cannot depend on a specific job in a matrix, and we want to start linux checks # without waiting for the macOS build build-and-test-macos: + if: ${{ github.event_name == 'pull_request' }} runs-on: macos-12-xl steps: - uses: actions/checkout@v3 From a76d47681d365b2d81962cc367da7b3f92c428ca Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Fri, 25 Nov 2022 10:05:54 +0000 Subject: [PATCH 593/796] Replace references in Qhelp files --- go/ql/src/Security/CWE-601/BadRedirectCheck.qhelp | 2 +- python/ql/src/Imports/SyntaxError.qhelp | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/go/ql/src/Security/CWE-601/BadRedirectCheck.qhelp b/go/ql/src/Security/CWE-601/BadRedirectCheck.qhelp index b6036f4399b..a592abfff38 100644 --- a/go/ql/src/Security/CWE-601/BadRedirectCheck.qhelp +++ b/go/ql/src/Security/CWE-601/BadRedirectCheck.qhelp @@ -7,7 +7,7 @@ Redirect URLs should be checked to ensure that user input cannot cause a site to to arbitrary domains. This is often done with a check that the redirect URL begins with a slash, which most of the time is an absolute redirect on the same host. However, browsers interpret URLs beginning with // or /\ as absolute URLs. For example, a redirect to -//lgtm.com will redirect to https://lgtm.com. Thus, redirect checks must +//example.com will redirect to https://example.com. Thus, redirect checks must also check the second character of redirect URLs.

    diff --git a/python/ql/src/Imports/SyntaxError.qhelp b/python/ql/src/Imports/SyntaxError.qhelp index 00b4870e86a..3498a7a5510 100644 --- a/python/ql/src/Imports/SyntaxError.qhelp +++ b/python/ql/src/Imports/SyntaxError.qhelp @@ -26,9 +26,10 @@ However, it is worth investigating why a module containing a syntax error was able to persist and address that problem as well.

    If you suspect that the syntax error is caused by the analysis using the -wrong version of Python, consider specifying the version explicitly. For -LGTM.com, you can customize extraction using an lgtm.yml file as -described here. +wrong version of Python, consider specifying the version explicitly. When +you run code scanning using the CodeQL action, you can configure the Python +version to use. For more information, see +Analyzing Python dependencies.

    From 36a6ccba8b15fbe2cd552514cf0c25c728906489 Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Fri, 25 Nov 2022 10:12:03 +0000 Subject: [PATCH 594/796] Remove reference in template --- .github/ISSUE_TEMPLATE/ql---general.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/ql---general.md b/.github/ISSUE_TEMPLATE/ql---general.md index 1d5b7d244f6..7d317fc7580 100644 --- a/.github/ISSUE_TEMPLATE/ql---general.md +++ b/.github/ISSUE_TEMPLATE/ql---general.md @@ -9,6 +9,5 @@ assignees: '' **Description of the issue** - + From 5f835da8387498cce3e6145206a32a95e8eaaef0 Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Fri, 25 Nov 2022 10:15:14 +0000 Subject: [PATCH 595/796] Update HTML comment in query --- cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql b/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql index 47ed2b704d5..bf39200c5b6 100644 --- a/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql +++ b/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql @@ -12,8 +12,8 @@ */ /* - * Note: this query is not assigned a precision yet because we don't want it on - * LGTM until its performance is well understood. + * Note: this query is not assigned a precision yet because we don't want it + * included in query suites until its performance is well understood. */ import cpp From fb0959bcea33d22382fdfad958e8199bba8771ac Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Fri, 25 Nov 2022 10:19:23 +0000 Subject: [PATCH 596/796] Update QL reference --- docs/codeql/ql-language-reference/annotations.rst | 1 - docs/codeql/ql-language-reference/expressions.rst | 4 ---- .../ql-language-reference/ql-language-specification.rst | 4 +--- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/docs/codeql/ql-language-reference/annotations.rst b/docs/codeql/ql-language-reference/annotations.rst index e801f0a95aa..b78ef5bdd34 100644 --- a/docs/codeql/ql-language-reference/annotations.rst +++ b/docs/codeql/ql-language-reference/annotations.rst @@ -433,7 +433,6 @@ The ``bindingset`` annotation takes a comma-separated list of variables. (for characteristic predicates and member predicates) and ``result`` (for predicates that return a result). For more information, see ":ref:`predicate-binding`." - When you annotate a class, each variable must be ``this`` or a field in the class. - Binding sets for classes are supported from release 2.3.0 of the CodeQL CLI, and release 1.26 of LGTM Enterprise. .. Links to use in substitutions diff --git a/docs/codeql/ql-language-reference/expressions.rst b/docs/codeql/ql-language-reference/expressions.rst index 2091c7628a3..fdb0d6cd35a 100644 --- a/docs/codeql/ql-language-reference/expressions.rst +++ b/docs/codeql/ql-language-reference/expressions.rst @@ -117,8 +117,6 @@ The values of the contained expressions need to be of :ref:`compatible types Date: Fri, 25 Nov 2022 10:28:29 +0000 Subject: [PATCH 597/796] Remove LGTM support info --- .../supported-languages-and-frameworks.rst | 4 +- .../codeql-overview/system-requirements.rst | 4 +- docs/codeql/ql-training/template.rst | 2 +- .../supported-frameworks.rst} | 0 .../supported-platforms.rst} | 0 .../supported-versions-compilers.rst} | 0 docs/codeql/support/conf.py | 101 ------------------ docs/codeql/support/framework-support.rst | 19 ---- docs/codeql/support/index.rst | 19 ---- docs/codeql/support/language-support.rst | 16 --- docs/codeql/support/ql-training.rst | 63 ----------- docs/codeql/support/read-me-project.rst | 15 --- 12 files changed, 5 insertions(+), 238 deletions(-) rename docs/codeql/{support/reusables/frameworks.rst => reusables/supported-frameworks.rst} (100%) rename docs/codeql/{support/reusables/platforms.rst => reusables/supported-platforms.rst} (100%) rename docs/codeql/{support/reusables/versions-compilers.rst => reusables/supported-versions-compilers.rst} (100%) delete mode 100644 docs/codeql/support/conf.py delete mode 100644 docs/codeql/support/framework-support.rst delete mode 100644 docs/codeql/support/index.rst delete mode 100644 docs/codeql/support/language-support.rst delete mode 100644 docs/codeql/support/ql-training.rst delete mode 100644 docs/codeql/support/read-me-project.rst diff --git a/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst b/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst index be66125846a..7cb78873ceb 100644 --- a/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst +++ b/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst @@ -16,7 +16,7 @@ CodeQL library packs (`source `__) support the following languages and compilers. -.. include:: ../support/reusables/versions-compilers.rst +.. include:: ../reusables/supported-versions-compilers.rst Frameworks and libraries ######################## @@ -31,4 +31,4 @@ The current versions of the CodeQL library and query packs (`source v documentation". -html_title = 'Supported languages and frameworks' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'Supported languages and frameworks' - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['../_templates'] - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['../_static'] - -html_theme_options = {'font_size': '16px', - 'body_text': '#333', - 'link': '#2F1695', - 'link_hover': '#2F1695', - 'show_powered_by': False, - 'nosidebar':True, - 'head_font_family': '-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"', - } - -html_favicon = '../images/site/favicon.ico' - -# -- Currently unused, but potentially useful, configs-------------------------------------- - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -#html_extra_path = [] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['read-me-project.rst', 'reusables/*'] diff --git a/docs/codeql/support/framework-support.rst b/docs/codeql/support/framework-support.rst deleted file mode 100644 index d12b1a96c8f..00000000000 --- a/docs/codeql/support/framework-support.rst +++ /dev/null @@ -1,19 +0,0 @@ -Frameworks and libraries -######################## - -LGTM Enterprise |release| includes CodeQL CLI |version|. The CodeQL libraries and queries used by this version of LGTM Enterprise have been explicitly checked against the libraries and frameworks listed below. - -.. pull-quote:: - - Note - - For details of framework and library support in the most recent release of the CodeQL CLI, see `Supported languages and frameworks `__ in the CodeQL CLI documentation. - -.. pull-quote:: - - Tip - - If you're interested in other libraries or frameworks, you can extend the analysis to cover them. - For example, by extending the data flow libraries to include data sources and sinks for additional libraries or frameworks. - -.. include:: reusables/frameworks.rst diff --git a/docs/codeql/support/index.rst b/docs/codeql/support/index.rst deleted file mode 100644 index 89812242fce..00000000000 --- a/docs/codeql/support/index.rst +++ /dev/null @@ -1,19 +0,0 @@ -Supported languages and frameworks -################################## - -These pages describe the languages and frameworks supported in the latest enterprise release of CodeQL and LGTM. (CodeQL was previously known as QL.) -Users of `LGTM.com `_ may find that additional features are supported because it's updated more frequently. - -For details see: - -.. toctree:: - - language-support.rst - framework-support.rst - -For details of the CodeQL libraries, see `CodeQL standard libraries `_. - -.. toctree:: - :hidden: - - ql-training \ No newline at end of file diff --git a/docs/codeql/support/language-support.rst b/docs/codeql/support/language-support.rst deleted file mode 100644 index 49b90693a7c..00000000000 --- a/docs/codeql/support/language-support.rst +++ /dev/null @@ -1,16 +0,0 @@ -Languages and compilers -####################### - -LGTM Enterprise |release| includes CodeQL CLI |version|. LGTM Enterprise supports analysis of the following languages compiled by the following compilers. - -.. pull-quote:: - - Note - - For details of language and compiler support in the most recent release of the CodeQL CLI, see `Supported languages and frameworks `__ in the CodeQL CLI documentation. - -Note that where there are several versions or dialects of a language, the supported variants are listed. -If your code requires a particular version of a compiler, check that this version is included below. -If you have any questions about language and compiler support, you can find help on the `GitHub Security Lab discussions board `__. - -.. include:: reusables/versions-compilers.rst diff --git a/docs/codeql/support/ql-training.rst b/docs/codeql/support/ql-training.rst deleted file mode 100644 index 6eb8019e5c9..00000000000 --- a/docs/codeql/support/ql-training.rst +++ /dev/null @@ -1,63 +0,0 @@ -CodeQL training and variant analysis examples -============================================= - -CodeQL and variant analysis ---------------------------- - -Variant analysis is the process of using a known vulnerability as a seed to find similar problems in your code. Security engineers typically perform variant analysis to identify possible vulnerabilities and to ensure that these threats are properly fixed across multiple code bases. - -CodeQL is the code analysis engine that underpins LGTM, the community driven security analysis platform. Together, CodeQL and LGTM provide continuous monitoring and scalable variant analysis for your projects, even if you don’t have your own team of dedicated security engineers. You can read more about using CodeQL and LGTM in variant analysis on the `Security Lab research page `__. - -CodeQL is easy to learn, and exploring code using CodeQL is the most efficient way to perform variant analysis. - -Learning CodeQL for variant analysis ------------------------------------- - -Start learning how to use CodeQL in variant analysis for a specific language by looking at the topics below. Each topic links to a short presentation on CodeQL, its libraries, or an example variant discovered using CodeQL. - -.. |arrow-l| unicode:: U+2190 - -.. |arrow-r| unicode:: U+2192 - -.. |info| unicode:: U+24D8 - -When you have selected a presentation, use |arrow-r| and |arrow-l| to navigate between slides. -Press **p** to view the additional notes on slides that have an information icon |info| in the top right corner, and press **f** to enter full-screen mode. - -The presentations contain a number of query examples. -We recommend that you download `CodeQL for Visual Studio Code `__ and add the example database for each presentation so that you can find the bugs mentioned in the slides. - - -.. pull-quote:: - - Information - - The presentations listed below are used in CodeQL and variant analysis training sessions run by GitHub engineers. - Therefore, be aware that the slides are designed to be presented by an instructor. - If you are using the slides without an instructor, please use the additional notes to help guide you through the examples. - -CodeQL and variant analysis for C/C++ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- `Introduction to variant analysis: CodeQL for C/C++ `__–an introduction to variant analysis and CodeQL for C/C++ programmers. -- `Example: Bad overflow guard `__–an example of iterative query development to find bad overflow guards in a C++ project. -- `Program representation: CodeQL for C/C++ `__–information on how CodeQL analysis represents C/C++ programs. -- `Introduction to local data flow `__–an introduction to analyzing local data flow in C/C++ using CodeQL, including an example demonstrating how to develop a query to find a real CVE. -- `Exercise: snprintf overflow `__–an example demonstrating how to develop a data flow query. -- `Introduction to global data flow `__–an introduction to analyzing global data flow in C/C++ using CodeQL. -- `Analyzing control flow: CodeQL for C/C++ `__–an introduction to analyzing control flow in C/C++ using CodeQL. - -CodeQL and variant analysis for Java -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- `Introduction to variant analysis: CodeQL for Java `__–an introduction to variant analysis and CodeQL for Java programmers. -- `Example: Query injection `__–an example of iterative query development to find unsanitized SPARQL injections in a Java project. -- `Program representation: CodeQL for Java `__–information on how CodeQL analysis represents Java programs. -- `Introduction to local data flow `__–an introduction to analyzing local data flow in Java using CodeQL, including an example demonstrating how to develop a query to find a real CVE. -- `Exercise: Apache Struts `__–an example demonstrating how to develop a data flow query. -- `Introduction to global data flow `__–an introduction to analyzing global data flow in Java using CodeQL. - -Further reading -~~~~~~~~~~~~~~~ - -- `GitHub Security Lab `__ diff --git a/docs/codeql/support/read-me-project.rst b/docs/codeql/support/read-me-project.rst deleted file mode 100644 index 81182043793..00000000000 --- a/docs/codeql/support/read-me-project.rst +++ /dev/null @@ -1,15 +0,0 @@ -Publishing this project for a new version -######################################### - -To update this project for a new version: - -1. Check with the language teams that all information in the ``ql/change-notes/support/`` directory is ready. - -2. Open the ``global-conf.py`` file in the ``global-sphinx-files`` directory and change the following variables -to the correct value(s) if necessary: - - * ``version =`` - * ``release = `` - * If it's the first release of the year, ``copyright =`` - -3. Commit your changes. The output of the ``doc/sphinx`` PR check should be correct for the new version and ready to publish. \ No newline at end of file From b5f849463bc771e65c30246d700f0e643ea5c198 Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Fri, 25 Nov 2022 11:19:40 +0000 Subject: [PATCH 598/796] Update QL library references --- cpp/ql/lib/definitions.qll | 4 ++-- cpp/ql/src/Metrics/Dependencies/ExternalDependencies.qll | 2 +- ruby/ql/lib/codeql/Locations.qll | 4 ++-- ruby/ql/lib/codeql/ruby/printAst.qll | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cpp/ql/lib/definitions.qll b/cpp/ql/lib/definitions.qll index cb229d66ef1..e866a50513b 100644 --- a/cpp/ql/lib/definitions.qll +++ b/cpp/ql/lib/definitions.qll @@ -12,8 +12,8 @@ import IDEContextual * * In some cases it is preferable to modify locations (the * `hasLocationInfo()` predicate) so that they are short, and - * non-overlapping with other locations that might be highlighted in - * the LGTM interface. + * non-overlapping with other locations that might be reported as + * code scanning alerts in GitHub. * * We need to give locations that may not be in the database, so * we use `hasLocationInfo()` rather than `getLocation()`. diff --git a/cpp/ql/src/Metrics/Dependencies/ExternalDependencies.qll b/cpp/ql/src/Metrics/Dependencies/ExternalDependencies.qll index 352cf86ddd5..967a9987a4f 100644 --- a/cpp/ql/src/Metrics/Dependencies/ExternalDependencies.qll +++ b/cpp/ql/src/Metrics/Dependencies/ExternalDependencies.qll @@ -52,7 +52,7 @@ class Library extends LibraryT { // The versions reported for C/C++ dependencies are just the versions that // happen to be installed on the system where the build takes place. // Reporting those versions is likely to cause misunderstandings, both for - // people reading them and for the vulnerability checker of lgtm. + // people reading them and for vulnerability checkers. result = "unknown" } diff --git a/ruby/ql/lib/codeql/Locations.qll b/ruby/ql/lib/codeql/Locations.qll index 8bed8d904f1..269d16833eb 100644 --- a/ruby/ql/lib/codeql/Locations.qll +++ b/ruby/ql/lib/codeql/Locations.qll @@ -6,7 +6,7 @@ import files.FileSystem * A location as given by a file, a start line, a start column, * an end line, and an end column. * - * For more information about locations see [LGTM locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + * For more information about locations see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ class Location extends @location { /** Gets the file for this location. */ @@ -40,7 +40,7 @@ class Location extends @location { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [LGTM locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + * [Providing locations in CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/ruby/ql/lib/codeql/ruby/printAst.qll b/ruby/ql/lib/codeql/ruby/printAst.qll index 28f5def4969..25aa7908db3 100644 --- a/ruby/ql/lib/codeql/ruby/printAst.qll +++ b/ruby/ql/lib/codeql/ruby/printAst.qll @@ -70,7 +70,7 @@ class PrintAstNode extends TPrintNode { * Holds if this node is at the specified location. The location spans column * `startcolumn` of line `startline` to column `endcolumn` of line `endline` * in file `filepath`. For more information, see - * [LGTM locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn From ea127c3d99c217bee0f7f0c7165eb90ed2dfa5e3 Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Fri, 25 Nov 2022 11:20:03 +0000 Subject: [PATCH 599/796] A few more references --- docs/codeql/reusables/supported-versions-compilers.rst | 2 +- .../metadata-for-codeql-queries.rst | 8 ++++---- .../providing-locations-in-codeql-queries.rst | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/codeql/reusables/supported-versions-compilers.rst b/docs/codeql/reusables/supported-versions-compilers.rst index ab09831884b..85a650ed17a 100644 --- a/docs/codeql/reusables/supported-versions-compilers.rst +++ b/docs/codeql/reusables/supported-versions-compilers.rst @@ -37,4 +37,4 @@ .. [7] JSX and Flow code, YAML, JSON, HTML, and XML files may also be analyzed with JavaScript files. .. [8] The extractor requires Python 3 to run. To analyze Python 2.7 you should install both versions of Python. .. [9] Requires glibc 2.17. - .. [10] TypeScript analysis is performed by running the JavaScript extractor with TypeScript enabled. This is the default for LGTM. + .. [10] TypeScript analysis is performed by running the JavaScript extractor with TypeScript enabled. This is the default. diff --git a/docs/codeql/writing-codeql-queries/metadata-for-codeql-queries.rst b/docs/codeql/writing-codeql-queries/metadata-for-codeql-queries.rst index 040f873d410..46807e45399 100644 --- a/docs/codeql/writing-codeql-queries/metadata-for-codeql-queries.rst +++ b/docs/codeql/writing-codeql-queries/metadata-for-codeql-queries.rst @@ -9,7 +9,7 @@ About query metadata -------------------- Any query that is run as part of an analysis includes a number of properties, known as query metadata. Metadata is included at the top of each query file as the content of a QLDoc comment. -This metadata tells LGTM and the CodeQL :ref:`extension for VS Code ` how to handle the query and display its results correctly. +This metadata tells the CodeQL :ref:`extension for VS Code ` and the `Code scanning feature in GitHub `__ how to handle the query and display its results correctly. It also gives other users information about what the query results mean. For more information on query metadata, see the `query metadata style guide `__ in our `open source repository `__ on GitHub. .. pull-quote:: @@ -28,7 +28,7 @@ The following properties are supported by all query files: +=======================+===========================+=======================================================================================================================================================================================================================================================================================================================================================================+ | ``@description`` | ```` | A sentence or short paragraph to describe the purpose of the query and *why* the result is useful or important. The description is written in plain text, and uses single quotes (``'``) to enclose code elements. | +-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``@id`` | ```` | A sequence of words composed of lowercase letters or digits, delimited by ``/`` or ``-``, identifying and classifying the query. Each query must have a **unique** ID. To ensure this, it may be helpful to use a fixed structure for each ID. For example, the standard LGTM queries have the following format: ``/``. | +| ``@id`` | ```` | A sequence of words composed of lowercase letters or digits, delimited by ``/`` or ``-``, identifying and classifying the query. Each query must have a **unique** ID. To ensure this, it may be helpful to use a fixed structure for each ID. For example, the standard CodeQL queries have the following format: ``/``. | +-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``@kind`` | | ``problem`` | Identifies the query is an alert (``@kind problem``) or a path (``@kind path-problem``). For more information on these query types, see ":doc:`About CodeQL queries `." | | | | ``path-problem`` | | @@ -40,12 +40,12 @@ The following properties are supported by all query files: | | | ``readability`` | | | | | ``security`` | | +-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``@precision`` | | ``low`` | Indicates the percentage of query results that are true positives (as opposed to false positive results). This, along with the ``@problem.severity`` property, determines whether the results are displayed by default on LGTM. | +| ``@precision`` | | ``low`` | Indicates the percentage of query results that are true positives (as opposed to false positive results). This, along with the ``@problem.severity`` property, determines how the results are displayed in GitHub. | | | | ``medium`` | | | | | ``high`` | | | | | ``very-high`` | | +-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``@problem.severity`` | | ``error`` | Defines the level of severity of any alerts generated by a non-security query. This, along with the ``@precision`` property, determines whether the results are displayed by default on LGTM. | +| ``@problem.severity`` | | ``error`` | Defines the level of severity of any alerts generated by a non-security query. This, along with the ``@precision`` property, determines how the results are displayed in GitHub. | | | | ``warning`` | | | | | ``recommendation`` | | +-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ diff --git a/docs/codeql/writing-codeql-queries/providing-locations-in-codeql-queries.rst b/docs/codeql/writing-codeql-queries/providing-locations-in-codeql-queries.rst index 239d3fc7628..f8f5682c8b9 100644 --- a/docs/codeql/writing-codeql-queries/providing-locations-in-codeql-queries.rst +++ b/docs/codeql/writing-codeql-queries/providing-locations-in-codeql-queries.rst @@ -11,7 +11,7 @@ CodeQL includes mechanisms for extracting the location of elements in a codebase About locations --------------- -When displaying information to the user, LGTM needs to be able to extract location information from the results of a query. In order to do this, all QL classes which can provide location information should do this by using one of the following mechanisms: +When displaying information to the user, applications need to be able to extract location information from the results of a query. In order to do this, all QL classes which can provide location information should do this by using one of the following mechanisms: - `Providing URLs <#providing-urls>`__ - `Providing location information <#providing-location-information>`__ @@ -49,7 +49,7 @@ A custom URL can be provided by defining a QL predicate returning ``string`` wit File URLs ^^^^^^^^^ -LGTM supports the display of URLs which define a line and column in a source file. +The CodeQL extension for Visual Studio Code and the code scanning views in GitHub support the display of URLs which define a line and column in a source file. The schema is ``file://``, which is followed by the absolute path to a file, followed by four numbers separated by colons. The numbers denote start line, start column, end line and end column. Both line and column numbers are **1-based**, for example: @@ -57,12 +57,12 @@ The schema is ``file://``, which is followed by the absolute path to a file, fol - ``file:///opt/src/my/file.java:1:1:2:1`` denotes the location that starts at the beginning of the file and extends to the first character of the second line (the range is inclusive). - ``file:///opt/src/my/file.java:1:0:1:0`` is taken, by convention, to denote the entire first line of the file. -By convention, the location of an entire file may also be denoted by a ``file://`` URL without trailing numbers. Optionally, the location within a file can be denoted using three numbers to define the start line number, character offset and character length of the location respectively. Results of these types are not displayed in LGTM. +By convention, the location of an entire file may also be denoted by a ``file://`` URL without trailing numbers. Optionally, the location within a file can be denoted using three numbers to define the start line number, character offset and character length of the location respectively. Results of these types are not displayed as code scanning alerts. Other types of URL ^^^^^^^^^^^^^^^^^^ -The following, less-common types of URL are valid but are not supported by LGTM and will be omitted from any results: +The following, less-common types of URL are valid but are not interpreted as code scanning alerts and will be omitted from any results: - **HTTP URLs** are supported in some client applications. For an example, see the code snippet above. - **Folder URLs** can be useful, for example to provide folder-level metrics. They may use a file URL, for example ``file:///opt/src:0:0:0:0``, but they may also start with a scheme of ``folder://``, and no trailing numbers, for example ``folder:///opt/src``. From c451fa8ad4ca3bf8e5fa1d0e9ad3503b89d9f870 Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Fri, 25 Nov 2022 12:59:48 +0000 Subject: [PATCH 600/796] Update cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql Co-authored-by: Taus --- cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql b/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql index bf39200c5b6..0de0979f9a3 100644 --- a/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql +++ b/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql @@ -12,7 +12,7 @@ */ /* - * Note: this query is not assigned a precision yet because we don't want it + * Note: this query is not assigned a precision yet because we don't want it * included in query suites until its performance is well understood. */ From c1e6d4c82af7fef1d90405d2a219562b3d56b2ef Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Mon, 28 Nov 2022 11:19:34 +0000 Subject: [PATCH 601/796] Update .github/ISSUE_TEMPLATE/ql---general.md --- .github/ISSUE_TEMPLATE/ql---general.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/ql---general.md b/.github/ISSUE_TEMPLATE/ql---general.md index 7d317fc7580..f68574485c1 100644 --- a/.github/ISSUE_TEMPLATE/ql---general.md +++ b/.github/ISSUE_TEMPLATE/ql---general.md @@ -9,5 +9,6 @@ assignees: '' **Description of the issue** - + From da4c17853472d69a5a5f4b913c116ab65154457a Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Thu, 24 Nov 2022 12:19:29 +0000 Subject: [PATCH 602/796] Update main Python articles --- .../analyzing-control-flow-in-python.rst | 6 +++--- .../analyzing-data-flow-in-python.rst | 18 ++++++------------ .../codeql-for-python.rst | 2 +- .../codeql-library-for-python.rst | 10 ++++------ .../expressions-and-statements-in-python.rst | 10 ++-------- .../functions-in-python.rst | 8 +++----- .../using-api-graphs-in-python.rst | 12 ------------ 7 files changed, 19 insertions(+), 47 deletions(-) diff --git a/docs/codeql/codeql-language-guides/analyzing-control-flow-in-python.rst b/docs/codeql/codeql-language-guides/analyzing-control-flow-in-python.rst index 15f6a96596d..c37b721cc87 100644 --- a/docs/codeql/codeql-language-guides/analyzing-control-flow-in-python.rst +++ b/docs/codeql/codeql-language-guides/analyzing-control-flow-in-python.rst @@ -47,7 +47,7 @@ Example finding unreachable AST nodes where not exists(node.getAFlowNode()) select node -➤ `See this in the query console on LGTM.com `__. The demo projects on LGTM.com all have some code that has no control flow node, and is therefore unreachable. However, since the ``Module`` class is also a subclass of the ``AstNode`` class, the query also finds any modules implemented in C or with no source code. Therefore, it is better to find all unreachable statements. +Many codebases have some code that has no control flow node, and is therefore unreachable. However, since the ``Module`` class is also a subclass of the ``AstNode`` class, the query also finds any modules implemented in C or with no source code. Therefore, it is better to find all unreachable statements. Example finding unreachable statements ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ Example finding unreachable statements where not exists(s.getAFlowNode()) select s -➤ `See this in the query console on LGTM.com `__. This query gives fewer results, but most of the projects have some unreachable nodes. These are also highlighted by the standard "Unreachable code" query. For more information, see `Unreachable code `__ on LGTM.com. +This query should give fewer results. You can also find unreachable code using the standard "Unreachable code" query. For more information, see `Unreachable code `__. The ``BasicBlock`` class ------------------------ @@ -114,7 +114,7 @@ Example finding mutually exclusive blocks within the same function ) select b1, b2 -➤ `See this in the query console on LGTM.com `__. This typically gives a very large number of results, because it is a common occurrence in normal control flow. It is, however, an example of the sort of control-flow analysis that is possible. Control-flow analyses such as this are an important aid to data flow analysis. For more information, see ":doc:`Analyzing data flow in Python `." +This typically gives a very large number of results, because it is a common occurrence in normal control flow. It is, however, an example of the sort of control-flow analysis that is possible. Control-flow analyses such as this are an important aid to data flow analysis. For more information, see ":doc:`Analyzing data flow in Python `." Further reading --------------- diff --git a/docs/codeql/codeql-language-guides/analyzing-data-flow-in-python.rst b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-python.rst index f5128e5eafd..2ad5fc925f0 100644 --- a/docs/codeql/codeql-language-guides/analyzing-data-flow-in-python.rst +++ b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-python.rst @@ -97,11 +97,9 @@ Python has builtin functionality for reading and writing files, such as the func call = API::moduleImport("os").getMember("open").getACall() select call.getArg(0) -➤ `See this in the query console on LGTM.com `__. Two of the demo projects make use of this low-level API. - Notice the use of the ``API`` module for referring to library functions. For more information, see ":doc:`Using API graphs in Python `." -Unfortunately this will only give the expression in the argument, not the values which could be passed to it. So we use local data flow to find all expressions that flow into the argument: +Unfortunately this query will only give the expression in the argument, not the values which could be passed to it. So we use local data flow to find all expressions that flow into the argument: .. code-block:: ql @@ -115,9 +113,7 @@ Unfortunately this will only give the expression in the argument, not the values DataFlow::localFlow(expr, call.getArg(0)) select call, expr -➤ `See this in the query console on LGTM.com `__. Many expressions flow to the same call. - -We see that we get several data-flow nodes for an expression as it flows towards a call (notice repeated locations in the ``call`` column). We are mostly interested in the "first" of these, what might be called the local source for the file name. To restrict attention to such local sources, and to simultaneously make the analysis more performant, we have the QL class ``LocalSourceNode``. We could demand that ``expr`` is such a node: +Typically, you will see several data-flow nodes for an expression as it flows towards a call (notice repeated locations in the ``call`` column). We are mostly interested in the "first" of these, what might be called the local source for the file name. To restrict attention to such local sources, and to simultaneously make the analysis more performant, we have the QL class ``LocalSourceNode``. We could demand that ``expr`` is such a node: .. code-block:: ql @@ -160,9 +156,9 @@ As an alternative, we can ask more directly that ``expr`` is a local source of t expr = call.getArg(0).getALocalSource() select call, expr -➤ `See this in the query console on LGTM.com `__. All these three queries give identical results. We now mostly have one expression per call. +These three queries all give identical results. We now mostly have one expression per call. -We still have some cases of more than one expression flowing to a call, but then they flow through different code paths (possibly due to control-flow splitting, as in the second case). +We still have some cases of more than one expression flowing to a call, but then they flow through different code paths (possibly due to control-flow splitting). We might want to make the source more specific, for example a parameter to a function or method. This query finds instances where a parameter is used as the name when opening a file: @@ -178,7 +174,7 @@ We might want to make the source more specific, for example a parameter to a fun DataFlow::localFlow(p, call.getArg(0)) select call, p -➤ `See this in the query console on LGTM.com `__. Very few results now; these could feasibly be inspected manually. +For most codebases, this will return only a few results and these could be inspected manually. Using the exact name supplied via the parameter may be too strict. If we want to know if the parameter influences the file name, we can use taint tracking instead of data flow. This query finds calls to ``os.open`` where the filename is derived from a parameter: @@ -194,7 +190,7 @@ Using the exact name supplied via the parameter may be too strict. If we want to TaintTracking::localTaint(p, call.getArg(0)) select call, p -➤ `See this in the query console on LGTM.com `__. Now we get more results and in more projects. +Typically, this finds more results. Global data flow ---------------- @@ -369,8 +365,6 @@ This data flow configuration tracks data flow from environment variables to open select fileOpen, "This call to 'os.open' uses data from $@.", environment, "call to 'os.getenv'" -➤ `Running this in the query console on LGTM.com `__ unsurprisingly yields no results in the demo projects. - Further reading --------------- diff --git a/docs/codeql/codeql-language-guides/codeql-for-python.rst b/docs/codeql/codeql-language-guides/codeql-for-python.rst index 15b0c4a84f8..3b639e9cdf2 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-python.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-python.rst @@ -16,7 +16,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat expressions-and-statements-in-python analyzing-control-flow-in-python -- :doc:`Basic query for Python code `: Learn to write and run a simple CodeQL query using LGTM. +- :doc:`Basic query for Python code `: Learn to write and run a simple CodeQL query. - :doc:`CodeQL library for Python `: When you need to analyze a Python program, you can make use of the large collection of classes in the CodeQL library for Python. diff --git a/docs/codeql/codeql-language-guides/codeql-library-for-python.rst b/docs/codeql/codeql-language-guides/codeql-library-for-python.rst index 204a6d22c3b..c1b392cc358 100644 --- a/docs/codeql/codeql-language-guides/codeql-library-for-python.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-python.rst @@ -53,7 +53,7 @@ All scopes are basically a list of statements, although ``Scope`` classes have a where f.getScope() instanceof Function select f -➤ `See this in the query console on LGTM.com `__. Many projects have nested functions. +Many codebases use nested functions. Statement ^^^^^^^^^ @@ -95,7 +95,7 @@ As an example, to find expressions of the form ``a+2`` where the left is a simpl where bin.getLeft() instanceof Name and bin.getRight() instanceof Num select bin -➤ `See this in the query console on LGTM.com `__. Many projects include examples of this pattern. +Many codebases include examples of this pattern. Variable ^^^^^^^^ @@ -126,7 +126,7 @@ For our first example, we can find all ``finally`` blocks by using the ``Try`` c from Try t select t.getFinalbody() -➤ `See this in the query console on LGTM.com `__. Many projects include examples of this pattern. +Many codebases include examples of this pattern. 2. Finding ``except`` blocks that do nothing '''''''''''''''''''''''''''''''''''''''''''' @@ -157,7 +157,7 @@ Both forms are equivalent. Using the positive expression, the whole query looks where forall(Stmt s | s = ex.getAStmt() | s instanceof Pass) select ex -➤ `See this in the query console on LGTM.com `__. Many projects include pass-only ``except`` blocks. +Many codebases include pass-only ``except`` blocks. Summary ^^^^^^^ @@ -278,8 +278,6 @@ Using this predicate we can select the longest ``BasicBlock`` by selecting the ` where bb_length(b) = max(bb_length(_)) select b -➤ `See this in the query console on LGTM.com `__. When we ran it on the LGTM.com demo projects, the *openstack/nova* and *ytdl-org/youtube-dl* projects both contained source code results for this query. - .. pull-quote:: Note diff --git a/docs/codeql/codeql-language-guides/expressions-and-statements-in-python.rst b/docs/codeql/codeql-language-guides/expressions-and-statements-in-python.rst index 48cca630660..32a16560bc3 100644 --- a/docs/codeql/codeql-language-guides/expressions-and-statements-in-python.rst +++ b/docs/codeql/codeql-language-guides/expressions-and-statements-in-python.rst @@ -54,8 +54,6 @@ The ``global`` statement in Python declares a variable with a global (module-lev where g.getScope() instanceof Module select g -➤ `See this in the query console on LGTM.com `__. None of the demo projects on LGTM.com has a global statement that matches this pattern. - The line: ``g.getScope() instanceof Module`` ensures that the ``Scope`` of ``Global g`` is a ``Module``, rather than a class or function. Example finding 'if' statements with redundant branches @@ -81,7 +79,7 @@ To find statements like this that could be simplified we can write a query. and forall(Stmt p | p = l.getAnItem() | p instanceof Pass) select i -➤ `See this in the query console on LGTM.com `__. Many projects have some ``if`` statements that match this pattern. +Many codebases have some ``if`` statements that match this pattern. The line: ``(l = i.getBody() or l = i.getOrelse())`` restricts the ``StmtList l`` to branches of the ``if`` statement. @@ -150,8 +148,6 @@ We can check for these using a query. and cmp.getOp(0) instanceof Is and cmp.getComparator(0) = literal select cmp -➤ `See this in the query console on LGTM.com `__. Two of the demo projects on LGTM.com use this pattern: *saltstack/salt* and *openstack/nova*. - The clause ``cmp.getOp(0) instanceof Is and cmp.getComparator(0) = literal`` checks that the first comparison operator is "is" and that the first comparator is a literal. .. pull-quote:: @@ -180,7 +176,7 @@ If there are duplicate keys in a Python dictionary, then the second key will ove and k1 != k2 and same_key(k1, k2) select k1, "Duplicate key in dict literal" -➤ `See this in the query console on LGTM.com `__. When we ran this query on LGTM.com, the source code of the *saltstack/salt* project contained an example of duplicate dictionary keys. The results were also highlighted as alerts by the standard "Duplicate key in dict literal" query. Two of the other demo projects on LGTM.com refer to duplicate dictionary keys in library files. For more information, see `Duplicate key in dict literal `__ on LGTM.com. +When we ran this query on some test codebases, we found examples of duplicate dictionary keys. The results were also highlighted as alerts by the standard "Duplicate key in dict literal" query. For more information, see `Duplicate key in dict literal `__. The supporting predicate ``same_key`` checks that the keys have the same identifier. Separating this part of the logic into a supporting predicate, instead of directly including it in the query, makes it easier to understand the query as a whole. The casts defined in the predicate restrict the expression to the type specified and allow predicates to be called on the type that is cast-to. For example: @@ -222,8 +218,6 @@ This basic query can be improved by checking that the one line of code is a Java and attr.getObject() = self and self.getId() = "self" select f, "This function is a Java-style getter." -➤ `See this in the query console on LGTM.com `__. Of the demo projects on LGTM.com, only the *openstack/nova* project has examples of functions that appear to be Java-style getters. - .. code-block:: ql ret = f.getStmt(0) and ret.getValue() = attr diff --git a/docs/codeql/codeql-language-guides/functions-in-python.rst b/docs/codeql/codeql-language-guides/functions-in-python.rst index ab401f6c5e5..fbb4ff0d6e5 100644 --- a/docs/codeql/codeql-language-guides/functions-in-python.rst +++ b/docs/codeql/codeql-language-guides/functions-in-python.rst @@ -28,7 +28,7 @@ Using the member predicate ``Function.getName()``, we can list all of the getter where f.getName().matches("get%") select f, "This is a function called get..." -➤ `See this in the query console on LGTM.com `__. This query typically finds a large number of results. Usually, many of these results are for functions (rather than methods) which we are not interested in. +This query typically finds a large number of results. Usually, many of these results are for functions (rather than methods) which we are not interested in. Finding all methods called "get..." ----------------------------------- @@ -43,7 +43,7 @@ You can modify the query above to return more interesting results. As we are onl where f.getName().matches("get%") and f.isMethod() select f, "This is a method called get..." -➤ `See this in the query console on LGTM.com `__. This finds methods whose name starts with ``"get"``, but many of those are not the sort of simple getters we are interested in. +This finds methods whose name starts with ``"get"``, but many of those are not the sort of simple getters we are interested in. Finding one line methods called "get..." ---------------------------------------- @@ -59,7 +59,7 @@ We can modify the query further to include only methods whose body consists of a and count(f.getAStmt()) = 1 select f, "This function is (probably) a getter." -➤ `See this in the query console on LGTM.com `__. This query returns fewer results, but if you examine the results you can see that there are still refinements to be made. This is refined further in ":doc:`Expressions and statements in Python `." +This query returns fewer results, but if you examine the results you can see that there are still refinements to be made. This is refined further in ":doc:`Expressions and statements in Python `." Finding a call to a specific function ------------------------------------- @@ -74,8 +74,6 @@ This query uses ``Call`` and ``Name`` to find calls to the function ``eval`` - w where call.getFunc() = name and name.getId() = "eval" select call, "call to 'eval'." -➤ `See this in the query console on LGTM.com `__. Some of the demo projects on LGTM.com use this function. - The ``Call`` class represents calls in Python. The ``Call.getFunc()`` predicate gets the expression being called. ``Name.getId()`` gets the identifier (as a string) of the ``Name`` expression. Due to the dynamic nature of Python, this query will select any call of the form ``eval(...)`` regardless of whether it is a call to the built-in function ``eval`` or not. In a later tutorial we will see how to use the type-inference library to find calls to the built-in function ``eval`` regardless of name of the variable called. diff --git a/docs/codeql/codeql-language-guides/using-api-graphs-in-python.rst b/docs/codeql/codeql-language-guides/using-api-graphs-in-python.rst index 24be065c912..adfcdaa8d60 100644 --- a/docs/codeql/codeql-language-guides/using-api-graphs-in-python.rst +++ b/docs/codeql/codeql-language-guides/using-api-graphs-in-python.rst @@ -29,8 +29,6 @@ following snippet demonstrates. select API::moduleImport("re") -➤ `See this in the query console on LGTM.com `__. - This query selects the API graph node corresponding to the ``re`` module. This node represents the fact that the ``re`` module has been imported rather than a specific location in the program where the import happens. Therefore, there will be at most one result per project, and it will not have a useful location, so you'll have to click `Show 1 non-source result` in order to see it. To find where the ``re`` module is referenced in the program, you can use the ``getAUse`` method. The following query selects all references to the ``re`` module in the current database. @@ -42,8 +40,6 @@ To find where the ``re`` module is referenced in the program, you can use the `` select API::moduleImport("re").getAUse() -➤ `See this in the query console on LGTM.com `__. - Note that the ``getAUse`` method accounts for local flow, so that ``my_re_compile`` in the following snippet is correctly recognized as a reference to the ``re.compile`` function. @@ -77,8 +73,6 @@ the above ``re.compile`` example, you can now find references to ``re.compile``. select API::moduleImport("re").getMember("compile").getAUse() -➤ `See this in the query console on LGTM.com `__. - In addition to ``getMember``, you can use the ``getUnknownMember`` method to find references to API components where the name is not known statically. You can use the ``getAMember`` method to access all members, both known and unknown. @@ -97,15 +91,11 @@ where the return value of ``re.compile`` is used: select API::moduleImport("re").getMember("compile").getReturn().getAUse() -➤ `See this in the query console on LGTM.com `__. - Note that this includes all uses of the result of ``re.compile``, including those reachable via local flow. To get just the *calls* to ``re.compile``, you can use ``getAnImmediateUse`` instead of ``getAUse``. As this is a common occurrence, you can use ``getACall`` instead of ``getReturn`` followed by ``getAnImmediateUse``. -➤ `See this in the query console on LGTM.com `__. - Note that the API graph does not distinguish between class instantiations and function calls. As far as it's concerned, both are simply places where an API graph node is called. @@ -134,8 +124,6 @@ all subclasses of ``View``, you must explicitly include the subclasses of ``Meth select viewClass().getAUse() -➤ `See this in the query console on LGTM.com `__. - Note the use of the set literal ``["View", "MethodView"]`` to match both classes simultaneously. Built-in functions and classes From a407f0a4ac34b32728de5884b6c7f9f9be7c6192 Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Thu, 24 Nov 2022 13:25:50 +0000 Subject: [PATCH 603/796] Update main C/C++ articles --- docs/codeql/codeql-language-guides/codeql-for-cpp.rst | 2 +- .../conversions-and-classes-in-cpp.rst | 10 +--------- .../expressions-types-and-statements-in-cpp.rst | 10 +--------- .../codeql/codeql-language-guides/functions-in-cpp.rst | 10 ++-------- .../refining-a-query-to-account-for-edge-cases.rst | 2 -- 5 files changed, 5 insertions(+), 29 deletions(-) diff --git a/docs/codeql/codeql-language-guides/codeql-for-cpp.rst b/docs/codeql/codeql-language-guides/codeql-for-cpp.rst index 8acd450ecd7..4e5e53d8cb2 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-cpp.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-cpp.rst @@ -21,7 +21,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat hash-consing-and-value-numbering -- :doc:`Basic query for C and C++ code `: Learn to write and run a simple CodeQL query using LGTM. +- :doc:`Basic query for C and C++ code `: Learn to write and run a simple CodeQL query. - :doc:`CodeQL library for C and C++ `: When analyzing C or C++ code, you can use the large collection of classes in the CodeQL library for C and C++. diff --git a/docs/codeql/codeql-language-guides/conversions-and-classes-in-cpp.rst b/docs/codeql/codeql-language-guides/conversions-and-classes-in-cpp.rst index 9bd057412f6..0ceacc3acd9 100644 --- a/docs/codeql/codeql-language-guides/conversions-and-classes-in-cpp.rst +++ b/docs/codeql/codeql-language-guides/conversions-and-classes-in-cpp.rst @@ -165,8 +165,6 @@ Our starting point for the query is pairs of a base class and a derived class, c where derived.getABaseClass+() = base select base, derived, "The second class is derived from the first." -➤ `See this in the query console on LGTM.com `__ - Note that the transitive closure symbol ``+`` indicates that ``Class.getABaseClass()`` may be followed one or more times, rather than only accepting a direct base class. A lot of the results are uninteresting template parameters. You can remove those results by updating the ``where`` clause as follows: @@ -177,8 +175,6 @@ A lot of the results are uninteresting template parameters. You can remove those and not exists(base.getATemplateArgument()) and not exists(derived.getATemplateArgument()) -➤ `See this in the query console on LGTM.com `__ - Finding derived classes with destructors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -196,8 +192,6 @@ Now we can extend the query to find derived classes with destructors, using the and d2 = derived.getDestructor() select base, derived, "The second class is derived from the first, and both have a destructor." -➤ `See this in the query console on LGTM.com `__ - Notice that getting the destructor implicitly asserts that one exists. As a result, this version of the query returns fewer results than before. Finding base classes where the destructor is not virtual @@ -216,11 +210,9 @@ Our last change is to use ``Function.isVirtual()`` to find cases where the base and not d1.isVirtual() select d1, "This destructor should probably be virtual." -➤ `See this in the query console on LGTM.com `__ - That completes the query. -There is a similar built-in `query `__ on LGTM.com that finds classes in a C/C++ project with virtual functions but no virtual destructor. You can take a look at the code for this query by clicking **Open in query console** at the top of that page. +There is a similar standard query `Non-virtual destructor in base class `__ that finds classes in a C/C++ project with virtual functions but no virtual destructor. Further reading --------------- diff --git a/docs/codeql/codeql-language-guides/expressions-types-and-statements-in-cpp.rst b/docs/codeql/codeql-language-guides/expressions-types-and-statements-in-cpp.rst index d7adc22c2cd..c9515aca4c8 100644 --- a/docs/codeql/codeql-language-guides/expressions-types-and-statements-in-cpp.rst +++ b/docs/codeql/codeql-language-guides/expressions-types-and-statements-in-cpp.rst @@ -23,8 +23,6 @@ In the following example we find instances of ``AssignExpr`` which assign the co where e.getRValue().getValue().toInt() = 0 select e, "Assigning the value 0 to something." -➤ `See this in the query console on LGTM.com `__ - The ``where`` clause in this example gets the expression on the right side of the assignment, ``getRValue()``, and compares it with zero. Notice that there are no checks to make sure that the right side of the assignment is an integer or that it has a value (that is, it is compile-time constant, rather than a variable). For expressions where either of these assumptions is wrong, the associated predicate simply does not return anything and the ``where`` clause will not produce a result. You could think of it as if there is an implicit ``exists(e.getRValue().getValue().toInt())`` at the beginning of this line. It is also worth noting that the query above would find this C code: @@ -33,7 +31,7 @@ It is also worth noting that the query above would find this C code: yPtr = NULL; -This is because the database contains a representation of the code base after the preprocessor transforms have run. This means that any macro invocations, such as the ``NULL`` define used here, are expanded during the creation of the database. If you want to write queries about macros then there are some special library classes that have been designed specifically for this purpose (for example, the ``Macro``, ``MacroInvocation`` classes and predicates like ``Element.isInMacroExpansion()``). In this case, it is good that macros are expanded, but we do not want to find assignments to pointers. For more information, see `Database generation `__ on LGTM.com. +This is because the database contains a representation of the code base after the preprocessor transforms have run. This means that any macro invocations, such as the ``NULL`` define used here, are expanded during the creation of the database. If you want to write queries about macros then there are some special library classes that have been designed specifically for this purpose (for example, the ``Macro``, ``MacroInvocation`` classes and predicates like ``Element.isInMacroExpansion()``). In this case, it is good that macros are expanded, but we do not want to find assignments to pointers. For more information, see `Database creation `__. Finding assignments of 0 to an integer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -49,8 +47,6 @@ We can make the query more specific by defining a condition for the left side of and e.getLValue().getType().getUnspecifiedType() instanceof IntegralType select e, "Assigning the value 0 to an integer." -➤ `See this in the query console on LGTM.com `__ - This checks that the left side of the assignment has a type that is some kind of integer. Note the call to ``Type.getUnspecifiedType()``. This resolves ``typedef`` types to their underlying types so that the query finds assignments like this one: .. code-block:: cpp @@ -109,8 +105,6 @@ Unfortunately this would not quite work, because the loop initialization is actu and e.getLValue().getType().getUnspecifiedType() instanceof IntegralType select e, "Assigning the value 0 to an integer, inside a for loop initialization." -➤ `See this in the query console on LGTM.com `__ - Finding assignments of 0 within the loop body ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -127,8 +121,6 @@ We can find assignments inside the loop body using similar code with the predica and e.getLValue().getType().getUnderlyingType() instanceof IntegralType select e, "Assigning the value 0 to an integer, inside a for loop body." -➤ `See this in the query console on LGTM.com `__ - Note that we replaced ``e.getEnclosingStmt()`` with ``e.getEnclosingStmt().getParentStmt*()``, to find an assignment expression that is deeply nested inside the loop body. The transitive closure modifier ``*`` here indicates that ``Stmt.getParentStmt()`` may be followed zero or more times, rather than just once, giving us the statement, its parent statement, its parent's parent statement etc. Further reading diff --git a/docs/codeql/codeql-language-guides/functions-in-cpp.rst b/docs/codeql/codeql-language-guides/functions-in-cpp.rst index 84d72e5376a..574b11a33f3 100644 --- a/docs/codeql/codeql-language-guides/functions-in-cpp.rst +++ b/docs/codeql/codeql-language-guides/functions-in-cpp.rst @@ -40,8 +40,6 @@ It might be more interesting to find functions that are not called, using the st where not exists(FunctionCall fc | fc.getTarget() = f) select f, "This function is never called." -➤ `See this in the query console on LGTM.com `__ - The new query finds functions that are not the target of any ``FunctionCall``—in other words, functions that are never called. You may be surprised by how many results the query finds. However, if you examine the results, you can see that many of the functions it finds are used indirectly. To create a query that finds only unused functions, we need to refine the query and exclude other ways of using a function. Excluding functions that are referenced with a function pointer @@ -58,11 +56,9 @@ You can modify the query to remove functions where a function pointer is used to and not exists(FunctionAccess fa | fa.getTarget() = f) select f, "This function is never called, or referenced with a function pointer." -➤ `See this in the query console on LGTM.com `__ - This query returns fewer results. However, if you examine the results then you can probably still find potential refinements. -For example, there is a more complicated LGTM `query `__ that finds unused static functions. To see the code for this query, click **Open in query console** at the top of the page. +For example, there is a more complicated standard query, `Unused static function `__, that finds unused static functions. You can explore the definition of an element in the standard libraries and see what predicates are available. Use the keyboard **F3** button to open the definition of any element. Alternatively, hover over the element and click **Jump to definition** in the tooltip displayed. The library file is opened in a new tab with the definition highlighted. @@ -80,8 +76,6 @@ This query uses ``Function`` and ``FunctionCall`` to find calls to the function and not fc.getArgument(1) instanceof StringLiteral select fc, "sprintf called with variable format string." -➤ `See this in the query console on LGTM.com `__ - This uses: - ``Declaration.getQualifiedName()`` to identify calls to the specific function ``sprintf``. @@ -89,7 +83,7 @@ This uses: Note that we could have used ``Declaration.getName()``, but ``Declaration.getQualifiedName()`` is a better choice because it includes the namespace. For example: ``getName()`` would return ``vector`` where ``getQualifiedName`` would return ``std::vector``. -The LGTM version of this query is considerably more complicated, but if you look carefully you will find that its structure is the same. See `Non-constant format string `__ and click **Open in query console** at the top of the page. +The published version of this query is considerably more complicated, but if you look carefully you will find that its structure is the same. See `Non-constant format string `__. Further reading --------------- diff --git a/docs/codeql/codeql-language-guides/refining-a-query-to-account-for-edge-cases.rst b/docs/codeql/codeql-language-guides/refining-a-query-to-account-for-edge-cases.rst index d2a6cee326a..049dc95ad9b 100644 --- a/docs/codeql/codeql-language-guides/refining-a-query-to-account-for-edge-cases.rst +++ b/docs/codeql/codeql-language-guides/refining-a-query-to-account-for-edge-cases.rst @@ -146,8 +146,6 @@ Finally we can simplify the query by using the transitive closure operator. In t and exists(c.getBlock()) select c, "Constructor does not initialize fields $@.", f, f.getName() -➤ `See this in the query console on LGTM.com `__ - Further reading --------------- From 0ac0277639dc4c89c004ab567e9b2aa929d409d8 Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Thu, 24 Nov 2022 13:43:57 +0000 Subject: [PATCH 604/796] Minor change to C# article --- docs/codeql/codeql-language-guides/codeql-for-csharp.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/codeql-for-csharp.rst b/docs/codeql/codeql-language-guides/codeql-for-csharp.rst index e327cb177ee..9b692094841 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-csharp.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-csharp.rst @@ -12,7 +12,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat codeql-library-for-csharp analyzing-data-flow-in-csharp -- :doc:`Basic query for C# code `: Learn to write and run a simple CodeQL query using LGTM. +- :doc:`Basic query for C# code `: Learn to write and run a simple CodeQL query. - :doc:`CodeQL library for C# `: When you're analyzing a C# program, you can make use of the large collection of classes in the CodeQL library for C#. From b22ccc114eed793234ea03302289e23df61de0f3 Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Thu, 24 Nov 2022 13:47:14 +0000 Subject: [PATCH 605/796] Minor changes to Go and Ruby article --- docs/codeql/codeql-language-guides/codeql-for-go.rst | 2 +- docs/codeql/codeql-language-guides/codeql-for-ruby.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/codeql/codeql-language-guides/codeql-for-go.rst b/docs/codeql/codeql-language-guides/codeql-for-go.rst index be81a19f1a8..0eaefbb5922 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-go.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-go.rst @@ -13,7 +13,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat abstract-syntax-tree-classes-for-working-with-go-programs modeling-data-flow-in-go-libraries -- :doc:`Basic query for Go code `: Learn to write and run a simple CodeQL query using LGTM. +- :doc:`Basic query for Go code `: Learn to write and run a simple CodeQL query. - :doc:`CodeQL library for Go `: When you're analyzing a Go program, you can make use of the large collection of classes in the CodeQL library for Go. diff --git a/docs/codeql/codeql-language-guides/codeql-for-ruby.rst b/docs/codeql/codeql-language-guides/codeql-for-ruby.rst index 82d13cf410e..f36df2496bf 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-ruby.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-ruby.rst @@ -14,7 +14,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat analyzing-data-flow-in-ruby using-api-graphs-in-ruby -- :doc:`Basic query for Ruby code `: Learn to write and run a simple CodeQL query using LGTM. +- :doc:`Basic query for Ruby code `: Learn to write and run a simple CodeQL query. - :doc:`CodeQL library for Ruby `: When you're analyzing a Ruby program, you can make use of the large collection of classes in the CodeQL library for Ruby. From 8ec06d45e06a09ea48f7297914e2c4280cbb6683 Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Fri, 25 Nov 2022 08:42:09 +0000 Subject: [PATCH 606/796] Replace LGTM description with VS Code --- docs/codeql/codeql-language-guides/functions-in-cpp.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/functions-in-cpp.rst b/docs/codeql/codeql-language-guides/functions-in-cpp.rst index 574b11a33f3..b6f3e26db50 100644 --- a/docs/codeql/codeql-language-guides/functions-in-cpp.rst +++ b/docs/codeql/codeql-language-guides/functions-in-cpp.rst @@ -60,7 +60,7 @@ This query returns fewer results. However, if you examine the results then you c For example, there is a more complicated standard query, `Unused static function `__, that finds unused static functions. - You can explore the definition of an element in the standard libraries and see what predicates are available. Use the keyboard **F3** button to open the definition of any element. Alternatively, hover over the element and click **Jump to definition** in the tooltip displayed. The library file is opened in a new tab with the definition highlighted. + You can explore the definition of an element in the standard libraries and see what predicates are available. Highlight the element, right-click to display the context menu, and click **Go to Definition**. The library file is opened in a new tab with the definition of the element highlighted. Finding a specific function --------------------------- From 85961f5dce3331b075de5e09cc95ed75922088e3 Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Mon, 28 Nov 2022 12:41:26 +0000 Subject: [PATCH 607/796] Update docs/codeql/codeql-language-guides/functions-in-cpp.rst --- docs/codeql/codeql-language-guides/functions-in-cpp.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/functions-in-cpp.rst b/docs/codeql/codeql-language-guides/functions-in-cpp.rst index b6f3e26db50..34c99885c6a 100644 --- a/docs/codeql/codeql-language-guides/functions-in-cpp.rst +++ b/docs/codeql/codeql-language-guides/functions-in-cpp.rst @@ -60,7 +60,7 @@ This query returns fewer results. However, if you examine the results then you c For example, there is a more complicated standard query, `Unused static function `__, that finds unused static functions. - You can explore the definition of an element in the standard libraries and see what predicates are available. Highlight the element, right-click to display the context menu, and click **Go to Definition**. The library file is opened in a new tab with the definition of the element highlighted. + You can explore the definition of an element in the standard libraries and see what predicates are available. Right-click the element to display the context menu, and click **Go to Definition**. The library file is opened in a new tab with the definition of the element highlighted. Finding a specific function --------------------------- From a9b6a1231725935af4f0f4e1d9aee50912a6187b Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Thu, 24 Nov 2022 14:06:55 +0000 Subject: [PATCH 608/796] Updates for Java articles --- .../annotations-in-java.rst | 8 +-- .../codeql-for-java.rst | 2 +- .../codeql-library-for-java.rst | 32 +++------- .../codeql/codeql-language-guides/javadoc.rst | 4 +- .../overflow-prone-comparisons-in-java.rst | 46 ++++++++++++--- .../codeql-language-guides/types-in-java.rst | 59 ++++++++++++++----- 6 files changed, 94 insertions(+), 57 deletions(-) diff --git a/docs/codeql/codeql-language-guides/annotations-in-java.rst b/docs/codeql/codeql-language-guides/annotations-in-java.rst index 3439fb6ff0e..38f30e238f0 100644 --- a/docs/codeql/codeql-language-guides/annotations-in-java.rst +++ b/docs/codeql/codeql-language-guides/annotations-in-java.rst @@ -51,7 +51,7 @@ We could then write this query to find all ``@SuppressWarnings`` annotations att anntp.hasQualifiedName("java.lang", "SuppressWarnings") select ann, ann.getValue("value") -➤ `See the full query in the query console on LGTM.com `__. Several of the LGTM.com demo projects use the ``@SuppressWarnings`` annotation. Looking at the ``value``\ s of the annotation element returned by the query, we can see that the *apache/activemq* project uses the ``"rawtypes"`` value described above. +If the codebase you are analyzing uses the ``@SuppressWarnings`` annotation, you can check the ``value``\ s of the annotation element returned by the query. They should use the ``"rawtypes"`` value described above. As another example, this query finds all annotation types that only have a single annotation element, which has name ``value``: @@ -66,8 +66,6 @@ As another example, this query finds all annotation types that only have a singl ) select anntp -➤ `See the full query in the query console on LGTM.com `__. - Example: Finding missing ``@Override`` annotations -------------------------------------------------- @@ -124,7 +122,7 @@ This makes it very easy to write our query for finding methods that override ano not overriding.getAnAnnotation() instanceof OverrideAnnotation select overriding, "Method overrides another method, but does not have an @Override annotation." -➤ `See this in the query console on LGTM.com `__. In practice, this query may yield many results from compiled library code, which aren't very interesting. It's therefore a good idea to add another conjunct ``overriding.fromSource()`` to restrict the result to only report methods for which source code is available. +In practice, this query may yield many results from compiled library code, which aren't very interesting. It's therefore a good idea to add another conjunct ``overriding.fromSource()`` to restrict the result to only report methods for which source code is available. Example: Finding calls to deprecated methods -------------------------------------------- @@ -237,7 +235,7 @@ Now we can extend our query to filter out calls in methods carrying a ``Suppress and not call.getCaller().getAnAnnotation() instanceof SuppressDeprecationWarningAnnotation select call, "This call invokes a deprecated method." -➤ `See this in the query console on LGTM.com `__. It's fairly common for projects to contain calls to methods that appear to be deprecated. +It's fairly common for projects to contain calls to methods that appear to be deprecated. Further reading --------------- diff --git a/docs/codeql/codeql-language-guides/codeql-for-java.rst b/docs/codeql/codeql-language-guides/codeql-for-java.rst index 392ef19c8b2..aa10f481592 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-java.rst @@ -26,7 +26,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat working-with-source-locations abstract-syntax-tree-classes-for-working-with-java-programs -- :doc:`Basic query for Java code `: Learn to write and run a simple CodeQL query using LGTM. +- :doc:`Basic query for Java code `: Learn to write and run a simple CodeQL query. - :doc:`CodeQL library for Java `: When analyzing Java code, you can use the large collection of classes in the CodeQL library for Java. diff --git a/docs/codeql/codeql-language-guides/codeql-library-for-java.rst b/docs/codeql/codeql-language-guides/codeql-library-for-java.rst index c4072ad55b2..c4bbc67d319 100644 --- a/docs/codeql/codeql-language-guides/codeql-library-for-java.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-java.rst @@ -70,7 +70,7 @@ For example, the following query finds all variables of type ``int`` in the prog pt.hasName("int") select v -➤ `See this in the query console on LGTM.com `__. You're likely to get many results when you run this query because most projects contain many variables of type ``int``. +You're likely to get many results when you run this query because most projects contain many variables of type ``int``. Reference types are also categorized according to their declaration scope: @@ -87,7 +87,7 @@ For instance, this query finds all top-level types whose name is not the same as where tl.getName() != tl.getCompilationUnit().getName() select tl -➤ `See this in the query console on LGTM.com `__. This pattern is seen in many projects. When we ran it on the LGTM.com demo projects, most of the projects had at least one instance of this problem in the source code. There were many more instances in the files referenced by the source code. +You will typically see this pattern in the source code of a repository, with many more instances in the files referenced by the source code. Several more specialized classes are available as well: @@ -109,7 +109,7 @@ As an example, we can write a query that finds all nested classes that directly where nc.getASupertype() instanceof TypeObject select nc -➤ `See this in the query console on LGTM.com `__. You're likely to get many results when you run this query because many projects include nested classes that extend ``Object`` directly. +You're likely to get many results when you run this query because many projects include nested classes that extend ``Object`` directly. Generics ~~~~~~~~ @@ -143,8 +143,6 @@ For instance, we could use the following query to find all parameterized instanc pt.getSourceDeclaration() = map select pt -➤ `See this in the query console on LGTM.com `__. None of the LGTM.com demo projects contain parameterized instances of ``java.util.Map`` in their source code, but they all have results in reference files. - In general, generic types may restrict which types a type parameter can be bound to. For instance, a type of maps from strings to numbers could be declared as follows: .. code-block:: java @@ -166,8 +164,6 @@ As an example, the following query finds all type variables with type bound ``Nu tb.getType().hasQualifiedName("java.lang", "Number") select tv -➤ `See this in the query console on LGTM.com `__. When we ran it on the LGTM.com demo projects, the *neo4j/neo4j*, *hibernate/hibernate-orm* and *apache/hadoop* projects all contained examples of this pattern. - For dealing with legacy code that is unaware of generics, every generic type has a "raw" version without any type parameters. In the CodeQL libraries, raw types are represented using class ``RawType``, which has the expected subclasses ``RawClass`` and ``RawInterface``. Again, there is a predicate ``getSourceDeclaration`` for obtaining the corresponding generic type. As an example, we can find variables of (raw) type ``Map``: .. code-block:: ql @@ -179,8 +175,6 @@ For dealing with legacy code that is unaware of generics, every generic type has rt.getSourceDeclaration().hasQualifiedName("java.util", "Map") select v -➤ `See this in the query console on LGTM.com `__. Many projects have variables of raw type ``Map``. - For example, in the following code snippet this query would find ``m1``, but not ``m2``: .. code-block:: java @@ -230,7 +224,7 @@ For example, the following query finds all expressions whose parents are ``retur where e.getParent() instanceof ReturnStmt select e -➤ `See this in the query console on LGTM.com `__. Many projects have examples of ``return`` statements with child expressions. +Many projects have examples of ``return`` statements with child expressions. Therefore, if the program contains a return statement ``return x + y;``, this query will return ``x + y``. @@ -244,7 +238,7 @@ As another example, the following query finds statements whose parent is an ``if where s.getParent() instanceof IfStmt select s -➤ `See this in the query console on LGTM.com `__. Many projects have examples of ``if`` statements with child statements. +Many projects have examples of ``if`` statements with child statements. This query will find both ``then`` branches and ``else`` branches of all ``if`` statements in the program. @@ -258,8 +252,6 @@ Finally, here is a query that finds method bodies: where s.getParent() instanceof Method select s -➤ `See this in the query console on LGTM.com `__. Most projects have many method bodies. - As these examples show, the parent node of an expression is not always an expression: it may also be a statement, for example, an ``IfStmt``. Similarly, the parent node of a statement is not always a statement: it may also be a method or a constructor. To capture this, the QL Java library provides two abstract class ``ExprParent`` and ``StmtParent``, the former representing any node that may be the parent node of an expression, and the latter any node that may be the parent node of a statement. For more information on working with AST classes, see the :doc:`article on overflow-prone comparisons in Java `. @@ -278,7 +270,7 @@ For annotations, class ``Annotatable`` is a superclass of all program elements t from Constructor c select c.getAnAnnotation() -➤ `See this in the query console on LGTM.com `__. The LGTM.com demo projects all use annotations, you can see examples where they are used to suppress warnings and mark code as deprecated. +You may see examples where annottions are used to suppress warnings or to mark code as deprecated. These annotations are represented by class ``Annotation``. An annotation is simply an expression whose type is an ``AnnotationType``. For example, you can amend this query so that it only reports deprecated constructors: @@ -292,7 +284,7 @@ These annotations are represented by class ``Annotation``. An annotation is simp anntp.hasQualifiedName("java.lang", "Deprecated") select ann -➤ `See this in the query console on LGTM.com `__. Only constructors with the ``@Deprecated`` annotation are reported this time. +Only constructors with the ``@Deprecated`` annotation are reported this time. For more information on working with annotations, see the :doc:`article on annotations `. @@ -307,8 +299,6 @@ For Javadoc, class ``Element`` has a member predicate ``getDoc`` that returns a jdoc = f.getDoc().getJavadoc() select jdoc -➤ `See this in the query console on LGTM.com `__. You can see this pattern in many projects. - Class ``Javadoc`` represents an entire Javadoc comment as a tree of ``JavadocElement`` nodes, which can be traversed using member predicates ``getAChild`` and ``getParent``. For instance, you could edit the query so that it finds all ``@author`` tags in Javadoc comments on private fields: .. code-block:: ql @@ -321,8 +311,6 @@ Class ``Javadoc`` represents an entire Javadoc comment as a tree of ``JavadocEle at.getParent+() = jdoc select at -➤ `See this in the query console on LGTM.com `__. None of the LGTM.com demo projects uses the ``@author`` tag on private fields. - .. pull-quote:: Note @@ -349,7 +337,7 @@ For example, the following query finds methods with a `cyclomatic complexity 40 select m -➤ `See this in the query console on LGTM.com `__. Most large projects include some methods with a very high cyclomatic complexity. These methods are likely to be difficult to understand and test. +Most large projects include some methods with a very high cyclomatic complexity. These methods are likely to be difficult to understand and test. Call graph ---------- @@ -369,8 +357,6 @@ We can use predicate ``Call.getCallee`` to find out which method or constructor m.hasName("println") select c -➤ `See this in the query console on LGTM.com `__. The LGTM.com demo projects all include many calls to methods of this name. - Conversely, ``Callable.getAReference`` returns a ``Call`` that refers to it. So we can find methods and constructors that are never called using this query: .. code-block:: ql @@ -381,7 +367,7 @@ Conversely, ``Callable.getAReference`` returns a ``Call`` that refers to it. So where not exists(c.getAReference()) select c -➤ `See this in the query console on LGTM.com `__. The LGTM.com demo projects all appear to have many methods that are not called directly, but this is unlikely to be the whole story. To explore this area further, see ":doc:`Navigating the call graph `." +Codebases often have many methods that are not called direcstly, but this is unlikely to be the whole story. To explore this area further, see ":doc:`Navigating the call graph `." For more information about callables and calls, see the :doc:`article on the call graph `. diff --git a/docs/codeql/codeql-language-guides/javadoc.rst b/docs/codeql/codeql-language-guides/javadoc.rst index 7e16cc6ce36..c1bce79a0a2 100644 --- a/docs/codeql/codeql-language-guides/javadoc.rst +++ b/docs/codeql/codeql-language-guides/javadoc.rst @@ -149,8 +149,6 @@ Now we can write a query for finding all callables ``c`` and ``@throws`` tags `` not mayThrow(c, exn) select tt, "Spurious @throws tag." -➤ `See this in the query console on LGTM.com `__. This finds several results in the LGTM.com demo projects. - Improvements ~~~~~~~~~~~~ @@ -216,7 +214,7 @@ The first case can be covered by changing ``getDocumentedException`` to use the (result.hasName(tt.getExceptionName()) and visibleIn(tt.getFile(), result)) } -➤ `See this in the query console on LGTM.com `__. This finds many fewer, more interesting results in the LGTM.com demo projects. +This query should find many fewer, more interesting results. Currently, ``visibleIn`` only considers single-type imports, but you could extend it with support for other kinds of imports. diff --git a/docs/codeql/codeql-language-guides/overflow-prone-comparisons-in-java.rst b/docs/codeql/codeql-language-guides/overflow-prone-comparisons-in-java.rst index b0762a5c139..53c36c7f786 100644 --- a/docs/codeql/codeql-language-guides/overflow-prone-comparisons-in-java.rst +++ b/docs/codeql/codeql-language-guides/overflow-prone-comparisons-in-java.rst @@ -44,7 +44,7 @@ We'll start by writing a query that finds less-than expressions (CodeQL class `` expr.getRightOperand().getType().hasName("long") select expr -➤ `See this in the query console on LGTM.com `__. This query usually finds results on most projects. +This query usually finds results on most codebases. Notice that we use the predicate ``getType`` (available on all subclasses of ``Expr``) to determine the type of the operands. Types, in turn, define the ``hasName`` predicate, which allows us to identify the primitive types ``int`` and ``long``. As it stands, this query finds *all* less-than expressions comparing ``int`` and ``long``, but in fact we are only interested in comparisons that are part of a loop condition. Also, we want to filter out comparisons where either operand is constant, since these are less likely to be real bugs. The revised query looks like this: @@ -59,7 +59,7 @@ Notice that we use the predicate ``getType`` (available on all subclasses of ``E not expr.getAnOperand().isCompileTimeConstant() select expr -➤ `See this in the query console on LGTM.com `__. Notice that fewer results are found. +Notice that fewer results are found. The class ``LoopStmt`` is a common superclass of all loops, including, in particular, ``for`` loops as in our example above. While different kinds of loops have different syntax, they all have a loop condition, which can be accessed through predicate ``getCondition``. We use the reflexive transitive closure operator ``*`` applied to the ``getAChildExpr`` predicate to express the requirement that ``expr`` should be nested inside the loop condition. In particular, it can be the loop condition itself. @@ -113,16 +113,44 @@ Now we rewrite our query to make use of these new classes: .. code-block:: ql - import Java + import java - // Insert the class definitions from above + // Return the width (in bits) of a given integral type + int width(PrimitiveType pt) { + (pt.hasName("byte") and result=8) or + (pt.hasName("short") and result=16) or + (pt.hasName("char") and result=16) or + (pt.hasName("int") and result=32) or + (pt.hasName("long") and result=64) + } - from OverflowProneComparison expr - where exists(LoopStmt l | l.getCondition().getAChildExpr*() = expr) and - not expr.getAnOperand().isCompileTimeConstant() - select expr + // Find any comparison where the width of the type on the smaller end of + // the comparison is less than the width of the type on the greater end + abstract class OverflowProneComparison extends ComparisonExpr { + Expr getLesserOperand() { none() } + Expr getGreaterOperand() { none() } + } -➤ `See the full query in the query console on LGTM.com `__. + // Return `<=` and `<` comparisons + class LTOverflowProneComparison extends OverflowProneComparison { + LTOverflowProneComparison() { + (this instanceof LEExpr or this instanceof LTExpr) and + width(this.getLeftOperand().getType()) < width(this.getRightOperand().getType()) + } + } + + // Return `>=` and `>` comparisons + class GTOverflowProneComparison extends OverflowProneComparison { + GTOverflowProneComparison() { + (this instanceof GEExpr or this instanceof GTExpr) and + width(this.getRightOperand().getType()) < width(this.getLeftOperand().getType()) + } + } + + from OverflowProneComparison expr + where exists(LoopStmt l | l.getCondition().getAChildExpr*() = expr) and + not expr.getAnOperand().isCompileTimeConstant() + select expr Further reading --------------- diff --git a/docs/codeql/codeql-language-guides/types-in-java.rst b/docs/codeql/codeql-language-guides/types-in-java.rst index 04cc716b961..e7dc5113294 100644 --- a/docs/codeql/codeql-language-guides/types-in-java.rst +++ b/docs/codeql/codeql-language-guides/types-in-java.rst @@ -34,7 +34,7 @@ To determine ancestor types (including immediate super types, and also *their* s where B.hasName("B") select B.getASupertype+() -➤ `See this in the query console on LGTM.com `__. If this query were run on the example snippet above, the query would return ``A``, ``I``, and ``java.lang.Object``. +If we ran this query on the example snippet above, the query would return ``A``, ``I``, and ``java.lang.Object``. .. pull-quote:: @@ -80,8 +80,6 @@ This recipe is not too difficult to translate into a query: target.getElementType().(RefType).getASupertype+() = source.getElementType() select ce, "Potentially problematic array downcast." -➤ `See this in the query console on LGTM.com `__. Many projects return results for this query. - Note that by casting ``target.getElementType()`` to a ``RefType``, we eliminate all cases where the element type is a primitive type, that is, ``target`` is an array of primitive type: the problem we are looking for cannot arise in that case. Unlike in Java, a cast in QL never fails: if an expression cannot be cast to the desired type, it is simply excluded from the query results, which is exactly what we want. Improvements @@ -143,7 +141,7 @@ Using these new classes we can extend our query to exclude calls to ``toArray`` not ce.getExpr().(CollectionToArrayCall).getActualReturnType() = target select ce, "Potentially problematic array downcast." -➤ `See this in the query console on LGTM.com `__. Notice that fewer results are found by this improved query. +Notice that fewer results are found by this improved query. Example: Finding mismatched contains checks ------------------------------------------- @@ -269,8 +267,6 @@ Now we are ready to write a first version of our query: not haveCommonDescendant(collEltType, argType) select juccc, "Element type " + collEltType + " is incompatible with argument type " + argType -➤ `See this in the query console on LGTM.com `__. - Improvements ~~~~~~~~~~~~ @@ -284,19 +280,50 @@ Adding these three improvements, our final query becomes: .. code-block:: ql - import java + import java - // Insert the class definitions from above + class JavaUtilCollection extends GenericInterface { + JavaUtilCollection() { + this.hasQualifiedName("java.util", "Collection") + } + } - from JavaUtilCollectionContainsCall juccc, Type collEltType, Type argType - where collEltType = juccc.getCollectionElementType() and argType = juccc.getArgumentType() and - not haveCommonDescendant(collEltType, argType) and - not collEltType instanceof TypeVariable and not argType instanceof TypeVariable and - not collEltType = argType.(PrimitiveType).getBoxedType() and - not argType.hasName("") - select juccc, "Element type " + collEltType + " is incompatible with argument type " + argType + class JavaUtilCollectionContains extends Method { + JavaUtilCollectionContains() { + this.getDeclaringType() instanceof JavaUtilCollection and + this.hasStringSignature("contains(Object)") + } + } -➤ `See the full query in the query console on LGTM.com `__. + class JavaUtilCollectionContainsCall extends MethodAccess { + JavaUtilCollectionContainsCall() { + exists(JavaUtilCollectionContains jucc | + this.getMethod().getSourceDeclaration().overrides*(jucc) + ) + } + Type getArgumentType() { + result = this.getArgument(0).getType() + } + Type getCollectionElementType() { + exists(RefType D, ParameterizedInterface S | + D = this.getMethod().getDeclaringType() and + D.hasSupertype*(S) and S.getSourceDeclaration() instanceof JavaUtilCollection and + result = S.getTypeArgument(0) + ) + } + } + + predicate haveCommonDescendant(RefType tp1, RefType tp2) { + exists(RefType commondesc | commondesc.hasSupertype*(tp1) and commondesc.hasSupertype*(tp2)) + } + + from JavaUtilCollectionContainsCall juccc, Type collEltType, Type argType + where collEltType = juccc.getCollectionElementType() and argType = juccc.getArgumentType() and + not haveCommonDescendant(collEltType, argType) and + not collEltType instanceof TypeVariable and not argType instanceof TypeVariable and + not collEltType = argType.(PrimitiveType).getBoxedType() and + not argType.hasName("") + select juccc, "Element type " + collEltType + " is incompatible with argument type " + argType Further reading --------------- From d6ae5c898ab2778d58c85ccc289400546f2b7566 Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Fri, 25 Nov 2022 08:32:58 +0000 Subject: [PATCH 609/796] Respond to review feedback --- docs/codeql/codeql-language-guides/codeql-library-for-java.rst | 2 ++ docs/codeql/codeql-language-guides/types-in-java.rst | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docs/codeql/codeql-language-guides/codeql-library-for-java.rst b/docs/codeql/codeql-language-guides/codeql-library-for-java.rst index c4bbc67d319..d6b021bb81e 100644 --- a/docs/codeql/codeql-language-guides/codeql-library-for-java.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-java.rst @@ -299,6 +299,8 @@ For Javadoc, class ``Element`` has a member predicate ``getDoc`` that returns a jdoc = f.getDoc().getJavadoc() select jdoc +You can see this pattern in many projects. + Class ``Javadoc`` represents an entire Javadoc comment as a tree of ``JavadocElement`` nodes, which can be traversed using member predicates ``getAChild`` and ``getParent``. For instance, you could edit the query so that it finds all ``@author`` tags in Javadoc comments on private fields: .. code-block:: ql diff --git a/docs/codeql/codeql-language-guides/types-in-java.rst b/docs/codeql/codeql-language-guides/types-in-java.rst index e7dc5113294..3bb1c59fed7 100644 --- a/docs/codeql/codeql-language-guides/types-in-java.rst +++ b/docs/codeql/codeql-language-guides/types-in-java.rst @@ -80,6 +80,8 @@ This recipe is not too difficult to translate into a query: target.getElementType().(RefType).getASupertype+() = source.getElementType() select ce, "Potentially problematic array downcast." +Many projects return results for this query. + Note that by casting ``target.getElementType()`` to a ``RefType``, we eliminate all cases where the element type is a primitive type, that is, ``target`` is an array of primitive type: the problem we are looking for cannot arise in that case. Unlike in Java, a cast in QL never fails: if an expression cannot be cast to the desired type, it is simply excluded from the query results, which is exactly what we want. Improvements From 33ae086861c2965d65fa64e0f93f2da5098b40bd Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Fri, 25 Nov 2022 08:27:34 +0000 Subject: [PATCH 610/796] Apply suggestions from code review Co-authored-by: Tony Torralba --- .../codeql/codeql-language-guides/codeql-library-for-java.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/codeql/codeql-language-guides/codeql-library-for-java.rst b/docs/codeql/codeql-language-guides/codeql-library-for-java.rst index d6b021bb81e..319afdf29c0 100644 --- a/docs/codeql/codeql-language-guides/codeql-library-for-java.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-java.rst @@ -270,7 +270,7 @@ For annotations, class ``Annotatable`` is a superclass of all program elements t from Constructor c select c.getAnAnnotation() -You may see examples where annottions are used to suppress warnings or to mark code as deprecated. +You may see examples where annotations are used to suppress warnings or to mark code as deprecated. These annotations are represented by class ``Annotation``. An annotation is simply an expression whose type is an ``AnnotationType``. For example, you can amend this query so that it only reports deprecated constructors: @@ -369,7 +369,7 @@ Conversely, ``Callable.getAReference`` returns a ``Call`` that refers to it. So where not exists(c.getAReference()) select c -Codebases often have many methods that are not called direcstly, but this is unlikely to be the whole story. To explore this area further, see ":doc:`Navigating the call graph `." +Codebases often have many methods that are not called directly, but this is unlikely to be the whole story. To explore this area further, see ":doc:`Navigating the call graph `." For more information about callables and calls, see the :doc:`article on the call graph `. From 179941daabf10a4d4f6be0e90f146bf091b6136d Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Thu, 24 Nov 2022 14:25:44 +0000 Subject: [PATCH 611/796] First set of updates for JavaScript articles --- .../codeql-for-javascript.rst | 2 +- .../codeql-library-for-javascript.rst | 36 ++++--------------- 2 files changed, 8 insertions(+), 30 deletions(-) diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst index ce6651acb79..11a4c5e456c 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst @@ -18,7 +18,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs data-flow-cheat-sheet-for-javascript -- :doc:`Basic query for JavaScript code `: Learn to write and run a simple CodeQL query using LGTM. +- :doc:`Basic query for JavaScript code `: Learn to write and run a simple CodeQL query. - :doc:`CodeQL library for JavaScript `: When you're analyzing a JavaScript program, you can make use of the large collection of classes in the CodeQL library for JavaScript. diff --git a/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst b/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst index e9070cc493b..0b3f8daedb1 100644 --- a/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst @@ -43,7 +43,7 @@ Textual level At its most basic level, a JavaScript code base can simply be viewed as a collection of files organized into folders, where each file is composed of zero or more lines of text. -Note that the textual content of a program is not included in the CodeQL database unless you specifically request it during extraction. In particular, databases on LGTM (also known as "snapshots") do not normally include textual information. +Note that the textual content of a program is not included in the CodeQL database unless you specifically request it during extraction. Files and folders ^^^^^^^^^^^^^^^^^ @@ -77,7 +77,7 @@ For example, the following query computes, for each folder, the number of JavaSc from Folder d select d.getRelativePath(), count(File f | f = d.getAFile() and f.getExtension() = "js") -➤ `See this in the query console on LGTM.com `__. When you run the query on most projects, the results include folders that contain files with a ``js`` extension and folders that don't. +When you run the query on most projects, the results include folders that contain files with a ``js`` extension and folders that don't. Locations ^^^^^^^^^ @@ -138,7 +138,7 @@ As an example of a query operating entirely on the lexical level, consider the f where comma.getNextToken() instanceof CommaToken select comma, "Omitted array elements are bad style." -➤ `See this in the query console on LGTM.com `__. If the query returns no results, this pattern isn't used in the projects that you analyzed. +If the query returns no results, this pattern isn't used in the projects that you analyzed. You can use predicate ``Locatable.getFirstToken()`` and ``Locatable.getLastToken()`` to access the first and last token (if any) belonging to an element with a source location. @@ -179,8 +179,6 @@ As an example of a query using only lexical information, consider the following from HtmlLineComment c select c, "Do not use HTML comments." -➤ `See this in the query console on LGTM.com `__. When we ran this query on the *mozilla/pdf.js* project in LGTM.com, we found three HTML comments. - Syntactic level ~~~~~~~~~~~~~~~ @@ -351,8 +349,6 @@ As an example of how to use expression AST nodes, here is a query that finds exp where add = shift.getAnOperand() select add, "This expression should be bracketed to clarify precedence rules." -➤ `See this in the query console on LGTM.com `__. When we ran this query on the *meteor/meteor* project in LGTM.com, we found many results where precedence could be clarified using brackets. - Functions ^^^^^^^^^ @@ -373,8 +369,6 @@ As an example, here is a query that finds all expression closures: where fe.getBody() instanceof Expr select fe, "Use arrow expressions instead of expression closures." -➤ `See this in the query console on LGTM.com `__. None of the LGTM.com demo projects uses expression closures, but you may find this query gets results on other projects. - As another example, this query finds functions that have two parameters that bind the same variable: .. code-block:: ql @@ -388,8 +382,6 @@ As another example, this query finds functions that have two parameters that bin p.getAVariable() = q.getAVariable() select fun, "This function has two parameters that bind the same variable." -➤ `See this in the query console on LGTM.com `__. None of the LGTM.com demo projects has functions where two parameters bind the same variable. - Classes ^^^^^^^ @@ -444,7 +436,7 @@ Here is an example of a query to find declaration statements that declare the sa not ds.getTopLevel().isMinified() select ds, "Variable " + v.getName() + " is declared both $@ and $@.", d1, "here", d2, "here" -➤ `See this in the query console on LGTM.com `__. This is not a common problem, so you may not find any results in your own projects. The *angular/angular.js* project on LGTM.com has one instance of this problem at the time of writing. +This is not a common problem, so you may not find any results in your own projects. Notice the use of ``not ... isMinified()`` here and in the next few queries. This excludes any results found in minified code. If you delete ``and not ds.getTopLevel().isMinified()`` and re-run the query, two results in minified code in the *meteor/meteor* project are reported. @@ -471,8 +463,6 @@ As an example of a query involving properties, consider the following query that not oe.getTopLevel().isMinified() select oe, "Property " + p1.getName() + " is defined both $@ and $@.", p1, "here", p2, "here" -➤ `See this in the query console on LGTM.com `__. Many projects have a few instances of object expressions with two identically named properties. - Modules ^^^^^^^ @@ -537,7 +527,7 @@ As an example, consider the following query which finds distinct function declar not g.getTopLevel().isMinified() select f, g -➤ `See this in the query console on LGTM.com `__. Some projects declare conflicting functions of the same name and rely on platform-specific behavior to disambiguate the two declarations. +Some projects declare conflicting functions of the same name and rely on platform-specific behavior to disambiguate the two declarations. Control flow ~~~~~~~~~~~~ @@ -574,7 +564,7 @@ As an example of an analysis using basic blocks, ``BasicBlock.isLiveAtEntry(v, u not f.getStartBB().isLiveAtEntry(gv, _) select f, "This function uses " + gv + " like a local variable." -➤ `See this in the query console on LGTM.com `__. Many projects have some variables which look as if they were intended to be local. +Many projects have some variables which look as if they were intended to be local. Data flow ~~~~~~~~~ @@ -599,8 +589,6 @@ As an example, the following query finds definitions of local variables that are not exists (VarUse use | def = use.getADef()) select def, "Dead store of local variable." -➤ `See this in the query console on LGTM.com `__. Many projects have some examples of useless assignments to local variables. - SSA ^^^ @@ -642,8 +630,6 @@ For example, here is a query that finds all invocations of a method called ``sen send.getMethodName() = "send" select send -➤ `See this in the query console on LGTM.com `__. The query finds HTTP response sends in the `AMP HTML `__ project. - Note that the data flow modeling in this library is intraprocedural, that is, flow across function calls and returns is *not* modeled. Likewise, flow through object properties and global variables is not modeled. Type inference @@ -707,8 +693,6 @@ As an example of a call-graph-based query, here is a query to find invocations f not exists(invk.getACallee()) select invk, "Unable to find a callee for this invocation." -➤ `See this in the query console on LGTM.com `__ - Inter-procedural data flow ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -843,7 +827,7 @@ As an example of the use of these classes, here is a query that counts for every from NodeModule m select m, count(m.getAnImportedModule()) -➤ `See this in the query console on LGTM.com `__. When you analyze a project, for each module you can see how many other modules it imports. +When you analyze a project, for each module you can see how many other modules it imports. NPM ^^^ @@ -872,8 +856,6 @@ As an example of the use of these classes, here is a query that identifies unuse not exists (Require req | req.getTopLevel() = pkg.getAModule() | name = req.getImportedPath().getValue()) select deps, "Unused dependency '" + name + "'." -➤ `See this in the query console on LGTM.com `__. It is not uncommon for projects to have some unused dependencies. - React ^^^^^ @@ -899,8 +881,6 @@ For example, here is a query to find SQL queries that use string concatenation ( where ss instanceof AddExpr select ss, "Use templating instead of string concatenation." -➤ `See this in the query console on LGTM.com `__, showing two (benign) results on `strong-arc `__. - Miscellaneous ~~~~~~~~~~~~~ @@ -965,8 +945,6 @@ As an example, here is a query that finds ``@param`` tags that do not specify th not exists(t.getName()) select t, "@param tag is missing name." -➤ `See this in the query console on LGTM.com `__. Of the LGTM.com demo projects analyzed, only *Semantic-Org/Semantic-UI* has an example where the ``@param`` tag omits the name. - For full details on these and other classes representing JSDoc comments and type expressions, see `the API documentation `__. JSX From 7e5a9fbe2e82b9e6c9a72794f3ba8a3c3dcc86f0 Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Mon, 28 Nov 2022 09:30:35 +0000 Subject: [PATCH 612/796] Update note for review comments --- .../codeql-language-guides/codeql-library-for-javascript.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst b/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst index 0b3f8daedb1..8c9c6d8cffa 100644 --- a/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst @@ -228,7 +228,7 @@ The `TopLevel Date: Mon, 28 Nov 2022 11:49:19 +0000 Subject: [PATCH 613/796] Apply suggestions from code review Co-authored-by: hubwriter --- cpp/ql/lib/definitions.qll | 2 +- cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql | 2 +- .../writing-codeql-queries/metadata-for-codeql-queries.rst | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cpp/ql/lib/definitions.qll b/cpp/ql/lib/definitions.qll index e866a50513b..e4a2aca98f6 100644 --- a/cpp/ql/lib/definitions.qll +++ b/cpp/ql/lib/definitions.qll @@ -13,7 +13,7 @@ import IDEContextual * In some cases it is preferable to modify locations (the * `hasLocationInfo()` predicate) so that they are short, and * non-overlapping with other locations that might be reported as - * code scanning alerts in GitHub. + * code scanning alerts on GitHub. * * We need to give locations that may not be in the database, so * we use `hasLocationInfo()` rather than `getLocation()`. diff --git a/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql b/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql index 0de0979f9a3..4dacffb6a55 100644 --- a/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql +++ b/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql @@ -13,7 +13,7 @@ /* * Note: this query is not assigned a precision yet because we don't want it - * included in query suites until its performance is well understood. + * to be included in query suites until its performance is well understood. */ import cpp diff --git a/docs/codeql/writing-codeql-queries/metadata-for-codeql-queries.rst b/docs/codeql/writing-codeql-queries/metadata-for-codeql-queries.rst index 46807e45399..54cfd20bba7 100644 --- a/docs/codeql/writing-codeql-queries/metadata-for-codeql-queries.rst +++ b/docs/codeql/writing-codeql-queries/metadata-for-codeql-queries.rst @@ -40,12 +40,12 @@ The following properties are supported by all query files: | | | ``readability`` | | | | | ``security`` | | +-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``@precision`` | | ``low`` | Indicates the percentage of query results that are true positives (as opposed to false positive results). This, along with the ``@problem.severity`` property, determines how the results are displayed in GitHub. | +| ``@precision`` | | ``low`` | Indicates the percentage of query results that are true positives (as opposed to false positive results). This, along with the ``@problem.severity`` property, determines how the results are displayed on GitHub. | | | | ``medium`` | | | | | ``high`` | | | | | ``very-high`` | | +-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``@problem.severity`` | | ``error`` | Defines the level of severity of any alerts generated by a non-security query. This, along with the ``@precision`` property, determines how the results are displayed in GitHub. | +| ``@problem.severity`` | | ``error`` | Defines the level of severity of any alerts generated by a non-security query. This, along with the ``@precision`` property, determines how the results are displayed on GitHub. | | | | ``warning`` | | | | | ``recommendation`` | | +-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ From 97bd91ed19898335a9886b1ebbde20849e7c917c Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 28 Nov 2022 16:05:42 +0000 Subject: [PATCH 614/796] Swift: Simplify using ApplyExpr.getArgumentWithLabel. --- .../queries/Security/CWE-1204/StaticInitializationVector.ql | 6 ++---- swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql | 5 ++--- swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql | 5 ++--- .../queries/Security/CWE-916/InsufficientHashIterations.ql | 5 ++--- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-1204/StaticInitializationVector.ql b/swift/ql/src/queries/Security/CWE-1204/StaticInitializationVector.ql index ccf6584c391..9a0ac0e3d79 100644 --- a/swift/ql/src/queries/Security/CWE-1204/StaticInitializationVector.ql +++ b/swift/ql/src/queries/Security/CWE-1204/StaticInitializationVector.ql @@ -32,7 +32,7 @@ class StaticInitializationVectorSource extends Expr { class EncryptionInitializationSink extends Expr { EncryptionInitializationSink() { // `iv` arg in `init` is a sink - exists(CallExpr call, string fName, int arg | + exists(CallExpr call, string fName | call.getStaticTarget() .(MethodDecl) .hasQualifiedName([ @@ -40,9 +40,7 @@ class EncryptionInitializationSink extends Expr { "CCM", "CTR" ], fName) and fName.matches("%init(%iv:%") and - arg = [0, 1] and - call.getStaticTarget().(MethodDecl).getParam(pragma[only_bind_into](arg)).getName() = "iv" and - call.getArgument(pragma[only_bind_into](arg)).getExpr() = this + call.getArgumentWithLabel("iv").getExpr() = this ) } } diff --git a/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql b/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql index 75af598dc19..e17d8a4c778 100644 --- a/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql +++ b/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql @@ -32,13 +32,12 @@ class ConstantPasswordSource extends Expr { class ConstantPasswordSink extends Expr { ConstantPasswordSink() { // `password` arg in `init` is a sink - exists(ClassOrStructDecl c, AbstractFunctionDecl f, CallExpr call, int arg | + exists(ClassOrStructDecl c, AbstractFunctionDecl f, CallExpr call | c.getFullName() = ["HKDF", "PBKDF1", "PBKDF2", "Scrypt"] and c.getAMember() = f and f.getName().matches("%init(%password:%") and call.getStaticTarget() = f and - f.getParam(pragma[only_bind_into](arg)).getName() = "password" and - call.getArgument(pragma[only_bind_into](arg)).getExpr() = this + call.getArgumentWithLabel("password").getExpr() = this ) } } diff --git a/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql b/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql index 9cd6dbd5ace..b351eb710d7 100644 --- a/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql +++ b/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql @@ -32,13 +32,12 @@ class ConstantSaltSource extends Expr { class ConstantSaltSink extends Expr { ConstantSaltSink() { // `salt` arg in `init` is a sink - exists(ClassOrStructDecl c, AbstractFunctionDecl f, CallExpr call, int arg | + exists(ClassOrStructDecl c, AbstractFunctionDecl f, CallExpr call | c.getFullName() = ["HKDF", "PBKDF1", "PBKDF2", "Scrypt"] and c.getAMember() = f and f.getName().matches("%init(%salt:%") and call.getStaticTarget() = f and - f.getParam(pragma[only_bind_into](arg)).getName() = "salt" and - call.getArgument(pragma[only_bind_into](arg)).getExpr() = this + call.getArgumentWithLabel("salt").getExpr() = this ) } } diff --git a/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql b/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql index 046c86d2f5c..19d400dfe1b 100644 --- a/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql +++ b/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql @@ -33,13 +33,12 @@ class IntLiteralSource extends IterationsSource instanceof IntegerLiteralExpr { class InsufficientHashIterationsSink extends Expr { InsufficientHashIterationsSink() { // `iterations` arg in `init` is a sink - exists(ClassOrStructDecl c, AbstractFunctionDecl f, CallExpr call, int arg | + exists(ClassOrStructDecl c, AbstractFunctionDecl f, CallExpr call | c.getFullName() = ["PBKDF1", "PBKDF2"] and c.getAMember() = f and f.getName().matches("init(%iterations:%") and call.getStaticTarget() = f and - f.getParam(pragma[only_bind_into](arg)).getName() = "iterations" and - call.getArgument(pragma[only_bind_into](arg)).getExpr() = this + call.getArgumentWithLabel("iterations").getExpr() = this ) } } From aa5c893d5e9c4eec894c1e8988f65515e6b31bb4 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 28 Nov 2022 16:08:24 +0000 Subject: [PATCH 615/796] Swift: Further simplify. --- .../src/queries/Security/CWE-1204/StaticInitializationVector.ql | 2 +- swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql | 2 +- swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql | 2 +- .../src/queries/Security/CWE-916/InsufficientHashIterations.ql | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-1204/StaticInitializationVector.ql b/swift/ql/src/queries/Security/CWE-1204/StaticInitializationVector.ql index 9a0ac0e3d79..28dbb45d95c 100644 --- a/swift/ql/src/queries/Security/CWE-1204/StaticInitializationVector.ql +++ b/swift/ql/src/queries/Security/CWE-1204/StaticInitializationVector.ql @@ -39,7 +39,7 @@ class EncryptionInitializationSink extends Expr { "AES", "ChaCha20", "Blowfish", "Rabbit", "CBC", "CFB", "GCM", "OCB", "OFB", "PCBC", "CCM", "CTR" ], fName) and - fName.matches("%init(%iv:%") and + fName.matches("%init(%") and call.getArgumentWithLabel("iv").getExpr() = this ) } diff --git a/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql b/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql index e17d8a4c778..91982a2a2dd 100644 --- a/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql +++ b/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql @@ -35,7 +35,7 @@ class ConstantPasswordSink extends Expr { exists(ClassOrStructDecl c, AbstractFunctionDecl f, CallExpr call | c.getFullName() = ["HKDF", "PBKDF1", "PBKDF2", "Scrypt"] and c.getAMember() = f and - f.getName().matches("%init(%password:%") and + f.getName().matches("%init(%") and call.getStaticTarget() = f and call.getArgumentWithLabel("password").getExpr() = this ) diff --git a/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql b/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql index b351eb710d7..47f84fd9bd7 100644 --- a/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql +++ b/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql @@ -35,7 +35,7 @@ class ConstantSaltSink extends Expr { exists(ClassOrStructDecl c, AbstractFunctionDecl f, CallExpr call | c.getFullName() = ["HKDF", "PBKDF1", "PBKDF2", "Scrypt"] and c.getAMember() = f and - f.getName().matches("%init(%salt:%") and + f.getName().matches("%init(%") and call.getStaticTarget() = f and call.getArgumentWithLabel("salt").getExpr() = this ) diff --git a/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql b/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql index 19d400dfe1b..7349978189d 100644 --- a/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql +++ b/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql @@ -36,7 +36,7 @@ class InsufficientHashIterationsSink extends Expr { exists(ClassOrStructDecl c, AbstractFunctionDecl f, CallExpr call | c.getFullName() = ["PBKDF1", "PBKDF2"] and c.getAMember() = f and - f.getName().matches("init(%iterations:%") and + f.getName().matches("init(%") and call.getStaticTarget() = f and call.getArgumentWithLabel("iterations").getExpr() = this ) From edb6325117e9b61725334d95c2cdc3a2a46bba90 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 28 Nov 2022 16:11:07 +0000 Subject: [PATCH 616/796] Swift: Fix comment. --- swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index 09d5319e11a..8f60c90b2c4 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -162,7 +162,7 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { call.getStaticTarget() = funcDecl and flowstate = "String" ) and - // match up `funcName`, `paramName`, `arg`, `node`. + // match up `funcName`, `arg`, `node`. funcDecl.getName() = funcName and call.getArgument(arg).getExpr() = node.asExpr() ) From 410609fed4832f431fdc24835e6c235bb1455648 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 28 Nov 2022 15:44:23 +0000 Subject: [PATCH 617/796] Swift: Make ConstructorDecl, DestructorDecl into MethodDecls. --- swift/ql/lib/codeql/swift/elements/decl/ConstructorDecl.qll | 4 ++-- swift/ql/lib/codeql/swift/elements/decl/DestructorDecl.qll | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/swift/ql/lib/codeql/swift/elements/decl/ConstructorDecl.qll b/swift/ql/lib/codeql/swift/elements/decl/ConstructorDecl.qll index 5905cf11cf6..0a88ec16700 100644 --- a/swift/ql/lib/codeql/swift/elements/decl/ConstructorDecl.qll +++ b/swift/ql/lib/codeql/swift/elements/decl/ConstructorDecl.qll @@ -1,4 +1,4 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file private import codeql.swift.generated.decl.ConstructorDecl +private import codeql.swift.elements.decl.MethodDecl -class ConstructorDecl extends Generated::ConstructorDecl { } +class ConstructorDecl extends Generated::ConstructorDecl, MethodDecl { } diff --git a/swift/ql/lib/codeql/swift/elements/decl/DestructorDecl.qll b/swift/ql/lib/codeql/swift/elements/decl/DestructorDecl.qll index fd331fb9be5..1dfa7c4c2e3 100644 --- a/swift/ql/lib/codeql/swift/elements/decl/DestructorDecl.qll +++ b/swift/ql/lib/codeql/swift/elements/decl/DestructorDecl.qll @@ -1,4 +1,4 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file private import codeql.swift.generated.decl.DestructorDecl +private import codeql.swift.elements.decl.MethodDecl -class DestructorDecl extends Generated::DestructorDecl { } +class DestructorDecl extends Generated::DestructorDecl, MethodDecl { } From e97aee5d9d85422e8501ccf1f626c3e8ac454412 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 28 Nov 2022 16:20:20 +0000 Subject: [PATCH 618/796] Swift: QLDoc. --- swift/ql/lib/codeql/swift/elements/decl/ConstructorDecl.qll | 3 +++ swift/ql/lib/codeql/swift/elements/decl/DestructorDecl.qll | 3 +++ 2 files changed, 6 insertions(+) diff --git a/swift/ql/lib/codeql/swift/elements/decl/ConstructorDecl.qll b/swift/ql/lib/codeql/swift/elements/decl/ConstructorDecl.qll index 0a88ec16700..7933c7f93b2 100644 --- a/swift/ql/lib/codeql/swift/elements/decl/ConstructorDecl.qll +++ b/swift/ql/lib/codeql/swift/elements/decl/ConstructorDecl.qll @@ -1,4 +1,7 @@ private import codeql.swift.generated.decl.ConstructorDecl private import codeql.swift.elements.decl.MethodDecl +/** + * An initializer of a class, struct, enum or protocol. + */ class ConstructorDecl extends Generated::ConstructorDecl, MethodDecl { } diff --git a/swift/ql/lib/codeql/swift/elements/decl/DestructorDecl.qll b/swift/ql/lib/codeql/swift/elements/decl/DestructorDecl.qll index 1dfa7c4c2e3..b9e1739f31a 100644 --- a/swift/ql/lib/codeql/swift/elements/decl/DestructorDecl.qll +++ b/swift/ql/lib/codeql/swift/elements/decl/DestructorDecl.qll @@ -1,4 +1,7 @@ private import codeql.swift.generated.decl.DestructorDecl private import codeql.swift.elements.decl.MethodDecl +/** + * A deinitializer of a class. + */ class DestructorDecl extends Generated::DestructorDecl, MethodDecl { } From 96e04e7f636ca9c6ecec38c9b81264effbff99c3 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 28 Nov 2022 16:13:12 +0000 Subject: [PATCH 619/796] Swift: Use ConstructorDecl in place of name matching. --- .../queries/Security/CWE-1204/StaticInitializationVector.ql | 3 +-- swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql | 3 +-- swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql | 3 +-- .../src/queries/Security/CWE-916/InsufficientHashIterations.ql | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-1204/StaticInitializationVector.ql b/swift/ql/src/queries/Security/CWE-1204/StaticInitializationVector.ql index 28dbb45d95c..ec595c53b6c 100644 --- a/swift/ql/src/queries/Security/CWE-1204/StaticInitializationVector.ql +++ b/swift/ql/src/queries/Security/CWE-1204/StaticInitializationVector.ql @@ -34,12 +34,11 @@ class EncryptionInitializationSink extends Expr { // `iv` arg in `init` is a sink exists(CallExpr call, string fName | call.getStaticTarget() - .(MethodDecl) + .(ConstructorDecl) .hasQualifiedName([ "AES", "ChaCha20", "Blowfish", "Rabbit", "CBC", "CFB", "GCM", "OCB", "OFB", "PCBC", "CCM", "CTR" ], fName) and - fName.matches("%init(%") and call.getArgumentWithLabel("iv").getExpr() = this ) } diff --git a/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql b/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql index 91982a2a2dd..5ba853575e4 100644 --- a/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql +++ b/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql @@ -32,10 +32,9 @@ class ConstantPasswordSource extends Expr { class ConstantPasswordSink extends Expr { ConstantPasswordSink() { // `password` arg in `init` is a sink - exists(ClassOrStructDecl c, AbstractFunctionDecl f, CallExpr call | + exists(ClassOrStructDecl c, ConstructorDecl f, CallExpr call | c.getFullName() = ["HKDF", "PBKDF1", "PBKDF2", "Scrypt"] and c.getAMember() = f and - f.getName().matches("%init(%") and call.getStaticTarget() = f and call.getArgumentWithLabel("password").getExpr() = this ) diff --git a/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql b/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql index 47f84fd9bd7..f0085e94f65 100644 --- a/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql +++ b/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql @@ -32,10 +32,9 @@ class ConstantSaltSource extends Expr { class ConstantSaltSink extends Expr { ConstantSaltSink() { // `salt` arg in `init` is a sink - exists(ClassOrStructDecl c, AbstractFunctionDecl f, CallExpr call | + exists(ClassOrStructDecl c, ConstructorDecl f, CallExpr call | c.getFullName() = ["HKDF", "PBKDF1", "PBKDF2", "Scrypt"] and c.getAMember() = f and - f.getName().matches("%init(%") and call.getStaticTarget() = f and call.getArgumentWithLabel("salt").getExpr() = this ) diff --git a/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql b/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql index 7349978189d..d8cb049ea50 100644 --- a/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql +++ b/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql @@ -33,10 +33,9 @@ class IntLiteralSource extends IterationsSource instanceof IntegerLiteralExpr { class InsufficientHashIterationsSink extends Expr { InsufficientHashIterationsSink() { // `iterations` arg in `init` is a sink - exists(ClassOrStructDecl c, AbstractFunctionDecl f, CallExpr call | + exists(ClassOrStructDecl c, ConstructorDecl f, CallExpr call | c.getFullName() = ["PBKDF1", "PBKDF2"] and c.getAMember() = f and - f.getName().matches("init(%") and call.getStaticTarget() = f and call.getArgumentWithLabel("iterations").getExpr() = this ) From 349a10c013623ad918d81a8bcb6b887d9f3ff5ef Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 28 Nov 2022 17:41:41 +0000 Subject: [PATCH 620/796] Swift: codegen. --- swift/ql/.generated.list | 2 -- 1 file changed, 2 deletions(-) diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index a62640aace8..f86852145f3 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -17,10 +17,8 @@ ql/lib/codeql/swift/elements/decl/ConcreteFuncDecl.qll 7dd23b6145977ec6ca60dd39c ql/lib/codeql/swift/elements/decl/ConcreteFuncDeclConstructor.qll 4eb2e9dc8b4c93e457bb594085d8f50862dc07a712ce7a0f2dee7f108467ce3e 1f994d6ae1ca2e4fd5da075b70ea22322181bdaf43034face1e82ef353fe34bf ql/lib/codeql/swift/elements/decl/ConcreteVarDecl.qll be33f40e8870a10aec413f35d8f62a502d7d5dd8a52665730740e880566206d7 d821efa43c6d83aedfb959500de42c5ecabbf856f8556f739bc6cec30a88dfab ql/lib/codeql/swift/elements/decl/ConcreteVarDeclConstructor.qll 4b6a9f458db5437f9351b14464b3809a78194029554ea818b3e18272c17afba3 a60d695b0d0ffa917ad01908bec2beaa663e644eddb00fb370fbc906623775d4 -ql/lib/codeql/swift/elements/decl/ConstructorDecl.qll df6725dfa6670b1ff9a5135126b38cb93d813f852ffd1290bb60b541e28b92d9 fb3ed454cdc97bedc5577c9823f6385eb9616d156085fc8796cc09732ae48121 ql/lib/codeql/swift/elements/decl/ConstructorDeclConstructor.qll ba5cc6f440cba3d47b364a37febd64f85941cdc0237db52a2b8844d1dc75d483 9fc039ca7a0f33f03b3f573186f02efecbac0c2e0dc5abba5d47876ca26390fe ql/lib/codeql/swift/elements/decl/Decl.qll 7a7ea5727a238684e783adf04ce8f721bf4451e1324ffc966ad671d60a43d64b 662e53ffc8226ae351032d0389784e6b70d517794e83a4c698ac84996361608f -ql/lib/codeql/swift/elements/decl/DestructorDecl.qll a2ba5e8861661ebc4cf875d540bf1edf0970920304aeeaef34592ea2739afc21 10001d21ec5aecc398e4c0e9bf05ee905c3edc4f89dd0afc7b2e5aca6b767dec ql/lib/codeql/swift/elements/decl/DestructorDeclConstructor.qll c33b113a3ccb0b1bfd9aad8b909940776da5fdb8a24e1b998c5ebde3903be981 155ad928fbebf9688eec30a2cf61d9a2d4cd15d1161dc3f6202e6331bdb3a56a ql/lib/codeql/swift/elements/decl/EnumCaseDeclConstructor.qll 8c907544170671f713a8665d294eeefdbe78a607c2f16e2c630ea9c33f484baf eec83efc930683628185dbdad8f73311aad510074d168a53d85ea09d13f1f7e1 ql/lib/codeql/swift/elements/decl/EnumDecl.qll 04271e164379af3a33eb060d230b768878e06acc37c3d132cad089a2c663c6c4 779940ebdbd510eb651972c57eb84b04af39c44ef59a8c307a44549ab730febb From 963407de4c20cf613db65183bc935f28145d7c89 Mon Sep 17 00:00:00 2001 From: tiferet Date: Mon, 28 Nov 2022 11:16:06 -0800 Subject: [PATCH 621/796] Update the documentation --- .../adaptivethreatmodeling/ATMConfig.qll | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index 8eceff9e362..814037837c1 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -73,16 +73,23 @@ abstract class AtmConfig extends string { not exists(this.getAReasonSinkExcluded(candidateSink)) } + /** + * Gets the list of characteristics that cause `candidateSink` to be excluded as an effective sink. + */ final EndpointCharacteristics::EndpointCharacteristic getAReasonSinkExcluded( JS::DataFlow::Node candidateSink ) { - // An endpoint is an effective sink if it has neither standard endpoint filter characteristics nor endpoint filter - // characteristics that are specific to this sink type. - // TODO: Experiment with excluding all endpoints that have a medium- or high-confidence characteristic that implies - // they're not sinks for this sink type (or not sinks for any sink type), not just the EndpointFilterCharacteristics. + // An endpoint is an effective sink (sink candidate) if none of its characteristics give much indication whether or + // not it is a sink. Historically, we used endpoint filters, and scored endpoints that are filtered out neither by + // a standard endpoint filter nor by an endpoint filter specific to this sink type. To replicate this behaviour, we + // have given the endpoint filter characteristics medium confidence, and we exclude endpoints that have a + // medium-confidence characteristic that indicates that they are not sinks, either in general or for this sink type. exists(EndpointCharacteristics::EndpointCharacteristic filter, float confidence | filter.getEndpoints(candidateSink) and confidence >= filter.mediumConfidence() and + // TODO: Experiment with excluding all endpoints that have a medium- or high-confidence characteristic that + // implies they're not sinks, rather than using only medium-confidence characteristics, by deleting the following + // line. confidence < filter.highConfidence() and ( // Exclude endpoints that have a characteristic that implies they're not sinks for _any_ sink type. From 7b0269c9991962e3b6ab466d62ecd08a84923c56 Mon Sep 17 00:00:00 2001 From: tiferet Date: Mon, 28 Nov 2022 11:28:08 -0800 Subject: [PATCH 622/796] Fix British spelling that code scanning didn't like. I've been working with Brits for too long :) --- .../lib/experimental/adaptivethreatmodeling/ATMConfig.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index 814037837c1..1417c87991b 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -81,7 +81,7 @@ abstract class AtmConfig extends string { ) { // An endpoint is an effective sink (sink candidate) if none of its characteristics give much indication whether or // not it is a sink. Historically, we used endpoint filters, and scored endpoints that are filtered out neither by - // a standard endpoint filter nor by an endpoint filter specific to this sink type. To replicate this behaviour, we + // a standard endpoint filter nor by an endpoint filter specific to this sink type. To replicate this behavior, we // have given the endpoint filter characteristics medium confidence, and we exclude endpoints that have a // medium-confidence characteristic that indicates that they are not sinks, either in general or for this sink type. exists(EndpointCharacteristics::EndpointCharacteristic filter, float confidence | From 99de397a5fa95ad80e1a881a10c7a119da169e70 Mon Sep 17 00:00:00 2001 From: tiferet Date: Thu, 17 Nov 2022 11:15:57 -0800 Subject: [PATCH 623/796] Remove redundant code `isOtherModeledArgument` and `isArgumentToBuiltinFunction` contained the old logic for selecting negative endpoints for training. These can now be deleted, and replaced by a single base class that collects all EndpointCharacteristics that are currently used to indicate negative training samples: `OtherModeledArgumentCharacteristic`. This in turn lets us delete code from `StandardEndpointFilters` that effectively said that endpoints that are high-confidence non-sinks shouldn't be scored at inference time, either. --- .../adaptivethreatmodeling/CoreKnowledge.qll | 114 ------------------ .../EndpointCharacteristics.qll | 80 ++++++++---- .../StandardEndpointFilters.qll | 24 +--- .../endpoint_large_scale/EndpointFeatures.ql | 5 +- 4 files changed, 59 insertions(+), 164 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll index e569fb3dc96..55dca5ba6a8 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll @@ -44,7 +44,6 @@ private import semmle.javascript.security.dataflow.HttpToFileAccessCustomization private import semmle.javascript.security.dataflow.BrokenCryptoAlgorithmCustomizations private import semmle.javascript.security.dataflow.LoopBoundInjectionCustomizations private import semmle.javascript.security.dataflow.CleartextStorageCustomizations -import FilteringReasons /** * Holds if the node `n` is a known sink in a modeled library, or a sibling-argument of such a sink. @@ -110,116 +109,3 @@ predicate isKnownStepSrc(DataFlow::Node n) { DataFlow::SharedFlowStep::step(n, _) or DataFlow::SharedFlowStep::step(n, _, _, _) } - -/** - * Holds if `n` is an argument to a function of a builtin object. - */ -private predicate isArgumentToBuiltinFunction(DataFlow::Node n, FilteringReason reason) { - exists(DataFlow::SourceNode builtin, DataFlow::SourceNode receiver, DataFlow::InvokeNode invk | - ( - builtin instanceof DataFlow::ArrayCreationNode and - reason instanceof ArgumentToArrayReason - or - builtin = - DataFlow::globalVarRef([ - "Map", "Set", "WeakMap", "WeakSet", "Number", "Object", "String", "Array", "Error", - "Math", "Boolean" - ]) and - reason instanceof ArgumentToBuiltinGlobalVarRefReason - ) - | - receiver = [builtin.getAnInvocation(), builtin] and - invk = [receiver, receiver.getAPropertyRead()].getAnInvocation() and - invk.getAnArgument() = n - ) - or - exists(Expr primitive, MethodCallExpr c | - primitive instanceof ConstantString or - primitive instanceof NumberLiteral or - primitive instanceof BooleanLiteral - | - c.calls(primitive, _) and - c.getAnArgument() = n.asExpr() and - reason instanceof ConstantReceiverReason - ) - or - exists(DataFlow::CallNode call | - call.getAnArgument() = n and - call.getCalleeName() = - [ - "indexOf", "hasOwnProperty", "substring", "isDecimal", "decode", "encode", "keys", "shift", - "values", "forEach", "toString", "slice", "splice", "push", "isArray", "sort" - ] and - reason instanceof BuiltinCallNameReason - ) -} - -predicate isOtherModeledArgument(DataFlow::Node n, FilteringReason reason) { - isArgumentToBuiltinFunction(n, reason) - or - any(LodashUnderscore::Member m).getACall().getAnArgument() = n and - reason instanceof LodashUnderscoreArgumentReason - or - any(JQuery::MethodCall m).getAnArgument() = n and - reason instanceof JQueryArgumentReason - or - exists(ClientRequest r | - r.getAnArgument() = n or n = r.getUrl() or n = r.getHost() or n = r.getADataNode() - ) and - reason instanceof ClientRequestReason - or - exists(PromiseDefinition p | - n = [p.getResolveParameter(), p.getRejectParameter()].getACall().getAnArgument() - ) and - reason instanceof PromiseDefinitionReason - or - n instanceof CryptographicKey and reason instanceof CryptographicKeyReason - or - any(CryptographicOperation op).getInput() = n and - reason instanceof CryptographicOperationFlowReason - or - exists(DataFlow::CallNode call | n = call.getAnArgument() | - call.getCalleeName() = getAStandardLoggerMethodName() and - reason instanceof LoggerMethodReason - or - call.getCalleeName() = ["setTimeout", "clearTimeout"] and - reason instanceof TimeoutReason - or - call.getReceiver() = DataFlow::globalVarRef(["localStorage", "sessionStorage"]) and - reason instanceof ReceiverStorageReason - or - call instanceof StringOps::StartsWith and reason instanceof StringStartsWithReason - or - call instanceof StringOps::EndsWith and reason instanceof StringEndsWithReason - or - call instanceof StringOps::RegExpTest and reason instanceof StringRegExpTestReason - or - call instanceof EventRegistration and reason instanceof EventRegistrationReason - or - call instanceof EventDispatch and reason instanceof EventDispatchReason - or - call = any(MembershipCandidate c).getTest() and - reason instanceof MembershipCandidateTestReason - or - call instanceof FileSystemAccess and reason instanceof FileSystemAccessReason - or - // TODO database accesses are less well defined than database query sinks, so this may cover unmodeled sinks on existing database models - [ - call, call.getAMethodCall() - /* command pattern where the query is built, and then exec'ed later */ ] instanceof - DatabaseAccess and - reason instanceof DatabaseAccessReason - or - call = DOM::domValueRef() and reason instanceof DomReason - or - call.getCalleeName() = "next" and - exists(DataFlow::FunctionNode f | call = f.getLastParameter().getACall()) and - reason instanceof NextFunctionCallReason - or - call = DataFlow::globalVarRef("dojo").getAPropertyRead("require").getACall() and - reason instanceof DojoRequireReason - ) - or - (exists(Base64::Decode d | n = d.getInput()) or exists(Base64::Encode d | n = d.getInput())) and - reason instanceof Base64ManipulationReason -} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index 7bd615df139..d86577d68b9 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -143,11 +143,19 @@ private class NosqlInjectionSinkCharacteristic extends EndpointCharacteristic { * negative samples for training. */ +/** + * A characteristic that is an indicator of not being a sink of any type, because it's a modeled argument. + */ +abstract class OtherModeledArgumentCharacteristic extends EndpointCharacteristic { + bindingset[this] + OtherModeledArgumentCharacteristic() { any() } +} + /** * A characteristic that is an indicator of not being a sink of any type, because it's an argument to a function of a * builtin object. */ -abstract private class ArgumentToBuiltinFunctionCharacteristic extends EndpointCharacteristic { +abstract private class ArgumentToBuiltinFunctionCharacteristic extends OtherModeledArgumentCharacteristic { bindingset[this] ArgumentToBuiltinFunctionCharacteristic() { any() } } @@ -187,15 +195,17 @@ abstract class LikelyNotASinkCharacteristic extends EndpointCharacteristic { } } -private class LodashUnderscore extends NotASinkCharacteristic { - LodashUnderscore() { this = "LodashUnderscoreArgument" } +private class LodashUnderscoreCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + LodashUnderscoreCharacteristic() { this = "LodashUnderscoreArgument" } override predicate getEndpoints(DataFlow::Node n) { any(LodashUnderscore::Member m).getACall().getAnArgument() = n } } -private class JQueryArgumentCharacteristic extends NotASinkCharacteristic { +private class JQueryArgumentCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { JQueryArgumentCharacteristic() { this = "JQueryArgument" } override predicate getEndpoints(DataFlow::Node n) { @@ -203,7 +213,8 @@ private class JQueryArgumentCharacteristic extends NotASinkCharacteristic { } } -private class ClientRequestCharacteristic extends NotASinkCharacteristic { +private class ClientRequestCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { ClientRequestCharacteristic() { this = "ClientRequest" } override predicate getEndpoints(DataFlow::Node n) { @@ -213,7 +224,8 @@ private class ClientRequestCharacteristic extends NotASinkCharacteristic { } } -private class PromiseDefinitionCharacteristic extends NotASinkCharacteristic { +private class PromiseDefinitionCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { PromiseDefinitionCharacteristic() { this = "PromiseDefinition" } override predicate getEndpoints(DataFlow::Node n) { @@ -223,13 +235,15 @@ private class PromiseDefinitionCharacteristic extends NotASinkCharacteristic { } } -private class CryptographicKeyCharacteristic extends NotASinkCharacteristic { +private class CryptographicKeyCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { CryptographicKeyCharacteristic() { this = "CryptographicKey" } override predicate getEndpoints(DataFlow::Node n) { n instanceof CryptographicKey } } -private class CryptographicOperationFlowCharacteristic extends NotASinkCharacteristic { +private class CryptographicOperationFlowCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { CryptographicOperationFlowCharacteristic() { this = "CryptographicOperationFlow" } override predicate getEndpoints(DataFlow::Node n) { @@ -237,7 +251,8 @@ private class CryptographicOperationFlowCharacteristic extends NotASinkCharacter } } -private class LoggerMethodCharacteristic extends NotASinkCharacteristic { +private class LoggerMethodCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { LoggerMethodCharacteristic() { this = "LoggerMethod" } override predicate getEndpoints(DataFlow::Node n) { @@ -247,7 +262,8 @@ private class LoggerMethodCharacteristic extends NotASinkCharacteristic { } } -private class TimeoutCharacteristic extends NotASinkCharacteristic { +private class TimeoutCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { TimeoutCharacteristic() { this = "Timeout" } override predicate getEndpoints(DataFlow::Node n) { @@ -257,7 +273,8 @@ private class TimeoutCharacteristic extends NotASinkCharacteristic { } } -private class ReceiverStorageCharacteristic extends NotASinkCharacteristic { +private class ReceiverStorageCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { ReceiverStorageCharacteristic() { this = "ReceiverStorage" } override predicate getEndpoints(DataFlow::Node n) { @@ -267,7 +284,8 @@ private class ReceiverStorageCharacteristic extends NotASinkCharacteristic { } } -private class StringStartsWithCharacteristic extends NotASinkCharacteristic { +private class StringStartsWithCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { StringStartsWithCharacteristic() { this = "StringStartsWith" } override predicate getEndpoints(DataFlow::Node n) { @@ -277,7 +295,8 @@ private class StringStartsWithCharacteristic extends NotASinkCharacteristic { } } -private class StringEndsWithCharacteristic extends NotASinkCharacteristic { +private class StringEndsWithCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { StringEndsWithCharacteristic() { this = "StringEndsWith" } override predicate getEndpoints(DataFlow::Node n) { @@ -285,7 +304,8 @@ private class StringEndsWithCharacteristic extends NotASinkCharacteristic { } } -private class StringRegExpTestCharacteristic extends NotASinkCharacteristic { +private class StringRegExpTestCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { StringRegExpTestCharacteristic() { this = "StringRegExpTest" } override predicate getEndpoints(DataFlow::Node n) { @@ -295,7 +315,8 @@ private class StringRegExpTestCharacteristic extends NotASinkCharacteristic { } } -private class EventRegistrationCharacteristic extends NotASinkCharacteristic { +private class EventRegistrationCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { EventRegistrationCharacteristic() { this = "EventRegistration" } override predicate getEndpoints(DataFlow::Node n) { @@ -303,7 +324,8 @@ private class EventRegistrationCharacteristic extends NotASinkCharacteristic { } } -private class EventDispatchCharacteristic extends NotASinkCharacteristic { +private class EventDispatchCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { EventDispatchCharacteristic() { this = "EventDispatch" } override predicate getEndpoints(DataFlow::Node n) { @@ -311,7 +333,8 @@ private class EventDispatchCharacteristic extends NotASinkCharacteristic { } } -private class MembershipCandidateTestCharacteristic extends NotASinkCharacteristic { +private class MembershipCandidateTestCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { MembershipCandidateTestCharacteristic() { this = "MembershipCandidateTest" } override predicate getEndpoints(DataFlow::Node n) { @@ -321,7 +344,8 @@ private class MembershipCandidateTestCharacteristic extends NotASinkCharacterist } } -private class FileSystemAccessCharacteristic extends NotASinkCharacteristic { +private class FileSystemAccessCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { FileSystemAccessCharacteristic() { this = "FileSystemAccess" } override predicate getEndpoints(DataFlow::Node n) { @@ -329,7 +353,8 @@ private class FileSystemAccessCharacteristic extends NotASinkCharacteristic { } } -private class DatabaseAccessCharacteristic extends NotASinkCharacteristic { +private class DatabaseAccessCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { DatabaseAccessCharacteristic() { this = "DatabaseAccess" } override predicate getEndpoints(DataFlow::Node n) { @@ -344,7 +369,7 @@ private class DatabaseAccessCharacteristic extends NotASinkCharacteristic { } } -private class DomCharacteristic extends NotASinkCharacteristic { +private class DomCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { DomCharacteristic() { this = "DOM" } override predicate getEndpoints(DataFlow::Node n) { @@ -352,7 +377,8 @@ private class DomCharacteristic extends NotASinkCharacteristic { } } -private class NextFunctionCallCharacteristic extends NotASinkCharacteristic { +private class NextFunctionCallCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { NextFunctionCallCharacteristic() { this = "NextFunctionCall" } override predicate getEndpoints(DataFlow::Node n) { @@ -363,7 +389,8 @@ private class NextFunctionCallCharacteristic extends NotASinkCharacteristic { } } -private class DojoRequireCharacteristic extends NotASinkCharacteristic { +private class DojoRequireCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { DojoRequireCharacteristic() { this = "DojoRequire" } override predicate getEndpoints(DataFlow::Node n) { @@ -373,7 +400,8 @@ private class DojoRequireCharacteristic extends NotASinkCharacteristic { } } -private class Base64ManipulationCharacteristic extends NotASinkCharacteristic { +private class Base64ManipulationCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { Base64ManipulationCharacteristic() { this = "Base64Manipulation" } override predicate getEndpoints(DataFlow::Node n) { @@ -475,7 +503,7 @@ abstract private class StandardEndpointFilterCharacteristic extends EndpointFilt } } -private class IsArgumentToModeledFunctionCharacteristic extends StandardEndpointFilterCharacteristic { +class IsArgumentToModeledFunctionCharacteristic extends StandardEndpointFilterCharacteristic { IsArgumentToModeledFunctionCharacteristic() { this = "argument to modeled function" } override predicate getEndpoints(DataFlow::Node n) { @@ -487,7 +515,9 @@ private class IsArgumentToModeledFunctionCharacteristic extends StandardEndpoint or CoreKnowledge::isKnownStepSrc(known) or - CoreKnowledge::isOtherModeledArgument(known, _) + exists(OtherModeledArgumentCharacteristic characteristic | + characteristic.getEndpoints(known) + ) ) ) } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll index 11041937a3a..b553376e017 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll @@ -7,28 +7,6 @@ */ private import javascript -private import semmle.javascript.filters.ClassifyFiles as ClassifyFiles -private import semmle.javascript.heuristics.SyntacticHeuristics -private import CoreKnowledge as CoreKnowledge -import EndpointCharacteristics as EndpointCharacteristics - -/** - * Holds if the node `n` is an argument to a function that has a manual model. - */ -predicate isArgumentToModeledFunction(DataFlow::Node n) { - exists(DataFlow::InvokeNode invk, DataFlow::Node known | - invk.getAnArgument() = n and invk.getAnArgument() = known and isSomeModeledArgument(known) - ) -} - -/** - * Holds if the node `n` is an argument that has a manual model. - */ -predicate isSomeModeledArgument(DataFlow::Node n) { - CoreKnowledge::isKnownLibrarySink(n) or - CoreKnowledge::isKnownStepSrc(n) or - CoreKnowledge::isOtherModeledArgument(n, _) -} /** * Holds if the data flow node is a (possibly indirect) argument of a likely external library call. @@ -69,7 +47,7 @@ private DataFlow::SourceNode getACallback(DataFlow::ParameterNode p, DataFlow::T * Get calls for which we do not have the callee (i.e. the definition of the called function). This * acts as a heuristic for identifying calls to external library functions. */ -DataFlow::CallNode getACallWithoutCallee() { +private DataFlow::CallNode getACallWithoutCallee() { forall(Function callee | callee = result.getACallee() | callee.getTopLevel().isExterns()) and not exists(DataFlow::ParameterNode param, DataFlow::FunctionNode callback | param.flowsTo(result.getCalleeNode()) and diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql index 6c1d88443d0..9439fda8ab2 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql @@ -12,8 +12,8 @@ import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm import experimental.adaptivethreatmodeling.XssATM as XssAtm import experimental.adaptivethreatmodeling.EndpointFeatures as EndpointFeatures -import experimental.adaptivethreatmodeling.StandardEndpointFilters as StandardEndpointFilters import extraction.NoFeaturizationRestrictionsConfig +private import experimental.adaptivethreatmodeling.EndpointCharacteristics as EndpointCharacteristics query predicate tokenFeatures(DataFlow::Node endpoint, string featureName, string featureValue) { ( @@ -21,7 +21,8 @@ query predicate tokenFeatures(DataFlow::Node endpoint, string featureName, strin not exists(any(SqlInjectionAtm::SqlInjectionAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or not exists(any(TaintedPathAtm::TaintedPathAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or not exists(any(XssAtm::DomBasedXssAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or - StandardEndpointFilters::isArgumentToModeledFunction(endpoint) + any(EndpointCharacteristics::IsArgumentToModeledFunctionCharacteristic characteristic) + .getEndpoints(endpoint) ) and EndpointFeatures::tokenFeatures(endpoint, featureName, featureValue) } From 1c679378e7a29bd15f55cc19c7218f3f2f991083 Mon Sep 17 00:00:00 2001 From: tiferet Date: Thu, 17 Nov 2022 11:39:00 -0800 Subject: [PATCH 624/796] `FilteringReason` is no longer being used and can be deleted --- .../FilteringReasons.qll | 220 ------------------ 1 file changed, 220 deletions(-) delete mode 100644 javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FilteringReasons.qll diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FilteringReasons.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FilteringReasons.qll deleted file mode 100644 index 4b0cdb986e8..00000000000 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FilteringReasons.qll +++ /dev/null @@ -1,220 +0,0 @@ -/** - * For internal use only. - * - * Defines a set of reasons why a particular endpoint was filtered out. This set of reasons - * contains both reasons why an endpoint could be `NotASink` and reasons why an endpoint could be - * `LikelyNotASink`. The `NotASinkReason`s defined here are exhaustive, but the - * `LikelyNotASinkReason`s are not exhaustive. - */ -newtype TFilteringReason = - TIsArgumentToBuiltinFunctionReason() or - TLodashUnderscoreArgumentReason() or - TClientRequestReason() or - TPromiseDefinitionReason() or - TCryptographicKeyReason() or - TCryptographicOperationFlowReason() or - TLoggerMethodReason() or - TTimeoutReason() or - TReceiverStorageReason() or - TStringStartsWithReason() or - TStringEndsWithReason() or - TStringRegExpTestReason() or - TEventRegistrationReason() or - TEventDispatchReason() or - TMembershipCandidateTestReason() or - TFileSystemAccessReason() or - TDatabaseAccessReason() or - TDomReason() or - TNextFunctionCallReason() or - TArgumentToArrayReason() or - TArgumentToBuiltinGlobalVarRefReason() or - TConstantReceiverReason() or - TBuiltinCallNameReason() or - TBase64ManipulationReason() or - TJQueryArgumentReason() or - TDojoRequireReason() - -/** A reason why a particular endpoint was filtered out by the endpoint filters. */ -abstract class FilteringReason extends TFilteringReason { - abstract string getDescription(); - - abstract int getEncoding(); - - string toString() { result = getDescription() } -} - -/** - * A reason why a particular endpoint might be considered to be `NotASink`. - * - * An endpoint is `NotASink` if it has at least one `NotASinkReason`, it does not have any - * `LikelyNotASinkReason`s, and it is not a known sink. - */ -abstract class NotASinkReason extends FilteringReason { } - -/** - * A reason why a particular endpoint might be considered to be `LikelyNotASink`. - * - * An endpoint is `LikelyNotASink` if it has at least one `LikelyNotASinkReason` and it is not a - * known sink. - */ -abstract class LikelyNotASinkReason extends FilteringReason { } - -class IsArgumentToBuiltinFunctionReason extends NotASinkReason, TIsArgumentToBuiltinFunctionReason { - override string getDescription() { result = "IsArgumentToBuiltinFunction" } - - override int getEncoding() { result = 5 } -} - -class LodashUnderscoreArgumentReason extends NotASinkReason, TLodashUnderscoreArgumentReason { - override string getDescription() { result = "LodashUnderscoreArgument" } - - override int getEncoding() { result = 6 } -} - -class ClientRequestReason extends NotASinkReason, TClientRequestReason { - override string getDescription() { result = "ClientRequest" } - - override int getEncoding() { result = 7 } -} - -class PromiseDefinitionReason extends NotASinkReason, TPromiseDefinitionReason { - override string getDescription() { result = "PromiseDefinition" } - - override int getEncoding() { result = 8 } -} - -class CryptographicKeyReason extends NotASinkReason, TCryptographicKeyReason { - override string getDescription() { result = "CryptographicKey" } - - override int getEncoding() { result = 9 } -} - -class CryptographicOperationFlowReason extends NotASinkReason, TCryptographicOperationFlowReason { - override string getDescription() { result = "CryptographicOperationFlow" } - - override int getEncoding() { result = 10 } -} - -class LoggerMethodReason extends NotASinkReason, TLoggerMethodReason { - override string getDescription() { result = "LoggerMethod" } - - override int getEncoding() { result = 11 } -} - -class TimeoutReason extends NotASinkReason, TTimeoutReason { - override string getDescription() { result = "Timeout" } - - override int getEncoding() { result = 12 } -} - -class ReceiverStorageReason extends NotASinkReason, TReceiverStorageReason { - override string getDescription() { result = "ReceiverStorage" } - - override int getEncoding() { result = 13 } -} - -class StringStartsWithReason extends NotASinkReason, TStringStartsWithReason { - override string getDescription() { result = "StringStartsWith" } - - override int getEncoding() { result = 14 } -} - -class StringEndsWithReason extends NotASinkReason, TStringEndsWithReason { - override string getDescription() { result = "StringEndsWith" } - - override int getEncoding() { result = 15 } -} - -class StringRegExpTestReason extends NotASinkReason, TStringRegExpTestReason { - override string getDescription() { result = "StringRegExpTest" } - - override int getEncoding() { result = 16 } -} - -class EventRegistrationReason extends NotASinkReason, TEventRegistrationReason { - override string getDescription() { result = "EventRegistration" } - - override int getEncoding() { result = 17 } -} - -class EventDispatchReason extends NotASinkReason, TEventDispatchReason { - override string getDescription() { result = "EventDispatch" } - - override int getEncoding() { result = 18 } -} - -class MembershipCandidateTestReason extends NotASinkReason, TMembershipCandidateTestReason { - override string getDescription() { result = "MembershipCandidateTest" } - - override int getEncoding() { result = 19 } -} - -class FileSystemAccessReason extends NotASinkReason, TFileSystemAccessReason { - override string getDescription() { result = "FileSystemAccess" } - - override int getEncoding() { result = 20 } -} - -class DatabaseAccessReason extends NotASinkReason, TDatabaseAccessReason { - override string getDescription() { result = "DatabaseAccess" } - - override int getEncoding() { result = 21 } -} - -class DomReason extends NotASinkReason, TDomReason { - override string getDescription() { result = "DOM" } - - override int getEncoding() { result = 22 } -} - -/** DEPRECATED: Alias for DomReason */ -deprecated class DOMReason = DomReason; - -class NextFunctionCallReason extends NotASinkReason, TNextFunctionCallReason { - override string getDescription() { result = "NextFunctionCall" } - - override int getEncoding() { result = 23 } -} - -class ArgumentToArrayReason extends LikelyNotASinkReason, TArgumentToArrayReason { - override string getDescription() { result = "ArgumentToArray" } - - override int getEncoding() { result = 24 } -} - -class ArgumentToBuiltinGlobalVarRefReason extends LikelyNotASinkReason, - TArgumentToBuiltinGlobalVarRefReason { - override string getDescription() { result = "ArgumentToBuiltinGlobalVarRef" } - - override int getEncoding() { result = 25 } -} - -class ConstantReceiverReason extends NotASinkReason, TConstantReceiverReason { - override string getDescription() { result = "ConstantReceiver" } - - override int getEncoding() { result = 26 } -} - -class BuiltinCallNameReason extends NotASinkReason, TBuiltinCallNameReason { - override string getDescription() { result = "BuiltinCallName" } - - override int getEncoding() { result = 27 } -} - -class Base64ManipulationReason extends NotASinkReason, TBase64ManipulationReason { - override string getDescription() { result = "Base64Manipulation" } - - override int getEncoding() { result = 28 } -} - -class JQueryArgumentReason extends NotASinkReason, TJQueryArgumentReason { - override string getDescription() { result = "JQueryArgument" } - - override int getEncoding() { result = 29 } -} - -class DojoRequireReason extends NotASinkReason, TDojoRequireReason { - override string getDescription() { result = "DojoRequire" } - - override int getEncoding() { result = 30 } -} From 15121931b47c85dfddb1287ecc80efc67a1879a3 Mon Sep 17 00:00:00 2001 From: tiferet Date: Thu, 17 Nov 2022 11:59:36 -0800 Subject: [PATCH 625/796] Delete `CoreKnowledge`. All remaining functionality in `CoreKnowledge` is only being used in `EndpointCharacteristics`, so it can be moved there as a small set of helper predicates. --- .../adaptivethreatmodeling/CoreKnowledge.qll | 111 ----------------- .../EndpointCharacteristics.qll | 113 +++++++++++++++++- .../NosqlInjectionATM.qll | 1 - .../SqlInjectionATM.qll | 1 - .../adaptivethreatmodeling/TaintedPathATM.qll | 1 - .../adaptivethreatmodeling/XssATM.qll | 1 - 6 files changed, 108 insertions(+), 120 deletions(-) delete mode 100644 javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll deleted file mode 100644 index 55dca5ba6a8..00000000000 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll +++ /dev/null @@ -1,111 +0,0 @@ -/* - * For internal use only. - * - * Provides predicates that expose the knowledge of models - * in the core CodeQL JavaScript libraries. - */ - -private import javascript -private import semmle.javascript.security.dataflow.XxeCustomizations -private import semmle.javascript.security.dataflow.RemotePropertyInjectionCustomizations -private import semmle.javascript.security.dataflow.TypeConfusionThroughParameterTamperingCustomizations -private import semmle.javascript.security.dataflow.ZipSlipCustomizations -private import semmle.javascript.security.dataflow.TaintedPathCustomizations -private import semmle.javascript.security.dataflow.CleartextLoggingCustomizations -private import semmle.javascript.security.dataflow.XpathInjectionCustomizations -private import semmle.javascript.security.dataflow.Xss::Shared as Xss -private import semmle.javascript.security.dataflow.StackTraceExposureCustomizations -private import semmle.javascript.security.dataflow.ClientSideUrlRedirectCustomizations -private import semmle.javascript.security.dataflow.CodeInjectionCustomizations -private import semmle.javascript.security.dataflow.RequestForgeryCustomizations -private import semmle.javascript.security.dataflow.CorsMisconfigurationForCredentialsCustomizations -private import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironmentCustomizations -private import semmle.javascript.security.dataflow.DifferentKindsComparisonBypassCustomizations -private import semmle.javascript.security.dataflow.CommandInjectionCustomizations -private import semmle.javascript.security.dataflow.PrototypePollutionCustomizations -private import semmle.javascript.security.dataflow.UnvalidatedDynamicMethodCallCustomizations -private import semmle.javascript.security.dataflow.TaintedFormatStringCustomizations -private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations -private import semmle.javascript.security.dataflow.PostMessageStarCustomizations -private import semmle.javascript.security.dataflow.RegExpInjectionCustomizations -private import semmle.javascript.security.dataflow.SqlInjectionCustomizations -private import semmle.javascript.security.dataflow.InsecureRandomnessCustomizations -private import semmle.javascript.security.dataflow.XmlBombCustomizations -private import semmle.javascript.security.dataflow.InsufficientPasswordHashCustomizations -private import semmle.javascript.security.dataflow.HardcodedCredentialsCustomizations -private import semmle.javascript.security.dataflow.FileAccessToHttpCustomizations -private import semmle.javascript.security.dataflow.UnsafeDynamicMethodAccessCustomizations -private import semmle.javascript.security.dataflow.UnsafeDeserializationCustomizations -private import semmle.javascript.security.dataflow.HardcodedDataInterpretedAsCodeCustomizations -private import semmle.javascript.security.dataflow.ServerSideUrlRedirectCustomizations -private import semmle.javascript.security.dataflow.IndirectCommandInjectionCustomizations -private import semmle.javascript.security.dataflow.ConditionalBypassCustomizations -private import semmle.javascript.security.dataflow.HttpToFileAccessCustomizations -private import semmle.javascript.security.dataflow.BrokenCryptoAlgorithmCustomizations -private import semmle.javascript.security.dataflow.LoopBoundInjectionCustomizations -private import semmle.javascript.security.dataflow.CleartextStorageCustomizations - -/** - * Holds if the node `n` is a known sink in a modeled library, or a sibling-argument of such a sink. - */ -predicate isArgumentToKnownLibrarySinkFunction(DataFlow::Node n) { - exists(DataFlow::InvokeNode invk, DataFlow::Node known | - invk.getAnArgument() = n and invk.getAnArgument() = known and isKnownLibrarySink(known) - ) -} - -/** - * Holds if the node `n` is a known sink for the external API security query. - * - * This corresponds to known sinks from security queries whose sources include remote flow and - * DOM-based sources. - */ -predicate isKnownExternalApiQuerySink(DataFlow::Node n) { - n instanceof Xxe::Sink or - n instanceof TaintedPath::Sink or - n instanceof XpathInjection::Sink or - n instanceof Xss::Sink or - n instanceof ClientSideUrlRedirect::Sink or - n instanceof CodeInjection::Sink or - n instanceof RequestForgery::Sink or - n instanceof CorsMisconfigurationForCredentials::Sink or - n instanceof CommandInjection::Sink or - n instanceof PrototypePollution::Sink or - n instanceof UnvalidatedDynamicMethodCall::Sink or - n instanceof TaintedFormatString::Sink or - n instanceof NosqlInjection::Sink or - n instanceof PostMessageStar::Sink or - n instanceof RegExpInjection::Sink or - n instanceof SqlInjection::Sink or - n instanceof XmlBomb::Sink or - n instanceof ZipSlip::Sink or - n instanceof UnsafeDeserialization::Sink or - n instanceof ServerSideUrlRedirect::Sink or - n instanceof CleartextStorage::Sink or - n instanceof HttpToFileAccess::Sink -} - -/** DEPRECATED: Alias for isKnownExternalApiQuerySink */ -deprecated predicate isKnownExternalAPIQuerySink = isKnownExternalApiQuerySink/1; - -/** - * Holds if the node `n` is a known sink in a modeled library. - */ -predicate isKnownLibrarySink(DataFlow::Node n) { - isKnownExternalApiQuerySink(n) or - n instanceof CleartextLogging::Sink or - n instanceof StackTraceExposure::Sink or - n instanceof ShellCommandInjectionFromEnvironment::Sink or - n instanceof InsecureRandomness::Sink or - n instanceof FileAccessToHttp::Sink or - n instanceof IndirectCommandInjection::Sink -} - -/** - * Holds if the node `n` is known as the predecessor in a modeled flow step. - */ -predicate isKnownStepSrc(DataFlow::Node n) { - TaintTracking::sharedTaintStep(n, _) or - DataFlow::SharedFlowStep::step(n, _) or - DataFlow::SharedFlowStep::step(n, _, _, _) -} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index d86577d68b9..7cfce4be406 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -7,10 +7,47 @@ private import semmle.javascript.security.dataflow.SqlInjectionCustomizations private import semmle.javascript.security.dataflow.DomBasedXssCustomizations private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations private import semmle.javascript.security.dataflow.TaintedPathCustomizations -private import CoreKnowledge as CoreKnowledge private import semmle.javascript.heuristics.SyntacticHeuristics as SyntacticHeuristics private import semmle.javascript.filters.ClassifyFiles as ClassifyFiles private import StandardEndpointFilters as StandardEndpointFilters +private import semmle.javascript.security.dataflow.XxeCustomizations +private import semmle.javascript.security.dataflow.RemotePropertyInjectionCustomizations +private import semmle.javascript.security.dataflow.TypeConfusionThroughParameterTamperingCustomizations +private import semmle.javascript.security.dataflow.ZipSlipCustomizations +private import semmle.javascript.security.dataflow.TaintedPathCustomizations +private import semmle.javascript.security.dataflow.CleartextLoggingCustomizations +private import semmle.javascript.security.dataflow.XpathInjectionCustomizations +private import semmle.javascript.security.dataflow.Xss::Shared as Xss +private import semmle.javascript.security.dataflow.StackTraceExposureCustomizations +private import semmle.javascript.security.dataflow.ClientSideUrlRedirectCustomizations +private import semmle.javascript.security.dataflow.CodeInjectionCustomizations +private import semmle.javascript.security.dataflow.RequestForgeryCustomizations +private import semmle.javascript.security.dataflow.CorsMisconfigurationForCredentialsCustomizations +private import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironmentCustomizations +private import semmle.javascript.security.dataflow.DifferentKindsComparisonBypassCustomizations +private import semmle.javascript.security.dataflow.CommandInjectionCustomizations +private import semmle.javascript.security.dataflow.PrototypePollutionCustomizations +private import semmle.javascript.security.dataflow.UnvalidatedDynamicMethodCallCustomizations +private import semmle.javascript.security.dataflow.TaintedFormatStringCustomizations +private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations +private import semmle.javascript.security.dataflow.PostMessageStarCustomizations +private import semmle.javascript.security.dataflow.RegExpInjectionCustomizations +private import semmle.javascript.security.dataflow.SqlInjectionCustomizations +private import semmle.javascript.security.dataflow.InsecureRandomnessCustomizations +private import semmle.javascript.security.dataflow.XmlBombCustomizations +private import semmle.javascript.security.dataflow.InsufficientPasswordHashCustomizations +private import semmle.javascript.security.dataflow.HardcodedCredentialsCustomizations +private import semmle.javascript.security.dataflow.FileAccessToHttpCustomizations +private import semmle.javascript.security.dataflow.UnsafeDynamicMethodAccessCustomizations +private import semmle.javascript.security.dataflow.UnsafeDeserializationCustomizations +private import semmle.javascript.security.dataflow.HardcodedDataInterpretedAsCodeCustomizations +private import semmle.javascript.security.dataflow.ServerSideUrlRedirectCustomizations +private import semmle.javascript.security.dataflow.IndirectCommandInjectionCustomizations +private import semmle.javascript.security.dataflow.ConditionalBypassCustomizations +private import semmle.javascript.security.dataflow.HttpToFileAccessCustomizations +private import semmle.javascript.security.dataflow.BrokenCryptoAlgorithmCustomizations +private import semmle.javascript.security.dataflow.LoopBoundInjectionCustomizations +private import semmle.javascript.security.dataflow.CleartextStorageCustomizations /** * A set of characteristics that a particular endpoint might have. This set of characteristics is used to make decisions @@ -61,6 +98,63 @@ abstract class EndpointCharacteristic extends string { final float mediumConfidence() { result = 0.6 } } +/* + * Helper predicates. + */ + +/** + * Holds if the node `n` is a known sink for the external API security query. + * + * This corresponds to known sinks from security queries whose sources include remote flow and + * DOM-based sources. + */ +private predicate isKnownExternalApiQuerySink(DataFlow::Node n) { + n instanceof Xxe::Sink or + n instanceof TaintedPath::Sink or + n instanceof XpathInjection::Sink or + n instanceof Xss::Sink or + n instanceof ClientSideUrlRedirect::Sink or + n instanceof CodeInjection::Sink or + n instanceof RequestForgery::Sink or + n instanceof CorsMisconfigurationForCredentials::Sink or + n instanceof CommandInjection::Sink or + n instanceof PrototypePollution::Sink or + n instanceof UnvalidatedDynamicMethodCall::Sink or + n instanceof TaintedFormatString::Sink or + n instanceof NosqlInjection::Sink or + n instanceof PostMessageStar::Sink or + n instanceof RegExpInjection::Sink or + n instanceof SqlInjection::Sink or + n instanceof XmlBomb::Sink or + n instanceof ZipSlip::Sink or + n instanceof UnsafeDeserialization::Sink or + n instanceof ServerSideUrlRedirect::Sink or + n instanceof CleartextStorage::Sink or + n instanceof HttpToFileAccess::Sink +} + +/** + * Holds if the node `n` is a known sink in a modeled library. + */ +private predicate isKnownLibrarySink(DataFlow::Node n) { + isKnownExternalApiQuerySink(n) or + n instanceof CleartextLogging::Sink or + n instanceof StackTraceExposure::Sink or + n instanceof ShellCommandInjectionFromEnvironment::Sink or + n instanceof InsecureRandomness::Sink or + n instanceof FileAccessToHttp::Sink or + n instanceof IndirectCommandInjection::Sink +} + +/** + * Holds if the node `n` is known as the predecessor in a modeled flow step. + */ +private predicate isKnownStepSrc(DataFlow::Node n) { + TaintTracking::sharedTaintStep(n, _) or + DataFlow::SharedFlowStep::step(n, _) or + DataFlow::SharedFlowStep::step(n, _, _, _) +} + /* * Characteristics that are indicative of a sink. * NOTE: Initially each sink type has only one characteristic, which is that it's a sink of this type in the standard @@ -511,9 +605,9 @@ class IsArgumentToModeledFunctionCharacteristic extends StandardEndpointFilterCh invk.getAnArgument() = n and invk.getAnArgument() = known and ( - CoreKnowledge::isKnownLibrarySink(known) + isKnownLibrarySink(known) or - CoreKnowledge::isKnownStepSrc(known) + isKnownStepSrc(known) or exists(OtherModeledArgumentCharacteristic characteristic | characteristic.getEndpoints(known) @@ -616,10 +710,19 @@ private class DatabaseAccessCallHeuristicCharacteristic extends NosqlInjectionSi private class ModeledSinkCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { ModeledSinkCharacteristic() { this = "modeled sink" } + /** + * Holds if the node `n` is a known sink in a modeled library, or a sibling-argument of such a sink. + */ + predicate isArgumentToKnownLibrarySinkFunction(DataFlow::Node n) { + exists(DataFlow::InvokeNode invk, DataFlow::Node known | + invk.getAnArgument() = n and invk.getAnArgument() = known and isKnownLibrarySink(known) + ) + } + override predicate getEndpoints(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | // Remove modeled sinks - CoreKnowledge::isArgumentToKnownLibrarySinkFunction(n) + isArgumentToKnownLibrarySinkFunction(n) ) } } @@ -630,7 +733,7 @@ private class PredecessorInModeledFlowStepCharacteristic extends NosqlInjectionS override predicate getEndpoints(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | // Remove common kinds of unlikely sinks - CoreKnowledge::isKnownStepSrc(n) + isKnownStepSrc(n) ) } } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll index 85b3d14d7e9..f03631bfdcf 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll @@ -8,7 +8,6 @@ import javascript private import semmle.javascript.heuristics.SyntacticHeuristics private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations import AdaptiveThreatModeling -private import CoreKnowledge as CoreKnowledge class NosqlInjectionAtmConfig extends AtmConfig { NosqlInjectionAtmConfig() { this = "NosqlInjectionATMConfig" } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll index f52e1898667..14821404e6d 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll @@ -7,7 +7,6 @@ import semmle.javascript.heuristics.SyntacticHeuristics import semmle.javascript.security.dataflow.SqlInjectionCustomizations import AdaptiveThreatModeling -import CoreKnowledge as CoreKnowledge class SqlInjectionAtmConfig extends AtmConfig { SqlInjectionAtmConfig() { this = "SqlInjectionATMConfig" } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll index e83938071df..302907820da 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll @@ -7,7 +7,6 @@ import semmle.javascript.heuristics.SyntacticHeuristics import semmle.javascript.security.dataflow.TaintedPathCustomizations import AdaptiveThreatModeling -import CoreKnowledge as CoreKnowledge class TaintedPathAtmConfig extends AtmConfig { TaintedPathAtmConfig() { this = "TaintedPathATMConfig" } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll index 508cac4544f..2cc848a7ea9 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll @@ -7,7 +7,6 @@ private import semmle.javascript.heuristics.SyntacticHeuristics private import semmle.javascript.security.dataflow.DomBasedXssCustomizations import AdaptiveThreatModeling -import CoreKnowledge as CoreKnowledge class DomBasedXssAtmConfig extends AtmConfig { DomBasedXssAtmConfig() { this = "DomBasedXssATMConfig" } From 210644e87d30b656cb81af047a7d8d6e688be6c5 Mon Sep 17 00:00:00 2001 From: tiferet Date: Thu, 17 Nov 2022 12:12:03 -0800 Subject: [PATCH 626/796] Delete `StandardEndpointFilters`. All remaining functionality in `StandardEndpointFilters` is only being used in `EndpointCharacteristics`, so it can be moved there as a small set of helper predicates. --- .../EndpointCharacteristics.qll | 59 ++++++++++++++++--- .../StandardEndpointFilters.qll | 56 ------------------ 2 files changed, 52 insertions(+), 63 deletions(-) delete mode 100644 javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index 7cfce4be406..74a5ca6256d 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -9,7 +9,6 @@ private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations private import semmle.javascript.security.dataflow.TaintedPathCustomizations private import semmle.javascript.heuristics.SyntacticHeuristics as SyntacticHeuristics private import semmle.javascript.filters.ClassifyFiles as ClassifyFiles -private import StandardEndpointFilters as StandardEndpointFilters private import semmle.javascript.security.dataflow.XxeCustomizations private import semmle.javascript.security.dataflow.RemotePropertyInjectionCustomizations private import semmle.javascript.security.dataflow.TypeConfusionThroughParameterTamperingCustomizations @@ -155,6 +154,53 @@ private predicate isKnownStepSrc(DataFlow::Node n) { DataFlow::SharedFlowStep::step(n, _, _, _) } +/** + * Holds if the data flow node is a (possibly indirect) argument of a likely external library call. + * + * This includes direct arguments of likely external library calls as well as nested object + * literals within those calls. + */ +private predicate flowsToArgumentOfLikelyExternalLibraryCall(DataFlow::Node n) { + n = getACallWithoutCallee().getAnArgument() + or + exists(DataFlow::SourceNode src | flowsToArgumentOfLikelyExternalLibraryCall(src) | + n = src.getAPropertyWrite().getRhs() + ) + or + exists(DataFlow::ArrayCreationNode arr | flowsToArgumentOfLikelyExternalLibraryCall(arr) | + n = arr.getAnElement() + ) +} + +/** + * Get calls for which we do not have the callee (i.e. the definition of the called function). This + * acts as a heuristic for identifying calls to external library functions. + */ +private DataFlow::CallNode getACallWithoutCallee() { + forall(Function callee | callee = result.getACallee() | callee.getTopLevel().isExterns()) and + not exists(DataFlow::ParameterNode param, DataFlow::FunctionNode callback | + param.flowsTo(result.getCalleeNode()) and + callback = getACallback(param, DataFlow::TypeBackTracker::end()) + ) +} + +/** + * Gets a node that flows to callback-parameter `p`. + */ +private DataFlow::SourceNode getACallback(DataFlow::ParameterNode p, DataFlow::TypeBackTracker t) { + t.start() and + result = p and + any(DataFlow::FunctionNode f).getLastParameter() = p and + exists(p.getACall()) + or + exists(DataFlow::TypeBackTracker t2 | result = getACallback(p, t2).backtrack(t2, t)) +} + +/** + * Get calls which are likely to be to external non-built-in libraries. + */ +DataFlow::CallNode getALikelyExternalLibraryCall() { result = getACallWithoutCallee() } + /* * Characteristics that are indicative of a sink. * NOTE: Initially each sink type has only one characteristic, which is that it's a sink of this type in the standard @@ -582,7 +628,6 @@ abstract class EndpointFilterCharacteristic extends EndpointCharacteristic { /** * An EndpointFilterCharacteristic that indicates that an endpoint is unlikely to be a sink of any type. - * Replaces https://github.com/github/codeql/blob/387e57546bf7352f7c1cfe781daa1a3799b7063e/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll#LL15C24-L15C24 */ abstract private class StandardEndpointFilterCharacteristic extends EndpointFilterCharacteristic { bindingset[this] @@ -786,7 +831,7 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkNosqlCh // // ## Direct arguments to external library calls // - // The `StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall` endpoint filter + // The `flowsToArgumentOfLikelyExternalLibraryCall` endpoint filter // allows sink candidates which are within object literals or array literals, for example // `req.sendFile(_, { path: ENDPOINT })`. // @@ -809,7 +854,7 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkNosqlCh // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. // We can't reuse the class because importing that file would cause us to treat these // heuristic sinks as known sinks. - not n = StandardEndpointFilters::getALikelyExternalLibraryCall().getAnArgument() and + not n = getALikelyExternalLibraryCall().getAnArgument() and not ( SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)(nosql|query)") or SyntacticHeuristics::isArgTo(n, "(?i)(query)") @@ -878,7 +923,7 @@ private class NotAnArgumentToLikelyExternalLibraryCallOrHeuristicSinkCharacteris // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. // We can't reuse the class because importing that file would cause us to treat these // heuristic sinks as known sinks. - not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(n) and + not flowsToArgumentOfLikelyExternalLibraryCall(n) and not ( SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)(sql|query)") or SyntacticHeuristics::isArgTo(n, "(?i)(query)") or @@ -916,7 +961,7 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkTainted // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. // We can't reuse the class because importing that file would cause us to treat these // heuristic sinks as known sinks. - not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(n) and + not flowsToArgumentOfLikelyExternalLibraryCall(n) and not ( SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)(file|folder|dir|absolute)") or @@ -977,7 +1022,7 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkXssChar // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. // We can't reuse the class because importing that file would cause us to treat these // heuristic sinks as known sinks. - not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(n) and + not flowsToArgumentOfLikelyExternalLibraryCall(n) and not ( SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)(html|innerhtml)") or diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll deleted file mode 100644 index b553376e017..00000000000 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll +++ /dev/null @@ -1,56 +0,0 @@ -/** - * For internal use only. - * - * Provides classes and predicates that are useful for endpoint filters. - * - * The standard use of this library is to make use of `isPotentialEffectiveSink/1` - */ - -private import javascript - -/** - * Holds if the data flow node is a (possibly indirect) argument of a likely external library call. - * - * This includes direct arguments of likely external library calls as well as nested object - * literals within those calls. - */ -predicate flowsToArgumentOfLikelyExternalLibraryCall(DataFlow::Node n) { - n = getACallWithoutCallee().getAnArgument() - or - exists(DataFlow::SourceNode src | flowsToArgumentOfLikelyExternalLibraryCall(src) | - n = src.getAPropertyWrite().getRhs() - ) - or - exists(DataFlow::ArrayCreationNode arr | flowsToArgumentOfLikelyExternalLibraryCall(arr) | - n = arr.getAnElement() - ) -} - -/** - * Get calls which are likely to be to external non-built-in libraries. - */ -DataFlow::CallNode getALikelyExternalLibraryCall() { result = getACallWithoutCallee() } - -/** - * Gets a node that flows to callback-parameter `p`. - */ -private DataFlow::SourceNode getACallback(DataFlow::ParameterNode p, DataFlow::TypeBackTracker t) { - t.start() and - result = p and - any(DataFlow::FunctionNode f).getLastParameter() = p and - exists(p.getACall()) - or - exists(DataFlow::TypeBackTracker t2 | result = getACallback(p, t2).backtrack(t2, t)) -} - -/** - * Get calls for which we do not have the callee (i.e. the definition of the called function). This - * acts as a heuristic for identifying calls to external library functions. - */ -private DataFlow::CallNode getACallWithoutCallee() { - forall(Function callee | callee = result.getACallee() | callee.getTopLevel().isExterns()) and - not exists(DataFlow::ParameterNode param, DataFlow::FunctionNode callback | - param.flowsTo(result.getCalleeNode()) and - callback = getACallback(param, DataFlow::TypeBackTracker::end()) - ) -} From 4580b5567350afb42b3adb9987c7ce0fe5754796 Mon Sep 17 00:00:00 2001 From: tiferet Date: Thu, 17 Nov 2022 12:27:40 -0800 Subject: [PATCH 627/796] Oops -- forgot to stage one file in the previous commit :) --- .../endpoint_large_scale/getALikelyExternalLibraryCall.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/getALikelyExternalLibraryCall.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/getALikelyExternalLibraryCall.ql index 6c2928c74e0..da91ecf1b43 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/getALikelyExternalLibraryCall.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/getALikelyExternalLibraryCall.ql @@ -1,3 +1,3 @@ -import experimental.adaptivethreatmodeling.StandardEndpointFilters +import experimental.adaptivethreatmodeling.EndpointCharacteristics as EndpointCharacteristics -select getALikelyExternalLibraryCall() +select EndpointCharacteristics::getALikelyExternalLibraryCall() From 0e5925744283f8a51215a24dc2313949e62581c0 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Tue, 29 Nov 2022 10:36:56 +0100 Subject: [PATCH 628/796] Fix local taint steps Local taint should include local flow and simple summaries through library code --- .../internal/TaintTrackingPrivate.qll | 6 + .../dataflow/taint/LocalTaint.expected | 1406 +++++++++++++++++ 2 files changed, 1412 insertions(+) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll index 92724729d0e..6fdcca98c36 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll @@ -74,7 +74,13 @@ private module Cached { */ cached predicate localTaintStepCached(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + DataFlow::localFlowStep(nodeFrom, nodeTo) + or defaultAdditionalTaintStep(nodeFrom, nodeTo) + or + // Simple flow through library code is included in the exposed local + // step relation, even though flow is technically inter-procedural + FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(nodeFrom, nodeTo, _) } } diff --git a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected index 3e594f2d7a8..9a5f74be04b 100644 --- a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected @@ -1,124 +1,855 @@ +| data.swift:2:8:2:8 | SSA def(self) | data.swift:2:8:2:8 | self[return] | +| data.swift:2:8:2:8 | self | data.swift:2:8:2:8 | SSA def(self) | +| data.swift:4:7:4:7 | SSA def(self) | data.swift:4:7:4:7 | self[return] | +| data.swift:4:7:4:7 | SSA def(self) | data.swift:4:7:4:7 | self[return] | +| data.swift:4:7:4:7 | self | data.swift:4:7:4:7 | SSA def(self) | +| data.swift:4:7:4:7 | self | data.swift:4:7:4:7 | SSA def(self) | +| data.swift:12:49:12:49 | self | data.swift:12:49:12:49 | SSA def(self) | +| data.swift:13:49:13:49 | self | data.swift:13:49:13:49 | SSA def(self) | +| data.swift:14:42:14:42 | self | data.swift:14:42:14:42 | SSA def(self) | +| data.swift:18:31:18:31 | SSA def(self) | data.swift:18:31:18:46 | self[return] | +| data.swift:18:31:18:31 | self | data.swift:18:31:18:31 | SSA def(self) | +| data.swift:19:29:19:29 | SSA def(self) | data.swift:19:29:19:44 | self[return] | +| data.swift:19:29:19:29 | self | data.swift:19:29:19:29 | SSA def(self) | +| data.swift:20:7:20:7 | SSA def(self) | data.swift:20:2:20:57 | self[return] | +| data.swift:20:7:20:7 | self | data.swift:20:7:20:7 | SSA def(self) | +| data.swift:21:7:21:7 | SSA def(self) | data.swift:21:2:21:58 | self[return] | +| data.swift:21:7:21:7 | self | data.swift:21:7:21:7 | SSA def(self) | +| data.swift:22:52:22:52 | SSA def(self) | data.swift:22:52:22:67 | self[return] | +| data.swift:22:52:22:52 | self | data.swift:22:52:22:52 | SSA def(self) | +| data.swift:24:5:24:5 | SSA def(self) | data.swift:24:5:24:29 | self[return] | +| data.swift:24:5:24:5 | self | data.swift:24:5:24:5 | SSA def(self) | +| data.swift:25:2:25:2 | SSA def(self) | data.swift:25:2:25:66 | self[return] | +| data.swift:25:2:25:2 | self | data.swift:25:2:25:2 | SSA def(self) | +| data.swift:26:2:26:2 | SSA def(self) | data.swift:26:2:26:61 | self[return] | +| data.swift:26:2:26:2 | self | data.swift:26:2:26:2 | SSA def(self) | +| data.swift:27:2:27:2 | SSA def(self) | data.swift:27:2:27:62 | self[return] | +| data.swift:27:2:27:2 | self | data.swift:27:2:27:2 | SSA def(self) | +| data.swift:28:2:28:2 | SSA def(self) | data.swift:28:2:28:45 | self[return] | +| data.swift:28:2:28:2 | self | data.swift:28:2:28:2 | SSA def(self) | +| data.swift:29:2:29:2 | SSA def(self) | data.swift:29:2:29:82 | self[return] | +| data.swift:29:2:29:2 | self | data.swift:29:2:29:2 | SSA def(self) | +| data.swift:30:2:30:2 | SSA def(self) | data.swift:30:2:30:50 | self[return] | +| data.swift:30:2:30:2 | self | data.swift:30:2:30:2 | SSA def(self) | +| data.swift:31:2:31:2 | SSA def(self) | data.swift:31:2:31:29 | self[return] | +| data.swift:31:2:31:2 | self | data.swift:31:2:31:2 | SSA def(self) | +| data.swift:32:7:32:7 | SSA def(self) | data.swift:32:2:32:24 | self[return] | +| data.swift:32:7:32:7 | self | data.swift:32:7:32:7 | SSA def(self) | +| data.swift:33:7:33:7 | SSA def(self) | data.swift:33:2:33:25 | self[return] | +| data.swift:33:7:33:7 | self | data.swift:33:7:33:7 | SSA def(self) | +| data.swift:34:7:34:7 | SSA def(self) | data.swift:34:2:34:63 | self[return] | +| data.swift:34:7:34:7 | self | data.swift:34:7:34:7 | SSA def(self) | +| data.swift:35:7:35:7 | SSA def(self) | data.swift:35:2:35:52 | self[return] | +| data.swift:35:7:35:7 | self | data.swift:35:7:35:7 | SSA def(self) | +| data.swift:36:7:36:7 | SSA def(self) | data.swift:36:2:36:36 | self[return] | +| data.swift:36:7:36:7 | self | data.swift:36:7:36:7 | SSA def(self) | +| data.swift:37:7:37:7 | SSA def(self) | data.swift:37:2:37:33 | self[return] | +| data.swift:37:7:37:7 | self | data.swift:37:7:37:7 | SSA def(self) | +| data.swift:38:7:38:7 | SSA def(self) | data.swift:38:2:38:88 | self[return] | +| data.swift:38:7:38:7 | self | data.swift:38:7:38:7 | SSA def(self) | +| data.swift:38:79:38:79 | Data.Type | data.swift:38:79:38:79 | call to init(_:) | +| data.swift:38:84:38:84 | | data.swift:38:79:38:86 | call to init(_:) | +| data.swift:39:7:39:7 | SSA def(self) | data.swift:39:2:39:86 | self[return] | +| data.swift:39:7:39:7 | self | data.swift:39:7:39:7 | SSA def(self) | +| data.swift:40:7:40:7 | SSA def(self) | data.swift:40:2:40:99 | self[return] | +| data.swift:40:7:40:7 | self | data.swift:40:7:40:7 | SSA def(self) | +| data.swift:41:7:41:7 | SSA def(self) | data.swift:41:2:41:53 | self[return] | +| data.swift:41:7:41:7 | self | data.swift:41:7:41:7 | SSA def(self) | +| data.swift:42:7:42:7 | SSA def(self) | data.swift:42:2:42:63 | self[return] | +| data.swift:42:7:42:7 | self | data.swift:42:7:42:7 | SSA def(self) | +| data.swift:43:7:43:7 | SSA def(self) | data.swift:43:2:43:76 | self[return] | +| data.swift:43:7:43:7 | self | data.swift:43:7:43:7 | SSA def(self) | +| data.swift:44:7:44:7 | SSA def(self) | data.swift:44:2:44:137 | self[return] | +| data.swift:44:7:44:7 | self | data.swift:44:7:44:7 | SSA def(self) | +| data.swift:45:7:45:7 | SSA def(self) | data.swift:45:2:45:97 | self[return] | +| data.swift:45:7:45:7 | self | data.swift:45:7:45:7 | SSA def(self) | +| data.swift:46:7:46:7 | SSA def(self) | data.swift:46:2:46:34 | self[return] | +| data.swift:46:7:46:7 | self | data.swift:46:7:46:7 | SSA def(self) | +| data.swift:47:7:47:7 | SSA def(self) | data.swift:47:2:47:83 | self[return] | +| data.swift:47:7:47:7 | self | data.swift:47:7:47:7 | SSA def(self) | +| data.swift:48:7:48:7 | SSA def(self) | data.swift:48:2:48:50 | self[return] | +| data.swift:48:7:48:7 | self | data.swift:48:7:48:7 | SSA def(self) | +| data.swift:49:7:49:7 | SSA def(self) | data.swift:49:2:49:115 | self[return] | +| data.swift:49:7:49:7 | self | data.swift:49:7:49:7 | SSA def(self) | +| data.swift:49:22:49:42 | SSA def(initialResult) | data.swift:49:101:49:101 | initialResult | +| data.swift:49:22:49:42 | initialResult | data.swift:49:22:49:42 | SSA def(initialResult) | +| data.swift:50:7:50:7 | SSA def(self) | data.swift:50:2:50:180 | self[return] | +| data.swift:50:7:50:7 | self | data.swift:50:7:50:7 | SSA def(self) | +| data.swift:51:7:51:7 | SSA def(self) | data.swift:51:2:51:58 | self[return] | +| data.swift:51:7:51:7 | self | data.swift:51:7:51:7 | SSA def(self) | +| data.swift:52:7:52:7 | SSA def(self) | data.swift:52:2:52:151 | self[return] | +| data.swift:52:7:52:7 | self | data.swift:52:7:52:7 | SSA def(self) | +| data.swift:53:7:53:7 | SSA def(self) | data.swift:53:2:53:97 | self[return] | +| data.swift:53:7:53:7 | self | data.swift:53:7:53:7 | SSA def(self) | +| data.swift:54:7:54:7 | SSA def(self) | data.swift:54:2:54:82 | self[return] | +| data.swift:54:7:54:7 | self | data.swift:54:7:54:7 | SSA def(self) | +| data.swift:55:7:55:7 | SSA def(self) | data.swift:55:2:55:123 | self[return] | +| data.swift:55:7:55:7 | self | data.swift:55:7:55:7 | SSA def(self) | +| data.swift:56:7:56:7 | SSA def(self) | data.swift:56:2:56:214 | self[return] | +| data.swift:56:7:56:7 | self | data.swift:56:7:56:7 | SSA def(self) | +| data.swift:56:205:56:205 | Data.Type | data.swift:56:205:56:205 | call to init(_:) | +| data.swift:56:210:56:210 | | data.swift:56:205:56:212 | call to init(_:) | +| data.swift:57:7:57:7 | SSA def(self) | data.swift:57:2:57:236 | self[return] | +| data.swift:57:7:57:7 | self | data.swift:57:7:57:7 | SSA def(self) | +| data.swift:57:227:57:227 | Data.Type | data.swift:57:227:57:227 | call to init(_:) | +| data.swift:57:232:57:232 | | data.swift:57:227:57:234 | call to init(_:) | +| data.swift:58:7:58:7 | SSA def(self) | data.swift:58:2:58:39 | self[return] | +| data.swift:58:7:58:7 | self | data.swift:58:7:58:7 | SSA def(self) | +| data.swift:59:7:59:7 | SSA def(self) | data.swift:59:2:59:81 | self[return] | +| data.swift:59:7:59:7 | self | data.swift:59:7:59:7 | SSA def(self) | +| data.swift:60:7:60:7 | SSA def(self) | data.swift:60:2:60:132 | self[return] | +| data.swift:60:7:60:7 | self | data.swift:60:7:60:7 | SSA def(self) | +| data.swift:61:7:61:7 | SSA def(self) | data.swift:61:2:61:41 | self[return] | +| data.swift:61:7:61:7 | self | data.swift:61:7:61:7 | SSA def(self) | +| data.swift:62:7:62:7 | SSA def(self) | data.swift:62:2:62:58 | self[return] | +| data.swift:62:7:62:7 | self | data.swift:62:7:62:7 | SSA def(self) | +| data.swift:62:19:62:32 | SSA def(using) | data.swift:62:2:62:58 | using[return] | +| data.swift:62:19:62:32 | using | data.swift:62:19:62:32 | SSA def(using) | +| data.swift:63:7:63:7 | SSA def(self) | data.swift:63:2:63:123 | self[return] | +| data.swift:63:7:63:7 | self | data.swift:63:7:63:7 | SSA def(self) | +| data.swift:63:114:63:114 | Data.Type | data.swift:63:114:63:114 | call to init(_:) | +| data.swift:63:119:63:119 | | data.swift:63:114:63:121 | call to init(_:) | +| data.swift:64:7:64:7 | SSA def(self) | data.swift:64:2:64:72 | self[return] | +| data.swift:64:7:64:7 | self | data.swift:64:7:64:7 | SSA def(self) | +| data.swift:64:63:64:63 | Data.Type | data.swift:64:63:64:63 | call to init(_:) | +| data.swift:64:68:64:68 | | data.swift:64:63:64:70 | call to init(_:) | +| data.swift:69:7:69:7 | SSA def(self) | data.swift:69:7:69:7 | self[return] | +| data.swift:69:7:69:7 | SSA def(self) | data.swift:69:7:69:7 | self[return] | +| data.swift:69:7:69:7 | self | data.swift:69:7:69:7 | SSA def(self) | +| data.swift:69:7:69:7 | self | data.swift:69:7:69:7 | SSA def(self) | +| data.swift:80:6:80:6 | SSA def(dataClean) | data.swift:84:12:84:12 | dataClean | +| data.swift:80:18:80:18 | Data.Type | data.swift:80:18:80:18 | call to init(_:) | +| data.swift:80:18:80:36 | call to init(_:) | data.swift:80:6:80:6 | SSA def(dataClean) | +| data.swift:80:23:80:32 | .utf8 | data.swift:80:18:80:36 | call to init(_:) | +| data.swift:81:6:81:6 | SSA def(dataTainted) | data.swift:82:26:82:26 | dataTainted | +| data.swift:81:20:81:20 | Data.Type | data.swift:81:20:81:20 | call to init(_:) | +| data.swift:81:20:81:51 | call to init(_:) | data.swift:81:6:81:6 | SSA def(dataTainted) | +| data.swift:81:25:81:47 | .utf8 | data.swift:81:20:81:51 | call to init(_:) | +| data.swift:82:6:82:6 | SSA def(dataTainted2) | data.swift:86:12:86:12 | dataTainted2 | +| data.swift:82:21:82:21 | Data.Type | data.swift:82:21:82:21 | call to init(_:) | +| data.swift:82:21:82:37 | call to init(_:) | data.swift:82:6:82:6 | SSA def(dataTainted2) | +| data.swift:82:26:82:26 | [post] dataTainted | data.swift:85:12:85:12 | dataTainted | +| data.swift:82:26:82:26 | dataTainted | data.swift:82:21:82:37 | call to init(_:) | +| data.swift:82:26:82:26 | dataTainted | data.swift:85:12:85:12 | dataTainted | +| data.swift:89:6:89:6 | SSA def(dataTainted3) | data.swift:90:12:90:12 | dataTainted3 | +| data.swift:89:21:89:21 | Data.Type | data.swift:89:21:89:21 | call to init(base64Encoded:options:) | +| data.swift:89:21:89:71 | call to init(base64Encoded:options:) | data.swift:89:6:89:6 | SSA def(dataTainted3) | +| data.swift:89:41:89:48 | call to source() | data.swift:89:21:89:71 | call to init(base64Encoded:options:) | +| data.swift:93:6:93:6 | SSA def(dataTainted4) | data.swift:94:12:94:12 | dataTainted4 | +| data.swift:93:21:93:21 | Data.Type | data.swift:93:21:93:21 | call to init(buffer:) | +| data.swift:93:21:93:73 | call to init(buffer:) | data.swift:93:6:93:6 | SSA def(dataTainted4) | +| data.swift:93:34:93:41 | call to source() | data.swift:93:21:93:73 | call to init(buffer:) | +| data.swift:95:6:95:6 | SSA def(dataTainted5) | data.swift:96:12:96:12 | dataTainted5 | +| data.swift:95:21:95:21 | Data.Type | data.swift:95:21:95:21 | call to init(buffer:) | +| data.swift:95:21:95:74 | call to init(buffer:) | data.swift:95:6:95:6 | SSA def(dataTainted5) | +| data.swift:95:34:95:41 | call to source() | data.swift:95:21:95:74 | call to init(buffer:) | +| data.swift:99:6:99:6 | SSA def(dataTainted6) | data.swift:100:12:100:12 | dataTainted6 | +| data.swift:99:21:99:21 | Data.Type | data.swift:99:21:99:21 | call to init(bytes:count:) | +| data.swift:99:21:99:72 | call to init(bytes:count:) | data.swift:99:6:99:6 | SSA def(dataTainted6) | +| data.swift:99:33:99:40 | call to source() | data.swift:99:21:99:72 | call to init(bytes:count:) | +| data.swift:103:6:103:6 | SSA def(dataTainted7) | data.swift:104:12:104:12 | dataTainted7 | +| data.swift:103:21:103:21 | Data.Type | data.swift:103:21:103:21 | call to init(bytesNoCopy:count:deallocator:) | +| data.swift:103:21:103:114 | call to init(bytesNoCopy:count:deallocator:) | data.swift:103:6:103:6 | SSA def(dataTainted7) | +| data.swift:103:39:103:46 | call to source() | data.swift:103:21:103:114 | call to init(bytesNoCopy:count:deallocator:) | +| data.swift:107:6:107:6 | SSA def(urlTainted8) | data.swift:108:38:108:38 | urlTainted8 | +| data.swift:107:20:107:27 | call to source() | data.swift:107:6:107:6 | SSA def(urlTainted8) | +| data.swift:108:6:108:6 | SSA def(dataTainted8) | data.swift:109:12:109:12 | dataTainted8 | +| data.swift:108:21:108:21 | Data.Type | data.swift:108:21:108:21 | call to init(contentsOf:options:) | +| data.swift:108:21:108:62 | call to init(contentsOf:options:) | data.swift:108:6:108:6 | SSA def(dataTainted8) | +| data.swift:108:38:108:38 | urlTainted8 | data.swift:108:21:108:62 | call to init(contentsOf:options:) | +| data.swift:112:6:112:6 | SSA def(dataTainted9) | data.swift:113:12:113:12 | dataTainted9 | +| data.swift:112:21:112:21 | Data.Type | data.swift:112:21:112:21 | call to init(referencing:) | +| data.swift:112:21:112:58 | call to init(referencing:) | data.swift:112:6:112:6 | SSA def(dataTainted9) | +| data.swift:112:39:112:46 | call to source() | data.swift:112:21:112:58 | call to init(referencing:) | +| data.swift:116:6:116:6 | SSA def(dataTainted10) | data.swift:117:2:117:2 | dataTainted10 | +| data.swift:116:22:116:22 | Data.Type | data.swift:116:22:116:22 | call to init(_:) | +| data.swift:116:22:116:29 | call to init(_:) | data.swift:116:6:116:6 | SSA def(dataTainted10) | +| data.swift:116:27:116:27 | | data.swift:116:22:116:29 | call to init(_:) | +| data.swift:117:2:117:2 | [post] dataTainted10 | data.swift:118:12:118:12 | dataTainted10 | +| data.swift:117:2:117:2 | dataTainted10 | data.swift:118:12:118:12 | dataTainted10 | +| data.swift:117:23:117:30 | call to source() | data.swift:117:2:117:2 | [post] dataTainted10 | +| data.swift:120:6:120:6 | SSA def(dataTainted11) | data.swift:121:2:121:2 | dataTainted11 | +| data.swift:120:22:120:22 | Data.Type | data.swift:120:22:120:22 | call to init(_:) | +| data.swift:120:22:120:29 | call to init(_:) | data.swift:120:6:120:6 | SSA def(dataTainted11) | +| data.swift:120:27:120:27 | | data.swift:120:22:120:29 | call to init(_:) | +| data.swift:121:2:121:2 | [post] dataTainted11 | data.swift:122:12:122:12 | dataTainted11 | +| data.swift:121:2:121:2 | dataTainted11 | data.swift:122:12:122:12 | dataTainted11 | +| data.swift:121:23:121:30 | call to source() | data.swift:121:2:121:2 | [post] dataTainted11 | +| data.swift:124:6:124:6 | SSA def(dataTainted12) | data.swift:125:2:125:2 | dataTainted12 | +| data.swift:124:22:124:22 | Data.Type | data.swift:124:22:124:22 | call to init(_:) | +| data.swift:124:22:124:29 | call to init(_:) | data.swift:124:6:124:6 | SSA def(dataTainted12) | +| data.swift:124:27:124:27 | | data.swift:124:22:124:29 | call to init(_:) | +| data.swift:125:2:125:2 | [post] dataTainted12 | data.swift:126:12:126:12 | dataTainted12 | +| data.swift:125:2:125:2 | dataTainted12 | data.swift:126:12:126:12 | dataTainted12 | +| data.swift:125:23:125:30 | call to source() | data.swift:125:2:125:2 | [post] dataTainted12 | +| data.swift:129:6:129:6 | SSA def(dataTainted13) | data.swift:130:2:130:2 | dataTainted13 | +| data.swift:129:22:129:22 | Data.Type | data.swift:129:22:129:22 | call to init(_:) | +| data.swift:129:22:129:29 | call to init(_:) | data.swift:129:6:129:6 | SSA def(dataTainted13) | +| data.swift:129:27:129:27 | | data.swift:129:22:129:29 | call to init(_:) | +| data.swift:130:2:130:2 | [post] dataTainted13 | data.swift:131:12:131:12 | dataTainted13 | +| data.swift:130:2:130:2 | dataTainted13 | data.swift:131:12:131:12 | dataTainted13 | +| data.swift:130:23:130:30 | call to source() | data.swift:130:2:130:2 | [post] dataTainted13 | +| data.swift:134:6:134:6 | SSA def(dataTainted14) | data.swift:135:2:135:2 | dataTainted14 | +| data.swift:134:22:134:22 | Data.Type | data.swift:134:22:134:22 | call to init(_:) | +| data.swift:134:22:134:29 | call to init(_:) | data.swift:134:6:134:6 | SSA def(dataTainted14) | +| data.swift:134:27:134:27 | | data.swift:134:22:134:29 | call to init(_:) | +| data.swift:135:2:135:2 | [post] dataTainted14 | data.swift:136:12:136:12 | dataTainted14 | +| data.swift:135:2:135:2 | dataTainted14 | data.swift:136:12:136:12 | dataTainted14 | +| data.swift:135:35:135:42 | call to source() | data.swift:135:2:135:2 | [post] dataTainted14 | +| data.swift:139:6:139:6 | SSA def(dataTainted15) | data.swift:140:12:140:12 | dataTainted15 | +| data.swift:139:22:139:29 | call to source() | data.swift:139:6:139:6 | SSA def(dataTainted15) | +| data.swift:140:12:140:12 | dataTainted15 | data.swift:140:12:140:55 | call to base64EncodedData(options:) | +| data.swift:143:6:143:6 | SSA def(dataTainted16) | data.swift:144:12:144:12 | dataTainted16 | +| data.swift:143:22:143:29 | call to source() | data.swift:143:6:143:6 | SSA def(dataTainted16) | +| data.swift:144:12:144:12 | dataTainted16 | data.swift:144:12:144:57 | call to base64EncodedString(options:) | +| data.swift:147:6:147:6 | SSA def(dataTainted17) | data.swift:148:29:148:29 | dataTainted17 | +| data.swift:147:22:147:29 | call to source() | data.swift:147:6:147:6 | SSA def(dataTainted17) | +| data.swift:148:6:148:25 | SSA def(compactMapped) | data.swift:149:12:149:12 | compactMapped | +| data.swift:148:29:148:29 | dataTainted17 | data.swift:148:29:148:72 | call to compactMap(_:) | +| data.swift:148:29:148:72 | call to compactMap(_:) | data.swift:148:6:148:25 | SSA def(compactMapped) | +| data.swift:148:56:148:56 | SSA def(str) | data.swift:148:67:148:67 | str | +| data.swift:148:56:148:56 | str | data.swift:148:56:148:56 | SSA def(str) | +| data.swift:152:6:152:6 | SSA def(dataTainted18) | data.swift:154:2:154:2 | dataTainted18 | +| data.swift:152:22:152:29 | call to source() | data.swift:152:6:152:6 | SSA def(dataTainted18) | +| data.swift:153:6:153:6 | SSA def(pointerTainted18) | data.swift:154:30:154:30 | pointerTainted18 | +| data.swift:153:25:153:90 | call to allocate(byteCount:alignment:) | data.swift:153:6:153:6 | SSA def(pointerTainted18) | +| data.swift:154:2:154:2 | dataTainted18 | data.swift:154:30:154:30 | [post] pointerTainted18 | +| data.swift:154:30:154:30 | [post] pointerTainted18 | data.swift:155:12:155:12 | pointerTainted18 | +| data.swift:154:30:154:30 | pointerTainted18 | data.swift:155:12:155:12 | pointerTainted18 | +| data.swift:158:6:158:6 | SSA def(dataTainted19) | data.swift:160:2:160:2 | dataTainted19 | +| data.swift:158:22:158:29 | call to source() | data.swift:158:6:158:6 | SSA def(dataTainted19) | +| data.swift:159:6:159:6 | SSA def(pointerTainted19) | data.swift:160:30:160:30 | pointerTainted19 | +| data.swift:159:25:159:73 | call to allocate(capacity:) | data.swift:159:6:159:6 | SSA def(pointerTainted19) | +| data.swift:160:30:160:30 | pointerTainted19 | data.swift:161:12:161:12 | pointerTainted19 | +| data.swift:164:6:164:6 | SSA def(dataTainted20) | data.swift:166:2:166:2 | dataTainted20 | +| data.swift:164:22:164:29 | call to source() | data.swift:164:6:164:6 | SSA def(dataTainted20) | +| data.swift:165:6:165:6 | SSA def(pointerTainted20) | data.swift:166:30:166:30 | pointerTainted20 | +| data.swift:165:25:165:73 | call to allocate(capacity:) | data.swift:165:6:165:6 | SSA def(pointerTainted20) | +| data.swift:166:30:166:30 | pointerTainted20 | data.swift:167:12:167:12 | pointerTainted20 | +| data.swift:170:6:170:6 | SSA def(dataTainted21) | data.swift:171:19:171:19 | dataTainted21 | +| data.swift:170:22:170:29 | call to source() | data.swift:170:6:170:6 | SSA def(dataTainted21) | +| data.swift:171:6:171:6 | SSA def(flatMapped) | data.swift:172:12:172:12 | flatMapped | +| data.swift:171:19:171:19 | dataTainted21 | data.swift:171:19:171:74 | call to flatMap(_:) | +| data.swift:171:19:171:74 | call to flatMap(_:) | data.swift:171:6:171:6 | SSA def(flatMapped) | +| data.swift:171:41:171:41 | $0 | data.swift:171:41:171:41 | SSA def($0) | +| data.swift:171:41:171:41 | SSA def($0) | data.swift:171:60:171:60 | $0 | +| data.swift:174:6:174:6 | SSA def(dataTainted22) | data.swift:175:20:175:20 | dataTainted22 | +| data.swift:174:22:174:29 | call to source() | data.swift:174:6:174:6 | SSA def(dataTainted22) | +| data.swift:175:6:175:6 | SSA def(flatMapped2) | data.swift:176:12:176:12 | flatMapped2 | +| data.swift:175:20:175:20 | dataTainted22 | data.swift:175:20:175:60 | call to flatMap(_:) | +| data.swift:175:20:175:60 | call to flatMap(_:) | data.swift:175:6:175:6 | SSA def(flatMapped2) | +| data.swift:175:44:175:44 | SSA def(str) | data.swift:175:55:175:55 | str | +| data.swift:175:44:175:44 | str | data.swift:175:44:175:44 | SSA def(str) | +| data.swift:179:6:179:6 | SSA def(dataTainted23) | data.swift:180:2:180:2 | dataTainted23 | +| data.swift:179:22:179:22 | Data.Type | data.swift:179:22:179:22 | call to init(_:) | +| data.swift:179:22:179:29 | call to init(_:) | data.swift:179:6:179:6 | SSA def(dataTainted23) | +| data.swift:179:27:179:27 | | data.swift:179:22:179:29 | call to init(_:) | +| data.swift:180:2:180:2 | [post] dataTainted23 | data.swift:181:12:181:12 | dataTainted23 | +| data.swift:180:2:180:2 | dataTainted23 | data.swift:181:12:181:12 | dataTainted23 | +| data.swift:180:23:180:30 | call to source() | data.swift:180:2:180:2 | [post] dataTainted23 | +| data.swift:184:6:184:6 | SSA def(dataTainted24) | data.swift:185:2:185:2 | dataTainted24 | +| data.swift:184:22:184:22 | Data.Type | data.swift:184:22:184:22 | call to init(_:) | +| data.swift:184:22:184:29 | call to init(_:) | data.swift:184:6:184:6 | SSA def(dataTainted24) | +| data.swift:184:27:184:27 | | data.swift:184:22:184:29 | call to init(_:) | +| data.swift:185:2:185:2 | [post] dataTainted24 | data.swift:186:12:186:12 | dataTainted24 | +| data.swift:185:2:185:2 | dataTainted24 | data.swift:186:12:186:12 | dataTainted24 | +| data.swift:185:35:185:42 | call to source() | data.swift:185:2:185:2 | [post] dataTainted24 | +| data.swift:189:6:189:6 | SSA def(dataTainted25) | data.swift:190:15:190:15 | dataTainted25 | +| data.swift:189:22:189:29 | call to source() | data.swift:189:6:189:6 | SSA def(dataTainted25) | +| data.swift:190:6:190:6 | SSA def(mapped) | data.swift:191:12:191:12 | mapped | +| data.swift:190:15:190:15 | dataTainted25 | data.swift:190:15:190:38 | call to map(_:) | +| data.swift:190:15:190:38 | call to map(_:) | data.swift:190:6:190:6 | SSA def(mapped) | +| data.swift:190:33:190:33 | $0 | data.swift:190:33:190:33 | SSA def($0) | +| data.swift:190:33:190:33 | SSA def($0) | data.swift:190:35:190:35 | $0 | +| data.swift:194:6:194:6 | SSA def(dataTainted26) | data.swift:195:16:195:16 | dataTainted26 | +| data.swift:194:22:194:29 | call to source() | data.swift:194:6:194:6 | SSA def(dataTainted26) | +| data.swift:195:6:195:6 | SSA def(reduced) | data.swift:196:12:196:12 | reduced | +| data.swift:195:16:195:16 | dataTainted26 | data.swift:195:16:195:80 | call to reduce(into:_:) | +| data.swift:195:16:195:80 | call to reduce(into:_:) | data.swift:195:6:195:6 | SSA def(reduced) | +| data.swift:195:50:195:50 | SSA def(c) | data.swift:195:58:195:58 | c | +| data.swift:195:50:195:50 | c | data.swift:195:50:195:50 | SSA def(c) | +| data.swift:195:53:195:53 | SSA def(i) | data.swift:195:60:195:60 | i | +| data.swift:195:53:195:53 | i | data.swift:195:53:195:53 | SSA def(i) | | data.swift:195:58:195:58 | &... | data.swift:195:58:195:73 | ...[...] | +| data.swift:195:58:195:58 | c | data.swift:195:58:195:58 | &... | +| data.swift:195:58:195:73 | ...[...] | data.swift:195:58:195:73 | &... | +| data.swift:199:6:199:6 | SSA def(dataTainted27) | data.swift:200:2:200:2 | dataTainted27 | +| data.swift:199:22:199:22 | Data.Type | data.swift:199:22:199:22 | call to init(_:) | +| data.swift:199:22:199:29 | call to init(_:) | data.swift:199:6:199:6 | SSA def(dataTainted27) | +| data.swift:199:27:199:27 | | data.swift:199:22:199:29 | call to init(_:) | +| data.swift:200:2:200:2 | [post] dataTainted27 | data.swift:201:12:201:12 | dataTainted27 | +| data.swift:200:2:200:2 | dataTainted27 | data.swift:201:12:201:12 | dataTainted27 | +| data.swift:200:35:200:42 | call to source() | data.swift:200:2:200:2 | [post] dataTainted27 | +| data.swift:204:6:204:6 | SSA def(dataTainted28) | data.swift:205:2:205:2 | dataTainted28 | +| data.swift:204:22:204:22 | Data.Type | data.swift:204:22:204:22 | call to init(_:) | +| data.swift:204:22:204:29 | call to init(_:) | data.swift:204:6:204:6 | SSA def(dataTainted28) | +| data.swift:204:27:204:27 | | data.swift:204:22:204:29 | call to init(_:) | +| data.swift:205:2:205:2 | [post] dataTainted28 | data.swift:206:12:206:12 | dataTainted28 | +| data.swift:205:2:205:2 | dataTainted28 | data.swift:206:12:206:12 | dataTainted28 | +| data.swift:205:45:205:52 | call to source() | data.swift:205:2:205:2 | [post] dataTainted28 | +| data.swift:208:6:208:6 | SSA def(dataTainted29) | data.swift:209:2:209:2 | dataTainted29 | +| data.swift:208:22:208:22 | Data.Type | data.swift:208:22:208:22 | call to init(_:) | +| data.swift:208:22:208:29 | call to init(_:) | data.swift:208:6:208:6 | SSA def(dataTainted29) | +| data.swift:208:27:208:27 | | data.swift:208:22:208:29 | call to init(_:) | +| data.swift:209:2:209:2 | [post] dataTainted29 | data.swift:210:12:210:12 | dataTainted29 | +| data.swift:209:2:209:2 | dataTainted29 | data.swift:210:12:210:12 | dataTainted29 | +| data.swift:209:45:209:52 | call to source() | data.swift:209:2:209:2 | [post] dataTainted29 | +| data.swift:212:6:212:6 | SSA def(dataTainted30) | data.swift:213:2:213:2 | dataTainted30 | +| data.swift:212:22:212:22 | Data.Type | data.swift:212:22:212:22 | call to init(_:) | +| data.swift:212:22:212:29 | call to init(_:) | data.swift:212:6:212:6 | SSA def(dataTainted30) | +| data.swift:212:27:212:27 | | data.swift:212:22:212:29 | call to init(_:) | +| data.swift:213:2:213:2 | [post] dataTainted30 | data.swift:214:12:214:12 | dataTainted30 | +| data.swift:213:2:213:2 | dataTainted30 | data.swift:214:12:214:12 | dataTainted30 | +| data.swift:213:45:213:52 | call to source() | data.swift:213:2:213:2 | [post] dataTainted30 | +| data.swift:217:6:217:6 | SSA def(dataTainted31) | data.swift:218:2:218:2 | dataTainted31 | +| data.swift:217:22:217:22 | Data.Type | data.swift:217:22:217:22 | call to init(_:) | +| data.swift:217:22:217:29 | call to init(_:) | data.swift:217:6:217:6 | SSA def(dataTainted31) | +| data.swift:217:27:217:27 | | data.swift:217:22:217:29 | call to init(_:) | +| data.swift:218:2:218:2 | [post] dataTainted31 | data.swift:219:12:219:12 | dataTainted31 | +| data.swift:218:2:218:2 | dataTainted31 | data.swift:219:12:219:12 | dataTainted31 | +| data.swift:218:45:218:52 | call to source() | data.swift:218:2:218:2 | [post] dataTainted31 | +| data.swift:222:6:222:6 | SSA def(dataTainted32) | data.swift:223:10:223:10 | dataTainted32 | +| data.swift:222:22:222:22 | Data.Type | data.swift:222:22:222:22 | call to init(_:) | +| data.swift:222:22:222:29 | call to init(_:) | data.swift:222:6:222:6 | SSA def(dataTainted32) | +| data.swift:222:27:222:27 | | data.swift:222:22:222:29 | call to init(_:) | +| data.swift:223:10:223:10 | [post] dataTainted32 | data.swift:224:12:224:12 | dataTainted32 | +| data.swift:223:10:223:10 | dataTainted32 | data.swift:224:12:224:12 | dataTainted32 | +| data.swift:223:45:223:52 | call to source() | data.swift:223:10:223:10 | [post] dataTainted32 | +| data.swift:227:6:227:6 | SSA def(dataTainted33) | data.swift:228:10:228:10 | dataTainted33 | +| data.swift:227:22:227:22 | Data.Type | data.swift:227:22:227:22 | call to init(_:) | +| data.swift:227:22:227:29 | call to init(_:) | data.swift:227:6:227:6 | SSA def(dataTainted33) | +| data.swift:227:27:227:27 | | data.swift:227:22:227:29 | call to init(_:) | +| data.swift:228:10:228:10 | [post] dataTainted33 | data.swift:229:12:229:12 | dataTainted33 | +| data.swift:228:10:228:10 | dataTainted33 | data.swift:229:12:229:12 | dataTainted33 | +| data.swift:228:45:228:52 | call to source() | data.swift:228:10:228:10 | [post] dataTainted33 | +| data.swift:232:6:232:6 | SSA def(dataTainted34) | data.swift:233:12:233:12 | dataTainted34 | +| data.swift:232:22:232:29 | call to source() | data.swift:232:6:232:6 | SSA def(dataTainted34) | +| data.swift:236:6:236:6 | SSA def(dataTainted35) | data.swift:237:12:237:12 | dataTainted35 | +| data.swift:236:22:236:29 | call to source() | data.swift:236:6:236:6 | SSA def(dataTainted35) | +| data.swift:237:12:237:12 | dataTainted35 | data.swift:237:12:237:33 | call to sorted() | +| data.swift:240:6:240:6 | SSA def(dataTainted36) | data.swift:241:12:241:12 | dataTainted36 | +| data.swift:240:22:240:29 | call to source() | data.swift:240:6:240:6 | SSA def(dataTainted36) | +| data.swift:241:12:241:12 | dataTainted36 | data.swift:241:12:241:54 | call to sorted(by:) | +| data.swift:244:6:244:6 | SSA def(dataTainted37) | data.swift:245:12:245:12 | dataTainted37 | +| data.swift:244:22:244:29 | call to source() | data.swift:244:6:244:6 | SSA def(dataTainted37) | +| data.swift:245:12:245:12 | dataTainted37 | data.swift:245:12:245:46 | call to sorted(using:) | +| data.swift:245:40:245:44 | call to cmp() | data.swift:245:40:245:45 | ...! | +| data.swift:248:6:248:6 | SSA def(dataTainted38) | data.swift:249:12:249:12 | dataTainted38 | +| data.swift:248:22:248:29 | call to source() | data.swift:248:6:248:6 | SSA def(dataTainted38) | +| data.swift:249:12:249:12 | dataTainted38 | data.swift:249:12:249:35 | call to shuffled() | +| data.swift:252:6:252:6 | SSA def(dataTainted39) | data.swift:254:12:254:12 | dataTainted39 | +| data.swift:252:22:252:29 | call to source() | data.swift:252:6:252:6 | SSA def(dataTainted39) | +| data.swift:253:6:253:6 | SSA def(rng) | data.swift:254:43:254:43 | rng | +| data.swift:253:12:253:16 | call to rng() | data.swift:253:12:253:17 | ...! | +| data.swift:253:12:253:17 | ...! | data.swift:253:6:253:6 | SSA def(rng) | +| data.swift:254:12:254:12 | dataTainted39 | data.swift:254:12:254:46 | call to shuffled(using:) | +| data.swift:254:43:254:43 | rng | data.swift:254:42:254:43 | &... | +| data.swift:257:6:257:6 | SSA def(dataTainted40) | data.swift:258:12:258:12 | dataTainted40 | +| data.swift:257:22:257:29 | call to source() | data.swift:257:6:257:6 | SSA def(dataTainted40) | +| data.swift:258:12:258:12 | dataTainted40 | data.swift:258:12:258:44 | call to trimmingPrefix(_:) | +| data.swift:261:6:261:6 | SSA def(dataTainted41) | data.swift:262:12:262:12 | dataTainted41 | +| data.swift:261:22:261:29 | call to source() | data.swift:261:6:261:6 | SSA def(dataTainted41) | +| data.swift:262:12:262:12 | dataTainted41 | data.swift:262:12:262:54 | call to trimmingPrefix(while:) | +| nsdata.swift:5:2:5:2 | SSA def(self) | nsdata.swift:5:2:5:25 | self[return] | +| nsdata.swift:5:2:5:2 | self | nsdata.swift:5:2:5:2 | SSA def(self) | +| nsdata.swift:10:5:10:5 | SSA def(self) | nsdata.swift:10:5:10:29 | self[return] | +| nsdata.swift:10:5:10:5 | self | nsdata.swift:10:5:10:5 | SSA def(self) | +| nsdata.swift:13:8:13:8 | SSA def(self) | nsdata.swift:13:8:13:8 | self[return] | +| nsdata.swift:13:8:13:8 | self | nsdata.swift:13:8:13:8 | SSA def(self) | +| nsdata.swift:15:8:15:8 | SSA def(self) | nsdata.swift:15:8:15:8 | self[return] | +| nsdata.swift:15:8:15:8 | self | nsdata.swift:15:8:15:8 | SSA def(self) | +| nsdata.swift:17:7:17:7 | SSA def(self) | nsdata.swift:17:7:17:7 | self[return] | +| nsdata.swift:17:7:17:7 | self | nsdata.swift:17:7:17:7 | SSA def(self) | +| nsdata.swift:18:45:18:45 | self | nsdata.swift:18:45:18:45 | SSA def(self) | +| nsdata.swift:19:52:19:52 | self | nsdata.swift:19:52:19:52 | SSA def(self) | +| nsdata.swift:20:52:20:52 | self | nsdata.swift:20:52:20:52 | SSA def(self) | +| nsdata.swift:22:9:22:9 | self | nsdata.swift:22:9:22:9 | SSA def(self) | +| nsdata.swift:22:9:22:9 | self | nsdata.swift:22:9:22:9 | SSA def(self) | +| nsdata.swift:22:9:22:9 | self | nsdata.swift:22:9:22:9 | SSA def(self) | +| nsdata.swift:22:9:22:9 | value | nsdata.swift:22:9:22:9 | SSA def(value) | +| nsdata.swift:23:9:23:9 | self | nsdata.swift:23:9:23:9 | SSA def(self) | +| nsdata.swift:23:9:23:9 | self | nsdata.swift:23:9:23:9 | SSA def(self) | +| nsdata.swift:23:9:23:9 | self | nsdata.swift:23:9:23:9 | SSA def(self) | +| nsdata.swift:23:9:23:9 | value | nsdata.swift:23:9:23:9 | SSA def(value) | +| nsdata.swift:24:5:24:5 | SSA def(self) | nsdata.swift:24:5:24:50 | self[return] | +| nsdata.swift:24:5:24:5 | self | nsdata.swift:24:5:24:5 | SSA def(self) | +| nsdata.swift:25:5:25:5 | SSA def(self) | nsdata.swift:25:5:25:68 | self[return] | +| nsdata.swift:25:5:25:5 | self | nsdata.swift:25:5:25:5 | SSA def(self) | +| nsdata.swift:26:5:26:5 | SSA def(self) | nsdata.swift:26:5:26:130 | self[return] | +| nsdata.swift:26:5:26:5 | self | nsdata.swift:26:5:26:5 | SSA def(self) | +| nsdata.swift:27:5:27:5 | SSA def(self) | nsdata.swift:27:5:27:90 | self[return] | +| nsdata.swift:27:5:27:5 | self | nsdata.swift:27:5:27:5 | SSA def(self) | +| nsdata.swift:28:5:28:5 | SSA def(self) | nsdata.swift:28:5:28:23 | self[return] | +| nsdata.swift:28:5:28:5 | self | nsdata.swift:28:5:28:5 | SSA def(self) | +| nsdata.swift:29:5:29:5 | SSA def(self) | nsdata.swift:29:5:29:36 | self[return] | +| nsdata.swift:29:5:29:5 | self | nsdata.swift:29:5:29:5 | SSA def(self) | +| nsdata.swift:30:5:30:5 | SSA def(self) | nsdata.swift:30:5:30:93 | self[return] | +| nsdata.swift:30:5:30:5 | self | nsdata.swift:30:5:30:5 | SSA def(self) | +| nsdata.swift:31:5:31:5 | SSA def(self) | nsdata.swift:31:5:31:29 | self[return] | +| nsdata.swift:31:5:31:5 | self | nsdata.swift:31:5:31:5 | SSA def(self) | +| nsdata.swift:32:5:32:5 | SSA def(self) | nsdata.swift:32:5:32:61 | self[return] | +| nsdata.swift:32:5:32:5 | self | nsdata.swift:32:5:32:5 | SSA def(self) | +| nsdata.swift:33:5:33:5 | SSA def(self) | nsdata.swift:33:5:33:47 | self[return] | +| nsdata.swift:33:5:33:5 | self | nsdata.swift:33:5:33:5 | SSA def(self) | +| nsdata.swift:34:5:34:5 | SSA def(self) | nsdata.swift:34:5:34:88 | self[return] | +| nsdata.swift:34:5:34:5 | self | nsdata.swift:34:5:34:5 | SSA def(self) | +| nsdata.swift:35:5:35:5 | SSA def(self) | nsdata.swift:35:5:35:92 | self[return] | +| nsdata.swift:35:5:35:5 | self | nsdata.swift:35:5:35:5 | SSA def(self) | +| nsdata.swift:36:5:36:5 | SSA def(self) | nsdata.swift:36:5:36:49 | self[return] | +| nsdata.swift:36:5:36:5 | self | nsdata.swift:36:5:36:5 | SSA def(self) | +| nsdata.swift:37:10:37:10 | SSA def(self) | nsdata.swift:37:5:37:98 | self[return] | +| nsdata.swift:37:10:37:10 | self | nsdata.swift:37:10:37:10 | SSA def(self) | +| nsdata.swift:37:89:37:89 | Data.Type | nsdata.swift:37:89:37:89 | call to init(_:) | +| nsdata.swift:37:94:37:94 | | nsdata.swift:37:89:37:96 | call to init(_:) | +| nsdata.swift:38:10:38:10 | SSA def(self) | nsdata.swift:38:5:38:96 | self[return] | +| nsdata.swift:38:10:38:10 | self | nsdata.swift:38:10:38:10 | SSA def(self) | +| nsdata.swift:39:10:39:10 | SSA def(self) | nsdata.swift:39:5:39:49 | self[return] | +| nsdata.swift:39:10:39:10 | self | nsdata.swift:39:10:39:10 | SSA def(self) | +| nsdata.swift:40:16:40:16 | SSA def(self) | nsdata.swift:40:5:40:82 | self[return] | +| nsdata.swift:40:16:40:16 | self | nsdata.swift:40:16:40:16 | SSA def(self) | +| nsdata.swift:41:10:41:10 | SSA def(self) | nsdata.swift:41:5:41:104 | self[return] | +| nsdata.swift:41:10:41:10 | self | nsdata.swift:41:10:41:10 | SSA def(self) | +| nsdata.swift:42:10:42:10 | SSA def(self) | nsdata.swift:42:5:42:55 | self[return] | +| nsdata.swift:42:10:42:10 | self | nsdata.swift:42:10:42:10 | SSA def(self) | +| nsdata.swift:43:10:43:10 | SSA def(self) | nsdata.swift:43:5:43:68 | self[return] | +| nsdata.swift:43:10:43:10 | self | nsdata.swift:43:10:43:10 | SSA def(self) | +| nsdata.swift:44:10:44:10 | SSA def(self) | nsdata.swift:44:5:44:71 | self[return] | +| nsdata.swift:44:10:44:10 | self | nsdata.swift:44:10:44:10 | SSA def(self) | +| nsdata.swift:45:10:45:10 | SSA def(self) | nsdata.swift:45:5:45:65 | self[return] | +| nsdata.swift:45:10:45:10 | self | nsdata.swift:45:10:45:10 | SSA def(self) | +| nsdata.swift:45:56:45:56 | Data.Type | nsdata.swift:45:56:45:56 | call to init(_:) | +| nsdata.swift:45:61:45:61 | | nsdata.swift:45:56:45:63 | call to init(_:) | +| nsdata.swift:46:10:46:10 | SSA def(self) | nsdata.swift:46:84:46:84 | self | +| nsdata.swift:46:10:46:10 | self | nsdata.swift:46:10:46:10 | SSA def(self) | +| nsdata.swift:46:84:46:84 | self | nsdata.swift:46:5:46:89 | self[return] | +| nsdata.swift:47:10:47:10 | SSA def(self) | nsdata.swift:47:86:47:86 | self | +| nsdata.swift:47:10:47:10 | self | nsdata.swift:47:10:47:10 | SSA def(self) | +| nsdata.swift:47:86:47:86 | self | nsdata.swift:47:5:47:91 | self[return] | +| nsdata.swift:57:9:57:9 | SSA def(nsDataTainted1) | nsdata.swift:58:15:58:15 | nsDataTainted1 | +| nsdata.swift:57:26:57:26 | NSData.Type | nsdata.swift:57:26:57:26 | call to init(bytes:length:) | +| nsdata.swift:57:26:57:80 | call to init(bytes:length:) | nsdata.swift:57:9:57:9 | SSA def(nsDataTainted1) | +| nsdata.swift:57:40:57:47 | call to source() | nsdata.swift:57:26:57:80 | call to init(bytes:length:) | +| nsdata.swift:60:9:60:9 | SSA def(nsDataTainted2) | nsdata.swift:61:15:61:15 | nsDataTainted2 | +| nsdata.swift:60:26:60:26 | NSData.Type | nsdata.swift:60:26:60:26 | call to init(bytesNoCopy:length:) | +| nsdata.swift:60:26:60:93 | call to init(bytesNoCopy:length:) | nsdata.swift:60:9:60:9 | SSA def(nsDataTainted2) | +| nsdata.swift:60:46:60:53 | call to source() | nsdata.swift:60:26:60:93 | call to init(bytesNoCopy:length:) | +| nsdata.swift:63:9:63:9 | SSA def(nsDataTainted3) | nsdata.swift:64:15:64:15 | nsDataTainted3 | +| nsdata.swift:63:26:63:26 | NSData.Type | nsdata.swift:63:26:63:26 | call to init(bytesNoCopy:length:deallocator:) | +| nsdata.swift:63:26:63:111 | call to init(bytesNoCopy:length:deallocator:) | nsdata.swift:63:9:63:9 | SSA def(nsDataTainted3) | +| nsdata.swift:63:46:63:53 | call to source() | nsdata.swift:63:26:63:111 | call to init(bytesNoCopy:length:deallocator:) | +| nsdata.swift:66:9:66:9 | SSA def(nsDataTainted4) | nsdata.swift:67:15:67:15 | nsDataTainted4 | +| nsdata.swift:66:26:66:26 | NSData.Type | nsdata.swift:66:26:66:26 | call to init(bytesNoCopy:length:freeWhenDone:) | +| nsdata.swift:66:26:66:113 | call to init(bytesNoCopy:length:freeWhenDone:) | nsdata.swift:66:9:66:9 | SSA def(nsDataTainted4) | +| nsdata.swift:66:46:66:53 | call to source() | nsdata.swift:66:26:66:113 | call to init(bytesNoCopy:length:freeWhenDone:) | +| nsdata.swift:69:9:69:9 | SSA def(nsDataTainted5) | nsdata.swift:70:15:70:15 | nsDataTainted5 | +| nsdata.swift:69:26:69:26 | NSData.Type | nsdata.swift:69:26:69:26 | call to init(data:) | +| nsdata.swift:69:26:69:56 | call to init(data:) | nsdata.swift:69:9:69:9 | SSA def(nsDataTainted5) | +| nsdata.swift:69:39:69:46 | call to source() | nsdata.swift:69:26:69:56 | call to init(data:) | +| nsdata.swift:72:9:72:9 | SSA def(nsDataTainted6) | nsdata.swift:73:15:73:15 | nsDataTainted6 | +| nsdata.swift:72:26:72:26 | NSData.Type | nsdata.swift:72:26:72:26 | call to init(contentsOfFile:) | +| nsdata.swift:72:26:72:68 | call to init(contentsOfFile:) | nsdata.swift:72:9:72:9 | SSA def(nsDataTainted6) | +| nsdata.swift:72:49:72:56 | call to source() | nsdata.swift:72:26:72:68 | call to init(contentsOfFile:) | +| nsdata.swift:73:15:73:15 | nsDataTainted6 | nsdata.swift:73:15:73:29 | ...! | +| nsdata.swift:75:9:75:9 | SSA def(nsDataTainted7) | nsdata.swift:76:15:76:15 | nsDataTainted7 | +| nsdata.swift:75:26:75:26 | NSData.Type | nsdata.swift:75:26:75:26 | call to init(contentsOfFile:options:) | +| nsdata.swift:75:26:75:81 | call to init(contentsOfFile:options:) | nsdata.swift:75:9:75:9 | SSA def(nsDataTainted7) | +| nsdata.swift:75:49:75:56 | call to source() | nsdata.swift:75:26:75:81 | call to init(contentsOfFile:options:) | +| nsdata.swift:78:9:78:9 | SSA def(nsDataTainted8) | nsdata.swift:79:15:79:15 | nsDataTainted8 | +| nsdata.swift:78:26:78:26 | NSData.Type | nsdata.swift:78:26:78:26 | call to init(contentsOf:) | +| nsdata.swift:78:26:78:61 | call to init(contentsOf:) | nsdata.swift:78:9:78:9 | SSA def(nsDataTainted8) | +| nsdata.swift:78:45:78:52 | call to source() | nsdata.swift:78:26:78:61 | call to init(contentsOf:) | +| nsdata.swift:79:15:79:15 | nsDataTainted8 | nsdata.swift:79:15:79:29 | ...! | +| nsdata.swift:81:9:81:9 | SSA def(nsDataTainted9) | nsdata.swift:82:15:82:15 | nsDataTainted9 | +| nsdata.swift:81:26:81:26 | NSData.Type | nsdata.swift:81:26:81:26 | call to init(contentsOf:options:) | +| nsdata.swift:81:26:81:74 | call to init(contentsOf:options:) | nsdata.swift:81:9:81:9 | SSA def(nsDataTainted9) | +| nsdata.swift:81:45:81:52 | call to source() | nsdata.swift:81:26:81:74 | call to init(contentsOf:options:) | +| nsdata.swift:82:15:82:15 | nsDataTainted9 | nsdata.swift:82:15:82:29 | ...! | +| nsdata.swift:84:9:84:9 | SSA def(nsDataTainted10) | nsdata.swift:85:15:85:15 | nsDataTainted10 | +| nsdata.swift:84:27:84:27 | NSData.Type | nsdata.swift:84:27:84:27 | call to init(contentsOfMappedFile:) | +| nsdata.swift:84:27:84:75 | call to init(contentsOfMappedFile:) | nsdata.swift:84:9:84:9 | SSA def(nsDataTainted10) | +| nsdata.swift:84:56:84:63 | call to source() | nsdata.swift:84:27:84:75 | call to init(contentsOfMappedFile:) | +| nsdata.swift:85:15:85:15 | nsDataTainted10 | nsdata.swift:85:15:85:30 | ...! | +| nsdata.swift:87:9:87:9 | SSA def(nsDataTainted11) | nsdata.swift:88:15:88:15 | nsDataTainted11 | +| nsdata.swift:87:27:87:27 | NSData.Type | nsdata.swift:87:27:87:27 | call to init(base64Encoded:options:) | +| nsdata.swift:87:27:87:79 | call to init(base64Encoded:options:) | nsdata.swift:87:9:87:9 | SSA def(nsDataTainted11) | +| nsdata.swift:87:49:87:56 | call to source() | nsdata.swift:87:27:87:79 | call to init(base64Encoded:options:) | +| nsdata.swift:88:15:88:15 | nsDataTainted11 | nsdata.swift:88:15:88:30 | ...! | +| nsdata.swift:89:9:89:9 | SSA def(nsDataTainted12) | nsdata.swift:90:15:90:15 | nsDataTainted12 | +| nsdata.swift:89:27:89:27 | NSData.Type | nsdata.swift:89:27:89:27 | call to init(base64Encoded:options:) | +| nsdata.swift:89:27:89:81 | call to init(base64Encoded:options:) | nsdata.swift:89:9:89:9 | SSA def(nsDataTainted12) | +| nsdata.swift:89:49:89:56 | call to source() | nsdata.swift:89:27:89:81 | call to init(base64Encoded:options:) | +| nsdata.swift:90:15:90:15 | nsDataTainted12 | nsdata.swift:90:15:90:30 | ...! | +| nsdata.swift:92:9:92:9 | SSA def(nsDataTainted13) | nsdata.swift:93:15:93:15 | nsDataTainted13 | +| nsdata.swift:92:27:92:27 | NSData.Type | nsdata.swift:92:27:92:27 | call to init(base64Encoding:) | +| nsdata.swift:92:27:92:69 | call to init(base64Encoding:) | nsdata.swift:92:9:92:9 | SSA def(nsDataTainted13) | +| nsdata.swift:92:50:92:57 | call to source() | nsdata.swift:92:27:92:69 | call to init(base64Encoding:) | +| nsdata.swift:93:15:93:15 | nsDataTainted13 | nsdata.swift:93:15:93:30 | ...! | +| nsdata.swift:95:9:95:9 | SSA def(nsDataTainted14) | nsdata.swift:96:15:96:15 | nsDataTainted14 | +| nsdata.swift:95:27:95:34 | call to source() | nsdata.swift:95:9:95:9 | SSA def(nsDataTainted14) | +| nsdata.swift:96:15:96:15 | [post] nsDataTainted14 | nsdata.swift:97:15:97:15 | nsDataTainted14 | +| nsdata.swift:96:15:96:15 | nsDataTainted14 | nsdata.swift:96:15:96:49 | call to base64EncodedData(options:) | +| nsdata.swift:96:15:96:15 | nsDataTainted14 | nsdata.swift:97:15:97:15 | nsDataTainted14 | +| nsdata.swift:97:15:97:15 | nsDataTainted14 | nsdata.swift:97:15:97:60 | call to base64EncodedData(options:) | +| nsdata.swift:99:9:99:9 | SSA def(nsDataTainted15) | nsdata.swift:100:15:100:15 | nsDataTainted15 | +| nsdata.swift:99:27:99:34 | call to source() | nsdata.swift:99:9:99:9 | SSA def(nsDataTainted15) | +| nsdata.swift:100:15:100:15 | [post] nsDataTainted15 | nsdata.swift:101:15:101:15 | nsDataTainted15 | +| nsdata.swift:100:15:100:15 | nsDataTainted15 | nsdata.swift:100:15:100:51 | call to base64EncodedString(options:) | +| nsdata.swift:100:15:100:15 | nsDataTainted15 | nsdata.swift:101:15:101:15 | nsDataTainted15 | +| nsdata.swift:101:15:101:15 | nsDataTainted15 | nsdata.swift:101:15:101:62 | call to base64EncodedString(options:) | +| nsdata.swift:103:9:103:9 | SSA def(nsDataTainted16) | nsdata.swift:104:15:104:15 | nsDataTainted16 | +| nsdata.swift:103:27:103:34 | call to source() | nsdata.swift:103:9:103:9 | SSA def(nsDataTainted16) | +| nsdata.swift:104:15:104:15 | nsDataTainted16 | nsdata.swift:104:15:104:46 | call to base64Encoding() | +| nsdata.swift:106:15:106:70 | call to dataWithContentsOfMappedFile(_:) | nsdata.swift:106:15:106:71 | ...! | +| nsdata.swift:106:51:106:58 | call to source() | nsdata.swift:106:15:106:70 | call to dataWithContentsOfMappedFile(_:) | +| nsdata.swift:108:9:108:9 | SSA def(nsDataTainted17) | nsdata.swift:109:5:109:5 | nsDataTainted17 | +| nsdata.swift:108:27:108:34 | call to source() | nsdata.swift:108:9:108:9 | SSA def(nsDataTainted17) | +| nsdata.swift:110:9:110:9 | SSA def(bytes) | nsdata.swift:110:45:110:45 | bytes | +| nsdata.swift:110:9:110:9 | bytes | nsdata.swift:110:9:110:9 | SSA def(bytes) | +| nsdata.swift:113:9:113:9 | SSA def(nsDataTainted18) | nsdata.swift:115:5:115:5 | nsDataTainted18 | +| nsdata.swift:113:27:113:34 | call to source() | nsdata.swift:113:9:113:9 | SSA def(nsDataTainted18) | +| nsdata.swift:114:9:114:9 | SSA def(bufferTainted18) | nsdata.swift:115:30:115:30 | bufferTainted18 | +| nsdata.swift:114:27:114:64 | call to init(bitPattern:) | nsdata.swift:114:27:114:65 | ...! | +| nsdata.swift:114:27:114:65 | ...! | nsdata.swift:114:9:114:9 | SSA def(bufferTainted18) | +| nsdata.swift:115:5:115:5 | nsDataTainted18 | nsdata.swift:115:30:115:30 | [post] bufferTainted18 | +| nsdata.swift:115:30:115:30 | [post] bufferTainted18 | nsdata.swift:116:15:116:15 | bufferTainted18 | +| nsdata.swift:115:30:115:30 | bufferTainted18 | nsdata.swift:116:15:116:15 | bufferTainted18 | +| nsdata.swift:118:9:118:9 | SSA def(nsDataTainted19) | nsdata.swift:120:5:120:5 | nsDataTainted19 | +| nsdata.swift:118:27:118:34 | call to source() | nsdata.swift:118:9:118:9 | SSA def(nsDataTainted19) | +| nsdata.swift:119:9:119:9 | SSA def(bufferTainted19) | nsdata.swift:120:30:120:30 | bufferTainted19 | +| nsdata.swift:119:27:119:64 | call to init(bitPattern:) | nsdata.swift:119:27:119:65 | ...! | +| nsdata.swift:119:27:119:65 | ...! | nsdata.swift:119:9:119:9 | SSA def(bufferTainted19) | +| nsdata.swift:120:5:120:5 | nsDataTainted19 | nsdata.swift:120:30:120:30 | [post] bufferTainted19 | +| nsdata.swift:120:30:120:30 | [post] bufferTainted19 | nsdata.swift:121:15:121:15 | bufferTainted19 | +| nsdata.swift:120:30:120:30 | bufferTainted19 | nsdata.swift:121:15:121:15 | bufferTainted19 | +| nsdata.swift:123:9:123:9 | SSA def(nsDataTainted20) | nsdata.swift:125:5:125:5 | nsDataTainted20 | +| nsdata.swift:123:27:123:34 | call to source() | nsdata.swift:123:9:123:9 | SSA def(nsDataTainted20) | +| nsdata.swift:124:9:124:9 | SSA def(bufferTainted20) | nsdata.swift:125:30:125:30 | bufferTainted20 | +| nsdata.swift:124:27:124:64 | call to init(bitPattern:) | nsdata.swift:124:27:124:65 | ...! | +| nsdata.swift:124:27:124:65 | ...! | nsdata.swift:124:9:124:9 | SSA def(bufferTainted20) | +| nsdata.swift:125:5:125:5 | nsDataTainted20 | nsdata.swift:125:30:125:30 | [post] bufferTainted20 | +| nsdata.swift:125:30:125:30 | [post] bufferTainted20 | nsdata.swift:126:15:126:15 | bufferTainted20 | +| nsdata.swift:125:30:125:30 | bufferTainted20 | nsdata.swift:126:15:126:15 | bufferTainted20 | +| nsdata.swift:128:9:128:9 | SSA def(nsDataTainted21) | nsdata.swift:129:15:129:15 | nsDataTainted21 | +| nsdata.swift:128:27:128:34 | call to source() | nsdata.swift:128:9:128:9 | SSA def(nsDataTainted21) | +| nsdata.swift:129:15:129:15 | nsDataTainted21 | nsdata.swift:129:15:129:54 | call to subdata(with:) | +| nsdata.swift:131:9:131:9 | SSA def(nsDataTainted22) | nsdata.swift:132:15:132:15 | nsDataTainted22 | +| nsdata.swift:131:27:131:34 | call to source() | nsdata.swift:131:9:131:9 | SSA def(nsDataTainted22) | +| nsdata.swift:132:15:132:15 | nsDataTainted22 | nsdata.swift:132:15:132:81 | call to compressed(using:) | +| nsdata.swift:134:9:134:9 | SSA def(nsDataTainted23) | nsdata.swift:135:15:135:15 | nsDataTainted23 | +| nsdata.swift:134:27:134:34 | call to source() | nsdata.swift:134:9:134:9 | SSA def(nsDataTainted23) | +| nsdata.swift:135:15:135:15 | nsDataTainted23 | nsdata.swift:135:15:135:83 | call to decompressed(using:) | +| nsdata.swift:138:9:138:9 | SSA def(nsDataTainted24) | nsdata.swift:139:15:139:15 | nsDataTainted24 | +| nsdata.swift:138:27:138:34 | call to source() | nsdata.swift:138:9:138:9 | SSA def(nsDataTainted24) | +| nsdata.swift:139:15:139:15 | [post] nsDataTainted24 | nsdata.swift:140:15:140:15 | nsDataTainted24 | | nsdata.swift:139:15:139:15 | nsDataTainted24 | nsdata.swift:139:15:139:31 | .bytes | +| nsdata.swift:139:15:139:15 | nsDataTainted24 | nsdata.swift:140:15:140:15 | nsDataTainted24 | | nsdata.swift:140:15:140:15 | nsDataTainted24 | nsdata.swift:140:15:140:31 | .description | +| nsmutabledata.swift:5:5:5:5 | SSA def(self) | nsmutabledata.swift:5:5:5:29 | self[return] | +| nsmutabledata.swift:5:5:5:5 | self | nsmutabledata.swift:5:5:5:5 | SSA def(self) | +| nsmutabledata.swift:8:8:8:8 | SSA def(self) | nsmutabledata.swift:8:8:8:8 | self[return] | +| nsmutabledata.swift:8:8:8:8 | self | nsmutabledata.swift:8:8:8:8 | SSA def(self) | +| nsmutabledata.swift:10:7:10:7 | SSA def(self) | nsmutabledata.swift:10:7:10:7 | self[return] | +| nsmutabledata.swift:10:7:10:7 | SSA def(self) | nsmutabledata.swift:10:7:10:7 | self[return] | +| nsmutabledata.swift:10:7:10:7 | self | nsmutabledata.swift:10:7:10:7 | SSA def(self) | +| nsmutabledata.swift:10:7:10:7 | self | nsmutabledata.swift:10:7:10:7 | SSA def(self) | +| nsmutabledata.swift:12:7:12:7 | SSA def(self) | nsmutabledata.swift:12:7:12:7 | self[return] | +| nsmutabledata.swift:12:7:12:7 | self | nsmutabledata.swift:12:7:12:7 | SSA def(self) | +| nsmutabledata.swift:12:30:12:30 | SSA def(self) | nsmutabledata.swift:12:30:12:30 | self[return] | +| nsmutabledata.swift:12:30:12:30 | self | nsmutabledata.swift:12:30:12:30 | SSA def(self) | +| nsmutabledata.swift:13:9:13:9 | self | nsmutabledata.swift:13:9:13:9 | SSA def(self) | +| nsmutabledata.swift:13:9:13:9 | self | nsmutabledata.swift:13:9:13:9 | SSA def(self) | +| nsmutabledata.swift:13:9:13:9 | self | nsmutabledata.swift:13:9:13:9 | SSA def(self) | +| nsmutabledata.swift:13:9:13:9 | value | nsmutabledata.swift:13:9:13:9 | SSA def(value) | +| nsmutabledata.swift:14:10:14:10 | SSA def(self) | nsmutabledata.swift:14:5:14:58 | self[return] | +| nsmutabledata.swift:14:10:14:10 | self | nsmutabledata.swift:14:10:14:10 | SSA def(self) | +| nsmutabledata.swift:15:10:15:10 | SSA def(self) | nsmutabledata.swift:15:5:15:33 | self[return] | +| nsmutabledata.swift:15:10:15:10 | self | nsmutabledata.swift:15:10:15:10 | SSA def(self) | +| nsmutabledata.swift:16:10:16:10 | SSA def(self) | nsmutabledata.swift:16:5:16:78 | self[return] | +| nsmutabledata.swift:16:10:16:10 | self | nsmutabledata.swift:16:10:16:10 | SSA def(self) | +| nsmutabledata.swift:17:10:17:10 | SSA def(self) | nsmutabledata.swift:17:5:17:121 | self[return] | +| nsmutabledata.swift:17:10:17:10 | self | nsmutabledata.swift:17:10:17:10 | SSA def(self) | +| nsmutabledata.swift:18:10:18:10 | SSA def(self) | nsmutabledata.swift:18:5:18:33 | self[return] | +| nsmutabledata.swift:18:10:18:10 | self | nsmutabledata.swift:18:10:18:10 | SSA def(self) | +| nsmutabledata.swift:27:9:27:9 | SSA def(nsMutableDataTainted1) | nsmutabledata.swift:28:5:28:5 | nsMutableDataTainted1 | +| nsmutabledata.swift:27:33:27:47 | call to init() | nsmutabledata.swift:27:9:27:9 | SSA def(nsMutableDataTainted1) | +| nsmutabledata.swift:28:5:28:5 | [post] nsMutableDataTainted1 | nsmutabledata.swift:29:15:29:15 | nsMutableDataTainted1 | +| nsmutabledata.swift:28:5:28:5 | nsMutableDataTainted1 | nsmutabledata.swift:29:15:29:15 | nsMutableDataTainted1 | +| nsmutabledata.swift:28:34:28:41 | call to source() | nsmutabledata.swift:28:5:28:5 | [post] nsMutableDataTainted1 | +| nsmutabledata.swift:31:9:31:9 | SSA def(nsMutableDataTainted2) | nsmutabledata.swift:32:5:32:5 | nsMutableDataTainted2 | +| nsmutabledata.swift:31:33:31:47 | call to init() | nsmutabledata.swift:31:9:31:9 | SSA def(nsMutableDataTainted2) | +| nsmutabledata.swift:32:5:32:5 | [post] nsMutableDataTainted2 | nsmutabledata.swift:33:15:33:15 | nsMutableDataTainted2 | +| nsmutabledata.swift:32:5:32:5 | nsMutableDataTainted2 | nsmutabledata.swift:33:15:33:15 | nsMutableDataTainted2 | +| nsmutabledata.swift:32:34:32:41 | call to source() | nsmutabledata.swift:32:5:32:5 | [post] nsMutableDataTainted2 | +| nsmutabledata.swift:35:9:35:9 | SSA def(nsMutableDataTainted3) | nsmutabledata.swift:36:5:36:5 | nsMutableDataTainted3 | +| nsmutabledata.swift:35:33:35:47 | call to init() | nsmutabledata.swift:35:9:35:9 | SSA def(nsMutableDataTainted3) | +| nsmutabledata.swift:36:5:36:5 | [post] nsMutableDataTainted3 | nsmutabledata.swift:37:15:37:15 | nsMutableDataTainted3 | +| nsmutabledata.swift:36:5:36:5 | nsMutableDataTainted3 | nsmutabledata.swift:37:15:37:15 | nsMutableDataTainted3 | +| nsmutabledata.swift:36:66:36:73 | call to source() | nsmutabledata.swift:36:5:36:5 | [post] nsMutableDataTainted3 | +| nsmutabledata.swift:39:9:39:9 | SSA def(nsMutableDataTainted4) | nsmutabledata.swift:40:5:40:5 | nsMutableDataTainted4 | +| nsmutabledata.swift:39:33:39:47 | call to init() | nsmutabledata.swift:39:9:39:9 | SSA def(nsMutableDataTainted4) | +| nsmutabledata.swift:40:5:40:5 | [post] nsMutableDataTainted4 | nsmutabledata.swift:41:15:41:15 | nsMutableDataTainted4 | +| nsmutabledata.swift:40:5:40:5 | nsMutableDataTainted4 | nsmutabledata.swift:41:15:41:15 | nsMutableDataTainted4 | +| nsmutabledata.swift:40:66:40:73 | call to source() | nsmutabledata.swift:40:5:40:5 | [post] nsMutableDataTainted4 | +| nsmutabledata.swift:43:9:43:9 | SSA def(nsMutableDataTainted5) | nsmutabledata.swift:44:5:44:5 | nsMutableDataTainted5 | +| nsmutabledata.swift:43:33:43:47 | call to init() | nsmutabledata.swift:43:9:43:9 | SSA def(nsMutableDataTainted5) | +| nsmutabledata.swift:44:5:44:5 | [post] nsMutableDataTainted5 | nsmutabledata.swift:45:15:45:15 | nsMutableDataTainted5 | +| nsmutabledata.swift:44:5:44:5 | nsMutableDataTainted5 | nsmutabledata.swift:45:15:45:15 | nsMutableDataTainted5 | +| nsmutabledata.swift:44:35:44:42 | call to source() | nsmutabledata.swift:44:5:44:5 | [post] nsMutableDataTainted5 | +| nsmutabledata.swift:48:9:48:9 | SSA def(nsMutableDataTainted6) | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 | +| nsmutabledata.swift:48:33:48:40 | call to source() | nsmutabledata.swift:48:9:48:9 | SSA def(nsMutableDataTainted6) | | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 | nsmutabledata.swift:49:15:49:37 | .mutableBytes | +| string.swift:5:7:5:7 | SSA def(x) | string.swift:7:16:7:16 | x | +| string.swift:5:11:5:18 | call to source() | string.swift:5:7:5:7 | SSA def(x) | | string.swift:7:13:7:13 | | string.swift:7:13:7:13 | [post] | | string.swift:7:13:7:13 | | string.swift:7:14:7:14 | [post] &... | +| string.swift:7:13:7:13 | SSA def($interpolation) | string.swift:7:14:7:14 | SSA phi($interpolation) | | string.swift:7:13:7:13 | TapExpr | string.swift:7:13:7:13 | "..." | +| string.swift:7:14:7:14 | $interpolation | string.swift:7:14:7:14 | &... | | string.swift:7:14:7:14 | &... | string.swift:7:13:7:13 | [post] | | string.swift:7:14:7:14 | &... | string.swift:7:14:7:14 | [post] &... | +| string.swift:7:14:7:14 | &... | string.swift:7:15:7:15 | $interpolation | +| string.swift:7:14:7:14 | SSA phi($interpolation) | string.swift:7:14:7:14 | $interpolation | +| string.swift:7:14:7:14 | [post] &... | string.swift:7:15:7:15 | $interpolation | +| string.swift:7:15:7:15 | $interpolation | string.swift:7:15:7:15 | &... | | string.swift:7:15:7:15 | &... | string.swift:7:15:7:15 | [post] &... | +| string.swift:7:15:7:15 | &... | string.swift:7:18:7:18 | $interpolation | +| string.swift:7:15:7:15 | [post] &... | string.swift:7:18:7:18 | $interpolation | | string.swift:7:16:7:16 | x | string.swift:7:15:7:15 | [post] &... | +| string.swift:7:16:7:16 | x | string.swift:9:16:9:16 | x | | string.swift:7:18:7:18 | | string.swift:7:18:7:18 | [post] | | string.swift:7:18:7:18 | | string.swift:7:18:7:18 | [post] &... | +| string.swift:7:18:7:18 | $interpolation | string.swift:7:18:7:18 | &... | +| string.swift:7:18:7:18 | &... | string.swift:7:13:7:13 | TapExpr | | string.swift:7:18:7:18 | &... | string.swift:7:18:7:18 | [post] | | string.swift:7:18:7:18 | &... | string.swift:7:18:7:18 | [post] &... | +| string.swift:7:18:7:18 | [post] &... | string.swift:7:13:7:13 | TapExpr | | string.swift:9:13:9:13 | | string.swift:9:13:9:13 | [post] | | string.swift:9:13:9:13 | | string.swift:9:14:9:14 | [post] &... | +| string.swift:9:13:9:13 | SSA def($interpolation) | string.swift:9:14:9:14 | SSA phi($interpolation) | | string.swift:9:13:9:13 | TapExpr | string.swift:9:13:9:13 | "..." | +| string.swift:9:14:9:14 | $interpolation | string.swift:9:14:9:14 | &... | | string.swift:9:14:9:14 | &... | string.swift:9:13:9:13 | [post] | | string.swift:9:14:9:14 | &... | string.swift:9:14:9:14 | [post] &... | +| string.swift:9:14:9:14 | &... | string.swift:9:15:9:15 | $interpolation | +| string.swift:9:14:9:14 | SSA phi($interpolation) | string.swift:9:14:9:14 | $interpolation | +| string.swift:9:14:9:14 | [post] &... | string.swift:9:15:9:15 | $interpolation | +| string.swift:9:15:9:15 | $interpolation | string.swift:9:15:9:15 | &... | | string.swift:9:15:9:15 | &... | string.swift:9:15:9:15 | [post] &... | +| string.swift:9:15:9:15 | &... | string.swift:9:18:9:18 | $interpolation | +| string.swift:9:15:9:15 | [post] &... | string.swift:9:18:9:18 | $interpolation | | string.swift:9:16:9:16 | x | string.swift:9:15:9:15 | [post] &... | +| string.swift:9:16:9:16 | x | string.swift:9:21:9:21 | x | | string.swift:9:18:9:18 | | string.swift:9:18:9:18 | [post] | | string.swift:9:18:9:18 | | string.swift:9:18:9:18 | [post] &... | +| string.swift:9:18:9:18 | $interpolation | string.swift:9:18:9:18 | &... | | string.swift:9:18:9:18 | &... | string.swift:9:18:9:18 | [post] | | string.swift:9:18:9:18 | &... | string.swift:9:18:9:18 | [post] &... | +| string.swift:9:18:9:18 | &... | string.swift:9:20:9:20 | $interpolation | +| string.swift:9:18:9:18 | [post] &... | string.swift:9:20:9:20 | $interpolation | +| string.swift:9:20:9:20 | $interpolation | string.swift:9:20:9:20 | &... | | string.swift:9:20:9:20 | &... | string.swift:9:20:9:20 | [post] &... | +| string.swift:9:20:9:20 | &... | string.swift:9:23:9:23 | $interpolation | +| string.swift:9:20:9:20 | [post] &... | string.swift:9:23:9:23 | $interpolation | | string.swift:9:21:9:21 | x | string.swift:9:20:9:20 | [post] &... | +| string.swift:9:21:9:21 | x | string.swift:11:16:11:16 | x | | string.swift:9:23:9:23 | | string.swift:9:23:9:23 | [post] | | string.swift:9:23:9:23 | | string.swift:9:23:9:23 | [post] &... | +| string.swift:9:23:9:23 | $interpolation | string.swift:9:23:9:23 | &... | +| string.swift:9:23:9:23 | &... | string.swift:9:13:9:13 | TapExpr | | string.swift:9:23:9:23 | &... | string.swift:9:23:9:23 | [post] | | string.swift:9:23:9:23 | &... | string.swift:9:23:9:23 | [post] &... | +| string.swift:9:23:9:23 | [post] &... | string.swift:9:13:9:13 | TapExpr | | string.swift:11:13:11:13 | | string.swift:11:13:11:13 | [post] | | string.swift:11:13:11:13 | | string.swift:11:14:11:14 | [post] &... | +| string.swift:11:13:11:13 | SSA def($interpolation) | string.swift:11:14:11:14 | SSA phi($interpolation) | | string.swift:11:13:11:13 | TapExpr | string.swift:11:13:11:13 | "..." | +| string.swift:11:14:11:14 | $interpolation | string.swift:11:14:11:14 | &... | | string.swift:11:14:11:14 | &... | string.swift:11:13:11:13 | [post] | | string.swift:11:14:11:14 | &... | string.swift:11:14:11:14 | [post] &... | +| string.swift:11:14:11:14 | &... | string.swift:11:15:11:15 | $interpolation | +| string.swift:11:14:11:14 | SSA phi($interpolation) | string.swift:11:14:11:14 | $interpolation | +| string.swift:11:14:11:14 | [post] &... | string.swift:11:15:11:15 | $interpolation | +| string.swift:11:15:11:15 | $interpolation | string.swift:11:15:11:15 | &... | | string.swift:11:15:11:15 | &... | string.swift:11:15:11:15 | [post] &... | +| string.swift:11:15:11:15 | &... | string.swift:11:18:11:18 | $interpolation | +| string.swift:11:15:11:15 | [post] &... | string.swift:11:18:11:18 | $interpolation | | string.swift:11:16:11:16 | x | string.swift:11:15:11:15 | [post] &... | +| string.swift:11:16:11:16 | x | string.swift:11:26:11:26 | x | | string.swift:11:18:11:18 | | string.swift:11:18:11:18 | [post] | | string.swift:11:18:11:18 | | string.swift:11:18:11:18 | [post] &... | +| string.swift:11:18:11:18 | $interpolation | string.swift:11:18:11:18 | &... | | string.swift:11:18:11:18 | &... | string.swift:11:18:11:18 | [post] | | string.swift:11:18:11:18 | &... | string.swift:11:18:11:18 | [post] &... | +| string.swift:11:18:11:18 | &... | string.swift:11:20:11:20 | $interpolation | +| string.swift:11:18:11:18 | [post] &... | string.swift:11:20:11:20 | $interpolation | +| string.swift:11:20:11:20 | $interpolation | string.swift:11:20:11:20 | &... | | string.swift:11:20:11:20 | &... | string.swift:11:20:11:20 | [post] &... | | string.swift:11:20:11:20 | &... | string.swift:11:21:11:21 | [post] 0 | +| string.swift:11:20:11:20 | &... | string.swift:11:23:11:23 | $interpolation | +| string.swift:11:20:11:20 | [post] &... | string.swift:11:23:11:23 | $interpolation | | string.swift:11:21:11:21 | 0 | string.swift:11:20:11:20 | [post] &... | | string.swift:11:21:11:21 | 0 | string.swift:11:21:11:21 | [post] 0 | | string.swift:11:23:11:23 | | string.swift:11:23:11:23 | [post] | | string.swift:11:23:11:23 | | string.swift:11:23:11:23 | [post] &... | +| string.swift:11:23:11:23 | $interpolation | string.swift:11:23:11:23 | &... | | string.swift:11:23:11:23 | &... | string.swift:11:23:11:23 | [post] | | string.swift:11:23:11:23 | &... | string.swift:11:23:11:23 | [post] &... | +| string.swift:11:23:11:23 | &... | string.swift:11:25:11:25 | $interpolation | +| string.swift:11:23:11:23 | [post] &... | string.swift:11:25:11:25 | $interpolation | +| string.swift:11:25:11:25 | $interpolation | string.swift:11:25:11:25 | &... | | string.swift:11:25:11:25 | &... | string.swift:11:25:11:25 | [post] &... | +| string.swift:11:25:11:25 | &... | string.swift:11:28:11:28 | $interpolation | +| string.swift:11:25:11:25 | [post] &... | string.swift:11:28:11:28 | $interpolation | | string.swift:11:26:11:26 | x | string.swift:11:25:11:25 | [post] &... | +| string.swift:11:26:11:26 | x | string.swift:16:16:16:16 | x | | string.swift:11:28:11:28 | | string.swift:11:28:11:28 | [post] | | string.swift:11:28:11:28 | | string.swift:11:28:11:28 | [post] &... | +| string.swift:11:28:11:28 | $interpolation | string.swift:11:28:11:28 | &... | +| string.swift:11:28:11:28 | &... | string.swift:11:13:11:13 | TapExpr | | string.swift:11:28:11:28 | &... | string.swift:11:28:11:28 | [post] | | string.swift:11:28:11:28 | &... | string.swift:11:28:11:28 | [post] &... | +| string.swift:11:28:11:28 | [post] &... | string.swift:11:13:11:13 | TapExpr | +| string.swift:13:7:13:7 | SSA def(y) | string.swift:14:16:14:16 | y | +| string.swift:13:11:13:11 | 42 | string.swift:13:7:13:7 | SSA def(y) | | string.swift:14:13:14:13 | | string.swift:14:13:14:13 | [post] | | string.swift:14:13:14:13 | | string.swift:14:14:14:14 | [post] &... | +| string.swift:14:13:14:13 | SSA def($interpolation) | string.swift:14:14:14:14 | SSA phi($interpolation) | | string.swift:14:13:14:13 | TapExpr | string.swift:14:13:14:13 | "..." | +| string.swift:14:14:14:14 | $interpolation | string.swift:14:14:14:14 | &... | | string.swift:14:14:14:14 | &... | string.swift:14:13:14:13 | [post] | | string.swift:14:14:14:14 | &... | string.swift:14:14:14:14 | [post] &... | +| string.swift:14:14:14:14 | &... | string.swift:14:15:14:15 | $interpolation | +| string.swift:14:14:14:14 | SSA phi($interpolation) | string.swift:14:14:14:14 | $interpolation | +| string.swift:14:14:14:14 | [post] &... | string.swift:14:15:14:15 | $interpolation | +| string.swift:14:15:14:15 | $interpolation | string.swift:14:15:14:15 | &... | | string.swift:14:15:14:15 | &... | string.swift:14:15:14:15 | [post] &... | +| string.swift:14:15:14:15 | &... | string.swift:14:18:14:18 | $interpolation | +| string.swift:14:15:14:15 | [post] &... | string.swift:14:18:14:18 | $interpolation | | string.swift:14:16:14:16 | y | string.swift:14:15:14:15 | [post] &... | +| string.swift:14:16:14:16 | y | string.swift:16:27:16:27 | y | | string.swift:14:18:14:18 | | string.swift:14:18:14:18 | [post] | | string.swift:14:18:14:18 | | string.swift:14:18:14:18 | [post] &... | +| string.swift:14:18:14:18 | $interpolation | string.swift:14:18:14:18 | &... | +| string.swift:14:18:14:18 | &... | string.swift:14:13:14:13 | TapExpr | | string.swift:14:18:14:18 | &... | string.swift:14:18:14:18 | [post] | | string.swift:14:18:14:18 | &... | string.swift:14:18:14:18 | [post] &... | +| string.swift:14:18:14:18 | [post] &... | string.swift:14:13:14:13 | TapExpr | | string.swift:16:13:16:13 | | string.swift:16:13:16:13 | [post] | | string.swift:16:13:16:13 | | string.swift:16:14:16:14 | [post] &... | +| string.swift:16:13:16:13 | SSA def($interpolation) | string.swift:16:14:16:14 | SSA phi($interpolation) | | string.swift:16:13:16:13 | TapExpr | string.swift:16:13:16:13 | "..." | +| string.swift:16:14:16:14 | $interpolation | string.swift:16:14:16:14 | &... | | string.swift:16:14:16:14 | &... | string.swift:16:13:16:13 | [post] | | string.swift:16:14:16:14 | &... | string.swift:16:14:16:14 | [post] &... | +| string.swift:16:14:16:14 | &... | string.swift:16:15:16:15 | $interpolation | +| string.swift:16:14:16:14 | SSA phi($interpolation) | string.swift:16:14:16:14 | $interpolation | +| string.swift:16:14:16:14 | [post] &... | string.swift:16:15:16:15 | $interpolation | +| string.swift:16:15:16:15 | $interpolation | string.swift:16:15:16:15 | &... | | string.swift:16:15:16:15 | &... | string.swift:16:15:16:15 | [post] &... | +| string.swift:16:15:16:15 | &... | string.swift:16:18:16:18 | $interpolation | +| string.swift:16:15:16:15 | [post] &... | string.swift:16:18:16:18 | $interpolation | | string.swift:16:16:16:16 | x | string.swift:16:15:16:15 | [post] &... | +| string.swift:16:16:16:16 | x | string.swift:18:27:18:27 | x | | string.swift:16:18:16:18 | hello | string.swift:16:18:16:18 | [post] hello | | string.swift:16:18:16:18 | hello | string.swift:16:18:16:18 | [post] &... | +| string.swift:16:18:16:18 | $interpolation | string.swift:16:18:16:18 | &... | | string.swift:16:18:16:18 | &... | string.swift:16:18:16:18 | [post] hello | | string.swift:16:18:16:18 | &... | string.swift:16:18:16:18 | [post] &... | +| string.swift:16:18:16:18 | &... | string.swift:16:26:16:26 | $interpolation | +| string.swift:16:18:16:18 | [post] &... | string.swift:16:26:16:26 | $interpolation | +| string.swift:16:26:16:26 | $interpolation | string.swift:16:26:16:26 | &... | | string.swift:16:26:16:26 | &... | string.swift:16:26:16:26 | [post] &... | +| string.swift:16:26:16:26 | &... | string.swift:16:29:16:29 | $interpolation | +| string.swift:16:26:16:26 | [post] &... | string.swift:16:29:16:29 | $interpolation | | string.swift:16:27:16:27 | y | string.swift:16:26:16:26 | [post] &... | +| string.swift:16:27:16:27 | y | string.swift:18:16:18:16 | y | | string.swift:16:29:16:29 | | string.swift:16:29:16:29 | [post] | | string.swift:16:29:16:29 | | string.swift:16:29:16:29 | [post] &... | +| string.swift:16:29:16:29 | $interpolation | string.swift:16:29:16:29 | &... | +| string.swift:16:29:16:29 | &... | string.swift:16:13:16:13 | TapExpr | | string.swift:16:29:16:29 | &... | string.swift:16:29:16:29 | [post] | | string.swift:16:29:16:29 | &... | string.swift:16:29:16:29 | [post] &... | +| string.swift:16:29:16:29 | [post] &... | string.swift:16:13:16:13 | TapExpr | | string.swift:18:13:18:13 | | string.swift:18:13:18:13 | [post] | | string.swift:18:13:18:13 | | string.swift:18:14:18:14 | [post] &... | +| string.swift:18:13:18:13 | SSA def($interpolation) | string.swift:18:14:18:14 | SSA phi($interpolation) | | string.swift:18:13:18:13 | TapExpr | string.swift:18:13:18:13 | "..." | +| string.swift:18:14:18:14 | $interpolation | string.swift:18:14:18:14 | &... | | string.swift:18:14:18:14 | &... | string.swift:18:13:18:13 | [post] | | string.swift:18:14:18:14 | &... | string.swift:18:14:18:14 | [post] &... | +| string.swift:18:14:18:14 | &... | string.swift:18:15:18:15 | $interpolation | +| string.swift:18:14:18:14 | SSA phi($interpolation) | string.swift:18:14:18:14 | $interpolation | +| string.swift:18:14:18:14 | [post] &... | string.swift:18:15:18:15 | $interpolation | +| string.swift:18:15:18:15 | $interpolation | string.swift:18:15:18:15 | &... | | string.swift:18:15:18:15 | &... | string.swift:18:15:18:15 | [post] &... | +| string.swift:18:15:18:15 | &... | string.swift:18:18:18:18 | $interpolation | +| string.swift:18:15:18:15 | [post] &... | string.swift:18:18:18:18 | $interpolation | | string.swift:18:16:18:16 | y | string.swift:18:15:18:15 | [post] &... | | string.swift:18:18:18:18 | world | string.swift:18:18:18:18 | [post] world | | string.swift:18:18:18:18 | world | string.swift:18:18:18:18 | [post] &... | +| string.swift:18:18:18:18 | $interpolation | string.swift:18:18:18:18 | &... | | string.swift:18:18:18:18 | &... | string.swift:18:18:18:18 | [post] world | | string.swift:18:18:18:18 | &... | string.swift:18:18:18:18 | [post] &... | +| string.swift:18:18:18:18 | &... | string.swift:18:26:18:26 | $interpolation | +| string.swift:18:18:18:18 | [post] &... | string.swift:18:26:18:26 | $interpolation | +| string.swift:18:26:18:26 | $interpolation | string.swift:18:26:18:26 | &... | | string.swift:18:26:18:26 | &... | string.swift:18:26:18:26 | [post] &... | +| string.swift:18:26:18:26 | &... | string.swift:18:29:18:29 | $interpolation | +| string.swift:18:26:18:26 | [post] &... | string.swift:18:29:18:29 | $interpolation | | string.swift:18:27:18:27 | x | string.swift:18:26:18:26 | [post] &... | | string.swift:18:29:18:29 | | string.swift:18:29:18:29 | [post] | | string.swift:18:29:18:29 | | string.swift:18:29:18:29 | [post] &... | +| string.swift:18:29:18:29 | $interpolation | string.swift:18:29:18:29 | &... | +| string.swift:18:29:18:29 | &... | string.swift:18:13:18:13 | TapExpr | | string.swift:18:29:18:29 | &... | string.swift:18:29:18:29 | [post] | | string.swift:18:29:18:29 | &... | string.swift:18:29:18:29 | [post] &... | +| string.swift:18:29:18:29 | [post] &... | string.swift:18:13:18:13 | TapExpr | +| string.swift:20:3:20:7 | SSA def(x) | string.swift:21:16:21:16 | x | +| string.swift:20:7:20:7 | 0 | string.swift:20:3:20:7 | SSA def(x) | | string.swift:21:13:21:13 | | string.swift:21:13:21:13 | [post] | | string.swift:21:13:21:13 | | string.swift:21:14:21:14 | [post] &... | +| string.swift:21:13:21:13 | SSA def($interpolation) | string.swift:21:14:21:14 | SSA phi($interpolation) | | string.swift:21:13:21:13 | TapExpr | string.swift:21:13:21:13 | "..." | +| string.swift:21:14:21:14 | $interpolation | string.swift:21:14:21:14 | &... | | string.swift:21:14:21:14 | &... | string.swift:21:13:21:13 | [post] | | string.swift:21:14:21:14 | &... | string.swift:21:14:21:14 | [post] &... | +| string.swift:21:14:21:14 | &... | string.swift:21:15:21:15 | $interpolation | +| string.swift:21:14:21:14 | SSA phi($interpolation) | string.swift:21:14:21:14 | $interpolation | +| string.swift:21:14:21:14 | [post] &... | string.swift:21:15:21:15 | $interpolation | +| string.swift:21:15:21:15 | $interpolation | string.swift:21:15:21:15 | &... | | string.swift:21:15:21:15 | &... | string.swift:21:15:21:15 | [post] &... | +| string.swift:21:15:21:15 | &... | string.swift:21:18:21:18 | $interpolation | +| string.swift:21:15:21:15 | [post] &... | string.swift:21:18:21:18 | $interpolation | | string.swift:21:16:21:16 | x | string.swift:21:15:21:15 | [post] &... | | string.swift:21:18:21:18 | | string.swift:21:18:21:18 | [post] | | string.swift:21:18:21:18 | | string.swift:21:18:21:18 | [post] &... | +| string.swift:21:18:21:18 | $interpolation | string.swift:21:18:21:18 | &... | +| string.swift:21:18:21:18 | &... | string.swift:21:13:21:13 | TapExpr | | string.swift:21:18:21:18 | &... | string.swift:21:18:21:18 | [post] | | string.swift:21:18:21:18 | &... | string.swift:21:18:21:18 | [post] &... | +| string.swift:21:18:21:18 | [post] &... | string.swift:21:13:21:13 | TapExpr | +| string.swift:27:7:27:7 | SSA def(clean) | string.swift:30:13:30:13 | clean | +| string.swift:27:15:27:15 | abcdef | string.swift:27:7:27:7 | SSA def(clean) | +| string.swift:28:7:28:7 | SSA def(tainted) | string.swift:31:13:31:13 | tainted | +| string.swift:28:17:28:25 | call to source2() | string.swift:28:7:28:7 | SSA def(tainted) | +| string.swift:30:13:30:13 | clean | string.swift:33:13:33:13 | clean | +| string.swift:31:13:31:13 | tainted | string.swift:34:21:34:21 | tainted | | string.swift:33:13:33:13 | clean | string.swift:33:13:33:21 | ... .+(_:_:) ... | +| string.swift:33:13:33:13 | clean | string.swift:33:21:33:21 | clean | | string.swift:33:21:33:21 | clean | string.swift:33:13:33:21 | ... .+(_:_:) ... | +| string.swift:33:21:33:21 | clean | string.swift:34:13:34:13 | clean | | string.swift:34:13:34:13 | clean | string.swift:34:13:34:21 | ... .+(_:_:) ... | +| string.swift:34:13:34:13 | clean | string.swift:35:23:35:23 | clean | | string.swift:34:21:34:21 | tainted | string.swift:34:13:34:21 | ... .+(_:_:) ... | +| string.swift:34:21:34:21 | tainted | string.swift:35:13:35:13 | tainted | | string.swift:35:13:35:13 | tainted | string.swift:35:13:35:23 | ... .+(_:_:) ... | +| string.swift:35:13:35:13 | tainted | string.swift:36:13:36:13 | tainted | | string.swift:35:23:35:23 | clean | string.swift:35:13:35:23 | ... .+(_:_:) ... | +| string.swift:35:23:35:23 | clean | string.swift:38:19:38:19 | clean | | string.swift:36:13:36:13 | tainted | string.swift:36:13:36:23 | ... .+(_:_:) ... | +| string.swift:36:13:36:13 | tainted | string.swift:36:23:36:23 | tainted | | string.swift:36:23:36:23 | tainted | string.swift:36:13:36:23 | ... .+(_:_:) ... | +| string.swift:36:23:36:23 | tainted | string.swift:39:19:39:19 | tainted | | string.swift:38:13:38:13 | > | string.swift:38:13:38:19 | ... .+(_:_:) ... | | string.swift:38:13:38:19 | ... .+(_:_:) ... | string.swift:38:13:38:27 | ... .+(_:_:) ... | | string.swift:38:19:38:19 | clean | string.swift:38:13:38:19 | ... .+(_:_:) ... | @@ -127,45 +858,720 @@ | string.swift:39:13:39:19 | ... .+(_:_:) ... | string.swift:39:13:39:29 | ... .+(_:_:) ... | | string.swift:39:19:39:19 | tainted | string.swift:39:13:39:19 | ... .+(_:_:) ... | | string.swift:39:29:39:29 | < | string.swift:39:13:39:29 | ... .+(_:_:) ... | +| string.swift:41:7:41:7 | SSA def(str) | string.swift:43:13:43:13 | str | +| string.swift:41:13:41:13 | abc | string.swift:41:7:41:7 | SSA def(str) | +| string.swift:43:13:43:13 | str | string.swift:45:3:45:3 | str | +| string.swift:45:3:45:3 | &... | string.swift:46:13:46:13 | str | +| string.swift:45:3:45:3 | [post] &... | string.swift:46:13:46:13 | str | +| string.swift:45:3:45:3 | str | string.swift:45:3:45:3 | &... | +| string.swift:46:13:46:13 | str | string.swift:48:3:48:3 | str | +| string.swift:48:3:48:3 | &... | string.swift:49:13:49:13 | str | +| string.swift:48:3:48:3 | [post] &... | string.swift:49:13:49:13 | str | +| string.swift:48:3:48:3 | str | string.swift:48:3:48:3 | &... | +| string.swift:51:7:51:7 | SSA def(str2) | string.swift:53:13:53:13 | str2 | +| string.swift:51:14:51:14 | abc | string.swift:51:7:51:7 | SSA def(str2) | +| string.swift:53:13:53:13 | str2 | string.swift:55:3:55:3 | str2 | +| string.swift:55:3:55:3 | &... | string.swift:56:13:56:13 | str2 | +| string.swift:55:3:55:3 | [post] &... | string.swift:56:13:56:13 | str2 | +| string.swift:55:3:55:3 | str2 | string.swift:55:3:55:3 | &... | +| string.swift:56:13:56:13 | str2 | string.swift:58:3:58:3 | str2 | +| string.swift:58:3:58:3 | &... | string.swift:59:13:59:13 | str2 | +| string.swift:58:3:58:3 | [post] &... | string.swift:59:13:59:13 | str2 | +| string.swift:58:3:58:3 | str2 | string.swift:58:3:58:3 | &... | +| string.swift:59:13:59:13 | str2 | string.swift:69:13:69:13 | str2 | +| string.swift:61:7:61:7 | SSA def(str3) | string.swift:63:13:63:13 | str3 | +| string.swift:61:14:61:14 | abc | string.swift:61:7:61:7 | SSA def(str3) | +| string.swift:63:13:63:13 | str3 | string.swift:65:3:65:3 | str3 | +| string.swift:65:3:65:3 | &... | string.swift:66:13:66:13 | str3 | +| string.swift:65:3:65:3 | [post] &... | string.swift:66:13:66:13 | str3 | +| string.swift:65:3:65:3 | str3 | string.swift:65:3:65:3 | &... | +| string.swift:66:13:66:13 | str3 | string.swift:68:3:68:3 | str3 | +| string.swift:68:3:68:3 | str3 | string.swift:68:3:68:3 | &... | +| string.swift:73:7:73:7 | SSA def(clean) | string.swift:77:20:77:20 | clean | +| string.swift:73:15:73:15 | | string.swift:73:7:73:7 | SSA def(clean) | +| string.swift:74:7:74:7 | SSA def(tainted) | string.swift:78:20:78:20 | tainted | +| string.swift:74:17:74:25 | call to source2() | string.swift:74:7:74:7 | SSA def(tainted) | +| string.swift:75:7:75:7 | SSA def(taintedInt) | string.swift:79:20:79:20 | taintedInt | +| string.swift:75:20:75:27 | call to source() | string.swift:75:7:75:7 | SSA def(taintedInt) | +| string.swift:77:20:77:20 | clean | string.swift:81:31:81:31 | clean | +| string.swift:78:20:78:20 | tainted | string.swift:82:31:82:31 | tainted | +| string.swift:81:31:81:31 | clean | string.swift:84:13:84:13 | clean | +| string.swift:82:31:82:31 | tainted | string.swift:85:13:85:13 | tainted | +| string.swift:84:13:84:13 | [post] clean | string.swift:87:13:87:13 | clean | +| string.swift:84:13:84:13 | clean | string.swift:87:13:87:13 | clean | +| string.swift:85:13:85:13 | [post] tainted | string.swift:88:13:88:13 | tainted | +| string.swift:85:13:85:13 | tainted | string.swift:88:13:88:13 | tainted | +| string.swift:91:7:91:7 | SSA def(self) | string.swift:91:7:91:7 | self[return] | +| string.swift:91:7:91:7 | self | string.swift:91:7:91:7 | SSA def(self) | +| string.swift:93:5:93:5 | SSA def(self) | string.swift:93:5:93:29 | self[return] | +| string.swift:93:5:93:5 | self | string.swift:93:5:93:5 | SSA def(self) | +| string.swift:97:9:97:9 | SSA def(self) | string.swift:97:9:97:9 | self[return] | +| string.swift:97:9:97:9 | self | string.swift:97:9:97:9 | SSA def(self) | +| string.swift:98:14:98:14 | self | string.swift:98:14:98:14 | SSA def(self) | +| string.swift:101:2:101:2 | SSA def(self) | string.swift:101:42:101:42 | self | +| string.swift:101:2:101:2 | self | string.swift:101:2:101:2 | SSA def(self) | +| string.swift:101:42:101:42 | &... | string.swift:101:2:101:54 | self[return] | +| string.swift:101:42:101:42 | [post] &... | string.swift:101:2:101:54 | self[return] | +| string.swift:101:42:101:42 | self | string.swift:101:42:101:42 | &... | +| string.swift:105:33:105:33 | Data.Type | string.swift:105:33:105:33 | call to init(_:) | +| string.swift:105:38:105:38 | | string.swift:105:33:105:40 | call to init(_:) | +| string.swift:108:7:108:7 | SSA def(stringClean) | string.swift:111:12:111:12 | stringClean | +| string.swift:108:21:108:74 | call to init(data:encoding:) | string.swift:108:7:108:7 | SSA def(stringClean) | +| string.swift:108:34:108:34 | Data.Type | string.swift:108:34:108:34 | call to init(_:) | +| string.swift:108:39:108:39 | | string.swift:108:34:108:41 | call to init(_:) | +| string.swift:109:7:109:7 | SSA def(stringTainted) | string.swift:112:12:112:12 | stringTainted | +| string.swift:109:23:109:77 | call to init(data:encoding:) | string.swift:109:7:109:7 | SSA def(stringTainted) | +| string.swift:111:12:111:12 | stringClean | string.swift:111:12:111:23 | ...! | +| string.swift:112:12:112:12 | stringTainted | string.swift:112:12:112:25 | ...! | +| subscript.swift:1:7:1:7 | SSA def(self) | subscript.swift:1:7:1:7 | self[return] | +| subscript.swift:1:7:1:7 | SSA def(self) | subscript.swift:1:7:1:7 | self[return] | +| subscript.swift:1:7:1:7 | self | subscript.swift:1:7:1:7 | SSA def(self) | +| subscript.swift:1:7:1:7 | self | subscript.swift:1:7:1:7 | SSA def(self) | +| subscript.swift:2:5:2:5 | self | subscript.swift:2:5:2:5 | SSA def(self) | +| subscript.swift:3:9:3:9 | SSA def(self) | subscript.swift:3:9:3:25 | self[return] | +| subscript.swift:3:9:3:9 | self | subscript.swift:3:9:3:9 | SSA def(self) | +| subscript.swift:4:9:4:9 | SSA def(self) | subscript.swift:4:9:4:24 | self[return] | +| subscript.swift:4:9:4:9 | self | subscript.swift:4:9:4:9 | SSA def(self) | | subscript.swift:13:15:13:22 | call to source() | subscript.swift:13:15:13:25 | ...[...] | | subscript.swift:14:15:14:23 | call to source2() | subscript.swift:14:15:14:26 | ...[...] | +| try.swift:8:17:8:23 | call to clean() | try.swift:8:13:8:23 | try ... | +| try.swift:9:17:9:24 | call to source() | try.swift:9:13:9:24 | try ... | +| try.swift:14:17:14:23 | call to clean() | try.swift:14:12:14:23 | try! ... | +| try.swift:15:17:15:24 | call to source() | try.swift:15:12:15:24 | try! ... | +| try.swift:17:13:17:24 | try? ... | try.swift:17:12:17:26 | ...! | +| try.swift:17:18:17:24 | call to clean() | try.swift:17:13:17:24 | try? ... | +| try.swift:18:13:18:25 | try? ... | try.swift:18:12:18:27 | ...! | +| try.swift:18:18:18:25 | call to source() | try.swift:18:13:18:25 | try? ... | +| url.swift:2:7:2:7 | SSA def(self) | url.swift:2:7:2:7 | self[return] | +| url.swift:2:7:2:7 | SSA def(self) | url.swift:2:7:2:7 | self[return] | +| url.swift:2:7:2:7 | self | url.swift:2:7:2:7 | SSA def(self) | +| url.swift:2:7:2:7 | self | url.swift:2:7:2:7 | SSA def(self) | +| url.swift:8:2:8:2 | SSA def(self) | url.swift:8:2:8:25 | self[return] | +| url.swift:8:2:8:2 | self | url.swift:8:2:8:2 | SSA def(self) | +| url.swift:9:2:9:2 | SSA def(self) | url.swift:9:2:9:43 | self[return] | +| url.swift:9:2:9:2 | self | url.swift:9:2:9:2 | SSA def(self) | +| url.swift:10:25:10:25 | SSA def(self) | url.swift:10:25:10:53 | self[return] | +| url.swift:10:25:10:25 | self | url.swift:10:25:10:25 | SSA def(self) | +| url.swift:10:37:10:37 | URL.Type | url.swift:10:37:10:37 | call to init(string:) | +| url.swift:10:37:10:51 | call to init(string:) | url.swift:10:37:10:52 | ...! | +| url.swift:10:49:10:49 | | url.swift:10:37:10:51 | call to init(string:) | +| url.swift:11:21:11:21 | SSA def(self) | url.swift:11:21:11:49 | self[return] | +| url.swift:11:21:11:21 | self | url.swift:11:21:11:21 | SSA def(self) | +| url.swift:11:33:11:33 | URL.Type | url.swift:11:33:11:33 | call to init(string:) | +| url.swift:11:33:11:47 | call to init(string:) | url.swift:11:33:11:48 | ...! | +| url.swift:11:45:11:45 | | url.swift:11:33:11:47 | call to init(string:) | +| url.swift:12:26:12:26 | SSA def(self) | url.swift:12:26:12:41 | self[return] | +| url.swift:12:26:12:26 | self | url.swift:12:26:12:26 | SSA def(self) | +| url.swift:13:22:13:22 | SSA def(self) | url.swift:13:22:13:37 | self[return] | +| url.swift:13:22:13:22 | self | url.swift:13:22:13:22 | SSA def(self) | +| url.swift:14:34:14:34 | SSA def(self) | url.swift:14:34:14:48 | self[return] | +| url.swift:14:34:14:34 | self | url.swift:14:34:14:34 | SSA def(self) | +| url.swift:15:21:15:21 | SSA def(self) | url.swift:15:21:15:35 | self[return] | +| url.swift:15:21:15:21 | self | url.swift:15:21:15:21 | SSA def(self) | +| url.swift:16:33:16:33 | SSA def(self) | url.swift:16:33:16:49 | self[return] | +| url.swift:16:33:16:33 | self | url.swift:16:33:16:33 | SSA def(self) | +| url.swift:17:30:17:30 | SSA def(self) | url.swift:17:30:17:44 | self[return] | +| url.swift:17:30:17:30 | self | url.swift:17:30:17:30 | SSA def(self) | +| url.swift:18:19:18:19 | SSA def(self) | url.swift:18:19:18:34 | self[return] | +| url.swift:18:19:18:19 | self | url.swift:18:19:18:19 | SSA def(self) | +| url.swift:19:23:19:23 | SSA def(self) | url.swift:19:23:19:38 | self[return] | +| url.swift:19:23:19:23 | self | url.swift:19:23:19:23 | SSA def(self) | +| url.swift:20:29:20:29 | SSA def(self) | url.swift:20:29:20:43 | self[return] | +| url.swift:20:29:20:29 | self | url.swift:20:29:20:29 | SSA def(self) | +| url.swift:21:31:21:31 | SSA def(self) | url.swift:21:31:21:45 | self[return] | +| url.swift:21:31:21:31 | self | url.swift:21:31:21:31 | SSA def(self) | +| url.swift:22:24:22:24 | SSA def(self) | url.swift:22:24:22:39 | self[return] | +| url.swift:22:24:22:24 | self | url.swift:22:24:22:24 | SSA def(self) | +| url.swift:23:26:23:26 | SSA def(self) | url.swift:23:26:23:54 | self[return] | +| url.swift:23:26:23:26 | self | url.swift:23:26:23:26 | SSA def(self) | +| url.swift:23:38:23:38 | URL.Type | url.swift:23:38:23:38 | call to init(string:) | +| url.swift:23:38:23:52 | call to init(string:) | url.swift:23:38:23:53 | ...! | +| url.swift:23:50:23:50 | | url.swift:23:38:23:52 | call to init(string:) | +| url.swift:24:33:24:33 | SSA def(self) | url.swift:24:33:24:61 | self[return] | +| url.swift:24:33:24:33 | self | url.swift:24:33:24:33 | SSA def(self) | +| url.swift:24:45:24:45 | URL.Type | url.swift:24:45:24:45 | call to init(string:) | +| url.swift:24:45:24:59 | call to init(string:) | url.swift:24:45:24:60 | ...! | +| url.swift:24:57:24:57 | | url.swift:24:45:24:59 | call to init(string:) | +| url.swift:25:22:25:22 | SSA def(self) | url.swift:25:22:25:37 | self[return] | +| url.swift:25:22:25:22 | self | url.swift:25:22:25:22 | SSA def(self) | +| url.swift:26:26:26:26 | SSA def(self) | url.swift:26:26:26:41 | self[return] | +| url.swift:26:26:26:26 | self | url.swift:26:26:26:26 | SSA def(self) | +| url.swift:29:7:29:7 | SSA def(self) | url.swift:29:7:29:7 | self[return] | +| url.swift:29:7:29:7 | self | url.swift:29:7:29:7 | SSA def(self) | +| url.swift:31:5:31:5 | SSA def(self) | url.swift:31:5:31:29 | self[return] | +| url.swift:31:5:31:5 | self | url.swift:31:5:31:5 | SSA def(self) | +| url.swift:34:7:34:7 | SSA def(self) | url.swift:34:7:34:7 | self[return] | +| url.swift:34:7:34:7 | self | url.swift:34:7:34:7 | SSA def(self) | +| url.swift:34:30:34:30 | SSA def(self) | url.swift:34:30:34:30 | self[return] | +| url.swift:34:30:34:30 | self | url.swift:34:30:34:30 | SSA def(self) | +| url.swift:36:7:36:7 | SSA def(self) | url.swift:36:7:36:7 | self[return] | +| url.swift:36:7:36:7 | self | url.swift:36:7:36:7 | SSA def(self) | +| url.swift:36:33:36:33 | SSA def(self) | url.swift:36:33:36:33 | self[return] | +| url.swift:36:33:36:33 | self | url.swift:36:33:36:33 | SSA def(self) | +| url.swift:38:7:38:7 | SSA def(self) | url.swift:38:7:38:7 | self[return] | +| url.swift:38:7:38:7 | self | url.swift:38:7:38:7 | SSA def(self) | +| url.swift:38:43:38:43 | SSA def(self) | url.swift:38:43:38:43 | self[return] | +| url.swift:38:43:38:43 | self | url.swift:38:43:38:43 | SSA def(self) | +| url.swift:40:7:40:7 | SSA def(self) | url.swift:40:7:40:7 | self[return] | +| url.swift:40:7:40:7 | SSA def(self) | url.swift:40:7:40:7 | self[return] | +| url.swift:40:7:40:7 | self | url.swift:40:7:40:7 | SSA def(self) | +| url.swift:40:7:40:7 | self | url.swift:40:7:40:7 | SSA def(self) | +| url.swift:41:33:41:33 | SSA def(self) | url.swift:41:33:41:59 | self[return] | +| url.swift:41:33:41:33 | self | url.swift:41:33:41:33 | SSA def(self) | +| url.swift:43:7:43:7 | SSA def(self) | url.swift:43:2:46:55 | self[return] | +| url.swift:43:7:43:7 | self | url.swift:43:7:43:7 | SSA def(self) | +| url.swift:56:6:56:6 | SSA def(clean) | url.swift:58:29:58:29 | clean | +| url.swift:56:14:56:14 | http://example.com/ | url.swift:56:6:56:6 | SSA def(clean) | +| url.swift:57:6:57:6 | SSA def(tainted) | url.swift:59:31:59:31 | tainted | +| url.swift:57:16:57:23 | call to source() | url.swift:57:6:57:6 | SSA def(tainted) | +| url.swift:58:6:58:6 | SSA def(urlClean) | url.swift:61:12:61:12 | urlClean | +| url.swift:58:17:58:17 | URL.Type | url.swift:58:17:58:17 | call to init(string:) | +| url.swift:58:17:58:34 | call to init(string:) | url.swift:58:17:58:35 | ...! | +| url.swift:58:17:58:35 | ...! | url.swift:58:6:58:6 | SSA def(urlClean) | +| url.swift:58:29:58:29 | [post] clean | url.swift:82:24:82:24 | clean | +| url.swift:58:29:58:29 | clean | url.swift:58:17:58:34 | call to init(string:) | +| url.swift:58:29:58:29 | clean | url.swift:82:24:82:24 | clean | +| url.swift:59:6:59:6 | SSA def(urlTainted) | url.swift:62:12:62:12 | urlTainted | +| url.swift:59:19:59:19 | URL.Type | url.swift:59:19:59:19 | call to init(string:) | +| url.swift:59:19:59:38 | call to init(string:) | url.swift:59:19:59:39 | ...! | +| url.swift:59:19:59:39 | ...! | url.swift:59:6:59:6 | SSA def(urlTainted) | +| url.swift:59:31:59:31 | [post] tainted | url.swift:83:24:83:24 | tainted | +| url.swift:59:31:59:31 | tainted | url.swift:59:19:59:38 | call to init(string:) | +| url.swift:59:31:59:31 | tainted | url.swift:83:24:83:24 | tainted | +| url.swift:61:12:61:12 | [post] urlClean | url.swift:84:43:84:43 | urlClean | +| url.swift:61:12:61:12 | urlClean | url.swift:84:43:84:43 | urlClean | +| url.swift:62:12:62:12 | [post] urlTainted | url.swift:64:12:64:12 | urlTainted | +| url.swift:62:12:62:12 | urlTainted | url.swift:64:12:64:12 | urlTainted | +| url.swift:64:12:64:12 | [post] urlTainted | url.swift:65:12:65:12 | urlTainted | | url.swift:64:12:64:12 | urlTainted | url.swift:64:12:64:23 | .absoluteURL | +| url.swift:64:12:64:12 | urlTainted | url.swift:65:12:65:12 | urlTainted | +| url.swift:65:12:65:12 | [post] urlTainted | url.swift:66:15:66:15 | urlTainted | | url.swift:65:12:65:12 | urlTainted | url.swift:65:12:65:23 | .baseURL | +| url.swift:65:12:65:12 | urlTainted | url.swift:66:15:66:15 | urlTainted | +| url.swift:66:15:66:15 | [post] urlTainted | url.swift:67:15:67:15 | urlTainted | | url.swift:66:15:66:15 | urlTainted | url.swift:66:15:66:26 | .fragment | +| url.swift:66:15:66:15 | urlTainted | url.swift:67:15:67:15 | urlTainted | +| url.swift:66:15:66:26 | .fragment | url.swift:66:15:66:34 | ...! | +| url.swift:67:15:67:15 | [post] urlTainted | url.swift:68:15:68:15 | urlTainted | | url.swift:67:15:67:15 | urlTainted | url.swift:67:15:67:26 | .host | +| url.swift:67:15:67:15 | urlTainted | url.swift:68:15:68:15 | urlTainted | +| url.swift:67:15:67:26 | .host | url.swift:67:15:67:30 | ...! | +| url.swift:68:15:68:15 | [post] urlTainted | url.swift:69:15:69:15 | urlTainted | | url.swift:68:15:68:15 | urlTainted | url.swift:68:15:68:26 | .lastPathComponent | +| url.swift:68:15:68:15 | urlTainted | url.swift:69:15:69:15 | urlTainted | +| url.swift:69:15:69:15 | [post] urlTainted | url.swift:70:15:70:15 | urlTainted | | url.swift:69:15:69:15 | urlTainted | url.swift:69:15:69:26 | .path | +| url.swift:69:15:69:15 | urlTainted | url.swift:70:15:70:15 | urlTainted | +| url.swift:70:15:70:15 | [post] urlTainted | url.swift:71:15:71:15 | urlTainted | | url.swift:70:15:70:15 | urlTainted | url.swift:70:15:70:26 | .pathComponents | +| url.swift:70:15:70:15 | urlTainted | url.swift:71:15:71:15 | urlTainted | | url.swift:70:15:70:26 | .pathComponents | url.swift:70:15:70:42 | ...[...] | +| url.swift:71:15:71:15 | [post] urlTainted | url.swift:72:12:72:12 | urlTainted | | url.swift:71:15:71:15 | urlTainted | url.swift:71:15:71:26 | .pathExtension | +| url.swift:71:15:71:15 | urlTainted | url.swift:72:12:72:12 | urlTainted | +| url.swift:72:12:72:12 | [post] urlTainted | url.swift:73:15:73:15 | urlTainted | | url.swift:72:12:72:12 | urlTainted | url.swift:72:12:72:23 | .port | +| url.swift:72:12:72:12 | urlTainted | url.swift:73:15:73:15 | urlTainted | +| url.swift:72:12:72:23 | .port | url.swift:72:12:72:27 | ...! | +| url.swift:73:15:73:15 | [post] urlTainted | url.swift:74:15:74:15 | urlTainted | | url.swift:73:15:73:15 | urlTainted | url.swift:73:15:73:26 | .query | +| url.swift:73:15:73:15 | urlTainted | url.swift:74:15:74:15 | urlTainted | +| url.swift:73:15:73:26 | .query | url.swift:73:15:73:31 | ...! | +| url.swift:74:15:74:15 | [post] urlTainted | url.swift:75:15:75:15 | urlTainted | | url.swift:74:15:74:15 | urlTainted | url.swift:74:15:74:26 | .relativePath | +| url.swift:74:15:74:15 | urlTainted | url.swift:75:15:75:15 | urlTainted | +| url.swift:75:15:75:15 | [post] urlTainted | url.swift:76:15:76:15 | urlTainted | | url.swift:75:15:75:15 | urlTainted | url.swift:75:15:75:26 | .relativeString | +| url.swift:75:15:75:15 | urlTainted | url.swift:76:15:76:15 | urlTainted | +| url.swift:76:15:76:15 | [post] urlTainted | url.swift:77:12:77:12 | urlTainted | | url.swift:76:15:76:15 | urlTainted | url.swift:76:15:76:26 | .scheme | +| url.swift:76:15:76:15 | urlTainted | url.swift:77:12:77:12 | urlTainted | +| url.swift:76:15:76:26 | .scheme | url.swift:76:15:76:32 | ...! | +| url.swift:77:12:77:12 | [post] urlTainted | url.swift:78:12:78:12 | urlTainted | | url.swift:77:12:77:12 | urlTainted | url.swift:77:12:77:23 | .standardized | +| url.swift:77:12:77:12 | urlTainted | url.swift:78:12:78:12 | urlTainted | +| url.swift:78:12:78:12 | [post] urlTainted | url.swift:79:15:79:15 | urlTainted | | url.swift:78:12:78:12 | urlTainted | url.swift:78:12:78:23 | .standardizedFileURL | +| url.swift:78:12:78:12 | urlTainted | url.swift:79:15:79:15 | urlTainted | +| url.swift:79:15:79:15 | [post] urlTainted | url.swift:80:15:80:15 | urlTainted | | url.swift:79:15:79:15 | urlTainted | url.swift:79:15:79:26 | .user | +| url.swift:79:15:79:15 | urlTainted | url.swift:80:15:80:15 | urlTainted | +| url.swift:79:15:79:26 | .user | url.swift:79:15:79:30 | ...! | +| url.swift:80:15:80:15 | [post] urlTainted | url.swift:86:43:86:43 | urlTainted | | url.swift:80:15:80:15 | urlTainted | url.swift:80:15:80:26 | .password | +| url.swift:80:15:80:15 | urlTainted | url.swift:86:43:86:43 | urlTainted | +| url.swift:80:15:80:26 | .password | url.swift:80:15:80:34 | ...! | +| url.swift:82:12:82:12 | URL.Type | url.swift:82:12:82:12 | call to init(string:relativeTo:) | +| url.swift:82:12:82:46 | call to init(string:relativeTo:) | url.swift:82:12:82:47 | ...! | +| url.swift:82:24:82:24 | [post] clean | url.swift:84:24:84:24 | clean | +| url.swift:82:24:82:24 | clean | url.swift:82:12:82:46 | call to init(string:relativeTo:) | +| url.swift:82:24:82:24 | clean | url.swift:84:24:84:24 | clean | +| url.swift:82:43:82:43 | nil | url.swift:82:12:82:46 | call to init(string:relativeTo:) | +| url.swift:83:12:83:12 | URL.Type | url.swift:83:12:83:12 | call to init(string:relativeTo:) | +| url.swift:83:12:83:48 | call to init(string:relativeTo:) | url.swift:83:12:83:49 | ...! | +| url.swift:83:24:83:24 | [post] tainted | url.swift:108:25:108:25 | tainted | +| url.swift:83:24:83:24 | tainted | url.swift:83:12:83:48 | call to init(string:relativeTo:) | +| url.swift:83:24:83:24 | tainted | url.swift:108:25:108:25 | tainted | +| url.swift:83:45:83:45 | nil | url.swift:83:12:83:48 | call to init(string:relativeTo:) | +| url.swift:84:12:84:12 | URL.Type | url.swift:84:12:84:12 | call to init(string:relativeTo:) | +| url.swift:84:12:84:51 | call to init(string:relativeTo:) | url.swift:84:12:84:52 | ...! | +| url.swift:84:24:84:24 | [post] clean | url.swift:86:24:86:24 | clean | +| url.swift:84:24:84:24 | clean | url.swift:84:12:84:51 | call to init(string:relativeTo:) | +| url.swift:84:24:84:24 | clean | url.swift:86:24:86:24 | clean | +| url.swift:84:43:84:43 | urlClean | url.swift:84:12:84:51 | call to init(string:relativeTo:) | +| url.swift:86:12:86:12 | URL.Type | url.swift:86:12:86:12 | call to init(string:relativeTo:) | +| url.swift:86:12:86:53 | call to init(string:relativeTo:) | url.swift:86:12:86:54 | ...! | | url.swift:86:12:86:54 | ...! | url.swift:86:12:86:56 | .absoluteURL | +| url.swift:86:24:86:24 | [post] clean | url.swift:87:24:87:24 | clean | +| url.swift:86:24:86:24 | clean | url.swift:86:12:86:53 | call to init(string:relativeTo:) | +| url.swift:86:24:86:24 | clean | url.swift:87:24:87:24 | clean | +| url.swift:86:43:86:43 | [post] urlTainted | url.swift:87:43:87:43 | urlTainted | +| url.swift:86:43:86:43 | urlTainted | url.swift:86:12:86:53 | call to init(string:relativeTo:) | +| url.swift:86:43:86:43 | urlTainted | url.swift:87:43:87:43 | urlTainted | +| url.swift:87:12:87:12 | URL.Type | url.swift:87:12:87:12 | call to init(string:relativeTo:) | +| url.swift:87:12:87:53 | call to init(string:relativeTo:) | url.swift:87:12:87:54 | ...! | | url.swift:87:12:87:54 | ...! | url.swift:87:12:87:56 | .baseURL | +| url.swift:87:24:87:24 | [post] clean | url.swift:88:27:88:27 | clean | +| url.swift:87:24:87:24 | clean | url.swift:87:12:87:53 | call to init(string:relativeTo:) | +| url.swift:87:24:87:24 | clean | url.swift:88:27:88:27 | clean | +| url.swift:87:43:87:43 | [post] urlTainted | url.swift:88:46:88:46 | urlTainted | +| url.swift:87:43:87:43 | urlTainted | url.swift:87:12:87:53 | call to init(string:relativeTo:) | +| url.swift:87:43:87:43 | urlTainted | url.swift:88:46:88:46 | urlTainted | +| url.swift:88:15:88:15 | URL.Type | url.swift:88:15:88:15 | call to init(string:relativeTo:) | +| url.swift:88:15:88:56 | call to init(string:relativeTo:) | url.swift:88:15:88:57 | ...! | | url.swift:88:15:88:57 | ...! | url.swift:88:15:88:59 | .fragment | +| url.swift:88:15:88:59 | .fragment | url.swift:88:15:88:67 | ...! | +| url.swift:88:27:88:27 | [post] clean | url.swift:89:27:89:27 | clean | +| url.swift:88:27:88:27 | clean | url.swift:88:15:88:56 | call to init(string:relativeTo:) | +| url.swift:88:27:88:27 | clean | url.swift:89:27:89:27 | clean | +| url.swift:88:46:88:46 | [post] urlTainted | url.swift:89:46:89:46 | urlTainted | +| url.swift:88:46:88:46 | urlTainted | url.swift:88:15:88:56 | call to init(string:relativeTo:) | +| url.swift:88:46:88:46 | urlTainted | url.swift:89:46:89:46 | urlTainted | +| url.swift:89:15:89:15 | URL.Type | url.swift:89:15:89:15 | call to init(string:relativeTo:) | +| url.swift:89:15:89:56 | call to init(string:relativeTo:) | url.swift:89:15:89:57 | ...! | | url.swift:89:15:89:57 | ...! | url.swift:89:15:89:59 | .host | +| url.swift:89:15:89:59 | .host | url.swift:89:15:89:63 | ...! | +| url.swift:89:27:89:27 | [post] clean | url.swift:90:27:90:27 | clean | +| url.swift:89:27:89:27 | clean | url.swift:89:15:89:56 | call to init(string:relativeTo:) | +| url.swift:89:27:89:27 | clean | url.swift:90:27:90:27 | clean | +| url.swift:89:46:89:46 | [post] urlTainted | url.swift:90:46:90:46 | urlTainted | +| url.swift:89:46:89:46 | urlTainted | url.swift:89:15:89:56 | call to init(string:relativeTo:) | +| url.swift:89:46:89:46 | urlTainted | url.swift:90:46:90:46 | urlTainted | +| url.swift:90:15:90:15 | URL.Type | url.swift:90:15:90:15 | call to init(string:relativeTo:) | +| url.swift:90:15:90:56 | call to init(string:relativeTo:) | url.swift:90:15:90:57 | ...! | | url.swift:90:15:90:57 | ...! | url.swift:90:15:90:59 | .lastPathComponent | +| url.swift:90:27:90:27 | [post] clean | url.swift:91:27:91:27 | clean | +| url.swift:90:27:90:27 | clean | url.swift:90:15:90:56 | call to init(string:relativeTo:) | +| url.swift:90:27:90:27 | clean | url.swift:91:27:91:27 | clean | +| url.swift:90:46:90:46 | [post] urlTainted | url.swift:91:46:91:46 | urlTainted | +| url.swift:90:46:90:46 | urlTainted | url.swift:90:15:90:56 | call to init(string:relativeTo:) | +| url.swift:90:46:90:46 | urlTainted | url.swift:91:46:91:46 | urlTainted | +| url.swift:91:15:91:15 | URL.Type | url.swift:91:15:91:15 | call to init(string:relativeTo:) | +| url.swift:91:15:91:56 | call to init(string:relativeTo:) | url.swift:91:15:91:57 | ...! | | url.swift:91:15:91:57 | ...! | url.swift:91:15:91:59 | .path | +| url.swift:91:27:91:27 | [post] clean | url.swift:92:27:92:27 | clean | +| url.swift:91:27:91:27 | clean | url.swift:91:15:91:56 | call to init(string:relativeTo:) | +| url.swift:91:27:91:27 | clean | url.swift:92:27:92:27 | clean | +| url.swift:91:46:91:46 | [post] urlTainted | url.swift:92:46:92:46 | urlTainted | +| url.swift:91:46:91:46 | urlTainted | url.swift:91:15:91:56 | call to init(string:relativeTo:) | +| url.swift:91:46:91:46 | urlTainted | url.swift:92:46:92:46 | urlTainted | +| url.swift:92:15:92:15 | URL.Type | url.swift:92:15:92:15 | call to init(string:relativeTo:) | +| url.swift:92:15:92:56 | call to init(string:relativeTo:) | url.swift:92:15:92:57 | ...! | | url.swift:92:15:92:57 | ...! | url.swift:92:15:92:59 | .pathComponents | | url.swift:92:15:92:59 | .pathComponents | url.swift:92:15:92:75 | ...[...] | +| url.swift:92:27:92:27 | [post] clean | url.swift:93:27:93:27 | clean | +| url.swift:92:27:92:27 | clean | url.swift:92:15:92:56 | call to init(string:relativeTo:) | +| url.swift:92:27:92:27 | clean | url.swift:93:27:93:27 | clean | +| url.swift:92:46:92:46 | [post] urlTainted | url.swift:93:46:93:46 | urlTainted | +| url.swift:92:46:92:46 | urlTainted | url.swift:92:15:92:56 | call to init(string:relativeTo:) | +| url.swift:92:46:92:46 | urlTainted | url.swift:93:46:93:46 | urlTainted | +| url.swift:93:15:93:15 | URL.Type | url.swift:93:15:93:15 | call to init(string:relativeTo:) | +| url.swift:93:15:93:56 | call to init(string:relativeTo:) | url.swift:93:15:93:57 | ...! | | url.swift:93:15:93:57 | ...! | url.swift:93:15:93:59 | .pathExtension | +| url.swift:93:27:93:27 | [post] clean | url.swift:94:24:94:24 | clean | +| url.swift:93:27:93:27 | clean | url.swift:93:15:93:56 | call to init(string:relativeTo:) | +| url.swift:93:27:93:27 | clean | url.swift:94:24:94:24 | clean | +| url.swift:93:46:93:46 | [post] urlTainted | url.swift:94:43:94:43 | urlTainted | +| url.swift:93:46:93:46 | urlTainted | url.swift:93:15:93:56 | call to init(string:relativeTo:) | +| url.swift:93:46:93:46 | urlTainted | url.swift:94:43:94:43 | urlTainted | +| url.swift:94:12:94:12 | URL.Type | url.swift:94:12:94:12 | call to init(string:relativeTo:) | +| url.swift:94:12:94:53 | call to init(string:relativeTo:) | url.swift:94:12:94:54 | ...! | | url.swift:94:12:94:54 | ...! | url.swift:94:12:94:56 | .port | +| url.swift:94:12:94:56 | .port | url.swift:94:12:94:60 | ...! | +| url.swift:94:24:94:24 | [post] clean | url.swift:95:27:95:27 | clean | +| url.swift:94:24:94:24 | clean | url.swift:94:12:94:53 | call to init(string:relativeTo:) | +| url.swift:94:24:94:24 | clean | url.swift:95:27:95:27 | clean | +| url.swift:94:43:94:43 | [post] urlTainted | url.swift:95:46:95:46 | urlTainted | +| url.swift:94:43:94:43 | urlTainted | url.swift:94:12:94:53 | call to init(string:relativeTo:) | +| url.swift:94:43:94:43 | urlTainted | url.swift:95:46:95:46 | urlTainted | +| url.swift:95:15:95:15 | URL.Type | url.swift:95:15:95:15 | call to init(string:relativeTo:) | +| url.swift:95:15:95:56 | call to init(string:relativeTo:) | url.swift:95:15:95:57 | ...! | | url.swift:95:15:95:57 | ...! | url.swift:95:15:95:59 | .query | +| url.swift:95:15:95:59 | .query | url.swift:95:15:95:64 | ...! | +| url.swift:95:27:95:27 | [post] clean | url.swift:96:27:96:27 | clean | +| url.swift:95:27:95:27 | clean | url.swift:95:15:95:56 | call to init(string:relativeTo:) | +| url.swift:95:27:95:27 | clean | url.swift:96:27:96:27 | clean | +| url.swift:95:46:95:46 | [post] urlTainted | url.swift:96:46:96:46 | urlTainted | +| url.swift:95:46:95:46 | urlTainted | url.swift:95:15:95:56 | call to init(string:relativeTo:) | +| url.swift:95:46:95:46 | urlTainted | url.swift:96:46:96:46 | urlTainted | +| url.swift:96:15:96:15 | URL.Type | url.swift:96:15:96:15 | call to init(string:relativeTo:) | +| url.swift:96:15:96:56 | call to init(string:relativeTo:) | url.swift:96:15:96:57 | ...! | | url.swift:96:15:96:57 | ...! | url.swift:96:15:96:59 | .relativePath | +| url.swift:96:27:96:27 | [post] clean | url.swift:97:27:97:27 | clean | +| url.swift:96:27:96:27 | clean | url.swift:96:15:96:56 | call to init(string:relativeTo:) | +| url.swift:96:27:96:27 | clean | url.swift:97:27:97:27 | clean | +| url.swift:96:46:96:46 | [post] urlTainted | url.swift:97:46:97:46 | urlTainted | +| url.swift:96:46:96:46 | urlTainted | url.swift:96:15:96:56 | call to init(string:relativeTo:) | +| url.swift:96:46:96:46 | urlTainted | url.swift:97:46:97:46 | urlTainted | +| url.swift:97:15:97:15 | URL.Type | url.swift:97:15:97:15 | call to init(string:relativeTo:) | +| url.swift:97:15:97:56 | call to init(string:relativeTo:) | url.swift:97:15:97:57 | ...! | | url.swift:97:15:97:57 | ...! | url.swift:97:15:97:59 | .relativeString | +| url.swift:97:27:97:27 | [post] clean | url.swift:98:27:98:27 | clean | +| url.swift:97:27:97:27 | clean | url.swift:97:15:97:56 | call to init(string:relativeTo:) | +| url.swift:97:27:97:27 | clean | url.swift:98:27:98:27 | clean | +| url.swift:97:46:97:46 | [post] urlTainted | url.swift:98:46:98:46 | urlTainted | +| url.swift:97:46:97:46 | urlTainted | url.swift:97:15:97:56 | call to init(string:relativeTo:) | +| url.swift:97:46:97:46 | urlTainted | url.swift:98:46:98:46 | urlTainted | +| url.swift:98:15:98:15 | URL.Type | url.swift:98:15:98:15 | call to init(string:relativeTo:) | +| url.swift:98:15:98:56 | call to init(string:relativeTo:) | url.swift:98:15:98:57 | ...! | | url.swift:98:15:98:57 | ...! | url.swift:98:15:98:59 | .scheme | +| url.swift:98:15:98:59 | .scheme | url.swift:98:15:98:65 | ...! | +| url.swift:98:27:98:27 | [post] clean | url.swift:99:24:99:24 | clean | +| url.swift:98:27:98:27 | clean | url.swift:98:15:98:56 | call to init(string:relativeTo:) | +| url.swift:98:27:98:27 | clean | url.swift:99:24:99:24 | clean | +| url.swift:98:46:98:46 | [post] urlTainted | url.swift:99:43:99:43 | urlTainted | +| url.swift:98:46:98:46 | urlTainted | url.swift:98:15:98:56 | call to init(string:relativeTo:) | +| url.swift:98:46:98:46 | urlTainted | url.swift:99:43:99:43 | urlTainted | +| url.swift:99:12:99:12 | URL.Type | url.swift:99:12:99:12 | call to init(string:relativeTo:) | +| url.swift:99:12:99:53 | call to init(string:relativeTo:) | url.swift:99:12:99:54 | ...! | | url.swift:99:12:99:54 | ...! | url.swift:99:12:99:56 | .standardized | +| url.swift:99:24:99:24 | [post] clean | url.swift:100:24:100:24 | clean | +| url.swift:99:24:99:24 | clean | url.swift:99:12:99:53 | call to init(string:relativeTo:) | +| url.swift:99:24:99:24 | clean | url.swift:100:24:100:24 | clean | +| url.swift:99:43:99:43 | [post] urlTainted | url.swift:100:43:100:43 | urlTainted | +| url.swift:99:43:99:43 | urlTainted | url.swift:99:12:99:53 | call to init(string:relativeTo:) | +| url.swift:99:43:99:43 | urlTainted | url.swift:100:43:100:43 | urlTainted | +| url.swift:100:12:100:12 | URL.Type | url.swift:100:12:100:12 | call to init(string:relativeTo:) | +| url.swift:100:12:100:53 | call to init(string:relativeTo:) | url.swift:100:12:100:54 | ...! | | url.swift:100:12:100:54 | ...! | url.swift:100:12:100:56 | .standardizedFileURL | +| url.swift:100:24:100:24 | [post] clean | url.swift:101:27:101:27 | clean | +| url.swift:100:24:100:24 | clean | url.swift:100:12:100:53 | call to init(string:relativeTo:) | +| url.swift:100:24:100:24 | clean | url.swift:101:27:101:27 | clean | +| url.swift:100:43:100:43 | [post] urlTainted | url.swift:101:46:101:46 | urlTainted | +| url.swift:100:43:100:43 | urlTainted | url.swift:100:12:100:53 | call to init(string:relativeTo:) | +| url.swift:100:43:100:43 | urlTainted | url.swift:101:46:101:46 | urlTainted | +| url.swift:101:15:101:15 | URL.Type | url.swift:101:15:101:15 | call to init(string:relativeTo:) | +| url.swift:101:15:101:56 | call to init(string:relativeTo:) | url.swift:101:15:101:57 | ...! | | url.swift:101:15:101:57 | ...! | url.swift:101:15:101:59 | .user | +| url.swift:101:15:101:59 | .user | url.swift:101:15:101:63 | ...! | +| url.swift:101:27:101:27 | [post] clean | url.swift:102:27:102:27 | clean | +| url.swift:101:27:101:27 | clean | url.swift:101:15:101:56 | call to init(string:relativeTo:) | +| url.swift:101:27:101:27 | clean | url.swift:102:27:102:27 | clean | +| url.swift:101:46:101:46 | [post] urlTainted | url.swift:102:46:102:46 | urlTainted | +| url.swift:101:46:101:46 | urlTainted | url.swift:101:15:101:56 | call to init(string:relativeTo:) | +| url.swift:101:46:101:46 | urlTainted | url.swift:102:46:102:46 | urlTainted | +| url.swift:102:15:102:15 | URL.Type | url.swift:102:15:102:15 | call to init(string:relativeTo:) | +| url.swift:102:15:102:56 | call to init(string:relativeTo:) | url.swift:102:15:102:57 | ...! | | url.swift:102:15:102:57 | ...! | url.swift:102:15:102:59 | .password | +| url.swift:102:15:102:59 | .password | url.swift:102:15:102:67 | ...! | +| url.swift:102:27:102:27 | [post] clean | url.swift:104:25:104:25 | clean | +| url.swift:102:27:102:27 | clean | url.swift:102:15:102:56 | call to init(string:relativeTo:) | +| url.swift:102:27:102:27 | clean | url.swift:104:25:104:25 | clean | +| url.swift:102:46:102:46 | [post] urlTainted | url.swift:120:46:120:46 | urlTainted | +| url.swift:102:46:102:46 | urlTainted | url.swift:102:15:102:56 | call to init(string:relativeTo:) | +| url.swift:102:46:102:46 | urlTainted | url.swift:120:46:120:46 | urlTainted | +| url.swift:104:13:104:13 | URL.Type | url.swift:104:13:104:13 | call to init(string:) | +| url.swift:104:25:104:25 | [post] clean | url.swift:113:26:113:26 | clean | +| url.swift:104:25:104:25 | clean | url.swift:104:13:104:30 | call to init(string:) | +| url.swift:104:25:104:25 | clean | url.swift:113:26:113:26 | clean | +| url.swift:108:13:108:13 | URL.Type | url.swift:108:13:108:13 | call to init(string:) | +| url.swift:108:25:108:25 | [post] tainted | url.swift:117:28:117:28 | tainted | +| url.swift:108:25:108:25 | tainted | url.swift:108:13:108:32 | call to init(string:) | +| url.swift:108:25:108:25 | tainted | url.swift:117:28:117:28 | tainted | +| url.swift:113:2:113:31 | SSA def(urlClean2) | url.swift:114:12:114:12 | urlClean2 | +| url.swift:113:14:113:14 | URL.Type | url.swift:113:14:113:14 | call to init(string:) | +| url.swift:113:14:113:31 | call to init(string:) | url.swift:113:2:113:31 | SSA def(urlClean2) | +| url.swift:113:26:113:26 | clean | url.swift:113:14:113:31 | call to init(string:) | +| url.swift:114:12:114:12 | urlClean2 | url.swift:114:12:114:12 | ...! | +| url.swift:117:2:117:35 | SSA def(urlTainted2) | url.swift:118:12:118:12 | urlTainted2 | +| url.swift:117:16:117:16 | URL.Type | url.swift:117:16:117:16 | call to init(string:) | +| url.swift:117:16:117:35 | call to init(string:) | url.swift:117:2:117:35 | SSA def(urlTainted2) | +| url.swift:117:28:117:28 | tainted | url.swift:117:16:117:35 | call to init(string:) | +| url.swift:118:12:118:12 | urlTainted2 | url.swift:118:12:118:12 | ...! | +| url.swift:120:61:120:61 | SSA def(data) | url.swift:121:15:121:15 | data | +| url.swift:120:61:120:61 | data | url.swift:120:61:120:61 | SSA def(data) | +| url.swift:121:15:121:15 | data | url.swift:121:15:121:19 | ...! | +| webview.swift:4:7:4:7 | SSA def(self) | webview.swift:4:7:4:7 | self[return] | +| webview.swift:4:7:4:7 | SSA def(self) | webview.swift:4:7:4:7 | self[return] | +| webview.swift:4:7:4:7 | self | webview.swift:4:7:4:7 | SSA def(self) | +| webview.swift:4:7:4:7 | self | webview.swift:4:7:4:7 | SSA def(self) | +| webview.swift:6:7:6:7 | SSA def(self) | webview.swift:6:7:6:7 | self[return] | +| webview.swift:6:7:6:7 | self | webview.swift:6:7:6:7 | SSA def(self) | +| webview.swift:6:34:6:34 | SSA def(self) | webview.swift:6:34:6:34 | self[return] | +| webview.swift:6:34:6:34 | self | webview.swift:6:34:6:34 | SSA def(self) | +| webview.swift:7:26:7:26 | SSA def(self) | webview.swift:7:26:7:42 | self[return] | +| webview.swift:7:26:7:26 | self | webview.swift:7:26:7:26 | SSA def(self) | +| webview.swift:10:7:10:7 | SSA def(self) | webview.swift:10:7:10:7 | self[return] | +| webview.swift:10:7:10:7 | self | webview.swift:10:7:10:7 | SSA def(self) | +| webview.swift:11:5:11:5 | SSA def(self) | webview.swift:11:5:11:23 | self[return] | +| webview.swift:11:5:11:5 | self | webview.swift:11:5:11:5 | SSA def(self) | +| webview.swift:14:7:14:7 | SSA def(self) | webview.swift:14:7:14:7 | self[return] | +| webview.swift:14:7:14:7 | SSA def(self) | webview.swift:14:7:14:7 | self[return] | +| webview.swift:14:7:14:7 | self | webview.swift:14:7:14:7 | SSA def(self) | +| webview.swift:14:7:14:7 | self | webview.swift:14:7:14:7 | SSA def(self) | +| webview.swift:16:7:16:7 | SSA def(self) | webview.swift:16:7:16:7 | self[return] | +| webview.swift:16:7:16:7 | SSA def(self) | webview.swift:16:7:16:7 | self[return] | +| webview.swift:16:7:16:7 | self | webview.swift:16:7:16:7 | SSA def(self) | +| webview.swift:16:7:16:7 | self | webview.swift:16:7:16:7 | SSA def(self) | +| webview.swift:18:7:18:7 | SSA def(self) | webview.swift:18:7:18:7 | self[return] | +| webview.swift:18:7:18:7 | SSA def(self) | webview.swift:18:7:18:7 | self[return] | +| webview.swift:18:7:18:7 | self | webview.swift:18:7:18:7 | SSA def(self) | +| webview.swift:18:7:18:7 | self | webview.swift:18:7:18:7 | SSA def(self) | +| webview.swift:20:7:20:7 | SSA def(self) | webview.swift:20:7:20:7 | self[return] | +| webview.swift:20:7:20:7 | SSA def(self) | webview.swift:20:7:20:7 | self[return] | +| webview.swift:20:7:20:7 | self | webview.swift:20:7:20:7 | SSA def(self) | +| webview.swift:20:7:20:7 | self | webview.swift:20:7:20:7 | SSA def(self) | +| webview.swift:22:7:22:7 | SSA def(self) | webview.swift:22:7:22:7 | self[return] | +| webview.swift:22:7:22:7 | SSA def(self) | webview.swift:22:7:22:7 | self[return] | +| webview.swift:22:7:22:7 | self | webview.swift:22:7:22:7 | SSA def(self) | +| webview.swift:22:7:22:7 | self | webview.swift:22:7:22:7 | SSA def(self) | +| webview.swift:24:7:24:7 | SSA def(self) | webview.swift:24:7:24:7 | self[return] | +| webview.swift:24:7:24:7 | SSA def(self) | webview.swift:24:7:24:7 | self[return] | +| webview.swift:24:7:24:7 | self | webview.swift:24:7:24:7 | SSA def(self) | +| webview.swift:24:7:24:7 | self | webview.swift:24:7:24:7 | SSA def(self) | +| webview.swift:26:7:26:7 | SSA def(self) | webview.swift:26:7:26:7 | self[return] | +| webview.swift:26:7:26:7 | self | webview.swift:26:7:26:7 | SSA def(self) | +| webview.swift:27:5:27:5 | SSA def(self) | webview.swift:27:5:27:39 | self[return] | +| webview.swift:27:5:27:5 | self | webview.swift:27:5:27:5 | SSA def(self) | +| webview.swift:28:5:28:5 | SSA def(self) | webview.swift:28:5:28:38 | self[return] | +| webview.swift:28:5:28:5 | self | webview.swift:28:5:28:5 | SSA def(self) | +| webview.swift:29:5:29:5 | SSA def(self) | webview.swift:29:5:29:42 | self[return] | +| webview.swift:29:5:29:5 | self | webview.swift:29:5:29:5 | SSA def(self) | +| webview.swift:30:5:30:5 | SSA def(self) | webview.swift:30:5:30:40 | self[return] | +| webview.swift:30:5:30:5 | self | webview.swift:30:5:30:5 | SSA def(self) | +| webview.swift:31:5:31:5 | SSA def(self) | webview.swift:31:5:31:42 | self[return] | +| webview.swift:31:5:31:5 | self | webview.swift:31:5:31:5 | SSA def(self) | +| webview.swift:32:5:32:5 | SSA def(self) | webview.swift:32:5:32:42 | self[return] | +| webview.swift:32:5:32:5 | self | webview.swift:32:5:32:5 | SSA def(self) | +| webview.swift:33:5:33:5 | SSA def(self) | webview.swift:33:5:33:42 | self[return] | +| webview.swift:33:5:33:5 | self | webview.swift:33:5:33:5 | SSA def(self) | +| webview.swift:34:5:34:5 | SSA def(self) | webview.swift:34:5:34:40 | self[return] | +| webview.swift:34:5:34:5 | self | webview.swift:34:5:34:5 | SSA def(self) | +| webview.swift:35:5:35:5 | SSA def(self) | webview.swift:35:5:35:40 | self[return] | +| webview.swift:35:5:35:5 | self | webview.swift:35:5:35:5 | SSA def(self) | +| webview.swift:36:10:36:10 | SSA def(self) | webview.swift:36:5:36:41 | self[return] | +| webview.swift:36:10:36:10 | self | webview.swift:36:10:36:10 | SSA def(self) | +| webview.swift:37:10:37:10 | SSA def(self) | webview.swift:37:5:37:55 | self[return] | +| webview.swift:37:10:37:10 | self | webview.swift:37:10:37:10 | SSA def(self) | +| webview.swift:38:10:38:10 | SSA def(self) | webview.swift:38:5:38:42 | self[return] | +| webview.swift:38:10:38:10 | self | webview.swift:38:10:38:10 | SSA def(self) | +| webview.swift:39:10:39:10 | SSA def(self) | webview.swift:39:5:39:44 | self[return] | +| webview.swift:39:10:39:10 | self | webview.swift:39:10:39:10 | SSA def(self) | +| webview.swift:40:10:40:10 | SSA def(self) | webview.swift:40:5:40:40 | self[return] | +| webview.swift:40:10:40:10 | self | webview.swift:40:10:40:10 | SSA def(self) | +| webview.swift:41:10:41:10 | SSA def(self) | webview.swift:41:5:41:42 | self[return] | +| webview.swift:41:10:41:10 | self | webview.swift:41:10:41:10 | SSA def(self) | +| webview.swift:42:10:42:10 | SSA def(self) | webview.swift:42:5:42:62 | self[return] | +| webview.swift:42:10:42:10 | self | webview.swift:42:10:42:10 | SSA def(self) | +| webview.swift:43:10:43:10 | SSA def(self) | webview.swift:43:5:43:44 | self[return] | +| webview.swift:43:10:43:10 | self | webview.swift:43:10:43:10 | SSA def(self) | +| webview.swift:44:10:44:10 | SSA def(self) | webview.swift:44:5:44:44 | self[return] | +| webview.swift:44:10:44:10 | self | webview.swift:44:10:44:10 | SSA def(self) | +| webview.swift:45:10:45:10 | SSA def(self) | webview.swift:45:5:45:44 | self[return] | +| webview.swift:45:10:45:10 | self | webview.swift:45:10:45:10 | SSA def(self) | +| webview.swift:46:10:46:10 | SSA def(self) | webview.swift:46:5:46:65 | self[return] | +| webview.swift:46:10:46:10 | self | webview.swift:46:10:46:10 | SSA def(self) | +| webview.swift:47:10:47:10 | SSA def(self) | webview.swift:47:5:47:50 | self[return] | +| webview.swift:47:10:47:10 | self | webview.swift:47:10:47:10 | SSA def(self) | +| webview.swift:48:10:48:10 | SSA def(self) | webview.swift:48:5:48:50 | self[return] | +| webview.swift:48:10:48:10 | self | webview.swift:48:10:48:10 | SSA def(self) | +| webview.swift:49:10:49:10 | SSA def(self) | webview.swift:49:5:49:47 | self[return] | +| webview.swift:49:10:49:10 | self | webview.swift:49:10:49:10 | SSA def(self) | +| webview.swift:50:10:50:10 | SSA def(self) | webview.swift:50:5:50:47 | self[return] | +| webview.swift:50:10:50:10 | self | webview.swift:50:10:50:10 | SSA def(self) | +| webview.swift:51:10:51:10 | SSA def(self) | webview.swift:51:5:51:84 | self[return] | +| webview.swift:51:10:51:10 | self | webview.swift:51:10:51:10 | SSA def(self) | +| webview.swift:51:47:51:47 | JSValue.Type | webview.swift:51:47:51:47 | call to init(object:in:) | +| webview.swift:51:63:51:63 | | webview.swift:51:47:51:82 | call to init(object:in:) | +| webview.swift:52:10:52:10 | SSA def(self) | webview.swift:52:5:52:53 | self[return] | +| webview.swift:52:10:52:10 | self | webview.swift:52:10:52:10 | SSA def(self) | +| webview.swift:53:10:53:10 | SSA def(self) | webview.swift:53:5:53:89 | self[return] | +| webview.swift:53:10:53:10 | self | webview.swift:53:10:53:10 | SSA def(self) | +| webview.swift:53:52:53:52 | JSValue.Type | webview.swift:53:52:53:52 | call to init(object:in:) | +| webview.swift:53:68:53:68 | | webview.swift:53:52:53:87 | call to init(object:in:) | +| webview.swift:54:10:54:10 | SSA def(self) | webview.swift:54:5:54:38 | self[return] | +| webview.swift:54:10:54:10 | self | webview.swift:54:10:54:10 | SSA def(self) | +| webview.swift:55:10:55:10 | SSA def(self) | webview.swift:55:5:55:48 | self[return] | +| webview.swift:55:10:55:10 | self | webview.swift:55:10:55:10 | SSA def(self) | +| webview.swift:62:7:62:7 | SSA def(self) | webview.swift:62:7:62:7 | self[return] | +| webview.swift:62:7:62:7 | self | webview.swift:62:7:62:7 | SSA def(self) | +| webview.swift:62:33:62:33 | SSA def(self) | webview.swift:62:33:62:33 | self[return] | +| webview.swift:62:33:62:33 | self | webview.swift:62:33:62:33 | SSA def(self) | +| webview.swift:64:7:64:7 | SSA def(self) | webview.swift:64:7:64:7 | self[return] | +| webview.swift:64:7:64:7 | self | webview.swift:64:7:64:7 | SSA def(self) | +| webview.swift:64:31:64:31 | SSA def(self) | webview.swift:64:31:64:31 | self[return] | +| webview.swift:64:31:64:31 | self | webview.swift:64:31:64:31 | SSA def(self) | +| webview.swift:65:5:65:5 | SSA def(self) | webview.swift:65:5:65:93 | self[return] | +| webview.swift:65:5:65:5 | self | webview.swift:65:5:65:5 | SSA def(self) | +| webview.swift:66:5:66:5 | SSA def(self) | webview.swift:66:5:66:126 | self[return] | +| webview.swift:66:5:66:5 | self | webview.swift:66:5:66:5 | SSA def(self) | +| webview.swift:68:26:68:26 | SSA def(self) | webview.swift:68:26:68:42 | self[return] | +| webview.swift:68:26:68:26 | self | webview.swift:68:26:68:26 | SSA def(self) | | webview.swift:77:11:77:18 | call to source() | webview.swift:77:10:77:41 | .body | +| webview.swift:81:9:81:9 | SSA def(s) | webview.swift:83:18:83:18 | s | +| webview.swift:81:13:81:20 | call to source() | webview.swift:81:9:81:9 | SSA def(s) | +| webview.swift:83:9:83:9 | SSA def(source) | webview.swift:84:10:84:10 | source | +| webview.swift:83:18:83:18 | s | webview.swift:83:9:83:9 | SSA def(source) | +| webview.swift:83:18:83:18 | s | webview.swift:103:26:103:26 | s | +| webview.swift:84:10:84:10 | [post] source | webview.swift:85:10:85:10 | source | +| webview.swift:84:10:84:10 | source | webview.swift:84:10:84:26 | call to toObject() | +| webview.swift:84:10:84:10 | source | webview.swift:85:10:85:10 | source | +| webview.swift:85:10:85:10 | [post] source | webview.swift:86:10:86:10 | source | +| webview.swift:85:10:85:10 | source | webview.swift:85:10:85:41 | call to toObjectOf(_:) | +| webview.swift:85:10:85:10 | source | webview.swift:86:10:86:10 | source | +| webview.swift:86:10:86:10 | [post] source | webview.swift:87:10:87:10 | source | +| webview.swift:86:10:86:10 | source | webview.swift:86:10:86:24 | call to toBool() | +| webview.swift:86:10:86:10 | source | webview.swift:87:10:87:10 | source | +| webview.swift:87:10:87:10 | [post] source | webview.swift:88:10:88:10 | source | +| webview.swift:87:10:87:10 | source | webview.swift:87:10:87:26 | call to toDouble() | +| webview.swift:87:10:87:10 | source | webview.swift:88:10:88:10 | source | +| webview.swift:88:10:88:10 | [post] source | webview.swift:89:10:89:10 | source | +| webview.swift:88:10:88:10 | source | webview.swift:88:10:88:25 | call to toInt32() | +| webview.swift:88:10:88:10 | source | webview.swift:89:10:89:10 | source | +| webview.swift:89:10:89:10 | [post] source | webview.swift:90:10:90:10 | source | +| webview.swift:89:10:89:10 | source | webview.swift:89:10:89:26 | call to toUInt32() | +| webview.swift:89:10:89:10 | source | webview.swift:90:10:90:10 | source | +| webview.swift:90:10:90:10 | [post] source | webview.swift:91:10:91:10 | source | +| webview.swift:90:10:90:10 | source | webview.swift:90:10:90:26 | call to toNumber() | +| webview.swift:90:10:90:10 | source | webview.swift:91:10:91:10 | source | +| webview.swift:91:10:91:10 | [post] source | webview.swift:92:10:92:10 | source | +| webview.swift:91:10:91:10 | source | webview.swift:91:10:91:26 | call to toString() | +| webview.swift:91:10:91:10 | source | webview.swift:92:10:92:10 | source | +| webview.swift:92:10:92:10 | [post] source | webview.swift:93:10:93:10 | source | +| webview.swift:92:10:92:10 | source | webview.swift:92:10:92:24 | call to toDate() | +| webview.swift:92:10:92:10 | source | webview.swift:93:10:93:10 | source | +| webview.swift:93:10:93:10 | [post] source | webview.swift:94:10:94:10 | source | +| webview.swift:93:10:93:10 | source | webview.swift:93:10:93:25 | call to toArray() | +| webview.swift:93:10:93:10 | source | webview.swift:94:10:94:10 | source | +| webview.swift:94:10:94:10 | [post] source | webview.swift:95:10:95:10 | source | +| webview.swift:94:10:94:10 | source | webview.swift:94:10:94:30 | call to toDictionary() | +| webview.swift:94:10:94:10 | source | webview.swift:95:10:95:10 | source | +| webview.swift:95:10:95:10 | [post] source | webview.swift:96:10:96:10 | source | +| webview.swift:95:10:95:10 | source | webview.swift:95:10:95:25 | call to toPoint() | +| webview.swift:95:10:95:10 | source | webview.swift:96:10:96:10 | source | +| webview.swift:96:10:96:10 | [post] source | webview.swift:97:10:97:10 | source | +| webview.swift:96:10:96:10 | source | webview.swift:96:10:96:25 | call to toRange() | +| webview.swift:96:10:96:10 | source | webview.swift:97:10:97:10 | source | +| webview.swift:97:10:97:10 | [post] source | webview.swift:98:10:98:10 | source | +| webview.swift:97:10:97:10 | source | webview.swift:97:10:97:24 | call to toRect() | +| webview.swift:97:10:97:10 | source | webview.swift:98:10:98:10 | source | +| webview.swift:98:10:98:10 | [post] source | webview.swift:99:10:99:10 | source | +| webview.swift:98:10:98:10 | source | webview.swift:98:10:98:24 | call to toSize() | +| webview.swift:98:10:98:10 | source | webview.swift:99:10:99:10 | source | +| webview.swift:99:10:99:10 | [post] source | webview.swift:100:10:100:10 | source | +| webview.swift:99:10:99:10 | source | webview.swift:99:10:99:26 | call to atIndex(_:) | +| webview.swift:99:10:99:10 | source | webview.swift:100:10:100:10 | source | +| webview.swift:100:10:100:10 | source | webview.swift:100:10:100:31 | call to forProperty(_:) | +| webview.swift:102:9:102:9 | SSA def(context) | webview.swift:103:40:103:40 | context | +| webview.swift:102:19:102:29 | call to init() | webview.swift:102:9:102:9 | SSA def(context) | +| webview.swift:103:10:103:10 | JSValue.Type | webview.swift:103:10:103:10 | call to init(object:in:) | +| webview.swift:103:26:103:26 | s | webview.swift:103:10:103:47 | call to init(object:in:) | +| webview.swift:103:26:103:26 | s | webview.swift:104:24:104:24 | s | +| webview.swift:103:40:103:40 | [post] context | webview.swift:104:40:104:40 | context | +| webview.swift:103:40:103:40 | context | webview.swift:104:40:104:40 | context | +| webview.swift:104:10:104:10 | JSValue.Type | webview.swift:104:10:104:10 | call to init(bool:in:) | +| webview.swift:104:24:104:24 | s | webview.swift:104:10:104:47 | call to init(bool:in:) | +| webview.swift:104:24:104:24 | s | webview.swift:105:26:105:26 | s | +| webview.swift:104:40:104:40 | [post] context | webview.swift:105:44:105:44 | context | +| webview.swift:104:40:104:40 | context | webview.swift:105:44:105:44 | context | +| webview.swift:105:10:105:10 | JSValue.Type | webview.swift:105:10:105:10 | call to init(double:in:) | +| webview.swift:105:26:105:26 | s | webview.swift:105:10:105:51 | call to init(double:in:) | +| webview.swift:105:26:105:26 | s | webview.swift:106:25:106:25 | s | +| webview.swift:105:44:105:44 | [post] context | webview.swift:106:42:106:42 | context | +| webview.swift:105:44:105:44 | context | webview.swift:106:42:106:42 | context | +| webview.swift:106:10:106:10 | JSValue.Type | webview.swift:106:10:106:10 | call to init(int32:in:) | +| webview.swift:106:25:106:25 | s | webview.swift:106:10:106:49 | call to init(int32:in:) | +| webview.swift:106:25:106:25 | s | webview.swift:107:26:107:26 | s | +| webview.swift:106:42:106:42 | [post] context | webview.swift:107:44:107:44 | context | +| webview.swift:106:42:106:42 | context | webview.swift:107:44:107:44 | context | +| webview.swift:107:10:107:10 | JSValue.Type | webview.swift:107:10:107:10 | call to init(uInt32:in:) | +| webview.swift:107:26:107:26 | s | webview.swift:107:10:107:51 | call to init(uInt32:in:) | +| webview.swift:107:26:107:26 | s | webview.swift:108:25:108:25 | s | +| webview.swift:107:44:107:44 | [post] context | webview.swift:108:44:108:44 | context | +| webview.swift:107:44:107:44 | context | webview.swift:108:44:108:44 | context | +| webview.swift:108:10:108:10 | JSValue.Type | webview.swift:108:10:108:10 | call to init(point:in:) | +| webview.swift:108:25:108:25 | s | webview.swift:108:10:108:51 | call to init(point:in:) | +| webview.swift:108:25:108:25 | s | webview.swift:109:25:109:25 | s | +| webview.swift:108:44:108:44 | [post] context | webview.swift:109:44:109:44 | context | +| webview.swift:108:44:108:44 | context | webview.swift:109:44:109:44 | context | +| webview.swift:109:10:109:10 | JSValue.Type | webview.swift:109:10:109:10 | call to init(range:in:) | +| webview.swift:109:25:109:25 | s | webview.swift:109:10:109:51 | call to init(range:in:) | +| webview.swift:109:25:109:25 | s | webview.swift:110:24:110:24 | s | +| webview.swift:109:44:109:44 | [post] context | webview.swift:110:42:110:42 | context | +| webview.swift:109:44:109:44 | context | webview.swift:110:42:110:42 | context | +| webview.swift:110:10:110:10 | JSValue.Type | webview.swift:110:10:110:10 | call to init(rect:in:) | +| webview.swift:110:24:110:24 | s | webview.swift:110:10:110:49 | call to init(rect:in:) | +| webview.swift:110:24:110:24 | s | webview.swift:111:24:111:24 | s | +| webview.swift:110:42:110:42 | [post] context | webview.swift:111:42:111:42 | context | +| webview.swift:110:42:110:42 | context | webview.swift:111:42:111:42 | context | +| webview.swift:111:10:111:10 | JSValue.Type | webview.swift:111:10:111:10 | call to init(size:in:) | +| webview.swift:111:24:111:24 | s | webview.swift:111:10:111:49 | call to init(size:in:) | +| webview.swift:111:24:111:24 | s | webview.swift:114:39:114:39 | s | +| webview.swift:111:42:111:42 | [post] context | webview.swift:113:38:113:38 | context | +| webview.swift:111:42:111:42 | context | webview.swift:113:38:113:38 | context | +| webview.swift:113:9:113:9 | SSA def(v1) | webview.swift:114:5:114:5 | v1 | +| webview.swift:113:14:113:14 | JSValue.Type | webview.swift:113:14:113:14 | call to init(object:in:) | +| webview.swift:113:14:113:45 | call to init(object:in:) | webview.swift:113:9:113:9 | SSA def(v1) | +| webview.swift:113:30:113:30 | | webview.swift:113:14:113:45 | call to init(object:in:) | +| webview.swift:113:38:113:38 | [post] context | webview.swift:117:38:117:38 | context | +| webview.swift:113:38:113:38 | context | webview.swift:117:38:117:38 | context | +| webview.swift:114:5:114:5 | [post] v1 | webview.swift:115:10:115:10 | v1 | +| webview.swift:114:5:114:5 | v1 | webview.swift:115:10:115:10 | v1 | +| webview.swift:114:39:114:39 | s | webview.swift:114:5:114:5 | [post] v1 | +| webview.swift:114:39:114:39 | s | webview.swift:118:17:118:17 | s | +| webview.swift:117:9:117:9 | SSA def(v2) | webview.swift:118:5:118:5 | v2 | +| webview.swift:117:14:117:14 | JSValue.Type | webview.swift:117:14:117:14 | call to init(object:in:) | +| webview.swift:117:14:117:45 | call to init(object:in:) | webview.swift:117:9:117:9 | SSA def(v2) | +| webview.swift:117:30:117:30 | | webview.swift:117:14:117:45 | call to init(object:in:) | +| webview.swift:117:38:117:38 | [post] context | webview.swift:121:38:121:38 | context | +| webview.swift:117:38:117:38 | context | webview.swift:121:38:121:38 | context | +| webview.swift:118:5:118:5 | [post] v2 | webview.swift:119:10:119:10 | v2 | +| webview.swift:118:5:118:5 | v2 | webview.swift:119:10:119:10 | v2 | +| webview.swift:118:17:118:17 | s | webview.swift:118:5:118:5 | [post] v2 | +| webview.swift:118:17:118:17 | s | webview.swift:122:17:122:17 | s | +| webview.swift:121:9:121:9 | SSA def(v3) | webview.swift:122:5:122:5 | v3 | +| webview.swift:121:14:121:14 | JSValue.Type | webview.swift:121:14:121:14 | call to init(object:in:) | +| webview.swift:121:14:121:45 | call to init(object:in:) | webview.swift:121:9:121:9 | SSA def(v3) | +| webview.swift:121:30:121:30 | | webview.swift:121:14:121:45 | call to init(object:in:) | +| webview.swift:122:5:122:5 | [post] v3 | webview.swift:123:10:123:10 | v3 | +| webview.swift:122:5:122:5 | v3 | webview.swift:123:10:123:10 | v3 | +| webview.swift:122:17:122:17 | s | webview.swift:122:5:122:5 | [post] v3 | +| webview.swift:127:9:127:9 | SSA def(atStart) | webview.swift:128:56:128:56 | atStart | +| webview.swift:127:19:127:45 | .atDocumentStart | webview.swift:127:9:127:9 | SSA def(atStart) | +| webview.swift:128:9:128:9 | SSA def(a) | webview.swift:129:10:129:10 | a | +| webview.swift:128:13:128:13 | WKUserScript.Type | webview.swift:128:13:128:13 | call to init(source:injectionTime:forMainFrameOnly:) | +| webview.swift:128:13:128:88 | call to init(source:injectionTime:forMainFrameOnly:) | webview.swift:128:9:128:9 | SSA def(a) | +| webview.swift:128:34:128:34 | abc | webview.swift:128:13:128:88 | call to init(source:injectionTime:forMainFrameOnly:) | +| webview.swift:128:56:128:56 | [post] atStart | webview.swift:132:70:132:70 | atStart | +| webview.swift:128:56:128:56 | atStart | webview.swift:132:70:132:70 | atStart | +| webview.swift:129:10:129:10 | [post] a | webview.swift:130:10:130:10 | a | +| webview.swift:129:10:129:10 | a | webview.swift:130:10:130:10 | a | | webview.swift:130:10:130:10 | a | webview.swift:130:10:130:12 | .source | +| webview.swift:132:9:132:9 | SSA def(b) | webview.swift:133:10:133:10 | b | +| webview.swift:132:13:132:13 | WKUserScript.Type | webview.swift:132:13:132:13 | call to init(source:injectionTime:forMainFrameOnly:) | +| webview.swift:132:13:132:102 | call to init(source:injectionTime:forMainFrameOnly:) | webview.swift:132:9:132:9 | SSA def(b) | +| webview.swift:132:34:132:41 | call to source() | webview.swift:132:13:132:102 | call to init(source:injectionTime:forMainFrameOnly:) | +| webview.swift:132:70:132:70 | [post] atStart | webview.swift:137:70:137:70 | atStart | +| webview.swift:132:70:132:70 | atStart | webview.swift:137:70:137:70 | atStart | +| webview.swift:133:10:133:10 | [post] b | webview.swift:134:10:134:10 | b | +| webview.swift:133:10:133:10 | b | webview.swift:134:10:134:10 | b | | webview.swift:134:10:134:10 | b | webview.swift:134:10:134:12 | .source | +| webview.swift:136:9:136:9 | SSA def(world) | webview.swift:137:108:137:108 | world | +| webview.swift:136:17:136:32 | call to init() | webview.swift:136:9:136:9 | SSA def(world) | +| webview.swift:137:9:137:9 | SSA def(c) | webview.swift:138:10:138:10 | c | +| webview.swift:137:13:137:13 | WKUserScript.Type | webview.swift:137:13:137:13 | call to init(source:injectionTime:forMainFrameOnly:in:) | +| webview.swift:137:13:137:113 | call to init(source:injectionTime:forMainFrameOnly:in:) | webview.swift:137:9:137:9 | SSA def(c) | +| webview.swift:137:34:137:41 | call to source() | webview.swift:137:13:137:113 | call to init(source:injectionTime:forMainFrameOnly:in:) | +| webview.swift:138:10:138:10 | [post] c | webview.swift:139:10:139:10 | c | +| webview.swift:138:10:138:10 | c | webview.swift:139:10:139:10 | c | | webview.swift:139:10:139:10 | c | webview.swift:139:10:139:12 | .source | From 67e9841bf33b5a5791d063987245a920ebea88d4 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 29 Nov 2022 10:40:54 +0100 Subject: [PATCH 629/796] place the compilation cache in the temp dir --- .github/actions/cache-query-compilation/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/cache-query-compilation/action.yml b/.github/actions/cache-query-compilation/action.yml index 9f7569e5f0c..8cc496bb8fc 100644 --- a/.github/actions/cache-query-compilation/action.yml +++ b/.github/actions/cache-query-compilation/action.yml @@ -58,4 +58,4 @@ runs: echo "compdir=${COMBINED_CACHE_DIR}" >> $GITHUB_OUTPUT env: - COMBINED_CACHE_DIR: ${{ github.workspace }}/compilation-dir \ No newline at end of file + COMBINED_CACHE_DIR: ${{ runner.temp }}/compilation-dir \ No newline at end of file From 915d680fcc9bc4136189c56467d0700f96995a3d Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 29 Nov 2022 10:41:08 +0100 Subject: [PATCH 630/796] use a node script instead of bash to move the compilation cache --- .../cache-query-compilation/action.yml | 7 +- .../cache-query-compilation/move-caches.js | 80 +++++++++++++++++++ 2 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 .github/actions/cache-query-compilation/move-caches.js diff --git a/.github/actions/cache-query-compilation/action.yml b/.github/actions/cache-query-compilation/action.yml index 8cc496bb8fc..5a13191af3d 100644 --- a/.github/actions/cache-query-compilation/action.yml +++ b/.github/actions/cache-query-compilation/action.yml @@ -49,12 +49,7 @@ runs: shell: bash run: | # Move all the existing cache into another folder, so we only preserve the cache for the current queries. - mkdir -p ${COMBINED_CACHE_DIR} - rm -f **/.cache/{lock,size} # -f to avoid errors if the cache is empty. - # copy the contents of the .cache folders into the combined cache folder. - cp -r **/.cache/* ${COMBINED_CACHE_DIR}/ || : # ignore missing files - # clean up the .cache folders - rm -rf **/.cache/* + node $GITHUB_WORKSPACE/.github/actions/cache-query-compilation/move-caches.js ${COMBINED_CACHE_DIR} echo "compdir=${COMBINED_CACHE_DIR}" >> $GITHUB_OUTPUT env: diff --git a/.github/actions/cache-query-compilation/move-caches.js b/.github/actions/cache-query-compilation/move-caches.js new file mode 100644 index 00000000000..e86b1765cf7 --- /dev/null +++ b/.github/actions/cache-query-compilation/move-caches.js @@ -0,0 +1,80 @@ +// # Move all the existing cache into another folder, so we only preserve the cache for the current queries. +// mkdir -p ${COMBINED_CACHE_DIR} +// rm -f **/.cache/{lock,size} # -f to avoid errors if the cache is empty. +// # copy the contents of the .cache folders into the combined cache folder. +// cp -r **/.cache/* ${COMBINED_CACHE_DIR}/ || : # ignore missing files +// # clean up the .cache folders +// rm -rf **/.cache/* + +const fs = require("fs"); +const path = require("path"); + +// the first argv is the cache folder to create. +const COMBINED_CACHE_DIR = process.argv[2]; + +function* walkCaches(dir) { + const files = fs.readdirSync(dir); + for (const file of files) { + const filePath = path.join(dir, file); + if (!fs.existsSync(filePath)) { + continue; + } + const stat = fs.statSync(filePath); + if (stat.isDirectory()) { + yield* walkCaches(filePath); + if (file === ".cache") { + yield filePath; + } + } + } +} + +async function copyDir(src, dest) { + for await (const file of await fs.promises.readdir(src)) { + const srcPath = path.join(src, file); + const destPath = path.join(dest, file); + const stat = await fs.promises.stat(srcPath); + if (stat.isDirectory()) { + if (!fs.existsSync(destPath)) { + fs.mkdirSync(destPath); + } + await copyDir(srcPath, destPath); + } else { + await fs.promises.copyFile(srcPath, destPath); + } + } +} + +async function main() { + const cacheDirs = [...walkCaches(".")]; + + for (const dir of cacheDirs) { + console.log(`Found .cache dir at ${dir}`); + } + + // mkdir -p ${COMBINED_CACHE_DIR} + fs.mkdirSync(COMBINED_CACHE_DIR, { recursive: true }); + + // rm -f **/.cache/{lock,size} # -f to avoid errors if the cache is empty. + await Promise.all( + cacheDirs.map((cacheDir) => + (async function () { + await fs.promises.rm(path.join(cacheDir, "lock"), { force: true }); + await fs.promises.rm(path.join(cacheDir, "size"), { force: true }); + })() + ) + ); + + // # copy the contents of the .cache folders into the combined cache folder. + // cp -r **/.cache/* ${COMBINED_CACHE_DIR}/ || : # ignore missing files + await Promise.all( + cacheDirs.map((cacheDir) => copyDir(cacheDir, COMBINED_CACHE_DIR)) + ); + + // # clean up the .cache folders + // rm -rf **/.cache/* + await Promise.all( + cacheDirs.map((cacheDir) => fs.promises.rm(cacheDir, { recursive: true })) + ); +} +main(); From 58a87396ba12169b003d51fb24a47278a872cf58 Mon Sep 17 00:00:00 2001 From: Karim Ali Date: Wed, 9 Nov 2022 14:36:35 +0200 Subject: [PATCH 631/796] add taint steps for fields of String if a String is tainted, then all its fields (including those declared in extensions) should be tainted as well --- .../swift/frameworks/StandardLibrary/String.qll | 14 ++++++++++++++ .../test/library-tests/dataflow/taint/string.swift | 14 ++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll index 492dc314c17..14456885572 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll @@ -1,5 +1,7 @@ import swift +private import codeql.swift.dataflow.DataFlow private import codeql.swift.dataflow.ExternalFlow +private import codeql.swift.dataflow.FlowSteps private class StringSource extends SourceModelCsv { override predicate row(string row) { @@ -16,3 +18,15 @@ private class StringSource extends SourceModelCsv { ] } } + +/** + * A content implying that, if a `String` is tainted, then all its fields are tainted. + */ +private class StringFieldsInheritTaint extends TaintInheritingContent, + DataFlow::Content::FieldContent { + StringFieldsInheritTaint() { + this.getField().getEnclosingDecl().(ClassOrStructDecl).getFullName() = "String" or + this.getField().getEnclosingDecl().(ExtensionDecl).getExtendedTypeDecl().getFullName() = + "String" + } +} diff --git a/swift/ql/test/library-tests/dataflow/taint/string.swift b/swift/ql/test/library-tests/dataflow/taint/string.swift index 5b54a8dc444..5724be8d375 100644 --- a/swift/ql/test/library-tests/dataflow/taint/string.swift +++ b/swift/ql/test/library-tests/dataflow/taint/string.swift @@ -82,10 +82,10 @@ func taintThroughStringOperations() { sink(arg: String(repeating: tainted, count: 2)) // $ MISSING: tainted=74 sink(arg: clean.description) - sink(arg: tainted.description) // $ MISSING: tainted=74 + sink(arg: tainted.description) // $ tainted=74 sink(arg: clean.debugDescription) - sink(arg: tainted.debugDescription) // $ MISSING: tainted=74 + sink(arg: tainted.debugDescription) // $ tainted=74 } class Data @@ -111,3 +111,13 @@ func taintThroughData() { sink(arg: stringClean!) sink(arg: stringTainted!) // $ MISSING: tainted=100 } + +func sink(arg: String.UTF8View) {} + +func taintThroughStringFields() { + let clean = "" + let tainted = source2().utf8 + + sink(arg: clean) + sink(arg: tainted) // $ tainted=95 +} From 7541b01a86cfdd6c20a3443f0d06410ee1c50c41 Mon Sep 17 00:00:00 2001 From: Karim Ali Date: Wed, 9 Nov 2022 15:23:36 +0200 Subject: [PATCH 632/796] add test case for utf8CString --- swift/ql/test/library-tests/dataflow/taint/string.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/swift/ql/test/library-tests/dataflow/taint/string.swift b/swift/ql/test/library-tests/dataflow/taint/string.swift index 5724be8d375..cece90a0981 100644 --- a/swift/ql/test/library-tests/dataflow/taint/string.swift +++ b/swift/ql/test/library-tests/dataflow/taint/string.swift @@ -113,11 +113,14 @@ func taintThroughData() { } func sink(arg: String.UTF8View) {} +func sink(arg: ContiguousArray) {} func taintThroughStringFields() { let clean = "" let tainted = source2().utf8 + let taintedCString = source2().utf8CString sink(arg: clean) - sink(arg: tainted) // $ tainted=95 + sink(arg: tainted) // $ tainted=120 + sink(arg: taintedCString) // $ tainted=121 } From 9b3c4e8db25ea5bdebc56d48d9caa4adbfbfdd3e Mon Sep 17 00:00:00 2001 From: Karim Ali Date: Wed, 9 Nov 2022 15:49:27 +0200 Subject: [PATCH 633/796] add test case for unicodeScalars --- swift/ql/test/library-tests/dataflow/taint/string.swift | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/swift/ql/test/library-tests/dataflow/taint/string.swift b/swift/ql/test/library-tests/dataflow/taint/string.swift index cece90a0981..1186ffd8a6c 100644 --- a/swift/ql/test/library-tests/dataflow/taint/string.swift +++ b/swift/ql/test/library-tests/dataflow/taint/string.swift @@ -114,13 +114,16 @@ func taintThroughData() { func sink(arg: String.UTF8View) {} func sink(arg: ContiguousArray) {} +func sink(arg: String.UnicodeScalarView) {} func taintThroughStringFields() { let clean = "" let tainted = source2().utf8 let taintedCString = source2().utf8CString + let taintedUnicodeScalars = source2().unicodeScalars sink(arg: clean) - sink(arg: tainted) // $ tainted=120 - sink(arg: taintedCString) // $ tainted=121 + sink(arg: tainted) // $ tainted=121 + sink(arg: taintedCString) // $ tainted=122 + sink(arg: taintedUnicodeScalars) // $ tainted=123 } From f0d9dabca2fd2bb5708bd30c9db4aa5a3c7c8919 Mon Sep 17 00:00:00 2001 From: Karim Ali Date: Wed, 9 Nov 2022 16:34:46 +0200 Subject: [PATCH 634/796] updated expected output for LocalTaint and Tain --- .../dataflow/taint/LocalTaint.expected | 9 +++++++++ .../dataflow/taint/Taint.expected | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected index 9a5f74be04b..60dde1510ef 100644 --- a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected @@ -600,6 +600,8 @@ | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 | nsmutabledata.swift:49:15:49:37 | .mutableBytes | | string.swift:5:7:5:7 | SSA def(x) | string.swift:7:16:7:16 | x | | string.swift:5:11:5:18 | call to source() | string.swift:5:7:5:7 | SSA def(x) | +| data.swift:20:23:20:23 | 123456 | data.swift:20:23:20:32 | .utf8 | +| data.swift:21:25:21:32 | call to source() | data.swift:21:25:21:34 | .utf8 | | string.swift:7:13:7:13 | | string.swift:7:13:7:13 | [post] | | string.swift:7:13:7:13 | | string.swift:7:14:7:14 | [post] &... | | string.swift:7:13:7:13 | SSA def($interpolation) | string.swift:7:14:7:14 | SSA phi($interpolation) | @@ -932,6 +934,13 @@ | subscript.swift:3:9:3:9 | self | subscript.swift:3:9:3:9 | SSA def(self) | | subscript.swift:4:9:4:9 | SSA def(self) | subscript.swift:4:9:4:24 | self[return] | | subscript.swift:4:9:4:9 | self | subscript.swift:4:9:4:9 | SSA def(self) | +| string.swift:84:13:84:13 | clean | string.swift:84:13:84:19 | .description | +| string.swift:85:13:85:13 | tainted | string.swift:85:13:85:21 | .description | +| string.swift:87:13:87:13 | clean | string.swift:87:13:87:19 | .debugDescription | +| string.swift:88:13:88:13 | tainted | string.swift:88:13:88:21 | .debugDescription | +| string.swift:97:17:97:25 | call to source2() | string.swift:97:17:97:27 | .utf8 | +| string.swift:98:24:98:32 | call to source2() | string.swift:98:24:98:34 | .utf8CString | +| string.swift:99:31:99:39 | call to source2() | string.swift:99:31:99:41 | .unicodeScalars | | subscript.swift:13:15:13:22 | call to source() | subscript.swift:13:15:13:25 | ...[...] | | subscript.swift:14:15:14:23 | call to source2() | subscript.swift:14:15:14:26 | ...[...] | | try.swift:8:17:8:23 | call to clean() | try.swift:8:13:8:23 | try ... | diff --git a/swift/ql/test/library-tests/dataflow/taint/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/Taint.expected index b72d5905fd7..7404255629f 100644 --- a/swift/ql/test/library-tests/dataflow/taint/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/Taint.expected @@ -301,6 +301,11 @@ edges | string.swift:28:17:28:25 | call to source2() : | string.swift:35:13:35:23 | ... .+(_:_:) ... | | string.swift:28:17:28:25 | call to source2() : | string.swift:36:13:36:23 | ... .+(_:_:) ... | | string.swift:28:17:28:25 | call to source2() : | string.swift:39:13:39:29 | ... .+(_:_:) ... | +| string.swift:74:17:74:25 | call to source2() : | string.swift:85:13:85:21 | .description | +| string.swift:74:17:74:25 | call to source2() : | string.swift:88:13:88:21 | .debugDescription | +| string.swift:97:17:97:25 | call to source2() : | string.swift:102:13:102:13 | tainted | +| string.swift:98:24:98:32 | call to source2() : | string.swift:103:13:103:13 | taintedCString | +| string.swift:99:31:99:39 | call to source2() : | string.swift:104:13:104:13 | taintedUnicodeScalars | | subscript.swift:13:15:13:22 | call to source() : | subscript.swift:13:15:13:25 | ...[...] | | subscript.swift:14:15:14:23 | call to source2() : | subscript.swift:14:15:14:26 | ...[...] | | try.swift:9:17:9:24 | call to source() : | try.swift:9:13:9:24 | try ... | @@ -940,6 +945,15 @@ nodes | string.swift:35:13:35:23 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | | string.swift:36:13:36:23 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | | string.swift:39:13:39:29 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | +| string.swift:74:17:74:25 | call to source2() : | semmle.label | call to source2() : | +| string.swift:85:13:85:21 | .description | semmle.label | .description | +| string.swift:88:13:88:21 | .debugDescription | semmle.label | .debugDescription | +| string.swift:97:17:97:25 | call to source2() : | semmle.label | call to source2() : | +| string.swift:98:24:98:32 | call to source2() : | semmle.label | call to source2() : | +| string.swift:99:31:99:39 | call to source2() : | semmle.label | call to source2() : | +| string.swift:102:13:102:13 | tainted | semmle.label | tainted | +| string.swift:103:13:103:13 | taintedCString | semmle.label | taintedCString | +| string.swift:104:13:104:13 | taintedUnicodeScalars | semmle.label | taintedUnicodeScalars | | subscript.swift:13:15:13:22 | call to source() : | semmle.label | call to source() : | | subscript.swift:13:15:13:25 | ...[...] | semmle.label | ...[...] | | subscript.swift:14:15:14:23 | call to source2() : | semmle.label | call to source2() : | @@ -1340,6 +1354,11 @@ subpaths | string.swift:35:13:35:23 | ... .+(_:_:) ... | string.swift:28:17:28:25 | call to source2() : | string.swift:35:13:35:23 | ... .+(_:_:) ... | result | | string.swift:36:13:36:23 | ... .+(_:_:) ... | string.swift:28:17:28:25 | call to source2() : | string.swift:36:13:36:23 | ... .+(_:_:) ... | result | | string.swift:39:13:39:29 | ... .+(_:_:) ... | string.swift:28:17:28:25 | call to source2() : | string.swift:39:13:39:29 | ... .+(_:_:) ... | result | +| string.swift:85:13:85:21 | .description | string.swift:74:17:74:25 | call to source2() : | string.swift:85:13:85:21 | .description | result | +| string.swift:88:13:88:21 | .debugDescription | string.swift:74:17:74:25 | call to source2() : | string.swift:88:13:88:21 | .debugDescription | result | +| string.swift:102:13:102:13 | tainted | string.swift:97:17:97:25 | call to source2() : | string.swift:102:13:102:13 | tainted | result | +| string.swift:103:13:103:13 | taintedCString | string.swift:98:24:98:32 | call to source2() : | string.swift:103:13:103:13 | taintedCString | result | +| string.swift:104:13:104:13 | taintedUnicodeScalars | string.swift:99:31:99:39 | call to source2() : | string.swift:104:13:104:13 | taintedUnicodeScalars | result | | subscript.swift:13:15:13:25 | ...[...] | subscript.swift:13:15:13:22 | call to source() : | subscript.swift:13:15:13:25 | ...[...] | result | | subscript.swift:14:15:14:26 | ...[...] | subscript.swift:14:15:14:23 | call to source2() : | subscript.swift:14:15:14:26 | ...[...] | result | | try.swift:9:13:9:24 | try ... | try.swift:9:17:9:24 | call to source() : | try.swift:9:13:9:24 | try ... | result | From 9a25de3ef1d55f2bfdeb577f519402afcf545123 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 29 Nov 2022 11:17:08 +0100 Subject: [PATCH 635/796] Swift: revert `swift-actions/setup-swift` --- swift/actions/run-integration-tests/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/actions/run-integration-tests/action.yml b/swift/actions/run-integration-tests/action.yml index 00ef006ea09..6894ef461bc 100644 --- a/swift/actions/run-integration-tests/action.yml +++ b/swift/actions/run-integration-tests/action.yml @@ -13,7 +13,7 @@ runs: - uses: actions/setup-python@v4 with: python-version-file: 'swift/.python-version' - - uses: swift-actions/setup-swift@v1 + - uses: swift-actions/setup-swift@5cdaa9161ad1f55ae39a5ea1784ef96de72f95d9 with: swift-version: "${{steps.get_swift_version.outputs.version}}" - uses: ./.github/actions/fetch-codeql From c89c449a2c4061685f3e5019b8b200e9792c10ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Wed, 16 Nov 2022 14:06:02 +0100 Subject: [PATCH 636/796] Swift: silence cmake/vscode intellisense Problem i.e. "TrapLabel not found" --- swift/extractor/trap/TrapTagTraits.h | 1 + 1 file changed, 1 insertion(+) diff --git a/swift/extractor/trap/TrapTagTraits.h b/swift/extractor/trap/TrapTagTraits.h index f0f8c41cc8d..565f7f20892 100644 --- a/swift/extractor/trap/TrapTagTraits.h +++ b/swift/extractor/trap/TrapTagTraits.h @@ -4,6 +4,7 @@ // label tags #include +#include "swift/extractor/trap/TrapLabel.h" namespace codeql { From 36e7235493b6e605215b780b82f680dc35b9b8e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Mon, 28 Nov 2022 19:29:30 +0100 Subject: [PATCH 637/796] Swift: fix `-Wmissing-braces` warning in extractor By initializing va_list the standard way, i.e. leaving it uninitialized until va_start(). --- swift/extractor/remapping/SwiftOpenInterception.macOS.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/extractor/remapping/SwiftOpenInterception.macOS.cpp b/swift/extractor/remapping/SwiftOpenInterception.macOS.cpp index 0ac23d14cbc..d378a571e58 100644 --- a/swift/extractor/remapping/SwiftOpenInterception.macOS.cpp +++ b/swift/extractor/remapping/SwiftOpenInterception.macOS.cpp @@ -27,7 +27,7 @@ static std::string originalHashFile(const fs::path& filename) { } static int codeql_open(const char* path, int oflag, ...) { - va_list ap = {0}; + va_list ap; mode_t mode = 0; if ((oflag & O_CREAT) != 0) { // mode only applies to O_CREAT From 931173350f8ca9f77c1887d7601bd5560408a6c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Mon, 28 Nov 2022 13:15:10 +0100 Subject: [PATCH 638/796] Swift: extract missing cases of AccessorKind and AccessSemantics This resolves the warnings that were showing up during extractor-pack compilation. --- .../extractor/translators/DeclTranslator.cpp | 12 +++++ .../extractor/translators/ExprTranslator.cpp | 3 ++ swift/ql/lib/codeql/swift/generated/Raw.qll | 18 +++++++ .../swift/generated/decl/AccessorDecl.qll | 24 +++++++++ .../swift/generated/expr/DeclRefExpr.qll | 7 +++ .../swift/generated/expr/MemberRefExpr.qll | 7 +++ .../swift/generated/expr/SubscriptExpr.qll | 7 +++ swift/ql/lib/swift.dbscheme | 35 ++++++++++++ .../decl/AccessorDecl/AccessorDecl.expected | 54 +++++++++---------- .../decl/AccessorDecl/AccessorDecl.ql | 15 ++++-- swift/schema.py | 7 +++ 11 files changed, 159 insertions(+), 30 deletions(-) diff --git a/swift/extractor/translators/DeclTranslator.cpp b/swift/extractor/translators/DeclTranslator.cpp index 2482499a32c..09927cad47b 100644 --- a/swift/extractor/translators/DeclTranslator.cpp +++ b/swift/extractor/translators/DeclTranslator.cpp @@ -231,6 +231,18 @@ std::optional DeclTranslator::translateAccessorDecl( case swift::AccessorKind::DidSet: entry->is_did_set = true; break; + case swift::AccessorKind::Read: + entry->is_read = true; + break; + case swift::AccessorKind::Modify: + entry->is_modify = true; + break; + case swift::AccessorKind::Address: + entry->is_unsafe_address = true; + break; + case swift::AccessorKind::MutableAddress: + entry->is_unsafe_mutable_address = true; + break; } fillAbstractFunctionDecl(decl, *entry); return entry; diff --git a/swift/extractor/translators/ExprTranslator.cpp b/swift/extractor/translators/ExprTranslator.cpp index f51839d623e..fa521269e86 100644 --- a/swift/extractor/translators/ExprTranslator.cpp +++ b/swift/extractor/translators/ExprTranslator.cpp @@ -16,6 +16,9 @@ void ExprTranslator::fillAccessorSemantics(const T& ast, TrapClassOf& entry) case swift::AccessSemantics::Ordinary: entry.has_ordinary_semantics = true; break; + case swift::AccessSemantics::DistributedThunk: + entry.has_distributed_thunk_semantics = true; + break; } } diff --git a/swift/ql/lib/codeql/swift/generated/Raw.qll b/swift/ql/lib/codeql/swift/generated/Raw.qll index a34018bc3b9..a15be0be546 100644 --- a/swift/ql/lib/codeql/swift/generated/Raw.qll +++ b/swift/ql/lib/codeql/swift/generated/Raw.qll @@ -261,6 +261,14 @@ module Raw { predicate isWillSet() { accessor_decl_is_will_set(this) } predicate isDidSet() { accessor_decl_is_did_set(this) } + + predicate isRead() { accessor_decl_is_read(this) } + + predicate isModify() { accessor_decl_is_modify(this) } + + predicate isUnsafeAddress() { accessor_decl_is_unsafe_address(this) } + + predicate isUnsafeMutableAddress() { accessor_decl_is_unsafe_mutable_address(this) } } class AssociatedTypeDecl extends @associated_type_decl, AbstractTypeParamDecl { @@ -403,6 +411,8 @@ module Raw { } predicate hasOrdinarySemantics() { decl_ref_expr_has_ordinary_semantics(this) } + + predicate hasDistributedThunkSemantics() { decl_ref_expr_has_distributed_thunk_semantics(this) } } class DefaultArgumentExpr extends @default_argument_expr, Expr { @@ -851,6 +861,10 @@ module Raw { } predicate hasOrdinarySemantics() { member_ref_expr_has_ordinary_semantics(this) } + + predicate hasDistributedThunkSemantics() { + member_ref_expr_has_distributed_thunk_semantics(this) + } } class MetatypeConversionExpr extends @metatype_conversion_expr, ImplicitConversionExpr { @@ -918,6 +932,10 @@ module Raw { } predicate hasOrdinarySemantics() { subscript_expr_has_ordinary_semantics(this) } + + predicate hasDistributedThunkSemantics() { + subscript_expr_has_distributed_thunk_semantics(this) + } } class TryExpr extends @try_expr, AnyTryExpr { diff --git a/swift/ql/lib/codeql/swift/generated/decl/AccessorDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/AccessorDecl.qll index 8b0a8f7582a..6616023d814 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/AccessorDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/AccessorDecl.qll @@ -26,5 +26,29 @@ module Generated { * Holds if this accessor is a `didSet`, called after the property is set. */ predicate isDidSet() { Synth::convertAccessorDeclToRaw(this).(Raw::AccessorDecl).isDidSet() } + + /** + * Holds if this accessor is a `_read` coroutine, yielding a borrowed value of the property. + */ + predicate isRead() { Synth::convertAccessorDeclToRaw(this).(Raw::AccessorDecl).isRead() } + + /** + * Holds if this accessor is a `_modify` coroutine, yielding an inout value of the property. + */ + predicate isModify() { Synth::convertAccessorDeclToRaw(this).(Raw::AccessorDecl).isModify() } + + /** + * Holds if this accessor is an `unsafeAddress` immutable addressor. + */ + predicate isUnsafeAddress() { + Synth::convertAccessorDeclToRaw(this).(Raw::AccessorDecl).isUnsafeAddress() + } + + /** + * Holds if this accessor is an `unsafeMutableAddress` mutable addressor. + */ + predicate isUnsafeMutableAddress() { + Synth::convertAccessorDeclToRaw(this).(Raw::AccessorDecl).isUnsafeMutableAddress() + } } } diff --git a/swift/ql/lib/codeql/swift/generated/expr/DeclRefExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/DeclRefExpr.qll index bb83df6d35c..cb95cd82a27 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/DeclRefExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/DeclRefExpr.qll @@ -75,5 +75,12 @@ module Generated { predicate hasOrdinarySemantics() { Synth::convertDeclRefExprToRaw(this).(Raw::DeclRefExpr).hasOrdinarySemantics() } + + /** + * Holds if this declaration ref expression has distributed thunk semantics. + */ + predicate hasDistributedThunkSemantics() { + Synth::convertDeclRefExprToRaw(this).(Raw::DeclRefExpr).hasDistributedThunkSemantics() + } } } diff --git a/swift/ql/lib/codeql/swift/generated/expr/MemberRefExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/MemberRefExpr.qll index ed91bd4a98c..4f12da0b1fa 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/MemberRefExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/MemberRefExpr.qll @@ -29,5 +29,12 @@ module Generated { predicate hasOrdinarySemantics() { Synth::convertMemberRefExprToRaw(this).(Raw::MemberRefExpr).hasOrdinarySemantics() } + + /** + * Holds if this member ref expression has distributed thunk semantics. + */ + predicate hasDistributedThunkSemantics() { + Synth::convertMemberRefExprToRaw(this).(Raw::MemberRefExpr).hasDistributedThunkSemantics() + } } } diff --git a/swift/ql/lib/codeql/swift/generated/expr/SubscriptExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/SubscriptExpr.qll index c75de17d112..456fda265f0 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/SubscriptExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/SubscriptExpr.qll @@ -58,5 +58,12 @@ module Generated { predicate hasOrdinarySemantics() { Synth::convertSubscriptExprToRaw(this).(Raw::SubscriptExpr).hasOrdinarySemantics() } + + /** + * Holds if this subscript expression has distributed thunk semantics. + */ + predicate hasDistributedThunkSemantics() { + Synth::convertSubscriptExprToRaw(this).(Raw::SubscriptExpr).hasDistributedThunkSemantics() + } } } diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index abbb8c9e840..1a6e9325bd6 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -524,6 +524,26 @@ accessor_decl_is_did_set( //dir=decl int id: @accessor_decl ref ); +#keyset[id] +accessor_decl_is_read( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_modify( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_address( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_mutable_address( //dir=decl + int id: @accessor_decl ref +); + associated_type_decls( //dir=decl unique int id: @associated_type_decl ); @@ -771,6 +791,11 @@ decl_ref_expr_has_ordinary_semantics( //dir=expr int id: @decl_ref_expr ref ); +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + default_argument_exprs( //dir=expr unique int id: @default_argument_expr, int param_decl: @param_decl_or_none ref, @@ -1319,6 +1344,11 @@ member_ref_expr_has_ordinary_semantics( //dir=expr int id: @member_ref_expr ref ); +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + metatype_conversion_exprs( //dir=expr unique int id: @metatype_conversion_expr ); @@ -1408,6 +1438,11 @@ subscript_expr_has_ordinary_semantics( //dir=expr int id: @subscript_expr ref ); +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + try_exprs( //dir=expr unique int id: @try_expr ); diff --git a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.expected b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.expected index 024e88a36b3..9927e4ef93b 100644 --- a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.expected +++ b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.expected @@ -1,27 +1,27 @@ -| accessors.swift:2:9:2:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | -| accessors.swift:2:9:2:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | -| accessors.swift:2:9:2:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | -| accessors.swift:3:9:3:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | -| accessors.swift:4:9:4:28 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | -| accessors.swift:5:9:5:42 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | -| accessors.swift:7:9:7:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | -| accessors.swift:7:9:7:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | -| accessors.swift:7:9:7:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | -| accessors.swift:8:9:8:29 | willSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | yes | isDidSet: | no | -| accessors.swift:11:9:11:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | -| accessors.swift:11:9:11:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | -| accessors.swift:11:9:11:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | -| accessors.swift:12:9:12:19 | willSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | yes | isDidSet: | no | -| accessors.swift:15:9:15:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | -| accessors.swift:15:9:15:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | -| accessors.swift:15:9:15:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | -| accessors.swift:16:9:16:28 | didSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | yes | -| accessors.swift:19:9:19:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | -| accessors.swift:19:9:19:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | -| accessors.swift:19:9:19:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | -| accessors.swift:20:9:20:18 | didSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | yes | -| accessors.swift:23:9:23:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | -| accessors.swift:23:9:23:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | -| accessors.swift:23:9:23:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | -| accessors.swift:24:9:24:19 | willSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | yes | isDidSet: | no | -| accessors.swift:26:9:26:18 | didSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | yes | +| accessors.swift:2:9:2:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:2:9:2:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:2:9:2:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:3:9:3:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:4:9:4:28 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:5:9:5:42 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:7:9:7:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:7:9:7:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:7:9:7:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:8:9:8:29 | willSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | yes | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:11:9:11:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:11:9:11:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:11:9:11:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:12:9:12:19 | willSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | yes | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:15:9:15:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:15:9:15:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:15:9:15:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:16:9:16:28 | didSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | yes | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:19:9:19:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:19:9:19:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:19:9:19:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:20:9:20:18 | didSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | yes | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:23:9:23:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:23:9:23:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:23:9:23:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:24:9:24:19 | willSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | yes | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:26:9:26:18 | didSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | yes | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | diff --git a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.ql b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.ql index 4488c81f510..5fdb7d55297 100644 --- a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.ql +++ b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.ql @@ -4,7 +4,8 @@ import TestUtils from AccessorDecl x, ModuleDecl getModule, Type getInterfaceType, string getName, string isGetter, - string isSetter, string isWillSet, string isDidSet + string isSetter, string isWillSet, string isDidSet, string isRead, string isModify, + string isUnsafeAddress, string isUnsafeMutableAddress where toBeTested(x) and not x.isUnknown() and @@ -14,6 +15,14 @@ where (if x.isGetter() then isGetter = "yes" else isGetter = "no") and (if x.isSetter() then isSetter = "yes" else isSetter = "no") and (if x.isWillSet() then isWillSet = "yes" else isWillSet = "no") and - if x.isDidSet() then isDidSet = "yes" else isDidSet = "no" + (if x.isDidSet() then isDidSet = "yes" else isDidSet = "no") and + (if x.isRead() then isRead = "yes" else isRead = "no") and + (if x.isModify() then isModify = "yes" else isModify = "no") and + (if x.isUnsafeAddress() then isUnsafeAddress = "yes" else isUnsafeAddress = "no") and + if x.isUnsafeMutableAddress() + then isUnsafeMutableAddress = "yes" + else isUnsafeMutableAddress = "no" select x, "getModule:", getModule, "getInterfaceType:", getInterfaceType, "getName:", getName, - "isGetter:", isGetter, "isSetter:", isSetter, "isWillSet:", isWillSet, "isDidSet:", isDidSet + "isGetter:", isGetter, "isSetter:", isSetter, "isWillSet:", isWillSet, "isDidSet:", isDidSet, + "isRead:", isRead, "isModify:", isModify, "isUnsafeAddress:", isUnsafeAddress, + "isUnsafeMutableAddress:", isUnsafeMutableAddress diff --git a/swift/schema.py b/swift/schema.py index e9e8746d0c3..3162c1277e0 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -232,6 +232,10 @@ class AccessorDecl(FuncDecl): is_setter: predicate | doc('this accessor is a setter') is_will_set: predicate | doc('this accessor is a `willSet`, called before the property is set') is_did_set: predicate | doc('this accessor is a `didSet`, called after the property is set') + is_read: predicate | doc('this accessor is a `_read` coroutine, yielding a borrowed value of the property') + is_modify: predicate | doc('this accessor is a `_modify` coroutine, yielding an inout value of the property') + is_unsafe_address: predicate | doc('this accessor is an `unsafeAddress` immutable addressor') + is_unsafe_mutable_address: predicate | doc('this accessor is an `unsafeMutableAddress` mutable addressor') class AssociatedTypeDecl(AbstractTypeParamDecl): pass @@ -322,6 +326,7 @@ class DeclRefExpr(Expr): has_direct_to_storage_semantics: predicate has_direct_to_implementation_semantics: predicate has_ordinary_semantics: predicate + has_distributed_thunk_semantics: predicate class DefaultArgumentExpr(Expr): param_decl: ParamDecl @@ -589,6 +594,7 @@ class MemberRefExpr(LookupExpr): has_direct_to_storage_semantics: predicate has_direct_to_implementation_semantics: predicate has_ordinary_semantics: predicate + has_distributed_thunk_semantics: predicate class MetatypeConversionExpr(ImplicitConversionExpr): pass @@ -642,6 +648,7 @@ class SubscriptExpr(LookupExpr): has_direct_to_storage_semantics: predicate has_direct_to_implementation_semantics: predicate has_ordinary_semantics: predicate + has_distributed_thunk_semantics: predicate class TryExpr(AnyTryExpr): pass From 13bbee73d864c51037b58947c673eab152297220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Mon, 28 Nov 2022 19:05:13 +0100 Subject: [PATCH 639/796] Swift: Add .generated.list file from codegen --- swift/ql/.generated.list | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index a62640aace8..a40adbaa5fa 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -380,9 +380,9 @@ ql/lib/codeql/swift/generated/ErrorElement.qll 4b032abe8ffb71376a29c63e470a52943 ql/lib/codeql/swift/generated/File.qll 61454459f5f1ae378bd4970ad1da4f39f3e696bac8a5eebdd162f131995c5316 3e6805f8858cd55dd0e0d0e5aeab923d6a55292dbf98b0029db1ae0208efe684 ql/lib/codeql/swift/generated/Locatable.qll bdc98b9fb7788f44a4bf7e487ee5bd329473409950a8e9f116d61995615ad849 0b36b4fe45e2aa195e4bb70c50ea95f32f141b8e01e5f23466c6427dd9ab88fb ql/lib/codeql/swift/generated/Location.qll 851766e474cdfdfa67da42e0031fc42dd60196ff5edd39d82f08d3e32deb84c1 b29b2c37672f5acff15f1d3c5727d902f193e51122327b31bd27ec5f877bca3b -ql/lib/codeql/swift/generated/ParentChild.qll 9d6fe5dd7ab99fa9afdc1bd846e21ce951613bbe6a89d4e34c29e36466a8293f e0e59a05018e4b59ebda3a9fdc3435b1c82207b915630d55edbe6d3f92488356 +ql/lib/codeql/swift/generated/ParentChild.qll d9c1edbbb28e685d31153c3a17419e80fd106cb580ef8440e25a8709e7f4c021 e0e59a05018e4b59ebda3a9fdc3435b1c82207b915630d55edbe6d3f92488356 ql/lib/codeql/swift/generated/PureSynthConstructors.qll 1cd47d61fec37e019ce2e476603eb2273775bea81062d6bf3d6bbc49796f7b77 1cd47d61fec37e019ce2e476603eb2273775bea81062d6bf3d6bbc49796f7b77 -ql/lib/codeql/swift/generated/Raw.qll 34ce12e57d0cfffb8ca127e44041fece4ac6079cb2a80d14e0a05c0a8d344fdd dd7b6f54f2cc4ba1d8ed31168f97e3f6f8197ebb4d759e0bed0ed68d55a43c25 +ql/lib/codeql/swift/generated/Raw.qll 74159a7425c2da672d72e71655d27af3479b0acc23d871eafcee7d044d013550 0a6e8a85fbfd7262c983b6a6fedabbe9f11648edbcc52cba5828b97fe18fbd02 ql/lib/codeql/swift/generated/Synth.qll 90df85be365c89c3c2e22041ee7dc9dd2ad9194b66f82e8f9d8fefb8afd900ec 1632984f7a55f6bc55adb9f647baf634b002c299655cbf641dfb110525291689 ql/lib/codeql/swift/generated/SynthConstructors.qll 5c91f09bd82728651ed61f498704e0f62847788fa986dec5e674d81f294076c7 5c91f09bd82728651ed61f498704e0f62847788fa986dec5e674d81f294076c7 ql/lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 @@ -391,7 +391,7 @@ ql/lib/codeql/swift/generated/UnspecifiedElement.qll dbc6ca4018012977b26ca184a88 ql/lib/codeql/swift/generated/decl/AbstractFunctionDecl.qll 8255b24dddda83e8a7dee9d69a4cf9883b5a7ae43676d7242b5aab5169f68982 407c7d63681fb03ad6cb4ea3c2b04be7ccb5ddbe655a8aec4219eb3799bc36e8 ql/lib/codeql/swift/generated/decl/AbstractStorageDecl.qll 66147ad36cefce974b4ae0f3e84569bd6742ea2f3e842c3c04e6e5cbd17e7928 ce7c2347e2dfe0b141db103ccb8e56a61d286476c201aebe6a275edd7fca2c0f ql/lib/codeql/swift/generated/decl/AbstractTypeParamDecl.qll 1e268b00d0f2dbbd85aa70ac206c5e4a4612f06ba0091e5253483635f486ccf9 5479e13e99f68f1f347283535f8098964f7fd4a34326ff36ad5711b2de1ab0d0 -ql/lib/codeql/swift/generated/decl/AccessorDecl.qll 97773751c95475efd78ee5cb0c71e3094b13bba121b564c99934659d1908dca2 25c97d7586379558ff8f7cea4d4fcf7633256029fe3e560964353c3b90497076 +ql/lib/codeql/swift/generated/decl/AccessorDecl.qll 443cb9888dbdbaee680bf24469ce097a8292806dc53f0b109d492db621fa00aa 0dbe38cbbd3f3cd880c1569d9d42165e7cf0358da0cc7cb63e89890310ad40a0 ql/lib/codeql/swift/generated/decl/AssociatedTypeDecl.qll 4169d083104f9c089223ed3c5968f757b8cd6c726887bbb6fbaf21f5ed7ee144 4169d083104f9c089223ed3c5968f757b8cd6c726887bbb6fbaf21f5ed7ee144 ql/lib/codeql/swift/generated/decl/ClassDecl.qll a60e8af2fdbcd20cfa2049660c8bcbbc00508fbd3dde72b4778317dfc23c5ae4 a60e8af2fdbcd20cfa2049660c8bcbbc00508fbd3dde72b4778317dfc23c5ae4 ql/lib/codeql/swift/generated/decl/ConcreteFuncDecl.qll c7192e79ce67f77df36575cceb942f11b182c26c93899469654316de2d543cf9 c7192e79ce67f77df36575cceb942f11b182c26c93899469654316de2d543cf9 @@ -461,7 +461,7 @@ ql/lib/codeql/swift/generated/expr/ConditionalCheckedCastExpr.qll 92a999dd1dcc1f ql/lib/codeql/swift/generated/expr/ConstructorRefCallExpr.qll d0662d960b78c3cf7e81cf5b619aa9e2a906d35c094ae32702da96720354fe4f d0662d960b78c3cf7e81cf5b619aa9e2a906d35c094ae32702da96720354fe4f ql/lib/codeql/swift/generated/expr/CovariantFunctionConversionExpr.qll b749118590163eafbd538e71e4c903668451f52ae0dabbb13e504e7b1fefa9e1 d3af8e3beb6e395f537348d875978dfae119243dc3495c48a7c83b056aff2f6c ql/lib/codeql/swift/generated/expr/CovariantReturnConversionExpr.qll f1b409f0bf54b149deb1a40fbe337579a0f6eb2498ef176ef5f64bc53e94e2fe a32992597057657c7bbf13c809db67844b834668e8d2804adabcf6187d81c244 -ql/lib/codeql/swift/generated/expr/DeclRefExpr.qll c68a39ef4445d6c865976fe9f6013bbe77dca68a23d188f1fac3a8492eac70a6 92ae3f39d0e9e1d5017bd660c940225ad2cb07ef9076608dc1bca844adb5d6f0 +ql/lib/codeql/swift/generated/expr/DeclRefExpr.qll 441f0cba088ce3845a0d55500cccc94947da440d9f4ce879aed3e5bf5471d48e d54b4d0ca11d85a403fa470407e915472cd51116a633499bdfb293ac5f4a3b77 ql/lib/codeql/swift/generated/expr/DefaultArgumentExpr.qll b38015d25ef840298a284b3f4e20cd444987474545544dc451dd5e12c3783f20 afc581e2127983faae125fd58b24d346bfee34d9a474e6d499e4606b672fe5f0 ql/lib/codeql/swift/generated/expr/DerivedToBaseExpr.qll 5f371b5b82262efb416af1a54073079dcf857f7a744010294f79a631c76c0e68 5f371b5b82262efb416af1a54073079dcf857f7a744010294f79a631c76c0e68 ql/lib/codeql/swift/generated/expr/DestructureTupleExpr.qll 1214d25d0fa6a7c2f183d9b12c97c679e9b92420ca1970d802ea1fe84b42ccc8 1214d25d0fa6a7c2f183d9b12c97c679e9b92420ca1970d802ea1fe84b42ccc8 @@ -509,7 +509,7 @@ ql/lib/codeql/swift/generated/expr/LoadExpr.qll 90b9ba4c96c26c476c3692b1200c3107 ql/lib/codeql/swift/generated/expr/LookupExpr.qll 4b8c4f710e3cbdeb684a07c105f48915782e5de002da87f693ae1e07f3b67031 eceb13729282b77a44317c39f9206d9c1467bc93633b7bac5ada97ea13a773fe ql/lib/codeql/swift/generated/expr/MagicIdentifierLiteralExpr.qll 16f0050128caf916506b1f7372dc225a12809a60b5b00f108705fcdfce3344a8 c064778526a5854bdf8cdbf4b64ad680b60df9fe71ec7a2d9aa6c36a7c4e5b31 ql/lib/codeql/swift/generated/expr/MakeTemporarilyEscapableExpr.qll d23bd9ea3b13869d7a7f7eef3c3d1c3c156d384b72c65867a0b955bc517da775 f2fd167ac40f01c092b2b443af1557c92dac32074506f2195d32f60b0e0547d8 -ql/lib/codeql/swift/generated/expr/MemberRefExpr.qll 07000a05bec2e6d18e89ec4bbdba41a149691c50527da9073630d4193c0248d8 1bd43b79231aa31e0d60f9f7104f2b889fc3d9f042ecba8fe09d2cd289f4381d +ql/lib/codeql/swift/generated/expr/MemberRefExpr.qll 0ece9ffbfd4b15722aa3870014a46afdbf1b1382972fb366d741fafb5473e3de fcb57bd65a94ed4214730339c4ed2b167ec22a3dc9017399596f9b26bdeb95cd ql/lib/codeql/swift/generated/expr/MetatypeConversionExpr.qll 714ecbc8ac51fdaaa4075388f20fe5063ead9264ca20c4ab8864c48364ef4b42 714ecbc8ac51fdaaa4075388f20fe5063ead9264ca20c4ab8864c48364ef4b42 ql/lib/codeql/swift/generated/expr/MethodRefExpr.qll 014f976ce55cfc07a18a86c379fcf12c68f3c300c2d5e730731e61bfa50c6419 014f976ce55cfc07a18a86c379fcf12c68f3c300c2d5e730731e61bfa50c6419 ql/lib/codeql/swift/generated/expr/NilLiteralExpr.qll 6f44106bc5396c87681676fc3e1239fe052d1a481d0a854afa8b66369668b058 6f44106bc5396c87681676fc3e1239fe052d1a481d0a854afa8b66369668b058 @@ -535,7 +535,7 @@ ql/lib/codeql/swift/generated/expr/SelfApplyExpr.qll c676c551bcb528512dad6422cce ql/lib/codeql/swift/generated/expr/SequenceExpr.qll 044581c933d44ecf153a22724985d0c9d3b1bb0ca2614ba60db962ee126a293a 3ae93804ece0fa386099be2344dc7cb8b5d8091ce53980a265973c0faacad1c7 ql/lib/codeql/swift/generated/expr/StringLiteralExpr.qll f420c5cd51a223b6f98177147967266e0094a5718ba2d57ae2d3acbb64bbb4b6 30d6dab2a93fd95e652a700902c4d106fecfce13880c2ece565de29f2504bedf ql/lib/codeql/swift/generated/expr/StringToPointerExpr.qll ef69b570aa90697d438f5787a86797955b4b2f985960b5859a7bd13b9ecb9cd3 ef69b570aa90697d438f5787a86797955b4b2f985960b5859a7bd13b9ecb9cd3 -ql/lib/codeql/swift/generated/expr/SubscriptExpr.qll f207679b6a8387fe71eb7ce13061bc4ca8af62ccec92d062b8d67fb2ea0f0d10 ba7ed5c7105f2297ff15e0b07dce96b731da1249c9319bddb723d6898254c5f7 +ql/lib/codeql/swift/generated/expr/SubscriptExpr.qll 68523f3704985400e879903c365ece3910742a7d97368f6b3466efb25a23bd0f 3b5ea472a03958b6705d00041b4b354a6e691418c9d526bc70553b9b82698cda ql/lib/codeql/swift/generated/expr/SuperRefExpr.qll 3cc44a550ecab7d11b591082a3ad1ac88207d55cd694942ce44a90c576517482 d1712eed916f83d3e1b21c6af944ef56df2b82d163b9b3cb8dc793d48305fa6c ql/lib/codeql/swift/generated/expr/TapExpr.qll 0a2cbaaec596fa5aabb7acc3cab23bbf1bb1173ea4f240634698d5a89686d014 2267243198f67bb879d639f566e9729cfa9e3a3e205ffe6ff3782b7017a8bf7f ql/lib/codeql/swift/generated/expr/TryExpr.qll e6619905d9b2e06708c3bf41dace8c4e6332903f7111b3a59609d2bb7a6483ee e6619905d9b2e06708c3bf41dace8c4e6332903f7111b3a59609d2bb7a6483ee @@ -656,7 +656,7 @@ ql/lib/codeql/swift/generated/type/WeakStorageType.qll dda4397a49f537ec44117a86d ql/test/extractor-tests/generated/Comment/MISSING_SOURCE.txt 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd 7e714762ffb48c436102027d560fb5addc1f7dc6dd6936b06e0d3cca031d67fd ql/test/extractor-tests/generated/Diagnostics/Diagnostics.ql 6a4a9480cc929381e0337b181e5ac519a7abc6d597ebe24fb6701acf79ced86f 199c5bf8bd38e161d989e0e4db1ea1d3ddcb4d7cf571afd9112ce3ed8d9b8d2a ql/test/extractor-tests/generated/File/File.ql ab0968ae31b749da2b66462bd04e4dfb30604dba405a84594b575abfc4fa4c35 bcc0ff648b28c5ecd567e196e700272883756bbcc65296bbb880a979e3162628 -ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.ql f378065da46252a3fb7f960731645ad0d69639907bcbe4a5922c416a0c8efcf9 e80e09a2bb54c397f101aaa4c820c94a6d7df819dd746437e74325a8243405e0 +ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.ql 45a730bb247735161aa2b04f35d4e815c22a64cffd0ff8f7b1a03ab3a50dafb1 edb1031d59cbde8aa4961a985ce3ba2281f20463f805e154728487d76f826ced ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getBody.ql 1d42eb1a5b832cfaf1949b61a01a6a11448a6d4369a44f2511bb31d1d7fc10a8 b326a6743121353f8a66410d3d9151ca969939abcbbe5c411872ca290da45123 ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getGenericTypeParam.ql 8648679e9403477c7f97b6df450a0fa623dc9aff0777021ee33f9cc96eef2611 59c384c35804bf205c3c63e8b956e6bc89d3ded7952911c40e7bf156acb56bf8 ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getParam.ql 7c61c15d75f681c5f5817bdc1e0c1e2594afdc43a5a8889bd385b6cd007d6509 7f6111069c3f289fb3bd21933893757a0adbf8be8f21bf5f8960b6fb26840219 From 93cce0f4c28566b46cf005d5890c86d17606ff4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Mon, 28 Nov 2022 19:25:17 +0100 Subject: [PATCH 640/796] Swift: upgrade script --- .../old.dbscheme | 2513 +++++++++++++++++ .../swift.dbscheme | 2478 ++++++++++++++++ .../upgrade.properties | 9 + .../old.dbscheme | 2478 ++++++++++++++++ .../swift.dbscheme | 2513 +++++++++++++++++ .../upgrade.properties | 2 + 6 files changed, 9993 insertions(+) create mode 100644 swift/downgrades/1a6e9325bd60462e669e524438174deef4476df0/old.dbscheme create mode 100644 swift/downgrades/1a6e9325bd60462e669e524438174deef4476df0/swift.dbscheme create mode 100644 swift/downgrades/1a6e9325bd60462e669e524438174deef4476df0/upgrade.properties create mode 100644 swift/ql/lib/upgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/old.dbscheme create mode 100644 swift/ql/lib/upgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/swift.dbscheme create mode 100644 swift/ql/lib/upgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/upgrade.properties diff --git a/swift/downgrades/1a6e9325bd60462e669e524438174deef4476df0/old.dbscheme b/swift/downgrades/1a6e9325bd60462e669e524438174deef4476df0/old.dbscheme new file mode 100644 index 00000000000..1a6e9325bd6 --- /dev/null +++ b/swift/downgrades/1a6e9325bd60462e669e524438174deef4476df0/old.dbscheme @@ -0,0 +1,2513 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @iterable_decl_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @case_label_item +| @condition_element +| @decl +| @expr +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +@decl = + @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +@generic_context = + @abstract_function_decl +| @extension_decl +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +@iterable_decl_context = + @extension_decl +| @nominal_type_decl +; + +#keyset[id, index] +iterable_decl_context_members( //dir=decl + int id: @iterable_decl_context ref, + int index: int ref, + int member: @decl_or_none ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_function_decl +| @abstract_storage_decl +| @enum_element_decl +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_function_decl = + @constructor_decl +| @destructor_decl +| @func_decl +; + +#keyset[id] +abstract_function_decls( //dir=decl + int id: @abstract_function_decl ref, + string name: string ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessor_decls( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor_decl: @accessor_decl_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +constructor_decls( //dir=decl + unique int id: @constructor_decl +); + +destructor_decls( //dir=decl + unique int id: @destructor_decl +); + +@func_decl = + @accessor_decl +| @concrete_func_decl +; + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id, index] +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessor_decls( //dir=decl + unique int id: @accessor_decl +); + +#keyset[id] +accessor_decl_is_getter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_setter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_will_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_did_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_read( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_modify( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_address( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_mutable_address( //dir=decl + int id: @accessor_decl ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_func_decls( //dir=decl + unique int id: @concrete_func_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @abstract_closure_expr +| @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initializer_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_constructor_decl_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_constructor_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@abstract_closure_expr = + @auto_closure_expr +| @closure_expr +; + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id] +key_path_expr_parsed_paths( //dir=expr + int id: @key_path_expr ref, + int parsed_path: @expr_or_none ref +); + +lazy_initializer_exprs( //dir=expr + unique int id: @lazy_initializer_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @abstract_function_decl_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_constructor_decl_ref_exprs( //dir=expr + unique int id: @other_constructor_decl_ref_expr, + int constructor_decl: @constructor_decl_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_constructor_exprs( //dir=expr + unique int id: @rebind_self_in_constructor_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +closure_exprs( //dir=expr + unique int id: @closure_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr +); + +@self_apply_expr = + @constructor_ref_call_expr +| @dot_syntax_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +constructor_ref_call_exprs( //dir=expr + unique int id: @constructor_ref_call_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_labels( //dir=type + int id: @any_function_type ref, + int index: int ref, + string param_label: string ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@abstract_function_decl_or_none = + @abstract_function_decl +| @unspecified_element +; + +@accessor_decl_or_none = + @accessor_decl +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@constructor_decl_or_none = + @constructor_decl +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/downgrades/1a6e9325bd60462e669e524438174deef4476df0/swift.dbscheme b/swift/downgrades/1a6e9325bd60462e669e524438174deef4476df0/swift.dbscheme new file mode 100644 index 00000000000..abbb8c9e840 --- /dev/null +++ b/swift/downgrades/1a6e9325bd60462e669e524438174deef4476df0/swift.dbscheme @@ -0,0 +1,2478 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @iterable_decl_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @case_label_item +| @condition_element +| @decl +| @expr +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +@decl = + @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +@generic_context = + @abstract_function_decl +| @extension_decl +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +@iterable_decl_context = + @extension_decl +| @nominal_type_decl +; + +#keyset[id, index] +iterable_decl_context_members( //dir=decl + int id: @iterable_decl_context ref, + int index: int ref, + int member: @decl_or_none ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_function_decl +| @abstract_storage_decl +| @enum_element_decl +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_function_decl = + @constructor_decl +| @destructor_decl +| @func_decl +; + +#keyset[id] +abstract_function_decls( //dir=decl + int id: @abstract_function_decl ref, + string name: string ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessor_decls( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor_decl: @accessor_decl_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +constructor_decls( //dir=decl + unique int id: @constructor_decl +); + +destructor_decls( //dir=decl + unique int id: @destructor_decl +); + +@func_decl = + @accessor_decl +| @concrete_func_decl +; + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id, index] +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessor_decls( //dir=decl + unique int id: @accessor_decl +); + +#keyset[id] +accessor_decl_is_getter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_setter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_will_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_did_set( //dir=decl + int id: @accessor_decl ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_func_decls( //dir=decl + unique int id: @concrete_func_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @abstract_closure_expr +| @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initializer_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_constructor_decl_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_constructor_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@abstract_closure_expr = + @auto_closure_expr +| @closure_expr +; + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id] +key_path_expr_parsed_paths( //dir=expr + int id: @key_path_expr ref, + int parsed_path: @expr_or_none ref +); + +lazy_initializer_exprs( //dir=expr + unique int id: @lazy_initializer_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @abstract_function_decl_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_constructor_decl_ref_exprs( //dir=expr + unique int id: @other_constructor_decl_ref_expr, + int constructor_decl: @constructor_decl_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_constructor_exprs( //dir=expr + unique int id: @rebind_self_in_constructor_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +closure_exprs( //dir=expr + unique int id: @closure_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr +); + +@self_apply_expr = + @constructor_ref_call_expr +| @dot_syntax_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +constructor_ref_call_exprs( //dir=expr + unique int id: @constructor_ref_call_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_labels( //dir=type + int id: @any_function_type ref, + int index: int ref, + string param_label: string ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@abstract_function_decl_or_none = + @abstract_function_decl +| @unspecified_element +; + +@accessor_decl_or_none = + @accessor_decl +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@constructor_decl_or_none = + @constructor_decl +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/downgrades/1a6e9325bd60462e669e524438174deef4476df0/upgrade.properties b/swift/downgrades/1a6e9325bd60462e669e524438174deef4476df0/upgrade.properties new file mode 100644 index 00000000000..c1ba8a9be36 --- /dev/null +++ b/swift/downgrades/1a6e9325bd60462e669e524438174deef4476df0/upgrade.properties @@ -0,0 +1,9 @@ +description: Revert adding missing Accessor and AccessSemantics cases +compatibility: full +accessor_decl_is_read.rel: delete +accessor_decl_is_modify.rel: delete +accessor_decl_is_unsafe_address.rel: delete +accessor_decl_is_unsafe_mutable_address.rel: delete +decl_ref_expr_has_distributed_thunk_semantics.rel: delete +member_ref_expr_has_distributed_thunk_semantics.rel: delete +subscript_expr_has_distributed_thunk_semantics.rel: delete diff --git a/swift/ql/lib/upgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/old.dbscheme b/swift/ql/lib/upgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/old.dbscheme new file mode 100644 index 00000000000..abbb8c9e840 --- /dev/null +++ b/swift/ql/lib/upgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/old.dbscheme @@ -0,0 +1,2478 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @iterable_decl_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @case_label_item +| @condition_element +| @decl +| @expr +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +@decl = + @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +@generic_context = + @abstract_function_decl +| @extension_decl +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +@iterable_decl_context = + @extension_decl +| @nominal_type_decl +; + +#keyset[id, index] +iterable_decl_context_members( //dir=decl + int id: @iterable_decl_context ref, + int index: int ref, + int member: @decl_or_none ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_function_decl +| @abstract_storage_decl +| @enum_element_decl +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_function_decl = + @constructor_decl +| @destructor_decl +| @func_decl +; + +#keyset[id] +abstract_function_decls( //dir=decl + int id: @abstract_function_decl ref, + string name: string ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessor_decls( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor_decl: @accessor_decl_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +constructor_decls( //dir=decl + unique int id: @constructor_decl +); + +destructor_decls( //dir=decl + unique int id: @destructor_decl +); + +@func_decl = + @accessor_decl +| @concrete_func_decl +; + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id, index] +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessor_decls( //dir=decl + unique int id: @accessor_decl +); + +#keyset[id] +accessor_decl_is_getter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_setter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_will_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_did_set( //dir=decl + int id: @accessor_decl ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_func_decls( //dir=decl + unique int id: @concrete_func_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @abstract_closure_expr +| @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initializer_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_constructor_decl_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_constructor_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@abstract_closure_expr = + @auto_closure_expr +| @closure_expr +; + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id] +key_path_expr_parsed_paths( //dir=expr + int id: @key_path_expr ref, + int parsed_path: @expr_or_none ref +); + +lazy_initializer_exprs( //dir=expr + unique int id: @lazy_initializer_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @abstract_function_decl_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_constructor_decl_ref_exprs( //dir=expr + unique int id: @other_constructor_decl_ref_expr, + int constructor_decl: @constructor_decl_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_constructor_exprs( //dir=expr + unique int id: @rebind_self_in_constructor_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +closure_exprs( //dir=expr + unique int id: @closure_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr +); + +@self_apply_expr = + @constructor_ref_call_expr +| @dot_syntax_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +constructor_ref_call_exprs( //dir=expr + unique int id: @constructor_ref_call_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_labels( //dir=type + int id: @any_function_type ref, + int index: int ref, + string param_label: string ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@abstract_function_decl_or_none = + @abstract_function_decl +| @unspecified_element +; + +@accessor_decl_or_none = + @accessor_decl +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@constructor_decl_or_none = + @constructor_decl +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/ql/lib/upgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/swift.dbscheme b/swift/ql/lib/upgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/swift.dbscheme new file mode 100644 index 00000000000..1a6e9325bd6 --- /dev/null +++ b/swift/ql/lib/upgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/swift.dbscheme @@ -0,0 +1,2513 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @iterable_decl_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @case_label_item +| @condition_element +| @decl +| @expr +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +@decl = + @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +@generic_context = + @abstract_function_decl +| @extension_decl +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +@iterable_decl_context = + @extension_decl +| @nominal_type_decl +; + +#keyset[id, index] +iterable_decl_context_members( //dir=decl + int id: @iterable_decl_context ref, + int index: int ref, + int member: @decl_or_none ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_function_decl +| @abstract_storage_decl +| @enum_element_decl +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_function_decl = + @constructor_decl +| @destructor_decl +| @func_decl +; + +#keyset[id] +abstract_function_decls( //dir=decl + int id: @abstract_function_decl ref, + string name: string ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessor_decls( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor_decl: @accessor_decl_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +constructor_decls( //dir=decl + unique int id: @constructor_decl +); + +destructor_decls( //dir=decl + unique int id: @destructor_decl +); + +@func_decl = + @accessor_decl +| @concrete_func_decl +; + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id, index] +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessor_decls( //dir=decl + unique int id: @accessor_decl +); + +#keyset[id] +accessor_decl_is_getter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_setter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_will_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_did_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_read( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_modify( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_address( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_mutable_address( //dir=decl + int id: @accessor_decl ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_func_decls( //dir=decl + unique int id: @concrete_func_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @abstract_closure_expr +| @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initializer_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_constructor_decl_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_constructor_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@abstract_closure_expr = + @auto_closure_expr +| @closure_expr +; + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id] +key_path_expr_parsed_paths( //dir=expr + int id: @key_path_expr ref, + int parsed_path: @expr_or_none ref +); + +lazy_initializer_exprs( //dir=expr + unique int id: @lazy_initializer_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @abstract_function_decl_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_constructor_decl_ref_exprs( //dir=expr + unique int id: @other_constructor_decl_ref_expr, + int constructor_decl: @constructor_decl_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_constructor_exprs( //dir=expr + unique int id: @rebind_self_in_constructor_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +closure_exprs( //dir=expr + unique int id: @closure_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr +); + +@self_apply_expr = + @constructor_ref_call_expr +| @dot_syntax_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +constructor_ref_call_exprs( //dir=expr + unique int id: @constructor_ref_call_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_labels( //dir=type + int id: @any_function_type ref, + int index: int ref, + string param_label: string ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@abstract_function_decl_or_none = + @abstract_function_decl +| @unspecified_element +; + +@accessor_decl_or_none = + @accessor_decl +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@constructor_decl_or_none = + @constructor_decl +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/ql/lib/upgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/upgrade.properties b/swift/ql/lib/upgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/upgrade.properties new file mode 100644 index 00000000000..b1ad62a1a71 --- /dev/null +++ b/swift/ql/lib/upgrades/abbb8c9e8408841c2bc12e3deb2305f062f5399e/upgrade.properties @@ -0,0 +1,2 @@ +description: Add missing Accessor and AccessSemantics cases +compatibility: backwards From 52a117aaf5265fbd8e08647fd9e8aa2e55d2ec42 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 29 Nov 2022 09:18:03 +0100 Subject: [PATCH 641/796] Swift: optimize bazel caching in CI Previously the cache would become stale. Now the same incremental cache mechanism in use for the QL cache is adopted (and factored out in a separate action). Namely, pushes on main will populate the cache using the commit hash as key, while PRs will try to use the cache of their merge base, read-only. To avoid the cache growing out of control, a simple cache eviction is done on pushes. --- .../cache-query-compilation/action.yml | 37 +++---------- .github/actions/incremental-cache/action.yml | 44 +++++++++++++++ .github/workflows/go-tests-other-os.yml | 3 +- .github/workflows/go-tests.yml | 8 ++- .github/workflows/swift.yml | 20 +++---- swift/actions/build-and-test/action.yml | 54 +++++++++++++++++++ .../actions/create-extractor-pack/action.yml | 11 ---- swift/actions/print-unextracted/action.yml | 9 ---- swift/actions/run-quick-tests/action.yml | 18 ------- swift/actions/setup-env/action.yml | 24 --------- 10 files changed, 116 insertions(+), 112 deletions(-) create mode 100644 .github/actions/incremental-cache/action.yml create mode 100644 swift/actions/build-and-test/action.yml delete mode 100644 swift/actions/create-extractor-pack/action.yml delete mode 100644 swift/actions/print-unextracted/action.yml delete mode 100644 swift/actions/run-quick-tests/action.yml delete mode 100644 swift/actions/setup-env/action.yml diff --git a/.github/actions/cache-query-compilation/action.yml b/.github/actions/cache-query-compilation/action.yml index 9f7569e5f0c..e39216c9b7a 100644 --- a/.github/actions/cache-query-compilation/action.yml +++ b/.github/actions/cache-query-compilation/action.yml @@ -14,39 +14,14 @@ outputs: runs: using: composite steps: - # Cache the query compilation caches. - # calculate the merge-base with main, in a way that works both on PRs and pushes to main. - - name: Calculate merge-base - shell: bash - if: ${{ github.event_name == 'pull_request' }} - env: - BASE_BRANCH: ${{ github.base_ref }} - run: | - MERGE_BASE=$(git cat-file commit $GITHUB_SHA | grep '^parent ' | head -1 | cut -f 2 -d " ") - echo "merge_base=$MERGE_BASE" >> $GITHUB_ENV - - name: Read CodeQL query compilation - PR - if: ${{ github.event_name == 'pull_request' }} - uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6 + - name: Cache the query compilation caches + uses: ./.github/actions/incremental-cache with: path: '**/.cache' - read-only: true - key: codeql-compile-${{ inputs.key }}-pr-${{ github.sha }} # deliberately not using the `compile-compile-main` keys here. - restore-keys: | - codeql-compile-${{ inputs.key }}-${{ github.base_ref }}-${{ env.merge_base }} - codeql-compile-${{ inputs.key }}-${{ github.base_ref }}- - codeql-compile-${{ inputs.key }}-main- - - name: Fill CodeQL query compilation cache - main - if: ${{ github.event_name != 'pull_request' }} - uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6 - with: - path: '**/.cache' - key: codeql-compile-${{ inputs.key }}-${{ github.ref_name }}-${{ github.sha }} # just fill on main - restore-keys: | # restore from another random commit, to speed up compilation. - codeql-compile-${{ inputs.key }}-${{ github.ref_name }}- - codeql-compile-${{ inputs.key }}-main- + key: codeql-compile-${{ inputs.key }} - name: Fill compilation cache directory id: fill-compilation-dir - shell: bash + shell: bash run: | # Move all the existing cache into another folder, so we only preserve the cache for the current queries. mkdir -p ${COMBINED_CACHE_DIR} @@ -57,5 +32,5 @@ runs: rm -rf **/.cache/* echo "compdir=${COMBINED_CACHE_DIR}" >> $GITHUB_OUTPUT - env: - COMBINED_CACHE_DIR: ${{ github.workspace }}/compilation-dir \ No newline at end of file + env: + COMBINED_CACHE_DIR: ${{ github.workspace }}/compilation-dir diff --git a/.github/actions/incremental-cache/action.yml b/.github/actions/incremental-cache/action.yml new file mode 100644 index 00000000000..20dd41d0ca8 --- /dev/null +++ b/.github/actions/incremental-cache/action.yml @@ -0,0 +1,44 @@ +name: Setup an incremental cache +description: Special cache wrapper to be run on pull requests and pushes, that will try to restore + a cache as close as possible to the merge base + +inputs: + path: + description: 'The path to cache' + required: true + key: + description: 'The cache key to use - should be unique to the workflow' + required: true + +runs: + using: composite + steps: + # calculate the merge-base with main, in a way that works both on PRs and pushes to main. + - name: Calculate merge-base + shell: bash + if: ${{ github.event_name == 'pull_request' }} + env: + BASE_BRANCH: ${{ github.base_ref }} + run: | + MERGE_BASE=$(git cat-file commit $GITHUB_SHA | grep '^parent ' | head -1 | cut -f 2 -d " ") + echo "merge_base=$MERGE_BASE" >> $GITHUB_ENV + - name: Restore read-only cache (PR) + if: ${{ github.event_name == 'pull_request' }} + uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6 + with: + path: ${{ inputs.path }} + read-only: true + key: ${{ inputs.key }}-pr-${{ github.sha }} + restore-keys: | + ${{ inputs.key }}-${{ github.base_ref }}-${{ env.merge_base }} + ${{ inputs.key }}-${{ github.base_ref }}- + ${{ inputs.key }}-main- + - name: Fill cache (push) + if: ${{ github.event_name != 'pull_request' }} + uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6 + with: + path: ${{ inputs.path }} + key: ${{ inputs.key }}-${{ github.ref_name }}-${{ github.sha }} # just fill on main + restore-keys: | # restore from another random commit, to speed up compilation. + ${{ inputs.key }}-${{ github.ref_name }}- + ${{ inputs.key }}-main- diff --git a/.github/workflows/go-tests-other-os.yml b/.github/workflows/go-tests-other-os.yml index 5d99a170be3..edf6eb63d49 100644 --- a/.github/workflows/go-tests-other-os.yml +++ b/.github/workflows/go-tests-other-os.yml @@ -5,8 +5,7 @@ on: - "go/**" - "!go/ql/**" # don't run other-os if only ql/ files changed - .github/workflows/go-tests-other-os.yml - - .github/actions/fetch-codeql/action.yml - - .github/actions/cache-query-compilation/action.yml + - .github/actions/** - codeql-workspace.yml jobs: test-mac: diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index 685c28cf3e0..eceabb0410a 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -4,8 +4,7 @@ on: paths: - "go/**" - .github/workflows/go-tests.yml - - .github/actions/fetch-codeql/action.yml - - .github/actions/cache-query-compilation/action.yml + - .github/actions/** - codeql-workspace.yml branches: - main @@ -14,8 +13,7 @@ on: paths: - "go/**" - .github/workflows/go-tests.yml - - .github/actions/fetch-codeql/action.yml - - .github/actions/cache-query-compilation/action.yml + - .github/actions/** - codeql-workspace.yml jobs: test-linux: @@ -64,7 +62,7 @@ jobs: uses: ./.github/actions/cache-query-compilation with: key: go-qltest - + - name: Test run: | cd go diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index 4871442d4b7..47a2d2bf6ae 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -7,8 +7,7 @@ on: - "misc/bazel/**" - "*.bazel*" - .github/workflows/swift.yml - - .github/actions/fetch-codeql/action.yml - - .github/actions/cache-query-compilation/action.yml + - .github/actions/** - codeql-workspace.yml - .pre-commit-config.yaml - "!**/*.md" @@ -22,8 +21,7 @@ on: - "misc/bazel/**" - "*.bazel*" - .github/workflows/swift.yml - - .github/actions/fetch-codeql/action.yml - - .github/actions/cache-query-compilation/action.yml + - .github/actions/** - codeql-workspace.yml - "!**/*.md" - "!**/*.qhelp" @@ -35,20 +33,15 @@ jobs: # not using a matrix as you cannot depend on a specific job in a matrix, and we want to start linux checks # without waiting for the macOS build build-and-test-macos: - if: ${{ github.event_name == 'pull_request' }} runs-on: macos-12-xl steps: - uses: actions/checkout@v3 - - uses: ./swift/actions/create-extractor-pack - - uses: ./swift/actions/run-quick-tests - - uses: ./swift/actions/print-unextracted + - uses: ./swift/actions/build-and-test build-and-test-linux: runs-on: ubuntu-latest-xl steps: - uses: actions/checkout@v3 - - uses: ./swift/actions/create-extractor-pack - - uses: ./swift/actions/run-quick-tests - - uses: ./swift/actions/print-unextracted + - uses: ./swift/actions/build-and-test qltests-linux: needs: build-and-test-linux runs-on: ubuntu-latest-xl @@ -80,7 +73,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: ./swift/actions/setup-env + - uses: bazelbuild/setup-bazelisk@v2 + - uses: actions/setup-python@v4 + with: + python-version-file: 'swift/.python-version' - uses: pre-commit/action@v3.0.0 name: Check that python code is properly formatted with: diff --git a/swift/actions/build-and-test/action.yml b/swift/actions/build-and-test/action.yml new file mode 100644 index 00000000000..03706263d21 --- /dev/null +++ b/swift/actions/build-and-test/action.yml @@ -0,0 +1,54 @@ +name: Build Swift CodeQL pack +description: Builds the Swift CodeQL pack +runs: + using: composite + steps: + - uses: bazelbuild/setup-bazelisk@v2 + - uses: actions/setup-python@v4 + with: + python-version-file: 'swift/.python-version' + - name: Mount bazel cache + uses: ./.github/actions/incremental-cache + with: + path: "~/.cache/bazel-repository-cache" + key: bazel-cache-${{ runner.os }}-${{ runner.arch }} + - name: Mount bazel disk cache + uses: ./.github/actions/incremental-cache + with: + path: "~/.cache/bazel-disk-cache" + key: bazel-disk-cache-${{ runner.os }}-${{ runner.arch }} + - name: Configure bazel cache + shell: bash + run: | + echo build --repository_cache=~/.cache/bazel-repository-cache --disk_cache=~/.cache/bazel-disk-cache > ~/.bazelrc + echo test --test_output=errors >> ~/.bazelrc + - name: Print unextracted entities + shell: bash + run: | + bazel run //swift/extractor/print_unextracted + - uses: ./swift/actions/share-extractor-pack + - name: Build Swift extractor + shell: bash + run: | + bazel run //swift:create-extractor-pack + - name: Run xcode-autobuilder tests + if : ${{ github.event_name == 'pull_request' && runner.os == 'macOS' }} + shell: bash + run: | + bazel test //swift/xcode-autobuilder/tests + - name: Run codegen tests + if : ${{ github.event_name == 'pull_request' }} + shell: bash + run: | + bazel test //swift/codegen/test + - name: Run qltest tests + if : ${{ github.event_name == 'pull_request' }} + shell: bash + run: | + bazel test //swift/tools/test/qltest + - name: Evict bazel cache + if: ${{ github.event_name != 'pull_request' }} + shell: bash + run: | + find "~/.cache/bazel-repository-cache" "~/.cache/bazel-disk-cache" -atime +0 -type f -delete + du -sh "~/.cache/bazel-repository-cache" "~/.cache/bazel-disk-cache" diff --git a/swift/actions/create-extractor-pack/action.yml b/swift/actions/create-extractor-pack/action.yml deleted file mode 100644 index d020a41a071..00000000000 --- a/swift/actions/create-extractor-pack/action.yml +++ /dev/null @@ -1,11 +0,0 @@ -name: Build Swift CodeQL pack -description: Builds the Swift CodeQL pack -runs: - using: composite - steps: - - uses: ./swift/actions/setup-env - - uses: ./swift/actions/share-extractor-pack - - name: Build Swift extractor - shell: bash - run: | - bazel run //swift:create-extractor-pack diff --git a/swift/actions/print-unextracted/action.yml b/swift/actions/print-unextracted/action.yml deleted file mode 100644 index 5c59fc61b45..00000000000 --- a/swift/actions/print-unextracted/action.yml +++ /dev/null @@ -1,9 +0,0 @@ -name: Print unextracted entities -description: Prints all AST and Type entities that we do not extract yet. Must be run after `setup-env` -runs: - using: composite - steps: - - name: Print unextracted entities - shell: bash - run: | - bazel run //swift/extractor/print_unextracted diff --git a/swift/actions/run-quick-tests/action.yml b/swift/actions/run-quick-tests/action.yml deleted file mode 100644 index aca263cb996..00000000000 --- a/swift/actions/run-quick-tests/action.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Run Swift quick tests -description: Runs Swift tests defined in Bazel. Must be run after `setup-env` -runs: - using: composite - steps: - - name: Run xcode-autobuilder tests - if: runner.os == 'macOS' - shell: bash - run: | - bazel test //swift/xcode-autobuilder/tests - - name: Run codegen tests - shell: bash - run: | - bazel test //swift/codegen/test - - name: Run qltest tests - shell: bash - run: | - bazel test //swift/tools/test/qltest diff --git a/swift/actions/setup-env/action.yml b/swift/actions/setup-env/action.yml deleted file mode 100644 index 83c65d6f82a..00000000000 --- a/swift/actions/setup-env/action.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Setup Swift Package Environment -description: Sets up the environment in which to build the Swift package and run its tests -runs: - using: composite - steps: - - uses: bazelbuild/setup-bazelisk@v2 - - uses: actions/setup-python@v4 - with: - python-version-file: 'swift/.python-version' - - name: Mount bazel cache - uses: actions/cache@v3 - with: - path: "~/.cache/bazel-repository-cache" - key: bazel-cache-${{ runner.os }}-${{ runner.arch }} - - name: Mount bazel disk cache - uses: actions/cache@v3 - with: - path: "~/.cache/bazel-disk-cache" - key: bazel-disk-cache-${{ runner.os }}-${{ runner.arch }} - - name: Set up bazel disk cache - shell: bash - run: | - echo build --repository_cache=~/.cache/bazel-repository-cache --disk_cache=~/.cache/bazel-disk-cache > ~/.bazelrc - echo test --test_output=errors >> ~/.bazelrc From 3cb31ef0301f6e2e81228ef4f6075c646eddc75e Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Tue, 29 Nov 2022 12:10:00 +0100 Subject: [PATCH 642/796] use `withFileTypes` in move-caches.js Co-authored-by: Arthur Baars --- .../actions/cache-query-compilation/move-caches.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/.github/actions/cache-query-compilation/move-caches.js b/.github/actions/cache-query-compilation/move-caches.js index e86b1765cf7..5021fbf0a21 100644 --- a/.github/actions/cache-query-compilation/move-caches.js +++ b/.github/actions/cache-query-compilation/move-caches.js @@ -13,16 +13,12 @@ const path = require("path"); const COMBINED_CACHE_DIR = process.argv[2]; function* walkCaches(dir) { - const files = fs.readdirSync(dir); + const files = fs.readdirSync(dir, { withFileTypes: true }); for (const file of files) { - const filePath = path.join(dir, file); - if (!fs.existsSync(filePath)) { - continue; - } - const stat = fs.statSync(filePath); - if (stat.isDirectory()) { + if (file.isDirectory()) { + const filePath = path.join(dir, file.name); yield* walkCaches(filePath); - if (file === ".cache") { + if (file.name === ".cache") { yield filePath; } } From 7c1435b7c622dce99b4772e29a603477a4257b15 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 29 Nov 2022 12:16:38 +0100 Subject: [PATCH 643/796] use withFileTypes in move-caches.js some more --- .github/actions/cache-query-compilation/move-caches.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/actions/cache-query-compilation/move-caches.js b/.github/actions/cache-query-compilation/move-caches.js index 5021fbf0a21..67fc503cdc0 100644 --- a/.github/actions/cache-query-compilation/move-caches.js +++ b/.github/actions/cache-query-compilation/move-caches.js @@ -26,11 +26,10 @@ function* walkCaches(dir) { } async function copyDir(src, dest) { - for await (const file of await fs.promises.readdir(src)) { - const srcPath = path.join(src, file); - const destPath = path.join(dest, file); - const stat = await fs.promises.stat(srcPath); - if (stat.isDirectory()) { + for await (const file of await fs.promises.readdir(src, { withFileTypes: true })) { + const srcPath = path.join(src, file.name); + const destPath = path.join(dest, file.name); + if (file.isDirectory()) { if (!fs.existsSync(destPath)) { fs.mkdirSync(destPath); } From 1ee04dc0201841aa0c722bf0f969a1633028fff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Tue, 29 Nov 2022 12:36:51 +0100 Subject: [PATCH 644/796] Update prepare-db-upgrade.md Clarify the test steps based on my experience, where I got a "database may be too new" error when the `--search-path=` directory was not specified. --- docs/prepare-db-upgrade.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/prepare-db-upgrade.md b/docs/prepare-db-upgrade.md index 906c47d9c6d..42c329dd947 100644 --- a/docs/prepare-db-upgrade.md +++ b/docs/prepare-db-upgrade.md @@ -69,10 +69,10 @@ Although we have some automated testing of the scripts (e.g. to test that you ca To test the upgrade script, run: ``` -codeql test run --search-path= --search-path=ql +codeql test run --search-path= --search-path= ``` -Where `` is an extractor pack containing the old extractor and dbscheme that pre-date your changes, and `` is the directory containing the qltests for your language. This will run the tests using an old extractor, and the test databases will all be upgraded in place using your new upgrade script. +Where `` is an extractor pack containing the old extractor and dbscheme that pre-date your changes, `` is the directory containing the qltests for your language, and `` is the root directory directory of the `github/codeql` clone that contains ``. This will run the tests using an old extractor, and the test databases will all be upgraded in place using your new upgrade script. To test the downgrade script, create an extractor pack that includes your new dbscheme and extractor changes. Then checkout the `main` branch of `codeql` (i.e. a branch that does not include your changes), and run: From 9507dc15fd201a9a9f9b9a9f791017bbe4ffdd06 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 28 Nov 2022 15:15:58 +0100 Subject: [PATCH 645/796] Java: Remove un-needed qlfrag files. --- .../src/utils/flowtestcasegenerator/testModelsFooter.qlfrag | 3 --- .../src/utils/flowtestcasegenerator/testModelsHeader.qlfrag | 5 ----- 2 files changed, 8 deletions(-) delete mode 100644 java/ql/src/utils/flowtestcasegenerator/testModelsFooter.qlfrag delete mode 100644 java/ql/src/utils/flowtestcasegenerator/testModelsHeader.qlfrag diff --git a/java/ql/src/utils/flowtestcasegenerator/testModelsFooter.qlfrag b/java/ql/src/utils/flowtestcasegenerator/testModelsFooter.qlfrag deleted file mode 100644 index 77bc78669d2..00000000000 --- a/java/ql/src/utils/flowtestcasegenerator/testModelsFooter.qlfrag +++ /dev/null @@ -1,3 +0,0 @@ - ] - } -} diff --git a/java/ql/src/utils/flowtestcasegenerator/testModelsHeader.qlfrag b/java/ql/src/utils/flowtestcasegenerator/testModelsHeader.qlfrag deleted file mode 100644 index fb33b7eb5db..00000000000 --- a/java/ql/src/utils/flowtestcasegenerator/testModelsHeader.qlfrag +++ /dev/null @@ -1,5 +0,0 @@ -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind;provenance" From 48290c95a79e78d3564282631b06a132f45518a0 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 28 Nov 2022 15:17:32 +0100 Subject: [PATCH 646/796] Java: Update the flow test case generator to emit data extension like model data. --- .../FlowTestCaseSupportMethods.qll | 20 ++++++++++--------- .../GenerateFlowTestCase.qll | 6 +++--- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/java/ql/src/utils/flowtestcasegenerator/FlowTestCaseSupportMethods.qll b/java/ql/src/utils/flowtestcasegenerator/FlowTestCaseSupportMethods.qll index c3a47b5adea..80de2c6068d 100644 --- a/java/ql/src/utils/flowtestcasegenerator/FlowTestCaseSupportMethods.qll +++ b/java/ql/src/utils/flowtestcasegenerator/FlowTestCaseSupportMethods.qll @@ -97,12 +97,12 @@ abstract class SupportMethod extends string { int getPriority() { result = 50 } /** - * Gets the CSV row describing this support method if it is needed to set up the output for this test. + * Gets the data extension row describing this support method if it is needed to set up the output for this test. * - * For example, `newWithMapValue` will propagate a value from `Argument[0]` to `MapValue of ReturnValue`, and `getMapValue` + * For example, `newWithMapValue` will propagate a value from `Argument[0]` to `ReturnValue.MapValue`, and `getMapValue` * will do the opposite. */ - string getCsvModel() { none() } + string getDataExtensionModel() { none() } } /** @@ -162,10 +162,11 @@ private class DefaultGetMethod extends GetMethod { result = "Object get" + contentToken(c) + "Default(Object container) { return null; }" } - override string getCsvModel() { + override string getDataExtensionModel() { result = - "generatedtest;Test;false;" + this.getName() + ";(Object);;Argument[0]." + - getComponentSpec(SummaryComponent::content(c)) + ";ReturnValue;value;manual" + "\"generatedtest\", \"Test\", False, \"" + this.getName() + + "\", \"(Object)\", \"\", \"Argument[0]." + getComponentSpec(SummaryComponent::content(c)) + + "\", \"ReturnValue\", \"value\", \"manual\"" } } @@ -358,10 +359,11 @@ private class DefaultGenMethod extends GenMethod { result = "Object newWith" + contentToken(c) + "Default(Object element) { return null; }" } - override string getCsvModel() { + override string getDataExtensionModel() { result = - "generatedtest;Test;false;" + this.getName() + ";(Object);;Argument[0];ReturnValue." + - getComponentSpec(SummaryComponent::content(c)) + ";value;manual" + "\"generatedtest\", \"Test\", False, \"" + this.getName() + + "\", \"(Object)\", \"\", \"Argument[0]\", \"ReturnValue." + + getComponentSpec(SummaryComponent::content(c)) + "\", \"value\", \"manual\"" } } diff --git a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll index 613ea19753f..5d9aa884ecc 100644 --- a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll +++ b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll @@ -85,12 +85,12 @@ SupportMethod getASupportMethod() { } /** - * Returns a CSV specification of the taint-/value-propagation behavior of a test support method (`get` or `newWith` method). + * Returns a data extension specification of the taint-/value-propagation behavior of a test support method (`get` or `newWith` method). */ -query string getASupportMethodModel() { result = getASupportMethod().getCsvModel() } +query string getASupportMethodModel() { result = getASupportMethod().getDataExtensionModel() } /** - * Gets a Java file body testing all requested CSV rows against whatever classes and methods they resolve against. + * Gets a Java file body testing all requested Models as Data rows against whatever classes and methods they resolve against. */ query string getTestCase() { result = From 984124b3b5fbe7719e4fb23958ca4cb5f7306815 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 28 Nov 2022 15:53:52 +0100 Subject: [PATCH 647/796] Java: Improve flow test case generator to emit a data extensions YAML file and qlpack file if needed. --- .../flowtestcasegenerator/FlowTestCase.qll | 4 +- .../GenerateFlowTestCase.py | 51 +++++++++++++++---- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll b/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll index bab34473ed7..de4bae52065 100644 --- a/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll +++ b/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll @@ -42,11 +42,11 @@ predicate summaryModelRow( } /** - * Gets a CSV row for which a test has been requested, but `SummaryModelCsv.row` does not hold of it. + * Gets a CSV row for which a test has been requested, but where a summary has not already been defined. */ query string missingSummaryModelCsv() { any(TargetSummaryModelCsv target).row(result) and - not any(SummaryModelCsv model).row(result) + not summaryModelRow(_, _, _, _, _, _, _, _, _, _, result) } /** diff --git a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py index 38d90830bf5..65c485c19cc 100755 --- a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py +++ b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py @@ -24,7 +24,9 @@ contain the needed classes. If --force is present, existing files may be overwritten. -Requirements: `mvn` and `codeql` should both appear on your path. +Requirements: + - `mvn` and `codeql` should both appear on your path. + - `--additional-packs /path/to/semmle-code/ql` should be added to your `.config/codeql/config` file. After test generation completes, any lines in specsToTest.csv that didn't produce tests are output. If this happens, check the spelling of class and method names, and the syntax of input and output specifications. @@ -52,10 +54,12 @@ except Exception as e: resultJava = os.path.join(sys.argv[3], "Test.java") resultQl = os.path.join(sys.argv[3], "test.ql") +resultYml = os.path.join(sys.argv[3], "test.model.yml") +resultPack = os.path.join(sys.argv[3], "qlpack.yml") -if not force and (os.path.exists(resultJava) or os.path.exists(resultQl)): - print("Won't overwrite existing files '%s' or '%s'" % - (resultJava, resultQl), file=sys.stderr) +if not force and (os.path.exists(resultJava) or os.path.exists(resultQl) or os.path.exists(resultYml) or os.path.exists(resultPack)): + print("Won't overwrite existing files '%s', '%s', '%s' or '%s'." % + (resultJava, resultQl, resultYml, resultPack), file=sys.stderr) sys.exit(1) workDir = tempfile.mkdtemp() @@ -127,7 +131,13 @@ queryDir = os.path.join(workDir, "query") os.makedirs(queryDir) qlFile = os.path.join(queryDir, "gen.ql") with open(os.path.join(queryDir, "qlpack.yml"), "w") as f: - f.write("name: test-generation-query\nversion: 0.0.0\nlibraryPathDependencies: codeql/java-queries") + f.write(f"""name: test-generation-query +version: 0.0.0 +dependencies: + codeql/java-all: '*' + codeql/java-queries: '*' +""") + with open(qlFile, "w") as f: f.write( "import java\nimport utils.flowtestcasegenerator.GenerateFlowTestCase\n\nclass GenRow extends TargetSummaryModelCsv {\n\n\toverride predicate row(string r) {\n\t\tr = [\n") @@ -207,11 +217,32 @@ def copyfile(fromName, toFileHandle): with open(resultQl, "w") as f: copyfile("testHeader.qlfrag", f) - if len(supportModelRows) != 0: - copyfile("testModelsHeader.qlfrag", f) - f.write(", ".join('"%s"' % - modelSpecRow[0].strip() for modelSpecRow in supportModelRows)) - copyfile("testModelsFooter.qlfrag", f) + +if len(supportModelRows) != 0: + # Make a test extension file + with open(resultYml, "w") as f: + models = "\n".join(' - [%s]' % + modelSpecRow[0].strip() for modelSpecRow in supportModelRows) + dataextensions = f"""extensions: + - addsTo: + pack: codeql/java-tests + extensible: extSummaryModel + data: +{models} +""" + f.write(dataextensions) + # Make a qlpack file such that the extension will be picked up + with open(resultPack, "w") as f: + f.write(f"""name: example-test-pack +version: 0.0.0 +extractor: java +dependencies: + codeql/java-all: '*' + codeql/java-queries: '*' + codeql/java-tests: '*' +dataExtensions: + - test.model.yml +""") # Make an empty .expected file, since this is an inline-exectations test with open(os.path.join(sys.argv[3], "test.expected"), "w"): From d2c458c06640aa568aff7a4ae92f4a2224b5d516 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 29 Nov 2022 13:05:18 +0100 Subject: [PATCH 648/796] Java/C#: Correction of autogenerated comment(s) produced by the model generator. --- csharp/ql/lib/ext/generated/dotnet_runtime.model.yml | 3 +-- java/ql/lib/ext/generated/org.apache.commons.io.model.yml | 3 +-- .../scripts/models-as-data/generate_flow_model_extensions.py | 5 ++--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/csharp/ql/lib/ext/generated/dotnet_runtime.model.yml b/csharp/ql/lib/ext/generated/dotnet_runtime.model.yml index a396d121591..9d4afaacbf7 100644 --- a/csharp/ql/lib/ext/generated/dotnet_runtime.model.yml +++ b/csharp/ql/lib/ext/generated/dotnet_runtime.model.yml @@ -1,6 +1,5 @@ - # THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. -# Definitions of taint steps in the dotnet_runtime framework. +# Definitions of models for the dotnet_runtime framework. extensions: diff --git a/java/ql/lib/ext/generated/org.apache.commons.io.model.yml b/java/ql/lib/ext/generated/org.apache.commons.io.model.yml index f7af89c8a1b..f18303df59f 100644 --- a/java/ql/lib/ext/generated/org.apache.commons.io.model.yml +++ b/java/ql/lib/ext/generated/org.apache.commons.io.model.yml @@ -1,6 +1,5 @@ - # THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. -# Definitions of taint steps in the org.apache.commons.io framework. +# Definitions of models for the org.apache.commons.io framework. extensions: - addsTo: diff --git a/misc/scripts/models-as-data/generate_flow_model_extensions.py b/misc/scripts/models-as-data/generate_flow_model_extensions.py index 5367f87b1f6..c06e4eaeb62 100644 --- a/misc/scripts/models-as-data/generate_flow_model_extensions.py +++ b/misc/scripts/models-as-data/generate_flow_model_extensions.py @@ -173,9 +173,8 @@ Requirements: `codeql` should both appear on your path. else: negativeSummaryAddsTo = "" - return f""" -# THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. -# Definitions of taint steps in the {self.friendlyname} framework. + return f"""# THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. +# Definitions of models for the {self.friendlyname} framework. extensions: {sinkAddsTo} From a3a68fe83d25528f96ad2d2b9009cbae70d613a1 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 29 Nov 2022 13:09:02 +0100 Subject: [PATCH 649/796] Tweak comment in `incremental-cache` action --- .github/actions/incremental-cache/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/incremental-cache/action.yml b/.github/actions/incremental-cache/action.yml index 20dd41d0ca8..2ea62719886 100644 --- a/.github/actions/incremental-cache/action.yml +++ b/.github/actions/incremental-cache/action.yml @@ -39,6 +39,6 @@ runs: with: path: ${{ inputs.path }} key: ${{ inputs.key }}-${{ github.ref_name }}-${{ github.sha }} # just fill on main - restore-keys: | # restore from another random commit, to speed up compilation. + restore-keys: | # restore the latest cache if the exact cache is unavailable, to speed up compilation. ${{ inputs.key }}-${{ github.ref_name }}- ${{ inputs.key }}-main- From 52cf27653f5a5a68595146f24d4d8b72392db333 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Tue, 29 Nov 2022 13:12:14 +0100 Subject: [PATCH 650/796] Ruby: fix upgrade script --- .../1199e154f5e9b3560297633c6ebb4dfe0b191ae4/upgrade.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/downgrades/1199e154f5e9b3560297633c6ebb4dfe0b191ae4/upgrade.properties b/ruby/downgrades/1199e154f5e9b3560297633c6ebb4dfe0b191ae4/upgrade.properties index f1b4e1fd9f7..443afb8639f 100644 --- a/ruby/downgrades/1199e154f5e9b3560297633c6ebb4dfe0b191ae4/upgrade.properties +++ b/ruby/downgrades/1199e154f5e9b3560297633c6ebb4dfe0b191ae4/upgrade.properties @@ -9,4 +9,4 @@ ruby_rational_def.rel: run ruby_rational_def.qlo ruby_call_method.rel: delete ruby_complex_def.rel: delete ruby_block_parameters_locals.rel: delete -ruby_call_operator: delete +ruby_call_operator.rel: delete From f3f7a89ef802f076a2f081c58615cef02a777e98 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 29 Nov 2022 12:26:14 +0100 Subject: [PATCH 651/796] make the JS autobuilder consistent with Ruby when no JS code was detected --- .../extractor/src/com/semmle/js/extractor/AutoBuild.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java index 7f28d93a183..f8c0d4d699b 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java +++ b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java @@ -52,6 +52,7 @@ import com.semmle.util.exception.ResourceError; import com.semmle.util.exception.UserError; import com.semmle.util.extraction.ExtractorOutputConfig; import com.semmle.util.files.FileUtil; +import com.semmle.util.files.FileUtil8; import com.semmle.util.io.WholeIO; import com.semmle.util.io.csv.CSVReader; import com.semmle.util.language.LegacyLanguage; @@ -438,8 +439,10 @@ public class AutoBuild { startThreadPool(); try { extractSource(); - extractExterns(); extractXml(); + if (seenCode) { // don't bother with the externs if no code was seen + extractExterns(); + } } finally { shutdownThreadPool(); } @@ -449,7 +452,9 @@ public class AutoBuild { } else { warn("No JavaScript or TypeScript code found."); } - return -1; + // ensuring that the finalize steps detects that no code was seen + FileUtil8.recursiveDelete(Paths.get(EnvironmentVariables.getWipDatabase() + "/src")); + return 0; } return 0; } From 136b6db2ad46a074bcc471c4cceb0a9d1046eca0 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 29 Nov 2022 13:07:07 +0100 Subject: [PATCH 652/796] only delete the src/ folder if it was empty --- .../extractor/src/com/semmle/js/extractor/AutoBuild.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java index f8c0d4d699b..d7f8b0a8d28 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java +++ b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java @@ -452,8 +452,13 @@ public class AutoBuild { } else { warn("No JavaScript or TypeScript code found."); } - // ensuring that the finalize steps detects that no code was seen - FileUtil8.recursiveDelete(Paths.get(EnvironmentVariables.getWipDatabase() + "/src")); + // ensuring that the finalize steps detects that no code was seen. + Path srcFolder = Paths.get(EnvironmentVariables.getWipDatabase() + "/src"); + // check that the srcFolder is empty + if (Files.list(srcFolder).count() == 0) { + // Non-recursive delete because "src/" should be empty. + FileUtil8.delete(srcFolder); + } return 0; } return 0; From 3b31b509831719ab898b6dc191f818e58a41812d Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Tue, 29 Nov 2022 13:07:47 +0000 Subject: [PATCH 653/796] Kotlin: Rename compilerGeneratedKind to compilerGeneratedKindOverride --- .../src/main/kotlin/KotlinFileExtractor.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index bca94f95114..0dc226b86ce 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -1507,12 +1507,12 @@ open class KotlinFileExtractor( } is IrFunction -> { if (s.isLocalFunction()) { - val compilerGeneratedKind = if (s.origin == IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE) { + val compilerGeneratedKindOverride = if (s.origin == IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE) { CompilerGeneratedKinds.DECLARING_CLASSES_OF_ADAPTER_FUNCTIONS } else { null } - val classId = extractGeneratedClass(s, listOf(pluginContext.irBuiltIns.anyType), compilerGeneratedKind = compilerGeneratedKind) + val classId = extractGeneratedClass(s, listOf(pluginContext.irBuiltIns.anyType), compilerGeneratedKindOverride = compilerGeneratedKindOverride) extractLocalTypeDeclStmt(classId, s, callable, parent, idx) val ids = getLocallyVisibleFunctionLabels(s) tw.writeKtLocalFunction(ids.function) @@ -5390,7 +5390,7 @@ open class KotlinFileExtractor( locId: Label, elementToReportOn: IrElement, declarationParent: IrDeclarationParent, - compilerGeneratedKind: CompilerGeneratedKinds? = null, + compilerGeneratedKindOverride: CompilerGeneratedKinds? = null, superConstructorSelector: (IrFunction) -> Boolean = { it.valueParameters.isEmpty() }, extractSuperconstructorArgs: (Label) -> Unit = {}, ): Label { @@ -5398,7 +5398,7 @@ open class KotlinFileExtractor( val id = ids.type.javaResult.id.cast() val pkgId = extractPackage("") tw.writeClasses(id, "", pkgId, id) - tw.writeCompiler_generated(id, (compilerGeneratedKind ?: CompilerGeneratedKinds.CALLABLE_CLASS).kind) + tw.writeCompiler_generated(id, (compilerGeneratedKindOverride ?: CompilerGeneratedKinds.CALLABLE_CLASS).kind) tw.writeHasLocation(id, locId) // Extract constructor @@ -5448,12 +5448,12 @@ open class KotlinFileExtractor( private fun extractGeneratedClass( localFunction: IrFunction, superTypes: List, - compilerGeneratedKind: CompilerGeneratedKinds? = null + compilerGeneratedKindOverride: CompilerGeneratedKinds? = null ) : Label { with("generated class", localFunction) { val ids = getLocallyVisibleFunctionLabels(localFunction) - val id = extractGeneratedClass(ids, superTypes, tw.getLocation(localFunction), localFunction, localFunction.parent, compilerGeneratedKind = compilerGeneratedKind) + val id = extractGeneratedClass(ids, superTypes, tw.getLocation(localFunction), localFunction, localFunction.parent, compilerGeneratedKindOverride = compilerGeneratedKindOverride) // Extract local function as a member extractFunction(localFunction, id, extractBody = true, extractMethodAndParameterTypeAccesses = true, null, listOf()) From 63a5f8965e1df956dd0e00b858da5e7c22293f93 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 29 Nov 2022 14:08:21 +0100 Subject: [PATCH 654/796] fix tests --- .../src/com/semmle/js/extractor/AutoBuild.java | 12 ++++++++++-- .../com/semmle/js/extractor/test/AutoBuildTests.java | 5 +++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java index d7f8b0a8d28..266685e0abf 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java +++ b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java @@ -434,19 +434,27 @@ public class AutoBuild { return true; } + /** + * Returns whether the autobuilder has seen code. + * This is overridden in tests. + */ + protected boolean hasSeenCode() { + return seenCode; + } + /** Perform extraction. */ public int run() throws IOException { startThreadPool(); try { extractSource(); extractXml(); - if (seenCode) { // don't bother with the externs if no code was seen + if (hasSeenCode()) { // don't bother with the externs if no code was seen extractExterns(); } } finally { shutdownThreadPool(); } - if (!seenCode) { + if (!hasSeenCode()) { if (seenFiles) { warn("Only found JavaScript or TypeScript files that were empty or contained syntax errors."); } else { diff --git a/javascript/extractor/src/com/semmle/js/extractor/test/AutoBuildTests.java b/javascript/extractor/src/com/semmle/js/extractor/test/AutoBuildTests.java index d472353067e..7c60a05d33f 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/test/AutoBuildTests.java +++ b/javascript/extractor/src/com/semmle/js/extractor/test/AutoBuildTests.java @@ -119,6 +119,11 @@ public class AutoBuildTests { return CompletableFuture.completedFuture(null); } + @Override + protected boolean hasSeenCode() { + return true; + } + @Override public void verifyTypeScriptInstallation(ExtractorState state) {} From c0085cbb1ab847423544b5ff50926a864c289fae Mon Sep 17 00:00:00 2001 From: Karim Ali Date: Tue, 29 Nov 2022 15:18:39 +0200 Subject: [PATCH 655/796] fix expected output for Taint.ql --- .../dataflow/taint/Taint.expected | 46 ++++++++++++++----- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/swift/ql/test/library-tests/dataflow/taint/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/Taint.expected index 7404255629f..8d054f430bb 100644 --- a/swift/ql/test/library-tests/dataflow/taint/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/Taint.expected @@ -1,4 +1,5 @@ edges +| data.swift:24:5:24:29 | [summary param] 0 in init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | | data.swift:25:2:25:66 | [summary param] 0 in init(base64Encoded:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | | data.swift:26:2:26:61 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | | data.swift:27:2:27:62 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | @@ -34,6 +35,14 @@ edges | data.swift:62:2:62:58 | [summary param] this in shuffled(using:) : | file://:0:0:0:0 | [summary] to write: return (return) in shuffled(using:) : | | data.swift:63:2:63:123 | [summary param] this in trimmingPrefix(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(_:) : | | data.swift:64:2:64:72 | [summary param] this in trimmingPrefix(while:) : | file://:0:0:0:0 | [summary] to write: return (return) in trimmingPrefix(while:) : | +| data.swift:81:20:81:51 | call to init(_:) : | data.swift:82:26:82:26 | dataTainted : | +| data.swift:81:20:81:51 | call to init(_:) : | data.swift:85:12:85:12 | dataTainted | +| data.swift:81:25:81:47 | .utf8 : | data.swift:24:5:24:29 | [summary param] 0 in init(_:) : | +| data.swift:81:25:81:47 | .utf8 : | data.swift:81:20:81:51 | call to init(_:) : | +| data.swift:81:26:81:33 | call to source() : | data.swift:81:25:81:47 | .utf8 : | +| data.swift:82:21:82:37 | call to init(_:) : | data.swift:86:12:86:12 | dataTainted2 | +| data.swift:82:26:82:26 | dataTainted : | data.swift:24:5:24:29 | [summary param] 0 in init(_:) : | +| data.swift:82:26:82:26 | dataTainted : | data.swift:82:21:82:37 | call to init(_:) : | | data.swift:89:21:89:71 | call to init(base64Encoded:options:) : | data.swift:90:12:90:12 | dataTainted3 | | data.swift:89:41:89:48 | call to source() : | data.swift:25:2:25:66 | [summary param] 0 in init(base64Encoded:options:) : | | data.swift:89:41:89:48 | call to source() : | data.swift:89:21:89:71 | call to init(base64Encoded:options:) : | @@ -303,9 +312,9 @@ edges | string.swift:28:17:28:25 | call to source2() : | string.swift:39:13:39:29 | ... .+(_:_:) ... | | string.swift:74:17:74:25 | call to source2() : | string.swift:85:13:85:21 | .description | | string.swift:74:17:74:25 | call to source2() : | string.swift:88:13:88:21 | .debugDescription | -| string.swift:97:17:97:25 | call to source2() : | string.swift:102:13:102:13 | tainted | -| string.swift:98:24:98:32 | call to source2() : | string.swift:103:13:103:13 | taintedCString | -| string.swift:99:31:99:39 | call to source2() : | string.swift:104:13:104:13 | taintedUnicodeScalars | +| string.swift:121:17:121:25 | call to source2() : | string.swift:126:13:126:13 | tainted | +| string.swift:122:24:122:32 | call to source2() : | string.swift:127:13:127:13 | taintedCString | +| string.swift:123:31:123:39 | call to source2() : | string.swift:128:13:128:13 | taintedUnicodeScalars | | subscript.swift:13:15:13:22 | call to source() : | subscript.swift:13:15:13:25 | ...[...] | | subscript.swift:14:15:14:23 | call to source2() : | subscript.swift:14:15:14:26 | ...[...] | | try.swift:9:17:9:24 | call to source() : | try.swift:9:13:9:24 | try ... | @@ -546,6 +555,7 @@ edges | webview.swift:137:34:137:41 | call to source() : | webview.swift:66:5:66:126 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:in:) : | | webview.swift:137:34:137:41 | call to source() : | webview.swift:137:13:137:113 | call to init(source:injectionTime:forMainFrameOnly:in:) : | nodes +| data.swift:24:5:24:29 | [summary param] 0 in init(_:) : | semmle.label | [summary param] 0 in init(_:) : | | data.swift:25:2:25:66 | [summary param] 0 in init(base64Encoded:options:) : | semmle.label | [summary param] 0 in init(base64Encoded:options:) : | | data.swift:26:2:26:61 | [summary param] 0 in init(buffer:) : | semmle.label | [summary param] 0 in init(buffer:) : | | data.swift:27:2:27:62 | [summary param] 0 in init(buffer:) : | semmle.label | [summary param] 0 in init(buffer:) : | @@ -581,6 +591,13 @@ nodes | data.swift:62:2:62:58 | [summary param] this in shuffled(using:) : | semmle.label | [summary param] this in shuffled(using:) : | | data.swift:63:2:63:123 | [summary param] this in trimmingPrefix(_:) : | semmle.label | [summary param] this in trimmingPrefix(_:) : | | data.swift:64:2:64:72 | [summary param] this in trimmingPrefix(while:) : | semmle.label | [summary param] this in trimmingPrefix(while:) : | +| data.swift:81:20:81:51 | call to init(_:) : | semmle.label | call to init(_:) : | +| data.swift:81:25:81:47 | .utf8 : | semmle.label | .utf8 : | +| data.swift:81:26:81:33 | call to source() : | semmle.label | call to source() : | +| data.swift:82:21:82:37 | call to init(_:) : | semmle.label | call to init(_:) : | +| data.swift:82:26:82:26 | dataTainted : | semmle.label | dataTainted : | +| data.swift:85:12:85:12 | dataTainted | semmle.label | dataTainted | +| data.swift:86:12:86:12 | dataTainted2 | semmle.label | dataTainted2 | | data.swift:89:21:89:71 | call to init(base64Encoded:options:) : | semmle.label | call to init(base64Encoded:options:) : | | data.swift:89:41:89:48 | call to source() : | semmle.label | call to source() : | | data.swift:90:12:90:12 | dataTainted3 | semmle.label | dataTainted3 | @@ -739,6 +756,7 @@ nodes | file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | semmle.label | [summary] to write: return (return) in flatMap(_:) : | | file://:0:0:0:0 | [summary] to write: return (return) in flatMap(_:) : | semmle.label | [summary] to write: return (return) in flatMap(_:) : | | file://:0:0:0:0 | [summary] to write: return (return) in forProperty(_:) : | semmle.label | [summary] to write: return (return) in forProperty(_:) : | +| file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | semmle.label | [summary] to write: return (return) in init(_:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | semmle.label | [summary] to write: return (return) in init(base64Encoded:options:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | semmle.label | [summary] to write: return (return) in init(base64Encoded:options:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | semmle.label | [summary] to write: return (return) in init(base64Encoded:options:) : | @@ -948,12 +966,12 @@ nodes | string.swift:74:17:74:25 | call to source2() : | semmle.label | call to source2() : | | string.swift:85:13:85:21 | .description | semmle.label | .description | | string.swift:88:13:88:21 | .debugDescription | semmle.label | .debugDescription | -| string.swift:97:17:97:25 | call to source2() : | semmle.label | call to source2() : | -| string.swift:98:24:98:32 | call to source2() : | semmle.label | call to source2() : | -| string.swift:99:31:99:39 | call to source2() : | semmle.label | call to source2() : | -| string.swift:102:13:102:13 | tainted | semmle.label | tainted | -| string.swift:103:13:103:13 | taintedCString | semmle.label | taintedCString | -| string.swift:104:13:104:13 | taintedUnicodeScalars | semmle.label | taintedUnicodeScalars | +| string.swift:121:17:121:25 | call to source2() : | semmle.label | call to source2() : | +| string.swift:122:24:122:32 | call to source2() : | semmle.label | call to source2() : | +| string.swift:123:31:123:39 | call to source2() : | semmle.label | call to source2() : | +| string.swift:126:13:126:13 | tainted | semmle.label | tainted | +| string.swift:127:13:127:13 | taintedCString | semmle.label | taintedCString | +| string.swift:128:13:128:13 | taintedUnicodeScalars | semmle.label | taintedUnicodeScalars | | subscript.swift:13:15:13:22 | call to source() : | semmle.label | call to source() : | | subscript.swift:13:15:13:25 | ...[...] | semmle.label | ...[...] | | subscript.swift:14:15:14:23 | call to source2() : | semmle.label | call to source2() : | @@ -1153,6 +1171,8 @@ nodes | webview.swift:138:10:138:10 | c | semmle.label | c | | webview.swift:139:10:139:12 | .source | semmle.label | .source | subpaths +| data.swift:81:25:81:47 | .utf8 : | data.swift:24:5:24:29 | [summary param] 0 in init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | data.swift:81:20:81:51 | call to init(_:) : | +| data.swift:82:26:82:26 | dataTainted : | data.swift:24:5:24:29 | [summary param] 0 in init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | data.swift:82:21:82:37 | call to init(_:) : | | data.swift:89:41:89:48 | call to source() : | data.swift:25:2:25:66 | [summary param] 0 in init(base64Encoded:options:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(base64Encoded:options:) : | data.swift:89:21:89:71 | call to init(base64Encoded:options:) : | | data.swift:93:34:93:41 | call to source() : | data.swift:26:2:26:61 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | data.swift:93:21:93:73 | call to init(buffer:) : | | data.swift:95:34:95:41 | call to source() : | data.swift:27:2:27:62 | [summary param] 0 in init(buffer:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(buffer:) : | data.swift:95:21:95:74 | call to init(buffer:) : | @@ -1274,6 +1294,8 @@ subpaths | webview.swift:132:34:132:41 | call to source() : | webview.swift:65:5:65:93 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:) : | webview.swift:132:13:132:102 | call to init(source:injectionTime:forMainFrameOnly:) : | | webview.swift:137:34:137:41 | call to source() : | webview.swift:66:5:66:126 | [summary param] 0 in init(source:injectionTime:forMainFrameOnly:in:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(source:injectionTime:forMainFrameOnly:in:) : | webview.swift:137:13:137:113 | call to init(source:injectionTime:forMainFrameOnly:in:) : | #select +| data.swift:85:12:85:12 | dataTainted | data.swift:81:26:81:33 | call to source() : | data.swift:85:12:85:12 | dataTainted | result | +| data.swift:86:12:86:12 | dataTainted2 | data.swift:81:26:81:33 | call to source() : | data.swift:86:12:86:12 | dataTainted2 | result | | data.swift:90:12:90:12 | dataTainted3 | data.swift:89:41:89:48 | call to source() : | data.swift:90:12:90:12 | dataTainted3 | result | | data.swift:94:12:94:12 | dataTainted4 | data.swift:93:34:93:41 | call to source() : | data.swift:94:12:94:12 | dataTainted4 | result | | data.swift:96:12:96:12 | dataTainted5 | data.swift:95:34:95:41 | call to source() : | data.swift:96:12:96:12 | dataTainted5 | result | @@ -1356,9 +1378,9 @@ subpaths | string.swift:39:13:39:29 | ... .+(_:_:) ... | string.swift:28:17:28:25 | call to source2() : | string.swift:39:13:39:29 | ... .+(_:_:) ... | result | | string.swift:85:13:85:21 | .description | string.swift:74:17:74:25 | call to source2() : | string.swift:85:13:85:21 | .description | result | | string.swift:88:13:88:21 | .debugDescription | string.swift:74:17:74:25 | call to source2() : | string.swift:88:13:88:21 | .debugDescription | result | -| string.swift:102:13:102:13 | tainted | string.swift:97:17:97:25 | call to source2() : | string.swift:102:13:102:13 | tainted | result | -| string.swift:103:13:103:13 | taintedCString | string.swift:98:24:98:32 | call to source2() : | string.swift:103:13:103:13 | taintedCString | result | -| string.swift:104:13:104:13 | taintedUnicodeScalars | string.swift:99:31:99:39 | call to source2() : | string.swift:104:13:104:13 | taintedUnicodeScalars | result | +| string.swift:126:13:126:13 | tainted | string.swift:121:17:121:25 | call to source2() : | string.swift:126:13:126:13 | tainted | result | +| string.swift:127:13:127:13 | taintedCString | string.swift:122:24:122:32 | call to source2() : | string.swift:127:13:127:13 | taintedCString | result | +| string.swift:128:13:128:13 | taintedUnicodeScalars | string.swift:123:31:123:39 | call to source2() : | string.swift:128:13:128:13 | taintedUnicodeScalars | result | | subscript.swift:13:15:13:25 | ...[...] | subscript.swift:13:15:13:22 | call to source() : | subscript.swift:13:15:13:25 | ...[...] | result | | subscript.swift:14:15:14:26 | ...[...] | subscript.swift:14:15:14:23 | call to source2() : | subscript.swift:14:15:14:26 | ...[...] | result | | try.swift:9:13:9:24 | try ... | try.swift:9:17:9:24 | call to source() : | try.swift:9:13:9:24 | try ... | result | From 9d17fae00cdfdfb47043dd26596139d8762b6cc7 Mon Sep 17 00:00:00 2001 From: Karim Ali Date: Tue, 29 Nov 2022 15:24:12 +0200 Subject: [PATCH 656/796] fix expected output for TaintInline --- swift/ql/test/library-tests/dataflow/taint/TaintInline.expected | 2 ++ 1 file changed, 2 insertions(+) diff --git a/swift/ql/test/library-tests/dataflow/taint/TaintInline.expected b/swift/ql/test/library-tests/dataflow/taint/TaintInline.expected index e69de29bb2d..3e49fbfe3af 100644 --- a/swift/ql/test/library-tests/dataflow/taint/TaintInline.expected +++ b/swift/ql/test/library-tests/dataflow/taint/TaintInline.expected @@ -0,0 +1,2 @@ +| data.swift:85:12:85:12 | dataTainted | Fixed missing result:tainted=81 | +| data.swift:86:12:86:12 | dataTainted2 | Fixed missing result:tainted=81 | \ No newline at end of file From 9048d5d79b04846b3afdbf6c14258dcb490a99e8 Mon Sep 17 00:00:00 2001 From: Karim Ali Date: Tue, 29 Nov 2022 15:38:44 +0200 Subject: [PATCH 657/796] fix expected output for LocalTaint --- .../dataflow/taint/LocalTaint.expected | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected index 60dde1510ef..1e3d799cd58 100644 --- a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected @@ -120,11 +120,13 @@ | data.swift:80:6:80:6 | SSA def(dataClean) | data.swift:84:12:84:12 | dataClean | | data.swift:80:18:80:18 | Data.Type | data.swift:80:18:80:18 | call to init(_:) | | data.swift:80:18:80:36 | call to init(_:) | data.swift:80:6:80:6 | SSA def(dataClean) | +| data.swift:80:23:80:23 | 123456 | data.swift:80:23:80:32 | .utf8 | | data.swift:80:23:80:32 | .utf8 | data.swift:80:18:80:36 | call to init(_:) | | data.swift:81:6:81:6 | SSA def(dataTainted) | data.swift:82:26:82:26 | dataTainted | | data.swift:81:20:81:20 | Data.Type | data.swift:81:20:81:20 | call to init(_:) | | data.swift:81:20:81:51 | call to init(_:) | data.swift:81:6:81:6 | SSA def(dataTainted) | | data.swift:81:25:81:47 | .utf8 | data.swift:81:20:81:51 | call to init(_:) | +| data.swift:81:26:81:33 | call to source() | data.swift:81:25:81:47 | .utf8 | | data.swift:82:6:82:6 | SSA def(dataTainted2) | data.swift:86:12:86:12 | dataTainted2 | | data.swift:82:21:82:21 | Data.Type | data.swift:82:21:82:21 | call to init(_:) | | data.swift:82:21:82:37 | call to init(_:) | data.swift:82:6:82:6 | SSA def(dataTainted2) | @@ -600,8 +602,6 @@ | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 | nsmutabledata.swift:49:15:49:37 | .mutableBytes | | string.swift:5:7:5:7 | SSA def(x) | string.swift:7:16:7:16 | x | | string.swift:5:11:5:18 | call to source() | string.swift:5:7:5:7 | SSA def(x) | -| data.swift:20:23:20:23 | 123456 | data.swift:20:23:20:32 | .utf8 | -| data.swift:21:25:21:32 | call to source() | data.swift:21:25:21:34 | .utf8 | | string.swift:7:13:7:13 | | string.swift:7:13:7:13 | [post] | | string.swift:7:13:7:13 | | string.swift:7:14:7:14 | [post] &... | | string.swift:7:13:7:13 | SSA def($interpolation) | string.swift:7:14:7:14 | SSA phi($interpolation) | @@ -900,9 +900,13 @@ | string.swift:81:31:81:31 | clean | string.swift:84:13:84:13 | clean | | string.swift:82:31:82:31 | tainted | string.swift:85:13:85:13 | tainted | | string.swift:84:13:84:13 | [post] clean | string.swift:87:13:87:13 | clean | +| string.swift:84:13:84:13 | clean | string.swift:84:13:84:19 | .description | | string.swift:84:13:84:13 | clean | string.swift:87:13:87:13 | clean | | string.swift:85:13:85:13 | [post] tainted | string.swift:88:13:88:13 | tainted | +| string.swift:85:13:85:13 | tainted | string.swift:85:13:85:21 | .description | | string.swift:85:13:85:13 | tainted | string.swift:88:13:88:13 | tainted | +| string.swift:87:13:87:13 | clean | string.swift:87:13:87:19 | .debugDescription | +| string.swift:88:13:88:13 | tainted | string.swift:88:13:88:21 | .debugDescription | | string.swift:91:7:91:7 | SSA def(self) | string.swift:91:7:91:7 | self[return] | | string.swift:91:7:91:7 | self | string.swift:91:7:91:7 | SSA def(self) | | string.swift:93:5:93:5 | SSA def(self) | string.swift:93:5:93:29 | self[return] | @@ -925,6 +929,17 @@ | string.swift:109:23:109:77 | call to init(data:encoding:) | string.swift:109:7:109:7 | SSA def(stringTainted) | | string.swift:111:12:111:12 | stringClean | string.swift:111:12:111:23 | ...! | | string.swift:112:12:112:12 | stringTainted | string.swift:112:12:112:25 | ...! | +| string.swift:120:7:120:7 | SSA def(clean) | string.swift:125:13:125:13 | clean | +| string.swift:120:15:120:15 | | string.swift:120:7:120:7 | SSA def(clean) | +| string.swift:121:7:121:7 | SSA def(tainted) | string.swift:126:13:126:13 | tainted | +| string.swift:121:17:121:25 | call to source2() | string.swift:121:17:121:27 | .utf8 | +| string.swift:121:17:121:27 | .utf8 | string.swift:121:7:121:7 | SSA def(tainted) | +| string.swift:122:7:122:7 | SSA def(taintedCString) | string.swift:127:13:127:13 | taintedCString | +| string.swift:122:24:122:32 | call to source2() | string.swift:122:24:122:34 | .utf8CString | +| string.swift:122:24:122:34 | .utf8CString | string.swift:122:7:122:7 | SSA def(taintedCString) | +| string.swift:123:7:123:7 | SSA def(taintedUnicodeScalars) | string.swift:128:13:128:13 | taintedUnicodeScalars | +| string.swift:123:31:123:39 | call to source2() | string.swift:123:31:123:41 | .unicodeScalars | +| string.swift:123:31:123:41 | .unicodeScalars | string.swift:123:7:123:7 | SSA def(taintedUnicodeScalars) | | subscript.swift:1:7:1:7 | SSA def(self) | subscript.swift:1:7:1:7 | self[return] | | subscript.swift:1:7:1:7 | SSA def(self) | subscript.swift:1:7:1:7 | self[return] | | subscript.swift:1:7:1:7 | self | subscript.swift:1:7:1:7 | SSA def(self) | @@ -934,13 +949,6 @@ | subscript.swift:3:9:3:9 | self | subscript.swift:3:9:3:9 | SSA def(self) | | subscript.swift:4:9:4:9 | SSA def(self) | subscript.swift:4:9:4:24 | self[return] | | subscript.swift:4:9:4:9 | self | subscript.swift:4:9:4:9 | SSA def(self) | -| string.swift:84:13:84:13 | clean | string.swift:84:13:84:19 | .description | -| string.swift:85:13:85:13 | tainted | string.swift:85:13:85:21 | .description | -| string.swift:87:13:87:13 | clean | string.swift:87:13:87:19 | .debugDescription | -| string.swift:88:13:88:13 | tainted | string.swift:88:13:88:21 | .debugDescription | -| string.swift:97:17:97:25 | call to source2() | string.swift:97:17:97:27 | .utf8 | -| string.swift:98:24:98:32 | call to source2() | string.swift:98:24:98:34 | .utf8CString | -| string.swift:99:31:99:39 | call to source2() | string.swift:99:31:99:41 | .unicodeScalars | | subscript.swift:13:15:13:22 | call to source() | subscript.swift:13:15:13:25 | ...[...] | | subscript.swift:14:15:14:23 | call to source2() | subscript.swift:14:15:14:26 | ...[...] | | try.swift:8:17:8:23 | call to clean() | try.swift:8:13:8:23 | try ... | From e5f1fe86e4c622c87969e670292a5b83db40ff79 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 29 Nov 2022 15:02:08 +0100 Subject: [PATCH 658/796] don't crash on non-existing cache in swift --- swift/actions/build-and-test/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swift/actions/build-and-test/action.yml b/swift/actions/build-and-test/action.yml index 03706263d21..52a6415fedf 100644 --- a/swift/actions/build-and-test/action.yml +++ b/swift/actions/build-and-test/action.yml @@ -50,5 +50,5 @@ runs: if: ${{ github.event_name != 'pull_request' }} shell: bash run: | - find "~/.cache/bazel-repository-cache" "~/.cache/bazel-disk-cache" -atime +0 -type f -delete - du -sh "~/.cache/bazel-repository-cache" "~/.cache/bazel-disk-cache" + find "~/.cache/bazel-repository-cache" "~/.cache/bazel-disk-cache" -atime +0 -type f -delete || : # ignore errors if the cache is empty + du -sh "~/.cache/bazel-repository-cache" "~/.cache/bazel-disk-cache" || : # ignore errors if the cache is empty From d7aea228ce114ab7ae37574f390ded4232d90246 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 29 Nov 2022 15:10:09 +0100 Subject: [PATCH 659/796] Python: Add taint-sinks meta query Inspired by the one they have in JS: https://github.com/github/codeql/blob/097d5189e9bbaecfd0e239e5198ac8e8ac14f2f6/javascript/ql/src/meta/alerts/TaintSinks.ql --- python/ql/src/meta/alerts/TaintSinks.ql | 87 +++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 python/ql/src/meta/alerts/TaintSinks.ql diff --git a/python/ql/src/meta/alerts/TaintSinks.ql b/python/ql/src/meta/alerts/TaintSinks.ql new file mode 100644 index 00000000000..634ef18f129 --- /dev/null +++ b/python/ql/src/meta/alerts/TaintSinks.ql @@ -0,0 +1,87 @@ +/** + * @name Taint sinks + * @description Sinks from TaintTracking queries. + * @kind problem + * @problem.severity recommendation + * @id py/meta/alerts/taint-sinks + * @tags meta + * @precision very-low + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import meta.MetaMetrics +import semmle.python.security.dataflow.CleartextLoggingCustomizations +import semmle.python.security.dataflow.CleartextStorageCustomizations +import semmle.python.security.dataflow.CodeInjectionCustomizations +import semmle.python.security.dataflow.CommandInjectionCustomizations +import semmle.python.security.dataflow.LdapInjectionCustomizations +import semmle.python.security.dataflow.LogInjectionCustomizations +import semmle.python.security.dataflow.PathInjectionCustomizations +import semmle.python.security.dataflow.PolynomialReDoSCustomizations +import semmle.python.security.dataflow.ReflectedXSSCustomizations +import semmle.python.security.dataflow.RegexInjectionCustomizations +import semmle.python.security.dataflow.ServerSideRequestForgeryCustomizations +import semmle.python.security.dataflow.SqlInjectionCustomizations +import semmle.python.security.dataflow.StackTraceExposureCustomizations +import semmle.python.security.dataflow.TarSlipCustomizations +import semmle.python.security.dataflow.UnsafeDeserializationCustomizations +import semmle.python.security.dataflow.UrlRedirectCustomizations +import semmle.python.security.dataflow.WeakSensitiveDataHashingCustomizations +import semmle.python.security.dataflow.XmlBombCustomizations +import semmle.python.security.dataflow.XpathInjectionCustomizations +import semmle.python.security.dataflow.XxeCustomizations + +DataFlow::Node relevantTaintSink(string kind) { + not result.getLocation().getFile() instanceof IgnoredFile and + ( + kind = "CleartextLogging" and result instanceof CleartextLogging::Sink + or + kind = "CleartextStorage" and result instanceof CleartextStorage::Sink + or + kind = "CodeInjection" and result instanceof CodeInjection::Sink + or + kind = "CommandInjection" and result instanceof CommandInjection::Sink + or + kind = "LdapInjection (DN)" and result instanceof LdapInjection::DnSink + or + kind = "LdapInjection (Filter)" and result instanceof LdapInjection::FilterSink + or + kind = "LogInjection" and result instanceof LogInjection::Sink + or + kind = "PathInjection" and result instanceof PathInjection::Sink + or + kind = "PolynomialReDoS" and result instanceof PolynomialReDoS::Sink + or + kind = "ReflectedXss" and result instanceof ReflectedXss::Sink + or + kind = "RegexInjection" and result instanceof RegexInjection::Sink + or + kind = "ServerSideRequestForgery" and result instanceof ServerSideRequestForgery::Sink + or + kind = "SqlInjection" and result instanceof SqlInjection::Sink + or + kind = "StackTraceExposure" and result instanceof StackTraceExposure::Sink + or + kind = "TarSlip" and result instanceof TarSlip::Sink + or + kind = "UnsafeDeserialization" and result instanceof UnsafeDeserialization::Sink + or + kind = "UrlRedirect" and result instanceof UrlRedirect::Sink + or + kind = "WeakSensitiveDataHashing (NormalHashFunction)" and + result instanceof NormalHashFunction::Sink + or + kind = "WeakSensitiveDataHashing (ComputationallyExpensiveHashFunction)" and + result instanceof ComputationallyExpensiveHashFunction::Sink + or + kind = "XmlBomb" and result instanceof XmlBomb::Sink + or + kind = "XpathInjection" and result instanceof XpathInjection::Sink + or + kind = "Xxe" and result instanceof Xxe::Sink + ) +} + +from string kind +select relevantTaintSink(kind), kind + " sink" From 607639c100e5f651d9f8abdfd631835f3c305ef8 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 29 Nov 2022 15:10:45 +0100 Subject: [PATCH 660/796] Python: restrict `py/meta/points-to-call-graph` to non-ignored files --- python/ql/src/meta/analysis-quality/CallGraph.ql | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/python/ql/src/meta/analysis-quality/CallGraph.ql b/python/ql/src/meta/analysis-quality/CallGraph.ql index d23ee43014c..49be0157b05 100644 --- a/python/ql/src/meta/analysis-quality/CallGraph.ql +++ b/python/ql/src/meta/analysis-quality/CallGraph.ql @@ -10,7 +10,11 @@ import python import semmle.python.dataflow.new.internal.DataFlowPrivate +import meta.MetaMetrics from DataFlowCall c, DataFlowCallableValue f -where c.getCallable() = f +where + c.getCallable() = f and + not c.getLocation().getFile() instanceof IgnoredFile and + not f.getLocation().getFile() instanceof IgnoredFile select c, "Call to $@", f.getScope(), f.toString() From c5b4e87f6ddb3913e6a786c38d0149459c272c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Tue, 29 Nov 2022 16:00:00 +0100 Subject: [PATCH 661/796] Swift: AccessorDecl tests for new cases --- .../swift/elements/decl/AccessorDecl.qll | 8 +++++++ .../decl/AccessorDecl/AccessorDecl.expected | 23 +++++++++++++------ .../AccessorDecl_getBody.expected | 23 +++++++++++++------ .../AccessorDecl_getParam.expected | 2 ++ .../AccessorDecl_getSelfParam.expected | 23 +++++++++++++------ .../decl/AccessorDecl/accessors.swift | 18 +++++++++++++++ 6 files changed, 76 insertions(+), 21 deletions(-) diff --git a/swift/ql/lib/codeql/swift/elements/decl/AccessorDecl.qll b/swift/ql/lib/codeql/swift/elements/decl/AccessorDecl.qll index da91edb6810..4879a1e47fd 100644 --- a/swift/ql/lib/codeql/swift/elements/decl/AccessorDecl.qll +++ b/swift/ql/lib/codeql/swift/elements/decl/AccessorDecl.qll @@ -8,6 +8,14 @@ private predicate isKnownAccessorKind(AccessorDecl decl, string kind) { decl.isWillSet() and kind = "willSet" or decl.isDidSet() and kind = "didSet" + or + decl.isRead() and kind = "_read" + or + decl.isModify() and kind = "_modify" + or + decl.isUnsafeAddress() and kind = "unsafeAddress" + or + decl.isUnsafeMutableAddress() and kind = "unsafeMutableAddress" } class AccessorDecl extends Generated::AccessorDecl { diff --git a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.expected b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.expected index 9927e4ef93b..a93757f0e0c 100644 --- a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.expected +++ b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.expected @@ -1,27 +1,36 @@ -| accessors.swift:2:9:2:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:2:9:2:9 | _modify | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:2:9:2:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:2:9:2:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | -| accessors.swift:3:9:3:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:3:9:3:9 | _modify | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:4:9:4:28 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:5:9:5:42 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | -| accessors.swift:7:9:7:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:7:9:7:9 | _modify | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:7:9:7:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:7:9:7:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:8:9:8:29 | willSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | yes | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | -| accessors.swift:11:9:11:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:11:9:11:9 | _modify | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:11:9:11:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:11:9:11:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:12:9:12:19 | willSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | yes | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | -| accessors.swift:15:9:15:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:15:9:15:9 | _modify | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:15:9:15:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:15:9:15:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:16:9:16:28 | didSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | yes | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | -| accessors.swift:19:9:19:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:19:9:19:9 | _modify | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:19:9:19:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:19:9:19:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:20:9:20:18 | didSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | yes | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | -| accessors.swift:23:9:23:9 | (unnamed function decl) | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:23:9:23:9 | _modify | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:23:9:23:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:23:9:23:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:24:9:24:19 | willSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | yes | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | | accessors.swift:26:9:26:18 | didSet | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | yes | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:29:9:29:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:29:9:29:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:30:9:32:9 | _read | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | yes | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:33:9:35:9 | _modify | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:38:9:38:9 | _modify | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | yes | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:38:9:38:9 | get | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> Int | getName: | (unnamed function decl) | isGetter: | yes | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:38:9:38:9 | set | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> (Int) -> () | getName: | (unnamed function decl) | isGetter: | no | isSetter: | yes | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | no | +| accessors.swift:39:9:41:9 | unsafeAddress | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (Foo) -> () -> UnsafePointer | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | yes | isUnsafeMutableAddress: | no | +| accessors.swift:42:9:44:9 | unsafeMutableAddress | getModule: | file://:0:0:0:0 | accessors | getInterfaceType: | (inout Foo) -> () -> UnsafeMutablePointer | getName: | (unnamed function decl) | isGetter: | no | isSetter: | no | isWillSet: | no | isDidSet: | no | isRead: | no | isModify: | no | isUnsafeAddress: | no | isUnsafeMutableAddress: | yes | diff --git a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getBody.expected b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getBody.expected index 918643d76dd..7eccbae719f 100644 --- a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getBody.expected +++ b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getBody.expected @@ -1,27 +1,36 @@ -| accessors.swift:2:9:2:9 | (unnamed function decl) | accessors.swift:2:9:2:9 | { ... } | +| accessors.swift:2:9:2:9 | _modify | accessors.swift:2:9:2:9 | { ... } | | accessors.swift:2:9:2:9 | get | accessors.swift:2:9:2:9 | { ... } | | accessors.swift:2:9:2:9 | set | accessors.swift:2:9:2:9 | { ... } | -| accessors.swift:3:9:3:9 | (unnamed function decl) | accessors.swift:3:9:3:9 | { ... } | +| accessors.swift:3:9:3:9 | _modify | accessors.swift:3:9:3:9 | { ... } | | accessors.swift:4:9:4:28 | get | accessors.swift:4:13:4:28 | { ... } | | accessors.swift:5:9:5:42 | set | accessors.swift:5:23:5:42 | { ... } | -| accessors.swift:7:9:7:9 | (unnamed function decl) | accessors.swift:7:9:7:9 | { ... } | +| accessors.swift:7:9:7:9 | _modify | accessors.swift:7:9:7:9 | { ... } | | accessors.swift:7:9:7:9 | get | accessors.swift:7:9:7:9 | { ... } | | accessors.swift:7:9:7:9 | set | accessors.swift:7:9:7:9 | { ... } | | accessors.swift:8:9:8:29 | willSet | accessors.swift:8:27:8:29 | { ... } | -| accessors.swift:11:9:11:9 | (unnamed function decl) | accessors.swift:11:9:11:9 | { ... } | +| accessors.swift:11:9:11:9 | _modify | accessors.swift:11:9:11:9 | { ... } | | accessors.swift:11:9:11:9 | get | accessors.swift:11:9:11:9 | { ... } | | accessors.swift:11:9:11:9 | set | accessors.swift:11:9:11:9 | { ... } | | accessors.swift:12:9:12:19 | willSet | accessors.swift:12:17:12:19 | { ... } | -| accessors.swift:15:9:15:9 | (unnamed function decl) | accessors.swift:15:9:15:9 | { ... } | +| accessors.swift:15:9:15:9 | _modify | accessors.swift:15:9:15:9 | { ... } | | accessors.swift:15:9:15:9 | get | accessors.swift:15:9:15:9 | { ... } | | accessors.swift:15:9:15:9 | set | accessors.swift:15:9:15:9 | { ... } | | accessors.swift:16:9:16:28 | didSet | accessors.swift:16:26:16:28 | { ... } | -| accessors.swift:19:9:19:9 | (unnamed function decl) | accessors.swift:19:9:19:9 | { ... } | +| accessors.swift:19:9:19:9 | _modify | accessors.swift:19:9:19:9 | { ... } | | accessors.swift:19:9:19:9 | get | accessors.swift:19:9:19:9 | { ... } | | accessors.swift:19:9:19:9 | set | accessors.swift:19:9:19:9 | { ... } | | accessors.swift:20:9:20:18 | didSet | accessors.swift:20:16:20:18 | { ... } | -| accessors.swift:23:9:23:9 | (unnamed function decl) | accessors.swift:23:9:23:9 | { ... } | +| accessors.swift:23:9:23:9 | _modify | accessors.swift:23:9:23:9 | { ... } | | accessors.swift:23:9:23:9 | get | accessors.swift:23:9:23:9 | { ... } | | accessors.swift:23:9:23:9 | set | accessors.swift:23:9:23:9 | { ... } | | accessors.swift:24:9:24:19 | willSet | accessors.swift:24:17:24:19 | { ... } | | accessors.swift:26:9:26:18 | didSet | accessors.swift:26:16:26:18 | { ... } | +| accessors.swift:29:9:29:9 | get | accessors.swift:29:9:29:9 | { ... } | +| accessors.swift:29:9:29:9 | set | accessors.swift:29:9:29:9 | { ... } | +| accessors.swift:30:9:32:9 | _read | accessors.swift:30:15:32:9 | { ... } | +| accessors.swift:33:9:35:9 | _modify | accessors.swift:33:17:35:9 | { ... } | +| accessors.swift:38:9:38:9 | _modify | accessors.swift:38:9:38:9 | { ... } | +| accessors.swift:38:9:38:9 | get | accessors.swift:38:9:38:9 | { ... } | +| accessors.swift:38:9:38:9 | set | accessors.swift:38:9:38:9 | { ... } | +| accessors.swift:39:9:41:9 | unsafeAddress | accessors.swift:39:23:41:9 | { ... } | +| accessors.swift:42:9:44:9 | unsafeMutableAddress | accessors.swift:42:30:44:9 | { ... } | diff --git a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getParam.expected b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getParam.expected index 8b0da467bb2..e0544b5d4f5 100644 --- a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getParam.expected +++ b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getParam.expected @@ -9,3 +9,5 @@ | accessors.swift:19:9:19:9 | set | 0 | accessors.swift:19:9:19:9 | value | | accessors.swift:23:9:23:9 | set | 0 | accessors.swift:23:9:23:9 | value | | accessors.swift:24:9:24:19 | willSet | 0 | accessors.swift:24:9:24:9 | newValue | +| accessors.swift:29:9:29:9 | set | 0 | accessors.swift:29:9:29:9 | value | +| accessors.swift:38:9:38:9 | set | 0 | accessors.swift:38:9:38:9 | value | diff --git a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getSelfParam.expected b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getSelfParam.expected index 22d0fc5df1f..62143cca406 100644 --- a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getSelfParam.expected +++ b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getSelfParam.expected @@ -1,27 +1,36 @@ -| accessors.swift:2:9:2:9 | (unnamed function decl) | accessors.swift:2:9:2:9 | self | +| accessors.swift:2:9:2:9 | _modify | accessors.swift:2:9:2:9 | self | | accessors.swift:2:9:2:9 | get | accessors.swift:2:9:2:9 | self | | accessors.swift:2:9:2:9 | set | accessors.swift:2:9:2:9 | self | -| accessors.swift:3:9:3:9 | (unnamed function decl) | accessors.swift:3:9:3:9 | self | +| accessors.swift:3:9:3:9 | _modify | accessors.swift:3:9:3:9 | self | | accessors.swift:4:9:4:28 | get | accessors.swift:4:9:4:9 | self | | accessors.swift:5:9:5:42 | set | accessors.swift:5:9:5:9 | self | -| accessors.swift:7:9:7:9 | (unnamed function decl) | accessors.swift:7:9:7:9 | self | +| accessors.swift:7:9:7:9 | _modify | accessors.swift:7:9:7:9 | self | | accessors.swift:7:9:7:9 | get | accessors.swift:7:9:7:9 | self | | accessors.swift:7:9:7:9 | set | accessors.swift:7:9:7:9 | self | | accessors.swift:8:9:8:29 | willSet | accessors.swift:8:9:8:9 | self | -| accessors.swift:11:9:11:9 | (unnamed function decl) | accessors.swift:11:9:11:9 | self | +| accessors.swift:11:9:11:9 | _modify | accessors.swift:11:9:11:9 | self | | accessors.swift:11:9:11:9 | get | accessors.swift:11:9:11:9 | self | | accessors.swift:11:9:11:9 | set | accessors.swift:11:9:11:9 | self | | accessors.swift:12:9:12:19 | willSet | accessors.swift:12:9:12:9 | self | -| accessors.swift:15:9:15:9 | (unnamed function decl) | accessors.swift:15:9:15:9 | self | +| accessors.swift:15:9:15:9 | _modify | accessors.swift:15:9:15:9 | self | | accessors.swift:15:9:15:9 | get | accessors.swift:15:9:15:9 | self | | accessors.swift:15:9:15:9 | set | accessors.swift:15:9:15:9 | self | | accessors.swift:16:9:16:28 | didSet | accessors.swift:16:9:16:9 | self | -| accessors.swift:19:9:19:9 | (unnamed function decl) | accessors.swift:19:9:19:9 | self | +| accessors.swift:19:9:19:9 | _modify | accessors.swift:19:9:19:9 | self | | accessors.swift:19:9:19:9 | get | accessors.swift:19:9:19:9 | self | | accessors.swift:19:9:19:9 | set | accessors.swift:19:9:19:9 | self | | accessors.swift:20:9:20:18 | didSet | accessors.swift:20:9:20:9 | self | -| accessors.swift:23:9:23:9 | (unnamed function decl) | accessors.swift:23:9:23:9 | self | +| accessors.swift:23:9:23:9 | _modify | accessors.swift:23:9:23:9 | self | | accessors.swift:23:9:23:9 | get | accessors.swift:23:9:23:9 | self | | accessors.swift:23:9:23:9 | set | accessors.swift:23:9:23:9 | self | | accessors.swift:24:9:24:19 | willSet | accessors.swift:24:9:24:9 | self | | accessors.swift:26:9:26:18 | didSet | accessors.swift:26:9:26:9 | self | +| accessors.swift:29:9:29:9 | get | accessors.swift:29:9:29:9 | self | +| accessors.swift:29:9:29:9 | set | accessors.swift:29:9:29:9 | self | +| accessors.swift:30:9:32:9 | _read | accessors.swift:30:9:30:9 | self | +| accessors.swift:33:9:35:9 | _modify | accessors.swift:33:9:33:9 | self | +| accessors.swift:38:9:38:9 | _modify | accessors.swift:38:9:38:9 | self | +| accessors.swift:38:9:38:9 | get | accessors.swift:38:9:38:9 | self | +| accessors.swift:38:9:38:9 | set | accessors.swift:38:9:38:9 | self | +| accessors.swift:39:9:41:9 | unsafeAddress | accessors.swift:39:9:39:9 | self | +| accessors.swift:42:9:44:9 | unsafeMutableAddress | accessors.swift:42:9:42:9 | self | diff --git a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/accessors.swift b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/accessors.swift index 0dc6f4cc0c0..2f645a1592e 100644 --- a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/accessors.swift +++ b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/accessors.swift @@ -25,4 +25,22 @@ struct Foo { didSet { } } + + var borrowedProp: Int { + _read { + yield x + } + _modify { + yield &x + } + } + + var unsafeProp: Int { + unsafeAddress { + return UnsafePointer(bitPattern: 0)! + } + unsafeMutableAddress { + return UnsafeMutablePointer(bitPattern: 0)! + } + } } From 20b9c60d5864f61f810d13598640421b69de7917 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 22 Nov 2022 07:36:07 +0000 Subject: [PATCH 662/796] Remove DataFlowImplConsistency.qll from makefile --- go/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/Makefile b/go/Makefile index 7e691d48803..47f4cc0f801 100644 --- a/go/Makefile +++ b/go/Makefile @@ -135,7 +135,7 @@ build/testdb/go.dbscheme: ql/lib/upgrades/initial/go.dbscheme .PHONY: sync-dataflow-libraries sync-dataflow-libraries: - for f in DataFlowImpl.qll DataFlowImpl2.qll DataFlowImplCommon.qll DataFlowImplConsistency.qll tainttracking1/TaintTrackingImpl.qll tainttracking2/TaintTrackingImpl.qll FlowSummaryImpl.qll AccessPathSyntax.qll;\ + for f in DataFlowImpl.qll DataFlowImpl2.qll DataFlowImplCommon.qll tainttracking1/TaintTrackingImpl.qll tainttracking2/TaintTrackingImpl.qll FlowSummaryImpl.qll AccessPathSyntax.qll;\ do\ curl -s -o ./ql/lib/semmle/go/dataflow/internal/$$f https://raw.githubusercontent.com/github/codeql/$(DATAFLOW_BRANCH)/java/ql/lib/semmle/code/java/dataflow/internal/$$f;\ done From ae408290dd36c98e4b3aa80894834668405f2454 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 17 Nov 2022 16:48:26 +0000 Subject: [PATCH 663/796] Update shared library files for go to PR #9823 Merge commit: aa36556 --- .../go/dataflow/internal/DataFlowImpl.qll | 2507 +++++------------ .../go/dataflow/internal/DataFlowImpl2.qll | 2507 +++++------------ 2 files changed, 1536 insertions(+), 3478 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index a076f7a2e45..340bfe280b7 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -597,7 +597,7 @@ private predicate hasSinkCallCtx(Configuration config) { ) } -private module Stage1 { +private module Stage1 implements StageSig { class ApApprox = Unit; class Ap = Unit; @@ -944,12 +944,9 @@ private module Stage1 { predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } bindingset[node, state, config] - predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - revFlow(node, toReturn, pragma[only_bind_into](config)) and + predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { + revFlow(node, _, pragma[only_bind_into](config)) and exists(state) and - exists(returnAp) and exists(ap) } @@ -1142,66 +1139,754 @@ private predicate flowIntoCallNodeCand1( ) } -private module Stage2 { - module PrevStage = Stage1; +private signature module StageSig { + class Ap; + predicate revFlow(NodeEx node, Configuration config); + + bindingset[node, state, config] + predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); + + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); + + predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + + predicate storeStepCand( + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, + Configuration config + ); + + predicate readStepCand(NodeEx n1, Content c, NodeEx n2, Configuration config); +} + +private module MkStage { class ApApprox = PrevStage::Ap; - class Ap = boolean; + signature module StageParam { + class Ap; - class ApNil extends Ap { - ApNil() { this = false } + class ApNil extends Ap; + + bindingset[result, ap] + ApApprox getApprox(Ap ap); + + ApNil getApNil(NodeEx node); + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail); + + Content getHeadContent(Ap ap); + + class ApOption; + + ApOption apNone(); + + ApOption apSome(Ap ap); + + class Cc; + + class CcCall extends Cc; + + // TODO: member predicate on CcCall + predicate matchesCall(CcCall cc, DataFlowCall call); + + class CcNoCall extends Cc; + + Cc ccNone(); + + CcCall ccSomeCall(); + + class LocalCc; + + bindingset[call, c, outercc] + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc); + + bindingset[call, c, innercc] + CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc); + + bindingset[node, cc] + LocalCc getLocalCc(NodeEx node, Cc cc); + + bindingset[node1, state1, config] + bindingset[node2, state2, config] + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApNil ap, Configuration config, LocalCc lcc + ); + + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + ); + + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + ); + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config); + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType); } - bindingset[result, ap] - private ApApprox getApprox(Ap ap) { any() } + module Stage implements StageSig { + import Param - private ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and exists(result) } + /* Begin: Stage logic. */ + bindingset[result, apa] + private ApApprox unbindApa(ApApprox apa) { + pragma[only_bind_out](apa) = pragma[only_bind_out](result) + } - bindingset[tc, tail] - private Ap apCons(TypedContent tc, Ap tail) { result = true and exists(tc) and exists(tail) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, + pragma[only_bind_into](config)) and + matchesCall(ccc, call) + } - pragma[inline] - private Content getHeadContent(Ap ap) { exists(result) and ap = true } + /** + * Holds if `node` is reachable with access path `ap` from a source in the + * configuration `config`. + * + * The call context `cc` records whether the node is reached through an + * argument in a call, and if so, `argAp` records the access path of that + * argument. + */ + pragma[nomagic] + predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + ) { + fwdFlow0(node, state, cc, argAp, ap, config) and + PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + filter(node, state, ap, config) + } - class ApOption = BooleanOption; + pragma[nomagic] + private predicate fwdFlow0( + NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + ) { + sourceNode(node, state, config) and + (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and + argAp = apNone() and + ap = getApNil(node) + or + exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | + fwdFlow(mid, state0, cc, argAp, ap0, config) and + localCc = getLocalCc(mid, cc) + | + localStep(mid, state0, node, state, true, _, config, localCc) and + ap = ap0 + or + localStep(mid, state0, node, state, false, ap, config, localCc) and + ap0 instanceof ApNil + ) + or + exists(NodeEx mid | + fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + jumpStep(mid, node, config) and + cc = ccNone() and + argAp = apNone() + ) + or + exists(NodeEx mid, ApNil nil | + fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + additionalJumpStep(mid, node, config) and + cc = ccNone() and + argAp = apNone() and + ap = getApNil(node) + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + additionalJumpStateStep(mid, state0, node, state, config) and + cc = ccNone() and + argAp = apNone() and + ap = getApNil(node) + ) + or + // store + exists(TypedContent tc, Ap ap0 | + fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + ap = apCons(tc, ap0) + ) + or + // read + exists(Ap ap0, Content c | + fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) + ) + or + // flow into a callable + exists(ApApprox apa | + fwdFlowIn(_, node, state, _, cc, _, ap, config) and + apa = getApprox(ap) and + if PrevStage::parameterMayFlowThrough(node, _, apa, config) + then argAp = apSome(ap) + else argAp = apNone() + ) + or + // flow out of a callable + fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } - ApOption apNone() { result = TBooleanNone() } + pragma[nomagic] + private predicate fwdFlowStore( + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + Configuration config + ) { + exists(DataFlowType contentType | + fwdFlow(node1, state, cc, argAp, ap1, config) and + PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + typecheckStore(ap1, contentType) + ) + } - ApOption apSome(Ap ap) { result = TBooleanSome(ap) } + /** + * Holds if forward flow with access path `tail` reaches a store of `c` + * resulting in access path `cons`. + */ + pragma[nomagic] + private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { + exists(TypedContent tc | + fwdFlowStore(_, tail, tc, _, _, _, _, config) and + tc.getContent() = c and + cons = apCons(tc, tail) + ) + } + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + Configuration config + ) { + fwdFlow(node1, state, cc, argAp, ap, config) and + PrevStage::readStepCand(node1, c, node2, config) and + getHeadContent(ap) = c + } + + pragma[nomagic] + private predicate fwdFlowIn( + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, + Ap ap, Configuration config + ) { + exists(ArgNodeEx arg, boolean allowsFieldFlow | + fwdFlow(arg, state, outercc, argAp, ap, config) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate fwdFlowOutNotFromArg( + NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + ) { + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, argAp, ap, config) and + flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + ccOut = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + ) { + exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + /** + * Holds if an argument to `call` is reached in the flow covered by `fwdFlow` + * and data might flow through the target callable and back out at `call`. + */ + pragma[nomagic] + private predicate fwdFlowIsEntered( + DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + ) { + exists(ParamNodeEx p | + fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + ) + } + + pragma[nomagic] + private predicate storeStepFwd( + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config + ) { + fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + ap2 = apCons(tc, ap1) and + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + } + + private predicate readStepFwd( + NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config + ) { + fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowConsCand(ap1, c, ap2, config) + } + + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), + pragma[only_bind_into](config)) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate returnNodeMayFlowThrough( + RetNodeEx ret, FlowState state, Ap ap, Configuration config + ) { + fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + } + + /** + * Holds if `node` with access path `ap` is part of a path from a source to a + * sink in the configuration `config`. + * + * The Boolean `toReturn` records whether the node must be returned from the + * enclosing callable in order to reach a sink, and if so, `returnAp` records + * the access path of the returned value. + */ + pragma[nomagic] + predicate revFlow( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + revFlow0(node, state, toReturn, returnAp, ap, config) and + fwdFlow(node, state, _, _, ap, config) + } + + pragma[nomagic] + private predicate revFlow0( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + fwdFlow(node, state, _, _, ap, config) and + sinkNode(node, state, config) and + (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + returnAp = apNone() and + ap instanceof ApNil + or + exists(NodeEx mid, FlowState state0 | + localStep(node, state, mid, state0, true, _, config, _) and + revFlow(mid, state0, toReturn, returnAp, ap, config) + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and + revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + ap instanceof ApNil + ) + or + exists(NodeEx mid | + jumpStep(node, mid, config) and + revFlow(mid, state, _, _, ap, config) and + toReturn = false and + returnAp = apNone() + ) + or + exists(NodeEx mid, ApNil nil | + fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + additionalJumpStep(node, mid, config) and + revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and + toReturn = false and + returnAp = apNone() and + ap instanceof ApNil + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + additionalJumpStateStep(node, state, mid, state0, config) and + revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, + pragma[only_bind_into](config)) and + toReturn = false and + returnAp = apNone() and + ap instanceof ApNil + ) + or + // store + exists(Ap ap0, Content c | + revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowConsCand(ap0, c, ap, config) + ) + or + // read + exists(NodeEx mid, Ap ap0 | + revFlow(mid, state, toReturn, returnAp, ap0, config) and + readStepFwd(node, ap, _, mid, ap0, config) + ) + or + // flow into a callable + revFlowInNotToReturn(node, state, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + or + // flow out of a callable + revFlowOut(_, node, state, _, _, ap, config) and + toReturn = true and + if returnNodeMayFlowThrough(node, state, ap, config) + then returnAp = apSome(ap) + else returnAp = apNone() + } + + pragma[nomagic] + private predicate revFlowStore( + Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, + boolean toReturn, ApOption returnAp, Configuration config + ) { + revFlow(mid, state, toReturn, returnAp, ap0, config) and + storeStepFwd(node, ap, tc, mid, ap0, config) and + tc.getContent() = c + } + + /** + * Holds if reverse flow with access path `tail` reaches a read of `c` + * resulting in access path `cons`. + */ + pragma[nomagic] + private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { + exists(NodeEx mid, Ap tail0 | + revFlow(mid, _, _, _, tail, config) and + tail = pragma[only_bind_into](tail0) and + readStepFwd(_, cons, c, mid, tail0, config) + ) + } + + pragma[nomagic] + private predicate revFlowOut( + DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, + Configuration config + ) { + exists(NodeEx out, boolean allowsFieldFlow | + revFlow(out, state, toReturn, returnAp, ap, config) and + flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate revFlowInNotToReturn( + ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + ) { + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate revFlowInToReturn( + DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + ) { + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + /** + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. + */ + pragma[nomagic] + private predicate revFlowIsReturned( + DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + exists(RetNodeEx ret, FlowState state, CcCall ccc | + revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and + fwdFlow(ret, state, ccc, apSome(_), ap, config) and + matchesCall(ccc, call) + ) + } + + pragma[nomagic] + predicate storeStepCand( + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, + Configuration config + ) { + exists(Ap ap2, Content c | + PrevStage::storeStepCand(node1, _, tc, node2, contentType, config) and + revFlowStore(ap2, c, ap1, node1, _, tc, node2, _, _, config) and + revFlowConsCand(ap2, c, ap1, config) + ) + } + + predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { + exists(Ap ap1, Ap ap2 | + revFlow(node2, _, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and + readStepFwd(node1, ap1, c, node2, ap2, config) and + revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _, + pragma[only_bind_into](config)) + ) + } + + predicate revFlow(NodeEx node, FlowState state, Configuration config) { + revFlow(node, state, _, _, _, config) + } + + predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { + revFlow(node, state, _, _, ap, config) + } + + pragma[nomagic] + predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) { + revFlow(node, state, ap, config) + } + + private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { + storeStepFwd(_, ap, tc, _, _, config) + } + + private predicate revConsCand(TypedContent tc, Ap ap, Configuration config) { + storeStepCand(_, ap, tc, _, _, config) + } + + private predicate validAp(Ap ap, Configuration config) { + revFlow(_, _, _, _, ap, config) and ap instanceof ApNil + or + exists(TypedContent head, Ap tail | + consCand(head, tail, config) and + ap = apCons(head, tail) + ) + } + + predicate consCand(TypedContent tc, Ap ap, Configuration config) { + revConsCand(tc, ap, config) and + validAp(ap, config) + } + + pragma[noinline] + private predicate parameterFlow( + ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + ) { + revFlow(p, _, true, apSome(ap0), ap, config) and + c = p.getEnclosingCallable() + } + + predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { + exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | + parameterFlow(p, ap, ap0, c, config) and + c = ret.getEnclosingCallable() and + revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), + pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and + fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and + kind = ret.getKind() and + p.getPosition() = pos and + // we don't expect a parameter to return stored in itself, unless explicitly allowed + ( + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + p.allowParameterReturnInSelf() + ) + ) + } + + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists( + Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + | + revFlow(arg, state, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + + predicate stats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config + ) { + fwd = true and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and + conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, argAp, ap, config) + ) + or + fwd = false and + nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and + fields = count(TypedContent f0 | consCand(f0, _, config)) and + conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and + states = count(FlowState state | revFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | + revFlow(n, state, b, retAp, ap, config) + ) + } + /* End: Stage logic. */ + } +} + +private module BooleanCallContext { + class Cc extends boolean { + Cc() { this in [true, false] } + } + + class CcCall extends Cc { + CcCall() { this = true } + } + + /** Holds if the call context may be `call`. */ + predicate matchesCall(CcCall cc, DataFlowCall call) { any() } + + class CcNoCall extends Cc { + CcNoCall() { this = false } + } + + Cc ccNone() { result = false } + + CcCall ccSomeCall() { result = true } + + class LocalCc = Unit; + + bindingset[node, cc] + LocalCc getLocalCc(NodeEx node, Cc cc) { any() } + + bindingset[call, c, outercc] + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + + bindingset[call, c, innercc] + CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } +} + +private module Level1CallContext { class Cc = CallContext; class CcCall = CallContextCall; + pragma[inline] + predicate matchesCall(CcCall cc, DataFlowCall call) { cc.matchesCall(call) } + class CcNoCall = CallContextNoCall; Cc ccNone() { result instanceof CallContextAny } CcCall ccSomeCall() { result instanceof CallContextSomeCall } - private class LocalCc = Unit; + module NoLocalCallContext { + class LocalCc = Unit; - bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { - checkCallContextCall(outercc, call, c) and - if recordDataFlowCallSiteDispatch(call, c) - then result = TSpecificCall(call) - else result = TSomeCall() + bindingset[node, cc] + LocalCc getLocalCc(NodeEx node, Cc cc) { any() } + + bindingset[call, c, outercc] + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } + } + + module LocalCallContext { + class LocalCc = LocalCallContext; + + bindingset[node, cc] + LocalCc getLocalCc(NodeEx node, Cc cc) { + result = + getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), + node.getEnclosingCallable()) + } + + bindingset[call, c, outercc] + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall() + } } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { checkCallContextReturn(innercc, c, call) and if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() } +} - bindingset[node, cc] - private LocalCc getLocalCc(NodeEx node, Cc cc) { any() } +private module Stage2Param implements MkStage::StageParam { + private module PrevStage = Stage1; + + class Ap extends boolean { + Ap() { this in [true, false] } + } + + class ApNil extends Ap { + ApNil() { this = false } + } + + bindingset[result, ap] + PrevStage::Ap getApprox(Ap ap) { any() } + + ApNil getApNil(NodeEx node) { Stage1::revFlow(node, _) and exists(result) } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result = true and exists(tc) and exists(tail) } + + pragma[inline] + Content getHeadContent(Ap ap) { exists(result) and ap = true } + + class ApOption = BooleanOption; + + ApOption apNone() { result = TBooleanNone() } + + ApOption apSome(Ap ap) { result = TBooleanSome(ap) } + + import Level1CallContext + import NoLocalCallContext bindingset[node1, state1, config] bindingset[node2, state2, config] - private predicate localStep( + predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { @@ -1221,9 +1906,9 @@ private module Stage2 { exists(lcc) } - private predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/5; - private predicate flowIntoCall = flowIntoCallNodeCand1/5; + predicate flowIntoCall = flowIntoCallNodeCand1/5; pragma[nomagic] private predicate expectsContentCand(NodeEx node, Configuration config) { @@ -1235,7 +1920,7 @@ private module Stage2 { } bindingset[node, state, ap, config] - private predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { PrevStage::revFlowState(state, pragma[only_bind_into](config)) and exists(ap) and not stateBarrier(node, state, config) and @@ -1248,542 +1933,11 @@ private module Stage2 { } bindingset[ap, contentType] - private predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } + predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } +} - /* Begin: Stage 2 logic. */ - bindingset[node, state, config] - private predicate flowCand(NodeEx node, FlowState state, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, state, _, _, apa, config) - } - - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) - } - - pragma[nomagic] - private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config - ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - ccc.matchesCall(call) - } - - /** - * Holds if `node` is reachable with access path `ap` from a source in the - * configuration `config`. - * - * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. - */ - pragma[nomagic] - predicate fwdFlow(NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, state, cc, argAp, ap, config) and - flowCand(node, state, unbindApa(getApprox(ap)), config) and - filter(node, state, ap, config) - } - - pragma[nomagic] - private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - sourceNode(node, state, config) and - (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and - argAp = apNone() and - ap = getApNil(node) - or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc) - | - localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 - or - localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil - ) - or - exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and - jumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and - additionalJumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and - additionalJumpStateStep(mid, state0, node, state, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - // store - exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) - ) - or - // read - exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) - ) - or - // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() - ) - or - // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) - or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) - } - - pragma[nomagic] - private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config - ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and - typecheckStore(ap1, contentType) - ) - } - - /** - * Holds if forward flow with access path `tail` reaches a store of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and - tc.getContent() = c and - cons = apCons(tc, tail) - ) - } - - pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config - ) { - fwdFlow(node1, state, cc, argAp, ap, config) and - PrevStage::readStepCand(node1, c, node2, config) and - getHeadContent(ap) = c - } - - pragma[nomagic] - private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config - ) { - exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config - ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an argument to `call` is reached in the flow covered by `fwdFlow` - * and data might flow through the target callable and back out at `call`. - */ - pragma[nomagic] - private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) - ) - } - - pragma[nomagic] - private predicate storeStepFwd( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config - ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and - ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) - } - - private predicate readStepFwd( - NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config - ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and - fwdFlowConsCand(ap1, c, ap2, config) - } - - pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) - } - - pragma[nomagic] - private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config - ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) - } - - /** - * Holds if `node` with access path `ap` is part of a path from a source to a - * sink in the configuration `config`. - * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. - */ - pragma[nomagic] - predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) - } - - pragma[nomagic] - private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - fwdFlow(node, state, _, _, ap, config) and - sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and - returnAp = apNone() and - ap instanceof ApNil - or - exists(NodeEx mid, FlowState state0 | - localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and - localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and - ap instanceof ApNil - ) - or - exists(NodeEx mid | - jumpStep(node, mid, config) and - revFlow(mid, state, _, _, ap, config) and - toReturn = false and - returnAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStateStep(node, state, mid, state0, config) and - revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, - pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - // store - exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and - revFlowConsCand(ap0, c, ap, config) - ) - or - // read - exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and - readStepFwd(node, ap, _, mid, ap0, config) - ) - or - // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false - or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - or - // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() - } - - pragma[nomagic] - private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config - ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and - storeStepFwd(node, ap, tc, mid, ap0, config) and - tc.getContent() = c - } - - /** - * Holds if reverse flow with access path `tail` reaches a read of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, _, tail, config) and - tail = pragma[only_bind_into](tail0) and - readStepFwd(_, cons, c, mid, tail0, config) - ) - } - - pragma[nomagic] - private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config - ) { - exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an output from `call` is reached in the flow covered by `revFlow` - * and data might flow through the target callable resulting in reverse flow - * reaching an argument of `call`. - */ - pragma[nomagic] - private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and - ccc.matchesCall(call) - ) - } - - pragma[nomagic] - predicate storeStepCand( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, - Configuration config - ) { - exists(Ap ap2, Content c | - PrevStage::storeStepCand(node1, _, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, _, tc, node2, _, _, config) and - revFlowConsCand(ap2, c, ap1, config) - ) - } - - predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { - exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and - readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _, - pragma[only_bind_into](config)) - ) - } - - predicate revFlow(NodeEx node, FlowState state, Configuration config) { - revFlow(node, state, _, _, _, config) - } - - pragma[nomagic] - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } - - // use an alias as a workaround for bad functionality-induced joins - pragma[nomagic] - predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } - - // use an alias as a workaround for bad functionality-induced joins - pragma[nomagic] - predicate revFlowAlias( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - revFlow(node, state, toReturn, returnAp, ap, config) - } - - private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepFwd(_, ap, tc, _, _, config) - } - - private predicate revConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepCand(_, ap, tc, _, _, config) - } - - private predicate validAp(Ap ap, Configuration config) { - revFlow(_, _, _, _, ap, config) and ap instanceof ApNil - or - exists(TypedContent head, Ap tail | - consCand(head, tail, config) and - ap = apCons(head, tail) - ) - } - - predicate consCand(TypedContent tc, Ap ap, Configuration config) { - revConsCand(tc, ap, config) and - validAp(ap, config) - } - - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config - ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() - } - - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) - ) - } - - pragma[nomagic] - predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - } - - predicate stats( - boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config - ) { - fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and - fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and - tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) - ) - or - fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and - fields = count(TypedContent f0 | consCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - states = count(FlowState state | revFlow(_, state, _, _, _, config)) and - tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) - ) - } - /* End: Stage 2 logic. */ +private module Stage2 implements StageSig { + import MkStage::Stage } pragma[nomagic] @@ -1883,14 +2037,13 @@ private module LocalFlowBigStep { ) { additionalLocalFlowStepNodeCand1(node1, node2, config) and state1 = state2 and - Stage2::revFlow(node1, pragma[only_bind_into](state1), _, _, false, - pragma[only_bind_into](config)) and - Stage2::revFlowAlias(node2, pragma[only_bind_into](state2), _, _, false, + Stage2::revFlow(node1, pragma[only_bind_into](state1), false, pragma[only_bind_into](config)) and + Stage2::revFlowAlias(node2, pragma[only_bind_into](state2), false, pragma[only_bind_into](config)) or additionalLocalStateStep(node1, state1, node2, state2, config) and - Stage2::revFlow(node1, state1, _, _, false, pragma[only_bind_into](config)) and - Stage2::revFlowAlias(node2, state2, _, _, false, pragma[only_bind_into](config)) + Stage2::revFlow(node1, state1, false, pragma[only_bind_into](config)) and + Stage2::revFlowAlias(node2, state2, false, pragma[only_bind_into](config)) } /** @@ -1967,26 +2120,24 @@ private module LocalFlowBigStep { private import LocalFlowBigStep -private module Stage3 { - module PrevStage = Stage2; - - class ApApprox = PrevStage::Ap; +private module Stage3Param implements MkStage::StageParam { + private module PrevStage = Stage2; class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } - private ApNil getApNil(NodeEx node) { + ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) } bindingset[tc, tail] - private Ap apCons(TypedContent tc, Ap tail) { result.getHead() = tc and exists(tail) } + Ap apCons(TypedContent tc, Ap tail) { result.getHead() = tc and exists(tail) } pragma[noinline] - private Content getHeadContent(Ap ap) { result = ap.getHead().getContent() } + Content getHeadContent(Ap ap) { result = ap.getHead().getContent() } class ApOption = AccessPathFrontOption; @@ -1994,44 +2145,18 @@ private module Stage3 { ApOption apSome(Ap ap) { result = TAccessPathFrontSome(ap) } - class Cc = boolean; + import BooleanCallContext - class CcCall extends Cc { - CcCall() { this = true } - - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } - - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } - - CcCall ccSomeCall() { result = true } - - private class LocalCc = Unit; - - bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } - - bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } - - bindingset[node, cc] - private LocalCc getLocalCc(NodeEx node, Cc cc) { any() } - - private predicate localStep( + predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - private predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/5; - private predicate flowIntoCall = flowIntoCallNodeCand2/5; + predicate flowIntoCall = flowIntoCallNodeCand2/5; pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2067,7 +2192,7 @@ private module Stage3 { private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } bindingset[node, state, ap, config] - private predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { exists(state) and exists(config) and not clear(node, ap, config) and @@ -2080,546 +2205,15 @@ private module Stage3 { } bindingset[ap, contentType] - private predicate typecheckStore(Ap ap, DataFlowType contentType) { + predicate typecheckStore(Ap ap, DataFlowType contentType) { // We need to typecheck stores here, since reverse flow through a getter // might have a different type here compared to inside the getter. compatibleTypes(ap.getType(), contentType) } +} - /* Begin: Stage 3 logic. */ - bindingset[node, state, config] - private predicate flowCand(NodeEx node, FlowState state, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, state, _, _, apa, config) - } - - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) - } - - pragma[nomagic] - private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config - ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - ccc.matchesCall(call) - } - - /** - * Holds if `node` is reachable with access path `ap` from a source in the - * configuration `config`. - * - * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. - */ - pragma[nomagic] - predicate fwdFlow(NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, state, cc, argAp, ap, config) and - flowCand(node, state, unbindApa(getApprox(ap)), config) and - filter(node, state, ap, config) - } - - pragma[nomagic] - private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - sourceNode(node, state, config) and - (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and - argAp = apNone() and - ap = getApNil(node) - or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc) - | - localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 - or - localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil - ) - or - exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and - jumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and - additionalJumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and - additionalJumpStateStep(mid, state0, node, state, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - // store - exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) - ) - or - // read - exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) - ) - or - // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() - ) - or - // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) - or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) - } - - pragma[nomagic] - private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config - ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and - typecheckStore(ap1, contentType) - ) - } - - /** - * Holds if forward flow with access path `tail` reaches a store of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and - tc.getContent() = c and - cons = apCons(tc, tail) - ) - } - - pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config - ) { - fwdFlow(node1, state, cc, argAp, ap, config) and - PrevStage::readStepCand(node1, c, node2, config) and - getHeadContent(ap) = c - } - - pragma[nomagic] - private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config - ) { - exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config - ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an argument to `call` is reached in the flow covered by `fwdFlow` - * and data might flow through the target callable and back out at `call`. - */ - pragma[nomagic] - private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) - ) - } - - pragma[nomagic] - private predicate storeStepFwd( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config - ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and - ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) - } - - private predicate readStepFwd( - NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config - ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and - fwdFlowConsCand(ap1, c, ap2, config) - } - - pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) - } - - pragma[nomagic] - private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config - ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) - } - - /** - * Holds if `node` with access path `ap` is part of a path from a source to a - * sink in the configuration `config`. - * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. - */ - pragma[nomagic] - predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) - } - - pragma[nomagic] - private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - fwdFlow(node, state, _, _, ap, config) and - sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and - returnAp = apNone() and - ap instanceof ApNil - or - exists(NodeEx mid, FlowState state0 | - localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and - localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and - ap instanceof ApNil - ) - or - exists(NodeEx mid | - jumpStep(node, mid, config) and - revFlow(mid, state, _, _, ap, config) and - toReturn = false and - returnAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStateStep(node, state, mid, state0, config) and - revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, - pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - // store - exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and - revFlowConsCand(ap0, c, ap, config) - ) - or - // read - exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and - readStepFwd(node, ap, _, mid, ap0, config) - ) - or - // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false - or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - or - // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() - } - - pragma[nomagic] - private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config - ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and - storeStepFwd(node, ap, tc, mid, ap0, config) and - tc.getContent() = c - } - - /** - * Holds if reverse flow with access path `tail` reaches a read of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, _, tail, config) and - tail = pragma[only_bind_into](tail0) and - readStepFwd(_, cons, c, mid, tail0, config) - ) - } - - pragma[nomagic] - private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config - ) { - exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an output from `call` is reached in the flow covered by `revFlow` - * and data might flow through the target callable resulting in reverse flow - * reaching an argument of `call`. - */ - pragma[nomagic] - private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and - ccc.matchesCall(call) - ) - } - - pragma[nomagic] - predicate storeStepCand( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, - Configuration config - ) { - exists(Ap ap2, Content c | - PrevStage::storeStepCand(node1, _, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, _, tc, node2, _, _, config) and - revFlowConsCand(ap2, c, ap1, config) - ) - } - - predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { - exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and - readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _, - pragma[only_bind_into](config)) - ) - } - - predicate revFlow(NodeEx node, FlowState state, Configuration config) { - revFlow(node, state, _, _, _, config) - } - - pragma[nomagic] - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } - - // use an alias as a workaround for bad functionality-induced joins - pragma[nomagic] - predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } - - // use an alias as a workaround for bad functionality-induced joins - pragma[nomagic] - predicate revFlowAlias( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - revFlow(node, state, toReturn, returnAp, ap, config) - } - - private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepFwd(_, ap, tc, _, _, config) - } - - private predicate revConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepCand(_, ap, tc, _, _, config) - } - - private predicate validAp(Ap ap, Configuration config) { - revFlow(_, _, _, _, ap, config) and ap instanceof ApNil - or - exists(TypedContent head, Ap tail | - consCand(head, tail, config) and - ap = apCons(head, tail) - ) - } - - predicate consCand(TypedContent tc, Ap ap, Configuration config) { - revConsCand(tc, ap, config) and - validAp(ap, config) - } - - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config - ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() - } - - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) - ) - } - - pragma[nomagic] - predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - } - - predicate stats( - boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config - ) { - fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and - fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and - tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) - ) - or - fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and - fields = count(TypedContent f0 | consCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - states = count(FlowState state | revFlow(_, state, _, _, _, config)) and - tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) - ) - } - /* End: Stage 3 logic. */ +private module Stage3 implements StageSig { + import MkStage::Stage } /** @@ -2644,7 +2238,7 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, _, _, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2828,26 +2422,24 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4 { - module PrevStage = Stage3; - - class ApApprox = PrevStage::Ap; +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; - private ApApprox getApprox(Ap ap) { result = ap.getFront() } + PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } - private ApNil getApNil(NodeEx node) { + ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TNil(node.getDataFlowType()) } bindingset[tc, tail] - private Ap apCons(TypedContent tc, Ap tail) { result = push(tc, tail) } + Ap apCons(TypedContent tc, Ap tail) { result = push(tc, tail) } pragma[noinline] - private Content getHeadContent(Ap ap) { result = ap.getHead().getContent() } + Content getHeadContent(Ap ap) { result = ap.getHead().getContent() } class ApOption = AccessPathApproxOption; @@ -2855,38 +2447,10 @@ private module Stage4 { ApOption apSome(Ap ap) { result = TAccessPathApproxSome(ap) } - class Cc = CallContext; + import Level1CallContext + import LocalCallContext - class CcCall = CallContextCall; - - class CcNoCall = CallContextNoCall; - - Cc ccNone() { result instanceof CallContextAny } - - CcCall ccSomeCall() { result instanceof CallContextSomeCall } - - private class LocalCc = LocalCallContext; - - bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { - checkCallContextCall(outercc, call, c) and - if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall() - } - - bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { - checkCallContextReturn(innercc, c, call) and - if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() - } - - bindingset[node, cc] - private LocalCc getLocalCc(NodeEx node, Cc cc) { - result = - getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), - node.getEnclosingCallable()) - } - - private predicate localStep( + predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { @@ -2894,575 +2458,40 @@ private module Stage4 { } pragma[nomagic] - private predicate flowOutOfCall( + predicate flowOutOfCall( DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and - PrevStage::revFlow(node2, pragma[only_bind_into](state), _, _, _, - pragma[only_bind_into](config)) and - PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, _, _, + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) ) } pragma[nomagic] - private predicate flowIntoCall( + predicate flowIntoCall( DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and - PrevStage::revFlow(node2, pragma[only_bind_into](state), _, _, _, - pragma[only_bind_into](config)) and - PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, _, _, + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) ) } bindingset[node, state, ap, config] - private predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { any() } + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { any() } // Type checking is not necessary here as it has already been done in stage 3. bindingset[ap, contentType] - private predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } - - /* Begin: Stage 4 logic. */ - bindingset[node, state, config] - private predicate flowCand(NodeEx node, FlowState state, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, state, _, _, apa, config) - } - - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) - } - - pragma[nomagic] - private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config - ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - ccc.matchesCall(call) - } - - /** - * Holds if `node` is reachable with access path `ap` from a source in the - * configuration `config`. - * - * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. - */ - pragma[nomagic] - predicate fwdFlow(NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, state, cc, argAp, ap, config) and - flowCand(node, state, unbindApa(getApprox(ap)), config) and - filter(node, state, ap, config) - } - - pragma[nomagic] - private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - sourceNode(node, state, config) and - (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and - argAp = apNone() and - ap = getApNil(node) - or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc) - | - localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 - or - localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil - ) - or - exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and - jumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and - additionalJumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and - additionalJumpStateStep(mid, state0, node, state, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - // store - exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) - ) - or - // read - exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) - ) - or - // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() - ) - or - // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) - or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) - } - - pragma[nomagic] - private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config - ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and - typecheckStore(ap1, contentType) - ) - } - - /** - * Holds if forward flow with access path `tail` reaches a store of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and - tc.getContent() = c and - cons = apCons(tc, tail) - ) - } - - pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config - ) { - fwdFlow(node1, state, cc, argAp, ap, config) and - PrevStage::readStepCand(node1, c, node2, config) and - getHeadContent(ap) = c - } - - pragma[nomagic] - private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config - ) { - exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config - ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an argument to `call` is reached in the flow covered by `fwdFlow` - * and data might flow through the target callable and back out at `call`. - */ - pragma[nomagic] - private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) - ) - } - - pragma[nomagic] - private predicate storeStepFwd( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config - ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and - ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) - } - - private predicate readStepFwd( - NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config - ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and - fwdFlowConsCand(ap1, c, ap2, config) - } - - pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) - } - - pragma[nomagic] - private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config - ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) - } - - /** - * Holds if `node` with access path `ap` is part of a path from a source to a - * sink in the configuration `config`. - * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. - */ - pragma[nomagic] - predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) - } - - pragma[nomagic] - private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - fwdFlow(node, state, _, _, ap, config) and - sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and - returnAp = apNone() and - ap instanceof ApNil - or - exists(NodeEx mid, FlowState state0 | - localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and - localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and - ap instanceof ApNil - ) - or - exists(NodeEx mid | - jumpStep(node, mid, config) and - revFlow(mid, state, _, _, ap, config) and - toReturn = false and - returnAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStateStep(node, state, mid, state0, config) and - revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, - pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - // store - exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and - revFlowConsCand(ap0, c, ap, config) - ) - or - // read - exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and - readStepFwd(node, ap, _, mid, ap0, config) - ) - or - // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false - or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - or - // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() - } - - pragma[nomagic] - private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config - ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and - storeStepFwd(node, ap, tc, mid, ap0, config) and - tc.getContent() = c - } - - /** - * Holds if reverse flow with access path `tail` reaches a read of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, _, tail, config) and - tail = pragma[only_bind_into](tail0) and - readStepFwd(_, cons, c, mid, tail0, config) - ) - } - - pragma[nomagic] - private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config - ) { - exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an output from `call` is reached in the flow covered by `revFlow` - * and data might flow through the target callable resulting in reverse flow - * reaching an argument of `call`. - */ - pragma[nomagic] - private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and - ccc.matchesCall(call) - ) - } - - pragma[nomagic] - predicate storeStepCand( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, - Configuration config - ) { - exists(Ap ap2, Content c | - PrevStage::storeStepCand(node1, _, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, _, tc, node2, _, _, config) and - revFlowConsCand(ap2, c, ap1, config) - ) - } - - predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { - exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and - readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _, - pragma[only_bind_into](config)) - ) - } - - predicate revFlow(NodeEx node, FlowState state, Configuration config) { - revFlow(node, state, _, _, _, config) - } - - pragma[nomagic] - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } - - // use an alias as a workaround for bad functionality-induced joins - pragma[nomagic] - predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } - - // use an alias as a workaround for bad functionality-induced joins - pragma[nomagic] - predicate revFlowAlias( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - revFlow(node, state, toReturn, returnAp, ap, config) - } - - private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepFwd(_, ap, tc, _, _, config) - } - - private predicate revConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepCand(_, ap, tc, _, _, config) - } - - private predicate validAp(Ap ap, Configuration config) { - revFlow(_, _, _, _, ap, config) and ap instanceof ApNil - or - exists(TypedContent head, Ap tail | - consCand(head, tail, config) and - ap = apCons(head, tail) - ) - } - - predicate consCand(TypedContent tc, Ap ap, Configuration config) { - revConsCand(tc, ap, config) and - validAp(ap, config) - } - - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config - ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() - } - - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) - ) - } - - pragma[nomagic] - predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - } - - predicate stats( - boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config - ) { - fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and - fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and - tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) - ) - or - fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and - fields = count(TypedContent f0 | consCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - states = count(FlowState state | revFlow(_, state, _, _, _, config)) and - tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) - ) - } - /* End: Stage 4 logic. */ + predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } +private module Stage4 = MkStage::Stage; + bindingset[conf, result] private Configuration unbindConf(Configuration conf) { exists(Configuration c | result = pragma[only_bind_into](c) and conf = pragma[only_bind_into](c)) @@ -3495,7 +2524,7 @@ private newtype TSummaryCtx = TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, _, _, config) + Stage4::revFlow(p, state, _, config) ) } @@ -3553,7 +2582,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, _, _, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -3667,7 +2696,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, _, _, ap.getApprox(), pragma[only_bind_into](config)) + Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -4207,7 +3236,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, _, _, apa, config) + Stage4::revFlow(result, _, apa, config) } /** @@ -4243,7 +3272,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, _, _, apa, config) and + Stage4::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index a076f7a2e45..340bfe280b7 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -597,7 +597,7 @@ private predicate hasSinkCallCtx(Configuration config) { ) } -private module Stage1 { +private module Stage1 implements StageSig { class ApApprox = Unit; class Ap = Unit; @@ -944,12 +944,9 @@ private module Stage1 { predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } bindingset[node, state, config] - predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - revFlow(node, toReturn, pragma[only_bind_into](config)) and + predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { + revFlow(node, _, pragma[only_bind_into](config)) and exists(state) and - exists(returnAp) and exists(ap) } @@ -1142,66 +1139,754 @@ private predicate flowIntoCallNodeCand1( ) } -private module Stage2 { - module PrevStage = Stage1; +private signature module StageSig { + class Ap; + predicate revFlow(NodeEx node, Configuration config); + + bindingset[node, state, config] + predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); + + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); + + predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + + predicate storeStepCand( + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, + Configuration config + ); + + predicate readStepCand(NodeEx n1, Content c, NodeEx n2, Configuration config); +} + +private module MkStage { class ApApprox = PrevStage::Ap; - class Ap = boolean; + signature module StageParam { + class Ap; - class ApNil extends Ap { - ApNil() { this = false } + class ApNil extends Ap; + + bindingset[result, ap] + ApApprox getApprox(Ap ap); + + ApNil getApNil(NodeEx node); + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail); + + Content getHeadContent(Ap ap); + + class ApOption; + + ApOption apNone(); + + ApOption apSome(Ap ap); + + class Cc; + + class CcCall extends Cc; + + // TODO: member predicate on CcCall + predicate matchesCall(CcCall cc, DataFlowCall call); + + class CcNoCall extends Cc; + + Cc ccNone(); + + CcCall ccSomeCall(); + + class LocalCc; + + bindingset[call, c, outercc] + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc); + + bindingset[call, c, innercc] + CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc); + + bindingset[node, cc] + LocalCc getLocalCc(NodeEx node, Cc cc); + + bindingset[node1, state1, config] + bindingset[node2, state2, config] + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApNil ap, Configuration config, LocalCc lcc + ); + + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + ); + + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + ); + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config); + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType); } - bindingset[result, ap] - private ApApprox getApprox(Ap ap) { any() } + module Stage implements StageSig { + import Param - private ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and exists(result) } + /* Begin: Stage logic. */ + bindingset[result, apa] + private ApApprox unbindApa(ApApprox apa) { + pragma[only_bind_out](apa) = pragma[only_bind_out](result) + } - bindingset[tc, tail] - private Ap apCons(TypedContent tc, Ap tail) { result = true and exists(tc) and exists(tail) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, + pragma[only_bind_into](config)) and + matchesCall(ccc, call) + } - pragma[inline] - private Content getHeadContent(Ap ap) { exists(result) and ap = true } + /** + * Holds if `node` is reachable with access path `ap` from a source in the + * configuration `config`. + * + * The call context `cc` records whether the node is reached through an + * argument in a call, and if so, `argAp` records the access path of that + * argument. + */ + pragma[nomagic] + predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + ) { + fwdFlow0(node, state, cc, argAp, ap, config) and + PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + filter(node, state, ap, config) + } - class ApOption = BooleanOption; + pragma[nomagic] + private predicate fwdFlow0( + NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + ) { + sourceNode(node, state, config) and + (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and + argAp = apNone() and + ap = getApNil(node) + or + exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | + fwdFlow(mid, state0, cc, argAp, ap0, config) and + localCc = getLocalCc(mid, cc) + | + localStep(mid, state0, node, state, true, _, config, localCc) and + ap = ap0 + or + localStep(mid, state0, node, state, false, ap, config, localCc) and + ap0 instanceof ApNil + ) + or + exists(NodeEx mid | + fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + jumpStep(mid, node, config) and + cc = ccNone() and + argAp = apNone() + ) + or + exists(NodeEx mid, ApNil nil | + fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + additionalJumpStep(mid, node, config) and + cc = ccNone() and + argAp = apNone() and + ap = getApNil(node) + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + additionalJumpStateStep(mid, state0, node, state, config) and + cc = ccNone() and + argAp = apNone() and + ap = getApNil(node) + ) + or + // store + exists(TypedContent tc, Ap ap0 | + fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + ap = apCons(tc, ap0) + ) + or + // read + exists(Ap ap0, Content c | + fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) + ) + or + // flow into a callable + exists(ApApprox apa | + fwdFlowIn(_, node, state, _, cc, _, ap, config) and + apa = getApprox(ap) and + if PrevStage::parameterMayFlowThrough(node, _, apa, config) + then argAp = apSome(ap) + else argAp = apNone() + ) + or + // flow out of a callable + fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } - ApOption apNone() { result = TBooleanNone() } + pragma[nomagic] + private predicate fwdFlowStore( + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + Configuration config + ) { + exists(DataFlowType contentType | + fwdFlow(node1, state, cc, argAp, ap1, config) and + PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + typecheckStore(ap1, contentType) + ) + } - ApOption apSome(Ap ap) { result = TBooleanSome(ap) } + /** + * Holds if forward flow with access path `tail` reaches a store of `c` + * resulting in access path `cons`. + */ + pragma[nomagic] + private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { + exists(TypedContent tc | + fwdFlowStore(_, tail, tc, _, _, _, _, config) and + tc.getContent() = c and + cons = apCons(tc, tail) + ) + } + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + Configuration config + ) { + fwdFlow(node1, state, cc, argAp, ap, config) and + PrevStage::readStepCand(node1, c, node2, config) and + getHeadContent(ap) = c + } + + pragma[nomagic] + private predicate fwdFlowIn( + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, + Ap ap, Configuration config + ) { + exists(ArgNodeEx arg, boolean allowsFieldFlow | + fwdFlow(arg, state, outercc, argAp, ap, config) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate fwdFlowOutNotFromArg( + NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + ) { + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, argAp, ap, config) and + flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + ccOut = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + ) { + exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + /** + * Holds if an argument to `call` is reached in the flow covered by `fwdFlow` + * and data might flow through the target callable and back out at `call`. + */ + pragma[nomagic] + private predicate fwdFlowIsEntered( + DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + ) { + exists(ParamNodeEx p | + fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + ) + } + + pragma[nomagic] + private predicate storeStepFwd( + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config + ) { + fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + ap2 = apCons(tc, ap1) and + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + } + + private predicate readStepFwd( + NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config + ) { + fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowConsCand(ap1, c, ap2, config) + } + + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), + pragma[only_bind_into](config)) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate returnNodeMayFlowThrough( + RetNodeEx ret, FlowState state, Ap ap, Configuration config + ) { + fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + } + + /** + * Holds if `node` with access path `ap` is part of a path from a source to a + * sink in the configuration `config`. + * + * The Boolean `toReturn` records whether the node must be returned from the + * enclosing callable in order to reach a sink, and if so, `returnAp` records + * the access path of the returned value. + */ + pragma[nomagic] + predicate revFlow( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + revFlow0(node, state, toReturn, returnAp, ap, config) and + fwdFlow(node, state, _, _, ap, config) + } + + pragma[nomagic] + private predicate revFlow0( + NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + fwdFlow(node, state, _, _, ap, config) and + sinkNode(node, state, config) and + (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + returnAp = apNone() and + ap instanceof ApNil + or + exists(NodeEx mid, FlowState state0 | + localStep(node, state, mid, state0, true, _, config, _) and + revFlow(mid, state0, toReturn, returnAp, ap, config) + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and + revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + ap instanceof ApNil + ) + or + exists(NodeEx mid | + jumpStep(node, mid, config) and + revFlow(mid, state, _, _, ap, config) and + toReturn = false and + returnAp = apNone() + ) + or + exists(NodeEx mid, ApNil nil | + fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + additionalJumpStep(node, mid, config) and + revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and + toReturn = false and + returnAp = apNone() and + ap instanceof ApNil + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + additionalJumpStateStep(node, state, mid, state0, config) and + revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, + pragma[only_bind_into](config)) and + toReturn = false and + returnAp = apNone() and + ap instanceof ApNil + ) + or + // store + exists(Ap ap0, Content c | + revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowConsCand(ap0, c, ap, config) + ) + or + // read + exists(NodeEx mid, Ap ap0 | + revFlow(mid, state, toReturn, returnAp, ap0, config) and + readStepFwd(node, ap, _, mid, ap0, config) + ) + or + // flow into a callable + revFlowInNotToReturn(node, state, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + or + // flow out of a callable + revFlowOut(_, node, state, _, _, ap, config) and + toReturn = true and + if returnNodeMayFlowThrough(node, state, ap, config) + then returnAp = apSome(ap) + else returnAp = apNone() + } + + pragma[nomagic] + private predicate revFlowStore( + Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, + boolean toReturn, ApOption returnAp, Configuration config + ) { + revFlow(mid, state, toReturn, returnAp, ap0, config) and + storeStepFwd(node, ap, tc, mid, ap0, config) and + tc.getContent() = c + } + + /** + * Holds if reverse flow with access path `tail` reaches a read of `c` + * resulting in access path `cons`. + */ + pragma[nomagic] + private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { + exists(NodeEx mid, Ap tail0 | + revFlow(mid, _, _, _, tail, config) and + tail = pragma[only_bind_into](tail0) and + readStepFwd(_, cons, c, mid, tail0, config) + ) + } + + pragma[nomagic] + private predicate revFlowOut( + DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, + Configuration config + ) { + exists(NodeEx out, boolean allowsFieldFlow | + revFlow(out, state, toReturn, returnAp, ap, config) and + flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate revFlowInNotToReturn( + ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + ) { + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate revFlowInToReturn( + DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + ) { + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + /** + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. + */ + pragma[nomagic] + private predicate revFlowIsReturned( + DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + ) { + exists(RetNodeEx ret, FlowState state, CcCall ccc | + revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and + fwdFlow(ret, state, ccc, apSome(_), ap, config) and + matchesCall(ccc, call) + ) + } + + pragma[nomagic] + predicate storeStepCand( + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, + Configuration config + ) { + exists(Ap ap2, Content c | + PrevStage::storeStepCand(node1, _, tc, node2, contentType, config) and + revFlowStore(ap2, c, ap1, node1, _, tc, node2, _, _, config) and + revFlowConsCand(ap2, c, ap1, config) + ) + } + + predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { + exists(Ap ap1, Ap ap2 | + revFlow(node2, _, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and + readStepFwd(node1, ap1, c, node2, ap2, config) and + revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _, + pragma[only_bind_into](config)) + ) + } + + predicate revFlow(NodeEx node, FlowState state, Configuration config) { + revFlow(node, state, _, _, _, config) + } + + predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { + revFlow(node, state, _, _, ap, config) + } + + pragma[nomagic] + predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) { + revFlow(node, state, ap, config) + } + + private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { + storeStepFwd(_, ap, tc, _, _, config) + } + + private predicate revConsCand(TypedContent tc, Ap ap, Configuration config) { + storeStepCand(_, ap, tc, _, _, config) + } + + private predicate validAp(Ap ap, Configuration config) { + revFlow(_, _, _, _, ap, config) and ap instanceof ApNil + or + exists(TypedContent head, Ap tail | + consCand(head, tail, config) and + ap = apCons(head, tail) + ) + } + + predicate consCand(TypedContent tc, Ap ap, Configuration config) { + revConsCand(tc, ap, config) and + validAp(ap, config) + } + + pragma[noinline] + private predicate parameterFlow( + ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + ) { + revFlow(p, _, true, apSome(ap0), ap, config) and + c = p.getEnclosingCallable() + } + + predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { + exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | + parameterFlow(p, ap, ap0, c, config) and + c = ret.getEnclosingCallable() and + revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), + pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and + fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and + kind = ret.getKind() and + p.getPosition() = pos and + // we don't expect a parameter to return stored in itself, unless explicitly allowed + ( + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + p.allowParameterReturnInSelf() + ) + ) + } + + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists( + Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + | + revFlow(arg, state, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + + predicate stats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config + ) { + fwd = true and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and + conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, argAp, ap, config) + ) + or + fwd = false and + nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and + fields = count(TypedContent f0 | consCand(f0, _, config)) and + conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and + states = count(FlowState state | revFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | + revFlow(n, state, b, retAp, ap, config) + ) + } + /* End: Stage logic. */ + } +} + +private module BooleanCallContext { + class Cc extends boolean { + Cc() { this in [true, false] } + } + + class CcCall extends Cc { + CcCall() { this = true } + } + + /** Holds if the call context may be `call`. */ + predicate matchesCall(CcCall cc, DataFlowCall call) { any() } + + class CcNoCall extends Cc { + CcNoCall() { this = false } + } + + Cc ccNone() { result = false } + + CcCall ccSomeCall() { result = true } + + class LocalCc = Unit; + + bindingset[node, cc] + LocalCc getLocalCc(NodeEx node, Cc cc) { any() } + + bindingset[call, c, outercc] + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + + bindingset[call, c, innercc] + CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } +} + +private module Level1CallContext { class Cc = CallContext; class CcCall = CallContextCall; + pragma[inline] + predicate matchesCall(CcCall cc, DataFlowCall call) { cc.matchesCall(call) } + class CcNoCall = CallContextNoCall; Cc ccNone() { result instanceof CallContextAny } CcCall ccSomeCall() { result instanceof CallContextSomeCall } - private class LocalCc = Unit; + module NoLocalCallContext { + class LocalCc = Unit; - bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { - checkCallContextCall(outercc, call, c) and - if recordDataFlowCallSiteDispatch(call, c) - then result = TSpecificCall(call) - else result = TSomeCall() + bindingset[node, cc] + LocalCc getLocalCc(NodeEx node, Cc cc) { any() } + + bindingset[call, c, outercc] + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } + } + + module LocalCallContext { + class LocalCc = LocalCallContext; + + bindingset[node, cc] + LocalCc getLocalCc(NodeEx node, Cc cc) { + result = + getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), + node.getEnclosingCallable()) + } + + bindingset[call, c, outercc] + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall() + } } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { checkCallContextReturn(innercc, c, call) and if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() } +} - bindingset[node, cc] - private LocalCc getLocalCc(NodeEx node, Cc cc) { any() } +private module Stage2Param implements MkStage::StageParam { + private module PrevStage = Stage1; + + class Ap extends boolean { + Ap() { this in [true, false] } + } + + class ApNil extends Ap { + ApNil() { this = false } + } + + bindingset[result, ap] + PrevStage::Ap getApprox(Ap ap) { any() } + + ApNil getApNil(NodeEx node) { Stage1::revFlow(node, _) and exists(result) } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result = true and exists(tc) and exists(tail) } + + pragma[inline] + Content getHeadContent(Ap ap) { exists(result) and ap = true } + + class ApOption = BooleanOption; + + ApOption apNone() { result = TBooleanNone() } + + ApOption apSome(Ap ap) { result = TBooleanSome(ap) } + + import Level1CallContext + import NoLocalCallContext bindingset[node1, state1, config] bindingset[node2, state2, config] - private predicate localStep( + predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { @@ -1221,9 +1906,9 @@ private module Stage2 { exists(lcc) } - private predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/5; - private predicate flowIntoCall = flowIntoCallNodeCand1/5; + predicate flowIntoCall = flowIntoCallNodeCand1/5; pragma[nomagic] private predicate expectsContentCand(NodeEx node, Configuration config) { @@ -1235,7 +1920,7 @@ private module Stage2 { } bindingset[node, state, ap, config] - private predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { PrevStage::revFlowState(state, pragma[only_bind_into](config)) and exists(ap) and not stateBarrier(node, state, config) and @@ -1248,542 +1933,11 @@ private module Stage2 { } bindingset[ap, contentType] - private predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } + predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } +} - /* Begin: Stage 2 logic. */ - bindingset[node, state, config] - private predicate flowCand(NodeEx node, FlowState state, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, state, _, _, apa, config) - } - - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) - } - - pragma[nomagic] - private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config - ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - ccc.matchesCall(call) - } - - /** - * Holds if `node` is reachable with access path `ap` from a source in the - * configuration `config`. - * - * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. - */ - pragma[nomagic] - predicate fwdFlow(NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, state, cc, argAp, ap, config) and - flowCand(node, state, unbindApa(getApprox(ap)), config) and - filter(node, state, ap, config) - } - - pragma[nomagic] - private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - sourceNode(node, state, config) and - (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and - argAp = apNone() and - ap = getApNil(node) - or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc) - | - localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 - or - localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil - ) - or - exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and - jumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and - additionalJumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and - additionalJumpStateStep(mid, state0, node, state, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - // store - exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) - ) - or - // read - exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) - ) - or - // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() - ) - or - // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) - or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) - } - - pragma[nomagic] - private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config - ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and - typecheckStore(ap1, contentType) - ) - } - - /** - * Holds if forward flow with access path `tail` reaches a store of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and - tc.getContent() = c and - cons = apCons(tc, tail) - ) - } - - pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config - ) { - fwdFlow(node1, state, cc, argAp, ap, config) and - PrevStage::readStepCand(node1, c, node2, config) and - getHeadContent(ap) = c - } - - pragma[nomagic] - private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config - ) { - exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config - ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an argument to `call` is reached in the flow covered by `fwdFlow` - * and data might flow through the target callable and back out at `call`. - */ - pragma[nomagic] - private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) - ) - } - - pragma[nomagic] - private predicate storeStepFwd( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config - ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and - ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) - } - - private predicate readStepFwd( - NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config - ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and - fwdFlowConsCand(ap1, c, ap2, config) - } - - pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) - } - - pragma[nomagic] - private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config - ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) - } - - /** - * Holds if `node` with access path `ap` is part of a path from a source to a - * sink in the configuration `config`. - * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. - */ - pragma[nomagic] - predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) - } - - pragma[nomagic] - private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - fwdFlow(node, state, _, _, ap, config) and - sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and - returnAp = apNone() and - ap instanceof ApNil - or - exists(NodeEx mid, FlowState state0 | - localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and - localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and - ap instanceof ApNil - ) - or - exists(NodeEx mid | - jumpStep(node, mid, config) and - revFlow(mid, state, _, _, ap, config) and - toReturn = false and - returnAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStateStep(node, state, mid, state0, config) and - revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, - pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - // store - exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and - revFlowConsCand(ap0, c, ap, config) - ) - or - // read - exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and - readStepFwd(node, ap, _, mid, ap0, config) - ) - or - // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false - or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - or - // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() - } - - pragma[nomagic] - private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config - ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and - storeStepFwd(node, ap, tc, mid, ap0, config) and - tc.getContent() = c - } - - /** - * Holds if reverse flow with access path `tail` reaches a read of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, _, tail, config) and - tail = pragma[only_bind_into](tail0) and - readStepFwd(_, cons, c, mid, tail0, config) - ) - } - - pragma[nomagic] - private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config - ) { - exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an output from `call` is reached in the flow covered by `revFlow` - * and data might flow through the target callable resulting in reverse flow - * reaching an argument of `call`. - */ - pragma[nomagic] - private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and - ccc.matchesCall(call) - ) - } - - pragma[nomagic] - predicate storeStepCand( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, - Configuration config - ) { - exists(Ap ap2, Content c | - PrevStage::storeStepCand(node1, _, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, _, tc, node2, _, _, config) and - revFlowConsCand(ap2, c, ap1, config) - ) - } - - predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { - exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and - readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _, - pragma[only_bind_into](config)) - ) - } - - predicate revFlow(NodeEx node, FlowState state, Configuration config) { - revFlow(node, state, _, _, _, config) - } - - pragma[nomagic] - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } - - // use an alias as a workaround for bad functionality-induced joins - pragma[nomagic] - predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } - - // use an alias as a workaround for bad functionality-induced joins - pragma[nomagic] - predicate revFlowAlias( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - revFlow(node, state, toReturn, returnAp, ap, config) - } - - private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepFwd(_, ap, tc, _, _, config) - } - - private predicate revConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepCand(_, ap, tc, _, _, config) - } - - private predicate validAp(Ap ap, Configuration config) { - revFlow(_, _, _, _, ap, config) and ap instanceof ApNil - or - exists(TypedContent head, Ap tail | - consCand(head, tail, config) and - ap = apCons(head, tail) - ) - } - - predicate consCand(TypedContent tc, Ap ap, Configuration config) { - revConsCand(tc, ap, config) and - validAp(ap, config) - } - - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config - ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() - } - - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) - ) - } - - pragma[nomagic] - predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - } - - predicate stats( - boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config - ) { - fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and - fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and - tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) - ) - or - fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and - fields = count(TypedContent f0 | consCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - states = count(FlowState state | revFlow(_, state, _, _, _, config)) and - tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) - ) - } - /* End: Stage 2 logic. */ +private module Stage2 implements StageSig { + import MkStage::Stage } pragma[nomagic] @@ -1883,14 +2037,13 @@ private module LocalFlowBigStep { ) { additionalLocalFlowStepNodeCand1(node1, node2, config) and state1 = state2 and - Stage2::revFlow(node1, pragma[only_bind_into](state1), _, _, false, - pragma[only_bind_into](config)) and - Stage2::revFlowAlias(node2, pragma[only_bind_into](state2), _, _, false, + Stage2::revFlow(node1, pragma[only_bind_into](state1), false, pragma[only_bind_into](config)) and + Stage2::revFlowAlias(node2, pragma[only_bind_into](state2), false, pragma[only_bind_into](config)) or additionalLocalStateStep(node1, state1, node2, state2, config) and - Stage2::revFlow(node1, state1, _, _, false, pragma[only_bind_into](config)) and - Stage2::revFlowAlias(node2, state2, _, _, false, pragma[only_bind_into](config)) + Stage2::revFlow(node1, state1, false, pragma[only_bind_into](config)) and + Stage2::revFlowAlias(node2, state2, false, pragma[only_bind_into](config)) } /** @@ -1967,26 +2120,24 @@ private module LocalFlowBigStep { private import LocalFlowBigStep -private module Stage3 { - module PrevStage = Stage2; - - class ApApprox = PrevStage::Ap; +private module Stage3Param implements MkStage::StageParam { + private module PrevStage = Stage2; class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } - private ApNil getApNil(NodeEx node) { + ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) } bindingset[tc, tail] - private Ap apCons(TypedContent tc, Ap tail) { result.getHead() = tc and exists(tail) } + Ap apCons(TypedContent tc, Ap tail) { result.getHead() = tc and exists(tail) } pragma[noinline] - private Content getHeadContent(Ap ap) { result = ap.getHead().getContent() } + Content getHeadContent(Ap ap) { result = ap.getHead().getContent() } class ApOption = AccessPathFrontOption; @@ -1994,44 +2145,18 @@ private module Stage3 { ApOption apSome(Ap ap) { result = TAccessPathFrontSome(ap) } - class Cc = boolean; + import BooleanCallContext - class CcCall extends Cc { - CcCall() { this = true } - - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } - - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } - - CcCall ccSomeCall() { result = true } - - private class LocalCc = Unit; - - bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } - - bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } - - bindingset[node, cc] - private LocalCc getLocalCc(NodeEx node, Cc cc) { any() } - - private predicate localStep( + predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - private predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/5; - private predicate flowIntoCall = flowIntoCallNodeCand2/5; + predicate flowIntoCall = flowIntoCallNodeCand2/5; pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2067,7 +2192,7 @@ private module Stage3 { private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } bindingset[node, state, ap, config] - private predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { exists(state) and exists(config) and not clear(node, ap, config) and @@ -2080,546 +2205,15 @@ private module Stage3 { } bindingset[ap, contentType] - private predicate typecheckStore(Ap ap, DataFlowType contentType) { + predicate typecheckStore(Ap ap, DataFlowType contentType) { // We need to typecheck stores here, since reverse flow through a getter // might have a different type here compared to inside the getter. compatibleTypes(ap.getType(), contentType) } +} - /* Begin: Stage 3 logic. */ - bindingset[node, state, config] - private predicate flowCand(NodeEx node, FlowState state, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, state, _, _, apa, config) - } - - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) - } - - pragma[nomagic] - private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config - ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - ccc.matchesCall(call) - } - - /** - * Holds if `node` is reachable with access path `ap` from a source in the - * configuration `config`. - * - * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. - */ - pragma[nomagic] - predicate fwdFlow(NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, state, cc, argAp, ap, config) and - flowCand(node, state, unbindApa(getApprox(ap)), config) and - filter(node, state, ap, config) - } - - pragma[nomagic] - private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - sourceNode(node, state, config) and - (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and - argAp = apNone() and - ap = getApNil(node) - or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc) - | - localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 - or - localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil - ) - or - exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and - jumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and - additionalJumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and - additionalJumpStateStep(mid, state0, node, state, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - // store - exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) - ) - or - // read - exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) - ) - or - // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() - ) - or - // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) - or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) - } - - pragma[nomagic] - private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config - ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and - typecheckStore(ap1, contentType) - ) - } - - /** - * Holds if forward flow with access path `tail` reaches a store of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and - tc.getContent() = c and - cons = apCons(tc, tail) - ) - } - - pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config - ) { - fwdFlow(node1, state, cc, argAp, ap, config) and - PrevStage::readStepCand(node1, c, node2, config) and - getHeadContent(ap) = c - } - - pragma[nomagic] - private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config - ) { - exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config - ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an argument to `call` is reached in the flow covered by `fwdFlow` - * and data might flow through the target callable and back out at `call`. - */ - pragma[nomagic] - private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) - ) - } - - pragma[nomagic] - private predicate storeStepFwd( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config - ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and - ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) - } - - private predicate readStepFwd( - NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config - ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and - fwdFlowConsCand(ap1, c, ap2, config) - } - - pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) - } - - pragma[nomagic] - private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config - ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) - } - - /** - * Holds if `node` with access path `ap` is part of a path from a source to a - * sink in the configuration `config`. - * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. - */ - pragma[nomagic] - predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) - } - - pragma[nomagic] - private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - fwdFlow(node, state, _, _, ap, config) and - sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and - returnAp = apNone() and - ap instanceof ApNil - or - exists(NodeEx mid, FlowState state0 | - localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and - localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and - ap instanceof ApNil - ) - or - exists(NodeEx mid | - jumpStep(node, mid, config) and - revFlow(mid, state, _, _, ap, config) and - toReturn = false and - returnAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStateStep(node, state, mid, state0, config) and - revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, - pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - // store - exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and - revFlowConsCand(ap0, c, ap, config) - ) - or - // read - exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and - readStepFwd(node, ap, _, mid, ap0, config) - ) - or - // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false - or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - or - // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() - } - - pragma[nomagic] - private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config - ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and - storeStepFwd(node, ap, tc, mid, ap0, config) and - tc.getContent() = c - } - - /** - * Holds if reverse flow with access path `tail` reaches a read of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, _, tail, config) and - tail = pragma[only_bind_into](tail0) and - readStepFwd(_, cons, c, mid, tail0, config) - ) - } - - pragma[nomagic] - private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config - ) { - exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an output from `call` is reached in the flow covered by `revFlow` - * and data might flow through the target callable resulting in reverse flow - * reaching an argument of `call`. - */ - pragma[nomagic] - private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and - ccc.matchesCall(call) - ) - } - - pragma[nomagic] - predicate storeStepCand( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, - Configuration config - ) { - exists(Ap ap2, Content c | - PrevStage::storeStepCand(node1, _, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, _, tc, node2, _, _, config) and - revFlowConsCand(ap2, c, ap1, config) - ) - } - - predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { - exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and - readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _, - pragma[only_bind_into](config)) - ) - } - - predicate revFlow(NodeEx node, FlowState state, Configuration config) { - revFlow(node, state, _, _, _, config) - } - - pragma[nomagic] - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } - - // use an alias as a workaround for bad functionality-induced joins - pragma[nomagic] - predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } - - // use an alias as a workaround for bad functionality-induced joins - pragma[nomagic] - predicate revFlowAlias( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - revFlow(node, state, toReturn, returnAp, ap, config) - } - - private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepFwd(_, ap, tc, _, _, config) - } - - private predicate revConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepCand(_, ap, tc, _, _, config) - } - - private predicate validAp(Ap ap, Configuration config) { - revFlow(_, _, _, _, ap, config) and ap instanceof ApNil - or - exists(TypedContent head, Ap tail | - consCand(head, tail, config) and - ap = apCons(head, tail) - ) - } - - predicate consCand(TypedContent tc, Ap ap, Configuration config) { - revConsCand(tc, ap, config) and - validAp(ap, config) - } - - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config - ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() - } - - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) - ) - } - - pragma[nomagic] - predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - } - - predicate stats( - boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config - ) { - fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and - fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and - tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) - ) - or - fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and - fields = count(TypedContent f0 | consCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - states = count(FlowState state | revFlow(_, state, _, _, _, config)) and - tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) - ) - } - /* End: Stage 3 logic. */ +private module Stage3 implements StageSig { + import MkStage::Stage } /** @@ -2644,7 +2238,7 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, _, _, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2828,26 +2422,24 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4 { - module PrevStage = Stage3; - - class ApApprox = PrevStage::Ap; +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; - private ApApprox getApprox(Ap ap) { result = ap.getFront() } + PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } - private ApNil getApNil(NodeEx node) { + ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TNil(node.getDataFlowType()) } bindingset[tc, tail] - private Ap apCons(TypedContent tc, Ap tail) { result = push(tc, tail) } + Ap apCons(TypedContent tc, Ap tail) { result = push(tc, tail) } pragma[noinline] - private Content getHeadContent(Ap ap) { result = ap.getHead().getContent() } + Content getHeadContent(Ap ap) { result = ap.getHead().getContent() } class ApOption = AccessPathApproxOption; @@ -2855,38 +2447,10 @@ private module Stage4 { ApOption apSome(Ap ap) { result = TAccessPathApproxSome(ap) } - class Cc = CallContext; + import Level1CallContext + import LocalCallContext - class CcCall = CallContextCall; - - class CcNoCall = CallContextNoCall; - - Cc ccNone() { result instanceof CallContextAny } - - CcCall ccSomeCall() { result instanceof CallContextSomeCall } - - private class LocalCc = LocalCallContext; - - bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { - checkCallContextCall(outercc, call, c) and - if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall() - } - - bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { - checkCallContextReturn(innercc, c, call) and - if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() - } - - bindingset[node, cc] - private LocalCc getLocalCc(NodeEx node, Cc cc) { - result = - getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), - node.getEnclosingCallable()) - } - - private predicate localStep( + predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { @@ -2894,575 +2458,40 @@ private module Stage4 { } pragma[nomagic] - private predicate flowOutOfCall( + predicate flowOutOfCall( DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and - PrevStage::revFlow(node2, pragma[only_bind_into](state), _, _, _, - pragma[only_bind_into](config)) and - PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, _, _, + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) ) } pragma[nomagic] - private predicate flowIntoCall( + predicate flowIntoCall( DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, Configuration config ) { exists(FlowState state | flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and - PrevStage::revFlow(node2, pragma[only_bind_into](state), _, _, _, - pragma[only_bind_into](config)) and - PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, _, _, + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) ) } bindingset[node, state, ap, config] - private predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { any() } + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { any() } // Type checking is not necessary here as it has already been done in stage 3. bindingset[ap, contentType] - private predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } - - /* Begin: Stage 4 logic. */ - bindingset[node, state, config] - private predicate flowCand(NodeEx node, FlowState state, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, state, _, _, apa, config) - } - - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) - } - - pragma[nomagic] - private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config - ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - ccc.matchesCall(call) - } - - /** - * Holds if `node` is reachable with access path `ap` from a source in the - * configuration `config`. - * - * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. - */ - pragma[nomagic] - predicate fwdFlow(NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, state, cc, argAp, ap, config) and - flowCand(node, state, unbindApa(getApprox(ap)), config) and - filter(node, state, ap, config) - } - - pragma[nomagic] - private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - sourceNode(node, state, config) and - (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and - argAp = apNone() and - ap = getApNil(node) - or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc) - | - localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 - or - localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil - ) - or - exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and - jumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and - additionalJumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and - additionalJumpStateStep(mid, state0, node, state, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - // store - exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) - ) - or - // read - exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) - ) - or - // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() - ) - or - // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) - or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) - } - - pragma[nomagic] - private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config - ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and - typecheckStore(ap1, contentType) - ) - } - - /** - * Holds if forward flow with access path `tail` reaches a store of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and - tc.getContent() = c and - cons = apCons(tc, tail) - ) - } - - pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config - ) { - fwdFlow(node1, state, cc, argAp, ap, config) and - PrevStage::readStepCand(node1, c, node2, config) and - getHeadContent(ap) = c - } - - pragma[nomagic] - private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config - ) { - exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config - ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an argument to `call` is reached in the flow covered by `fwdFlow` - * and data might flow through the target callable and back out at `call`. - */ - pragma[nomagic] - private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) - ) - } - - pragma[nomagic] - private predicate storeStepFwd( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config - ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and - ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) - } - - private predicate readStepFwd( - NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config - ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and - fwdFlowConsCand(ap1, c, ap2, config) - } - - pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) - } - - pragma[nomagic] - private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config - ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) - } - - /** - * Holds if `node` with access path `ap` is part of a path from a source to a - * sink in the configuration `config`. - * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. - */ - pragma[nomagic] - predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) - } - - pragma[nomagic] - private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - fwdFlow(node, state, _, _, ap, config) and - sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and - returnAp = apNone() and - ap instanceof ApNil - or - exists(NodeEx mid, FlowState state0 | - localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and - localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and - ap instanceof ApNil - ) - or - exists(NodeEx mid | - jumpStep(node, mid, config) and - revFlow(mid, state, _, _, ap, config) and - toReturn = false and - returnAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStateStep(node, state, mid, state0, config) and - revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, - pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - // store - exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and - revFlowConsCand(ap0, c, ap, config) - ) - or - // read - exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and - readStepFwd(node, ap, _, mid, ap0, config) - ) - or - // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false - or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - or - // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() - } - - pragma[nomagic] - private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config - ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and - storeStepFwd(node, ap, tc, mid, ap0, config) and - tc.getContent() = c - } - - /** - * Holds if reverse flow with access path `tail` reaches a read of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, _, tail, config) and - tail = pragma[only_bind_into](tail0) and - readStepFwd(_, cons, c, mid, tail0, config) - ) - } - - pragma[nomagic] - private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config - ) { - exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an output from `call` is reached in the flow covered by `revFlow` - * and data might flow through the target callable resulting in reverse flow - * reaching an argument of `call`. - */ - pragma[nomagic] - private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and - ccc.matchesCall(call) - ) - } - - pragma[nomagic] - predicate storeStepCand( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, - Configuration config - ) { - exists(Ap ap2, Content c | - PrevStage::storeStepCand(node1, _, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, _, tc, node2, _, _, config) and - revFlowConsCand(ap2, c, ap1, config) - ) - } - - predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { - exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and - readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _, - pragma[only_bind_into](config)) - ) - } - - predicate revFlow(NodeEx node, FlowState state, Configuration config) { - revFlow(node, state, _, _, _, config) - } - - pragma[nomagic] - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } - - // use an alias as a workaround for bad functionality-induced joins - pragma[nomagic] - predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } - - // use an alias as a workaround for bad functionality-induced joins - pragma[nomagic] - predicate revFlowAlias( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - revFlow(node, state, toReturn, returnAp, ap, config) - } - - private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepFwd(_, ap, tc, _, _, config) - } - - private predicate revConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepCand(_, ap, tc, _, _, config) - } - - private predicate validAp(Ap ap, Configuration config) { - revFlow(_, _, _, _, ap, config) and ap instanceof ApNil - or - exists(TypedContent head, Ap tail | - consCand(head, tail, config) and - ap = apCons(head, tail) - ) - } - - predicate consCand(TypedContent tc, Ap ap, Configuration config) { - revConsCand(tc, ap, config) and - validAp(ap, config) - } - - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config - ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() - } - - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) - ) - } - - pragma[nomagic] - predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - } - - predicate stats( - boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config - ) { - fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and - fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and - tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) - ) - or - fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and - fields = count(TypedContent f0 | consCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - states = count(FlowState state | revFlow(_, state, _, _, _, config)) and - tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) - ) - } - /* End: Stage 4 logic. */ + predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } +private module Stage4 = MkStage::Stage; + bindingset[conf, result] private Configuration unbindConf(Configuration conf) { exists(Configuration c | result = pragma[only_bind_into](c) and conf = pragma[only_bind_into](c)) @@ -3495,7 +2524,7 @@ private newtype TSummaryCtx = TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, _, _, config) + Stage4::revFlow(p, state, _, config) ) } @@ -3553,7 +2582,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, _, _, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -3667,7 +2696,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, _, _, ap.getApprox(), pragma[only_bind_into](config)) + Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -4207,7 +3236,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, _, _, apa, config) + Stage4::revFlow(result, _, apa, config) } /** @@ -4243,7 +3272,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, _, _, apa, config) and + Stage4::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } From f05da69392a226139a3982b642a17138341717a9 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 17 Nov 2022 16:50:58 +0000 Subject: [PATCH 664/796] Update shared library files for go to PR #10007 Merge commit: a3fb54c --- go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll | 2 +- go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index 340bfe280b7..468f8640a78 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -3061,7 +3061,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { else cc instanceof CallContextAny ) and sc instanceof SummaryCtxNone and - ap instanceof AccessPathNil + ap = TAccessPathNil(node.getDataFlowType()) } predicate isAtSink() { diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index 340bfe280b7..468f8640a78 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -3061,7 +3061,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { else cc instanceof CallContextAny ) and sc instanceof SummaryCtxNone and - ap instanceof AccessPathNil + ap = TAccessPathNil(node.getDataFlowType()) } predicate isAtSink() { From c2b64d454517736f086ad89a2e1b2f8af5413d66 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Mon, 21 Nov 2022 06:55:43 +0000 Subject: [PATCH 665/796] Update shared library files for go to PR #9867 Merge commit: c514c88 --- .../go/dataflow/internal/FlowSummaryImpl.qll | 47 +++++++++++++++++-- .../internal/FlowSummaryImplSpecific.qll | 7 +++ 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index 7abae2b105b..e00fc952e1c 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -240,6 +240,16 @@ module Public { */ predicate isAutoGenerated() { none() } } + + /** A callable with a flow summary stating there is no flow via the callable. */ + class NegativeSummarizedCallable extends SummarizedCallableBase { + NegativeSummarizedCallable() { negativeSummaryElement(this, _) } + + /** + * Holds if the negative summary is auto generated. + */ + predicate isAutoGenerated() { negativeSummaryElement(this, true) } + } } /** @@ -1094,7 +1104,7 @@ module Private { /** Provides a query predicate for outputting a set of relevant flow summaries. */ module TestOutput { - /** A flow summary to include in the `summary/3` query predicate. */ + /** A flow summary to include in the `summary/1` query predicate. */ abstract class RelevantSummarizedCallable instanceof SummarizedCallable { /** Gets the string representation of this callable used by `summary/1`. */ abstract string getCallableCsv(); @@ -1109,6 +1119,14 @@ module Private { string toString() { result = super.toString() } } + /** A flow summary to include in the `negativeSummary/1` query predicate. */ + abstract class RelevantNegativeSummarizedCallable instanceof NegativeSummarizedCallable { + /** Gets the string representation of this callable used by `summary/1`. */ + abstract string getCallableCsv(); + + string toString() { result = super.toString() } + } + /** Render the kind in the format used in flow summaries. */ private string renderKind(boolean preservesValue) { preservesValue = true and result = "value" @@ -1116,8 +1134,12 @@ module Private { preservesValue = false and result = "taint" } - private string renderProvenance(RelevantSummarizedCallable c) { - if c.(SummarizedCallable).isAutoGenerated() then result = "generated" else result = "manual" + private string renderProvenance(SummarizedCallable c) { + if c.isAutoGenerated() then result = "generated" else result = "manual" + } + + private string renderProvenanceNegative(NegativeSummarizedCallable c) { + if c.isAutoGenerated() then result = "generated" else result = "manual" } /** @@ -1132,8 +1154,23 @@ module Private { | c.relevantSummary(input, output, preservesValue) and csv = - c.getCallableCsv() + getComponentStackCsv(input) + ";" + getComponentStackCsv(output) + - ";" + renderKind(preservesValue) + ";" + renderProvenance(c) + c.getCallableCsv() // Callable information + + getComponentStackCsv(input) + ";" // input + + getComponentStackCsv(output) + ";" // output + + renderKind(preservesValue) + ";" // kind + + renderProvenance(c) // provenance + ) + } + + /** + * Holds if a negative flow summary `csv` exists (semi-colon separated format). Used for testing purposes. + * The syntax is: "namespace;type;name;signature;provenance"", + */ + query predicate negativeSummary(string csv) { + exists(RelevantNegativeSummarizedCallable c | + csv = + c.getCallableCsv() // Callable information + + renderProvenanceNegative(c) // provenance ) } } diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll index 2af6cde0d63..95029942380 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll @@ -72,6 +72,13 @@ predicate summaryElement( ) } +/** + * Holds if a negative flow summary exists for `c`, which means that there is no + * flow through `c`. The flag `generated` states whether the summary is autogenerated. + * Note. Negative flow summaries has not been implemented for Go. + */ +predicate negativeSummaryElement(SummarizedCallable c, boolean generated) { none() } + /** Gets the summary component for specification component `c`, if any. */ bindingset[c] SummaryComponent interpretComponentSpecific(string c) { From 569da2da6017f3c1512893c4dea65c22ab792ea2 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 25 Nov 2022 17:30:54 +0000 Subject: [PATCH 666/796] Update shared library files for go to PR #10127 Merge commit: e265b07 --- .../go/dataflow/internal/FlowSummaryImpl.qll | 29 +------------------ 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index e00fc952e1c..d857cdaa359 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -226,15 +226,6 @@ module Public { none() } - /** - * Holds if values stored inside `content` are cleared on objects passed as - * arguments at position `pos` to this callable. - * - * TODO: Remove once all languages support `WithoutContent` tokens. - */ - pragma[nomagic] - predicate clearsContent(ParameterPosition pos, ContentSet content) { none() } - /** * Holds if the summary is auto generated. */ @@ -328,23 +319,6 @@ module Private { SummaryComponentStack::singleton(TArgumentSummaryComponent(_))) and preservesValue = preservesValue1.booleanAnd(preservesValue2) ) - or - exists(ParameterPosition ppos, ContentSet cs | - c.clearsContent(ppos, cs) and - input = SummaryComponentStack::push(SummaryComponent::withoutContent(cs), output) and - output = SummaryComponentStack::argument(ppos) and - preservesValue = true - ) - } - - private class MkClearStack extends RequiredSummaryComponentStack { - override predicate required(SummaryComponent head, SummaryComponentStack tail) { - exists(SummarizedCallable sc, ParameterPosition ppos, ContentSet cs | - sc.clearsContent(ppos, cs) and - head = SummaryComponent::withoutContent(cs) and - tail = SummaryComponentStack::argument(ppos) - ) - } } /** @@ -945,8 +919,7 @@ module Private { AccessPath inSpec, AccessPath outSpec, string kind ) { summaryElement(this, inSpec, outSpec, kind, true) and - not summaryElement(this, _, _, _, false) and - not this.clearsContent(_, _) + not summaryElement(this, _, _, _, false) } private predicate relevantSummaryElement(AccessPath inSpec, AccessPath outSpec, string kind) { From 628230f14c15d6cee2ce231b5f696769d4ddf0ed Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 17 Nov 2022 16:56:18 +0000 Subject: [PATCH 667/796] Update shared library files for go to PR #10360 Merge commit: 569fad6 --- .../change-notes/2022-12-16-implicit-read-flowstates.md | 4 ++++ .../dataflow/internal/tainttracking1/TaintTrackingImpl.qll | 7 ++++++- .../dataflow/internal/tainttracking2/TaintTrackingImpl.qll | 7 ++++++- 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 go/ql/lib/change-notes/2022-12-16-implicit-read-flowstates.md diff --git a/go/ql/lib/change-notes/2022-12-16-implicit-read-flowstates.md b/go/ql/lib/change-notes/2022-12-16-implicit-read-flowstates.md new file mode 100644 index 00000000000..49b42f82eb1 --- /dev/null +++ b/go/ql/lib/change-notes/2022-12-16-implicit-read-flowstates.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed an issue in the taint tracking analysis where implicit reads were not allowed by default in sinks or additional taint steps that used flow states. diff --git a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll index e6ce1ada8d4..bf937b6de31 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -172,7 +172,12 @@ abstract class Configuration extends DataFlow::Configuration { } override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and + ( + this.isSink(node) or + this.isSink(node, _) or + this.isAdditionalTaintStep(node, _) or + this.isAdditionalTaintStep(node, _, _, _) + ) and defaultImplicitTaintRead(node, c) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll index e6ce1ada8d4..bf937b6de31 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @@ -172,7 +172,12 @@ abstract class Configuration extends DataFlow::Configuration { } override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and + ( + this.isSink(node) or + this.isSink(node, _) or + this.isAdditionalTaintStep(node, _) or + this.isAdditionalTaintStep(node, _, _, _) + ) and defaultImplicitTaintRead(node, c) } From 6ccfb4b4ba9d8fdc355fc0ba5e24914089668507 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 22 Nov 2022 07:40:28 +0000 Subject: [PATCH 668/796] Update shared library files for go to PR #10505 Merge commit: 8b424d1 --- go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll index 95b34f15dad..ae9c6f3f12e 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll @@ -709,7 +709,8 @@ private module Cached { */ pragma[nomagic] private DataFlowCallable viableImplInCallContextExt(DataFlowCall call, DataFlowCall ctx) { - result = viableImplInCallContext(call, ctx) + result = viableImplInCallContext(call, ctx) and + result = viableCallable(call) or result = viableCallableLambda(call, TDataFlowCallSome(ctx)) or From c9aef4ac9f9cab602cbc618e612627bf8631b168 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 22 Nov 2022 07:41:12 +0000 Subject: [PATCH 669/796] Update shared library files for go to PR #10575 Merge commit: 9f1bbf2 --- go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll | 10 +++------- .../lib/semmle/go/dataflow/internal/DataFlowImpl2.qll | 10 +++------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index 468f8640a78..2638347463b 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -598,13 +598,9 @@ private predicate hasSinkCallCtx(Configuration config) { } private module Stage1 implements StageSig { - class ApApprox = Unit; - class Ap = Unit; - class ApOption = Unit; - - class Cc = boolean; + private class Cc = boolean; /* Begin: Stage 1 logic. */ /** @@ -613,7 +609,7 @@ private module Stage1 implements StageSig { * The Boolean `cc` records whether the node is reached through an * argument in a call. */ - predicate fwdFlow(NodeEx node, Cc cc, Configuration config) { + private predicate fwdFlow(NodeEx node, Cc cc, Configuration config) { sourceNode(node, _, config) and if hasSourceCallCtx(config) then cc = true else cc = false or @@ -753,7 +749,7 @@ private module Stage1 implements StageSig { * the enclosing callable in order to reach a sink. */ pragma[nomagic] - predicate revFlow(NodeEx node, boolean toReturn, Configuration config) { + private predicate revFlow(NodeEx node, boolean toReturn, Configuration config) { revFlow0(node, toReturn, config) and fwdFlow(node, config) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index 468f8640a78..2638347463b 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -598,13 +598,9 @@ private predicate hasSinkCallCtx(Configuration config) { } private module Stage1 implements StageSig { - class ApApprox = Unit; - class Ap = Unit; - class ApOption = Unit; - - class Cc = boolean; + private class Cc = boolean; /* Begin: Stage 1 logic. */ /** @@ -613,7 +609,7 @@ private module Stage1 implements StageSig { * The Boolean `cc` records whether the node is reached through an * argument in a call. */ - predicate fwdFlow(NodeEx node, Cc cc, Configuration config) { + private predicate fwdFlow(NodeEx node, Cc cc, Configuration config) { sourceNode(node, _, config) and if hasSourceCallCtx(config) then cc = true else cc = false or @@ -753,7 +749,7 @@ private module Stage1 implements StageSig { * the enclosing callable in order to reach a sink. */ pragma[nomagic] - predicate revFlow(NodeEx node, boolean toReturn, Configuration config) { + private predicate revFlow(NodeEx node, boolean toReturn, Configuration config) { revFlow0(node, toReturn, config) and fwdFlow(node, config) } From d63f161f06feb0d6db997ff653403e89d17783c7 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 22 Nov 2022 07:42:23 +0000 Subject: [PATCH 670/796] Update shared library files for go to PR #10577 Merge commit: df2b586 --- go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll | 5 ++++- go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index 2638347463b..67e93ea7f6f 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -558,13 +558,16 @@ private predicate expectsContentEx(NodeEx n, Content c) { pragma[nomagic] private predicate notExpectsContent(NodeEx n) { not expectsContentCached(n.asNode(), _) } +pragma[nomagic] +private predicate hasReadStep(Content c, Configuration config) { read(_, c, _, config) } + pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and - read(_, tc.getContent(), _, config) and + hasReadStep(tc.getContent(), config) and stepFilter(node1, node2, config) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index 2638347463b..67e93ea7f6f 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -558,13 +558,16 @@ private predicate expectsContentEx(NodeEx n, Content c) { pragma[nomagic] private predicate notExpectsContent(NodeEx n) { not expectsContentCached(n.asNode(), _) } +pragma[nomagic] +private predicate hasReadStep(Content c, Configuration config) { read(_, c, _, config) } + pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and - read(_, tc.getContent(), _, config) and + hasReadStep(tc.getContent(), config) and stepFilter(node1, node2, config) } From 8957437a4cc4eab2093c094705c6a2200e2a4dec Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 22 Nov 2022 07:43:53 +0000 Subject: [PATCH 671/796] Update shared library files for go to PR #10691 Merge commit: 0e6735b --- .../go/dataflow/internal/FlowSummaryImpl.qll | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index d857cdaa359..a13c7cd1224 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -750,6 +750,27 @@ module Private { ) } + /** + * Holds if `p` can reach `n` in a summarized callable, using only value-preserving + * local steps. `clearsOrExpects` records whether any node on the path from `p` to + * `n` either clears or expects contents. + */ + private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExpects) { + viableParam(_, _, _, p) and + n = p and + clearsOrExpects = false + or + exists(Node mid, boolean clearsOrExpectsMid | + paramReachesLocal(p, mid, clearsOrExpectsMid) and + summaryLocalStep(mid, n, true) and + if + summaryClearsContent(n, _) or + summaryExpectsContent(n, _) + then clearsOrExpects = true + else clearsOrExpects = clearsOrExpectsMid + ) + } + /** * Holds if use-use flow starting from `arg` should be prohibited. * @@ -759,15 +780,11 @@ module Private { */ pragma[nomagic] predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) { - exists(ParamNode p, Node mid, ParameterPosition ppos, Node ret | + exists(ParamNode p, ParameterPosition ppos, Node ret | + paramReachesLocal(p, ret, true) and p = summaryArgParam0(_, arg, sc) and p.isParameterOf(_, pragma[only_bind_into](ppos)) and - summaryLocalStep(p, mid, true) and - summaryLocalStep(mid, ret, true) and isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos)) - | - summaryClearsContent(mid, _) or - summaryExpectsContent(mid, _) ) } From c19ab7bc85f9c8de243bb29dbb897e08dd3f4e28 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 22 Nov 2022 07:45:25 +0000 Subject: [PATCH 672/796] Update shared library files for go to PR #10744 Merge commit: 60fe370 --- go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll | 4 +++- go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. From 5c7f7328ff0ee205e59268201ac24bf807e20b1a Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 23 Nov 2022 11:41:54 +0000 Subject: [PATCH 673/796] Update shared library files for go to PR #10754 Merge commit: d6df69d --- .../lib/semmle/go/dataflow/internal/DataFlowImpl.qll | 11 ++++++++--- .../lib/semmle/go/dataflow/internal/DataFlowImpl2.qll | 11 ++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index c8d9d66e1b9..9053019a6d0 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -2927,12 +2927,17 @@ abstract private class PathNodeImpl extends PathNode { result = this.getASuccessorImpl() } - final PathNodeImpl getANonHiddenSuccessor() { - result = this.getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and + pragma[nomagic] + private PathNodeImpl getANonHiddenSuccessor0() { + result = this.getASuccessorIfHidden*() and not result.isHidden() } + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getANonHiddenSuccessor0() and + not this.isHidden() + } + abstract NodeEx getNodeEx(); predicate isHidden() { diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index c8d9d66e1b9..9053019a6d0 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -2927,12 +2927,17 @@ abstract private class PathNodeImpl extends PathNode { result = this.getASuccessorImpl() } - final PathNodeImpl getANonHiddenSuccessor() { - result = this.getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and + pragma[nomagic] + private PathNodeImpl getANonHiddenSuccessor0() { + result = this.getASuccessorIfHidden*() and not result.isHidden() } + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getANonHiddenSuccessor0() and + not this.isHidden() + } + abstract NodeEx getNodeEx(); predicate isHidden() { From 3006551eb12ffc1156bacafac31319d1f55d19d4 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 23 Nov 2022 11:45:05 +0000 Subject: [PATCH 674/796] Update shared library files for go to PR #10806 Merge commit: d79a7e8 --- .../go/dataflow/internal/DataFlowImpl.qll | 26 ++++++++++--------- .../go/dataflow/internal/DataFlowImpl2.qll | 26 ++++++++++--------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index 9053019a6d0..b5631b26b0b 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -838,13 +838,13 @@ private module Stage1 implements StageSig { * by `revFlow`. */ pragma[nomagic] - predicate revFlowIsReadAndStored(Content c, Configuration conf) { + additional predicate revFlowIsReadAndStored(Content c, Configuration conf) { revFlowConsCand(c, conf) and revFlowStore(c, _, _, conf) } pragma[nomagic] - predicate viableReturnPosOutNodeCandFwd1( + additional predicate viableReturnPosOutNodeCandFwd1( DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config ) { fwdFlowReturnPosition(pos, _, config) and @@ -860,7 +860,7 @@ private module Stage1 implements StageSig { } pragma[nomagic] - predicate viableParamArgNodeCandFwd1( + additional predicate viableParamArgNodeCandFwd1( DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config ) { viableParamArgEx(call, p, arg) and @@ -907,7 +907,7 @@ private module Stage1 implements StageSig { ) } - predicate revFlowState(FlowState state, Configuration config) { + additional predicate revFlowState(FlowState state, Configuration config) { exists(NodeEx node | sinkNode(node, state, config) and revFlow(node, _, pragma[only_bind_into](config)) and @@ -999,7 +999,7 @@ private module Stage1 implements StageSig { ) } - predicate stats( + additional predicate stats( boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and @@ -1260,7 +1260,7 @@ private module MkStage { * argument. */ pragma[nomagic] - predicate fwdFlow( + additional predicate fwdFlow( NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config ) { fwdFlow0(node, state, cc, argAp, ap, config) and @@ -1484,7 +1484,7 @@ private module MkStage { * the access path of the returned value. */ pragma[nomagic] - predicate revFlow( + additional predicate revFlow( NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { revFlow0(node, state, toReturn, returnAp, ap, config) and @@ -1662,7 +1662,7 @@ private module MkStage { ) } - predicate revFlow(NodeEx node, FlowState state, Configuration config) { + additional predicate revFlow(NodeEx node, FlowState state, Configuration config) { revFlow(node, state, _, _, _, config) } @@ -1675,11 +1675,13 @@ private module MkStage { // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] - predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + additional predicate revFlowAlias(NodeEx node, Configuration config) { + revFlow(node, _, _, _, _, config) + } // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] - predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) { + additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, state, ap, config) } @@ -1700,7 +1702,7 @@ private module MkStage { ) } - predicate consCand(TypedContent tc, Ap ap, Configuration config) { + additional predicate consCand(TypedContent tc, Ap ap, Configuration config) { revConsCand(tc, ap, config) and validAp(ap, config) } @@ -1742,7 +1744,7 @@ private module MkStage { ) } - predicate stats( + additional predicate stats( boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index 9053019a6d0..b5631b26b0b 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -838,13 +838,13 @@ private module Stage1 implements StageSig { * by `revFlow`. */ pragma[nomagic] - predicate revFlowIsReadAndStored(Content c, Configuration conf) { + additional predicate revFlowIsReadAndStored(Content c, Configuration conf) { revFlowConsCand(c, conf) and revFlowStore(c, _, _, conf) } pragma[nomagic] - predicate viableReturnPosOutNodeCandFwd1( + additional predicate viableReturnPosOutNodeCandFwd1( DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config ) { fwdFlowReturnPosition(pos, _, config) and @@ -860,7 +860,7 @@ private module Stage1 implements StageSig { } pragma[nomagic] - predicate viableParamArgNodeCandFwd1( + additional predicate viableParamArgNodeCandFwd1( DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config ) { viableParamArgEx(call, p, arg) and @@ -907,7 +907,7 @@ private module Stage1 implements StageSig { ) } - predicate revFlowState(FlowState state, Configuration config) { + additional predicate revFlowState(FlowState state, Configuration config) { exists(NodeEx node | sinkNode(node, state, config) and revFlow(node, _, pragma[only_bind_into](config)) and @@ -999,7 +999,7 @@ private module Stage1 implements StageSig { ) } - predicate stats( + additional predicate stats( boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and @@ -1260,7 +1260,7 @@ private module MkStage { * argument. */ pragma[nomagic] - predicate fwdFlow( + additional predicate fwdFlow( NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config ) { fwdFlow0(node, state, cc, argAp, ap, config) and @@ -1484,7 +1484,7 @@ private module MkStage { * the access path of the returned value. */ pragma[nomagic] - predicate revFlow( + additional predicate revFlow( NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config ) { revFlow0(node, state, toReturn, returnAp, ap, config) and @@ -1662,7 +1662,7 @@ private module MkStage { ) } - predicate revFlow(NodeEx node, FlowState state, Configuration config) { + additional predicate revFlow(NodeEx node, FlowState state, Configuration config) { revFlow(node, state, _, _, _, config) } @@ -1675,11 +1675,13 @@ private module MkStage { // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] - predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + additional predicate revFlowAlias(NodeEx node, Configuration config) { + revFlow(node, _, _, _, _, config) + } // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] - predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) { + additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, state, ap, config) } @@ -1700,7 +1702,7 @@ private module MkStage { ) } - predicate consCand(TypedContent tc, Ap ap, Configuration config) { + additional predicate consCand(TypedContent tc, Ap ap, Configuration config) { revConsCand(tc, ap, config) and validAp(ap, config) } @@ -1742,7 +1744,7 @@ private module MkStage { ) } - predicate stats( + additional predicate stats( boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and From 40eb4225242d4f08808a5b7aaab3c68d04b12e95 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 23 Nov 2022 11:52:11 +0000 Subject: [PATCH 675/796] Update shared library files for go to PR #10814 Merge commit: 6ef5fac --- .../go/dataflow/internal/DataFlowPrivate.qll | 2 + .../go/dataflow/internal/FlowSummaryImpl.qll | 55 ++++++++++++++++++- .../internal/FlowSummaryImplSpecific.qll | 3 + 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index dfc01b6c574..e8bb843a8d4 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -126,6 +126,8 @@ predicate jumpStep(Node n1, Node n2) { n1.(DataFlow::PostUpdateNode).getPreUpdateNode() = sendRead and n2 = recvRead ) + or + FlowSummaryImpl::Private::Steps::summaryJumpStep(n1, n2) } /** diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index a13c7cd1224..275569b4c02 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -61,6 +61,20 @@ module Public { /** Gets a summary component for a return of kind `rk`. */ SummaryComponent return(ReturnKind rk) { result = TReturnSummaryComponent(rk) } + + /** Gets a summary component for synthetic global `sg`. */ + SummaryComponent syntheticGlobal(SyntheticGlobal sg) { + result = TSyntheticGlobalSummaryComponent(sg) + } + + /** + * A synthetic global. This represents some form of global state, which + * summaries can read and write individually. + */ + abstract class SyntheticGlobal extends string { + bindingset[this] + SyntheticGlobal() { any() } + } } /** @@ -256,6 +270,7 @@ module Private { TParameterSummaryComponent(ArgumentPosition pos) or TArgumentSummaryComponent(ParameterPosition pos) or TReturnSummaryComponent(ReturnKind rk) or + TSyntheticGlobalSummaryComponent(SummaryComponent::SyntheticGlobal sg) or TWithoutContentSummaryComponent(ContentSet c) or TWithContentSummaryComponent(ContentSet c) @@ -563,6 +578,11 @@ module Private { getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), s.tail())), rk) ) + or + exists(SummaryComponent::SyntheticGlobal sg | + head = TSyntheticGlobalSummaryComponent(sg) and + result = getSyntheticGlobalType(sg) + ) ) or n = summaryNodeOutputState(c, s) and @@ -582,6 +602,11 @@ module Private { getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), s.tail())), pos) ) + or + exists(SummaryComponent::SyntheticGlobal sg | + head = TSyntheticGlobalSummaryComponent(sg) and + result = getSyntheticGlobalType(sg) + ) ) ) } @@ -692,6 +717,18 @@ module Private { ) } + /** + * Holds if there is a jump step from `pred` to `succ`, which is synthesized + * from a flow summary. + */ + predicate summaryJumpStep(Node pred, Node succ) { + exists(SummaryComponentStack s | + s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and + pred = summaryNodeOutputState(_, s) and + succ = summaryNodeInputState(_, s) + ) + } + /** * Holds if values stored inside content `c` are cleared at `n`. `n` is a * synthesized summary node, so in order for values to be cleared at calls @@ -871,18 +908,28 @@ module Private { AccessPathRange() { relevantSpec(this) } } - /** Holds if specification component `c` parses as parameter `n`. */ + /** Holds if specification component `token` parses as parameter `pos`. */ predicate parseParam(AccessPathToken token, ArgumentPosition pos) { token.getName() = "Parameter" and pos = parseParamBody(token.getAnArgument()) } - /** Holds if specification component `c` parses as argument `n`. */ + /** Holds if specification component `token` parses as argument `pos`. */ predicate parseArg(AccessPathToken token, ParameterPosition pos) { token.getName() = "Argument" and pos = parseArgBody(token.getAnArgument()) } + /** Holds if specification component `token` parses as synthetic global `sg`. */ + predicate parseSynthGlobal(AccessPathToken token, string sg) { + token.getName() = "SyntheticGlobal" and + sg = token.getAnArgument() + } + + private class SyntheticGlobalFromAccessPath extends SummaryComponent::SyntheticGlobal { + SyntheticGlobalFromAccessPath() { parseSynthGlobal(_, this) } + } + private SummaryComponent interpretComponent(AccessPathToken token) { exists(ParameterPosition pos | parseArg(token, pos) and result = SummaryComponent::argument(pos) @@ -894,6 +941,10 @@ module Private { or token = "ReturnValue" and result = SummaryComponent::return(getReturnValueKind()) or + exists(string sg | + parseSynthGlobal(token, sg) and result = SummaryComponent::syntheticGlobal(sg) + ) + or result = interpretComponentSpecific(token) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll index 95029942380..5087403f3b4 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll @@ -56,6 +56,9 @@ DataFlowType getCallbackParameterType(DataFlowType t, int i) { none() } */ DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { none() } +/** Gets the type of synthetic global `sg`. */ +DataFlowType getSyntheticGlobalType(SummaryComponent::SyntheticGlobal sg) { none() } + /** * Holds if an external flow summary exists for `c` with input specification * `input`, output specification `output`, kind `kind`, and a flag `generated` From 804d131d3be23f80e373bc1120ccb54844de723b Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 23 Nov 2022 11:53:35 +0000 Subject: [PATCH 676/796] Update shared library files for go to PR #11060 Merge commit: 587e673 --- .../go/dataflow/internal/DataFlowImpl.qll | 144 ++++++++++-------- .../go/dataflow/internal/DataFlowImpl2.qll | 144 ++++++++++-------- 2 files changed, 158 insertions(+), 130 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index b5631b26b0b..8cd1071d084 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { } } -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source are generated. - */ -class PathNode extends TPathNode { - /** Gets a textual representation of this element. */ - string toString() { none() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - string toStringWithContext() { none() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - none() - } - - /** Gets the underlying `Node`. */ - final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result } - +abstract private class PathNodeImpl extends TPathNode { /** Gets the `FlowState` of this node. */ - FlowState getState() { none() } + abstract FlowState getState(); /** Gets the associated configuration. */ - Configuration getConfiguration() { none() } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { - result = this.(PathNodeImpl).getANonHiddenSuccessor() and - reach(this) and - reach(result) - } + abstract Configuration getConfiguration(); /** Holds if this node is a source. */ - predicate isSource() { none() } -} + abstract predicate isSource(); -abstract private class PathNodeImpl extends PathNode { abstract PathNodeImpl getASuccessorImpl(); private PathNodeImpl getASuccessorIfHidden() { @@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode { result = " <" + this.(PathNodeMid).getCallContext().toString() + ">" } - override string toString() { result = this.getNodeEx().toString() + this.ppAp() } + /** Gets a textual representation of this element. */ + string toString() { result = this.getNodeEx().toString() + this.ppAp() } - override string toStringWithContext() { - result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() - } + /** + * Gets a textual representation of this element, including a textual + * representation of the call context. + */ + string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() } - override predicate hasLocationInfo( + /** + * Holds if this element is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ + predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) @@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) { } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ -private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } +private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNodeImpl n1, PathNode n2) { +private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) { n1.getANonHiddenSuccessor() = n2 and directReach(n2) } -private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) +private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2) + +/** + * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. + * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. + */ +class PathNode instanceof PathNodeImpl { + PathNode() { reach(this) } + + /** Gets a textual representation of this element. */ + final string toString() { result = super.toString() } + + /** + * Gets a textual representation of this element, including a textual + * representation of the call context. + */ + final string toStringWithContext() { result = super.toStringWithContext() } + + /** + * Holds if this element is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ + final predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } + + /** Gets the underlying `Node`. */ + final Node getNode() { super.getNodeEx().projectToNode() = result } + + /** Gets the `FlowState` of this node. */ + final FlowState getState() { result = super.getState() } + + /** Gets the associated configuration. */ + final Configuration getConfiguration() { result = super.getConfiguration() } + + /** Gets a successor of this node, if any. */ + final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() } + + /** Holds if this node is a source. */ + final predicate isSource() { super.isSource() } +} /** * Provides the query predicates needed to include a graph in a path-problem query. @@ -3004,7 +3021,7 @@ module PathGraph { /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { - reach(n) and key = "semmle.label" and val = n.toString() + key = "semmle.label" and val = n.toString() } /** @@ -3013,11 +3030,7 @@ module PathGraph { * `ret -> out` is summarized as the edge `arg -> out`. */ query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) { - Subpaths::subpaths(arg, par, ret, out) and - reach(arg) and - reach(par) and - reach(ret) and - reach(out) + Subpaths::subpaths(arg, par, ret, out) } } @@ -3399,7 +3412,7 @@ private module Subpaths { */ pragma[nomagic] private predicate subpaths02( - PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, NodeEx out, FlowState sout, AccessPath apout ) { subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and @@ -3407,14 +3420,14 @@ private module Subpaths { } pragma[nomagic] - private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() } /** * Holds if `(arg, par, ret, out)` forms a subpath-tuple. */ pragma[nomagic] private predicate subpaths03( - PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout + PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout ) { exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and @@ -3444,7 +3457,7 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and @@ -3460,7 +3473,7 @@ private module Subpaths { * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ predicate retReach(PathNodeImpl n) { - exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) + exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or exists(PathNodeImpl mid | retReach(mid) and @@ -3477,11 +3490,12 @@ private module Subpaths { * sinks. */ private predicate flowsTo( - PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration + PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, + Configuration configuration ) { flowsource.isSource() and flowsource.getConfiguration() = configuration and - flowsource.(PathNodeImpl).getNodeEx().asNode() = source and + flowsource.getNodeEx().asNode() = source and (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and flowsink.getNodeEx().asNode() = sink } @@ -3504,14 +3518,14 @@ private predicate finalStats( fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and - tuples = count(PathNode pn) + tuples = count(PathNodeImpl pn) or fwd = false and nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and - tuples = count(PathNode pn | reach(pn)) + tuples = count(PathNode pn) } /** diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index b5631b26b0b..8cd1071d084 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { } } -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source are generated. - */ -class PathNode extends TPathNode { - /** Gets a textual representation of this element. */ - string toString() { none() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - string toStringWithContext() { none() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - none() - } - - /** Gets the underlying `Node`. */ - final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result } - +abstract private class PathNodeImpl extends TPathNode { /** Gets the `FlowState` of this node. */ - FlowState getState() { none() } + abstract FlowState getState(); /** Gets the associated configuration. */ - Configuration getConfiguration() { none() } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { - result = this.(PathNodeImpl).getANonHiddenSuccessor() and - reach(this) and - reach(result) - } + abstract Configuration getConfiguration(); /** Holds if this node is a source. */ - predicate isSource() { none() } -} + abstract predicate isSource(); -abstract private class PathNodeImpl extends PathNode { abstract PathNodeImpl getASuccessorImpl(); private PathNodeImpl getASuccessorIfHidden() { @@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode { result = " <" + this.(PathNodeMid).getCallContext().toString() + ">" } - override string toString() { result = this.getNodeEx().toString() + this.ppAp() } + /** Gets a textual representation of this element. */ + string toString() { result = this.getNodeEx().toString() + this.ppAp() } - override string toStringWithContext() { - result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() - } + /** + * Gets a textual representation of this element, including a textual + * representation of the call context. + */ + string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() } - override predicate hasLocationInfo( + /** + * Holds if this element is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ + predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) @@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) { } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ -private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } +private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNodeImpl n1, PathNode n2) { +private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) { n1.getANonHiddenSuccessor() = n2 and directReach(n2) } -private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) +private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2) + +/** + * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. + * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. + */ +class PathNode instanceof PathNodeImpl { + PathNode() { reach(this) } + + /** Gets a textual representation of this element. */ + final string toString() { result = super.toString() } + + /** + * Gets a textual representation of this element, including a textual + * representation of the call context. + */ + final string toStringWithContext() { result = super.toStringWithContext() } + + /** + * Holds if this element is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ + final predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } + + /** Gets the underlying `Node`. */ + final Node getNode() { super.getNodeEx().projectToNode() = result } + + /** Gets the `FlowState` of this node. */ + final FlowState getState() { result = super.getState() } + + /** Gets the associated configuration. */ + final Configuration getConfiguration() { result = super.getConfiguration() } + + /** Gets a successor of this node, if any. */ + final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() } + + /** Holds if this node is a source. */ + final predicate isSource() { super.isSource() } +} /** * Provides the query predicates needed to include a graph in a path-problem query. @@ -3004,7 +3021,7 @@ module PathGraph { /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { - reach(n) and key = "semmle.label" and val = n.toString() + key = "semmle.label" and val = n.toString() } /** @@ -3013,11 +3030,7 @@ module PathGraph { * `ret -> out` is summarized as the edge `arg -> out`. */ query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) { - Subpaths::subpaths(arg, par, ret, out) and - reach(arg) and - reach(par) and - reach(ret) and - reach(out) + Subpaths::subpaths(arg, par, ret, out) } } @@ -3399,7 +3412,7 @@ private module Subpaths { */ pragma[nomagic] private predicate subpaths02( - PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, NodeEx out, FlowState sout, AccessPath apout ) { subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and @@ -3407,14 +3420,14 @@ private module Subpaths { } pragma[nomagic] - private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() } /** * Holds if `(arg, par, ret, out)` forms a subpath-tuple. */ pragma[nomagic] private predicate subpaths03( - PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout + PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout ) { exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and @@ -3444,7 +3457,7 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and @@ -3460,7 +3473,7 @@ private module Subpaths { * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ predicate retReach(PathNodeImpl n) { - exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) + exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or exists(PathNodeImpl mid | retReach(mid) and @@ -3477,11 +3490,12 @@ private module Subpaths { * sinks. */ private predicate flowsTo( - PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration + PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, + Configuration configuration ) { flowsource.isSource() and flowsource.getConfiguration() = configuration and - flowsource.(PathNodeImpl).getNodeEx().asNode() = source and + flowsource.getNodeEx().asNode() = source and (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and flowsink.getNodeEx().asNode() = sink } @@ -3504,14 +3518,14 @@ private predicate finalStats( fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and - tuples = count(PathNode pn) + tuples = count(PathNodeImpl pn) or fwd = false and nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and - tuples = count(PathNode pn | reach(pn)) + tuples = count(PathNode pn) } /** From 309ab772da28fda18632eeb0d2a0f18cabe4a17e Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 23 Nov 2022 11:55:26 +0000 Subject: [PATCH 677/796] Update shared library files for go to PR #10886 Merge commit: 99ca28e --- go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll | 6 ++++++ go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index 8cd1071d084..2dde1c2819d 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration /** * Gets the number of `AccessPath`s that correspond to `apa`. */ +pragma[assume_small_delta] private int countAps(AccessPathApprox apa, Configuration config) { evalUnfold(apa, false, config) and result = 1 and @@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) { * that it is expanded to a precise head-tail representation. */ language[monotonicAggregates] +pragma[assume_small_delta] private int countPotentialAps(AccessPathApprox apa, Configuration config) { apa instanceof AccessPathApproxNil and result = 1 or @@ -2681,6 +2683,7 @@ private newtype TAccessPath = } private newtype TPathNode = + pragma[assume_small_delta] TPathNodeMid( NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { @@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons { override AccessPathFrontHead getFront() { result = TFrontHead(head) } + pragma[assume_small_delta] override AccessPathApproxCons getApprox() { result = TConsNil(head, tail.(AccessPathNil).getType()) or @@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons { result = TCons1(head, this.length()) } + pragma[assume_small_delta] override int length() { result = 1 + tail.length() } private string toStringImpl(boolean needsSuffix) { @@ -3155,6 +3160,7 @@ private predicate pathNode( * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ +pragma[assume_small_delta] pragma[nomagic] private predicate pathStep( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index 8cd1071d084..2dde1c2819d 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration /** * Gets the number of `AccessPath`s that correspond to `apa`. */ +pragma[assume_small_delta] private int countAps(AccessPathApprox apa, Configuration config) { evalUnfold(apa, false, config) and result = 1 and @@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) { * that it is expanded to a precise head-tail representation. */ language[monotonicAggregates] +pragma[assume_small_delta] private int countPotentialAps(AccessPathApprox apa, Configuration config) { apa instanceof AccessPathApproxNil and result = 1 or @@ -2681,6 +2683,7 @@ private newtype TAccessPath = } private newtype TPathNode = + pragma[assume_small_delta] TPathNodeMid( NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { @@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons { override AccessPathFrontHead getFront() { result = TFrontHead(head) } + pragma[assume_small_delta] override AccessPathApproxCons getApprox() { result = TConsNil(head, tail.(AccessPathNil).getType()) or @@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons { result = TCons1(head, this.length()) } + pragma[assume_small_delta] override int length() { result = 1 + tail.length() } private string toStringImpl(boolean needsSuffix) { @@ -3155,6 +3160,7 @@ private predicate pathNode( * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ +pragma[assume_small_delta] pragma[nomagic] private predicate pathStep( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap From b63d0892ab7b6ea87e5b4bc2b70a9783dd8fc45f Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 23 Nov 2022 11:58:16 +0000 Subject: [PATCH 678/796] Update shared library files for go to PR #10777 Merge commit: 9c6875e --- go/ql/lib/semmle/go/dataflow/internal/AccessPathSyntax.qll | 2 +- go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/AccessPathSyntax.qll b/go/ql/lib/semmle/go/dataflow/internal/AccessPathSyntax.qll index 076e12f2671..0c3dc8427b2 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/AccessPathSyntax.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/AccessPathSyntax.qll @@ -1,5 +1,5 @@ /** - * Module for parsing access paths from CSV models, both the identifying access path used + * Module for parsing access paths from MaD models, both the identifying access path used * by dynamic languages, and the input/output specifications for summary steps. * * This file is used by the shared data flow library and by the JavaScript libraries diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index 275569b4c02..4d41254e5e9 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -892,7 +892,7 @@ module Private { } /** - * Provides a means of translating externally (e.g., CSV) defined flow + * Provides a means of translating externally (e.g., MaD) defined flow * summaries into a `SummarizedCallable`s. */ module External { @@ -1121,7 +1121,7 @@ module Private { } /** - * Holds if `node` is specified as a source with the given kind in a CSV flow + * Holds if `node` is specified as a source with the given kind in a MaD flow * model. */ predicate isSourceNode(InterpretNode node, string kind) { @@ -1132,7 +1132,7 @@ module Private { } /** - * Holds if `node` is specified as a sink with the given kind in a CSV flow + * Holds if `node` is specified as a sink with the given kind in a MaD flow * model. */ predicate isSinkNode(InterpretNode node, string kind) { From d9f8420c8660527eb77a096ffb7f594f5e8c6be3 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 23 Nov 2022 12:07:39 +0000 Subject: [PATCH 679/796] Update shared library files for go to PR #11183 Merge commit: 94bca43 --- .../go/dataflow/internal/DataFlowImpl.qll | 114 +++++++++++++++++- .../go/dataflow/internal/DataFlowImpl2.qll | 114 +++++++++++++++++- 2 files changed, 222 insertions(+), 6 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index 2dde1c2819d..3c41b1876dc 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -2712,6 +2718,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3495,6 +3594,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration From 818f02826c7f3408e5bfea2e39c3dba6fd844935 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 29 Nov 2022 14:17:27 +0000 Subject: [PATCH 680/796] Update shared library files for go to f3dca95 --- .../go/dataflow/internal/DataFlowImpl.qll | 500 ++++++++++-------- .../go/dataflow/internal/DataFlowImpl2.qll | 500 ++++++++++-------- .../dataflow/internal/DataFlowImplCommon.qll | 49 ++ 3 files changed, 617 insertions(+), 432 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index 3c41b1876dc..e4cfd5986be 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,38 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +1011,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,12 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1087,10 +1122,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1099,10 +1135,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1152,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1136,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1194,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1262,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1262,29 +1303,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1339,82 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParameterPositionNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1427,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1435,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1396,29 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, + Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1428,11 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + pos = param.getPosition() ) } @@ -1440,27 +1493,40 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config + ) { + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1468,118 +1534,130 @@ private module MkStage { private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(kind) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,35 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1638,11 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1784,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1754,14 +1824,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1769,8 +1838,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1984,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2091,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2233,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2303,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2580,14 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + c = n.getEnclosingCallable() and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -2532,7 +2606,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3527,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index 3c41b1876dc..e4cfd5986be 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -319,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -608,6 +606,38 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + +/** + * Holds if flow from a parameter at position `pos` inside `c` to a return node of + * kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[c, pos, kind] +private predicate parameterFlowThroughAllowed( + DataFlowCallable c, ParameterPosition pos, ReturnKindExt kind +) { + exists(ParamNodeEx p | + p.isParameterOf(c, pos) and + parameterFlowThroughAllowed(p, kind) + ) +} + private module Stage1 implements StageSig { class Ap = Unit; @@ -981,21 +1011,22 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1052,12 +1083,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1087,10 +1122,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1099,10 +1135,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1115,12 +1152,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1136,10 +1174,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1156,7 +1194,9 @@ private signature module StageSig { predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1222,7 +1262,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1247,14 +1288,14 @@ private module MkStage { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, DataFlowCallable c, CcCall ccc, RetNodeEx ret, ReturnKindExt kind, + NodeEx out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + PrevStage::returnMayFlowThrough(ret, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) and + c = ret.getEnclosingCallable() } /** @@ -1262,29 +1303,32 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, config) and PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and filter(node, state, ap, config) } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and + summaryCtx = TParameterPositionNone() and ap = getApNil(node) or exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and @@ -1295,65 +1339,82 @@ private module MkStage { ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParameterPositionNone() and argAp = apNone() and ap = getApNil(node) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and ap = apCons(tc, ap0) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and fwdFlowConsCand(ap0, c, ap, config) ) or // flow into a callable exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and + fwdFlowIn(_, node, state, _, cc, _, _, ap, config) and apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParameterPositionNone() and argAp = apNone() + ) ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, config) and + flowOutOfCall(call, ret, _, node, allowsFieldFlow, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 | + fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config) ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, config) and PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) @@ -1366,7 +1427,7 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) @@ -1374,21 +1435,21 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParameterPositionOption summaryCtx, ApOption argAp, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, + ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, config) and flowIntoCall(call, arg, p, allowsFieldFlow, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1396,29 +1457,19 @@ private module MkStage { } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutFromArg( + DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap, + Configuration config ) { exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner + DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + fwdFlow(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), + TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, config) and + flowThroughOutOfCall(call, pragma[only_bind_into](c), ccc, ret, kind, out, allowsFieldFlow, + config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(c, pragma[only_bind_into](summaryCtx), kind) ) } @@ -1428,11 +1479,13 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + ParameterPosition pos, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ParamNodeEx param | + fwdFlowIn(call, param, _, cc, _, summaryCtx, argAp, ap, config) and + PrevStage::parameterMayFlowThrough(param, unbindApa(getApprox(ap)), config) and + pos = param.getPosition() ) } @@ -1440,27 +1493,40 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + private predicate returnFlowsThrough0( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, DataFlowCallable c, + ParameterPosition ppos, Ap argAp, Ap ap, Configuration config + ) { + exists(boolean allowsFieldFlow | + fwdFlow(ret, state, ccc, TParameterPositionSome(ppos), apSome(argAp), ap, config) and + flowThroughOutOfCall(_, c, _, pragma[only_bind_into](ret), kind, _, allowsFieldFlow, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCallable c, ParameterPosition ppos | + returnFlowsThrough0(ret, kind, state, ccc, c, ppos, argAp, ap, config) and + p.isParameterOf(c, ppos) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1468,118 +1534,130 @@ private module MkStage { private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config - ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(Ap argAp | + flowIntoCall(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), allowsFieldFlow, + pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _, + pragma[only_bind_into](config)) + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCall(_, node, p, allowsFieldFlow, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 | + revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnKindExt kind | + revFlowOut(_, node, kind, state, _, _, ap, config) and + if returnFlowsThrough(node, kind, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(kind) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1599,35 +1677,27 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, + Configuration config ) { exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and + revFlow(pragma[only_bind_into](p), state, + TReturnCtxMaybeFlowThrough(pragma[only_bind_into](kind)), apSome(returnAp), ap, config) and flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + parameterFlowThroughAllowed(p, kind) ) } @@ -1638,11 +1708,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1713,40 +1784,39 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnKindExt kind, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(_), ap, config) and + parameterFlowThroughAllowed(p, kind) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnKindExt kind | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind, Configuration config) { + exists(ParamNodeEx p, Ap ap | + returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, kind, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap + ReturnKindExt returnKind0, Ap returnAp0, ArgNodeEx arg, FlowState state, + ReturnCtx returnCtx, ApOption returnAp, Ap ap | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config) ) } @@ -1754,14 +1824,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) - ) + count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp, + Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and @@ -1769,8 +1838,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1915,7 +1984,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1951,9 +2020,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2021,8 +2091,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2163,7 +2233,7 @@ private module Stage3Param implements MkStage::StageParam { localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; predicate flowIntoCall = flowIntoCallNodeCand2/5; @@ -2233,8 +2303,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage3::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2468,10 +2539,11 @@ private module Stage4Param implements MkStage::StageParam { pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2508,13 +2580,14 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa, + Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + c = n.getEnclosingCallable() and + Stage4::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage4::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2522,9 +2595,10 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p | + Stage4::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, c, pos, state, apa, config) and + p.isParameterOf(c, pos) ) } @@ -2532,7 +2606,7 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and + Stage4::parameterMayFlowThrough(p, ap.getApprox(), config) and Stage4::revFlow(p, state, _, config) ) } @@ -3453,17 +3527,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll index ae9c6f3f12e..f981834a6d4 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll @@ -915,6 +915,17 @@ private module Cached { TDataFlowCallNone() or TDataFlowCallSome(DataFlowCall call) + cached + newtype TParameterPositionOption = + TParameterPositionNone() or + TParameterPositionSome(ParameterPosition pos) + + cached + newtype TReturnCtx = + TReturnCtxNone() or + TReturnCtxNoFlowThrough() or + TReturnCtxMaybeFlowThrough(ReturnKindExt kind) + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -1304,6 +1315,44 @@ class DataFlowCallOption extends TDataFlowCallOption { } } +/** An optional `ParameterPosition`. */ +class ParameterPositionOption extends TParameterPositionOption { + string toString() { + this = TParameterPositionNone() and + result = "(none)" + or + exists(ParameterPosition pos | + this = TParameterPositionSome(pos) and + result = pos.toString() + ) + } +} + +/** + * A return context used to calculate flow summaries in reverse flow. + * + * The possible values are: + * + * - `TReturnCtxNone()`: no return flow. + * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. + * - `TReturnCtxMaybeFlowThrough(ReturnKindExt kind)`: return flow, of kind `kind`, and + * flow through may be possible. + */ +class ReturnCtx extends TReturnCtx { + string toString() { + this = TReturnCtxNone() and + result = "(none)" + or + this = TReturnCtxNoFlowThrough() and + result = "(no flow through)" + or + exists(ReturnKindExt kind | + this = TReturnCtxMaybeFlowThrough(kind) and + result = kind.toString() + ) + } +} + /** A `Content` tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; From 1731d391198223416688ed523773b43f20eacaa7 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 29 Nov 2022 14:24:20 +0000 Subject: [PATCH 681/796] Remove sync-dataflow-libraries from go makefile --- go/Makefile | 7 ------- 1 file changed, 7 deletions(-) diff --git a/go/Makefile b/go/Makefile index 47f4cc0f801..900508ee6cb 100644 --- a/go/Makefile +++ b/go/Makefile @@ -132,10 +132,3 @@ build/testdb/go.dbscheme: ql/lib/upgrades/initial/go.dbscheme rm -rf build/testdb echo >build/empty.trap codeql dataset import -S ql/lib/upgrades/initial/go.dbscheme build/testdb build/empty.trap - -.PHONY: sync-dataflow-libraries -sync-dataflow-libraries: - for f in DataFlowImpl.qll DataFlowImpl2.qll DataFlowImplCommon.qll tainttracking1/TaintTrackingImpl.qll tainttracking2/TaintTrackingImpl.qll FlowSummaryImpl.qll AccessPathSyntax.qll;\ - do\ - curl -s -o ./ql/lib/semmle/go/dataflow/internal/$$f https://raw.githubusercontent.com/github/codeql/$(DATAFLOW_BRANCH)/java/ql/lib/semmle/code/java/dataflow/internal/$$f;\ - done From 5c5ec8f66a2c4bd8a8410007301e2c25730abc8d Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 29 Nov 2022 15:38:41 +0000 Subject: [PATCH 682/796] Add go files to identical-files.json --- config/identical-files.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/config/identical-files.json b/config/identical-files.json index 20d7dbc3606..bdce064e269 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -27,6 +27,8 @@ "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll", + "go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll", + "go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll", "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll", "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll", "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll", @@ -44,6 +46,7 @@ "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll", "cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll", + "go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll", "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll", "ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll", "swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll" @@ -62,6 +65,8 @@ "csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll", + "go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", + "go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", "java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", "java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", "java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingImpl.qll", @@ -85,6 +90,7 @@ "DataFlow Java/C#/Ruby/Python/Swift Flow Summaries": [ "java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll", + "go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll", "ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll", "python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll", "swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll" @@ -505,6 +511,7 @@ ], "AccessPathSyntax": [ "csharp/ql/lib/semmle/code/csharp/dataflow/internal/AccessPathSyntax.qll", + "go/ql/lib/semmle/go/dataflow/internal/AccessPathSyntax.qll", "java/ql/lib/semmle/code/java/dataflow/internal/AccessPathSyntax.qll", "javascript/ql/lib/semmle/javascript/frameworks/data/internal/AccessPathSyntax.qll", "ruby/ql/lib/codeql/ruby/dataflow/internal/AccessPathSyntax.qll", From 083a3bae6ec59a3276215a9e05ceca22966ba145 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 29 Nov 2022 15:42:40 +0000 Subject: [PATCH 683/796] Correct headings in identical-files.json --- config/identical-files.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config/identical-files.json b/config/identical-files.json index bdce064e269..0a5d037e226 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -1,5 +1,5 @@ { - "DataFlow Java/C++/C#/Python": [ + "DataFlow Java/C++/C#/Go/Python/Ruby/Swift": [ "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll", "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll", "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll", @@ -40,7 +40,7 @@ "ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll", "swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll" ], - "DataFlow Java/C++/C#/Python Common": [ + "DataFlow Java/C++/C#/Go/Python/Ruby/Swift Common": [ "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll", "cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll", "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll", @@ -51,7 +51,7 @@ "ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll", "swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll" ], - "TaintTracking::Configuration Java/C++/C#/Python": [ + "TaintTracking::Configuration Java/C++/C#/Go/Python/Ruby/Swift": [ "cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", "cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", @@ -77,7 +77,7 @@ "ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", "swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingImpl.qll" ], - "DataFlow Java/C++/C#/Python Consistency checks": [ + "DataFlow Java/C++/C#/Python/Ruby/Swift Consistency checks": [ "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll", "cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll", "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll", @@ -87,7 +87,7 @@ "ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplConsistency.qll", "swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplConsistency.qll" ], - "DataFlow Java/C#/Ruby/Python/Swift Flow Summaries": [ + "DataFlow Java/C#/Go/Ruby/Python/Swift Flow Summaries": [ "java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll", "go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll", From 47702b9e142eeacb33be49ace3e2bf4199eedb01 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 29 Nov 2022 18:16:33 +0100 Subject: [PATCH 684/796] Swift: tentative fix for the bazel cache --- swift/actions/build-and-test/action.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/swift/actions/build-and-test/action.yml b/swift/actions/build-and-test/action.yml index 52a6415fedf..14f8107dc0f 100644 --- a/swift/actions/build-and-test/action.yml +++ b/swift/actions/build-and-test/action.yml @@ -10,18 +10,19 @@ runs: - name: Mount bazel cache uses: ./.github/actions/incremental-cache with: - path: "~/.cache/bazel-repository-cache" + path: bazel-repository-cache key: bazel-cache-${{ runner.os }}-${{ runner.arch }} - name: Mount bazel disk cache uses: ./.github/actions/incremental-cache with: - path: "~/.cache/bazel-disk-cache" + path: bazel-disk-cache key: bazel-disk-cache-${{ runner.os }}-${{ runner.arch }} - name: Configure bazel cache shell: bash run: | - echo build --repository_cache=~/.cache/bazel-repository-cache --disk_cache=~/.cache/bazel-disk-cache > ~/.bazelrc - echo test --test_output=errors >> ~/.bazelrc + mkdir bazel-repository-cache bazel-disk-cache + echo build --repository_cache=bazel-repository-cache --disk_cache=bazel-disk-cache > local.bazelrc + echo test --test_output=errors >> local.bazelrc - name: Print unextracted entities shell: bash run: | @@ -50,5 +51,5 @@ runs: if: ${{ github.event_name != 'pull_request' }} shell: bash run: | - find "~/.cache/bazel-repository-cache" "~/.cache/bazel-disk-cache" -atime +0 -type f -delete || : # ignore errors if the cache is empty - du -sh "~/.cache/bazel-repository-cache" "~/.cache/bazel-disk-cache" || : # ignore errors if the cache is empty + find bazel-repository-cache bazel-disk-cache -atime +0 -type f -delete + du -sh bazel-repository-cache bazel-disk-cache From b471926030927aac8b1ae24bb69860d6ef16cd14 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 29 Nov 2022 17:17:39 +0000 Subject: [PATCH 685/796] Autoformat --- go/extractor/util/util.go | 1 - 1 file changed, 1 deletion(-) diff --git a/go/extractor/util/util.go b/go/extractor/util/util.go index b50651dbe98..c4bdf3d1c61 100644 --- a/go/extractor/util/util.go +++ b/go/extractor/util/util.go @@ -118,7 +118,6 @@ func GetPkgsInfo(patterns []string, includingDeps bool, flags ...string) (map[st return pkgInfoMapping, nil } - // GetPkgInfo fills the package info structure for the specified package path. // It passes the `go list` the flags specified by `flags`. func GetPkgInfo(pkgpath string, flags ...string) PkgInfo { From 91edeacb9fa7bb8a92b0f869d68a0870e91064f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Tue, 29 Nov 2022 19:39:48 +0100 Subject: [PATCH 686/796] Swift: update .expected test files --- .../extractor-tests/declarations/all.expected | 26 ++--- .../ConcreteVarDecl_getAccessorDecl.expected | 18 ++-- .../test/library-tests/ast/PrintAst.expected | 58 +++++------ .../controlflow/graph/Cfg.expected | 98 +++++++++---------- 4 files changed, 100 insertions(+), 100 deletions(-) diff --git a/swift/ql/test/extractor-tests/declarations/all.expected b/swift/ql/test/extractor-tests/declarations/all.expected index 332c4b08737..7f4f3af4bdf 100644 --- a/swift/ql/test/extractor-tests/declarations/all.expected +++ b/swift/ql/test/extractor-tests/declarations/all.expected @@ -5,7 +5,7 @@ | declarations.swift:1:8:1:8 | self | | declarations.swift:1:8:1:8 | x | | declarations.swift:2:3:2:11 | var ... = ... | -| declarations.swift:2:7:2:7 | (unnamed function decl) | +| declarations.swift:2:7:2:7 | _modify | | declarations.swift:2:7:2:7 | get | | declarations.swift:2:7:2:7 | self | | declarations.swift:2:7:2:7 | self | @@ -14,7 +14,7 @@ | declarations.swift:2:7:2:7 | value | | declarations.swift:2:7:2:7 | x | | declarations.swift:3:3:6:3 | var ... = ... | -| declarations.swift:3:7:3:7 | (unnamed function decl) | +| declarations.swift:3:7:3:7 | _modify | | declarations.swift:3:7:3:7 | next | | declarations.swift:3:7:3:7 | self | | declarations.swift:4:5:4:5 | self | @@ -28,7 +28,7 @@ | declarations.swift:9:7:9:7 | self | | declarations.swift:9:7:9:7 | self | | declarations.swift:9:13:9:30 | var ... = ... | -| declarations.swift:9:17:9:17 | (unnamed function decl) | +| declarations.swift:9:17:9:17 | _modify | | declarations.swift:9:17:9:17 | get | | declarations.swift:9:17:9:17 | self | | declarations.swift:9:17:9:17 | self | @@ -58,7 +58,7 @@ | declarations.swift:19:29:19:29 | _ | | declarations.swift:22:1:26:1 | MyProtocol | | declarations.swift:23:5:23:39 | var ... = ... | -| declarations.swift:23:9:23:9 | (unnamed function decl) | +| declarations.swift:23:9:23:9 | _modify | | declarations.swift:23:9:23:9 | mustBeSettable | | declarations.swift:23:9:23:9 | self | | declarations.swift:23:31:23:31 | get | @@ -86,7 +86,7 @@ | declarations.swift:38:1:38:33 | { ... } | | declarations.swift:40:1:53:1 | Baz | | declarations.swift:41:3:41:14 | var ... = ... | -| declarations.swift:41:7:41:7 | (unnamed function decl) | +| declarations.swift:41:7:41:7 | _modify | | declarations.swift:41:7:41:7 | field | | declarations.swift:41:7:41:7 | get | | declarations.swift:41:7:41:7 | self | @@ -127,7 +127,7 @@ | declarations.swift:81:8:81:8 | normalField | | declarations.swift:81:8:81:8 | self | | declarations.swift:82:3:87:3 | var ... = ... | -| declarations.swift:82:7:82:7 | (unnamed function decl) | +| declarations.swift:82:7:82:7 | _modify | | declarations.swift:82:7:82:7 | self | | declarations.swift:82:7:82:7 | settableField | | declarations.swift:83:5:83:5 | newValue | @@ -144,7 +144,7 @@ | declarations.swift:97:5:97:5 | self | | declarations.swift:97:5:99:5 | get | | declarations.swift:102:3:102:21 | var ... = ... | -| declarations.swift:102:7:102:7 | (unnamed function decl) | +| declarations.swift:102:7:102:7 | _modify | | declarations.swift:102:7:102:7 | get | | declarations.swift:102:7:102:7 | normalField | | declarations.swift:102:7:102:7 | self | @@ -152,7 +152,7 @@ | declarations.swift:102:7:102:7 | self | | declarations.swift:102:7:102:7 | set | | declarations.swift:102:7:102:7 | value | -| declarations.swift:104:3:104:3 | (unnamed function decl) | +| declarations.swift:104:3:104:3 | _modify | | declarations.swift:104:3:104:3 | self | | declarations.swift:104:3:109:3 | subscript ... | | declarations.swift:104:13:104:13 | x | @@ -171,7 +171,7 @@ | declarations.swift:111:37:111:37 | self | | declarations.swift:111:37:113:3 | get | | declarations.swift:115:3:117:3 | var ... = ... | -| declarations.swift:115:7:115:7 | (unnamed function decl) | +| declarations.swift:115:7:115:7 | _modify | | declarations.swift:115:7:115:7 | get | | declarations.swift:115:7:115:7 | hasWillSet1 | | declarations.swift:115:7:115:7 | self | @@ -183,7 +183,7 @@ | declarations.swift:116:5:116:25 | willSet | | declarations.swift:116:13:116:13 | newValue | | declarations.swift:119:3:121:3 | var ... = ... | -| declarations.swift:119:7:119:7 | (unnamed function decl) | +| declarations.swift:119:7:119:7 | _modify | | declarations.swift:119:7:119:7 | get | | declarations.swift:119:7:119:7 | hasWillSet2 | | declarations.swift:119:7:119:7 | self | @@ -195,7 +195,7 @@ | declarations.swift:120:5:120:5 | self | | declarations.swift:120:5:120:15 | willSet | | declarations.swift:123:3:125:3 | var ... = ... | -| declarations.swift:123:7:123:7 | (unnamed function decl) | +| declarations.swift:123:7:123:7 | _modify | | declarations.swift:123:7:123:7 | get | | declarations.swift:123:7:123:7 | hasDidSet1 | | declarations.swift:123:7:123:7 | self | @@ -207,7 +207,7 @@ | declarations.swift:124:5:124:24 | didSet | | declarations.swift:124:12:124:12 | oldValue | | declarations.swift:127:3:129:3 | var ... = ... | -| declarations.swift:127:7:127:7 | (unnamed function decl) | +| declarations.swift:127:7:127:7 | _modify | | declarations.swift:127:7:127:7 | get | | declarations.swift:127:7:127:7 | hasDidSet2 | | declarations.swift:127:7:127:7 | self | @@ -218,7 +218,7 @@ | declarations.swift:128:5:128:5 | self | | declarations.swift:128:5:128:14 | didSet | | declarations.swift:131:3:135:3 | var ... = ... | -| declarations.swift:131:7:131:7 | (unnamed function decl) | +| declarations.swift:131:7:131:7 | _modify | | declarations.swift:131:7:131:7 | get | | declarations.swift:131:7:131:7 | hasBoth | | declarations.swift:131:7:131:7 | self | diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.expected b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.expected index 08aff3c9809..956ca097bd1 100644 --- a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.expected +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.expected @@ -1,31 +1,31 @@ | var_decls.swift:10:12:10:12 | numbers | 0 | var_decls.swift:10:12:10:12 | get | | var_decls.swift:15:7:15:7 | wrappedValue | 0 | var_decls.swift:15:7:15:7 | get | | var_decls.swift:15:7:15:7 | wrappedValue | 1 | var_decls.swift:15:7:15:7 | set | -| var_decls.swift:15:7:15:7 | wrappedValue | 2 | var_decls.swift:15:7:15:7 | (unnamed function decl) | +| var_decls.swift:15:7:15:7 | wrappedValue | 2 | var_decls.swift:15:7:15:7 | _modify | | var_decls.swift:20:7:20:7 | wrappedValue | 0 | var_decls.swift:20:7:20:7 | get | | var_decls.swift:20:7:20:7 | wrappedValue | 1 | var_decls.swift:20:7:20:7 | set | -| var_decls.swift:20:7:20:7 | wrappedValue | 2 | var_decls.swift:20:7:20:7 | (unnamed function decl) | +| var_decls.swift:20:7:20:7 | wrappedValue | 2 | var_decls.swift:20:7:20:7 | _modify | | var_decls.swift:24:15:24:15 | _wrapped | 0 | var_decls.swift:24:15:24:15 | get | | var_decls.swift:24:15:24:15 | _wrapped | 1 | var_decls.swift:24:15:24:15 | set | -| var_decls.swift:24:15:24:15 | _wrapped | 2 | var_decls.swift:24:15:24:15 | (unnamed function decl) | +| var_decls.swift:24:15:24:15 | _wrapped | 2 | var_decls.swift:24:15:24:15 | _modify | | var_decls.swift:24:15:24:15 | wrapped | 0 | var_decls.swift:24:15:24:15 | get | | var_decls.swift:24:15:24:15 | wrapped | 1 | var_decls.swift:24:15:24:15 | set | -| var_decls.swift:24:15:24:15 | wrapped | 2 | var_decls.swift:24:15:24:15 | (unnamed function decl) | +| var_decls.swift:24:15:24:15 | wrapped | 2 | var_decls.swift:24:15:24:15 | _modify | | var_decls.swift:28:7:28:7 | wrappedValue | 0 | var_decls.swift:28:7:28:7 | get | | var_decls.swift:28:7:28:7 | wrappedValue | 1 | var_decls.swift:28:7:28:7 | set | -| var_decls.swift:28:7:28:7 | wrappedValue | 2 | var_decls.swift:28:7:28:7 | (unnamed function decl) | +| var_decls.swift:28:7:28:7 | wrappedValue | 2 | var_decls.swift:28:7:28:7 | _modify | | var_decls.swift:34:7:34:7 | wrappedValue | 0 | var_decls.swift:34:7:34:7 | get | | var_decls.swift:34:7:34:7 | wrappedValue | 1 | var_decls.swift:34:7:34:7 | set | -| var_decls.swift:34:7:34:7 | wrappedValue | 2 | var_decls.swift:34:7:34:7 | (unnamed function decl) | +| var_decls.swift:34:7:34:7 | wrappedValue | 2 | var_decls.swift:34:7:34:7 | _modify | | var_decls.swift:35:7:35:7 | projectedValue | 0 | var_decls.swift:35:7:35:7 | get | | var_decls.swift:35:7:35:7 | projectedValue | 1 | var_decls.swift:35:7:35:7 | set | -| var_decls.swift:35:7:35:7 | projectedValue | 2 | var_decls.swift:35:7:35:7 | (unnamed function decl) | +| var_decls.swift:35:7:35:7 | projectedValue | 2 | var_decls.swift:35:7:35:7 | _modify | | var_decls.swift:39:7:39:7 | wrappedValue | 0 | var_decls.swift:39:7:39:7 | get | | var_decls.swift:39:7:39:7 | wrappedValue | 1 | var_decls.swift:39:7:39:7 | set | -| var_decls.swift:39:7:39:7 | wrappedValue | 2 | var_decls.swift:39:7:39:7 | (unnamed function decl) | +| var_decls.swift:39:7:39:7 | wrappedValue | 2 | var_decls.swift:39:7:39:7 | _modify | | var_decls.swift:40:7:40:7 | projectedValue | 0 | var_decls.swift:40:7:40:7 | get | | var_decls.swift:40:7:40:7 | projectedValue | 1 | var_decls.swift:40:7:40:7 | set | -| var_decls.swift:40:7:40:7 | projectedValue | 2 | var_decls.swift:40:7:40:7 | (unnamed function decl) | +| var_decls.swift:40:7:40:7 | projectedValue | 2 | var_decls.swift:40:7:40:7 | _modify | | var_decls.swift:54:10:54:10 | w1 | 0 | var_decls.swift:54:10:54:10 | get | | var_decls.swift:54:10:54:10 | w1 | 1 | var_decls.swift:54:10:54:10 | set | | var_decls.swift:55:24:55:24 | w2 | 0 | var_decls.swift:55:24:55:24 | get | diff --git a/swift/ql/test/library-tests/ast/PrintAst.expected b/swift/ql/test/library-tests/ast/PrintAst.expected index 2397614f5fe..2ec81962d30 100644 --- a/swift/ql/test/library-tests/ast/PrintAst.expected +++ b/swift/ql/test/library-tests/ast/PrintAst.expected @@ -2453,7 +2453,7 @@ cfg.swift: #-----| getDest(): [MemberRefExpr] .field #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 394| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 394| getAccessorDecl(2): [AccessorDecl] _modify # 394| InterfaceType = (Structors) -> () -> () # 394| getSelfParam(): [ParamDecl] self # 394| Type = Structors @@ -2525,7 +2525,7 @@ cfg.swift: #-----| getDest(): [MemberRefExpr] .x #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 410| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 410| getAccessorDecl(2): [AccessorDecl] _modify # 410| InterfaceType = (MyLocalClass) -> () -> () # 410| getSelfParam(): [ParamDecl] self # 410| Type = MyLocalClass @@ -2575,7 +2575,7 @@ cfg.swift: #-----| getDest(): [MemberRefExpr] .x #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 417| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 417| getAccessorDecl(2): [AccessorDecl] _modify # 417| InterfaceType = (inout MyLocalStruct) -> () -> () # 417| getSelfParam(): [ParamDecl] self # 417| Type = MyLocalStruct @@ -2754,7 +2754,7 @@ cfg.swift: #-----| getDest(): [MemberRefExpr] .x #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 446| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 446| getAccessorDecl(2): [AccessorDecl] _modify # 446| InterfaceType = (inout B) -> () -> () # 446| getSelfParam(): [ParamDecl] self # 446| Type = B @@ -2795,7 +2795,7 @@ cfg.swift: #-----| getDest(): [MemberRefExpr] .b #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 450| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 450| getAccessorDecl(2): [AccessorDecl] _modify # 450| InterfaceType = (inout A) -> () -> () # 450| getSelfParam(): [ParamDecl] self # 450| Type = A @@ -2829,7 +2829,7 @@ cfg.swift: #-----| getDest(): [MemberRefExpr] .bs #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 451| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 451| getAccessorDecl(2): [AccessorDecl] _modify # 451| InterfaceType = (inout A) -> () -> () # 451| getSelfParam(): [ParamDecl] self # 451| Type = A @@ -2864,7 +2864,7 @@ cfg.swift: #-----| getDest(): [MemberRefExpr] .mayB #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 452| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 452| getAccessorDecl(2): [AccessorDecl] _modify # 452| InterfaceType = (inout A) -> () -> () # 452| getSelfParam(): [ParamDecl] self # 452| Type = A @@ -2983,7 +2983,7 @@ declarations.swift: #-----| getDest(): [MemberRefExpr] .x #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 2| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 2| getAccessorDecl(2): [AccessorDecl] _modify # 2| InterfaceType = (inout Foo) -> () -> () # 2| getSelfParam(): [ParamDecl] self # 2| Type = Foo @@ -3031,7 +3031,7 @@ declarations.swift: # 5| getExpr(): [DeclRefExpr] newValue # 5| getArgument(1): [Argument] : 1 # 5| getExpr(): [IntegerLiteralExpr] 1 -# 3| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 3| getAccessorDecl(2): [AccessorDecl] _modify # 3| InterfaceType = (inout Foo) -> () -> () # 3| getSelfParam(): [ParamDecl] self # 3| Type = Foo @@ -3079,7 +3079,7 @@ declarations.swift: #-----| getDest(): [MemberRefExpr] .x #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 9| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 9| getAccessorDecl(2): [AccessorDecl] _modify # 9| InterfaceType = (Bar) -> () -> () # 9| getSelfParam(): [ParamDecl] self # 9| Type = Bar @@ -3306,7 +3306,7 @@ declarations.swift: # 23| Type = Self # 23| getParam(0): [ParamDecl] newValue # 23| Type = Int -# 23| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 23| getAccessorDecl(2): [AccessorDecl] _modify # 23| InterfaceType = (inout Self) -> () -> () # 23| getSelfParam(): [ParamDecl] self # 23| Type = Self @@ -3393,7 +3393,7 @@ declarations.swift: #-----| getDest(): [MemberRefExpr] .field #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 41| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 41| getAccessorDecl(2): [AccessorDecl] _modify # 41| InterfaceType = (Baz) -> () -> () # 41| getSelfParam(): [ParamDecl] self # 41| Type = Baz @@ -3503,7 +3503,7 @@ declarations.swift: # 84| getBody(): [BraceStmt] { ... } # 85| getElement(0): [ReturnStmt] return ... # 85| getResult(): [IntegerLiteralExpr] 0 -# 82| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 82| getAccessorDecl(2): [AccessorDecl] _modify # 82| InterfaceType = (inout HasPropertyAndObserver) -> () -> () # 82| getSelfParam(): [ParamDecl] self # 82| Type = HasPropertyAndObserver @@ -3563,7 +3563,7 @@ declarations.swift: #-----| getDest(): [MemberRefExpr] .normalField #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 102| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 102| getAccessorDecl(2): [AccessorDecl] _modify # 102| InterfaceType = (inout HasPropertyAndObserver) -> () -> () # 102| getSelfParam(): [ParamDecl] self # 102| Type = HasPropertyAndObserver @@ -3591,7 +3591,7 @@ declarations.swift: # 104| getParam(1): [ParamDecl] x # 104| Type = Int # 108| getBody(): [BraceStmt] { ... } -# 104| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 104| getAccessorDecl(2): [AccessorDecl] _modify # 104| InterfaceType = (inout HasPropertyAndObserver) -> (Int) -> () # 104| getSelfParam(): [ParamDecl] self # 104| Type = HasPropertyAndObserver @@ -3660,7 +3660,7 @@ declarations.swift: #-----| getDest(): [MemberRefExpr] .hasWillSet1 #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 115| getAccessorDecl(3): [AccessorDecl] (unnamed function decl) +# 115| getAccessorDecl(3): [AccessorDecl] _modify # 115| InterfaceType = (inout HasPropertyAndObserver) -> () -> () # 115| getSelfParam(): [ParamDecl] self # 115| Type = HasPropertyAndObserver @@ -3707,7 +3707,7 @@ declarations.swift: #-----| getDest(): [MemberRefExpr] .hasWillSet2 #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 119| getAccessorDecl(3): [AccessorDecl] (unnamed function decl) +# 119| getAccessorDecl(3): [AccessorDecl] _modify # 119| InterfaceType = (inout HasPropertyAndObserver) -> () -> () # 119| getSelfParam(): [ParamDecl] self # 119| Type = HasPropertyAndObserver @@ -3761,7 +3761,7 @@ declarations.swift: #-----| getSubExpr(): [DeclRefExpr] self #-----| getArgument(0): [Argument] : tmp #-----| getExpr(): [DeclRefExpr] tmp -# 123| getAccessorDecl(3): [AccessorDecl] (unnamed function decl) +# 123| getAccessorDecl(3): [AccessorDecl] _modify # 123| InterfaceType = (inout HasPropertyAndObserver) -> () -> () # 123| getSelfParam(): [ParamDecl] self # 123| Type = HasPropertyAndObserver @@ -3804,7 +3804,7 @@ declarations.swift: #-----| getFunction(): [MethodRefExpr] .didSet #-----| getBase(): [InOutExpr] &... #-----| getSubExpr(): [DeclRefExpr] self -# 127| getAccessorDecl(3): [AccessorDecl] (unnamed function decl) +# 127| getAccessorDecl(3): [AccessorDecl] _modify # 127| InterfaceType = (inout HasPropertyAndObserver) -> () -> () # 127| getSelfParam(): [ParamDecl] self # 127| Type = HasPropertyAndObserver @@ -3864,7 +3864,7 @@ declarations.swift: #-----| getFunction(): [MethodRefExpr] .didSet #-----| getBase(): [InOutExpr] &... #-----| getSubExpr(): [DeclRefExpr] self -# 131| getAccessorDecl(4): [AccessorDecl] (unnamed function decl) +# 131| getAccessorDecl(4): [AccessorDecl] _modify # 131| InterfaceType = (inout HasPropertyAndObserver) -> () -> () # 131| getSelfParam(): [ParamDecl] self # 131| Type = HasPropertyAndObserver @@ -4632,7 +4632,7 @@ expressions.swift: # 98| getBody(): [BraceStmt] { ... } # 99| getElement(0): [ReturnStmt] return ... # 99| getResult(): [IntegerLiteralExpr] 0 -# 96| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 96| getAccessorDecl(2): [AccessorDecl] _modify # 96| InterfaceType = (inout HasProperty) -> () -> () # 96| getSelfParam(): [ParamDecl] self # 96| Type = HasProperty @@ -4692,7 +4692,7 @@ expressions.swift: #-----| getDest(): [MemberRefExpr] .normalField #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 116| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 116| getAccessorDecl(2): [AccessorDecl] _modify # 116| InterfaceType = (inout HasProperty) -> () -> () # 116| getSelfParam(): [ParamDecl] self # 116| Type = HasProperty @@ -4720,7 +4720,7 @@ expressions.swift: # 118| getParam(1): [ParamDecl] x # 118| Type = Int # 122| getBody(): [BraceStmt] { ... } -# 118| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 118| getAccessorDecl(2): [AccessorDecl] _modify # 118| InterfaceType = (inout HasProperty) -> (Int) -> () # 118| getSelfParam(): [ParamDecl] self # 118| Type = HasProperty @@ -4845,7 +4845,7 @@ expressions.swift: #-----| getDest(): [MemberRefExpr] .x #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 142| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 142| getAccessorDecl(2): [AccessorDecl] _modify # 142| InterfaceType = (inout B) -> () -> () # 142| getSelfParam(): [ParamDecl] self # 142| Type = B @@ -4886,7 +4886,7 @@ expressions.swift: #-----| getDest(): [MemberRefExpr] .b #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 146| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 146| getAccessorDecl(2): [AccessorDecl] _modify # 146| InterfaceType = (inout A) -> () -> () # 146| getSelfParam(): [ParamDecl] self # 146| Type = A @@ -4920,7 +4920,7 @@ expressions.swift: #-----| getDest(): [MemberRefExpr] .bs #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 147| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 147| getAccessorDecl(2): [AccessorDecl] _modify # 147| InterfaceType = (inout A) -> () -> () # 147| getSelfParam(): [ParamDecl] self # 147| Type = A @@ -4955,7 +4955,7 @@ expressions.swift: #-----| getDest(): [MemberRefExpr] .mayB #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 148| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 148| getAccessorDecl(2): [AccessorDecl] _modify # 148| InterfaceType = (inout A) -> () -> () # 148| getSelfParam(): [ParamDecl] self # 148| Type = A @@ -5695,7 +5695,7 @@ statements.swift: #-----| getDest(): [MemberRefExpr] .x #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 75| getAccessorDecl(2): [AccessorDecl] (unnamed function decl) +# 75| getAccessorDecl(2): [AccessorDecl] _modify # 75| InterfaceType = (inout HasModifyAccessorDecl) -> () -> () # 75| getSelfParam(): [ParamDecl] self # 75| Type = HasModifyAccessorDecl @@ -5710,7 +5710,7 @@ statements.swift: # 76| getTypeRepr(): [TypeRepr] Int # 76| getMember(3): [ConcreteVarDecl] hasModify # 76| Type = Int -# 77| getAccessorDecl(0): [AccessorDecl] (unnamed function decl) +# 77| getAccessorDecl(0): [AccessorDecl] _modify # 77| InterfaceType = (inout HasModifyAccessorDecl) -> () -> () # 77| getSelfParam(): [ParamDecl] self # 77| Type = HasModifyAccessorDecl diff --git a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected index 8146cf4fa3a..9eebf08a5c6 100644 --- a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -5148,11 +5148,11 @@ cfg.swift: # 390| 0 #-----| -> return ... -# 394| (unnamed function decl) +# 394| _modify #-----| -> self -# 394| enter (unnamed function decl) -#-----| -> (unnamed function decl) +# 394| enter _modify +#-----| -> _modify # 394| enter get #-----| -> get @@ -5160,10 +5160,10 @@ cfg.swift: # 394| enter set #-----| -> set -# 394| exit (unnamed function decl) +# 394| exit _modify -# 394| exit (unnamed function decl) (normal) -#-----| -> exit (unnamed function decl) +# 394| exit _modify (normal) +#-----| -> exit _modify # 394| exit get @@ -5191,7 +5191,7 @@ cfg.swift: # 394| value # 394| yield ... -#-----| -> exit (unnamed function decl) (normal) +#-----| -> exit _modify (normal) # 395| self #-----| -> self @@ -5320,11 +5320,11 @@ cfg.swift: # 409| { ... } #-----| -> exit deinit() (normal) -# 410| (unnamed function decl) +# 410| _modify #-----| -> self -# 410| enter (unnamed function decl) -#-----| -> (unnamed function decl) +# 410| enter _modify +#-----| -> _modify # 410| enter get #-----| -> get @@ -5332,10 +5332,10 @@ cfg.swift: # 410| enter set #-----| -> set -# 410| exit (unnamed function decl) +# 410| exit _modify -# 410| exit (unnamed function decl) (normal) -#-----| -> exit (unnamed function decl) +# 410| exit _modify (normal) +#-----| -> exit _modify # 410| exit get @@ -5363,7 +5363,7 @@ cfg.swift: # 410| value # 410| yield ... -#-----| -> exit (unnamed function decl) (normal) +#-----| -> exit _modify (normal) # 411| self #-----| -> self @@ -5397,11 +5397,11 @@ cfg.swift: # 416| MyLocalStruct #-----| -> MyLocalEnum -# 417| (unnamed function decl) +# 417| _modify #-----| -> self -# 417| enter (unnamed function decl) -#-----| -> (unnamed function decl) +# 417| enter _modify +#-----| -> _modify # 417| enter get #-----| -> get @@ -5409,10 +5409,10 @@ cfg.swift: # 417| enter set #-----| -> set -# 417| exit (unnamed function decl) +# 417| exit _modify -# 417| exit (unnamed function decl) (normal) -#-----| -> exit (unnamed function decl) +# 417| exit _modify (normal) +#-----| -> exit _modify # 417| exit get @@ -5440,7 +5440,7 @@ cfg.swift: # 417| value # 417| yield ... -#-----| -> exit (unnamed function decl) (normal) +#-----| -> exit _modify (normal) # 418| self #-----| -> self @@ -5492,11 +5492,11 @@ cfg.swift: # 442| 0 #-----| -> return ... -# 446| (unnamed function decl) +# 446| _modify #-----| -> self -# 446| enter (unnamed function decl) -#-----| -> (unnamed function decl) +# 446| enter _modify +#-----| -> _modify # 446| enter get #-----| -> get @@ -5504,10 +5504,10 @@ cfg.swift: # 446| enter set #-----| -> set -# 446| exit (unnamed function decl) +# 446| exit _modify -# 446| exit (unnamed function decl) (normal) -#-----| -> exit (unnamed function decl) +# 446| exit _modify (normal) +#-----| -> exit _modify # 446| exit get @@ -5535,13 +5535,13 @@ cfg.swift: # 446| value # 446| yield ... -#-----| -> exit (unnamed function decl) (normal) +#-----| -> exit _modify (normal) -# 450| (unnamed function decl) +# 450| _modify #-----| -> self -# 450| enter (unnamed function decl) -#-----| -> (unnamed function decl) +# 450| enter _modify +#-----| -> _modify # 450| enter get #-----| -> get @@ -5549,10 +5549,10 @@ cfg.swift: # 450| enter set #-----| -> set -# 450| exit (unnamed function decl) +# 450| exit _modify -# 450| exit (unnamed function decl) (normal) -#-----| -> exit (unnamed function decl) +# 450| exit _modify (normal) +#-----| -> exit _modify # 450| exit get @@ -5580,13 +5580,13 @@ cfg.swift: # 450| value # 450| yield ... -#-----| -> exit (unnamed function decl) (normal) +#-----| -> exit _modify (normal) -# 451| (unnamed function decl) +# 451| _modify #-----| -> self -# 451| enter (unnamed function decl) -#-----| -> (unnamed function decl) +# 451| enter _modify +#-----| -> _modify # 451| enter get #-----| -> get @@ -5594,10 +5594,10 @@ cfg.swift: # 451| enter set #-----| -> set -# 451| exit (unnamed function decl) +# 451| exit _modify -# 451| exit (unnamed function decl) (normal) -#-----| -> exit (unnamed function decl) +# 451| exit _modify (normal) +#-----| -> exit _modify # 451| exit get @@ -5625,13 +5625,13 @@ cfg.swift: # 451| value # 451| yield ... -#-----| -> exit (unnamed function decl) (normal) +#-----| -> exit _modify (normal) -# 452| (unnamed function decl) +# 452| _modify #-----| -> self -# 452| enter (unnamed function decl) -#-----| -> (unnamed function decl) +# 452| enter _modify +#-----| -> _modify # 452| enter get #-----| -> get @@ -5639,10 +5639,10 @@ cfg.swift: # 452| enter set #-----| -> set -# 452| exit (unnamed function decl) +# 452| exit _modify -# 452| exit (unnamed function decl) (normal) -#-----| -> exit (unnamed function decl) +# 452| exit _modify (normal) +#-----| -> exit _modify # 452| exit get @@ -5670,7 +5670,7 @@ cfg.swift: # 452| value # 452| yield ... -#-----| -> exit (unnamed function decl) (normal) +#-----| -> exit _modify (normal) # 455| enter test(a:) #-----| -> test(a:) From d0cf709d2e6e4b0623cc9bab5048d30224972c9a Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Tue, 29 Nov 2022 21:30:50 +0100 Subject: [PATCH 687/796] use proper path construction Co-authored-by: Asger F --- javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java index 266685e0abf..883b6efb859 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java +++ b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java @@ -461,7 +461,7 @@ public class AutoBuild { warn("No JavaScript or TypeScript code found."); } // ensuring that the finalize steps detects that no code was seen. - Path srcFolder = Paths.get(EnvironmentVariables.getWipDatabase() + "/src"); + Path srcFolder = Paths.get(EnvironmentVariables.getWipDatabase(), "src"); // check that the srcFolder is empty if (Files.list(srcFolder).count() == 0) { // Non-recursive delete because "src/" should be empty. From de5ffd5cfa55456fc1fcc589f409aa27ab5f8aa5 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 29 Nov 2022 21:31:29 +0100 Subject: [PATCH 688/796] bump extractor version --- javascript/extractor/src/com/semmle/js/extractor/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/extractor/src/com/semmle/js/extractor/Main.java b/javascript/extractor/src/com/semmle/js/extractor/Main.java index b7ab9b7e62b..69503631c04 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/Main.java +++ b/javascript/extractor/src/com/semmle/js/extractor/Main.java @@ -41,7 +41,7 @@ public class Main { * A version identifier that should be updated every time the extractor changes in such a way that * it may produce different tuples for the same file under the same {@link ExtractorConfig}. */ - public static final String EXTRACTOR_VERSION = "2022-11-16"; + public static final String EXTRACTOR_VERSION = "2022-11-29"; public static final Pattern NEWLINE = Pattern.compile("\n"); From 5402f047bfe4e249b7bd2159363f2077575b1a61 Mon Sep 17 00:00:00 2001 From: tiferet Date: Thu, 17 Nov 2022 11:59:36 -0800 Subject: [PATCH 689/796] Delete `CoreKnowledge`. All remaining functionality in `CoreKnowledge` is only being used in `EndpointCharacteristics`, so it can be moved there as a small set of helper predicates. --- .../EndpointCharacteristics.qll | 48 +------------------ 1 file changed, 1 insertion(+), 47 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index 74a5ca6256d..263685889c1 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -9,6 +9,7 @@ private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations private import semmle.javascript.security.dataflow.TaintedPathCustomizations private import semmle.javascript.heuristics.SyntacticHeuristics as SyntacticHeuristics private import semmle.javascript.filters.ClassifyFiles as ClassifyFiles +private import StandardEndpointFilters as StandardEndpointFilters private import semmle.javascript.security.dataflow.XxeCustomizations private import semmle.javascript.security.dataflow.RemotePropertyInjectionCustomizations private import semmle.javascript.security.dataflow.TypeConfusionThroughParameterTamperingCustomizations @@ -154,53 +155,6 @@ private predicate isKnownStepSrc(DataFlow::Node n) { DataFlow::SharedFlowStep::step(n, _, _, _) } -/** - * Holds if the data flow node is a (possibly indirect) argument of a likely external library call. - * - * This includes direct arguments of likely external library calls as well as nested object - * literals within those calls. - */ -private predicate flowsToArgumentOfLikelyExternalLibraryCall(DataFlow::Node n) { - n = getACallWithoutCallee().getAnArgument() - or - exists(DataFlow::SourceNode src | flowsToArgumentOfLikelyExternalLibraryCall(src) | - n = src.getAPropertyWrite().getRhs() - ) - or - exists(DataFlow::ArrayCreationNode arr | flowsToArgumentOfLikelyExternalLibraryCall(arr) | - n = arr.getAnElement() - ) -} - -/** - * Get calls for which we do not have the callee (i.e. the definition of the called function). This - * acts as a heuristic for identifying calls to external library functions. - */ -private DataFlow::CallNode getACallWithoutCallee() { - forall(Function callee | callee = result.getACallee() | callee.getTopLevel().isExterns()) and - not exists(DataFlow::ParameterNode param, DataFlow::FunctionNode callback | - param.flowsTo(result.getCalleeNode()) and - callback = getACallback(param, DataFlow::TypeBackTracker::end()) - ) -} - -/** - * Gets a node that flows to callback-parameter `p`. - */ -private DataFlow::SourceNode getACallback(DataFlow::ParameterNode p, DataFlow::TypeBackTracker t) { - t.start() and - result = p and - any(DataFlow::FunctionNode f).getLastParameter() = p and - exists(p.getACall()) - or - exists(DataFlow::TypeBackTracker t2 | result = getACallback(p, t2).backtrack(t2, t)) -} - -/** - * Get calls which are likely to be to external non-built-in libraries. - */ -DataFlow::CallNode getALikelyExternalLibraryCall() { result = getACallWithoutCallee() } - /* * Characteristics that are indicative of a sink. * NOTE: Initially each sink type has only one characteristic, which is that it's a sink of this type in the standard From 05a943c9b533afbe4cf71a6e09527daf17c340f7 Mon Sep 17 00:00:00 2001 From: tiferet Date: Thu, 17 Nov 2022 12:12:03 -0800 Subject: [PATCH 690/796] Delete `StandardEndpointFilters`. All remaining functionality in `StandardEndpointFilters` is only being used in `EndpointCharacteristics`, so it can be moved there as a small set of helper predicates. --- .../EndpointCharacteristics.qll | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index 263685889c1..74a5ca6256d 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -9,7 +9,6 @@ private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations private import semmle.javascript.security.dataflow.TaintedPathCustomizations private import semmle.javascript.heuristics.SyntacticHeuristics as SyntacticHeuristics private import semmle.javascript.filters.ClassifyFiles as ClassifyFiles -private import StandardEndpointFilters as StandardEndpointFilters private import semmle.javascript.security.dataflow.XxeCustomizations private import semmle.javascript.security.dataflow.RemotePropertyInjectionCustomizations private import semmle.javascript.security.dataflow.TypeConfusionThroughParameterTamperingCustomizations @@ -155,6 +154,53 @@ private predicate isKnownStepSrc(DataFlow::Node n) { DataFlow::SharedFlowStep::step(n, _, _, _) } +/** + * Holds if the data flow node is a (possibly indirect) argument of a likely external library call. + * + * This includes direct arguments of likely external library calls as well as nested object + * literals within those calls. + */ +private predicate flowsToArgumentOfLikelyExternalLibraryCall(DataFlow::Node n) { + n = getACallWithoutCallee().getAnArgument() + or + exists(DataFlow::SourceNode src | flowsToArgumentOfLikelyExternalLibraryCall(src) | + n = src.getAPropertyWrite().getRhs() + ) + or + exists(DataFlow::ArrayCreationNode arr | flowsToArgumentOfLikelyExternalLibraryCall(arr) | + n = arr.getAnElement() + ) +} + +/** + * Get calls for which we do not have the callee (i.e. the definition of the called function). This + * acts as a heuristic for identifying calls to external library functions. + */ +private DataFlow::CallNode getACallWithoutCallee() { + forall(Function callee | callee = result.getACallee() | callee.getTopLevel().isExterns()) and + not exists(DataFlow::ParameterNode param, DataFlow::FunctionNode callback | + param.flowsTo(result.getCalleeNode()) and + callback = getACallback(param, DataFlow::TypeBackTracker::end()) + ) +} + +/** + * Gets a node that flows to callback-parameter `p`. + */ +private DataFlow::SourceNode getACallback(DataFlow::ParameterNode p, DataFlow::TypeBackTracker t) { + t.start() and + result = p and + any(DataFlow::FunctionNode f).getLastParameter() = p and + exists(p.getACall()) + or + exists(DataFlow::TypeBackTracker t2 | result = getACallback(p, t2).backtrack(t2, t)) +} + +/** + * Get calls which are likely to be to external non-built-in libraries. + */ +DataFlow::CallNode getALikelyExternalLibraryCall() { result = getACallWithoutCallee() } + /* * Characteristics that are indicative of a sink. * NOTE: Initially each sink type has only one characteristic, which is that it's a sink of this type in the standard From 50291c7b7c1a759654d281665206710f51f1d747 Mon Sep 17 00:00:00 2001 From: tiferet Date: Thu, 17 Nov 2022 17:00:33 -0800 Subject: [PATCH 691/796] `AtmConfig` inherits from `TaintTracking::Configuration`. That way the specific configs which inherit from `AtmConfig` also inherit from `TaintTracking::Configuration`. This removes the need for two separate config classes for each query. --- .../adaptivethreatmodeling/ATMConfig.qll | 2 +- .../NosqlInjectionATM.qll | 96 +++++++++---------- .../SqlInjectionATM.qll | 24 ++--- .../adaptivethreatmodeling/TaintedPathATM.qll | 26 ++--- .../adaptivethreatmodeling/XssATM.qll | 25 ++--- .../modelbuilding/DebugResultInclusion.ql | 8 +- .../extraction/ExtractEndpointMapping.ql | 8 +- .../endpoint_large_scale/EndpointFeatures.ql | 8 +- .../FilteredTruePositives.ql | 8 +- ...ql_endpoint_filter_ignores_modeled_apis.ql | 2 +- 10 files changed, 90 insertions(+), 117 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index ed9ca5ce1c1..4106269d759 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -29,7 +29,7 @@ import EndpointCharacteristics as EndpointCharacteristics * `isAdditionalFlowStep` with a more generalised definition of additional edges. See * `NosqlInjectionATM.qll` for an example of doing this. */ -abstract class AtmConfig extends string { +abstract class AtmConfig extends JS::TaintTracking::Configuration { bindingset[this] AtmConfig() { any() } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll index f03631bfdcf..5de89d30c5e 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll @@ -1,6 +1,7 @@ /** * For internal use only. * + * A taint-tracking configuration for reasoning about NoSQL injection vulnerabilities. * Defines shared code used by the NoSQL injection boosted query. */ @@ -9,61 +10,20 @@ private import semmle.javascript.heuristics.SyntacticHeuristics private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations import AdaptiveThreatModeling -class NosqlInjectionAtmConfig extends AtmConfig { - NosqlInjectionAtmConfig() { this = "NosqlInjectionATMConfig" } +class Configuration extends AtmConfig { + Configuration() { this = "NosqlInjectionATMConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof NosqlInjection::Source or TaintedObject::isSource(source, _) } override EndpointType getASinkEndpointType() { result instanceof NosqlInjectionSinkType } -} -/** DEPRECATED: Alias for NosqlInjectionAtmConfig */ -deprecated class NosqlInjectionATMConfig = NosqlInjectionAtmConfig; - -/** Holds if src -> trg is an additional flow step in the non-boosted NoSql injection security query. */ -predicate isBaseAdditionalFlowStep( - DataFlow::Node src, DataFlow::Node trg, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl -) { - TaintedObject::step(src, trg, inlbl, outlbl) - or - // additional flow step to track taint through NoSQL query objects - inlbl = TaintedObject::label() and - outlbl = TaintedObject::label() and - exists(NoSql::Query query, DataFlow::SourceNode queryObj | - queryObj.flowsTo(query) and - queryObj.flowsTo(trg) and - src = queryObj.getAPropertyWrite().getRhs() - ) -} - -/** - * Gets a value that is (transitively) written to `query`, where `query` is a NoSQL sink. - * - * This predicate allows us to propagate data flow through property writes and array constructors - * within a query object, enabling the security query to pick up NoSQL injection vulnerabilities - * involving more complex queries. - */ -DataFlow::Node getASubexpressionWithinQuery(DataFlow::Node query) { - any(NosqlInjectionAtmConfig cfg).isEffectiveSink(query) and - exists(DataFlow::SourceNode receiver | - receiver = [getASubexpressionWithinQuery(query), query].getALocalSource() - | - result = - [receiver.getAPropertyWrite().getRhs(), receiver.(DataFlow::ArrayCreationNode).getAnElement()] - ) -} - -/** - * A taint-tracking configuration for reasoning about NoSQL injection vulnerabilities. - * - * This is largely a copy of the taint tracking configuration for the standard NoSQL injection - * query, except additional ATM sinks have been added and the additional flow step has been - * generalised to cover the sinks predicted by ATM. - */ -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "NosqlInjectionATM" } + /* + * This is largely a copy of the taint tracking configuration for the standard NoSQL injection + * query, except additional ATM sinks have been added and the additional flow step has been + * generalised to cover the sinks predicted by ATM. + */ override predicate isSource(DataFlow::Node source) { source instanceof NosqlInjection::Source } @@ -75,7 +35,7 @@ class Configuration extends TaintTracking::Configuration { sink.(NosqlInjection::Sink).getAFlowLabel() = label or // Allow effective sinks to have any taint label - any(NosqlInjectionAtmConfig cfg).isEffectiveSink(sink) + isEffectiveSink(sink) } override predicate isSanitizer(DataFlow::Node node) { @@ -94,7 +54,43 @@ class Configuration extends TaintTracking::Configuration { isBaseAdditionalFlowStep(src, trg, inlbl, outlbl) or // relaxed version of previous step to track taint through unmodeled NoSQL query objects - any(NosqlInjectionAtmConfig cfg).isEffectiveSink(trg) and + isEffectiveSink(trg) and src = getASubexpressionWithinQuery(trg) } + + /** Holds if src -> trg is an additional flow step in the non-boosted NoSql injection security query. */ + private predicate isBaseAdditionalFlowStep( + DataFlow::Node src, DataFlow::Node trg, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl + ) { + TaintedObject::step(src, trg, inlbl, outlbl) + or + // additional flow step to track taint through NoSQL query objects + inlbl = TaintedObject::label() and + outlbl = TaintedObject::label() and + exists(NoSql::Query query, DataFlow::SourceNode queryObj | + queryObj.flowsTo(query) and + queryObj.flowsTo(trg) and + src = queryObj.getAPropertyWrite().getRhs() + ) + } + + /** + * Gets a value that is (transitively) written to `query`, where `query` is a NoSQL sink. + * + * This predicate allows us to propagate data flow through property writes and array constructors + * within a query object, enabling the security query to pick up NoSQL injection vulnerabilities + * involving more complex queries. + */ + private DataFlow::Node getASubexpressionWithinQuery(DataFlow::Node query) { + isEffectiveSink(query) and + exists(DataFlow::SourceNode receiver | + receiver = [getASubexpressionWithinQuery(query), query].getALocalSource() + | + result = + [ + receiver.getAPropertyWrite().getRhs(), + receiver.(DataFlow::ArrayCreationNode).getAnElement() + ] + ) + } } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll index 14821404e6d..d51e99060bd 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll @@ -1,6 +1,7 @@ /** * For internal use only. * + * A taint-tracking configuration for reasoning about SQL injection vulnerabilities. * Defines shared code used by the SQL injection boosted query. */ @@ -8,30 +9,21 @@ import semmle.javascript.heuristics.SyntacticHeuristics import semmle.javascript.security.dataflow.SqlInjectionCustomizations import AdaptiveThreatModeling -class SqlInjectionAtmConfig extends AtmConfig { - SqlInjectionAtmConfig() { this = "SqlInjectionATMConfig" } +class Configuration extends AtmConfig { + Configuration() { this = "SqlInjectionATMConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof SqlInjection::Source } override EndpointType getASinkEndpointType() { result instanceof SqlInjectionSinkType } -} - -/** DEPRECATED: Alias for SqlInjectionAtmConfig */ -deprecated class SqlInjectionATMConfig = SqlInjectionAtmConfig; - -/** - * A taint-tracking configuration for reasoning about SQL injection vulnerabilities. - * - * This is largely a copy of the taint tracking configuration for the standard SQL injection - * query, except additional sinks have been added using the sink endpoint filter. - */ -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "SqlInjectionATM" } + /** + * This is largely a copy of the taint tracking configuration for the standard SQL injection + * query, except additional sinks have been added using the sink endpoint filter. + */ override predicate isSource(DataFlow::Node source) { source instanceof SqlInjection::Source } override predicate isSink(DataFlow::Node sink) { - sink instanceof SqlInjection::Sink or any(SqlInjectionAtmConfig cfg).isEffectiveSink(sink) + sink instanceof SqlInjection::Sink or isEffectiveSink(sink) } override predicate isSanitizer(DataFlow::Node node) { diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll index 302907820da..646748b29bc 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll @@ -1,6 +1,7 @@ /** * For internal use only. * + * A taint-tracking configuration for reasoning about path injection vulnerabilities. * Defines shared code used by the path injection boosted query. */ @@ -8,33 +9,24 @@ import semmle.javascript.heuristics.SyntacticHeuristics import semmle.javascript.security.dataflow.TaintedPathCustomizations import AdaptiveThreatModeling -class TaintedPathAtmConfig extends AtmConfig { - TaintedPathAtmConfig() { this = "TaintedPathATMConfig" } +class Configuration extends AtmConfig { + Configuration() { this = "TaintedPathATMConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof TaintedPath::Source } override EndpointType getASinkEndpointType() { result instanceof TaintedPathSinkType } -} - -/** DEPRECATED: Alias for TaintedPathAtmConfig */ -deprecated class TaintedPathATMConfig = TaintedPathAtmConfig; - -/** - * A taint-tracking configuration for reasoning about path injection vulnerabilities. - * - * This is largely a copy of the taint tracking configuration for the standard path injection - * query, except additional ATM sinks have been added to the `isSink` predicate. - */ -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "TaintedPathATM" } + /** + * This is largely a copy of the taint tracking configuration for the standard path injection + * query, except additional ATM sinks have been added to the `isSink` predicate. + */ override predicate isSource(DataFlow::Node source) { source instanceof TaintedPath::Source } override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { label = sink.(TaintedPath::Sink).getAFlowLabel() or // Allow effective sinks to have any taint label - any(TaintedPathAtmConfig cfg).isEffectiveSink(sink) + isEffectiveSink(sink) } override predicate isSanitizer(DataFlow::Node node) { node instanceof TaintedPath::Sanitizer } @@ -60,7 +52,7 @@ class Configuration extends TaintTracking::Configuration { * of barrier guards, we port the barrier guards for the boosted query from the standard library to * sanitizer guards here. */ -class BarrierGuardNodeAsSanitizerGuardNode extends TaintTracking::LabeledSanitizerGuardNode { +private class BarrierGuardNodeAsSanitizerGuardNode extends TaintTracking::LabeledSanitizerGuardNode { BarrierGuardNodeAsSanitizerGuardNode() { this instanceof TaintedPath::BarrierGuardNode } override predicate sanitizes(boolean outcome, Expr e) { diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll index 2cc848a7ea9..5869be2c325 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll @@ -8,31 +8,24 @@ private import semmle.javascript.heuristics.SyntacticHeuristics private import semmle.javascript.security.dataflow.DomBasedXssCustomizations import AdaptiveThreatModeling -class DomBasedXssAtmConfig extends AtmConfig { - DomBasedXssAtmConfig() { this = "DomBasedXssATMConfig" } +class Configuration extends AtmConfig { + Configuration() { this = "DomBasedXssATMConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof DomBasedXss::Source } override EndpointType getASinkEndpointType() { result instanceof XssSinkType } -} - -/** DEPRECATED: Alias for DomBasedXssAtmConfig */ -deprecated class DomBasedXssATMConfig = DomBasedXssAtmConfig; - -/** - * A taint-tracking configuration for reasoning about XSS vulnerabilities. - * - * This is largely a copy of the taint tracking configuration for the standard XSSThroughDom query, - * except additional ATM sinks have been added to the `isSink` predicate. - */ -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "DomBasedXssATMConfiguration" } + /** + * A taint-tracking configuration for reasoning about XSS vulnerabilities. + * + * This is largely a copy of the taint tracking configuration for the standard XSSThroughDom query, + * except additional ATM sinks have been added to the `isSink` predicate. + */ override predicate isSource(DataFlow::Node source) { source instanceof DomBasedXss::Source } override predicate isSink(DataFlow::Node sink) { sink instanceof DomBasedXss::Sink or - any(DomBasedXssAtmConfig cfg).isEffectiveSink(sink) + isEffectiveSink(sink) } override predicate isSanitizer(DataFlow::Node node) { diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql index 444f682304d..1b5c235107e 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql @@ -19,16 +19,16 @@ private import experimental.adaptivethreatmodeling.XssATM as XssAtm string getAReasonSinkExcluded(DataFlow::Node sinkCandidate, Query query) { query instanceof NosqlInjectionQuery and - result = any(NosqlInjectionAtm::NosqlInjectionAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) + result = any(NosqlInjectionAtm::Configuration cfg).getAReasonSinkExcluded(sinkCandidate) or query instanceof SqlInjectionQuery and - result = any(SqlInjectionAtm::SqlInjectionAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) + result = any(SqlInjectionAtm::Configuration cfg).getAReasonSinkExcluded(sinkCandidate) or query instanceof TaintedPathQuery and - result = any(TaintedPathAtm::TaintedPathAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) + result = any(TaintedPathAtm::Configuration cfg).getAReasonSinkExcluded(sinkCandidate) or query instanceof XssQuery and - result = any(XssAtm::DomBasedXssAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) + result = any(XssAtm::Configuration cfg).getAReasonSinkExcluded(sinkCandidate) } pragma[inline] diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql index 697928d74b0..98668ba01fd 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql @@ -14,15 +14,15 @@ from string queryName, AtmConfig c, EndpointType e where ( queryName = "SqlInjection" and - c instanceof SqlInjectionAtm::SqlInjectionAtmConfig + c instanceof SqlInjectionAtm::Configuration or queryName = "NosqlInjection" and - c instanceof NosqlInjectionAtm::NosqlInjectionAtmConfig + c instanceof NosqlInjectionAtm::Configuration or queryName = "TaintedPath" and - c instanceof TaintedPathAtm::TaintedPathAtmConfig + c instanceof TaintedPathAtm::Configuration or - queryName = "Xss" and c instanceof XssAtm::DomBasedXssAtmConfig + queryName = "Xss" and c instanceof XssAtm::Configuration ) and e = c.getASinkEndpointType() select queryName, e.getEncoding() as label diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql index 9439fda8ab2..04724557843 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql @@ -17,10 +17,10 @@ private import experimental.adaptivethreatmodeling.EndpointCharacteristics as En query predicate tokenFeatures(DataFlow::Node endpoint, string featureName, string featureValue) { ( - not exists(any(NosqlInjectionAtm::NosqlInjectionAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or - not exists(any(SqlInjectionAtm::SqlInjectionAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or - not exists(any(TaintedPathAtm::TaintedPathAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or - not exists(any(XssAtm::DomBasedXssAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or + not exists(any(NosqlInjectionAtm::Configuration cfg).getAReasonSinkExcluded(endpoint)) or + not exists(any(SqlInjectionAtm::Configuration cfg).getAReasonSinkExcluded(endpoint)) or + not exists(any(TaintedPathAtm::Configuration cfg).getAReasonSinkExcluded(endpoint)) or + not exists(any(XssAtm::Configuration cfg).getAReasonSinkExcluded(endpoint)) or any(EndpointCharacteristics::IsArgumentToModeledFunctionCharacteristic characteristic) .getEndpoints(endpoint) ) and diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql index d8de88e3454..deae494c226 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql @@ -23,24 +23,24 @@ import experimental.adaptivethreatmodeling.XssATM as XssAtm query predicate nosqlFilteredTruePositives(DataFlow::Node endpoint, string reason) { endpoint instanceof NosqlInjection::Sink and - reason = any(NosqlInjectionAtm::NosqlInjectionAtmConfig cfg).getAReasonSinkExcluded(endpoint) and + reason = any(NosqlInjectionAtm::Configuration cfg).getAReasonSinkExcluded(endpoint) and not reason = ["argument to modeled function", "modeled sink", "modeled database access"] } query predicate sqlFilteredTruePositives(DataFlow::Node endpoint, string reason) { endpoint instanceof SqlInjection::Sink and - reason = any(SqlInjectionAtm::SqlInjectionAtmConfig cfg).getAReasonSinkExcluded(endpoint) and + reason = any(SqlInjectionAtm::Configuration cfg).getAReasonSinkExcluded(endpoint) and reason != "argument to modeled function" } query predicate taintedPathFilteredTruePositives(DataFlow::Node endpoint, string reason) { endpoint instanceof TaintedPath::Sink and - reason = any(TaintedPathAtm::TaintedPathAtmConfig cfg).getAReasonSinkExcluded(endpoint) and + reason = any(TaintedPathAtm::Configuration cfg).getAReasonSinkExcluded(endpoint) and reason != "argument to modeled function" } query predicate xssFilteredTruePositives(DataFlow::Node endpoint, string reason) { endpoint instanceof DomBasedXss::Sink and - reason = any(XssAtm::DomBasedXssAtmConfig cfg).getAReasonSinkExcluded(endpoint) and + reason = any(XssAtm::Configuration cfg).getAReasonSinkExcluded(endpoint) and reason != "argument to modeled function" } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/modeled_apis/nosql_endpoint_filter_ignores_modeled_apis.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/modeled_apis/nosql_endpoint_filter_ignores_modeled_apis.ql index a1d06d2881d..b77685e966c 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/modeled_apis/nosql_endpoint_filter_ignores_modeled_apis.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/modeled_apis/nosql_endpoint_filter_ignores_modeled_apis.ql @@ -2,5 +2,5 @@ import javascript import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm query predicate effectiveSinks(DataFlow::Node node) { - not exists(any(NosqlInjectionAtm::NosqlInjectionAtmConfig cfg).getAReasonSinkExcluded(node)) + not exists(any(NosqlInjectionAtm::Configuration cfg).getAReasonSinkExcluded(node)) } From cd24ec88d6e57b00e0ba1e5e9110fbd451274ae1 Mon Sep 17 00:00:00 2001 From: tiferet Date: Thu, 17 Nov 2022 17:16:37 -0800 Subject: [PATCH 692/796] Move the definition of `isSource` to the base class: A long as we're not boosting sources, `isSource` is identical to `isKnownSource`. --- .../lib/experimental/adaptivethreatmodeling/ATMConfig.qll | 6 ++++++ .../adaptivethreatmodeling/NosqlInjectionATM.qll | 2 -- .../experimental/adaptivethreatmodeling/SqlInjectionATM.qll | 3 +-- .../experimental/adaptivethreatmodeling/TaintedPathATM.qll | 3 +-- .../lib/experimental/adaptivethreatmodeling/XssATM.qll | 6 ++---- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index 4106269d759..17ec9cf55cd 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -33,6 +33,12 @@ abstract class AtmConfig extends JS::TaintTracking::Configuration { bindingset[this] AtmConfig() { any() } + /** + * Holds if `source` is a relevant taint source. When sources are not boosted, `isSource` is equivalent to + * `isKnownSource` (i.e there are no "effective" sources to be classified by an ML model). + */ + override predicate isSource(JS::DataFlow::Node source) { this.isKnownSource(source) } + /** * EXPERIMENTAL. This API may change in the future. * diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll index 5de89d30c5e..6724b5794b8 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll @@ -25,8 +25,6 @@ class Configuration extends AtmConfig { * generalised to cover the sinks predicted by ATM. */ - override predicate isSource(DataFlow::Node source) { source instanceof NosqlInjection::Source } - override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { TaintedObject::isSource(source, label) } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll index d51e99060bd..cfca6bdebce 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll @@ -16,11 +16,10 @@ class Configuration extends AtmConfig { override EndpointType getASinkEndpointType() { result instanceof SqlInjectionSinkType } - /** + /* * This is largely a copy of the taint tracking configuration for the standard SQL injection * query, except additional sinks have been added using the sink endpoint filter. */ - override predicate isSource(DataFlow::Node source) { source instanceof SqlInjection::Source } override predicate isSink(DataFlow::Node sink) { sink instanceof SqlInjection::Sink or isEffectiveSink(sink) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll index 646748b29bc..a48eadc2532 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll @@ -16,11 +16,10 @@ class Configuration extends AtmConfig { override EndpointType getASinkEndpointType() { result instanceof TaintedPathSinkType } - /** + /* * This is largely a copy of the taint tracking configuration for the standard path injection * query, except additional ATM sinks have been added to the `isSink` predicate. */ - override predicate isSource(DataFlow::Node source) { source instanceof TaintedPath::Source } override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { label = sink.(TaintedPath::Sink).getAFlowLabel() diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll index 5869be2c325..cd3240e8cfc 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll @@ -1,6 +1,7 @@ /** * For internal use only. * + * A taint-tracking configuration for reasoning about XSS vulnerabilities. * Defines shared code used by the XSS boosted query. */ @@ -15,13 +16,10 @@ class Configuration extends AtmConfig { override EndpointType getASinkEndpointType() { result instanceof XssSinkType } - /** - * A taint-tracking configuration for reasoning about XSS vulnerabilities. - * + /* * This is largely a copy of the taint tracking configuration for the standard XSSThroughDom query, * except additional ATM sinks have been added to the `isSink` predicate. */ - override predicate isSource(DataFlow::Node source) { source instanceof DomBasedXss::Source } override predicate isSink(DataFlow::Node sink) { sink instanceof DomBasedXss::Sink or From a710b723d12f98aa6ef4de7cf9edf48d1239ae9a Mon Sep 17 00:00:00 2001 From: tiferet Date: Thu, 17 Nov 2022 17:57:57 -0800 Subject: [PATCH 693/796] Move the definition of `isSink` to the base class: Holds if `sink` is a known taint sink or an "effective" sink. --- .../lib/experimental/adaptivethreatmodeling/ATMConfig.qll | 7 +++++++ .../adaptivethreatmodeling/SqlInjectionATM.qll | 4 ---- .../lib/experimental/adaptivethreatmodeling/XssATM.qll | 5 ----- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index 17ec9cf55cd..a2a62911517 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -39,6 +39,13 @@ abstract class AtmConfig extends JS::TaintTracking::Configuration { */ override predicate isSource(JS::DataFlow::Node source) { this.isKnownSource(source) } + /** + * Holds if `sink` is a known taint sink or an "effective" sink (a candidate to be classified by an ML model). + */ + override predicate isSink(JS::DataFlow::Node sink) { + this.isKnownSink(sink) or this.isEffectiveSink(sink) + } + /** * EXPERIMENTAL. This API may change in the future. * diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll index cfca6bdebce..3dd9b595327 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll @@ -21,10 +21,6 @@ class Configuration extends AtmConfig { * query, except additional sinks have been added using the sink endpoint filter. */ - override predicate isSink(DataFlow::Node sink) { - sink instanceof SqlInjection::Sink or isEffectiveSink(sink) - } - override predicate isSanitizer(DataFlow::Node node) { super.isSanitizer(node) or node instanceof SqlInjection::Sanitizer diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll index cd3240e8cfc..43d8375b8a5 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll @@ -21,11 +21,6 @@ class Configuration extends AtmConfig { * except additional ATM sinks have been added to the `isSink` predicate. */ - override predicate isSink(DataFlow::Node sink) { - sink instanceof DomBasedXss::Sink or - isEffectiveSink(sink) - } - override predicate isSanitizer(DataFlow::Node node) { super.isSanitizer(node) or node instanceof DomBasedXss::Sanitizer From 75cd7a9ebce3692248fd486811ba188c13c840f4 Mon Sep 17 00:00:00 2001 From: tiferet Date: Fri, 18 Nov 2022 11:47:58 -0800 Subject: [PATCH 694/796] Remove code duplication in query .ql files: Define the query for finding ATM alerts in the base class `AtmConfig`, and call it from each query's .ql file. --- .../adaptivethreatmodeling/ATMConfig.qll | 12 ++++++++++++ .../adaptivethreatmodeling/src/NosqlInjectionATM.ql | 7 ++----- .../adaptivethreatmodeling/src/SqlInjectionATM.ql | 7 ++----- .../adaptivethreatmodeling/src/TaintedPathATM.ql | 7 ++----- .../adaptivethreatmodeling/src/XssATM.ql | 7 ++----- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index a2a62911517..d28cef259c3 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -7,6 +7,7 @@ private import javascript as JS import EndpointTypes import EndpointCharacteristics as EndpointCharacteristics +import AdaptiveThreatModeling::ATM::ResultsInfo as AtmResultsInfo /** * EXPERIMENTAL. This API may change in the future. @@ -140,6 +141,17 @@ abstract class AtmConfig extends JS::TaintTracking::Configuration { * A cut-off value of 1 produces all alerts including those that are likely false-positives. */ float getScoreCutoff() { result = 0.0 } + + /** + * Holds if there's an ATM alert (a flow path from `source` to `sink` with ML-determined likelihood `score`) according + * to this ML-boosted configuration, whereas the unboosted base query is unlikely to report an alert for this source + * and sink. + */ + predicate getAlerts(JS::DataFlow::PathNode source, JS::DataFlow::PathNode sink, float score) { + this.hasFlowPath(source, sink) and + not AtmResultsInfo::isFlowLikelyInBaseQuery(source.getNode(), sink.getNode()) and + score = AtmResultsInfo::getScoreForFlow(source.getNode(), sink.getNode()) + } } /** DEPRECATED: Alias for AtmConfig */ diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/NosqlInjectionATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/NosqlInjectionATM.ql index e35653fb96a..8ec315c3d9c 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/NosqlInjectionATM.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/NosqlInjectionATM.ql @@ -17,11 +17,8 @@ import ATM::ResultsInfo import DataFlow::PathGraph import experimental.adaptivethreatmodeling.NosqlInjectionATM -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score -where - cfg.hasFlowPath(source, sink) and - not isFlowLikelyInBaseQuery(source.getNode(), sink.getNode()) and - score = getScoreForFlow(source.getNode(), sink.getNode()) +from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score +where cfg.getAlerts(source, sink, score) select sink.getNode(), source, sink, "(Experimental) This may be a database query that depends on $@. Identified using machine learning.", source.getNode(), "a user-provided value", score diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/SqlInjectionATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/SqlInjectionATM.ql index b58dd9f4609..16921565707 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/SqlInjectionATM.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/SqlInjectionATM.ql @@ -17,11 +17,8 @@ import experimental.adaptivethreatmodeling.SqlInjectionATM import ATM::ResultsInfo import DataFlow::PathGraph -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score -where - cfg.hasFlowPath(source, sink) and - not isFlowLikelyInBaseQuery(source.getNode(), sink.getNode()) and - score = getScoreForFlow(source.getNode(), sink.getNode()) +from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score +where cfg.getAlerts(source, sink, score) select sink.getNode(), source, sink, "(Experimental) This may be a database query that depends on $@. Identified using machine learning.", source.getNode(), "a user-provided value", score diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/TaintedPathATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/TaintedPathATM.ql index 7e637687d75..e4e4db0bf32 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/TaintedPathATM.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/TaintedPathATM.ql @@ -21,11 +21,8 @@ import ATM::ResultsInfo import DataFlow::PathGraph import experimental.adaptivethreatmodeling.TaintedPathATM -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score -where - cfg.hasFlowPath(source, sink) and - not isFlowLikelyInBaseQuery(source.getNode(), sink.getNode()) and - score = getScoreForFlow(source.getNode(), sink.getNode()) +from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score +where cfg.getAlerts(source, sink, score) select sink.getNode(), source, sink, "(Experimental) This may be a path that depends on $@. Identified using machine learning.", source.getNode(), "a user-provided value", score diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/XssATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/XssATM.ql index d0e98c1cd54..deac86922ab 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/XssATM.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/XssATM.ql @@ -18,11 +18,8 @@ import ATM::ResultsInfo import DataFlow::PathGraph import experimental.adaptivethreatmodeling.XssATM -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score -where - cfg.hasFlowPath(source, sink) and - not isFlowLikelyInBaseQuery(source.getNode(), sink.getNode()) and - score = getScoreForFlow(source.getNode(), sink.getNode()) +from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score +where cfg.getAlerts(source, sink, score) select sink.getNode(), source, sink, "(Experimental) This may be a cross-site scripting vulnerability due to $@. Identified using machine learning.", source.getNode(), "a user-provided value", score From 6f807e9d43b94c5b0cd183766ca8b6e98d949371 Mon Sep 17 00:00:00 2001 From: tiferet Date: Tue, 29 Nov 2022 13:02:06 -0800 Subject: [PATCH 695/796] Doc suggestion from code review --- .../lib/experimental/adaptivethreatmodeling/ATMConfig.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index d28cef259c3..9f8c066f424 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -144,8 +144,8 @@ abstract class AtmConfig extends JS::TaintTracking::Configuration { /** * Holds if there's an ATM alert (a flow path from `source` to `sink` with ML-determined likelihood `score`) according - * to this ML-boosted configuration, whereas the unboosted base query is unlikely to report an alert for this source - * and sink. + * to this ML-boosted configuration, whereas the unboosted base query does not contain this source and sink + * combination. */ predicate getAlerts(JS::DataFlow::PathNode source, JS::DataFlow::PathNode sink, float score) { this.hasFlowPath(source, sink) and From 84ce23249f8806f53967b6dbc0cb6353ed7822ac Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 29 Nov 2022 22:20:45 +0100 Subject: [PATCH 696/796] use the query compilation cache in the ATM qltest --- .github/workflows/js-ml-tests.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/js-ml-tests.yml b/.github/workflows/js-ml-tests.yml index d3b5d49f2ba..f05bfccab1f 100644 --- a/.github/workflows/js-ml-tests.yml +++ b/.github/workflows/js-ml-tests.yml @@ -36,6 +36,12 @@ jobs: for pack in modelbuilding src; do codeql pack install --mode verify -- "${pack}" done + + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: js-ml-compilation - name: Check QL compilation run: | @@ -44,6 +50,7 @@ jobs: --ram 5120 \ --additional-packs "${{ github.workspace }}" \ --threads=0 \ + --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" \ -- \ lib modelbuilding src @@ -58,11 +65,18 @@ jobs: - name: Install pack dependencies run: codeql pack install -- test + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: js-ml-tests + - name: Run QL tests run: | codeql test run \ --threads=0 \ --ram 5120 \ --additional-packs "${{ github.workspace }}" \ + --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" \ -- \ test From 0eae638a93daa8fabb69be7a1272e7e18ad2f09d Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 29 Nov 2022 22:29:45 +0100 Subject: [PATCH 697/796] combine into one job, and run on an XL runner --- .github/workflows/js-ml-tests.yml | 33 ++++++++----------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/.github/workflows/js-ml-tests.yml b/.github/workflows/js-ml-tests.yml index f05bfccab1f..031b17c83ba 100644 --- a/.github/workflows/js-ml-tests.yml +++ b/.github/workflows/js-ml-tests.yml @@ -23,9 +23,9 @@ defaults: working-directory: javascript/ql/experimental/adaptivethreatmodeling jobs: - qlcompile: - name: Check QL compilation - runs-on: ubuntu-latest + qltest: + name: Test QL + runs-on: ubuntu-latest-xl steps: - uses: actions/checkout@v3 @@ -33,7 +33,7 @@ jobs: - name: Install pack dependencies run: | - for pack in modelbuilding src; do + for pack in modelbuilding src test; do codeql pack install --mode verify -- "${pack}" done @@ -41,42 +41,25 @@ jobs: id: query-cache uses: ./.github/actions/cache-query-compilation with: - key: js-ml-compilation + key: js-ml-test - name: Check QL compilation run: | codeql query compile \ --check-only \ - --ram 5120 \ + --ram 52000 \ --additional-packs "${{ github.workspace }}" \ --threads=0 \ --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" \ -- \ lib modelbuilding src - qltest: - name: Run QL tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - uses: ./.github/actions/fetch-codeql - - - name: Install pack dependencies - run: codeql pack install -- test - - - name: Cache compilation cache - id: query-cache - uses: ./.github/actions/cache-query-compilation - with: - key: js-ml-tests - - name: Run QL tests run: | codeql test run \ --threads=0 \ - --ram 5120 \ + --ram 52000 \ --additional-packs "${{ github.workspace }}" \ --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" \ -- \ - test + test \ No newline at end of file From c5184d37e7c8b3cfafaf5dcafab850589315bfac Mon Sep 17 00:00:00 2001 From: tiferet Date: Tue, 29 Nov 2022 15:46:05 -0800 Subject: [PATCH 698/796] Suggestion from code review: Name the query configuration e.g. `NosqlInjectionATMConfig` rather than `Configuration`. --- .../adaptivethreatmodeling/NosqlInjectionATM.qll | 4 ++-- .../adaptivethreatmodeling/SqlInjectionATM.qll | 4 ++-- .../adaptivethreatmodeling/TaintedPathATM.qll | 4 ++-- .../lib/experimental/adaptivethreatmodeling/XssATM.qll | 4 ++-- .../modelbuilding/DebugResultInclusion.ql | 8 ++++---- .../extraction/ExtractEndpointDataTraining.qll | 9 +++++---- .../modelbuilding/extraction/ExtractEndpointMapping.ql | 8 ++++---- .../test/endpoint_large_scale/EndpointFeatures.ql | 8 ++++---- .../test/endpoint_large_scale/FilteredTruePositives.ql | 8 ++++---- .../nosql_endpoint_filter_ignores_modeled_apis.ql | 2 +- 10 files changed, 30 insertions(+), 29 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll index 6724b5794b8..e6d602280a4 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll @@ -10,8 +10,8 @@ private import semmle.javascript.heuristics.SyntacticHeuristics private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations import AdaptiveThreatModeling -class Configuration extends AtmConfig { - Configuration() { this = "NosqlInjectionATMConfig" } +class NosqlInjectionAtmConfig extends AtmConfig { + NosqlInjectionAtmConfig() { this = "NosqlInjectionAtmConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof NosqlInjection::Source or TaintedObject::isSource(source, _) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll index 3dd9b595327..917e79f401e 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll @@ -9,8 +9,8 @@ import semmle.javascript.heuristics.SyntacticHeuristics import semmle.javascript.security.dataflow.SqlInjectionCustomizations import AdaptiveThreatModeling -class Configuration extends AtmConfig { - Configuration() { this = "SqlInjectionATMConfig" } +class SqlInjectionAtmConfig extends AtmConfig { + SqlInjectionAtmConfig() { this = "SqlInjectionAtmConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof SqlInjection::Source } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll index a48eadc2532..55b295c72ba 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll @@ -9,8 +9,8 @@ import semmle.javascript.heuristics.SyntacticHeuristics import semmle.javascript.security.dataflow.TaintedPathCustomizations import AdaptiveThreatModeling -class Configuration extends AtmConfig { - Configuration() { this = "TaintedPathATMConfig" } +class TaintedPathAtmConfig extends AtmConfig { + TaintedPathAtmConfig() { this = "TaintedPathAtmConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof TaintedPath::Source } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll index 43d8375b8a5..d28b669bf49 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll @@ -9,8 +9,8 @@ private import semmle.javascript.heuristics.SyntacticHeuristics private import semmle.javascript.security.dataflow.DomBasedXssCustomizations import AdaptiveThreatModeling -class Configuration extends AtmConfig { - Configuration() { this = "DomBasedXssATMConfig" } +class DomBasedXssAtmConfig extends AtmConfig { + DomBasedXssAtmConfig() { this = "DomBasedXssAtmConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof DomBasedXss::Source } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql index 1b5c235107e..444f682304d 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql @@ -19,16 +19,16 @@ private import experimental.adaptivethreatmodeling.XssATM as XssAtm string getAReasonSinkExcluded(DataFlow::Node sinkCandidate, Query query) { query instanceof NosqlInjectionQuery and - result = any(NosqlInjectionAtm::Configuration cfg).getAReasonSinkExcluded(sinkCandidate) + result = any(NosqlInjectionAtm::NosqlInjectionAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) or query instanceof SqlInjectionQuery and - result = any(SqlInjectionAtm::Configuration cfg).getAReasonSinkExcluded(sinkCandidate) + result = any(SqlInjectionAtm::SqlInjectionAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) or query instanceof TaintedPathQuery and - result = any(TaintedPathAtm::Configuration cfg).getAReasonSinkExcluded(sinkCandidate) + result = any(TaintedPathAtm::TaintedPathAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) or query instanceof XssQuery and - result = any(XssAtm::Configuration cfg).getAReasonSinkExcluded(sinkCandidate) + result = any(XssAtm::DomBasedXssAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) } pragma[inline] diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll index 73628c744cf..325809e085f 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll @@ -206,13 +206,14 @@ query predicate reformattedTrainingEndpoints( * TODO: Delete this once we are no longer surfacing `hasFlowFromSource`. */ DataFlow::Configuration getDataFlowCfg(Query query) { - query instanceof NosqlInjectionQuery and result instanceof NosqlInjectionAtm::Configuration + query instanceof NosqlInjectionQuery and + result instanceof NosqlInjectionAtm::NosqlInjectionAtmConfig or - query instanceof SqlInjectionQuery and result instanceof SqlInjectionAtm::Configuration + query instanceof SqlInjectionQuery and result instanceof SqlInjectionAtm::SqlInjectionAtmConfig or - query instanceof TaintedPathQuery and result instanceof TaintedPathAtm::Configuration + query instanceof TaintedPathQuery and result instanceof TaintedPathAtm::TaintedPathAtmConfig or - query instanceof XssQuery and result instanceof XssAtm::Configuration + query instanceof XssQuery and result instanceof XssAtm::DomBasedXssAtmConfig } // TODO: Delete this once we are no longer surfacing `hasFlowFromSource`. diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql index 98668ba01fd..697928d74b0 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql @@ -14,15 +14,15 @@ from string queryName, AtmConfig c, EndpointType e where ( queryName = "SqlInjection" and - c instanceof SqlInjectionAtm::Configuration + c instanceof SqlInjectionAtm::SqlInjectionAtmConfig or queryName = "NosqlInjection" and - c instanceof NosqlInjectionAtm::Configuration + c instanceof NosqlInjectionAtm::NosqlInjectionAtmConfig or queryName = "TaintedPath" and - c instanceof TaintedPathAtm::Configuration + c instanceof TaintedPathAtm::TaintedPathAtmConfig or - queryName = "Xss" and c instanceof XssAtm::Configuration + queryName = "Xss" and c instanceof XssAtm::DomBasedXssAtmConfig ) and e = c.getASinkEndpointType() select queryName, e.getEncoding() as label diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql index 04724557843..9439fda8ab2 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql @@ -17,10 +17,10 @@ private import experimental.adaptivethreatmodeling.EndpointCharacteristics as En query predicate tokenFeatures(DataFlow::Node endpoint, string featureName, string featureValue) { ( - not exists(any(NosqlInjectionAtm::Configuration cfg).getAReasonSinkExcluded(endpoint)) or - not exists(any(SqlInjectionAtm::Configuration cfg).getAReasonSinkExcluded(endpoint)) or - not exists(any(TaintedPathAtm::Configuration cfg).getAReasonSinkExcluded(endpoint)) or - not exists(any(XssAtm::Configuration cfg).getAReasonSinkExcluded(endpoint)) or + not exists(any(NosqlInjectionAtm::NosqlInjectionAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or + not exists(any(SqlInjectionAtm::SqlInjectionAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or + not exists(any(TaintedPathAtm::TaintedPathAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or + not exists(any(XssAtm::DomBasedXssAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or any(EndpointCharacteristics::IsArgumentToModeledFunctionCharacteristic characteristic) .getEndpoints(endpoint) ) and diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql index deae494c226..d8de88e3454 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql @@ -23,24 +23,24 @@ import experimental.adaptivethreatmodeling.XssATM as XssAtm query predicate nosqlFilteredTruePositives(DataFlow::Node endpoint, string reason) { endpoint instanceof NosqlInjection::Sink and - reason = any(NosqlInjectionAtm::Configuration cfg).getAReasonSinkExcluded(endpoint) and + reason = any(NosqlInjectionAtm::NosqlInjectionAtmConfig cfg).getAReasonSinkExcluded(endpoint) and not reason = ["argument to modeled function", "modeled sink", "modeled database access"] } query predicate sqlFilteredTruePositives(DataFlow::Node endpoint, string reason) { endpoint instanceof SqlInjection::Sink and - reason = any(SqlInjectionAtm::Configuration cfg).getAReasonSinkExcluded(endpoint) and + reason = any(SqlInjectionAtm::SqlInjectionAtmConfig cfg).getAReasonSinkExcluded(endpoint) and reason != "argument to modeled function" } query predicate taintedPathFilteredTruePositives(DataFlow::Node endpoint, string reason) { endpoint instanceof TaintedPath::Sink and - reason = any(TaintedPathAtm::Configuration cfg).getAReasonSinkExcluded(endpoint) and + reason = any(TaintedPathAtm::TaintedPathAtmConfig cfg).getAReasonSinkExcluded(endpoint) and reason != "argument to modeled function" } query predicate xssFilteredTruePositives(DataFlow::Node endpoint, string reason) { endpoint instanceof DomBasedXss::Sink and - reason = any(XssAtm::Configuration cfg).getAReasonSinkExcluded(endpoint) and + reason = any(XssAtm::DomBasedXssAtmConfig cfg).getAReasonSinkExcluded(endpoint) and reason != "argument to modeled function" } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/modeled_apis/nosql_endpoint_filter_ignores_modeled_apis.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/modeled_apis/nosql_endpoint_filter_ignores_modeled_apis.ql index b77685e966c..a1d06d2881d 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/modeled_apis/nosql_endpoint_filter_ignores_modeled_apis.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/modeled_apis/nosql_endpoint_filter_ignores_modeled_apis.ql @@ -2,5 +2,5 @@ import javascript import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm query predicate effectiveSinks(DataFlow::Node node) { - not exists(any(NosqlInjectionAtm::Configuration cfg).getAReasonSinkExcluded(node)) + not exists(any(NosqlInjectionAtm::NosqlInjectionAtmConfig cfg).getAReasonSinkExcluded(node)) } From 0a98559fcb26c45a677db06d73cc56d8752f7e2f Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Mon, 7 Nov 2022 12:29:14 +1300 Subject: [PATCH 699/796] Ruby: Add flow summaries for ActiveSupport::JSON --- .../codeql/ruby/frameworks/ActiveSupport.qll | 13 ++++++++++++ .../ActiveSupportDataFlow.expected | 20 +++++++++++++++++++ .../active_support/active_support.rb | 20 +++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll index 3e90875206c..79be1a72617 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll @@ -374,4 +374,17 @@ module ActiveSupport { ] } } + + /** `ActiveSupport::JSON` */ + module Json { + private class JsonSummary extends ModelInput::SummaryModelCsv { + override predicate row(string row) { + row = + [ + "activesupport;;Member[ActiveSupport].Member[JSON].Method[encode,dump];Argument[0];ReturnValue;taint", + "activesupport;;Member[ActiveSupport].Member[JSON].Method[decode,load];Argument[0];ReturnValue;taint", + ] + } + } + } } diff --git a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected index 2ea08b4c384..8a44022f72f 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected +++ b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected @@ -189,6 +189,14 @@ edges | active_support.rb:303:7:303:16 | call to source : | active_support.rb:304:19:304:19 | a : | | active_support.rb:304:7:304:19 | call to json_escape : | active_support.rb:305:8:305:8 | b | | active_support.rb:304:19:304:19 | a : | active_support.rb:304:7:304:19 | call to json_escape : | +| active_support.rb:309:9:309:18 | call to source : | active_support.rb:310:37:310:37 | x : | +| active_support.rb:310:37:310:37 | x : | active_support.rb:310:10:310:38 | call to encode | +| active_support.rb:314:9:314:18 | call to source : | active_support.rb:315:37:315:37 | x : | +| active_support.rb:315:37:315:37 | x : | active_support.rb:315:10:315:38 | call to decode | +| active_support.rb:319:9:319:18 | call to source : | active_support.rb:320:35:320:35 | x : | +| active_support.rb:320:35:320:35 | x : | active_support.rb:320:10:320:36 | call to dump | +| active_support.rb:324:9:324:18 | call to source : | active_support.rb:325:35:325:35 | x : | +| active_support.rb:325:35:325:35 | x : | active_support.rb:325:10:325:36 | call to load | | hash_extensions.rb:2:14:2:24 | call to source : | hash_extensions.rb:3:9:3:9 | h [element :a] : | | hash_extensions.rb:2:14:2:24 | call to source : | hash_extensions.rb:3:9:3:9 | h [element :a] : | | hash_extensions.rb:3:9:3:9 | h [element :a] : | hash_extensions.rb:3:9:3:24 | call to stringify_keys [element] : | @@ -539,6 +547,18 @@ nodes | active_support.rb:304:7:304:19 | call to json_escape : | semmle.label | call to json_escape : | | active_support.rb:304:19:304:19 | a : | semmle.label | a : | | active_support.rb:305:8:305:8 | b | semmle.label | b | +| active_support.rb:309:9:309:18 | call to source : | semmle.label | call to source : | +| active_support.rb:310:10:310:38 | call to encode | semmle.label | call to encode | +| active_support.rb:310:37:310:37 | x : | semmle.label | x : | +| active_support.rb:314:9:314:18 | call to source : | semmle.label | call to source : | +| active_support.rb:315:10:315:38 | call to decode | semmle.label | call to decode | +| active_support.rb:315:37:315:37 | x : | semmle.label | x : | +| active_support.rb:319:9:319:18 | call to source : | semmle.label | call to source : | +| active_support.rb:320:10:320:36 | call to dump | semmle.label | call to dump | +| active_support.rb:320:35:320:35 | x : | semmle.label | x : | +| active_support.rb:324:9:324:18 | call to source : | semmle.label | call to source : | +| active_support.rb:325:10:325:36 | call to load | semmle.label | call to load | +| active_support.rb:325:35:325:35 | x : | semmle.label | x : | | hash_extensions.rb:2:14:2:24 | call to source : | semmle.label | call to source : | | hash_extensions.rb:2:14:2:24 | call to source : | semmle.label | call to source : | | hash_extensions.rb:3:9:3:9 | h [element :a] : | semmle.label | h [element :a] : | diff --git a/ruby/ql/test/library-tests/frameworks/active_support/active_support.rb b/ruby/ql/test/library-tests/frameworks/active_support/active_support.rb index c2dfb8b421d..a71af8bc5e6 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/active_support.rb +++ b/ruby/ql/test/library-tests/frameworks/active_support/active_support.rb @@ -304,3 +304,23 @@ def m_json_escape b = json_escape a sink b # $hasTaintFlow=a end + +def m_json_encode + x = source "a" + sink ActiveSupport::JSON.encode(x) # $hasTaintFlow=a +end + +def m_json_decode + x = source "a" + sink ActiveSupport::JSON.decode(x) # $hasTaintFlow=a +end + +def m_json_dump + x = source "a" + sink ActiveSupport::JSON.dump(x) # $hasTaintFlow=a +end + +def m_json_load + x = source "a" + sink ActiveSupport::JSON.load(x) # $hasTaintFlow=a +end From 5259d4af63105f0f0b03a895596d086cd8132636 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Mon, 7 Nov 2022 12:46:03 +1300 Subject: [PATCH 700/796] Ruby: Model various JSON methods --- ruby/ql/lib/codeql/ruby/Frameworks.qll | 1 + ruby/ql/lib/codeql/ruby/frameworks/Json.qll | 22 +++++++++++++ .../frameworks/json/JsonDataFlow.expected | 32 +++++++++++++++++++ .../frameworks/json/JsonDataFlow.ql | 12 +++++++ .../library-tests/frameworks/json/json.rb | 10 ++++++ 5 files changed, 77 insertions(+) create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/Json.qll create mode 100644 ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.expected create mode 100644 ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.ql create mode 100644 ruby/ql/test/library-tests/frameworks/json/json.rb diff --git a/ruby/ql/lib/codeql/ruby/Frameworks.qll b/ruby/ql/lib/codeql/ruby/Frameworks.qll index 9896cf23c39..e608967f591 100644 --- a/ruby/ql/lib/codeql/ruby/Frameworks.qll +++ b/ruby/ql/lib/codeql/ruby/Frameworks.qll @@ -24,3 +24,4 @@ private import codeql.ruby.frameworks.XmlParsing private import codeql.ruby.frameworks.ActionDispatch private import codeql.ruby.frameworks.PosixSpawn private import codeql.ruby.frameworks.StringFormatters +private import codeql.ruby.frameworks.Json diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Json.qll b/ruby/ql/lib/codeql/ruby/frameworks/Json.qll new file mode 100644 index 00000000000..f82782199f2 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/Json.qll @@ -0,0 +1,22 @@ +/** Provides modelling for the `json` gem. */ + +private import codeql.ruby.frameworks.data.ModelsAsData + +/** Provides modelling for the `json` gem. */ +module Json { + /** + * Flow summaries for common `JSON` methods. + * Not all of these methods are strictly defined in the `json` gem. + * The `JSON` namespace is heavily overloaded by other JSON parsing gems such as `oj`, `json_pure`, `multi_json` etc. + * This summary covers common methods we've seen called on `JSON` in the wild. + */ + private class JsonSummary extends ModelInput::SummaryModelCsv { + override predicate row(string row) { + row = + [ + "json;;Member[JSON].Method[parse,parse!,load,restore];Argument[0];ReturnValue;taint", + "json;;Member[JSON].Method[generate,fast_generate,dump,unparse,fast_unparse];Argument[0];ReturnValue;taint", + ] + } + } +} diff --git a/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.expected b/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.expected new file mode 100644 index 00000000000..689a8d22702 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.expected @@ -0,0 +1,32 @@ +failures +edges +| json.rb:1:17:1:26 | call to source : | json.rb:1:6:1:27 | call to parse | +| json.rb:2:18:2:27 | call to source : | json.rb:2:6:2:28 | call to parse! | +| json.rb:3:16:3:25 | call to source : | json.rb:3:6:3:26 | call to load | +| json.rb:4:19:4:28 | call to source : | json.rb:4:6:4:29 | call to restore | +| json.rb:6:20:6:29 | call to source : | json.rb:6:6:6:30 | call to generate | +| json.rb:7:25:7:34 | call to source : | json.rb:7:6:7:35 | call to fast_generate | +| json.rb:8:16:8:25 | call to source : | json.rb:8:6:8:26 | call to dump | +| json.rb:9:19:9:28 | call to source : | json.rb:9:6:9:29 | call to unparse | +| json.rb:10:24:10:33 | call to source : | json.rb:10:6:10:34 | call to fast_unparse | +nodes +| json.rb:1:6:1:27 | call to parse | semmle.label | call to parse | +| json.rb:1:17:1:26 | call to source : | semmle.label | call to source : | +| json.rb:2:6:2:28 | call to parse! | semmle.label | call to parse! | +| json.rb:2:18:2:27 | call to source : | semmle.label | call to source : | +| json.rb:3:6:3:26 | call to load | semmle.label | call to load | +| json.rb:3:16:3:25 | call to source : | semmle.label | call to source : | +| json.rb:4:6:4:29 | call to restore | semmle.label | call to restore | +| json.rb:4:19:4:28 | call to source : | semmle.label | call to source : | +| json.rb:6:6:6:30 | call to generate | semmle.label | call to generate | +| json.rb:6:20:6:29 | call to source : | semmle.label | call to source : | +| json.rb:7:6:7:35 | call to fast_generate | semmle.label | call to fast_generate | +| json.rb:7:25:7:34 | call to source : | semmle.label | call to source : | +| json.rb:8:6:8:26 | call to dump | semmle.label | call to dump | +| json.rb:8:16:8:25 | call to source : | semmle.label | call to source : | +| json.rb:9:6:9:29 | call to unparse | semmle.label | call to unparse | +| json.rb:9:19:9:28 | call to source : | semmle.label | call to source : | +| json.rb:10:6:10:34 | call to fast_unparse | semmle.label | call to fast_unparse | +| json.rb:10:24:10:33 | call to source : | semmle.label | call to source : | +subpaths +#select diff --git a/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.ql b/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.ql new file mode 100644 index 00000000000..8a14d5f686e --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.ql @@ -0,0 +1,12 @@ +/** + * @kind path-problem + */ + +import codeql.ruby.AST +import TestUtilities.InlineFlowTest +import codeql.ruby.Frameworks +import PathGraph + +from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf +where conf.hasFlowPath(source, sink) +select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/frameworks/json/json.rb b/ruby/ql/test/library-tests/frameworks/json/json.rb new file mode 100644 index 00000000000..ee549a76447 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/json/json.rb @@ -0,0 +1,10 @@ +sink JSON.parse(source "a") # $hasTaintFlow=a +sink JSON.parse!(source "a") # $hasTaintFlow=a +sink JSON.load(source "a") # $hasTaintFlow=a +sink JSON.restore(source "a") # $hasTaintFlow=a + +sink JSON.generate(source "a") # $hasTaintFlow=a +sink JSON.fast_generate(source "a") # $hasTaintFlow=a +sink JSON.dump(source "a") # $hasTaintFlow=a +sink JSON.unparse(source "a") # $hasTaintFlow=a +sink JSON.fast_unparse(source "a") # $hasTaintFlow=a From eff763d127dc76a7a7a76c0ace9b12e58ca7e2d0 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Mon, 7 Nov 2022 12:52:20 +1300 Subject: [PATCH 701/796] Ruby: Model to_json ActiveSupport extension --- ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll | 11 +++++++++++ .../active_support/ActiveSupportDataFlow.expected | 11 +++++++++++ .../frameworks/active_support/active_support.rb | 7 +++++++ 3 files changed, 29 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll index 79be1a72617..a50d8888975 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll @@ -104,6 +104,17 @@ module ActiveSupport { override predicate runsArbitraryCode() { none() } } + + /** Flow summary for `Object#to_json`, which serializes the receiver as a JSON string. */ + private class ToJsonSummary extends SimpleSummarizedCallable { + ToJsonSummary() { this = "to_json" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = ["Argument[self]", "Argument[self].Element[any]"] and + output = "ReturnValue" and + preservesValue = false + } + } } /** diff --git a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected index 8a44022f72f..5641c2185db 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected +++ b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected @@ -197,6 +197,11 @@ edges | active_support.rb:320:35:320:35 | x : | active_support.rb:320:10:320:36 | call to dump | | active_support.rb:324:9:324:18 | call to source : | active_support.rb:325:35:325:35 | x : | | active_support.rb:325:35:325:35 | x : | active_support.rb:325:10:325:36 | call to load | +| active_support.rb:329:9:329:18 | call to source : | active_support.rb:330:10:330:10 | x : | +| active_support.rb:329:9:329:18 | call to source : | active_support.rb:331:10:331:10 | x : | +| active_support.rb:330:10:330:10 | x : | active_support.rb:332:10:332:10 | y [element 0] : | +| active_support.rb:331:10:331:10 | x : | active_support.rb:331:10:331:18 | call to to_json | +| active_support.rb:332:10:332:10 | y [element 0] : | active_support.rb:332:10:332:18 | call to to_json | | hash_extensions.rb:2:14:2:24 | call to source : | hash_extensions.rb:3:9:3:9 | h [element :a] : | | hash_extensions.rb:2:14:2:24 | call to source : | hash_extensions.rb:3:9:3:9 | h [element :a] : | | hash_extensions.rb:3:9:3:9 | h [element :a] : | hash_extensions.rb:3:9:3:24 | call to stringify_keys [element] : | @@ -559,6 +564,12 @@ nodes | active_support.rb:324:9:324:18 | call to source : | semmle.label | call to source : | | active_support.rb:325:10:325:36 | call to load | semmle.label | call to load | | active_support.rb:325:35:325:35 | x : | semmle.label | x : | +| active_support.rb:329:9:329:18 | call to source : | semmle.label | call to source : | +| active_support.rb:330:10:330:10 | x : | semmle.label | x : | +| active_support.rb:331:10:331:10 | x : | semmle.label | x : | +| active_support.rb:331:10:331:18 | call to to_json | semmle.label | call to to_json | +| active_support.rb:332:10:332:10 | y [element 0] : | semmle.label | y [element 0] : | +| active_support.rb:332:10:332:18 | call to to_json | semmle.label | call to to_json | | hash_extensions.rb:2:14:2:24 | call to source : | semmle.label | call to source : | | hash_extensions.rb:2:14:2:24 | call to source : | semmle.label | call to source : | | hash_extensions.rb:3:9:3:9 | h [element :a] : | semmle.label | h [element :a] : | diff --git a/ruby/ql/test/library-tests/frameworks/active_support/active_support.rb b/ruby/ql/test/library-tests/frameworks/active_support/active_support.rb index a71af8bc5e6..661f2ecd0cf 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/active_support.rb +++ b/ruby/ql/test/library-tests/frameworks/active_support/active_support.rb @@ -324,3 +324,10 @@ def m_json_load x = source "a" sink ActiveSupport::JSON.load(x) # $hasTaintFlow=a end + +def m_to_json + x = source "a" + y = [x] + sink x.to_json # $hasTaintFlow=a + sink y.to_json # $hasTaintFlow=a +end From 1bd2dd0a6e5f2942a6b408c1b553ff1c9f93a9a4 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Mon, 7 Nov 2022 14:53:34 +1300 Subject: [PATCH 702/796] Ruby: update test fixture --- ruby/ql/test/library-tests/dataflow/local/TaintStep.expected | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected index f1b8eb2da26..fe75f1b0313 100644 --- a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected +++ b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected @@ -21,6 +21,10 @@ | file://:0:0:0:0 | parameter position 0 of activesupport;;Member[ActionView].Member[SafeBuffer].Instance.Method[safe_concat] | file://:0:0:0:0 | [summary] to write: argument self in activesupport;;Member[ActionView].Member[SafeBuffer].Instance.Method[safe_concat] | | file://:0:0:0:0 | parameter position 0 of activesupport;;Member[ActionView].Member[SafeBuffer].Instance.Method[safe_concat] | file://:0:0:0:0 | [summary] to write: return (return) in activesupport;;Member[ActionView].Member[SafeBuffer].Instance.Method[safe_concat] | | file://:0:0:0:0 | parameter position 0 of activesupport;;Member[ActionView].Member[SafeBuffer].Method[new] | file://:0:0:0:0 | [summary] to write: return (return) in activesupport;;Member[ActionView].Member[SafeBuffer].Method[new] | +| file://:0:0:0:0 | parameter position 0 of activesupport;;Member[ActiveSupport].Member[JSON].Method[decode,load] | file://:0:0:0:0 | [summary] to write: return (return) in activesupport;;Member[ActiveSupport].Member[JSON].Method[decode,load] | +| file://:0:0:0:0 | parameter position 0 of activesupport;;Member[ActiveSupport].Member[JSON].Method[encode,dump] | file://:0:0:0:0 | [summary] to write: return (return) in activesupport;;Member[ActiveSupport].Member[JSON].Method[encode,dump] | +| file://:0:0:0:0 | parameter position 0 of json;;Member[JSON].Method[generate,fast_generate,dump,unparse,fast_unparse] | file://:0:0:0:0 | [summary] to write: return (return) in json;;Member[JSON].Method[generate,fast_generate,dump,unparse,fast_unparse] | +| file://:0:0:0:0 | parameter position 0 of json;;Member[JSON].Method[parse,parse!,load,restore] | file://:0:0:0:0 | [summary] to write: return (return) in json;;Member[JSON].Method[parse,parse!,load,restore] | | file://:0:0:0:0 | parameter position 0.. of File.join | file://:0:0:0:0 | [summary] to write: return (return) in File.join | | file://:0:0:0:0 | parameter self of & | file://:0:0:0:0 | [summary] read: argument self.any element in & | | file://:0:0:0:0 | parameter self of * | file://:0:0:0:0 | [summary] read: argument self.any element in * | From 35a62018e43eee4594380c950d7265ccbc5086b2 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Mon, 7 Nov 2022 14:53:57 +1300 Subject: [PATCH 703/796] Ruby: US spelling --- ruby/ql/lib/codeql/ruby/frameworks/Json.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Json.qll b/ruby/ql/lib/codeql/ruby/frameworks/Json.qll index f82782199f2..3024fea57a1 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Json.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Json.qll @@ -1,8 +1,8 @@ -/** Provides modelling for the `json` gem. */ +/** Provides modeling for the `json` gem. */ private import codeql.ruby.frameworks.data.ModelsAsData -/** Provides modelling for the `json` gem. */ +/** Provides modeling for the `json` gem. */ module Json { /** * Flow summaries for common `JSON` methods. From 13f4a0e284ef0085f033242d9c9be1c44291a4ed Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 30 Nov 2022 00:18:26 +0000 Subject: [PATCH 704/796] Add changed framework coverage reports --- .../library-coverage/coverage.csv | 262 +++++++++--------- .../library-coverage/coverage.rst | 8 +- 2 files changed, 136 insertions(+), 134 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index 75e3309bb4c..496d7f2f9e3 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -1,130 +1,132 @@ -package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jdbc-url,sink:jexl,sink:jndi-injection,sink:ldap,sink:logging,sink:mvel,sink:ognl-injection,sink:open-url,sink:pending-intent-sent,sink:regex-use,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:set-hostname-verifier,sink:sql,sink:ssti,sink:url-open-stream,sink:url-redirect,sink:write-file,sink:xpath,sink:xslt,sink:xss,source:android-external-storage-dir,source:android-widget,source:contentprovider,source:remote,summary:taint,summary:value -android.app,24,,103,,,,,,7,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,18,85 -android.content,24,31,154,,,,,,16,,,,,,,,,,,,,,,,,,8,,,,,,,,4,,27,,63,91 -android.database,59,,39,,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,,,,,39, -android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15 -android.os,,2,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,41,81 -android.util,6,16,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,16,, -android.webkit,3,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,2,, -android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,1, -androidx.core.app,6,,95,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,12,83 -androidx.slice,2,5,88,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,5,,27,61 -cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, -com.google.common.base,4,,85,,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,,,,62,23 -com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 -com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 -com.google.common.flogger,29,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,,,,, -com.google.common.io,6,,73,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,72,1 -com.hubspot.jinjava,2,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,, -com.mitchellbosecke.pebble,2,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,, -com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,,,,, -com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7, -com.unboundid.ldap.sdk,17,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,, -com.zaxxer.hikari,2,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -freemarker.cache,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,, -freemarker.template,7,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,, -groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, -jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 -jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, -jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, -jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 -java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -java.io,37,,40,,15,,,,,,,,,,,,,,,,,,,,,,,,,,22,,,,,,,,40, -java.lang,13,,66,,,,,,,,,,,8,,,,,,4,,,1,,,,,,,,,,,,,,,,54,12 -java.net,10,3,7,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,,,3,7, -java.nio,15,,16,,13,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,16, -java.sql,11,,,,,,,,,4,,,,,,,,,,,,,,,,,7,,,,,,,,,,,,, -java.util,44,,461,,,,,,,,,,,34,,,,,,,5,2,,1,2,,,,,,,,,,,,,,36,425 -javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, -javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57, -javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 -javax.management.remote,2,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,, -javax.naming,7,,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,,,,,,,,,,, -javax.net.ssl,2,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,, -javax.script,1,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,, -javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,2, -javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,, -javax.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, -javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, -javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 -javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,6, -javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,, -jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 -kotlin,12,,1835,,10,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,1828,7 -net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,,, -ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,, -okhttp3,2,,47,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,22,25 -org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, -org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 -org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 -org.apache.commons.io,106,,556,,91,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,542,14 -org.apache.commons.jexl2,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.jexl3,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.lang3,6,,424,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,293,131 -org.apache.commons.logging,6,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52 -org.apache.directory.ldap.client.api,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,2,39, -org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2, -org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6 -org.apache.http,27,3,70,,,,,,,,,,,,,,25,,,,,,,,,,,,,,,,,2,,,,3,62,8 -org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,57, -org.apache.log4j,11,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.logging.log4j,359,,8,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,,,,4,4 -org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.shiro.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.velocity.app,4,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,, -org.apache.velocity.runtime,4,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,, -org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,,, -org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,,, -org.jboss.logging,324,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,,,,, -org.jdbi.v3.core,6,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,, -org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38 -org.mvel2,16,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,,,,, -org.scijava.log,13,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,,,,, -org.slf4j,55,,6,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,,,,2,4 -org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30 -org.springframework.boot.jdbc,1,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13 -org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -org.springframework.data.repository,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -org.springframework.http,14,,70,,,,,,,,,,,,,,14,,,,,,,,,,,,,,,,,,,,,,60,10 -org.springframework.jdbc.core,10,,,,,,,,,,,,,,,,,,,,,,,,,,10,,,,,,,,,,,,, -org.springframework.jdbc.datasource,4,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,,, -org.springframework.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.ldap,47,,,,,,,,,,,33,14,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,, -org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32 -org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,87,52 -org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13, -org.springframework.web.client,13,3,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,3,, -org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,, -org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13, -org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,138,25 -org.thymeleaf,2,,2,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,2, -org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,, -play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,, -ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, -ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, -ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48 -ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 -ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, -ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, -ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 -retrofit2,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, +package,sink,source,summary,sink:bean-validation,sink:create-file,sink:fragment-injection,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jdbc-url,sink:jexl,sink:jndi-injection,sink:ldap,sink:logging,sink:mvel,sink:ognl-injection,sink:open-url,sink:pending-intent-sent,sink:regex-use,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:set-hostname-verifier,sink:sql,sink:ssti,sink:url-open-stream,sink:url-redirect,sink:write-file,sink:xpath,sink:xslt,sink:xss,source:android-external-storage-dir,source:android-widget,source:contentprovider,source:remote,summary:taint,summary:value +android.app,35,,103,,,11,,,,7,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,18,85 +android.content,24,31,154,,,,,,,16,,,,,,,,,,,,,,,,,,8,,,,,,,,4,,27,,63,91 +android.database,59,,39,,,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,,,,,39, +android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15 +android.os,,2,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,41,81 +android.support.v4.app,11,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +android.util,6,16,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,16,, +android.webkit,3,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,2,, +android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,1, +androidx.core.app,6,,95,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,12,83 +androidx.fragment.app,11,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +androidx.slice,2,5,88,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,5,,27,61 +cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, +com.google.common.base,4,,85,,,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,,,,62,23 +com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 +com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 +com.google.common.flogger,29,,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,,,,, +com.google.common.io,6,,73,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,72,1 +com.hubspot.jinjava,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,, +com.mitchellbosecke.pebble,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,, +com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,,,,, +com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7, +com.unboundid.ldap.sdk,17,,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,, +com.zaxxer.hikari,2,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 +freemarker.cache,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,, +freemarker.template,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,, +groovy.lang,26,,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +groovy.util,5,,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, +jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 +jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, +jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, +jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 +java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +java.io,37,,40,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,22,,,,,,,,40, +java.lang,13,,66,,,,,,,,,,,,8,,,,,,4,,,1,,,,,,,,,,,,,,,,54,12 +java.net,10,3,7,,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,,,3,7, +java.nio,15,,16,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,16, +java.sql,11,,,,,,,,,,4,,,,,,,,,,,,,,,,,7,,,,,,,,,,,,, +java.util,44,,461,,,,,,,,,,,,34,,,,,,,5,2,,1,2,,,,,,,,,,,,,,36,425 +javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, +javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57, +javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 +javax.management.remote,2,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,, +javax.naming,7,,,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,,,,,,,,,,, +javax.net.ssl,2,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,, +javax.script,1,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,, +javax.servlet,4,21,2,,,,,3,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,2, +javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,, +javax.ws.rs.client,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, +javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, +javax.ws.rs.core,3,,149,,,,,1,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 +javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,6, +javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,, +jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 +kotlin,12,,1835,,10,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,1828,7 +net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,,, +ognl,6,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,, +okhttp3,2,,47,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,22,25 +org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, +org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 +org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 +org.apache.commons.io,106,,560,,91,,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,546,14 +org.apache.commons.jexl2,15,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.jexl3,15,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.lang3,6,,424,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,293,131 +org.apache.commons.logging,6,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.ognl,6,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52 +org.apache.directory.ldap.client.api,1,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,2,39, +org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2, +org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6 +org.apache.http,27,3,70,,,,,,,,,,,,,,,25,,,,,,,,,,,,,,,,,2,,,,3,62,8 +org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,57, +org.apache.log4j,11,,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.logging.log4j,359,,8,,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,,,,4,4 +org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.shiro.jndi,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.velocity.app,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,, +org.apache.velocity.runtime,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,, +org.codehaus.groovy.control,1,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,,, +org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,,, +org.jboss.logging,324,,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,,,,, +org.jdbi.v3.core,6,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,, +org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38 +org.mvel2,16,,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,,,,, +org.scijava.log,13,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,,,,, +org.slf4j,55,,6,,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,,,,2,4 +org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30 +org.springframework.boot.jdbc,1,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13 +org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +org.springframework.data.repository,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 +org.springframework.http,14,,70,,,,,,,,,,,,,,,14,,,,,,,,,,,,,,,,,,,,,,60,10 +org.springframework.jdbc.core,10,,,,,,,,,,,,,,,,,,,,,,,,,,,10,,,,,,,,,,,,, +org.springframework.jdbc.datasource,4,,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,,, +org.springframework.jndi,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.ldap,47,,,,,,,,,,,,33,14,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,, +org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32 +org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,87,52 +org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13, +org.springframework.web.client,13,3,,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,3,, +org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,, +org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13, +org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,138,25 +org.thymeleaf,2,,2,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,2, +org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,, +play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,, +ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, +ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, +ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48 +ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 +ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, +ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, +ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 +retrofit2,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index 703932814c1..c5258aa5d3e 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -7,10 +7,10 @@ Java framework & library support :widths: auto Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE‑022` :sub:`Path injection`,`CWE‑036` :sub:`Path traversal`,`CWE‑079` :sub:`Cross-site scripting`,`CWE‑089` :sub:`SQL injection`,`CWE‑090` :sub:`LDAP injection`,`CWE‑094` :sub:`Code injection`,`CWE‑319` :sub:`Cleartext transmission` - Android,``android.*``,52,479,116,,,3,67,,, - Android extensions,``androidx.*``,5,183,8,,,,,,, + Android,``android.*``,52,479,138,,,3,67,,, + Android extensions,``androidx.*``,5,183,19,,,,,,, `Apache Commons Collections `_,"``org.apache.commons.collections``, ``org.apache.commons.collections4``",,1600,,,,,,,, - `Apache Commons IO `_,``org.apache.commons.io``,,556,106,91,,,,,,15 + `Apache Commons IO `_,``org.apache.commons.io``,,560,106,91,,,,,,15 `Apache Commons Lang `_,``org.apache.commons.lang3``,,424,6,,,,,,, `Apache Commons Text `_,``org.apache.commons.text``,,272,,,,,,,, `Apache HttpComponents `_,"``org.apache.hc.core5.*``, ``org.apache.http``",5,136,28,,,3,,,,25 @@ -23,5 +23,5 @@ Java framework & library support Kotlin Standard Library,``kotlin*``,,1835,12,10,,,,,,2 `Spring `_,``org.springframework.*``,29,477,101,,,,19,14,,29 Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.hubspot.jinjava``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",60,300,269,,,,14,18,,3 - Totals,,217,8434,1530,129,6,10,107,33,1,86 + Totals,,217,8438,1563,129,6,10,107,33,1,86 From d20d1e5e75c804ac6d9f70b333290d9686f97e0e Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Thu, 24 Nov 2022 19:15:08 +1300 Subject: [PATCH 705/796] Ruby: Add change note --- ruby/ql/lib/change-notes/2022-11-24-json-taint-flow.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ruby/ql/lib/change-notes/2022-11-24-json-taint-flow.md diff --git a/ruby/ql/lib/change-notes/2022-11-24-json-taint-flow.md b/ruby/ql/lib/change-notes/2022-11-24-json-taint-flow.md new file mode 100644 index 00000000000..c816037ccb9 --- /dev/null +++ b/ruby/ql/lib/change-notes/2022-11-24-json-taint-flow.md @@ -0,0 +1,4 @@ +--- + category: minorAnalysis +--- + * Taint flow is now tracked through many common JSON parsing and generation methods. \ No newline at end of file From 67257671ea83291756754b8b746b7496041dfe9d Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Fri, 25 Nov 2022 08:54:10 +1300 Subject: [PATCH 706/796] Ruby: Remove redundant dataflow test --- .../test/library-tests/frameworks/json/JsonDataFlow.expected | 1 - ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.ql | 5 ----- 2 files changed, 6 deletions(-) diff --git a/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.expected b/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.expected index 689a8d22702..79325635fb0 100644 --- a/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.expected +++ b/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.expected @@ -29,4 +29,3 @@ nodes | json.rb:10:6:10:34 | call to fast_unparse | semmle.label | call to fast_unparse | | json.rb:10:24:10:33 | call to source : | semmle.label | call to source : | subpaths -#select diff --git a/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.ql b/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.ql index 8a14d5f686e..11a25d33e71 100644 --- a/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.ql +++ b/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.ql @@ -2,11 +2,6 @@ * @kind path-problem */ -import codeql.ruby.AST import TestUtilities.InlineFlowTest import codeql.ruby.Frameworks import PathGraph - -from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf -where conf.hasFlowPath(source, sink) -select sink, source, sink, "$@", source, source.toString() From 14a19d23a6323ef5db7a290898187a013e6b7efd Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Fri, 25 Nov 2022 08:54:46 +1300 Subject: [PATCH 707/796] Ruby: Fix typo in documentation This import isn't needed. --- ruby/ql/test/TestUtilities/InlineFlowTest.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/ruby/ql/test/TestUtilities/InlineFlowTest.qll b/ruby/ql/test/TestUtilities/InlineFlowTest.qll index 462ae240865..dbac70ede0a 100644 --- a/ruby/ql/test/TestUtilities/InlineFlowTest.qll +++ b/ruby/ql/test/TestUtilities/InlineFlowTest.qll @@ -3,7 +3,6 @@ * * Example for a test.ql: * ```ql - * *import codeql.ruby.AST * import TestUtilities.InlineFlowTest * import PathGraph * From dab797008733cfc59c32e6260a66e687519dd52d Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Fri, 25 Nov 2022 09:02:44 +1300 Subject: [PATCH 708/796] Ruby: Model JSON.pretty_generate --- ruby/ql/lib/codeql/ruby/frameworks/Json.qll | 2 +- .../frameworks/json/JsonDataFlow.expected | 21 +++++++++++-------- .../library-tests/frameworks/json/json.rb | 1 + 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Json.qll b/ruby/ql/lib/codeql/ruby/frameworks/Json.qll index 3024fea57a1..dacb9bf48b7 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Json.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Json.qll @@ -15,7 +15,7 @@ module Json { row = [ "json;;Member[JSON].Method[parse,parse!,load,restore];Argument[0];ReturnValue;taint", - "json;;Member[JSON].Method[generate,fast_generate,dump,unparse,fast_unparse];Argument[0];ReturnValue;taint", + "json;;Member[JSON].Method[generate,fast_generate,pretty_generate,dump,unparse,fast_unparse];Argument[0];ReturnValue;taint", ] } } diff --git a/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.expected b/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.expected index 79325635fb0..d7173f8b110 100644 --- a/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.expected +++ b/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.expected @@ -6,9 +6,10 @@ edges | json.rb:4:19:4:28 | call to source : | json.rb:4:6:4:29 | call to restore | | json.rb:6:20:6:29 | call to source : | json.rb:6:6:6:30 | call to generate | | json.rb:7:25:7:34 | call to source : | json.rb:7:6:7:35 | call to fast_generate | -| json.rb:8:16:8:25 | call to source : | json.rb:8:6:8:26 | call to dump | -| json.rb:9:19:9:28 | call to source : | json.rb:9:6:9:29 | call to unparse | -| json.rb:10:24:10:33 | call to source : | json.rb:10:6:10:34 | call to fast_unparse | +| json.rb:8:27:8:36 | call to source : | json.rb:8:6:8:37 | call to pretty_generate | +| json.rb:9:16:9:25 | call to source : | json.rb:9:6:9:26 | call to dump | +| json.rb:10:19:10:28 | call to source : | json.rb:10:6:10:29 | call to unparse | +| json.rb:11:24:11:33 | call to source : | json.rb:11:6:11:34 | call to fast_unparse | nodes | json.rb:1:6:1:27 | call to parse | semmle.label | call to parse | | json.rb:1:17:1:26 | call to source : | semmle.label | call to source : | @@ -22,10 +23,12 @@ nodes | json.rb:6:20:6:29 | call to source : | semmle.label | call to source : | | json.rb:7:6:7:35 | call to fast_generate | semmle.label | call to fast_generate | | json.rb:7:25:7:34 | call to source : | semmle.label | call to source : | -| json.rb:8:6:8:26 | call to dump | semmle.label | call to dump | -| json.rb:8:16:8:25 | call to source : | semmle.label | call to source : | -| json.rb:9:6:9:29 | call to unparse | semmle.label | call to unparse | -| json.rb:9:19:9:28 | call to source : | semmle.label | call to source : | -| json.rb:10:6:10:34 | call to fast_unparse | semmle.label | call to fast_unparse | -| json.rb:10:24:10:33 | call to source : | semmle.label | call to source : | +| json.rb:8:6:8:37 | call to pretty_generate | semmle.label | call to pretty_generate | +| json.rb:8:27:8:36 | call to source : | semmle.label | call to source : | +| json.rb:9:6:9:26 | call to dump | semmle.label | call to dump | +| json.rb:9:16:9:25 | call to source : | semmle.label | call to source : | +| json.rb:10:6:10:29 | call to unparse | semmle.label | call to unparse | +| json.rb:10:19:10:28 | call to source : | semmle.label | call to source : | +| json.rb:11:6:11:34 | call to fast_unparse | semmle.label | call to fast_unparse | +| json.rb:11:24:11:33 | call to source : | semmle.label | call to source : | subpaths diff --git a/ruby/ql/test/library-tests/frameworks/json/json.rb b/ruby/ql/test/library-tests/frameworks/json/json.rb index ee549a76447..a48fe9bf5e0 100644 --- a/ruby/ql/test/library-tests/frameworks/json/json.rb +++ b/ruby/ql/test/library-tests/frameworks/json/json.rb @@ -5,6 +5,7 @@ sink JSON.restore(source "a") # $hasTaintFlow=a sink JSON.generate(source "a") # $hasTaintFlow=a sink JSON.fast_generate(source "a") # $hasTaintFlow=a +sink JSON.pretty_generate(source "a") # $hasTaintFlow=a sink JSON.dump(source "a") # $hasTaintFlow=a sink JSON.unparse(source "a") # $hasTaintFlow=a sink JSON.fast_unparse(source "a") # $hasTaintFlow=a From b885249d9d36b867bffabc280d104209fa471899 Mon Sep 17 00:00:00 2001 From: tiferet Date: Tue, 29 Nov 2022 16:26:29 -0800 Subject: [PATCH 709/796] Add a boosted version of XssThroughDOM --- .../XssThroughDomATM.qll | 88 +++++++++++++++++++ .../extraction/ExtractEndpointMapping.ql | 3 + .../src/XssThroughDomATM.ql | 25 ++++++ 3 files changed, 116 insertions(+) create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssThroughDomATM.qll create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/src/XssThroughDomATM.ql diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssThroughDomATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssThroughDomATM.qll new file mode 100644 index 00000000000..87d69a37165 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssThroughDomATM.qll @@ -0,0 +1,88 @@ +/** + * For internal use only. + * + * A taint-tracking configuration for reasoning about XSS through the DOM. + * Defines shared code used by the XSS Through DOM boosted query. + */ + +private import semmle.javascript.heuristics.SyntacticHeuristics +private import semmle.javascript.security.dataflow.DomBasedXssCustomizations +private import semmle.javascript.dataflow.InferredTypes +private import semmle.javascript.security.dataflow.XssThroughDomCustomizations::XssThroughDom as XssThroughDom +private import semmle.javascript.security.dataflow.UnsafeJQueryPluginCustomizations::UnsafeJQueryPlugin as UnsafeJQuery +import AdaptiveThreatModeling + +class XssThroughDomAtmConfig extends AtmConfig { + XssThroughDomAtmConfig() { this = "XssThroughDomAtmConfig" } + + override predicate isKnownSource(DataFlow::Node source) { + source instanceof XssThroughDom::Source + } + + override EndpointType getASinkEndpointType() { result instanceof XssSinkType } + + override predicate isSanitizer(DataFlow::Node node) { + super.isSanitizer(node) or + node instanceof DomBasedXss::Sanitizer + } + + override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) { + guard instanceof TypeTestGuard or + guard instanceof UnsafeJQuery::PropertyPresenceSanitizer or + guard instanceof UnsafeJQuery::NumberGuard or + guard instanceof PrefixStringSanitizer or + guard instanceof QuoteGuard or + guard instanceof ContainsHtmlGuard + } + + override predicate isSanitizerEdge(DataFlow::Node pred, DataFlow::Node succ) { + DomBasedXss::isOptionallySanitizedEdge(pred, succ) + } +} + +/** + * A test of form `typeof x === "something"`, preventing `x` from being a string in some cases. + * + * This sanitizer helps prune infeasible paths in type-overloaded functions. + */ +class TypeTestGuard extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode { + override EqualityTest astNode; + Expr operand; + boolean polarity; + + TypeTestGuard() { + exists(TypeofTag tag | TaintTracking::isTypeofGuard(astNode, operand, tag) | + // typeof x === "string" sanitizes `x` when it evaluates to false + tag = "string" and + polarity = astNode.getPolarity().booleanNot() + or + // typeof x === "object" sanitizes `x` when it evaluates to true + tag != "string" and + polarity = astNode.getPolarity() + ) + } + + override predicate sanitizes(boolean outcome, Expr e) { + polarity = outcome and + e = operand + } +} + +private import semmle.javascript.security.dataflow.Xss::Shared as Shared + +private class PrefixStringSanitizer extends TaintTracking::SanitizerGuardNode, + DomBasedXss::PrefixStringSanitizer { + PrefixStringSanitizer() { this = this } +} + +private class PrefixString extends DataFlow::FlowLabel, DomBasedXss::PrefixString { + PrefixString() { this = this } +} + +private class QuoteGuard extends TaintTracking::SanitizerGuardNode, Shared::QuoteGuard { + QuoteGuard() { this = this } +} + +private class ContainsHtmlGuard extends TaintTracking::SanitizerGuardNode, Shared::ContainsHtmlGuard { + ContainsHtmlGuard() { this = this } +} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql index 697928d74b0..57c536eac12 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql @@ -8,6 +8,7 @@ import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm import experimental.adaptivethreatmodeling.XssATM as XssAtm +import experimental.adaptivethreatmodeling.XssThroughDomATM as XssThroughDomAtm import experimental.adaptivethreatmodeling.AdaptiveThreatModeling from string queryName, AtmConfig c, EndpointType e @@ -23,6 +24,8 @@ where c instanceof TaintedPathAtm::TaintedPathAtmConfig or queryName = "Xss" and c instanceof XssAtm::DomBasedXssAtmConfig + or + queryName = "XssThroughDom" and c instanceof XssThroughDomAtm::XssThroughDomAtmConfig ) and e = c.getASinkEndpointType() select queryName, e.getEncoding() as label diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/XssThroughDomATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/XssThroughDomATM.ql new file mode 100644 index 00000000000..60df6941400 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/XssThroughDomATM.ql @@ -0,0 +1,25 @@ +/** + * For internal use only. + * + * @name DOM text reinterpreted as HTML (experimental) + * @description Reinterpreting text from the DOM as HTML can lead + * to a cross-site scripting vulnerability. + * @kind path-problem + * @scored + * @problem.severity error + * @security-severity 6.1 + * @id js/ml-powered/xss-through-dom + * @tags experimental security + * external/cwe/cwe-079 external/cwe/cwe-116 + */ + +import javascript +import ATM::ResultsInfo +import DataFlow::PathGraph +import experimental.adaptivethreatmodeling.XssThroughDomATM + +from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score +where cfg.getAlerts(source, sink, score) +select sink.getNode(), source, sink, + "(Experimental) $@ may be reinterpreted as HTML without escaping meta-characters. Identified using machine learning.", + source.getNode(), "DOM text", score From 045e6ef148f23466aeaba6c013d7c07b9b9612e1 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 30 Nov 2022 09:59:20 +0100 Subject: [PATCH 710/796] remove unused environment variable --- .github/workflows/compile-queries.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/compile-queries.yml b/.github/workflows/compile-queries.yml index ee6d48c45ea..96d8e4cc30b 100644 --- a/.github/workflows/compile-queries.yml +++ b/.github/workflows/compile-queries.yml @@ -35,5 +35,3 @@ jobs: if : ${{ github.event_name != 'pull_request' }} shell: bash run: codeql query compile -j0 */ql/{src,examples} --keep-going --warnings=error --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" - env: - COMBINED_CACHE_DIR: ${{ github.workspace }}/compilation-dir \ No newline at end of file From 71f5c8aa8805a7a8fe86a670b34189342c20dc33 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 30 Nov 2022 10:43:33 +0100 Subject: [PATCH 711/796] Shared: Add Util qlpack. --- .../2022-11-30-initial-version.md | 4 ++ shared/util/codeql/util/Boolean.qll | 10 +++++ shared/util/codeql/util/Option.qll | 41 +++++++++++++++++++ shared/util/codeql/util/Unit.qll | 10 +++++ shared/util/qlpack.yml | 5 +++ 5 files changed, 70 insertions(+) create mode 100644 shared/util/change-notes/2022-11-30-initial-version.md create mode 100644 shared/util/codeql/util/Boolean.qll create mode 100644 shared/util/codeql/util/Option.qll create mode 100644 shared/util/codeql/util/Unit.qll create mode 100644 shared/util/qlpack.yml diff --git a/shared/util/change-notes/2022-11-30-initial-version.md b/shared/util/change-notes/2022-11-30-initial-version.md new file mode 100644 index 00000000000..81893f23dfc --- /dev/null +++ b/shared/util/change-notes/2022-11-30-initial-version.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Initial release. Includes common utility classes and modules: Unit, Boolean, and Option. diff --git a/shared/util/codeql/util/Boolean.qll b/shared/util/codeql/util/Boolean.qll new file mode 100644 index 00000000000..84a91f763e4 --- /dev/null +++ b/shared/util/codeql/util/Boolean.qll @@ -0,0 +1,10 @@ +/** Provides the `Boolean` class. */ + +/** + * A utility class that is equivalent to `boolean`. + * + * As opposed to `boolean`, this type does not require explicit binding. + */ +class Boolean extends boolean { + Boolean() { this = [true, false] } +} diff --git a/shared/util/codeql/util/Option.qll b/shared/util/codeql/util/Option.qll new file mode 100644 index 00000000000..0114fe0a59b --- /dev/null +++ b/shared/util/codeql/util/Option.qll @@ -0,0 +1,41 @@ +/** Provides a module for constructing optional versions of types. */ + +/** A type with `toString`. */ +signature class TypeWithToString { + string toString(); +} + +/** + * Constructs an `Option` type that is a disjoint union of the given type and an + * additional singleton element. + */ +module Option { + private newtype TOption = + TNone() or + TSome(T c) + + /** + * An option type. This is either a singleton `None` or a `Some` wrapping the + * given type. + */ + class Option extends TOption { + /** Gets a textual representation of this element. */ + string toString() { + this = TNone() and result = "(none)" + or + exists(T c | this = TSome(c) and result = c.toString()) + } + + /** Gets the wrapped element, if any. */ + T asSome() { this = TSome(result) } + } + + /** The singleton `None` element. */ + class None extends Option, TNone { } + + /** A wrapper for the given type. */ + class Some extends Option, TSome { } + + /** Gets the given element wrapped as an `Option`. */ + Some some(T c) { result = TSome(c) } +} diff --git a/shared/util/codeql/util/Unit.qll b/shared/util/codeql/util/Unit.qll new file mode 100644 index 00000000000..e9611ed3df4 --- /dev/null +++ b/shared/util/codeql/util/Unit.qll @@ -0,0 +1,10 @@ +/** Provides the `Unit` class. */ + +/** The unit type. */ +private newtype TUnit = TMkUnit() + +/** The trivial type with a single element. */ +class Unit extends TUnit { + /** Gets a textual representation of this element. */ + string toString() { result = "unit" } +} diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml new file mode 100644 index 00000000000..faee72042d6 --- /dev/null +++ b/shared/util/qlpack.yml @@ -0,0 +1,5 @@ +name: codeql/util +version: 0.0.1-dev +groups: shared +library: true +dependencies: From d165c4963d4a074611fe498a7fe6fdb688e36e95 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 30 Nov 2022 09:48:28 +0100 Subject: [PATCH 712/796] CI: add workaround for nested composite actions issue Because of https://github.com/actions/runner/issues/2009 the deeply nested action cache was failing to save the cache in the post run phase. For the moment we just avoid the nesting with a copy-pasted action snippet. --- .../cache-query-compilation/action.yml | 30 ++++++++++-- .github/actions/incremental-cache/action.yml | 44 ----------------- swift/actions/build-and-test/action.yml | 49 ++++++++++++++----- 3 files changed, 63 insertions(+), 60 deletions(-) delete mode 100644 .github/actions/incremental-cache/action.yml diff --git a/.github/actions/cache-query-compilation/action.yml b/.github/actions/cache-query-compilation/action.yml index b93e4f6c790..9ca35e01218 100644 --- a/.github/actions/cache-query-compilation/action.yml +++ b/.github/actions/cache-query-compilation/action.yml @@ -14,11 +14,35 @@ outputs: runs: using: composite steps: - - name: Cache the query compilation caches - uses: ./.github/actions/incremental-cache + # calculate the merge-base with main, in a way that works both on PRs and pushes to main. + - name: Calculate merge-base + shell: bash + if: ${{ github.event_name == 'pull_request' }} + env: + BASE_BRANCH: ${{ github.base_ref }} + run: | + MERGE_BASE=$(git cat-file commit $GITHUB_SHA | grep '^parent ' | head -1 | cut -f 2 -d " ") + echo "merge_base=$MERGE_BASE" >> $GITHUB_ENV + - name: Restore read-only cache (PR) + if: ${{ github.event_name == 'pull_request' }} + uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6 with: path: '**/.cache' - key: codeql-compile-${{ inputs.key }} + read-only: true + key: ${{ inputs.key }}-pr-${{ github.sha }} + restore-keys: | + ${{ inputs.key }}-${{ github.base_ref }}-${{ env.merge_base }} + ${{ inputs.key }}-${{ github.base_ref }}- + ${{ inputs.key }}-main- + - name: Fill cache (push) + if: ${{ github.event_name != 'pull_request' }} + uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6 + with: + path: '**/.cache' + key: ${{ inputs.key }}-${{ github.ref_name }}-${{ github.sha }} # just fill on main + restore-keys: | # restore the latest cache if the exact cache is unavailable, to speed up compilation. + ${{ inputs.key }}-${{ github.ref_name }}- + ${{ inputs.key }}-main- - name: Fill compilation cache directory id: fill-compilation-dir shell: bash diff --git a/.github/actions/incremental-cache/action.yml b/.github/actions/incremental-cache/action.yml deleted file mode 100644 index 2ea62719886..00000000000 --- a/.github/actions/incremental-cache/action.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Setup an incremental cache -description: Special cache wrapper to be run on pull requests and pushes, that will try to restore - a cache as close as possible to the merge base - -inputs: - path: - description: 'The path to cache' - required: true - key: - description: 'The cache key to use - should be unique to the workflow' - required: true - -runs: - using: composite - steps: - # calculate the merge-base with main, in a way that works both on PRs and pushes to main. - - name: Calculate merge-base - shell: bash - if: ${{ github.event_name == 'pull_request' }} - env: - BASE_BRANCH: ${{ github.base_ref }} - run: | - MERGE_BASE=$(git cat-file commit $GITHUB_SHA | grep '^parent ' | head -1 | cut -f 2 -d " ") - echo "merge_base=$MERGE_BASE" >> $GITHUB_ENV - - name: Restore read-only cache (PR) - if: ${{ github.event_name == 'pull_request' }} - uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6 - with: - path: ${{ inputs.path }} - read-only: true - key: ${{ inputs.key }}-pr-${{ github.sha }} - restore-keys: | - ${{ inputs.key }}-${{ github.base_ref }}-${{ env.merge_base }} - ${{ inputs.key }}-${{ github.base_ref }}- - ${{ inputs.key }}-main- - - name: Fill cache (push) - if: ${{ github.event_name != 'pull_request' }} - uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6 - with: - path: ${{ inputs.path }} - key: ${{ inputs.key }}-${{ github.ref_name }}-${{ github.sha }} # just fill on main - restore-keys: | # restore the latest cache if the exact cache is unavailable, to speed up compilation. - ${{ inputs.key }}-${{ github.ref_name }}- - ${{ inputs.key }}-main- diff --git a/swift/actions/build-and-test/action.yml b/swift/actions/build-and-test/action.yml index 14f8107dc0f..386bd4d5a19 100644 --- a/swift/actions/build-and-test/action.yml +++ b/swift/actions/build-and-test/action.yml @@ -7,21 +7,43 @@ runs: - uses: actions/setup-python@v4 with: python-version-file: 'swift/.python-version' - - name: Mount bazel cache - uses: ./.github/actions/incremental-cache + # FIXME: this is copy-pasted from .github/actions/cache-query-compilation, but we cannot factor it out to a common + # composite action because of https://github.com/actions/runner/issues/2009 (cache fails to save in the post action + # phase because its inputs were lost in the meantime) + # calculate the merge-base with main, in a way that works both on PRs and pushes to main. + - name: Calculate merge-base + shell: bash + if: ${{ github.event_name == 'pull_request' }} + env: + BASE_BRANCH: ${{ github.base_ref }} + run: | + MERGE_BASE=$(git cat-file commit $GITHUB_SHA | grep '^parent ' | head -1 | cut -f 2 -d " ") + echo "merge_base=$MERGE_BASE" >> $GITHUB_ENV + - name: Restore read-only cache (PR) + if: ${{ github.event_name == 'pull_request' }} + uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6 with: - path: bazel-repository-cache - key: bazel-cache-${{ runner.os }}-${{ runner.arch }} - - name: Mount bazel disk cache - uses: ./.github/actions/incremental-cache + path: 'bazel-cache' + read-only: true + key: bazel-pr-${{ github.sha }} + restore-keys: | + bazel-${{ github.base_ref }}-${{ env.merge_base }} + bazel-${{ github.base_ref }}- + bazel-main- + - name: Fill cache (push) + if: ${{ github.event_name != 'pull_request' }} + uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6 with: - path: bazel-disk-cache - key: bazel-disk-cache-${{ runner.os }}-${{ runner.arch }} - - name: Configure bazel cache + path: 'bazel-cache' + key: bazel-${{ github.ref_name }}-${{ github.sha }} # just fill on main + restore-keys: | # restore the latest cache if the exact cache is unavailable, to speed up compilation. + bazel-${{ github.ref_name }}- + bazel-main- + - name: Configure bazel shell: bash run: | - mkdir bazel-repository-cache bazel-disk-cache - echo build --repository_cache=bazel-repository-cache --disk_cache=bazel-disk-cache > local.bazelrc + mkdir -p bazel-cache/{repository,disk} + echo build --repository_cache=bazel-cache/repository --disk_cache=bazel-cache/disk > local.bazelrc echo test --test_output=errors >> local.bazelrc - name: Print unextracted entities shell: bash @@ -51,5 +73,6 @@ runs: if: ${{ github.event_name != 'pull_request' }} shell: bash run: | - find bazel-repository-cache bazel-disk-cache -atime +0 -type f -delete - du -sh bazel-repository-cache bazel-disk-cache + du -sh bazel-cache/* + find bazel-cache -atime +0 -type f -delete + du -sh bazel-cache/* From e12e86b52006354d1725a75cc5493a87b29d7545 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 30 Nov 2022 10:45:22 +0100 Subject: [PATCH 713/796] Restore previous cache key Co-authored-by: Erik Krogh Kristensen --- .github/actions/cache-query-compilation/action.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/actions/cache-query-compilation/action.yml b/.github/actions/cache-query-compilation/action.yml index 9ca35e01218..95f25cbfc68 100644 --- a/.github/actions/cache-query-compilation/action.yml +++ b/.github/actions/cache-query-compilation/action.yml @@ -29,20 +29,20 @@ runs: with: path: '**/.cache' read-only: true - key: ${{ inputs.key }}-pr-${{ github.sha }} + key: codeql-compile-${{ inputs.key }}-pr-${{ github.sha }} restore-keys: | - ${{ inputs.key }}-${{ github.base_ref }}-${{ env.merge_base }} - ${{ inputs.key }}-${{ github.base_ref }}- - ${{ inputs.key }}-main- + codeql-compile-${{ inputs.key }}-${{ github.base_ref }}-${{ env.merge_base }} + codeql-compile-${{ inputs.key }}-${{ github.base_ref }}- + codeql-compile-${{ inputs.key }}-main- - name: Fill cache (push) if: ${{ github.event_name != 'pull_request' }} uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6 with: path: '**/.cache' - key: ${{ inputs.key }}-${{ github.ref_name }}-${{ github.sha }} # just fill on main + key: codeql-compile-${{ inputs.key }}-${{ github.ref_name }}-${{ github.sha }} # just fill on main restore-keys: | # restore the latest cache if the exact cache is unavailable, to speed up compilation. - ${{ inputs.key }}-${{ github.ref_name }}- - ${{ inputs.key }}-main- + codeql-compile-${{ inputs.key }}-${{ github.ref_name }}- + codeql-compile-${{ inputs.key }}-main- - name: Fill compilation cache directory id: fill-compilation-dir shell: bash From ba5656512564fd37586be350fd008ae1fd8c483d Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 30 Nov 2022 10:55:07 +0100 Subject: [PATCH 714/796] Update shared/util/codeql/util/Option.qll Co-authored-by: Erik Krogh Kristensen --- shared/util/codeql/util/Option.qll | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shared/util/codeql/util/Option.qll b/shared/util/codeql/util/Option.qll index 0114fe0a59b..f47d975d268 100644 --- a/shared/util/codeql/util/Option.qll +++ b/shared/util/codeql/util/Option.qll @@ -28,6 +28,9 @@ module Option { /** Gets the wrapped element, if any. */ T asSome() { this = TSome(result) } + + /** Holds if this option is the singleton `None`. */ + predicate isNone() { this = TNone() } } /** The singleton `None` element. */ From 758cb8b412c00b173e13890af178ab5974a0fc38 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 30 Nov 2022 11:14:43 +0100 Subject: [PATCH 715/796] Shared: Fix trailing and non-ascii whitespace. --- shared/util/codeql/util/Option.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/util/codeql/util/Option.qll b/shared/util/codeql/util/Option.qll index f47d975d268..9382dc9555c 100644 --- a/shared/util/codeql/util/Option.qll +++ b/shared/util/codeql/util/Option.qll @@ -28,9 +28,9 @@ module Option { /** Gets the wrapped element, if any. */ T asSome() { this = TSome(result) } - + /** Holds if this option is the singleton `None`. */ - predicate isNone() { this = TNone() } + predicate isNone() { this = TNone() } } /** The singleton `None` element. */ From ce8a20cfd17eed1ce77c7d30d52dd20beef05a39 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 30 Nov 2022 10:51:59 +0000 Subject: [PATCH 716/796] Fix variable name (`source` should be `sink`) --- java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index e4cfd5986be..ccde916a3c2 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes From 207ba86d51ca21cc685b6f40cbeafd803be15d4d Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Thu, 17 Nov 2022 15:41:56 +0100 Subject: [PATCH 717/796] Ruby: add flow summary for Enumerable#pick --- .../codeql/ruby/frameworks/ActiveSupport.qll | 60 ++++++++++++++- .../ActiveSupportDataFlow.expected | 74 +++++++++++++++++++ .../active_support/hash_extensions.rb | 12 +++ 3 files changed, 145 insertions(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll index 48bd1193aaa..0d5cc410835 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll @@ -308,7 +308,65 @@ module ActiveSupport { preservesValue = true } } - // TODO: pick, pluck (they require Hash dataflow) + + private string getKeyArgument(MethodCall mc, int i) { + mc.getMethodName() = ["pick", "pluck"] and + result = DataFlow::Content::getKnownElementIndex(mc.getArgument(i)).serialize() + } + + private class PickSingleSummary extends SummarizedCallable { + private MethodCall mc; + private string key; + + PickSingleSummary() { + key = getKeyArgument(mc, 0) and + this = "Enumerable.pick(" + key + ")" and + mc.getMethodName() = "pick" and + mc.getNumberOfArguments() = 1 + } + + override MethodCall getACall() { result = mc } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[self].Element[0].Element[" + key + "!]" and + output = "ReturnValue" and + preservesValue = true + } + } + + private class PickMultipleSummary extends SummarizedCallable { + private MethodCall mc; + + PickMultipleSummary() { + mc.getMethodName() = "pick" and + mc.getNumberOfArguments() > 1 and + exists(int maxKey | + maxKey = max(int j | exists(getKeyArgument(mc, j))) and + this = + "Enumerable.pick(" + + concat(int i, string key | + key = getKeyArgument(mc, i) + or + key = "_" and + not exists(getKeyArgument(mc, i)) and + i in [0 .. maxKey] + | + key, "," order by i + ) + ")" + ) + } + + override MethodCall getACall() { result = mc } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + exists(string s, int i | + s = getKeyArgument(mc, i) and + input = "Argument[self].Element[0].Element[" + s + "!]" and + output = "ReturnValue.Element[" + i + "!]" + ) and + preservesValue = true + } + } } } diff --git a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected index c2d169d1bb9..5237512e7b8 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected +++ b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected @@ -320,6 +320,38 @@ edges | hash_extensions.rb:91:10:91:10 | j [element] : | hash_extensions.rb:91:10:91:16 | ...[...] | | hash_extensions.rb:92:10:92:10 | j [element] : | hash_extensions.rb:92:10:92:16 | ...[...] | | hash_extensions.rb:92:10:92:10 | j [element] : | hash_extensions.rb:92:10:92:16 | ...[...] | +| hash_extensions.rb:98:21:98:31 | call to source : | hash_extensions.rb:99:10:99:15 | values [element 0, element :id] : | +| hash_extensions.rb:98:21:98:31 | call to source : | hash_extensions.rb:99:10:99:15 | values [element 0, element :id] : | +| hash_extensions.rb:98:21:98:31 | call to source : | hash_extensions.rb:101:10:101:15 | values [element 0, element :id] : | +| hash_extensions.rb:98:21:98:31 | call to source : | hash_extensions.rb:101:10:101:15 | values [element 0, element :id] : | +| hash_extensions.rb:98:21:98:31 | call to source : | hash_extensions.rb:104:10:104:15 | values [element 0, element :id] : | +| hash_extensions.rb:98:21:98:31 | call to source : | hash_extensions.rb:104:10:104:15 | values [element 0, element :id] : | +| hash_extensions.rb:98:40:98:54 | call to source : | hash_extensions.rb:100:10:100:15 | values [element 0, element :name] : | +| hash_extensions.rb:98:40:98:54 | call to source : | hash_extensions.rb:100:10:100:15 | values [element 0, element :name] : | +| hash_extensions.rb:98:40:98:54 | call to source : | hash_extensions.rb:102:10:102:15 | values [element 0, element :name] : | +| hash_extensions.rb:98:40:98:54 | call to source : | hash_extensions.rb:102:10:102:15 | values [element 0, element :name] : | +| hash_extensions.rb:98:40:98:54 | call to source : | hash_extensions.rb:103:10:103:15 | values [element 0, element :name] : | +| hash_extensions.rb:98:40:98:54 | call to source : | hash_extensions.rb:103:10:103:15 | values [element 0, element :name] : | +| hash_extensions.rb:99:10:99:15 | values [element 0, element :id] : | hash_extensions.rb:99:10:99:25 | call to pick | +| hash_extensions.rb:99:10:99:15 | values [element 0, element :id] : | hash_extensions.rb:99:10:99:25 | call to pick | +| hash_extensions.rb:100:10:100:15 | values [element 0, element :name] : | hash_extensions.rb:100:10:100:27 | call to pick | +| hash_extensions.rb:100:10:100:15 | values [element 0, element :name] : | hash_extensions.rb:100:10:100:27 | call to pick | +| hash_extensions.rb:101:10:101:15 | values [element 0, element :id] : | hash_extensions.rb:101:10:101:32 | call to pick [element 0] : | +| hash_extensions.rb:101:10:101:15 | values [element 0, element :id] : | hash_extensions.rb:101:10:101:32 | call to pick [element 0] : | +| hash_extensions.rb:101:10:101:32 | call to pick [element 0] : | hash_extensions.rb:101:10:101:35 | ...[...] | +| hash_extensions.rb:101:10:101:32 | call to pick [element 0] : | hash_extensions.rb:101:10:101:35 | ...[...] | +| hash_extensions.rb:102:10:102:15 | values [element 0, element :name] : | hash_extensions.rb:102:10:102:32 | call to pick [element 1] : | +| hash_extensions.rb:102:10:102:15 | values [element 0, element :name] : | hash_extensions.rb:102:10:102:32 | call to pick [element 1] : | +| hash_extensions.rb:102:10:102:32 | call to pick [element 1] : | hash_extensions.rb:102:10:102:35 | ...[...] | +| hash_extensions.rb:102:10:102:32 | call to pick [element 1] : | hash_extensions.rb:102:10:102:35 | ...[...] | +| hash_extensions.rb:103:10:103:15 | values [element 0, element :name] : | hash_extensions.rb:103:10:103:32 | call to pick [element 0] : | +| hash_extensions.rb:103:10:103:15 | values [element 0, element :name] : | hash_extensions.rb:103:10:103:32 | call to pick [element 0] : | +| hash_extensions.rb:103:10:103:32 | call to pick [element 0] : | hash_extensions.rb:103:10:103:35 | ...[...] | +| hash_extensions.rb:103:10:103:32 | call to pick [element 0] : | hash_extensions.rb:103:10:103:35 | ...[...] | +| hash_extensions.rb:104:10:104:15 | values [element 0, element :id] : | hash_extensions.rb:104:10:104:32 | call to pick [element 1] : | +| hash_extensions.rb:104:10:104:15 | values [element 0, element :id] : | hash_extensions.rb:104:10:104:32 | call to pick [element 1] : | +| hash_extensions.rb:104:10:104:32 | call to pick [element 1] : | hash_extensions.rb:104:10:104:35 | ...[...] | +| hash_extensions.rb:104:10:104:32 | call to pick [element 1] : | hash_extensions.rb:104:10:104:35 | ...[...] | nodes | active_support.rb:10:9:10:18 | call to source : | semmle.label | call to source : | | active_support.rb:11:10:11:10 | x : | semmle.label | x : | @@ -722,6 +754,42 @@ nodes | hash_extensions.rb:92:10:92:10 | j [element] : | semmle.label | j [element] : | | hash_extensions.rb:92:10:92:16 | ...[...] | semmle.label | ...[...] | | hash_extensions.rb:92:10:92:16 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:98:21:98:31 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:98:21:98:31 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:98:40:98:54 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:98:40:98:54 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:99:10:99:15 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : | +| hash_extensions.rb:99:10:99:15 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : | +| hash_extensions.rb:99:10:99:25 | call to pick | semmle.label | call to pick | +| hash_extensions.rb:99:10:99:25 | call to pick | semmle.label | call to pick | +| hash_extensions.rb:100:10:100:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : | +| hash_extensions.rb:100:10:100:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : | +| hash_extensions.rb:100:10:100:27 | call to pick | semmle.label | call to pick | +| hash_extensions.rb:100:10:100:27 | call to pick | semmle.label | call to pick | +| hash_extensions.rb:101:10:101:15 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : | +| hash_extensions.rb:101:10:101:15 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : | +| hash_extensions.rb:101:10:101:32 | call to pick [element 0] : | semmle.label | call to pick [element 0] : | +| hash_extensions.rb:101:10:101:32 | call to pick [element 0] : | semmle.label | call to pick [element 0] : | +| hash_extensions.rb:101:10:101:35 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:101:10:101:35 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:102:10:102:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : | +| hash_extensions.rb:102:10:102:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : | +| hash_extensions.rb:102:10:102:32 | call to pick [element 1] : | semmle.label | call to pick [element 1] : | +| hash_extensions.rb:102:10:102:32 | call to pick [element 1] : | semmle.label | call to pick [element 1] : | +| hash_extensions.rb:102:10:102:35 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:102:10:102:35 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:103:10:103:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : | +| hash_extensions.rb:103:10:103:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : | +| hash_extensions.rb:103:10:103:32 | call to pick [element 0] : | semmle.label | call to pick [element 0] : | +| hash_extensions.rb:103:10:103:32 | call to pick [element 0] : | semmle.label | call to pick [element 0] : | +| hash_extensions.rb:103:10:103:35 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:103:10:103:35 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:104:10:104:15 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : | +| hash_extensions.rb:104:10:104:15 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : | +| hash_extensions.rb:104:10:104:32 | call to pick [element 1] : | semmle.label | call to pick [element 1] : | +| hash_extensions.rb:104:10:104:32 | call to pick [element 1] : | semmle.label | call to pick [element 1] : | +| hash_extensions.rb:104:10:104:35 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:104:10:104:35 | ...[...] | semmle.label | ...[...] | subpaths #select | active_support.rb:182:10:182:13 | ...[...] | active_support.rb:180:10:180:17 | call to source : | active_support.rb:182:10:182:13 | ...[...] | $@ | active_support.rb:180:10:180:17 | call to source : | call to source : | @@ -766,3 +834,9 @@ subpaths | hash_extensions.rb:87:10:87:16 | ...[...] | hash_extensions.rb:83:9:83:19 | call to source : | hash_extensions.rb:87:10:87:16 | ...[...] | $@ | hash_extensions.rb:83:9:83:19 | call to source : | call to source : | | hash_extensions.rb:91:10:91:16 | ...[...] | hash_extensions.rb:89:27:89:37 | call to source : | hash_extensions.rb:91:10:91:16 | ...[...] | $@ | hash_extensions.rb:89:27:89:37 | call to source : | call to source : | | hash_extensions.rb:92:10:92:16 | ...[...] | hash_extensions.rb:89:27:89:37 | call to source : | hash_extensions.rb:92:10:92:16 | ...[...] | $@ | hash_extensions.rb:89:27:89:37 | call to source : | call to source : | +| hash_extensions.rb:99:10:99:25 | call to pick | hash_extensions.rb:98:21:98:31 | call to source : | hash_extensions.rb:99:10:99:25 | call to pick | $@ | hash_extensions.rb:98:21:98:31 | call to source : | call to source : | +| hash_extensions.rb:100:10:100:27 | call to pick | hash_extensions.rb:98:40:98:54 | call to source : | hash_extensions.rb:100:10:100:27 | call to pick | $@ | hash_extensions.rb:98:40:98:54 | call to source : | call to source : | +| hash_extensions.rb:101:10:101:35 | ...[...] | hash_extensions.rb:98:21:98:31 | call to source : | hash_extensions.rb:101:10:101:35 | ...[...] | $@ | hash_extensions.rb:98:21:98:31 | call to source : | call to source : | +| hash_extensions.rb:102:10:102:35 | ...[...] | hash_extensions.rb:98:40:98:54 | call to source : | hash_extensions.rb:102:10:102:35 | ...[...] | $@ | hash_extensions.rb:98:40:98:54 | call to source : | call to source : | +| hash_extensions.rb:103:10:103:35 | ...[...] | hash_extensions.rb:98:40:98:54 | call to source : | hash_extensions.rb:103:10:103:35 | ...[...] | $@ | hash_extensions.rb:98:40:98:54 | call to source : | call to source : | +| hash_extensions.rb:104:10:104:35 | ...[...] | hash_extensions.rb:98:21:98:31 | call to source : | hash_extensions.rb:104:10:104:35 | ...[...] | $@ | hash_extensions.rb:98:21:98:31 | call to source : | call to source : | diff --git a/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb b/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb index 4675e6ea72e..d31f5f0b271 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb +++ b/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb @@ -93,3 +93,15 @@ def m_index_with end m_index_with() + +def m_pick + values = [{ id: source("1"), name: source("David") }, { id: source("2"), name: source("Rafael") }] + sink(values.pick(:id)) # $ hasValueFlow=1 + sink(values.pick(:name)) # $ hasValueFlow=David + sink(values.pick(:id, :name)[0]) # $ hasValueFlow=1 + sink(values.pick(:id, :name)[1]) # $ hasValueFlow=David + sink(values.pick(:name, :id)[0]) # $ hasValueFlow=David + sink(values.pick(:name, :id)[1]) # $ hasValueFlow=1 +end + +m_pick() From 5517cfa6c0313ee121efef03aa43a674f10bd309 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Thu, 17 Nov 2022 15:49:43 +0100 Subject: [PATCH 718/796] Ruby: add flow summary for Enumerable#pluck --- .../codeql/ruby/frameworks/ActiveSupport.qll | 54 ++++++++ .../ActiveSupportDataFlow.expected | 124 ++++++++++++++++++ .../active_support/hash_extensions.rb | 11 ++ 3 files changed, 189 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll index 0d5cc410835..727a233b438 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll @@ -367,6 +367,60 @@ module ActiveSupport { preservesValue = true } } + + private class PluckSingleSummary extends SummarizedCallable { + private MethodCall mc; + private string key; + + PluckSingleSummary() { + key = getKeyArgument(mc, 0) and + this = "Enumerable.pluck(" + key + ")" and + mc.getMethodName() = "pluck" and + mc.getNumberOfArguments() = 1 + } + + override MethodCall getACall() { result = mc } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[self].Element[any].Element[" + key + "!]" and + output = "ReturnValue.Element[any]" and + preservesValue = true + } + } + + private class PluckMultipleSummary extends SummarizedCallable { + private MethodCall mc; + + PluckMultipleSummary() { + mc.getMethodName() = "pluck" and + mc.getNumberOfArguments() > 1 and + exists(int maxKey | + maxKey = max(int j | exists(getKeyArgument(mc, j))) and + this = + "Enumerable.pluck(" + + concat(int i, string key | + key = getKeyArgument(mc, i) + or + key = "_" and + not exists(getKeyArgument(mc, i)) and + i in [0 .. maxKey] + | + key, "," order by i + ) + ")" + ) + } + + override MethodCall getACall() { result = mc } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + exists(string s, int i | + s = getKeyArgument(mc, i) and + input = "Argument[self].Element[any].Element[" + s + "!]" and + output = "ReturnValue.Element[?].Element[" + i + "!]" + ) and + preservesValue = true + } + } } } diff --git a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected index 5237512e7b8..f5c4e418b08 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected +++ b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected @@ -352,6 +352,64 @@ edges | hash_extensions.rb:104:10:104:15 | values [element 0, element :id] : | hash_extensions.rb:104:10:104:32 | call to pick [element 1] : | | hash_extensions.rb:104:10:104:32 | call to pick [element 1] : | hash_extensions.rb:104:10:104:35 | ...[...] | | hash_extensions.rb:104:10:104:32 | call to pick [element 1] : | hash_extensions.rb:104:10:104:35 | ...[...] | +| hash_extensions.rb:110:21:110:31 | call to source : | hash_extensions.rb:112:10:112:15 | values [element 0, element :id] : | +| hash_extensions.rb:110:21:110:31 | call to source : | hash_extensions.rb:112:10:112:15 | values [element 0, element :id] : | +| hash_extensions.rb:110:21:110:31 | call to source : | hash_extensions.rb:115:10:115:15 | values [element 0, element :id] : | +| hash_extensions.rb:110:21:110:31 | call to source : | hash_extensions.rb:115:10:115:15 | values [element 0, element :id] : | +| hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:111:10:111:15 | values [element 0, element :name] : | +| hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:111:10:111:15 | values [element 0, element :name] : | +| hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:113:10:113:15 | values [element 0, element :name] : | +| hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:113:10:113:15 | values [element 0, element :name] : | +| hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:114:10:114:15 | values [element 0, element :name] : | +| hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:114:10:114:15 | values [element 0, element :name] : | +| hash_extensions.rb:110:65:110:75 | call to source : | hash_extensions.rb:112:10:112:15 | values [element 1, element :id] : | +| hash_extensions.rb:110:65:110:75 | call to source : | hash_extensions.rb:112:10:112:15 | values [element 1, element :id] : | +| hash_extensions.rb:110:65:110:75 | call to source : | hash_extensions.rb:115:10:115:15 | values [element 1, element :id] : | +| hash_extensions.rb:110:65:110:75 | call to source : | hash_extensions.rb:115:10:115:15 | values [element 1, element :id] : | +| hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:111:10:111:15 | values [element 1, element :name] : | +| hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:111:10:111:15 | values [element 1, element :name] : | +| hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:113:10:113:15 | values [element 1, element :name] : | +| hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:113:10:113:15 | values [element 1, element :name] : | +| hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:114:10:114:15 | values [element 1, element :name] : | +| hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:114:10:114:15 | values [element 1, element :name] : | +| hash_extensions.rb:111:10:111:15 | values [element 0, element :name] : | hash_extensions.rb:111:10:111:28 | call to pluck [element] : | +| hash_extensions.rb:111:10:111:15 | values [element 0, element :name] : | hash_extensions.rb:111:10:111:28 | call to pluck [element] : | +| hash_extensions.rb:111:10:111:15 | values [element 1, element :name] : | hash_extensions.rb:111:10:111:28 | call to pluck [element] : | +| hash_extensions.rb:111:10:111:15 | values [element 1, element :name] : | hash_extensions.rb:111:10:111:28 | call to pluck [element] : | +| hash_extensions.rb:111:10:111:28 | call to pluck [element] : | hash_extensions.rb:111:10:111:31 | ...[...] | +| hash_extensions.rb:111:10:111:28 | call to pluck [element] : | hash_extensions.rb:111:10:111:31 | ...[...] | +| hash_extensions.rb:112:10:112:15 | values [element 0, element :id] : | hash_extensions.rb:112:10:112:33 | call to pluck [element, element 0] : | +| hash_extensions.rb:112:10:112:15 | values [element 0, element :id] : | hash_extensions.rb:112:10:112:33 | call to pluck [element, element 0] : | +| hash_extensions.rb:112:10:112:15 | values [element 1, element :id] : | hash_extensions.rb:112:10:112:33 | call to pluck [element, element 0] : | +| hash_extensions.rb:112:10:112:15 | values [element 1, element :id] : | hash_extensions.rb:112:10:112:33 | call to pluck [element, element 0] : | +| hash_extensions.rb:112:10:112:33 | call to pluck [element, element 0] : | hash_extensions.rb:112:10:112:36 | ...[...] [element 0] : | +| hash_extensions.rb:112:10:112:33 | call to pluck [element, element 0] : | hash_extensions.rb:112:10:112:36 | ...[...] [element 0] : | +| hash_extensions.rb:112:10:112:36 | ...[...] [element 0] : | hash_extensions.rb:112:10:112:39 | ...[...] | +| hash_extensions.rb:112:10:112:36 | ...[...] [element 0] : | hash_extensions.rb:112:10:112:39 | ...[...] | +| hash_extensions.rb:113:10:113:15 | values [element 0, element :name] : | hash_extensions.rb:113:10:113:33 | call to pluck [element, element 1] : | +| hash_extensions.rb:113:10:113:15 | values [element 0, element :name] : | hash_extensions.rb:113:10:113:33 | call to pluck [element, element 1] : | +| hash_extensions.rb:113:10:113:15 | values [element 1, element :name] : | hash_extensions.rb:113:10:113:33 | call to pluck [element, element 1] : | +| hash_extensions.rb:113:10:113:15 | values [element 1, element :name] : | hash_extensions.rb:113:10:113:33 | call to pluck [element, element 1] : | +| hash_extensions.rb:113:10:113:33 | call to pluck [element, element 1] : | hash_extensions.rb:113:10:113:36 | ...[...] [element 1] : | +| hash_extensions.rb:113:10:113:33 | call to pluck [element, element 1] : | hash_extensions.rb:113:10:113:36 | ...[...] [element 1] : | +| hash_extensions.rb:113:10:113:36 | ...[...] [element 1] : | hash_extensions.rb:113:10:113:39 | ...[...] | +| hash_extensions.rb:113:10:113:36 | ...[...] [element 1] : | hash_extensions.rb:113:10:113:39 | ...[...] | +| hash_extensions.rb:114:10:114:15 | values [element 0, element :name] : | hash_extensions.rb:114:10:114:33 | call to pluck [element, element 0] : | +| hash_extensions.rb:114:10:114:15 | values [element 0, element :name] : | hash_extensions.rb:114:10:114:33 | call to pluck [element, element 0] : | +| hash_extensions.rb:114:10:114:15 | values [element 1, element :name] : | hash_extensions.rb:114:10:114:33 | call to pluck [element, element 0] : | +| hash_extensions.rb:114:10:114:15 | values [element 1, element :name] : | hash_extensions.rb:114:10:114:33 | call to pluck [element, element 0] : | +| hash_extensions.rb:114:10:114:33 | call to pluck [element, element 0] : | hash_extensions.rb:114:10:114:36 | ...[...] [element 0] : | +| hash_extensions.rb:114:10:114:33 | call to pluck [element, element 0] : | hash_extensions.rb:114:10:114:36 | ...[...] [element 0] : | +| hash_extensions.rb:114:10:114:36 | ...[...] [element 0] : | hash_extensions.rb:114:10:114:39 | ...[...] | +| hash_extensions.rb:114:10:114:36 | ...[...] [element 0] : | hash_extensions.rb:114:10:114:39 | ...[...] | +| hash_extensions.rb:115:10:115:15 | values [element 0, element :id] : | hash_extensions.rb:115:10:115:33 | call to pluck [element, element 1] : | +| hash_extensions.rb:115:10:115:15 | values [element 0, element :id] : | hash_extensions.rb:115:10:115:33 | call to pluck [element, element 1] : | +| hash_extensions.rb:115:10:115:15 | values [element 1, element :id] : | hash_extensions.rb:115:10:115:33 | call to pluck [element, element 1] : | +| hash_extensions.rb:115:10:115:15 | values [element 1, element :id] : | hash_extensions.rb:115:10:115:33 | call to pluck [element, element 1] : | +| hash_extensions.rb:115:10:115:33 | call to pluck [element, element 1] : | hash_extensions.rb:115:10:115:36 | ...[...] [element 1] : | +| hash_extensions.rb:115:10:115:33 | call to pluck [element, element 1] : | hash_extensions.rb:115:10:115:36 | ...[...] [element 1] : | +| hash_extensions.rb:115:10:115:36 | ...[...] [element 1] : | hash_extensions.rb:115:10:115:39 | ...[...] | +| hash_extensions.rb:115:10:115:36 | ...[...] [element 1] : | hash_extensions.rb:115:10:115:39 | ...[...] | nodes | active_support.rb:10:9:10:18 | call to source : | semmle.label | call to source : | | active_support.rb:11:10:11:10 | x : | semmle.label | x : | @@ -790,6 +848,62 @@ nodes | hash_extensions.rb:104:10:104:32 | call to pick [element 1] : | semmle.label | call to pick [element 1] : | | hash_extensions.rb:104:10:104:35 | ...[...] | semmle.label | ...[...] | | hash_extensions.rb:104:10:104:35 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:110:21:110:31 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:110:21:110:31 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:110:40:110:54 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:110:40:110:54 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:110:65:110:75 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:110:65:110:75 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:110:84:110:99 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:110:84:110:99 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:111:10:111:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : | +| hash_extensions.rb:111:10:111:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : | +| hash_extensions.rb:111:10:111:15 | values [element 1, element :name] : | semmle.label | values [element 1, element :name] : | +| hash_extensions.rb:111:10:111:15 | values [element 1, element :name] : | semmle.label | values [element 1, element :name] : | +| hash_extensions.rb:111:10:111:28 | call to pluck [element] : | semmle.label | call to pluck [element] : | +| hash_extensions.rb:111:10:111:28 | call to pluck [element] : | semmle.label | call to pluck [element] : | +| hash_extensions.rb:111:10:111:31 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:111:10:111:31 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:112:10:112:15 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : | +| hash_extensions.rb:112:10:112:15 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : | +| hash_extensions.rb:112:10:112:15 | values [element 1, element :id] : | semmle.label | values [element 1, element :id] : | +| hash_extensions.rb:112:10:112:15 | values [element 1, element :id] : | semmle.label | values [element 1, element :id] : | +| hash_extensions.rb:112:10:112:33 | call to pluck [element, element 0] : | semmle.label | call to pluck [element, element 0] : | +| hash_extensions.rb:112:10:112:33 | call to pluck [element, element 0] : | semmle.label | call to pluck [element, element 0] : | +| hash_extensions.rb:112:10:112:36 | ...[...] [element 0] : | semmle.label | ...[...] [element 0] : | +| hash_extensions.rb:112:10:112:36 | ...[...] [element 0] : | semmle.label | ...[...] [element 0] : | +| hash_extensions.rb:112:10:112:39 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:112:10:112:39 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:113:10:113:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : | +| hash_extensions.rb:113:10:113:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : | +| hash_extensions.rb:113:10:113:15 | values [element 1, element :name] : | semmle.label | values [element 1, element :name] : | +| hash_extensions.rb:113:10:113:15 | values [element 1, element :name] : | semmle.label | values [element 1, element :name] : | +| hash_extensions.rb:113:10:113:33 | call to pluck [element, element 1] : | semmle.label | call to pluck [element, element 1] : | +| hash_extensions.rb:113:10:113:33 | call to pluck [element, element 1] : | semmle.label | call to pluck [element, element 1] : | +| hash_extensions.rb:113:10:113:36 | ...[...] [element 1] : | semmle.label | ...[...] [element 1] : | +| hash_extensions.rb:113:10:113:36 | ...[...] [element 1] : | semmle.label | ...[...] [element 1] : | +| hash_extensions.rb:113:10:113:39 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:113:10:113:39 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:114:10:114:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : | +| hash_extensions.rb:114:10:114:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : | +| hash_extensions.rb:114:10:114:15 | values [element 1, element :name] : | semmle.label | values [element 1, element :name] : | +| hash_extensions.rb:114:10:114:15 | values [element 1, element :name] : | semmle.label | values [element 1, element :name] : | +| hash_extensions.rb:114:10:114:33 | call to pluck [element, element 0] : | semmle.label | call to pluck [element, element 0] : | +| hash_extensions.rb:114:10:114:33 | call to pluck [element, element 0] : | semmle.label | call to pluck [element, element 0] : | +| hash_extensions.rb:114:10:114:36 | ...[...] [element 0] : | semmle.label | ...[...] [element 0] : | +| hash_extensions.rb:114:10:114:36 | ...[...] [element 0] : | semmle.label | ...[...] [element 0] : | +| hash_extensions.rb:114:10:114:39 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:114:10:114:39 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:115:10:115:15 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : | +| hash_extensions.rb:115:10:115:15 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : | +| hash_extensions.rb:115:10:115:15 | values [element 1, element :id] : | semmle.label | values [element 1, element :id] : | +| hash_extensions.rb:115:10:115:15 | values [element 1, element :id] : | semmle.label | values [element 1, element :id] : | +| hash_extensions.rb:115:10:115:33 | call to pluck [element, element 1] : | semmle.label | call to pluck [element, element 1] : | +| hash_extensions.rb:115:10:115:33 | call to pluck [element, element 1] : | semmle.label | call to pluck [element, element 1] : | +| hash_extensions.rb:115:10:115:36 | ...[...] [element 1] : | semmle.label | ...[...] [element 1] : | +| hash_extensions.rb:115:10:115:36 | ...[...] [element 1] : | semmle.label | ...[...] [element 1] : | +| hash_extensions.rb:115:10:115:39 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:115:10:115:39 | ...[...] | semmle.label | ...[...] | subpaths #select | active_support.rb:182:10:182:13 | ...[...] | active_support.rb:180:10:180:17 | call to source : | active_support.rb:182:10:182:13 | ...[...] | $@ | active_support.rb:180:10:180:17 | call to source : | call to source : | @@ -840,3 +954,13 @@ subpaths | hash_extensions.rb:102:10:102:35 | ...[...] | hash_extensions.rb:98:40:98:54 | call to source : | hash_extensions.rb:102:10:102:35 | ...[...] | $@ | hash_extensions.rb:98:40:98:54 | call to source : | call to source : | | hash_extensions.rb:103:10:103:35 | ...[...] | hash_extensions.rb:98:40:98:54 | call to source : | hash_extensions.rb:103:10:103:35 | ...[...] | $@ | hash_extensions.rb:98:40:98:54 | call to source : | call to source : | | hash_extensions.rb:104:10:104:35 | ...[...] | hash_extensions.rb:98:21:98:31 | call to source : | hash_extensions.rb:104:10:104:35 | ...[...] | $@ | hash_extensions.rb:98:21:98:31 | call to source : | call to source : | +| hash_extensions.rb:111:10:111:31 | ...[...] | hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:111:10:111:31 | ...[...] | $@ | hash_extensions.rb:110:40:110:54 | call to source : | call to source : | +| hash_extensions.rb:111:10:111:31 | ...[...] | hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:111:10:111:31 | ...[...] | $@ | hash_extensions.rb:110:84:110:99 | call to source : | call to source : | +| hash_extensions.rb:112:10:112:39 | ...[...] | hash_extensions.rb:110:21:110:31 | call to source : | hash_extensions.rb:112:10:112:39 | ...[...] | $@ | hash_extensions.rb:110:21:110:31 | call to source : | call to source : | +| hash_extensions.rb:112:10:112:39 | ...[...] | hash_extensions.rb:110:65:110:75 | call to source : | hash_extensions.rb:112:10:112:39 | ...[...] | $@ | hash_extensions.rb:110:65:110:75 | call to source : | call to source : | +| hash_extensions.rb:113:10:113:39 | ...[...] | hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:113:10:113:39 | ...[...] | $@ | hash_extensions.rb:110:40:110:54 | call to source : | call to source : | +| hash_extensions.rb:113:10:113:39 | ...[...] | hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:113:10:113:39 | ...[...] | $@ | hash_extensions.rb:110:84:110:99 | call to source : | call to source : | +| hash_extensions.rb:114:10:114:39 | ...[...] | hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:114:10:114:39 | ...[...] | $@ | hash_extensions.rb:110:40:110:54 | call to source : | call to source : | +| hash_extensions.rb:114:10:114:39 | ...[...] | hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:114:10:114:39 | ...[...] | $@ | hash_extensions.rb:110:84:110:99 | call to source : | call to source : | +| hash_extensions.rb:115:10:115:39 | ...[...] | hash_extensions.rb:110:21:110:31 | call to source : | hash_extensions.rb:115:10:115:39 | ...[...] | $@ | hash_extensions.rb:110:21:110:31 | call to source : | call to source : | +| hash_extensions.rb:115:10:115:39 | ...[...] | hash_extensions.rb:110:65:110:75 | call to source : | hash_extensions.rb:115:10:115:39 | ...[...] | $@ | hash_extensions.rb:110:65:110:75 | call to source : | call to source : | diff --git a/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb b/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb index d31f5f0b271..d3980c4a1d1 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb +++ b/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb @@ -105,3 +105,14 @@ def m_pick end m_pick() + +def m_pluck(i) + values = [{ id: source("1"), name: source("David") }, { id: source("2"), name: source("Rafael") }] + sink(values.pluck(:name)[i]) # $ hasValueFlow=David $ hasValueFlow=Rafael + sink(values.pluck(:id, :name)[i][0]) # $ hasValueFlow=1 $ hasValueFlow=2 + sink(values.pluck(:id, :name)[i][1]) # $ hasValueFlow=David $ hasValueFlow=Rafael + sink(values.pluck(:name, :id)[i][0]) # $ hasValueFlow=David $ hasValueFlow=Rafael + sink(values.pluck(:name, :id)[i][1]) # $ hasValueFlow=1 $ hasValueFlow=2 +end + +m_pluck(0) From 0f2cb440b0d5b3e2af4db53e7e52fbab3b6640f0 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Wed, 16 Nov 2022 13:43:26 +0100 Subject: [PATCH 719/796] Ruby: add flow summary for Enumerable#sole --- .../codeql/ruby/frameworks/ActiveSupport.qll | 10 ++++++++ .../ActiveSupportDataFlow.expected | 23 +++++++++++++++++++ .../active_support/hash_extensions.rb | 11 +++++++++ 3 files changed, 44 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll index 727a233b438..04eeefc18b0 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll @@ -421,6 +421,16 @@ module ActiveSupport { preservesValue = true } } + + private class SoleSummary extends SimpleSummarizedCallable { + SoleSummary() { this = "sole" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[self].Element[0]" and + output = "ReturnValue" and + preservesValue = true + } + } } } diff --git a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected index f5c4e418b08..1d90832cee5 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected +++ b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected @@ -1,4 +1,5 @@ failures +| hash_extensions.rb:126:10:126:19 | call to sole | Unexpected result: hasValueFlow=b | edges | active_support.rb:10:9:10:18 | call to source : | active_support.rb:11:10:11:10 | x : | | active_support.rb:11:10:11:10 | x : | active_support.rb:11:10:11:19 | call to at | @@ -410,6 +411,14 @@ edges | hash_extensions.rb:115:10:115:33 | call to pluck [element, element 1] : | hash_extensions.rb:115:10:115:36 | ...[...] [element 1] : | | hash_extensions.rb:115:10:115:36 | ...[...] [element 1] : | hash_extensions.rb:115:10:115:39 | ...[...] | | hash_extensions.rb:115:10:115:36 | ...[...] [element 1] : | hash_extensions.rb:115:10:115:39 | ...[...] | +| hash_extensions.rb:122:15:122:25 | call to source : | hash_extensions.rb:125:10:125:15 | single [element 0] : | +| hash_extensions.rb:122:15:122:25 | call to source : | hash_extensions.rb:125:10:125:15 | single [element 0] : | +| hash_extensions.rb:123:14:123:24 | call to source : | hash_extensions.rb:126:10:126:14 | multi [element 0] : | +| hash_extensions.rb:123:14:123:24 | call to source : | hash_extensions.rb:126:10:126:14 | multi [element 0] : | +| hash_extensions.rb:125:10:125:15 | single [element 0] : | hash_extensions.rb:125:10:125:20 | call to sole | +| hash_extensions.rb:125:10:125:15 | single [element 0] : | hash_extensions.rb:125:10:125:20 | call to sole | +| hash_extensions.rb:126:10:126:14 | multi [element 0] : | hash_extensions.rb:126:10:126:19 | call to sole | +| hash_extensions.rb:126:10:126:14 | multi [element 0] : | hash_extensions.rb:126:10:126:19 | call to sole | nodes | active_support.rb:10:9:10:18 | call to source : | semmle.label | call to source : | | active_support.rb:11:10:11:10 | x : | semmle.label | x : | @@ -904,6 +913,18 @@ nodes | hash_extensions.rb:115:10:115:36 | ...[...] [element 1] : | semmle.label | ...[...] [element 1] : | | hash_extensions.rb:115:10:115:39 | ...[...] | semmle.label | ...[...] | | hash_extensions.rb:115:10:115:39 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:122:15:122:25 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:122:15:122:25 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:123:14:123:24 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:123:14:123:24 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:125:10:125:15 | single [element 0] : | semmle.label | single [element 0] : | +| hash_extensions.rb:125:10:125:15 | single [element 0] : | semmle.label | single [element 0] : | +| hash_extensions.rb:125:10:125:20 | call to sole | semmle.label | call to sole | +| hash_extensions.rb:125:10:125:20 | call to sole | semmle.label | call to sole | +| hash_extensions.rb:126:10:126:14 | multi [element 0] : | semmle.label | multi [element 0] : | +| hash_extensions.rb:126:10:126:14 | multi [element 0] : | semmle.label | multi [element 0] : | +| hash_extensions.rb:126:10:126:19 | call to sole | semmle.label | call to sole | +| hash_extensions.rb:126:10:126:19 | call to sole | semmle.label | call to sole | subpaths #select | active_support.rb:182:10:182:13 | ...[...] | active_support.rb:180:10:180:17 | call to source : | active_support.rb:182:10:182:13 | ...[...] | $@ | active_support.rb:180:10:180:17 | call to source : | call to source : | @@ -964,3 +985,5 @@ subpaths | hash_extensions.rb:114:10:114:39 | ...[...] | hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:114:10:114:39 | ...[...] | $@ | hash_extensions.rb:110:84:110:99 | call to source : | call to source : | | hash_extensions.rb:115:10:115:39 | ...[...] | hash_extensions.rb:110:21:110:31 | call to source : | hash_extensions.rb:115:10:115:39 | ...[...] | $@ | hash_extensions.rb:110:21:110:31 | call to source : | call to source : | | hash_extensions.rb:115:10:115:39 | ...[...] | hash_extensions.rb:110:65:110:75 | call to source : | hash_extensions.rb:115:10:115:39 | ...[...] | $@ | hash_extensions.rb:110:65:110:75 | call to source : | call to source : | +| hash_extensions.rb:125:10:125:20 | call to sole | hash_extensions.rb:122:15:122:25 | call to source : | hash_extensions.rb:125:10:125:20 | call to sole | $@ | hash_extensions.rb:122:15:122:25 | call to source : | call to source : | +| hash_extensions.rb:126:10:126:19 | call to sole | hash_extensions.rb:123:14:123:24 | call to source : | hash_extensions.rb:126:10:126:19 | call to sole | $@ | hash_extensions.rb:123:14:123:24 | call to source : | call to source : | diff --git a/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb b/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb index d3980c4a1d1..63d4e7a588d 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb +++ b/ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb @@ -116,3 +116,14 @@ def m_pluck(i) end m_pluck(0) + +def m_sole + empty = [] + single = [source("a")] + multi = [source("b"), source("c")] + sink(empty.sole) + sink(single.sole) # $ hasValueFlow=a + sink(multi.sole) # TODO: model that 'sole' does not return if the receiver has multiple elements +end + +m_sole() From cbf4197575a7d045b87912ca59bcbb830702488a Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Mon, 28 Nov 2022 13:54:32 +0100 Subject: [PATCH 720/796] Ruby: add change note --- .../lib/change-notes/2022-11-28-activesupport-enumerable.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ruby/ql/lib/change-notes/2022-11-28-activesupport-enumerable.md diff --git a/ruby/ql/lib/change-notes/2022-11-28-activesupport-enumerable.md b/ruby/ql/lib/change-notes/2022-11-28-activesupport-enumerable.md new file mode 100644 index 00000000000..81e11cc2eef --- /dev/null +++ b/ruby/ql/lib/change-notes/2022-11-28-activesupport-enumerable.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Data flow through the `ActiveSupport` extensions `Enumerable#index_with`, `Enumerable#pick`, `Enumerable#pluck` and `Enumerable#sole` are now modeled. From 55c4643b203062cb13138ea003d45407f46e50f2 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 30 Nov 2022 11:00:07 +0000 Subject: [PATCH 721/796] Dataflow: Sync. --- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll | 2 +- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll | 2 +- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll | 2 +- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll | 2 +- cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll | 2 +- cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll | 2 +- cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll | 2 +- cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll | 2 +- .../lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll | 2 +- .../lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll | 2 +- .../lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll | 2 +- .../lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll | 2 +- .../lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll | 2 +- .../lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll | 2 +- .../lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll | 2 +- .../lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll | 2 +- .../lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll | 2 +- .../lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll | 2 +- .../csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll | 2 +- go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll | 2 +- go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll | 2 +- .../ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll | 2 +- .../ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll | 2 +- .../ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll | 2 +- .../ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll | 2 +- .../ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll | 2 +- .../java/dataflow/internal/DataFlowImplForOnActivityResult.qll | 2 +- .../java/dataflow/internal/DataFlowImplForSerializability.qll | 2 +- .../ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll | 2 +- .../lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll | 2 +- .../lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll | 2 +- .../lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll | 2 +- ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll | 2 +- ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll | 2 +- .../dataflow/internal/DataFlowImplForHttpClientLibraries.qll | 2 +- .../codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll | 2 +- .../lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll | 2 +- swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll | 2 +- 38 files changed, 38 insertions(+), 38 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index e4cfd5986be..ccde916a3c2 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index e4cfd5986be..ccde916a3c2 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index e4cfd5986be..ccde916a3c2 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index e4cfd5986be..ccde916a3c2 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index e4cfd5986be..ccde916a3c2 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index e4cfd5986be..ccde916a3c2 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index e4cfd5986be..ccde916a3c2 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index e4cfd5986be..ccde916a3c2 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index e4cfd5986be..ccde916a3c2 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index e4cfd5986be..ccde916a3c2 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index e4cfd5986be..ccde916a3c2 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index e4cfd5986be..ccde916a3c2 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index e4cfd5986be..ccde916a3c2 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index e4cfd5986be..ccde916a3c2 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index e4cfd5986be..ccde916a3c2 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index e4cfd5986be..ccde916a3c2 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index e4cfd5986be..ccde916a3c2 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index e4cfd5986be..ccde916a3c2 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll index e4cfd5986be..ccde916a3c2 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index e4cfd5986be..ccde916a3c2 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index e4cfd5986be..ccde916a3c2 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index e4cfd5986be..ccde916a3c2 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index e4cfd5986be..ccde916a3c2 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index e4cfd5986be..ccde916a3c2 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index e4cfd5986be..ccde916a3c2 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index e4cfd5986be..ccde916a3c2 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll index e4cfd5986be..ccde916a3c2 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll index e4cfd5986be..ccde916a3c2 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll index e4cfd5986be..ccde916a3c2 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll index e4cfd5986be..ccde916a3c2 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll index e4cfd5986be..ccde916a3c2 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll index e4cfd5986be..ccde916a3c2 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index e4cfd5986be..ccde916a3c2 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll index e4cfd5986be..ccde916a3c2 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll index e4cfd5986be..ccde916a3c2 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll index e4cfd5986be..ccde916a3c2 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll index e4cfd5986be..ccde916a3c2 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index e4cfd5986be..ccde916a3c2 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes From 6103c577b60d4953ebb6617fde917230d3183e19 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Wed, 30 Nov 2022 12:02:42 +0100 Subject: [PATCH 722/796] Address comments --- ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll index 04eeefc18b0..d4490dde6da 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll @@ -328,7 +328,7 @@ module ActiveSupport { override MethodCall getACall() { result = mc } override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { - input = "Argument[self].Element[0].Element[" + key + "!]" and + input = "Argument[self].Element[0].Element[" + key + "]" and output = "ReturnValue" and preservesValue = true } @@ -361,8 +361,8 @@ module ActiveSupport { override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { exists(string s, int i | s = getKeyArgument(mc, i) and - input = "Argument[self].Element[0].Element[" + s + "!]" and - output = "ReturnValue.Element[" + i + "!]" + input = "Argument[self].Element[0].Element[" + s + "]" and + output = "ReturnValue.Element[" + i + "]" ) and preservesValue = true } @@ -382,7 +382,7 @@ module ActiveSupport { override MethodCall getACall() { result = mc } override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { - input = "Argument[self].Element[any].Element[" + key + "!]" and + input = "Argument[self].Element[any].Element[" + key + "]" and output = "ReturnValue.Element[any]" and preservesValue = true } @@ -415,8 +415,8 @@ module ActiveSupport { override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { exists(string s, int i | s = getKeyArgument(mc, i) and - input = "Argument[self].Element[any].Element[" + s + "!]" and - output = "ReturnValue.Element[?].Element[" + i + "!]" + input = "Argument[self].Element[any].Element[" + s + "]" and + output = "ReturnValue.Element[?].Element[" + i + "]" ) and preservesValue = true } From 635c202ced3e9295eccdcb0af4d305f646e31b8c Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 30 Nov 2022 10:53:54 +0000 Subject: [PATCH 723/796] Use `ArgumentPosition` instead of `int` This matches what all of the other languages do. --- .../code/java/dataflow/internal/FlowSummaryImplSpecific.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll index b005bab3257..007105d3e95 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll @@ -17,7 +17,7 @@ class SummarizedCallableBase = FlowSummary::SummarizedCallableBase; DataFlowCallable inject(SummarizedCallable c) { result.asSummarizedCallable() = c } /** Gets the parameter position of the instance parameter. */ -int instanceParameterPosition() { result = -1 } +ArgumentPosition instanceParameterPosition() { result = -1 } /** Gets the synthesized summary data-flow node for the given values. */ Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = getSummaryNode(c, state) } From 75940dc8b1730572ca6b10286eb38c90bd31f422 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 30 Nov 2022 10:55:08 +0000 Subject: [PATCH 724/796] Remove @codeql-go from code owners for dataflow --- CODEOWNERS | 7 ------- 1 file changed, 7 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 55ee2f974f7..42fb364418f 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -12,13 +12,6 @@ # ML-powered queries /javascript/ql/experimental/adaptivethreatmodeling/ @github/codeql-ml-powered-queries-reviewers -# Notify members of codeql-go about PRs to the shared data-flow library files -/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll @github/codeql-java @github/codeql-go -/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @github/codeql-java @github/codeql-go -/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll @github/codeql-java @github/codeql-go -/java/ql/src/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @github/codeql-java @github/codeql-go -/java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @github/codeql-java @github/codeql-go - # CodeQL tools and associated docs /docs/codeql/codeql-cli/ @github/codeql-cli-reviewers /docs/codeql/codeql-for-visual-studio-code/ @github/codeql-vscode-reviewers From 90d471b486db1103b72e88881da4bfe5ef4cd5c6 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Wed, 16 Nov 2022 14:31:14 +0100 Subject: [PATCH 725/796] Swift: upgrade to Swift 5.7.1 --- misc/bazel/workspace.bzl | 10 +++++----- .../ModuleDecl/ModuleDecl_getImportedModule.expected | 10 ++++++---- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/misc/bazel/workspace.bzl b/misc/bazel/workspace.bzl index 4248a09d47a..df5995b499b 100644 --- a/misc/bazel/workspace.bzl +++ b/misc/bazel/workspace.bzl @@ -1,15 +1,15 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") -_swift_prebuilt_version = "swift-5.7-RELEASE.43809.66" +_swift_prebuilt_version = "swift-5.7.1-RELEASE.44356.85" _swift_sha_map = { - "linux": "8c6480ed4b38bf46d2e55a97f08c38ae183bfeb68649f98193b7540b04428741", - "macos-x86_64": "ab103774b384a7f3f01c0d876699cae6afafe6cf2ee458b77b9aac6e08e4ca4d", + "Linux-X64": "c9f17e13cac89f097aaaa65b1bc32aac566c8e4f3b68fc18e970cc3ee31f4913", + "macOS-X64": "638ac0552e9e1ccee9e276525d1ea9454256feec20bc778efa8856fd6e506987", } _swift_arch_map = { - "linux": "linux", - "macos-x86_64": "darwin_x86_64", + "Linux-X64": "linux", + "macOS-X64": "darwin_x86_64", } def codeql_workspace(repository_name = "codeql"): diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getImportedModule.expected b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getImportedModule.expected index 7e29a9ce479..ca1793b95ef 100644 --- a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getImportedModule.expected +++ b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getImportedModule.expected @@ -1,7 +1,9 @@ | file://:0:0:0:0 | Foo | 0 | file://:0:0:0:0 | Swift | -| file://:0:0:0:0 | Foo | 1 | file://:0:0:0:0 | _Concurrency | -| file://:0:0:0:0 | Foo | 2 | file://:0:0:0:0 | SwiftOnoneSupport | +| file://:0:0:0:0 | Foo | 1 | file://:0:0:0:0 | _StringProcessing | +| file://:0:0:0:0 | Foo | 2 | file://:0:0:0:0 | _Concurrency | +| file://:0:0:0:0 | Foo | 3 | file://:0:0:0:0 | SwiftOnoneSupport | | file://:0:0:0:0 | __ObjC | 0 | file://:0:0:0:0 | Swift | | file://:0:0:0:0 | default_module_name | 0 | file://:0:0:0:0 | Swift | -| file://:0:0:0:0 | default_module_name | 1 | file://:0:0:0:0 | _Concurrency | -| file://:0:0:0:0 | default_module_name | 2 | file://:0:0:0:0 | SwiftOnoneSupport | +| file://:0:0:0:0 | default_module_name | 1 | file://:0:0:0:0 | _StringProcessing | +| file://:0:0:0:0 | default_module_name | 2 | file://:0:0:0:0 | _Concurrency | +| file://:0:0:0:0 | default_module_name | 3 | file://:0:0:0:0 | SwiftOnoneSupport | From f618d53302b9b36d3f2ed3a825d2354f54de5d5e Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Wed, 23 Nov 2022 12:33:41 +0100 Subject: [PATCH 726/796] Swift: add new implicit conversion --- swift/extractor/infra/SwiftTagTraits.h | 2 ++ swift/ql/.generated.list | 13 +++++---- swift/ql/lib/codeql/swift/elements.qll | 1 + .../elements/expr/AbiSafeConversionExpr.qll | 4 +++ .../expr/AbiSafeConversionExprConstructor.qll | 4 +++ .../codeql/swift/generated/ParentChild.qll | 19 +++++++++++++ swift/ql/lib/codeql/swift/generated/Raw.qll | 4 +++ swift/ql/lib/codeql/swift/generated/Synth.qll | 27 ++++++++++++++----- .../swift/generated/SynthConstructors.qll | 1 + .../generated/expr/AbiSafeConversionExpr.qll | 10 +++++++ swift/ql/lib/swift.dbscheme | 7 ++++- .../ImplicitConversionExpr.expected | 2 ++ .../ImplicitConversionExpr_getType.expected | 2 ++ .../implicit_conversions.swift | 9 +++++++ swift/schema.py | 3 +++ 15 files changed, 96 insertions(+), 12 deletions(-) create mode 100644 swift/ql/lib/codeql/swift/elements/expr/AbiSafeConversionExpr.qll create mode 100644 swift/ql/lib/codeql/swift/elements/expr/AbiSafeConversionExprConstructor.qll create mode 100644 swift/ql/lib/codeql/swift/generated/expr/AbiSafeConversionExpr.qll diff --git a/swift/extractor/infra/SwiftTagTraits.h b/swift/extractor/infra/SwiftTagTraits.h index 78b7bcc530e..5c3c2305460 100644 --- a/swift/extractor/infra/SwiftTagTraits.h +++ b/swift/extractor/infra/SwiftTagTraits.h @@ -36,6 +36,8 @@ using SILTokenTypeTag = void; // This is created during type checking and is only used for constraint checking using TypeVariableTypeTag = void; +using ABISafeConversionExprTag = AbiSafeConversionExprTag; + #define MAP_TYPE_TO_TAG(TYPE, TAG) \ template <> \ struct detail::ToTagFunctor { \ diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index 098740a9329..597e435a0f7 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -58,6 +58,8 @@ ql/lib/codeql/swift/elements/decl/TopLevelCodeDeclConstructor.qll 6920a4e7aec45a ql/lib/codeql/swift/elements/decl/TypeAliasDecl.qll ecb457a9a81c6b13a1068f471c0b87e59227838f54c5d4effe7d4c2f6e7f5800 630dc9cbf20603855c599a9f86037ba0d889ad3d2c2b6f9ac17508d398bff9e3 ql/lib/codeql/swift/elements/decl/TypeAliasDeclConstructor.qll ba70bb69b3a14283def254cc1859c29963838f624b3f1062a200a8df38f1edd5 96ac51d1b3156d4139e583f7f803e9eb95fe25cc61c12986e1b2972a781f9c8b ql/lib/codeql/swift/elements/decl/ValueDecl.qll b344768498e0d1794d92bc5b7c0417e75079aa8a82e27d7b3449f1e52f78d1e9 e3056cf6a883da2737cb220a89499a9e3977eb1c56b9e1d2f41a56b71a0c29f9 +ql/lib/codeql/swift/elements/expr/AbiSafeConversionExpr.qll 599bdb52d99a1e2800563209cecc01a5b5eb80cb4aff36b2d037b67c34ebb948 a87738539276438cef63145461adf25309d1938cfac367f53f53d33db9b12844 +ql/lib/codeql/swift/elements/expr/AbiSafeConversionExprConstructor.qll 7d70e7c47a9919efcb1ebcbf70e69cab1be30dd006297b75f6d72b25ae75502a e7a741c42401963f0c1da414b3ae779adeba091e9b8f56c9abf2a686e3a04d52 ql/lib/codeql/swift/elements/expr/AbstractClosureExpr.qll 125f8bd8f21c95c439616744539577afcfa9fd63c65683132a2c971abcec3523 400790fe643585ad39f40c433eff8934bbe542d140b81341bca3b6dfc5b22861 ql/lib/codeql/swift/elements/expr/AnyHashableErasureExpr.qll 20dd848a35a47af94d0fb8cf1a33a2bd6582c751440708c365cf338e522f6de5 bf80cab3e9ff5366a6223153409f4852acdb9e4a5d464fb73b2a8cffc664ca29 ql/lib/codeql/swift/elements/expr/AnyHashableErasureExprConstructor.qll 12816f18d079477176519a20b0f1262fc84da98f60bce3d3dd6476098c6542e7 4cc5c8492a97f4639e7d857f2fca9065293dfa953d6af451206ce911cda9f323 @@ -366,7 +368,7 @@ ql/lib/codeql/swift/elements/type/VariadicSequenceType.qll 5bca77dd661d3b2653d31 ql/lib/codeql/swift/elements/type/VariadicSequenceTypeConstructor.qll 0d1d2328a3b5e503a883e7e6d7efd0ca5e7f2633abead9e4c94a9f98ed3cb223 69bff81c1b9413949eacb9298d2efb718ea808e68364569a1090c9878c4af856 ql/lib/codeql/swift/elements/type/WeakStorageType.qll 87a28616eea3600fb0156fffcd65eeddc1ea74ce9c0ba5886c6365b9359e00ce 9c968414d7cc8d672f3754bced5d4f83f43a6d7872d0d263d79ff60483e1f996 ql/lib/codeql/swift/elements/type/WeakStorageTypeConstructor.qll d88b031ef44d6de14b3ddcff2eb47b53dbd11550c37250ff2edb42e5d21ec3e9 26d855c33492cf7a118e439f7baeed0e5425cfaf058b1dcc007eca7ed765c897 -ql/lib/codeql/swift/elements.qll af0ce7fc361a5cffdbdfbe1c7ff2a5addf6b8a79e3fc062f266776bc97886c33 af0ce7fc361a5cffdbdfbe1c7ff2a5addf6b8a79e3fc062f266776bc97886c33 +ql/lib/codeql/swift/elements.qll 954945d6d4939b28e024b85f77c58ab5b4fab2c931aa5650e22d8ded97a7eda9 954945d6d4939b28e024b85f77c58ab5b4fab2c931aa5650e22d8ded97a7eda9 ql/lib/codeql/swift/generated/AstNode.qll 02ca56d82801f942ae6265c6079d92ccafdf6b532f6bcebd98a04029ddf696e4 6216fda240e45bd4302fa0cf0f08f5f945418b144659264cdda84622b0420aa2 ql/lib/codeql/swift/generated/Callable.qll f4050fac68d745fe0fc4d7bd6cff7c326d6c19a5820a780e1d7e589328b1e550 b6540534acc0b583481a18918264b95a129f13ad26256abe667bf4f72c4432d2 ql/lib/codeql/swift/generated/Comment.qll f58b49f6e68c21f87c51e2ff84c8a64b09286d733e86f70d67d3a98fe6260bd6 975bbb599a2a7adc35179f6ae06d9cbc56ea8a03b972ef2ee87604834bc6deb1 @@ -378,11 +380,11 @@ ql/lib/codeql/swift/generated/ErrorElement.qll 4b032abe8ffb71376a29c63e470a52943 ql/lib/codeql/swift/generated/File.qll 61454459f5f1ae378bd4970ad1da4f39f3e696bac8a5eebdd162f131995c5316 3e6805f8858cd55dd0e0d0e5aeab923d6a55292dbf98b0029db1ae0208efe684 ql/lib/codeql/swift/generated/Locatable.qll bdc98b9fb7788f44a4bf7e487ee5bd329473409950a8e9f116d61995615ad849 0b36b4fe45e2aa195e4bb70c50ea95f32f141b8e01e5f23466c6427dd9ab88fb ql/lib/codeql/swift/generated/Location.qll 851766e474cdfdfa67da42e0031fc42dd60196ff5edd39d82f08d3e32deb84c1 b29b2c37672f5acff15f1d3c5727d902f193e51122327b31bd27ec5f877bca3b -ql/lib/codeql/swift/generated/ParentChild.qll d9c1edbbb28e685d31153c3a17419e80fd106cb580ef8440e25a8709e7f4c021 e0e59a05018e4b59ebda3a9fdc3435b1c82207b915630d55edbe6d3f92488356 +ql/lib/codeql/swift/generated/ParentChild.qll 0667eb3c260b97beefd4934c80f7ffd2350488807effb3fd79bf187d179cd9bb dc0d237357baa46fae3e453d0446646c6a444155f08a9811aa29167c8cd34c73 ql/lib/codeql/swift/generated/PureSynthConstructors.qll 1cd47d61fec37e019ce2e476603eb2273775bea81062d6bf3d6bbc49796f7b77 1cd47d61fec37e019ce2e476603eb2273775bea81062d6bf3d6bbc49796f7b77 -ql/lib/codeql/swift/generated/Raw.qll 74159a7425c2da672d72e71655d27af3479b0acc23d871eafcee7d044d013550 0a6e8a85fbfd7262c983b6a6fedabbe9f11648edbcc52cba5828b97fe18fbd02 -ql/lib/codeql/swift/generated/Synth.qll 90df85be365c89c3c2e22041ee7dc9dd2ad9194b66f82e8f9d8fefb8afd900ec 1632984f7a55f6bc55adb9f647baf634b002c299655cbf641dfb110525291689 -ql/lib/codeql/swift/generated/SynthConstructors.qll 5c91f09bd82728651ed61f498704e0f62847788fa986dec5e674d81f294076c7 5c91f09bd82728651ed61f498704e0f62847788fa986dec5e674d81f294076c7 +ql/lib/codeql/swift/generated/Raw.qll 6b8e3e3d86254d5689b17a08c41d23cda0d913b5d3b22b18b55aa00363ace6df 3736f05fc2c2eb6a9d9dd0d244061abe72161714cd435233106804472213e2b1 +ql/lib/codeql/swift/generated/Synth.qll cc7285c43e6c9f47ab67047916d232ad2078443b342ba1bb036c147127c40167 522a3ba4fc7f9fbb0b7d12fc5177fa0a0d2f8239bd6b4c36fc7d7a918fcdcccf +ql/lib/codeql/swift/generated/SynthConstructors.qll 0ff9cfcd64e7701003091f366ec903ec1bf82ec8385ee683b6e7b4e189033b11 0ff9cfcd64e7701003091f366ec903ec1bf82ec8385ee683b6e7b4e189033b11 ql/lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 ql/lib/codeql/swift/generated/UnknownLocation.qll e50efefa02a0ec1ff635a00951b5924602fc8cab57e5756e4a039382c69d3882 e50efefa02a0ec1ff635a00951b5924602fc8cab57e5756e4a039382c69d3882 ql/lib/codeql/swift/generated/UnspecifiedElement.qll dbc6ca4018012977b26ca184a88044c55b0661e3998cd14d46295b62a8d69625 184c9a0ce18c2ac881943b0fb400613d1401ed1d5564f90716b6c310ba5afe71 @@ -428,6 +430,7 @@ ql/lib/codeql/swift/generated/decl/TypeAliasDecl.qll 15cb5bdbe9d722c403874f744bf ql/lib/codeql/swift/generated/decl/TypeDecl.qll 3fb055ab433ec40186f822c5711e3d47f9084fb12a1faee550e1e3e2507cfb45 1f46f7ae90c414c5d00bc2e33c86aa80f5ffddfd6be1853d8d6d4222b8e3f584 ql/lib/codeql/swift/generated/decl/ValueDecl.qll 7b4e4c9334be676f242857c77099306d8a0a4357b253f8bc68f71328cedf1f58 f18938c47f670f2e0c27ffd7e31e55f291f88fb50d8e576fcea116d5f9e5c66d ql/lib/codeql/swift/generated/decl/VarDecl.qll 2fca00ba8b535d7cefc2fa863246a0821437ca29b885c4c30362e8a63f284479 5ba623001e071c16267e94d050bfd973addf2436152c7726945b5d87aa521af8 +ql/lib/codeql/swift/generated/expr/AbiSafeConversionExpr.qll f4c913df3f1c139a0533f9a3a2f2e07aee96ab723c957fc7153d68564e4fdd6d f4c913df3f1c139a0533f9a3a2f2e07aee96ab723c957fc7153d68564e4fdd6d ql/lib/codeql/swift/generated/expr/AbstractClosureExpr.qll f0060c2972d2e1f9818d8deea3ceebbbe0b19d2ce11adc9b670beb672c4564d3 5f2500c5f3728f81599bd4e1fb9c97ac5a44a6dce8c1ab84a850c62aae3741ff ql/lib/codeql/swift/generated/expr/AnyHashableErasureExpr.qll f450ac8e316def1cd64dcb61411bae191144079df7f313a5973e59dc89fe367f f450ac8e316def1cd64dcb61411bae191144079df7f313a5973e59dc89fe367f ql/lib/codeql/swift/generated/expr/AnyTryExpr.qll f2929f39407e1717b91fc41f593bd52f1ae14c619d61598bd0668a478a04a91e 62693c2c18678af1ff9ce5393f0dd87c5381e567b340f1a8a9ecf91a92e2e666 diff --git a/swift/ql/lib/codeql/swift/elements.qll b/swift/ql/lib/codeql/swift/elements.qll index ed474615518..672c5fc73cf 100644 --- a/swift/ql/lib/codeql/swift/elements.qll +++ b/swift/ql/lib/codeql/swift/elements.qll @@ -55,6 +55,7 @@ import codeql.swift.elements.decl.TypeAliasDecl import codeql.swift.elements.decl.TypeDecl import codeql.swift.elements.decl.ValueDecl import codeql.swift.elements.decl.VarDecl +import codeql.swift.elements.expr.AbiSafeConversionExpr import codeql.swift.elements.expr.AbstractClosureExpr import codeql.swift.elements.expr.AnyHashableErasureExpr import codeql.swift.elements.expr.AnyTryExpr diff --git a/swift/ql/lib/codeql/swift/elements/expr/AbiSafeConversionExpr.qll b/swift/ql/lib/codeql/swift/elements/expr/AbiSafeConversionExpr.qll new file mode 100644 index 00000000000..1a86e009f7a --- /dev/null +++ b/swift/ql/lib/codeql/swift/elements/expr/AbiSafeConversionExpr.qll @@ -0,0 +1,4 @@ +// generated by codegen/codegen.py, remove this comment if you wish to edit this file +private import codeql.swift.generated.expr.AbiSafeConversionExpr + +class AbiSafeConversionExpr extends Generated::AbiSafeConversionExpr { } diff --git a/swift/ql/lib/codeql/swift/elements/expr/AbiSafeConversionExprConstructor.qll b/swift/ql/lib/codeql/swift/elements/expr/AbiSafeConversionExprConstructor.qll new file mode 100644 index 00000000000..0ffc0618124 --- /dev/null +++ b/swift/ql/lib/codeql/swift/elements/expr/AbiSafeConversionExprConstructor.qll @@ -0,0 +1,4 @@ +// generated by codegen/codegen.py, remove this comment if you wish to edit this file +private import codeql.swift.generated.Raw + +predicate constructAbiSafeConversionExpr(Raw::AbiSafeConversionExpr id) { any() } diff --git a/swift/ql/lib/codeql/swift/generated/ParentChild.qll b/swift/ql/lib/codeql/swift/generated/ParentChild.qll index fe182ec2360..a44d0f746dd 100644 --- a/swift/ql/lib/codeql/swift/generated/ParentChild.qll +++ b/swift/ql/lib/codeql/swift/generated/ParentChild.qll @@ -1872,6 +1872,23 @@ private module Impl { ) } + private Element getImmediateChildOfAbiSafeConversionExpr( + AbiSafeConversionExpr e, int index, string partialPredicateCall + ) { + exists(int b, int bImplicitConversionExpr, int n | + b = 0 and + bImplicitConversionExpr = + b + 1 + + max(int i | i = -1 or exists(getImmediateChildOfImplicitConversionExpr(e, i, _)) | i) and + n = bImplicitConversionExpr and + ( + none() + or + result = getImmediateChildOfImplicitConversionExpr(e, index - b, partialPredicateCall) + ) + ) + } + private Element getImmediateChildOfAnyHashableErasureExpr( AnyHashableErasureExpr e, int index, string partialPredicateCall ) { @@ -4885,6 +4902,8 @@ private module Impl { or result = getImmediateChildOfVarargExpansionExpr(e, index, partialAccessor) or + result = getImmediateChildOfAbiSafeConversionExpr(e, index, partialAccessor) + or result = getImmediateChildOfAnyHashableErasureExpr(e, index, partialAccessor) or result = getImmediateChildOfArchetypeToSuperExpr(e, index, partialAccessor) diff --git a/swift/ql/lib/codeql/swift/generated/Raw.qll b/swift/ql/lib/codeql/swift/generated/Raw.qll index a15be0be546..66083c2bfd6 100644 --- a/swift/ql/lib/codeql/swift/generated/Raw.qll +++ b/swift/ql/lib/codeql/swift/generated/Raw.qll @@ -677,6 +677,10 @@ module Raw { Expr getSubExpr() { vararg_expansion_exprs(this, result) } } + class AbiSafeConversionExpr extends @abi_safe_conversion_expr, ImplicitConversionExpr { + override string toString() { result = "AbiSafeConversionExpr" } + } + class AnyHashableErasureExpr extends @any_hashable_erasure_expr, ImplicitConversionExpr { override string toString() { result = "AnyHashableErasureExpr" } } diff --git a/swift/ql/lib/codeql/swift/generated/Synth.qll b/swift/ql/lib/codeql/swift/generated/Synth.qll index b292cc8dbd4..4671a86634c 100644 --- a/swift/ql/lib/codeql/swift/generated/Synth.qll +++ b/swift/ql/lib/codeql/swift/generated/Synth.qll @@ -41,6 +41,7 @@ module Synth { TSubscriptDecl(Raw::SubscriptDecl id) { constructSubscriptDecl(id) } or TTopLevelCodeDecl(Raw::TopLevelCodeDecl id) { constructTopLevelCodeDecl(id) } or TTypeAliasDecl(Raw::TypeAliasDecl id) { constructTypeAliasDecl(id) } or + TAbiSafeConversionExpr(Raw::AbiSafeConversionExpr id) { constructAbiSafeConversionExpr(id) } or TAnyHashableErasureExpr(Raw::AnyHashableErasureExpr id) { constructAnyHashableErasureExpr(id) } or TAppliedPropertyWrapperExpr(Raw::AppliedPropertyWrapperExpr id) { constructAppliedPropertyWrapperExpr(id) @@ -386,12 +387,12 @@ module Synth { TAwaitExpr or TDotSelfExpr or TParenExpr or TUnresolvedMemberChainResultExpr; class TImplicitConversionExpr = - TAnyHashableErasureExpr or TArchetypeToSuperExpr or TArrayToPointerExpr or - TBridgeFromObjCExpr or TBridgeToObjCExpr or TClassMetatypeToObjectExpr or - TCollectionUpcastConversionExpr or TConditionalBridgeFromObjCExpr or - TCovariantFunctionConversionExpr or TCovariantReturnConversionExpr or TDerivedToBaseExpr or - TDestructureTupleExpr or TDifferentiableFunctionExpr or - TDifferentiableFunctionExtractOriginalExpr or TErasureExpr or + TAbiSafeConversionExpr or TAnyHashableErasureExpr or TArchetypeToSuperExpr or + TArrayToPointerExpr or TBridgeFromObjCExpr or TBridgeToObjCExpr or + TClassMetatypeToObjectExpr or TCollectionUpcastConversionExpr or + TConditionalBridgeFromObjCExpr or TCovariantFunctionConversionExpr or + TCovariantReturnConversionExpr or TDerivedToBaseExpr or TDestructureTupleExpr or + TDifferentiableFunctionExpr or TDifferentiableFunctionExtractOriginalExpr or TErasureExpr or TExistentialMetatypeToObjectExpr or TForeignObjectConversionExpr or TFunctionConversionExpr or TInOutToPointerExpr or TInjectIntoOptionalExpr or TLinearFunctionExpr or TLinearFunctionExtractOriginalExpr or @@ -592,6 +593,11 @@ module Synth { cached TTypeAliasDecl convertTypeAliasDeclFromRaw(Raw::Element e) { result = TTypeAliasDecl(e) } + cached + TAbiSafeConversionExpr convertAbiSafeConversionExprFromRaw(Raw::Element e) { + result = TAbiSafeConversionExpr(e) + } + cached TAnyHashableErasureExpr convertAnyHashableErasureExprFromRaw(Raw::Element e) { result = TAnyHashableErasureExpr(e) @@ -1751,6 +1757,8 @@ module Synth { cached TImplicitConversionExpr convertImplicitConversionExprFromRaw(Raw::Element e) { + result = convertAbiSafeConversionExprFromRaw(e) + or result = convertAnyHashableErasureExprFromRaw(e) or result = convertArchetypeToSuperExprFromRaw(e) @@ -2225,6 +2233,11 @@ module Synth { cached Raw::Element convertTypeAliasDeclToRaw(TTypeAliasDecl e) { e = TTypeAliasDecl(result) } + cached + Raw::Element convertAbiSafeConversionExprToRaw(TAbiSafeConversionExpr e) { + e = TAbiSafeConversionExpr(result) + } + cached Raw::Element convertAnyHashableErasureExprToRaw(TAnyHashableErasureExpr e) { e = TAnyHashableErasureExpr(result) @@ -3382,6 +3395,8 @@ module Synth { cached Raw::Element convertImplicitConversionExprToRaw(TImplicitConversionExpr e) { + result = convertAbiSafeConversionExprToRaw(e) + or result = convertAnyHashableErasureExprToRaw(e) or result = convertArchetypeToSuperExprToRaw(e) diff --git a/swift/ql/lib/codeql/swift/generated/SynthConstructors.qll b/swift/ql/lib/codeql/swift/generated/SynthConstructors.qll index 2009999e1d8..4623b04b784 100644 --- a/swift/ql/lib/codeql/swift/generated/SynthConstructors.qll +++ b/swift/ql/lib/codeql/swift/generated/SynthConstructors.qll @@ -33,6 +33,7 @@ import codeql.swift.elements.decl.StructDeclConstructor import codeql.swift.elements.decl.SubscriptDeclConstructor import codeql.swift.elements.decl.TopLevelCodeDeclConstructor import codeql.swift.elements.decl.TypeAliasDeclConstructor +import codeql.swift.elements.expr.AbiSafeConversionExprConstructor import codeql.swift.elements.expr.AnyHashableErasureExprConstructor import codeql.swift.elements.expr.AppliedPropertyWrapperExprConstructor import codeql.swift.elements.expr.ArchetypeToSuperExprConstructor diff --git a/swift/ql/lib/codeql/swift/generated/expr/AbiSafeConversionExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/AbiSafeConversionExpr.qll new file mode 100644 index 00000000000..3908c403ba5 --- /dev/null +++ b/swift/ql/lib/codeql/swift/generated/expr/AbiSafeConversionExpr.qll @@ -0,0 +1,10 @@ +// generated by codegen/codegen.py +private import codeql.swift.generated.Synth +private import codeql.swift.generated.Raw +import codeql.swift.elements.expr.ImplicitConversionExpr + +module Generated { + class AbiSafeConversionExpr extends Synth::TAbiSafeConversionExpr, ImplicitConversionExpr { + override string getAPrimaryQlClass() { result = "AbiSafeConversionExpr" } + } +} diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index 1a6e9325bd6..62fc609c1ab 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -870,7 +870,8 @@ if_exprs( //dir=expr ); @implicit_conversion_expr = - @any_hashable_erasure_expr + @abi_safe_conversion_expr +| @any_hashable_erasure_expr | @archetype_to_super_expr | @array_to_pointer_expr | @bridge_from_obj_c_expr @@ -1129,6 +1130,10 @@ vararg_expansion_exprs( //dir=expr int sub_expr: @expr_or_none ref ); +abi_safe_conversion_exprs( //dir=expr + unique int id: @abi_safe_conversion_expr +); + any_hashable_erasure_exprs( //dir=expr unique int id: @any_hashable_erasure_expr ); diff --git a/swift/ql/test/extractor-tests/generated/expr/ImplicitConversionExpr/ImplicitConversionExpr.expected b/swift/ql/test/extractor-tests/generated/expr/ImplicitConversionExpr/ImplicitConversionExpr.expected index 2fb20ad740c..fcc62b36775 100644 --- a/swift/ql/test/extractor-tests/generated/expr/ImplicitConversionExpr/ImplicitConversionExpr.expected +++ b/swift/ql/test/extractor-tests/generated/expr/ImplicitConversionExpr/ImplicitConversionExpr.expected @@ -1,3 +1,5 @@ | implicit_conversions.swift:2:3:2:3 | (UnsafePointer) ... | StringToPointerExpr | getSubExpr: | implicit_conversions.swift:2:3:2:3 | Hello | | implicit_conversions.swift:4:16:4:16 | (Int?) ... | InjectIntoOptionalExpr | getSubExpr: | implicit_conversions.swift:4:16:4:16 | 42 | | implicit_conversions.swift:5:25:5:25 | (Equatable) ... | ErasureExpr | getSubExpr: | implicit_conversions.swift:5:25:5:25 | 42 | +| implicit_conversions.swift:12:3:12:5 | (@lvalue (() -> Void)?) ... | AbiSafeConversionExpr | getSubExpr: | implicit_conversions.swift:12:3:12:5 | .b | +| implicit_conversions.swift:12:9:12:10 | ((() -> Void)?) ... | InjectIntoOptionalExpr | getSubExpr: | implicit_conversions.swift:12:9:12:10 | { ... } | diff --git a/swift/ql/test/extractor-tests/generated/expr/ImplicitConversionExpr/ImplicitConversionExpr_getType.expected b/swift/ql/test/extractor-tests/generated/expr/ImplicitConversionExpr/ImplicitConversionExpr_getType.expected index 470228364ae..d8dfc2cd957 100644 --- a/swift/ql/test/extractor-tests/generated/expr/ImplicitConversionExpr/ImplicitConversionExpr_getType.expected +++ b/swift/ql/test/extractor-tests/generated/expr/ImplicitConversionExpr/ImplicitConversionExpr_getType.expected @@ -1,3 +1,5 @@ | implicit_conversions.swift:2:3:2:3 | (UnsafePointer) ... | UnsafePointer | | implicit_conversions.swift:4:16:4:16 | (Int?) ... | Int? | | implicit_conversions.swift:5:25:5:25 | (Equatable) ... | Equatable | +| implicit_conversions.swift:12:3:12:5 | (@lvalue (() -> Void)?) ... | @lvalue (() -> Void)? | +| implicit_conversions.swift:12:9:12:10 | ((() -> Void)?) ... | (() -> Void)? | diff --git a/swift/ql/test/extractor-tests/generated/expr/ImplicitConversionExpr/implicit_conversions.swift b/swift/ql/test/extractor-tests/generated/expr/ImplicitConversionExpr/implicit_conversions.swift index 62a5197d420..6bd2b4b3fb1 100644 --- a/swift/ql/test/extractor-tests/generated/expr/ImplicitConversionExpr/implicit_conversions.swift +++ b/swift/ql/test/extractor-tests/generated/expr/ImplicitConversionExpr/implicit_conversions.swift @@ -3,3 +3,12 @@ f("Hello") // StringToPointerExpr let a : Int? = 42 // InjectIntoOptionalExpr let b : any Equatable = 42 // ErasureExpr + +@preconcurrency class A { + @preconcurrency var b: (@Sendable () -> Void)? +} + +func g(_ a: A) { + a.b = {} +} + diff --git a/swift/schema.py b/swift/schema.py index 3162c1277e0..7654f9e2ec8 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -1040,3 +1040,6 @@ class ParameterizedProtocolType(Type): """ base: ProtocolType args: list[Type] + +class AbiSafeConversionExpr(ImplicitConversionExpr): + pass From 67fb56deb8879a353aa25efa6a0a6f1323cbf735 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Thu, 24 Nov 2022 15:36:35 +0100 Subject: [PATCH 727/796] Swift: workaround an internal crash coming from Swift 5.7.1 --- swift/extractor/infra/SwiftDispatcher.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/swift/extractor/infra/SwiftDispatcher.h b/swift/extractor/infra/SwiftDispatcher.h index 991511e300c..0175bba1e6b 100644 --- a/swift/extractor/infra/SwiftDispatcher.h +++ b/swift/extractor/infra/SwiftDispatcher.h @@ -215,6 +215,17 @@ class SwiftDispatcher { // Emits a Location TRAP entry and attaches it to a `Locatable` trap label template void attachLocation(Locatable* locatable, TrapLabel locatableLabel) { + // Swift 5.7.1 causing a crash when the Swift compiler uses .back() of and empty + // getPatternList() when getting the source location. + // So far this only observed with the entities coming from precompiled modules, so they + // should not have locations anyway. + if constexpr (std::is_base_of::value) { + if (auto* decl = llvm::dyn_cast(locatable)) { + if (decl->getPatternList().empty()) { + return; + } + } + } attachLocation(locatable->getStartLoc(), locatable->getEndLoc(), locatableLabel); } From ad663533c7ed9b1b6fe4c976e6ba9a824125dad5 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Wed, 30 Nov 2022 08:27:36 +0100 Subject: [PATCH 728/796] Swift: bump setup Swift action --- swift/actions/run-integration-tests/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/actions/run-integration-tests/action.yml b/swift/actions/run-integration-tests/action.yml index 6894ef461bc..27ea6cde433 100644 --- a/swift/actions/run-integration-tests/action.yml +++ b/swift/actions/run-integration-tests/action.yml @@ -13,7 +13,7 @@ runs: - uses: actions/setup-python@v4 with: python-version-file: 'swift/.python-version' - - uses: swift-actions/setup-swift@5cdaa9161ad1f55ae39a5ea1784ef96de72f95d9 + - uses: swift-actions/setup-swift@194625b58a582570f61cc707c3b558086c26b723 with: swift-version: "${{steps.get_swift_version.outputs.version}}" - uses: ./.github/actions/fetch-codeql From fe0ae6bf0b0f7bc71ddea0c0d22335bb4fd94309 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Thu, 24 Nov 2022 10:31:04 +0100 Subject: [PATCH 729/796] Swift: add 5.7.1 migration scripts --- .../implicit_conversion_exprs.ql | 8 + .../old.dbscheme | 2518 +++++++++++++++++ .../swift.dbscheme | 2513 ++++++++++++++++ .../unspecified_elements.ql | 13 + .../upgrade.properties | 5 + .../old.dbscheme | 2513 ++++++++++++++++ .../swift.dbscheme | 2518 +++++++++++++++++ .../upgrade.properties | 2 + 8 files changed, 10090 insertions(+) create mode 100644 swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/implicit_conversion_exprs.ql create mode 100644 swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/old.dbscheme create mode 100644 swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/swift.dbscheme create mode 100644 swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/unspecified_elements.ql create mode 100644 swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/upgrade.properties create mode 100644 swift/ql/lib/upgrades/1a6e9325bd60462e669e524438174deef4476df0/old.dbscheme create mode 100644 swift/ql/lib/upgrades/1a6e9325bd60462e669e524438174deef4476df0/swift.dbscheme create mode 100644 swift/ql/lib/upgrades/1a6e9325bd60462e669e524438174deef4476df0/upgrade.properties diff --git a/swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/implicit_conversion_exprs.ql b/swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/implicit_conversion_exprs.ql new file mode 100644 index 00000000000..67418103c99 --- /dev/null +++ b/swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/implicit_conversion_exprs.ql @@ -0,0 +1,8 @@ +// Removes AbiSafeConversionExprs from ImplicitConversionExprs +class Element extends @element { + string toString() { none() } +} + +from Element e, Element child +where implicit_conversion_exprs(e, child) and not abi_safe_conversion_exprs(e) +select e, child diff --git a/swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/old.dbscheme b/swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/old.dbscheme new file mode 100644 index 00000000000..62fc609c1ab --- /dev/null +++ b/swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/old.dbscheme @@ -0,0 +1,2518 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @iterable_decl_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @case_label_item +| @condition_element +| @decl +| @expr +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +@decl = + @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +@generic_context = + @abstract_function_decl +| @extension_decl +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +@iterable_decl_context = + @extension_decl +| @nominal_type_decl +; + +#keyset[id, index] +iterable_decl_context_members( //dir=decl + int id: @iterable_decl_context ref, + int index: int ref, + int member: @decl_or_none ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_function_decl +| @abstract_storage_decl +| @enum_element_decl +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_function_decl = + @constructor_decl +| @destructor_decl +| @func_decl +; + +#keyset[id] +abstract_function_decls( //dir=decl + int id: @abstract_function_decl ref, + string name: string ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessor_decls( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor_decl: @accessor_decl_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +constructor_decls( //dir=decl + unique int id: @constructor_decl +); + +destructor_decls( //dir=decl + unique int id: @destructor_decl +); + +@func_decl = + @accessor_decl +| @concrete_func_decl +; + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id, index] +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessor_decls( //dir=decl + unique int id: @accessor_decl +); + +#keyset[id] +accessor_decl_is_getter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_setter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_will_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_did_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_read( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_modify( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_address( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_mutable_address( //dir=decl + int id: @accessor_decl ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_func_decls( //dir=decl + unique int id: @concrete_func_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @abstract_closure_expr +| @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initializer_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_constructor_decl_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_constructor_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@abstract_closure_expr = + @auto_closure_expr +| @closure_expr +; + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @abi_safe_conversion_expr +| @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id] +key_path_expr_parsed_paths( //dir=expr + int id: @key_path_expr ref, + int parsed_path: @expr_or_none ref +); + +lazy_initializer_exprs( //dir=expr + unique int id: @lazy_initializer_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @abstract_function_decl_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_constructor_decl_ref_exprs( //dir=expr + unique int id: @other_constructor_decl_ref_expr, + int constructor_decl: @constructor_decl_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_constructor_exprs( //dir=expr + unique int id: @rebind_self_in_constructor_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +abi_safe_conversion_exprs( //dir=expr + unique int id: @abi_safe_conversion_expr +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +closure_exprs( //dir=expr + unique int id: @closure_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr +); + +@self_apply_expr = + @constructor_ref_call_expr +| @dot_syntax_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +constructor_ref_call_exprs( //dir=expr + unique int id: @constructor_ref_call_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_labels( //dir=type + int id: @any_function_type ref, + int index: int ref, + string param_label: string ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@abstract_function_decl_or_none = + @abstract_function_decl +| @unspecified_element +; + +@accessor_decl_or_none = + @accessor_decl +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@constructor_decl_or_none = + @constructor_decl +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/swift.dbscheme b/swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/swift.dbscheme new file mode 100644 index 00000000000..1a6e9325bd6 --- /dev/null +++ b/swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/swift.dbscheme @@ -0,0 +1,2513 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @iterable_decl_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @case_label_item +| @condition_element +| @decl +| @expr +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +@decl = + @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +@generic_context = + @abstract_function_decl +| @extension_decl +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +@iterable_decl_context = + @extension_decl +| @nominal_type_decl +; + +#keyset[id, index] +iterable_decl_context_members( //dir=decl + int id: @iterable_decl_context ref, + int index: int ref, + int member: @decl_or_none ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_function_decl +| @abstract_storage_decl +| @enum_element_decl +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_function_decl = + @constructor_decl +| @destructor_decl +| @func_decl +; + +#keyset[id] +abstract_function_decls( //dir=decl + int id: @abstract_function_decl ref, + string name: string ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessor_decls( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor_decl: @accessor_decl_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +constructor_decls( //dir=decl + unique int id: @constructor_decl +); + +destructor_decls( //dir=decl + unique int id: @destructor_decl +); + +@func_decl = + @accessor_decl +| @concrete_func_decl +; + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id, index] +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessor_decls( //dir=decl + unique int id: @accessor_decl +); + +#keyset[id] +accessor_decl_is_getter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_setter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_will_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_did_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_read( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_modify( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_address( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_mutable_address( //dir=decl + int id: @accessor_decl ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_func_decls( //dir=decl + unique int id: @concrete_func_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @abstract_closure_expr +| @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initializer_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_constructor_decl_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_constructor_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@abstract_closure_expr = + @auto_closure_expr +| @closure_expr +; + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id] +key_path_expr_parsed_paths( //dir=expr + int id: @key_path_expr ref, + int parsed_path: @expr_or_none ref +); + +lazy_initializer_exprs( //dir=expr + unique int id: @lazy_initializer_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @abstract_function_decl_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_constructor_decl_ref_exprs( //dir=expr + unique int id: @other_constructor_decl_ref_expr, + int constructor_decl: @constructor_decl_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_constructor_exprs( //dir=expr + unique int id: @rebind_self_in_constructor_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +closure_exprs( //dir=expr + unique int id: @closure_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr +); + +@self_apply_expr = + @constructor_ref_call_expr +| @dot_syntax_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +constructor_ref_call_exprs( //dir=expr + unique int id: @constructor_ref_call_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_labels( //dir=type + int id: @any_function_type ref, + int index: int ref, + string param_label: string ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@abstract_function_decl_or_none = + @abstract_function_decl +| @unspecified_element +; + +@accessor_decl_or_none = + @accessor_decl +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@constructor_decl_or_none = + @constructor_decl +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/unspecified_elements.ql b/swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/unspecified_elements.ql new file mode 100644 index 00000000000..0be4d91ad6f --- /dev/null +++ b/swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/unspecified_elements.ql @@ -0,0 +1,13 @@ +// Moves AbiSafeConversionExprs into UnspecifiedElements +class Element extends @element { + string toString() { none() } +} + +from Element e, string property, string error +where + abi_safe_conversion_exprs(e) and + property = "" and + error = "Removed ABISafeConversionExpr during the database downgrade" + or + unspecified_elements(e, property, error) +select e, property, error diff --git a/swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/upgrade.properties b/swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/upgrade.properties new file mode 100644 index 00000000000..70c85c2ad6c --- /dev/null +++ b/swift/downgrades/62fc609c1ab6ae748ff51362ffa5c368ba834ddf/upgrade.properties @@ -0,0 +1,5 @@ +description: Remove new implicit conversion +compatibility: partial +unspecified_elements.rel: run unspecified_elements.ql +implicit_conversion_exprs.rel: run implicit_conversion_exprs.ql +abi_safe_conversion_exprs.rel: delete diff --git a/swift/ql/lib/upgrades/1a6e9325bd60462e669e524438174deef4476df0/old.dbscheme b/swift/ql/lib/upgrades/1a6e9325bd60462e669e524438174deef4476df0/old.dbscheme new file mode 100644 index 00000000000..1a6e9325bd6 --- /dev/null +++ b/swift/ql/lib/upgrades/1a6e9325bd60462e669e524438174deef4476df0/old.dbscheme @@ -0,0 +1,2513 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @iterable_decl_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @case_label_item +| @condition_element +| @decl +| @expr +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +@decl = + @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +@generic_context = + @abstract_function_decl +| @extension_decl +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +@iterable_decl_context = + @extension_decl +| @nominal_type_decl +; + +#keyset[id, index] +iterable_decl_context_members( //dir=decl + int id: @iterable_decl_context ref, + int index: int ref, + int member: @decl_or_none ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_function_decl +| @abstract_storage_decl +| @enum_element_decl +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_function_decl = + @constructor_decl +| @destructor_decl +| @func_decl +; + +#keyset[id] +abstract_function_decls( //dir=decl + int id: @abstract_function_decl ref, + string name: string ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessor_decls( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor_decl: @accessor_decl_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +constructor_decls( //dir=decl + unique int id: @constructor_decl +); + +destructor_decls( //dir=decl + unique int id: @destructor_decl +); + +@func_decl = + @accessor_decl +| @concrete_func_decl +; + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id, index] +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessor_decls( //dir=decl + unique int id: @accessor_decl +); + +#keyset[id] +accessor_decl_is_getter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_setter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_will_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_did_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_read( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_modify( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_address( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_mutable_address( //dir=decl + int id: @accessor_decl ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_func_decls( //dir=decl + unique int id: @concrete_func_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @abstract_closure_expr +| @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initializer_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_constructor_decl_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_constructor_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@abstract_closure_expr = + @auto_closure_expr +| @closure_expr +; + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id] +key_path_expr_parsed_paths( //dir=expr + int id: @key_path_expr ref, + int parsed_path: @expr_or_none ref +); + +lazy_initializer_exprs( //dir=expr + unique int id: @lazy_initializer_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @abstract_function_decl_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_constructor_decl_ref_exprs( //dir=expr + unique int id: @other_constructor_decl_ref_expr, + int constructor_decl: @constructor_decl_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_constructor_exprs( //dir=expr + unique int id: @rebind_self_in_constructor_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +closure_exprs( //dir=expr + unique int id: @closure_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr +); + +@self_apply_expr = + @constructor_ref_call_expr +| @dot_syntax_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +constructor_ref_call_exprs( //dir=expr + unique int id: @constructor_ref_call_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_labels( //dir=type + int id: @any_function_type ref, + int index: int ref, + string param_label: string ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@abstract_function_decl_or_none = + @abstract_function_decl +| @unspecified_element +; + +@accessor_decl_or_none = + @accessor_decl +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@constructor_decl_or_none = + @constructor_decl +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/ql/lib/upgrades/1a6e9325bd60462e669e524438174deef4476df0/swift.dbscheme b/swift/ql/lib/upgrades/1a6e9325bd60462e669e524438174deef4476df0/swift.dbscheme new file mode 100644 index 00000000000..62fc609c1ab --- /dev/null +++ b/swift/ql/lib/upgrades/1a6e9325bd60462e669e524438174deef4476df0/swift.dbscheme @@ -0,0 +1,2518 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @iterable_decl_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @case_label_item +| @condition_element +| @decl +| @expr +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +@decl = + @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +@generic_context = + @abstract_function_decl +| @extension_decl +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +@iterable_decl_context = + @extension_decl +| @nominal_type_decl +; + +#keyset[id, index] +iterable_decl_context_members( //dir=decl + int id: @iterable_decl_context ref, + int index: int ref, + int member: @decl_or_none ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_function_decl +| @abstract_storage_decl +| @enum_element_decl +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_function_decl = + @constructor_decl +| @destructor_decl +| @func_decl +; + +#keyset[id] +abstract_function_decls( //dir=decl + int id: @abstract_function_decl ref, + string name: string ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessor_decls( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor_decl: @accessor_decl_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +constructor_decls( //dir=decl + unique int id: @constructor_decl +); + +destructor_decls( //dir=decl + unique int id: @destructor_decl +); + +@func_decl = + @accessor_decl +| @concrete_func_decl +; + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id, index] +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int index: int ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessor_decls( //dir=decl + unique int id: @accessor_decl +); + +#keyset[id] +accessor_decl_is_getter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_setter( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_will_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_did_set( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_read( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_modify( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_address( //dir=decl + int id: @accessor_decl ref +); + +#keyset[id] +accessor_decl_is_unsafe_mutable_address( //dir=decl + int id: @accessor_decl ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_func_decls( //dir=decl + unique int id: @concrete_func_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @abstract_closure_expr +| @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initializer_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_constructor_decl_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_constructor_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@abstract_closure_expr = + @auto_closure_expr +| @closure_expr +; + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @abi_safe_conversion_expr +| @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id] +key_path_expr_parsed_paths( //dir=expr + int id: @key_path_expr ref, + int parsed_path: @expr_or_none ref +); + +lazy_initializer_exprs( //dir=expr + unique int id: @lazy_initializer_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @abstract_function_decl_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_constructor_decl_ref_exprs( //dir=expr + unique int id: @other_constructor_decl_ref_expr, + int constructor_decl: @constructor_decl_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_constructor_exprs( //dir=expr + unique int id: @rebind_self_in_constructor_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +abi_safe_conversion_exprs( //dir=expr + unique int id: @abi_safe_conversion_expr +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +closure_exprs( //dir=expr + unique int id: @closure_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr +); + +@self_apply_expr = + @constructor_ref_call_expr +| @dot_syntax_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +constructor_ref_call_exprs( //dir=expr + unique int id: @constructor_ref_call_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_labels( //dir=type + int id: @any_function_type ref, + int index: int ref, + string param_label: string ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@abstract_function_decl_or_none = + @abstract_function_decl +| @unspecified_element +; + +@accessor_decl_or_none = + @accessor_decl +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@constructor_decl_or_none = + @constructor_decl +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/ql/lib/upgrades/1a6e9325bd60462e669e524438174deef4476df0/upgrade.properties b/swift/ql/lib/upgrades/1a6e9325bd60462e669e524438174deef4476df0/upgrade.properties new file mode 100644 index 00000000000..e5bd2c32e33 --- /dev/null +++ b/swift/ql/lib/upgrades/1a6e9325bd60462e669e524438174deef4476df0/upgrade.properties @@ -0,0 +1,2 @@ +description: Added new implicit conversion +compatibility: full From 4e7e70f9815deaf0c0bb6d6117bd5249a18f85f1 Mon Sep 17 00:00:00 2001 From: intrigus-lgtm <60750685+intrigus-lgtm@users.noreply.github.com> Date: Wed, 30 Nov 2022 13:12:06 +0100 Subject: [PATCH 730/796] Docs: Add missing `language[monotonicAggregates]` annotation This adds the `language[monotonicAggregates]` annotation so that the example compiles. --- docs/codeql/ql-language-reference/expressions.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/codeql/ql-language-reference/expressions.rst b/docs/codeql/ql-language-reference/expressions.rst index fdb0d6cd35a..29771fde93d 100644 --- a/docs/codeql/ql-language-reference/expressions.rst +++ b/docs/codeql/ql-language-reference/expressions.rst @@ -602,6 +602,7 @@ the distance of a node in a graph from the leaves as follows: .. code-block:: ql + language[monotonicAggregates] int depth(Node n) { if not exists(n.getAChild()) then result = 0 From 76db5f22b3705daa81317eded08d0d624381ced5 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 30 Nov 2022 13:39:56 +0100 Subject: [PATCH 731/796] Swift: make `codegen` resilient to formatting errors More in general, the managed renderer flow does things more sensibly in case an exception is thrown: * it will not remove any file * it will drop already written files from the registry, so that codegen won't be skipped for those files during the next run --- swift/codegen/lib/render.py | 18 +++++++++----- swift/codegen/test/test_render.py | 39 +++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/swift/codegen/lib/render.py b/swift/codegen/lib/render.py index 9564f5eb4ab..cc26880fbac 100644 --- a/swift/codegen/lib/render.py +++ b/swift/codegen/lib/render.py @@ -103,12 +103,18 @@ class RenderManager(Renderer): return self def __exit__(self, exc_type, exc_val, exc_tb): - for f in self._existing - self._skipped - self.written: - self._hashes.pop(self._get_path(f), None) - f.unlink(missing_ok=True) - log.info(f"removed {f.name}") - for f in self.written: - self._hashes[self._get_path(f)].post = self._hash_file(f) + if exc_val is None: + for f in self._existing - self._skipped - self.written: + self._hashes.pop(self._get_path(f), None) + f.unlink(missing_ok=True) + log.info(f"removed {f.name}") + for f in self.written: + self._hashes[self._get_path(f)].post = self._hash_file(f) + else: + # if an error was encountered, drop already written files from the registry + # so that they get the chance to be regenerated again during the next run + for f in self.written: + self._hashes.pop(self._get_path(f), None) self._dump_registry() def _do_write(self, mnemonic: str, contents: str, output: pathlib.Path): diff --git a/swift/codegen/test/test_render.py b/swift/codegen/test/test_render.py index 64cc745046f..8c48902eea7 100644 --- a/swift/codegen/test/test_render.py +++ b/swift/codegen/test/test_render.py @@ -192,6 +192,45 @@ def test_managed_render_with_modified_stub_file_not_marked_as_generated(pystache assert_file(registry, "") +class MyError(Exception): + pass + + +def test_managed_render_exception_drops_written_from_registry(pystache_renderer, sut): + data = mock.Mock(spec=("template",)) + text = "some text" + pystache_renderer.render_name.side_effect = (text,) + output = paths.swift_dir / "some/output.txt" + registry = paths.swift_dir / "a/registry.list" + write(output, text) + write(registry, "a a a\n" + f"some/output.txt whatever {hash(text)}\n" + "b b b") + + with pytest.raises(MyError): + with sut.manage(generated=(), stubs=(), registry=registry) as renderer: + renderer.render(data, output) + raise MyError + + assert_file(registry, "a a a\nb b b\n") + + +def test_managed_render_exception_does_not_erase(pystache_renderer, sut): + output = paths.swift_dir / "some/output.txt" + stub = paths.swift_dir / "some/stub.txt" + registry = paths.swift_dir / "a/registry.list" + write(output) + write(stub, "// generated bla bla") + write(registry) + + with pytest.raises(MyError): + with sut.manage(generated=(output,), stubs=(stub,), registry=registry) as renderer: + raise MyError + + assert output.is_file() + assert stub.is_file() + + def test_render_with_extensions(pystache_renderer, sut): data = mock.Mock(spec=("template", "extensions")) data.template = "test_template" From d6aad13a9866c7fa2e2a58296d28780142d4a113 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 30 Nov 2022 13:47:12 +0100 Subject: [PATCH 732/796] Swift: make `codegen` run when no registry is there --- swift/codegen/lib/render.py | 12 ++++++++---- swift/codegen/test/test_render.py | 17 +++++++++++++++++ swift/ql/.generated.list | 2 +- .../swift/generated/UnspecifiedElement.qll | 3 +++ swift/schema.py | 1 + 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/swift/codegen/lib/render.py b/swift/codegen/lib/render.py index cc26880fbac..8294ecfda2b 100644 --- a/swift/codegen/lib/render.py +++ b/swift/codegen/lib/render.py @@ -171,12 +171,16 @@ class RenderManager(Renderer): return h.hexdigest() def _load_registry(self): - with open(self._registry_path) as reg: - for line in reg: - filename, prehash, posthash = line.split() - self._hashes[pathlib.Path(filename)] = self.Hashes(prehash, posthash) + try: + with open(self._registry_path) as reg: + for line in reg: + filename, prehash, posthash = line.split() + self._hashes[pathlib.Path(filename)] = self.Hashes(prehash, posthash) + except FileNotFoundError: + pass def _dump_registry(self): + self._registry_path.parent.mkdir(parents=True, exist_ok=True) with open(self._registry_path, 'w') as out: for f, hashes in sorted(self._hashes.items()): print(f, hashes.pre, hashes.post, file=out) diff --git a/swift/codegen/test/test_render.py b/swift/codegen/test/test_render.py index 8c48902eea7..cb249046b7b 100644 --- a/swift/codegen/test/test_render.py +++ b/swift/codegen/test/test_render.py @@ -75,6 +75,23 @@ def test_managed_render(pystache_renderer, sut): mock.call.render_name(data.template, data, generator=paths.exe_file.relative_to(paths.swift_dir)), ] +def test_managed_render_with_no_registry(pystache_renderer, sut): + data = mock.Mock(spec=("template",)) + text = "some text" + pystache_renderer.render_name.side_effect = (text,) + output = paths.swift_dir / "some/output.txt" + registry = paths.swift_dir / "a/registry.list" + + with sut.manage(generated=(), stubs=(), registry=registry) as renderer: + renderer.render(data, output) + assert renderer.written == {output} + assert_file(output, text) + + assert_file(registry, f"some/output.txt {hash(text)} {hash(text)}\n") + assert pystache_renderer.mock_calls == [ + mock.call.render_name(data.template, data, generator=paths.exe_file.relative_to(paths.swift_dir)), + ] + def test_managed_render_with_post_processing(pystache_renderer, sut): data = mock.Mock(spec=("template",)) diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index 098740a9329..5822256c11f 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -385,7 +385,7 @@ ql/lib/codeql/swift/generated/Synth.qll 90df85be365c89c3c2e22041ee7dc9dd2ad9194b ql/lib/codeql/swift/generated/SynthConstructors.qll 5c91f09bd82728651ed61f498704e0f62847788fa986dec5e674d81f294076c7 5c91f09bd82728651ed61f498704e0f62847788fa986dec5e674d81f294076c7 ql/lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 ql/lib/codeql/swift/generated/UnknownLocation.qll e50efefa02a0ec1ff635a00951b5924602fc8cab57e5756e4a039382c69d3882 e50efefa02a0ec1ff635a00951b5924602fc8cab57e5756e4a039382c69d3882 -ql/lib/codeql/swift/generated/UnspecifiedElement.qll dbc6ca4018012977b26ca184a88044c55b0661e3998cd14d46295b62a8d69625 184c9a0ce18c2ac881943b0fb400613d1401ed1d5564f90716b6c310ba5afe71 +ql/lib/codeql/swift/generated/UnspecifiedElement.qll a3a73f53c492adc6655fb88b40b1bd9b2c9d365fc5c019b3233c01d6110fb3f2 ba77cd5272cffd1d3aad8bea69786b97aec0c93a4b59a070d621fe2d21c2e90c ql/lib/codeql/swift/generated/decl/AbstractFunctionDecl.qll 8255b24dddda83e8a7dee9d69a4cf9883b5a7ae43676d7242b5aab5169f68982 407c7d63681fb03ad6cb4ea3c2b04be7ccb5ddbe655a8aec4219eb3799bc36e8 ql/lib/codeql/swift/generated/decl/AbstractStorageDecl.qll 66147ad36cefce974b4ae0f3e84569bd6742ea2f3e842c3c04e6e5cbd17e7928 ce7c2347e2dfe0b141db103ccb8e56a61d286476c201aebe6a275edd7fca2c0f ql/lib/codeql/swift/generated/decl/AbstractTypeParamDecl.qll 1e268b00d0f2dbbd85aa70ac206c5e4a4612f06ba0091e5253483635f486ccf9 5479e13e99f68f1f347283535f8098964f7fd4a34326ff36ad5711b2de1ab0d0 diff --git a/swift/ql/lib/codeql/swift/generated/UnspecifiedElement.qll b/swift/ql/lib/codeql/swift/generated/UnspecifiedElement.qll index c37d4d35515..2658e63164a 100644 --- a/swift/ql/lib/codeql/swift/generated/UnspecifiedElement.qll +++ b/swift/ql/lib/codeql/swift/generated/UnspecifiedElement.qll @@ -5,6 +5,9 @@ import codeql.swift.elements.Element import codeql.swift.elements.ErrorElement module Generated { + /** + * bla + */ class UnspecifiedElement extends Synth::TUnspecifiedElement, ErrorElement { override string getAPrimaryQlClass() { result = "UnspecifiedElement" } diff --git a/swift/schema.py b/swift/schema.py index 3162c1277e0..3148a43f67b 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -40,6 +40,7 @@ class ErrorElement(Locatable): @use_for_null class UnspecifiedElement(ErrorElement): + """bla""" parent: optional[Element] property: string index: optional[int] From bb3aa9e9082273cf747ec8d9e203d72167cc43f4 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 30 Nov 2022 14:11:24 +0100 Subject: [PATCH 733/796] Swift: add `--force` to `codegen` --- swift/codegen/codegen.py | 2 + swift/codegen/generators/qlgen.py | 3 +- swift/codegen/lib/render.py | 23 +++++-- swift/codegen/test/test_qlgen.py | 7 +- swift/codegen/test/test_render.py | 66 +++++++++++++++++++ swift/ql/.generated.list | 2 +- .../swift/generated/UnspecifiedElement.qll | 3 - swift/schema.py | 1 - 8 files changed, 92 insertions(+), 15 deletions(-) diff --git a/swift/codegen/codegen.py b/swift/codegen/codegen.py index b2da3678b1c..58160e9b998 100755 --- a/swift/codegen/codegen.py +++ b/swift/codegen/codegen.py @@ -42,6 +42,8 @@ def _parse_args() -> argparse.Namespace: help="output directory for generated C++ files, required if trap or cpp is provided to --generate") p.add_argument("--generated-registry", type=_abspath, default=paths.swift_dir / "ql/.generated.list", help="registry file containing information about checked-in generated code") + p.add_argument("--force", "-f", action="store_true", + help="generate all files without skipping unchanged files and overwriting modified ones") return p.parse_args() diff --git a/swift/codegen/generators/qlgen.py b/swift/codegen/generators/qlgen.py index c1650974796..b6b50498028 100755 --- a/swift/codegen/generators/qlgen.py +++ b/swift/codegen/generators/qlgen.py @@ -302,7 +302,8 @@ def generate(opts, renderer): imports = {} - with renderer.manage(generated=generated, stubs=stubs, registry=opts.generated_registry) as renderer: + with renderer.manage(generated=generated, stubs=stubs, registry=opts.generated_registry, + force=opts.force) as renderer: db_classes = [cls for cls in classes.values() if not cls.ipa] renderer.render(ql.DbClasses(db_classes), out / "Raw.qll") diff --git a/swift/codegen/lib/render.py b/swift/codegen/lib/render.py index 8294ecfda2b..65014a42fa2 100644 --- a/swift/codegen/lib/render.py +++ b/swift/codegen/lib/render.py @@ -59,8 +59,8 @@ class Renderer: log.debug(f"{mnemonic}: generated {output.name}") def manage(self, generated: typing.Iterable[pathlib.Path], stubs: typing.Iterable[pathlib.Path], - registry: pathlib.Path) -> "RenderManager": - return RenderManager(self._swift_dir, generated, stubs, registry) + registry: pathlib.Path, force: bool = False) -> "RenderManager": + return RenderManager(self._swift_dir, generated, stubs, registry, force) class RenderManager(Renderer): @@ -87,9 +87,10 @@ class RenderManager(Renderer): def __init__(self, swift_dir: pathlib.Path, generated: typing.Iterable[pathlib.Path], stubs: typing.Iterable[pathlib.Path], - registry: pathlib.Path): + registry: pathlib.Path, force: bool = False): super().__init__(swift_dir) self._registry_path = registry + self._force = force self._hashes = {} self.written = set() self._existing = set() @@ -132,10 +133,13 @@ class RenderManager(Renderer): for f in generated: self._existing.add(f) rel_path = self._get_path(f) - if rel_path not in self._hashes: + if self._force: + pass + elif rel_path not in self._hashes: log.warning(f"{rel_path} marked as generated but absent from the registry") elif self._hashes[rel_path].post != self._hash_file(f): - raise Error(f"{rel_path} is generated but was modified, please revert the file") + raise Error(f"{rel_path} is generated but was modified, please revert the file " + "or pass --force to overwrite") def _process_stubs(self, stubs: typing.Iterable[pathlib.Path]): for f in stubs: @@ -144,10 +148,13 @@ class RenderManager(Renderer): self._hashes.pop(rel_path, None) continue self._existing.add(f) - if rel_path not in self._hashes: + if self._force: + pass + elif rel_path not in self._hashes: log.warning(f"{rel_path} marked as stub but absent from the registry") elif self._hashes[rel_path].post != self._hash_file(f): - raise Error(f"{rel_path} is a stub marked as generated, but it was modified") + raise Error(f"{rel_path} is a stub marked as generated, but it was modified, " + "please remove the `// generated` header, revert the file or pass --force to overwrite it") @staticmethod def is_customized_stub(file: pathlib.Path) -> bool: @@ -171,6 +178,8 @@ class RenderManager(Renderer): return h.hexdigest() def _load_registry(self): + if self._force: + return try: with open(self._registry_path) as reg: for line in reg: diff --git a/swift/codegen/test/test_qlgen.py b/swift/codegen/test/test_qlgen.py index 0db445f07b9..3b2598ed8fd 100644 --- a/swift/codegen/test/test_qlgen.py +++ b/swift/codegen/test/test_qlgen.py @@ -48,6 +48,7 @@ def qlgen_opts(opts): opts.generated_registry = generated_registry_path() opts.ql_format = True opts.swift_dir = paths.swift_dir + opts.force = False return opts @@ -430,7 +431,9 @@ def test_format_error(opts, generate, render_manager, run_mock): generate([schema.Class('A')]) -def test_manage_parameters(opts, generate, renderer): +@pytest.mark.parametrize("force", [False, True]) +def test_manage_parameters(opts, generate, renderer, force): + opts.force = force ql_a = opts.ql_output / "A.qll" ql_b = opts.ql_output / "B.qll" stub_a = opts.ql_stub_output / "A.qll" @@ -448,7 +451,7 @@ def test_manage_parameters(opts, generate, renderer): generate([schema.Class('A')]) assert renderer.mock_calls == [ mock.call.manage(generated={ql_a, ql_b, test_a, test_b, import_file()}, stubs={stub_a, stub_b}, - registry=opts.generated_registry) + registry=opts.generated_registry, force=force) ] diff --git a/swift/codegen/test/test_render.py b/swift/codegen/test/test_render.py index cb249046b7b..950ca385e2f 100644 --- a/swift/codegen/test/test_render.py +++ b/swift/codegen/test/test_render.py @@ -75,6 +75,7 @@ def test_managed_render(pystache_renderer, sut): mock.call.render_name(data.template, data, generator=paths.exe_file.relative_to(paths.swift_dir)), ] + def test_managed_render_with_no_registry(pystache_renderer, sut): data = mock.Mock(spec=("template",)) text = "some text" @@ -266,5 +267,70 @@ def test_render_with_extensions(pystache_renderer, sut): assert_file(expected_output, expected_contents) +def test_managed_render_with_force_not_skipping_generated_file(pystache_renderer, sut): + data = mock.Mock(spec=("template",)) + output = paths.swift_dir / "some/output.txt" + some_output = "some output" + registry = paths.swift_dir / "a/registry.list" + write(output, some_output) + write(registry, f"some/output.txt {hash(some_output)} {hash(some_output)}\n") + + pystache_renderer.render_name.side_effect = (some_output,) + + with sut.manage(generated=(output,), stubs=(), registry=registry, force=True) as renderer: + renderer.render(data, output) + assert renderer.written == {output} + assert_file(output, some_output) + + assert_file(registry, f"some/output.txt {hash(some_output)} {hash(some_output)}\n") + assert pystache_renderer.mock_calls == [ + mock.call.render_name(data.template, data, generator=paths.exe_file.relative_to(paths.swift_dir)), + ] + + +def test_managed_render_with_force_not_skipping_stub_file(pystache_renderer, sut): + data = mock.Mock(spec=("template",)) + stub = paths.swift_dir / "some/stub.txt" + some_output = "// generated some output" + some_processed_output = "// generated some processed output" + registry = paths.swift_dir / "a/registry.list" + write(stub, some_processed_output) + write(registry, f"some/stub.txt {hash(some_output)} {hash(some_processed_output)}\n") + + pystache_renderer.render_name.side_effect = (some_output,) + + with sut.manage(generated=(), stubs=(stub,), registry=registry, force=True) as renderer: + renderer.render(data, stub) + assert renderer.written == {stub} + assert_file(stub, some_output) + + assert_file(registry, f"some/stub.txt {hash(some_output)} {hash(some_output)}\n") + assert pystache_renderer.mock_calls == [ + mock.call.render_name(data.template, data, generator=paths.exe_file.relative_to(paths.swift_dir)), + ] + + +def test_managed_render_with_force_ignores_modified_generated_file(sut): + output = paths.swift_dir / "some/output.txt" + some_processed_output = "// some processed output" + registry = paths.swift_dir / "a/registry.list" + write(output, "// something else") + write(registry, f"some/output.txt whatever {hash(some_processed_output)}\n") + + with sut.manage(generated=(output,), stubs=(), registry=registry, force=True): + pass + + +def test_managed_render_with_force_ignores_modified_stub_file_still_marked_as_generated(sut): + stub = paths.swift_dir / "some/stub.txt" + some_processed_output = "// generated some processed output" + registry = paths.swift_dir / "a/registry.list" + write(stub, "// generated something else") + write(registry, f"some/stub.txt whatever {hash(some_processed_output)}\n") + + with sut.manage(generated=(), stubs=(stub,), registry=registry, force=True): + pass + + if __name__ == '__main__': sys.exit(pytest.main([__file__] + sys.argv[1:])) diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index 5822256c11f..098740a9329 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -385,7 +385,7 @@ ql/lib/codeql/swift/generated/Synth.qll 90df85be365c89c3c2e22041ee7dc9dd2ad9194b ql/lib/codeql/swift/generated/SynthConstructors.qll 5c91f09bd82728651ed61f498704e0f62847788fa986dec5e674d81f294076c7 5c91f09bd82728651ed61f498704e0f62847788fa986dec5e674d81f294076c7 ql/lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 ql/lib/codeql/swift/generated/UnknownLocation.qll e50efefa02a0ec1ff635a00951b5924602fc8cab57e5756e4a039382c69d3882 e50efefa02a0ec1ff635a00951b5924602fc8cab57e5756e4a039382c69d3882 -ql/lib/codeql/swift/generated/UnspecifiedElement.qll a3a73f53c492adc6655fb88b40b1bd9b2c9d365fc5c019b3233c01d6110fb3f2 ba77cd5272cffd1d3aad8bea69786b97aec0c93a4b59a070d621fe2d21c2e90c +ql/lib/codeql/swift/generated/UnspecifiedElement.qll dbc6ca4018012977b26ca184a88044c55b0661e3998cd14d46295b62a8d69625 184c9a0ce18c2ac881943b0fb400613d1401ed1d5564f90716b6c310ba5afe71 ql/lib/codeql/swift/generated/decl/AbstractFunctionDecl.qll 8255b24dddda83e8a7dee9d69a4cf9883b5a7ae43676d7242b5aab5169f68982 407c7d63681fb03ad6cb4ea3c2b04be7ccb5ddbe655a8aec4219eb3799bc36e8 ql/lib/codeql/swift/generated/decl/AbstractStorageDecl.qll 66147ad36cefce974b4ae0f3e84569bd6742ea2f3e842c3c04e6e5cbd17e7928 ce7c2347e2dfe0b141db103ccb8e56a61d286476c201aebe6a275edd7fca2c0f ql/lib/codeql/swift/generated/decl/AbstractTypeParamDecl.qll 1e268b00d0f2dbbd85aa70ac206c5e4a4612f06ba0091e5253483635f486ccf9 5479e13e99f68f1f347283535f8098964f7fd4a34326ff36ad5711b2de1ab0d0 diff --git a/swift/ql/lib/codeql/swift/generated/UnspecifiedElement.qll b/swift/ql/lib/codeql/swift/generated/UnspecifiedElement.qll index 2658e63164a..c37d4d35515 100644 --- a/swift/ql/lib/codeql/swift/generated/UnspecifiedElement.qll +++ b/swift/ql/lib/codeql/swift/generated/UnspecifiedElement.qll @@ -5,9 +5,6 @@ import codeql.swift.elements.Element import codeql.swift.elements.ErrorElement module Generated { - /** - * bla - */ class UnspecifiedElement extends Synth::TUnspecifiedElement, ErrorElement { override string getAPrimaryQlClass() { result = "UnspecifiedElement" } diff --git a/swift/schema.py b/swift/schema.py index 3148a43f67b..3162c1277e0 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -40,7 +40,6 @@ class ErrorElement(Locatable): @use_for_null class UnspecifiedElement(ErrorElement): - """bla""" parent: optional[Element] property: string index: optional[int] From f6bc88471a968fe9c09a4f06dc785045fe24d771 Mon Sep 17 00:00:00 2001 From: Karim Ali Date: Wed, 30 Nov 2022 16:34:24 +0200 Subject: [PATCH 734/796] update the expected output for CWE-079 Now that we have support for taint through fields of String, we can now detect certain flows that we previously marked as [NOT DETECTED]. This commit updates the expected output of CWE-079 (and the in-code annotation of the accompanying test case) to reflect that update. --- .../CWE-079/UnsafeWebViewFetch.expected | 25 +++++++++++++++++++ .../Security/CWE-079/UnsafeWebViewFetch.swift | 4 +-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/swift/ql/test/query-tests/Security/CWE-079/UnsafeWebViewFetch.expected b/swift/ql/test/query-tests/Security/CWE-079/UnsafeWebViewFetch.expected index 66ef1d4cb4e..8f7d3cd0a9f 100644 --- a/swift/ql/test/query-tests/Security/CWE-079/UnsafeWebViewFetch.expected +++ b/swift/ql/test/query-tests/Security/CWE-079/UnsafeWebViewFetch.expected @@ -1,6 +1,7 @@ edges | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in init(string:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | +| UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | | UnsafeWebViewFetch.swift:94:10:94:37 | try ... : | UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | | UnsafeWebViewFetch.swift:94:10:94:37 | try ... : | UnsafeWebViewFetch.swift:120:25:120:39 | call to getRemoteData() | | UnsafeWebViewFetch.swift:94:10:94:37 | try ... : | UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | @@ -18,6 +19,7 @@ edges | UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:137:25:137:25 | remoteString | | UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:139:25:139:25 | remoteString | | UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:141:25:141:25 | remoteString | +| UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:150:24:150:37 | .utf8 : | | UnsafeWebViewFetch.swift:131:18:131:42 | call to init(string:) : | UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL : | | UnsafeWebViewFetch.swift:131:18:131:42 | call to init(string:) : | UnsafeWebViewFetch.swift:138:47:138:56 | ...! | | UnsafeWebViewFetch.swift:131:18:131:42 | call to init(string:) : | UnsafeWebViewFetch.swift:139:48:139:57 | ...! | @@ -29,6 +31,10 @@ edges | UnsafeWebViewFetch.swift:132:19:132:61 | call to init(string:relativeTo:) : | UnsafeWebViewFetch.swift:141:48:141:58 | ...! | | UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL : | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in init(string:relativeTo:) : | | UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL : | UnsafeWebViewFetch.swift:132:19:132:61 | call to init(string:relativeTo:) : | +| UnsafeWebViewFetch.swift:150:19:150:41 | call to init(_:) : | UnsafeWebViewFetch.swift:152:15:152:15 | remoteData | +| UnsafeWebViewFetch.swift:150:19:150:41 | call to init(_:) : | UnsafeWebViewFetch.swift:154:15:154:15 | remoteData | +| UnsafeWebViewFetch.swift:150:24:150:37 | .utf8 : | UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in init(_:) : | +| UnsafeWebViewFetch.swift:150:24:150:37 | .utf8 : | UnsafeWebViewFetch.swift:150:19:150:41 | call to init(_:) : | | UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:168:25:168:25 | remoteString | | UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:171:25:171:51 | ... .+(_:_:) ... | | UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:174:25:174:25 | "..." | @@ -37,6 +43,7 @@ edges | UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:184:25:184:25 | remoteString | | UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:186:25:186:25 | remoteString | | UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:188:25:188:25 | remoteString | +| UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:197:24:197:37 | .utf8 : | | UnsafeWebViewFetch.swift:178:18:178:42 | call to init(string:) : | UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL : | | UnsafeWebViewFetch.swift:178:18:178:42 | call to init(string:) : | UnsafeWebViewFetch.swift:185:47:185:56 | ...! | | UnsafeWebViewFetch.swift:178:18:178:42 | call to init(string:) : | UnsafeWebViewFetch.swift:186:48:186:57 | ...! | @@ -48,11 +55,16 @@ edges | UnsafeWebViewFetch.swift:179:19:179:61 | call to init(string:relativeTo:) : | UnsafeWebViewFetch.swift:188:48:188:58 | ...! | | UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL : | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in init(string:relativeTo:) : | | UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL : | UnsafeWebViewFetch.swift:179:19:179:61 | call to init(string:relativeTo:) : | +| UnsafeWebViewFetch.swift:197:19:197:41 | call to init(_:) : | UnsafeWebViewFetch.swift:199:15:199:15 | remoteData | +| UnsafeWebViewFetch.swift:197:19:197:41 | call to init(_:) : | UnsafeWebViewFetch.swift:201:15:201:15 | remoteData | +| UnsafeWebViewFetch.swift:197:24:197:37 | .utf8 : | UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in init(_:) : | +| UnsafeWebViewFetch.swift:197:24:197:37 | .utf8 : | UnsafeWebViewFetch.swift:197:19:197:41 | call to init(_:) : | | UnsafeWebViewFetch.swift:206:17:206:31 | call to getRemoteData() : | UnsafeWebViewFetch.swift:210:25:210:25 | htmlData | | UnsafeWebViewFetch.swift:206:17:206:31 | call to getRemoteData() : | UnsafeWebViewFetch.swift:211:25:211:25 | htmlData | nodes | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in init(string:) : | semmle.label | [summary param] 0 in init(string:) : | | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in init(string:relativeTo:) : | semmle.label | [summary param] 1 in init(string:relativeTo:) : | +| UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in init(_:) : | semmle.label | [summary param] 0 in init(_:) : | | UnsafeWebViewFetch.swift:94:10:94:37 | try ... : | semmle.label | try ... : | | UnsafeWebViewFetch.swift:94:14:94:37 | call to init(contentsOf:) : | semmle.label | call to init(contentsOf:) : | | UnsafeWebViewFetch.swift:103:25:103:84 | try! ... | semmle.label | try! ... | @@ -78,7 +90,11 @@ nodes | UnsafeWebViewFetch.swift:140:47:140:57 | ...! | semmle.label | ...! | | UnsafeWebViewFetch.swift:141:25:141:25 | remoteString | semmle.label | remoteString | | UnsafeWebViewFetch.swift:141:48:141:58 | ...! | semmle.label | ...! | +| UnsafeWebViewFetch.swift:150:19:150:41 | call to init(_:) : | semmle.label | call to init(_:) : | +| UnsafeWebViewFetch.swift:150:24:150:37 | .utf8 : | semmle.label | .utf8 : | +| UnsafeWebViewFetch.swift:152:15:152:15 | remoteData | semmle.label | remoteData | | UnsafeWebViewFetch.swift:153:85:153:94 | ...! | semmle.label | ...! | +| UnsafeWebViewFetch.swift:154:15:154:15 | remoteData | semmle.label | remoteData | | UnsafeWebViewFetch.swift:154:86:154:95 | ...! | semmle.label | ...! | | UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | semmle.label | call to getRemoteData() : | | UnsafeWebViewFetch.swift:167:25:167:39 | call to getRemoteData() | semmle.label | call to getRemoteData() | @@ -97,18 +113,25 @@ nodes | UnsafeWebViewFetch.swift:187:47:187:57 | ...! | semmle.label | ...! | | UnsafeWebViewFetch.swift:188:25:188:25 | remoteString | semmle.label | remoteString | | UnsafeWebViewFetch.swift:188:48:188:58 | ...! | semmle.label | ...! | +| UnsafeWebViewFetch.swift:197:19:197:41 | call to init(_:) : | semmle.label | call to init(_:) : | +| UnsafeWebViewFetch.swift:197:24:197:37 | .utf8 : | semmle.label | .utf8 : | +| UnsafeWebViewFetch.swift:199:15:199:15 | remoteData | semmle.label | remoteData | | UnsafeWebViewFetch.swift:200:90:200:99 | ...! | semmle.label | ...! | +| UnsafeWebViewFetch.swift:201:15:201:15 | remoteData | semmle.label | remoteData | | UnsafeWebViewFetch.swift:201:91:201:100 | ...! | semmle.label | ...! | | UnsafeWebViewFetch.swift:206:17:206:31 | call to getRemoteData() : | semmle.label | call to getRemoteData() : | | UnsafeWebViewFetch.swift:210:25:210:25 | htmlData | semmle.label | htmlData | | UnsafeWebViewFetch.swift:211:25:211:25 | htmlData | semmle.label | htmlData | +| file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | semmle.label | [summary] to write: return (return) in init(_:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | semmle.label | [summary] to write: return (return) in init(string:) : | | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | semmle.label | [summary] to write: return (return) in init(string:relativeTo:) : | subpaths | UnsafeWebViewFetch.swift:131:30:131:30 | remoteString : | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in init(string:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | UnsafeWebViewFetch.swift:131:18:131:42 | call to init(string:) : | | UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL : | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | UnsafeWebViewFetch.swift:132:19:132:61 | call to init(string:relativeTo:) : | +| UnsafeWebViewFetch.swift:150:24:150:37 | .utf8 : | UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | UnsafeWebViewFetch.swift:150:19:150:41 | call to init(_:) : | | UnsafeWebViewFetch.swift:178:30:178:30 | remoteString : | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in init(string:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | UnsafeWebViewFetch.swift:178:18:178:42 | call to init(string:) : | | UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL : | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | UnsafeWebViewFetch.swift:179:19:179:61 | call to init(string:relativeTo:) : | +| UnsafeWebViewFetch.swift:197:24:197:37 | .utf8 : | UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(_:) : | UnsafeWebViewFetch.swift:197:19:197:41 | call to init(_:) : | #select | UnsafeWebViewFetch.swift:103:25:103:84 | try! ... | UnsafeWebViewFetch.swift:103:30:103:84 | call to init(contentsOf:) : | UnsafeWebViewFetch.swift:103:25:103:84 | try! ... | Tainted data is used in a WebView fetch without restricting the base URL. | | UnsafeWebViewFetch.swift:106:25:106:25 | data | UnsafeWebViewFetch.swift:105:18:105:72 | call to init(contentsOf:) : | UnsafeWebViewFetch.swift:106:25:106:25 | data | Tainted data is used in a WebView fetch without restricting the base URL. | @@ -119,10 +142,12 @@ subpaths | UnsafeWebViewFetch.swift:127:25:127:25 | "..." | UnsafeWebViewFetch.swift:94:14:94:37 | call to init(contentsOf:) : | UnsafeWebViewFetch.swift:127:25:127:25 | "..." | Tainted data is used in a WebView fetch without restricting the base URL. | | UnsafeWebViewFetch.swift:139:25:139:25 | remoteString | UnsafeWebViewFetch.swift:94:14:94:37 | call to init(contentsOf:) : | UnsafeWebViewFetch.swift:139:25:139:25 | remoteString | Tainted data is used in a WebView fetch with a tainted base URL. | | UnsafeWebViewFetch.swift:141:25:141:25 | remoteString | UnsafeWebViewFetch.swift:94:14:94:37 | call to init(contentsOf:) : | UnsafeWebViewFetch.swift:141:25:141:25 | remoteString | Tainted data is used in a WebView fetch with a tainted base URL. | +| UnsafeWebViewFetch.swift:154:15:154:15 | remoteData | UnsafeWebViewFetch.swift:94:14:94:37 | call to init(contentsOf:) : | UnsafeWebViewFetch.swift:154:15:154:15 | remoteData | Tainted data is used in a WebView fetch with a tainted base URL. | | UnsafeWebViewFetch.swift:167:25:167:39 | call to getRemoteData() | UnsafeWebViewFetch.swift:94:14:94:37 | call to init(contentsOf:) : | UnsafeWebViewFetch.swift:167:25:167:39 | call to getRemoteData() | Tainted data is used in a WebView fetch without restricting the base URL. | | UnsafeWebViewFetch.swift:168:25:168:25 | remoteString | UnsafeWebViewFetch.swift:94:14:94:37 | call to init(contentsOf:) : | UnsafeWebViewFetch.swift:168:25:168:25 | remoteString | Tainted data is used in a WebView fetch without restricting the base URL. | | UnsafeWebViewFetch.swift:171:25:171:51 | ... .+(_:_:) ... | UnsafeWebViewFetch.swift:94:14:94:37 | call to init(contentsOf:) : | UnsafeWebViewFetch.swift:171:25:171:51 | ... .+(_:_:) ... | Tainted data is used in a WebView fetch without restricting the base URL. | | UnsafeWebViewFetch.swift:174:25:174:25 | "..." | UnsafeWebViewFetch.swift:94:14:94:37 | call to init(contentsOf:) : | UnsafeWebViewFetch.swift:174:25:174:25 | "..." | Tainted data is used in a WebView fetch without restricting the base URL. | | UnsafeWebViewFetch.swift:186:25:186:25 | remoteString | UnsafeWebViewFetch.swift:94:14:94:37 | call to init(contentsOf:) : | UnsafeWebViewFetch.swift:186:25:186:25 | remoteString | Tainted data is used in a WebView fetch with a tainted base URL. | | UnsafeWebViewFetch.swift:188:25:188:25 | remoteString | UnsafeWebViewFetch.swift:94:14:94:37 | call to init(contentsOf:) : | UnsafeWebViewFetch.swift:188:25:188:25 | remoteString | Tainted data is used in a WebView fetch with a tainted base URL. | +| UnsafeWebViewFetch.swift:201:15:201:15 | remoteData | UnsafeWebViewFetch.swift:94:14:94:37 | call to init(contentsOf:) : | UnsafeWebViewFetch.swift:201:15:201:15 | remoteData | Tainted data is used in a WebView fetch with a tainted base URL. | | UnsafeWebViewFetch.swift:210:25:210:25 | htmlData | UnsafeWebViewFetch.swift:94:14:94:37 | call to init(contentsOf:) : | UnsafeWebViewFetch.swift:210:25:210:25 | htmlData | Tainted data is used in a WebView fetch without restricting the base URL. | diff --git a/swift/ql/test/query-tests/Security/CWE-079/UnsafeWebViewFetch.swift b/swift/ql/test/query-tests/Security/CWE-079/UnsafeWebViewFetch.swift index 2555e23758d..1b687ade014 100644 --- a/swift/ql/test/query-tests/Security/CWE-079/UnsafeWebViewFetch.swift +++ b/swift/ql/test/query-tests/Security/CWE-079/UnsafeWebViewFetch.swift @@ -151,7 +151,7 @@ func testUIWebView() { webview.load(localData, mimeType: "text/html", textEncodingName: "utf-8", baseURL: localSafeURL!) // GOOD: the data is local webview.load(remoteData, mimeType: "text/html", textEncodingName: "utf-8", baseURL: localSafeURL!) // GOOD: a safe baseURL is specified webview.load(localData, mimeType: "text/html", textEncodingName: "utf-8", baseURL: remoteURL!) // GOOD: the HTML data is local - webview.load(remoteData, mimeType: "text/html", textEncodingName: "utf-8", baseURL: remoteURL!) // BAD [NOT DETECTED] + webview.load(remoteData, mimeType: "text/html", textEncodingName: "utf-8", baseURL: remoteURL!) // BAD } func testWKWebView() { @@ -198,7 +198,7 @@ func testWKWebView() { webview.load(localData, mimeType: "text/html", characterEncodingName: "utf-8", baseURL: localSafeURL!) // GOOD: the data is local webview.load(remoteData, mimeType: "text/html", characterEncodingName: "utf-8", baseURL: localSafeURL!) // GOOD: a safe baseURL is specified webview.load(localData, mimeType: "text/html", characterEncodingName: "utf-8", baseURL: remoteURL!) // GOOD: the HTML data is local - webview.load(remoteData, mimeType: "text/html", characterEncodingName: "utf-8", baseURL: remoteURL!) // BAD [NOT DETECTED] + webview.load(remoteData, mimeType: "text/html", characterEncodingName: "utf-8", baseURL: remoteURL!) // BAD } func testQHelpExamples() { From 0bfe502bb04ff075935e35752c684429183a5028 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Wed, 30 Nov 2022 15:12:55 +0100 Subject: [PATCH 735/796] Swift: remove patches from the extractor Moved elsewhere https://github.com/dsp-testing/codeql-swift-artifacts/pull/3 --- misc/bazel/workspace.bzl | 10 +++------- swift/extractor/infra/SwiftDispatcher.h | 11 ----------- .../patches/remove_getFallthrougDest_assert.patch | 11 ----------- 3 files changed, 3 insertions(+), 29 deletions(-) delete mode 100644 swift/third_party/swift-llvm-support/patches/remove_getFallthrougDest_assert.patch diff --git a/misc/bazel/workspace.bzl b/misc/bazel/workspace.bzl index df5995b499b..d0aee216668 100644 --- a/misc/bazel/workspace.bzl +++ b/misc/bazel/workspace.bzl @@ -1,10 +1,10 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") -_swift_prebuilt_version = "swift-5.7.1-RELEASE.44356.85" +_swift_prebuilt_version = "swift-5.7.1-RELEASE.44428.89" _swift_sha_map = { - "Linux-X64": "c9f17e13cac89f097aaaa65b1bc32aac566c8e4f3b68fc18e970cc3ee31f4913", - "macOS-X64": "638ac0552e9e1ccee9e276525d1ea9454256feec20bc778efa8856fd6e506987", + "Linux-X64": "1fa0b62b3a87c6528bd21b3f3fa1b32ad00e2b6ff04c20652c93c7d00c4cf517", + "macOS-X64": "6e1239335874cbde635ae9ca9eeb215efee4988888a75f4eda1abbcf97e4d038", } _swift_arch_map = { @@ -22,10 +22,6 @@ def codeql_workspace(repository_name = "codeql"): _swift_prebuilt_version, repo_arch, ), - patches = [ - "@%s//swift/third_party/swift-llvm-support:patches/remove_getFallthrougDest_assert.patch" % repository_name, - ], - patch_args = ["-p1"], build_file = "@%s//swift/third_party/swift-llvm-support:BUILD.swift-prebuilt.bazel" % repository_name, sha256 = sha256, ) diff --git a/swift/extractor/infra/SwiftDispatcher.h b/swift/extractor/infra/SwiftDispatcher.h index 0175bba1e6b..991511e300c 100644 --- a/swift/extractor/infra/SwiftDispatcher.h +++ b/swift/extractor/infra/SwiftDispatcher.h @@ -215,17 +215,6 @@ class SwiftDispatcher { // Emits a Location TRAP entry and attaches it to a `Locatable` trap label template void attachLocation(Locatable* locatable, TrapLabel locatableLabel) { - // Swift 5.7.1 causing a crash when the Swift compiler uses .back() of and empty - // getPatternList() when getting the source location. - // So far this only observed with the entities coming from precompiled modules, so they - // should not have locations anyway. - if constexpr (std::is_base_of::value) { - if (auto* decl = llvm::dyn_cast(locatable)) { - if (decl->getPatternList().empty()) { - return; - } - } - } attachLocation(locatable->getStartLoc(), locatable->getEndLoc(), locatableLabel); } diff --git a/swift/third_party/swift-llvm-support/patches/remove_getFallthrougDest_assert.patch b/swift/third_party/swift-llvm-support/patches/remove_getFallthrougDest_assert.patch deleted file mode 100644 index c16942a807c..00000000000 --- a/swift/third_party/swift-llvm-support/patches/remove_getFallthrougDest_assert.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -ru a/include/swift/AST/Stmt.h b/include/swift/AST/Stmt.h ---- a/include/swift/AST/Stmt.h 2022-09-21 12:56:54.000000000 +0200 -+++ b/include/swift/AST/Stmt.h 2022-11-04 14:39:18.407971007 +0100 -@@ -920,7 +920,6 @@ - /// Get the CaseStmt block to which the fallthrough transfers control. - /// Set during Sema. - CaseStmt *getFallthroughDest() const { -- assert(FallthroughDest && "fallthrough dest is not set until Sema"); - return FallthroughDest; - } - void setFallthroughDest(CaseStmt *C) { From cddc9db690cc7fe416af351825ad005c89de1e41 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 30 Nov 2022 15:46:46 +0100 Subject: [PATCH 736/796] change back to the old order of extracting externs before Xml --- javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java index 883b6efb859..445f1116ec7 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java +++ b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java @@ -447,10 +447,10 @@ public class AutoBuild { startThreadPool(); try { extractSource(); - extractXml(); if (hasSeenCode()) { // don't bother with the externs if no code was seen extractExterns(); } + extractXml(); } finally { shutdownThreadPool(); } From d958a62bf20d6c2ab203fe186944066ad51f49f2 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Wed, 30 Nov 2022 16:19:55 +0100 Subject: [PATCH 737/796] Fix expectations in data.swift --- .../ql/test/library-tests/dataflow/taint/TaintInline.expected | 2 -- swift/ql/test/library-tests/dataflow/taint/data.swift | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/swift/ql/test/library-tests/dataflow/taint/TaintInline.expected b/swift/ql/test/library-tests/dataflow/taint/TaintInline.expected index 3e49fbfe3af..e69de29bb2d 100644 --- a/swift/ql/test/library-tests/dataflow/taint/TaintInline.expected +++ b/swift/ql/test/library-tests/dataflow/taint/TaintInline.expected @@ -1,2 +0,0 @@ -| data.swift:85:12:85:12 | dataTainted | Fixed missing result:tainted=81 | -| data.swift:86:12:86:12 | dataTainted2 | Fixed missing result:tainted=81 | \ No newline at end of file diff --git a/swift/ql/test/library-tests/dataflow/taint/data.swift b/swift/ql/test/library-tests/dataflow/taint/data.swift index 2fdc4e1c949..d4a5178a9bd 100644 --- a/swift/ql/test/library-tests/dataflow/taint/data.swift +++ b/swift/ql/test/library-tests/dataflow/taint/data.swift @@ -82,8 +82,8 @@ func taintThroughData() { let dataTainted2 = Data(dataTainted) sink(arg: dataClean) - sink(arg: dataTainted) // $ MISSING: tainted=81 - sink(arg: dataTainted2) // $ MISSING: tainted=81 + sink(arg: dataTainted) // $ tainted=81 + sink(arg: dataTainted2) // $ tainted=81 // ";Data;true;init(base64Encoded:options:);;;Argument[0];ReturnValue;taint", let dataTainted3 = Data(base64Encoded: source() as! Data, options: []) From 4e29ff1d6e52b2ea5047a75f2a8f804c05d31cd1 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 30 Nov 2022 17:42:26 +0100 Subject: [PATCH 738/796] Swift: add `-merge-modules` to `frontend-invocations` test Also, moved from Makefile to a bash source. --- swift/integration-tests/.gitignore | 1 + .../posix-only/frontend-invocations/F1.swift | 0 .../posix-only/frontend-invocations/F2.swift | 0 .../frontend-invocations/Files.expected | 2 ++ .../posix-only/frontend-invocations/Makefile | 15 --------------- .../posix-only/frontend-invocations/build.sh | 18 ++++++++++++++++++ .../posix-only/frontend-invocations/test.py | 2 +- 7 files changed, 22 insertions(+), 16 deletions(-) create mode 100644 swift/integration-tests/posix-only/frontend-invocations/F1.swift create mode 100644 swift/integration-tests/posix-only/frontend-invocations/F2.swift delete mode 100644 swift/integration-tests/posix-only/frontend-invocations/Makefile create mode 100755 swift/integration-tests/posix-only/frontend-invocations/build.sh diff --git a/swift/integration-tests/.gitignore b/swift/integration-tests/.gitignore index 9ea4244ad91..b613644a5ae 100644 --- a/swift/integration-tests/.gitignore +++ b/swift/integration-tests/.gitignore @@ -7,3 +7,4 @@ DerivedData/ .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata *.actual db +*.swiftmodule diff --git a/swift/integration-tests/posix-only/frontend-invocations/F1.swift b/swift/integration-tests/posix-only/frontend-invocations/F1.swift new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/integration-tests/posix-only/frontend-invocations/F2.swift b/swift/integration-tests/posix-only/frontend-invocations/F2.swift new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/integration-tests/posix-only/frontend-invocations/Files.expected b/swift/integration-tests/posix-only/frontend-invocations/Files.expected index 319c1010ab4..f13e45d89a5 100644 --- a/swift/integration-tests/posix-only/frontend-invocations/Files.expected +++ b/swift/integration-tests/posix-only/frontend-invocations/Files.expected @@ -3,4 +3,6 @@ | C.swift:0:0:0:0 | C.swift | | D.swift:0:0:0:0 | D.swift | | E.swift:0:0:0:0 | E.swift | +| F1.swift:0:0:0:0 | F1.swift | +| F2.swift:0:0:0:0 | F2.swift | | file://:0:0:0:0 | | diff --git a/swift/integration-tests/posix-only/frontend-invocations/Makefile b/swift/integration-tests/posix-only/frontend-invocations/Makefile deleted file mode 100644 index d3ddece6b9f..00000000000 --- a/swift/integration-tests/posix-only/frontend-invocations/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -OS=$(shell uname) -ifeq ($(OS),Darwin) -SDK=-sdk $(shell xcrun -show-sdk-path) -FRONTEND=$(shell xcrun -find swift-frontend) -else -SDK="" -FRONTEND=swiftc -endif - -all: - $(FRONTEND) -frontend -c A.swift $(SDK) - $(FRONTEND) -frontend -c B.swift -o B.o $(SDK) - $(FRONTEND) -frontend -c -primary-file C.swift $(SDK) - $(FRONTEND) -frontend -c -primary-file D.swift -o D.o $(SDK) - $(FRONTEND) -frontend -c -primary-file E.swift Esup.swift -o E.o $(SDK) diff --git a/swift/integration-tests/posix-only/frontend-invocations/build.sh b/swift/integration-tests/posix-only/frontend-invocations/build.sh new file mode 100755 index 00000000000..03f1148ca05 --- /dev/null +++ b/swift/integration-tests/posix-only/frontend-invocations/build.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +if [[ "$(uname)" == Darwin ]]; then + SDK="-sdk $(xcrun -show-sdk-path)" + FRONTEND="$(xcrun -find swift-frontend)" +else + SDK="" + FRONTEND="swift-frontend" +fi + +$FRONTEND -frontend -c A.swift $SDK +$FRONTEND -frontend -c B.swift -o B.o $SDK +$FRONTEND -frontend -c -primary-file C.swift $SDK +$FRONTEND -frontend -c -primary-file D.swift -o D.o $SDK +$FRONTEND -frontend -c -primary-file E.swift Esup.swift -o E.o $SDK +$FRONTEND -frontend -emit-module -primary-file F1.swift F2.swift -module-name F -o F1.swiftmodule $SDK +$FRONTEND -frontend -emit-module F1.swift -primary-file F2.swift -module-name F -o F2.swiftmodule $SDK +$FRONTEND -merge-modules F1.swiftmodule F2.swiftmodule -o F.swiftmodule $SDK diff --git a/swift/integration-tests/posix-only/frontend-invocations/test.py b/swift/integration-tests/posix-only/frontend-invocations/test.py index b415c024e56..4aec427a4b4 100644 --- a/swift/integration-tests/posix-only/frontend-invocations/test.py +++ b/swift/integration-tests/posix-only/frontend-invocations/test.py @@ -1,5 +1,5 @@ from create_database_utils import * run_codeql_database_create([ - 'make', + './build.sh', ], lang='swift') From cd8c40e063832adfc7b22eebf6a143c43321540f Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Fri, 25 Nov 2022 17:10:03 +0000 Subject: [PATCH 739/796] Kotlin: Enable java/non-serializable-field for Kotlin It now ignores compiler-generated classes --- java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql | 4 +++- .../change-notes/2022-11-25-NonSerializableField-kotlin.md | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 java/ql/src/change-notes/2022-11-25-NonSerializableField-kotlin.md diff --git a/java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql b/java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql index bf00248720c..a39e29f6576 100644 --- a/java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql +++ b/java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql @@ -55,6 +55,8 @@ string nonSerialReason(RefType t) { predicate exceptions(Class c, Field f) { f.getDeclaringType() = c and ( + c.isCompilerGenerated() + or // `Serializable` objects with custom `readObject` or `writeObject` methods // may write out the "non-serializable" fields in a different way. c.declaresMethod("readObject") @@ -90,7 +92,7 @@ predicate exceptions(Class c, Field f) { from Class c, Field f, string reason where - c.getFile().isJavaSourceFile() and + c.fromSource() and c.getAStrictAncestor() instanceof TypeSerializable and f.getDeclaringType() = c and not exceptions(c, f) and diff --git a/java/ql/src/change-notes/2022-11-25-NonSerializableField-kotlin.md b/java/ql/src/change-notes/2022-11-25-NonSerializableField-kotlin.md new file mode 100644 index 00000000000..25977b2e807 --- /dev/null +++ b/java/ql/src/change-notes/2022-11-25-NonSerializableField-kotlin.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The query `java/non-serializable-field` is now enabled for Kotlin. From 91421528df892f756ad14b04454e0b1faeb75e45 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Thu, 1 Dec 2022 09:01:03 +1300 Subject: [PATCH 740/796] Ruby: Update test --- ruby/ql/test/library-tests/dataflow/local/TaintStep.expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected index fe75f1b0313..a2f7ed05c86 100644 --- a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected +++ b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected @@ -23,7 +23,7 @@ | file://:0:0:0:0 | parameter position 0 of activesupport;;Member[ActionView].Member[SafeBuffer].Method[new] | file://:0:0:0:0 | [summary] to write: return (return) in activesupport;;Member[ActionView].Member[SafeBuffer].Method[new] | | file://:0:0:0:0 | parameter position 0 of activesupport;;Member[ActiveSupport].Member[JSON].Method[decode,load] | file://:0:0:0:0 | [summary] to write: return (return) in activesupport;;Member[ActiveSupport].Member[JSON].Method[decode,load] | | file://:0:0:0:0 | parameter position 0 of activesupport;;Member[ActiveSupport].Member[JSON].Method[encode,dump] | file://:0:0:0:0 | [summary] to write: return (return) in activesupport;;Member[ActiveSupport].Member[JSON].Method[encode,dump] | -| file://:0:0:0:0 | parameter position 0 of json;;Member[JSON].Method[generate,fast_generate,dump,unparse,fast_unparse] | file://:0:0:0:0 | [summary] to write: return (return) in json;;Member[JSON].Method[generate,fast_generate,dump,unparse,fast_unparse] | +| file://:0:0:0:0 | parameter position 0 of json;;Member[JSON].Method[generate,fast_generate,pretty_generate,dump,unparse,fast_unparse] | file://:0:0:0:0 | [summary] to write: return (return) in json;;Member[JSON].Method[generate,fast_generate,pretty_generate,dump,unparse,fast_unparse] | | file://:0:0:0:0 | parameter position 0 of json;;Member[JSON].Method[parse,parse!,load,restore] | file://:0:0:0:0 | [summary] to write: return (return) in json;;Member[JSON].Method[parse,parse!,load,restore] | | file://:0:0:0:0 | parameter position 0.. of File.join | file://:0:0:0:0 | [summary] to write: return (return) in File.join | | file://:0:0:0:0 | parameter self of & | file://:0:0:0:0 | [summary] read: argument self.any element in & | From 210d8529b6f022f2452c34f6768e80e28154a8d5 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Tue, 29 Nov 2022 19:09:29 -0500 Subject: [PATCH 741/796] add query for SupportedExternalApis --- .../ql/src/Telemetry/SupportedExternalApis.ql | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 java/ql/src/Telemetry/SupportedExternalApis.ql diff --git a/java/ql/src/Telemetry/SupportedExternalApis.ql b/java/ql/src/Telemetry/SupportedExternalApis.ql new file mode 100644 index 00000000000..2e1baebd60f --- /dev/null +++ b/java/ql/src/Telemetry/SupportedExternalApis.ql @@ -0,0 +1,24 @@ +/** + * @name Usage of supported APIs coming from external libraries + * @description A list of supported 3rd party APIs used in the codebase. Excludes test and generated code. + * @kind metric + * @tags summary telemetry + * @id java/telemetry/supported-external-api + */ + +import java +import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl +import semmle.code.java.dataflow.internal.NegativeSummary +import ExternalApi + +private predicate relevant(ExternalApi api) { + not api.isUninteresting() and + ( + api.isSupported() or + api = any(FlowSummaryImpl::Public::NegativeSummarizedCallable nsc).asCallable() + ) +} + +from string apiName, int usages +where Results::restrict(apiName, usages) +select apiName, usages order by usages desc From 7f45e320d88eb8f92307490dccd9310937881496 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Tue, 29 Nov 2022 20:16:29 -0500 Subject: [PATCH 742/796] add tests --- .../SupportedExternalApis.expected | 3 +++ .../SupportedExternalApis.java | 16 ++++++++++++++++ .../SupportedExternalApis.qlref | 1 + 3 files changed, 20 insertions(+) create mode 100644 java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected create mode 100644 java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java create mode 100644 java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected new file mode 100644 index 00000000000..ce4b3dbe87a --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected @@ -0,0 +1,3 @@ +| java.lang.StringBuilder#append(String) | 1 | +| java.lang.StringBuilder#toString() | 1 | +| java.util.Map#put(Object,Object) | 1 | diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java new file mode 100644 index 00000000000..34b56d5412e --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java @@ -0,0 +1,16 @@ +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; + +class SupportedExternalApis { + public static void main(String[] args) throws Exception { + StringBuilder builder = new StringBuilder(); + builder.append("foo"); // supported + builder.toString(); // supported + + Map map = new HashMap<>(); + map.put("foo", new Object()); // supported + + Duration d = java.time.Duration.ofMillis(1000); // not supported + } +} diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref new file mode 100644 index 00000000000..2e12499cf62 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref @@ -0,0 +1 @@ +Telemetry/SupportedExternalApis.ql From 22c4d975adc7e9da87fc1b762095a8fe6bcc7e43 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Wed, 30 Nov 2022 18:03:57 -0500 Subject: [PATCH 743/796] remove old import --- java/ql/src/Telemetry/SupportedExternalApis.ql | 1 - 1 file changed, 1 deletion(-) diff --git a/java/ql/src/Telemetry/SupportedExternalApis.ql b/java/ql/src/Telemetry/SupportedExternalApis.ql index 2e1baebd60f..13c6473b580 100644 --- a/java/ql/src/Telemetry/SupportedExternalApis.ql +++ b/java/ql/src/Telemetry/SupportedExternalApis.ql @@ -8,7 +8,6 @@ import java import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl -import semmle.code.java.dataflow.internal.NegativeSummary import ExternalApi private predicate relevant(ExternalApi api) { From 94c5d53192139ba36c907519c6f6aed0c8511f53 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Wed, 30 Nov 2022 18:51:05 -0500 Subject: [PATCH 744/796] add a couple more tests --- .../SupportedExternalApis.expected | 6 ++++++ .../SupportedExternalApis.java | 20 ++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected index ce4b3dbe87a..6abe5a43232 100644 --- a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected @@ -1,3 +1,9 @@ +| java.net.URL#URL(String) | 2 | +| java.io.File#File(String) | 1 | +| java.io.FileWriter#FileWriter(File) | 1 | | java.lang.StringBuilder#append(String) | 1 | | java.lang.StringBuilder#toString() | 1 | +| java.net.URL#openConnection() | 1 | +| java.net.URL#openStream() | 1 | +| java.net.URLConnection#getInputStream() | 1 | | java.util.Map#put(Object,Object) | 1 | diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java index 34b56d5412e..ec05018fd21 100644 --- a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java @@ -1,16 +1,26 @@ import java.time.Duration; import java.util.HashMap; import java.util.Map; +import java.io.InputStream; +import java.net.URL; +import java.io.File; +import java.io.FileWriter; class SupportedExternalApis { public static void main(String[] args) throws Exception { - StringBuilder builder = new StringBuilder(); - builder.append("foo"); // supported - builder.toString(); // supported + StringBuilder builder = new StringBuilder(); // uninteresting (parameterless constructor) + builder.append("foo"); // supported summary + builder.toString(); // supported summary - Map map = new HashMap<>(); - map.put("foo", new Object()); // supported + Map map = new HashMap<>(); // uninteresting (parameterless constructor) + map.put("foo", new Object()); // supported summary Duration d = java.time.Duration.ofMillis(1000); // not supported + + URL github = new URL("https://www.github.com/"); // supported summary + InputStream stream = github.openConnection().getInputStream(); // supported source (getInputStream), supported sink (openConnection) + + new FileWriter(new File("foo")); // supported sink (FileWriter), supported summary (File) + new URL("http://foo").openStream(); // supported sink (openStream), supported summary (URL) } } From a0a742eb82ece5c66464558d2ab2ba2dee57ff52 Mon Sep 17 00:00:00 2001 From: tiferet Date: Wed, 30 Nov 2022 17:01:56 -0800 Subject: [PATCH 745/796] Rename predicates to fit style guide: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `getEndpoints` → `appliesToEndpoint` - `getImplications` → `hasImplications` - `getAlerts` → `hasAlert` --- .../adaptivethreatmodeling/ATMConfig.qll | 12 +- .../EndpointCharacteristics.qll | 128 +++++++++--------- .../ExtractEndpointDataTraining.qll | 24 ++-- .../src/NosqlInjectionATM.ql | 2 +- .../src/SqlInjectionATM.ql | 2 +- .../src/TaintedPathATM.ql | 2 +- .../adaptivethreatmodeling/src/XssATM.ql | 2 +- .../endpoint_large_scale/EndpointFeatures.ql | 2 +- 8 files changed, 87 insertions(+), 87 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index 9f8c066f424..b4a92bf1010 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -63,9 +63,9 @@ abstract class AtmConfig extends JS::TaintTracking::Configuration { // If the list of characteristics includes positive indicators with maximal confidence for this class, then it's a // known sink for the class. exists(EndpointCharacteristics::EndpointCharacteristic characteristic | - characteristic.getEndpoints(sink) and + characteristic.appliesToEndpoint(sink) and characteristic - .getImplications(this.getASinkEndpointType(), true, characteristic.maximalConfidence()) + .hasImplications(this.getASinkEndpointType(), true, characteristic.maximalConfidence()) ) } @@ -99,7 +99,7 @@ abstract class AtmConfig extends JS::TaintTracking::Configuration { // have given the endpoint filter characteristics medium confidence, and we exclude endpoints that have a // medium-confidence characteristic that indicates that they are not sinks, either in general or for this sink type. exists(EndpointCharacteristics::EndpointCharacteristic filter, float confidence | - filter.getEndpoints(candidateSink) and + filter.appliesToEndpoint(candidateSink) and confidence >= filter.mediumConfidence() and // TODO: Experiment with excluding all endpoints that have a medium- or high-confidence characteristic that // implies they're not sinks, rather than using only medium-confidence characteristics, by deleting the following @@ -107,10 +107,10 @@ abstract class AtmConfig extends JS::TaintTracking::Configuration { confidence < filter.highConfidence() and ( // Exclude endpoints that have a characteristic that implies they're not sinks for _any_ sink type. - filter.getImplications(any(NegativeType negative), true, confidence) + filter.hasImplications(any(NegativeType negative), true, confidence) or // Exclude endpoints that have a characteristic that implies they're not sinks for _this particular_ sink type. - filter.getImplications(this.getASinkEndpointType(), false, confidence) + filter.hasImplications(this.getASinkEndpointType(), false, confidence) ) and result = filter ) @@ -147,7 +147,7 @@ abstract class AtmConfig extends JS::TaintTracking::Configuration { * to this ML-boosted configuration, whereas the unboosted base query does not contain this source and sink * combination. */ - predicate getAlerts(JS::DataFlow::PathNode source, JS::DataFlow::PathNode sink, float score) { + predicate hasAlert(JS::DataFlow::PathNode source, JS::DataFlow::PathNode sink, float score) { this.hasFlowPath(source, sink) and not AtmResultsInfo::isFlowLikelyInBaseQuery(source.getNode(), sink.getNode()) and score = AtmResultsInfo::getScoreForFlow(source.getNode(), sink.getNode()) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index 74a5ca6256d..e95b2785ceb 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -65,7 +65,7 @@ abstract class EndpointCharacteristic extends string { * Holds for endpoints that have this characteristic. This predicate contains the logic that applies characteristics * to the appropriate set of dataflow nodes. */ - abstract predicate getEndpoints(DataFlow::Node n); + abstract predicate appliesToEndpoint(DataFlow::Node n); /** * This predicate describes what the characteristic tells us about an endpoint. @@ -81,7 +81,7 @@ abstract class EndpointCharacteristic extends string { * indicator of whether or not the endpoint belongs to the class. A confidence of 1 means that all endpoints with * this characteristic definitively do/don't belong to the class. */ - abstract predicate getImplications( + abstract predicate hasImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ); @@ -213,9 +213,9 @@ DataFlow::CallNode getALikelyExternalLibraryCall() { result = getACallWithoutCal private class DomBasedXssSinkCharacteristic extends EndpointCharacteristic { DomBasedXssSinkCharacteristic() { this = "DomBasedXssSink" } - override predicate getEndpoints(DataFlow::Node n) { n instanceof DomBasedXss::Sink } + override predicate appliesToEndpoint(DataFlow::Node n) { n instanceof DomBasedXss::Sink } - override predicate getImplications( + override predicate hasImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { endpointClass instanceof XssSinkType and @@ -231,9 +231,9 @@ private class DomBasedXssSinkCharacteristic extends EndpointCharacteristic { private class TaintedPathSinkCharacteristic extends EndpointCharacteristic { TaintedPathSinkCharacteristic() { this = "TaintedPathSink" } - override predicate getEndpoints(DataFlow::Node n) { n instanceof TaintedPath::Sink } + override predicate appliesToEndpoint(DataFlow::Node n) { n instanceof TaintedPath::Sink } - override predicate getImplications( + override predicate hasImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { endpointClass instanceof TaintedPathSinkType and @@ -249,9 +249,9 @@ private class TaintedPathSinkCharacteristic extends EndpointCharacteristic { private class SqlInjectionSinkCharacteristic extends EndpointCharacteristic { SqlInjectionSinkCharacteristic() { this = "SqlInjectionSink" } - override predicate getEndpoints(DataFlow::Node n) { n instanceof SqlInjection::Sink } + override predicate appliesToEndpoint(DataFlow::Node n) { n instanceof SqlInjection::Sink } - override predicate getImplications( + override predicate hasImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { endpointClass instanceof SqlInjectionSinkType and @@ -267,9 +267,9 @@ private class SqlInjectionSinkCharacteristic extends EndpointCharacteristic { private class NosqlInjectionSinkCharacteristic extends EndpointCharacteristic { NosqlInjectionSinkCharacteristic() { this = "NosqlInjectionSink" } - override predicate getEndpoints(DataFlow::Node n) { n instanceof NosqlInjection::Sink } + override predicate appliesToEndpoint(DataFlow::Node n) { n instanceof NosqlInjection::Sink } - override predicate getImplications( + override predicate hasImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { endpointClass instanceof NosqlInjectionSinkType and @@ -307,7 +307,7 @@ abstract private class NotASinkCharacteristic extends EndpointCharacteristic { bindingset[this] NotASinkCharacteristic() { any() } - override predicate getImplications( + override predicate hasImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { endpointClass instanceof NegativeType and @@ -326,7 +326,7 @@ abstract class LikelyNotASinkCharacteristic extends EndpointCharacteristic { bindingset[this] LikelyNotASinkCharacteristic() { any() } - override predicate getImplications( + override predicate hasImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { endpointClass instanceof NegativeType and @@ -339,7 +339,7 @@ private class LodashUnderscoreCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { LodashUnderscoreCharacteristic() { this = "LodashUnderscoreArgument" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { any(LodashUnderscore::Member m).getACall().getAnArgument() = n } } @@ -348,7 +348,7 @@ private class JQueryArgumentCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { JQueryArgumentCharacteristic() { this = "JQueryArgument" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { any(JQuery::MethodCall m).getAnArgument() = n } } @@ -357,7 +357,7 @@ private class ClientRequestCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { ClientRequestCharacteristic() { this = "ClientRequest" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(ClientRequest r | r.getAnArgument() = n or n = r.getUrl() or n = r.getHost() or n = r.getADataNode() ) @@ -368,7 +368,7 @@ private class PromiseDefinitionCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { PromiseDefinitionCharacteristic() { this = "PromiseDefinition" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(PromiseDefinition p | n = [p.getResolveParameter(), p.getRejectParameter()].getACall().getAnArgument() ) @@ -379,14 +379,14 @@ private class CryptographicKeyCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { CryptographicKeyCharacteristic() { this = "CryptographicKey" } - override predicate getEndpoints(DataFlow::Node n) { n instanceof CryptographicKey } + override predicate appliesToEndpoint(DataFlow::Node n) { n instanceof CryptographicKey } } private class CryptographicOperationFlowCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { CryptographicOperationFlowCharacteristic() { this = "CryptographicOperationFlow" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { any(CryptographicOperation op).getInput() = n } } @@ -395,7 +395,7 @@ private class LoggerMethodCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { LoggerMethodCharacteristic() { this = "LoggerMethod" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | call.getCalleeName() = getAStandardLoggerMethodName() ) @@ -406,7 +406,7 @@ private class TimeoutCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { TimeoutCharacteristic() { this = "Timeout" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | call.getCalleeName() = ["setTimeout", "clearTimeout"] ) @@ -417,7 +417,7 @@ private class ReceiverStorageCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { ReceiverStorageCharacteristic() { this = "ReceiverStorage" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | call.getReceiver() = DataFlow::globalVarRef(["localStorage", "sessionStorage"]) ) @@ -428,7 +428,7 @@ private class StringStartsWithCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { StringStartsWithCharacteristic() { this = "StringStartsWith" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | call instanceof StringOps::StartsWith ) @@ -439,7 +439,7 @@ private class StringEndsWithCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { StringEndsWithCharacteristic() { this = "StringEndsWith" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | call instanceof StringOps::EndsWith) } } @@ -448,7 +448,7 @@ private class StringRegExpTestCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { StringRegExpTestCharacteristic() { this = "StringRegExpTest" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | call instanceof StringOps::RegExpTest ) @@ -459,7 +459,7 @@ private class EventRegistrationCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { EventRegistrationCharacteristic() { this = "EventRegistration" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | call instanceof EventRegistration) } } @@ -468,7 +468,7 @@ private class EventDispatchCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { EventDispatchCharacteristic() { this = "EventDispatch" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | call instanceof EventDispatch) } } @@ -477,7 +477,7 @@ private class MembershipCandidateTestCharacteristic extends NotASinkCharacterist OtherModeledArgumentCharacteristic { MembershipCandidateTestCharacteristic() { this = "MembershipCandidateTest" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | call = any(MembershipCandidate c).getTest() ) @@ -488,7 +488,7 @@ private class FileSystemAccessCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { FileSystemAccessCharacteristic() { this = "FileSystemAccess" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | call instanceof FileSystemAccess) } } @@ -497,7 +497,7 @@ private class DatabaseAccessCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { DatabaseAccessCharacteristic() { this = "DatabaseAccess" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { // TODO database accesses are less well defined than database query sinks, so this may cover unmodeled sinks on // existing database models exists(DataFlow::CallNode call | n = call.getAnArgument() | @@ -512,7 +512,7 @@ private class DatabaseAccessCharacteristic extends NotASinkCharacteristic, private class DomCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { DomCharacteristic() { this = "DOM" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | call = DOM::domValueRef()) } } @@ -521,7 +521,7 @@ private class NextFunctionCallCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { NextFunctionCallCharacteristic() { this = "NextFunctionCall" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | call.getCalleeName() = "next" and exists(DataFlow::FunctionNode f | call = f.getLastParameter().getACall()) @@ -533,7 +533,7 @@ private class DojoRequireCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { DojoRequireCharacteristic() { this = "DojoRequire" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | call = DataFlow::globalVarRef("dojo").getAPropertyRead("require").getACall() ) @@ -544,7 +544,7 @@ private class Base64ManipulationCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { Base64ManipulationCharacteristic() { this = "Base64Manipulation" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(Base64::Decode d | n = d.getInput()) or exists(Base64::Encode d | n = d.getInput()) } @@ -554,7 +554,7 @@ private class ArgumentToArrayCharacteristic extends ArgumentToBuiltinFunctionCha LikelyNotASinkCharacteristic { ArgumentToArrayCharacteristic() { this = "ArgumentToArray" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::SourceNode builtin, DataFlow::SourceNode receiver, DataFlow::InvokeNode invk | builtin instanceof DataFlow::ArrayCreationNode | @@ -569,7 +569,7 @@ private class ArgumentToBuiltinGlobalVarRefCharacteristic extends ArgumentToBuil LikelyNotASinkCharacteristic { ArgumentToBuiltinGlobalVarRefCharacteristic() { this = "ArgumentToBuiltinGlobalVarRef" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::SourceNode builtin, DataFlow::SourceNode receiver, DataFlow::InvokeNode invk | builtin = DataFlow::globalVarRef([ @@ -588,7 +588,7 @@ private class ConstantReceiverCharacteristic extends ArgumentToBuiltinFunctionCh NotASinkCharacteristic { ConstantReceiverCharacteristic() { this = "ConstantReceiver" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(Expr primitive, MethodCallExpr c | primitive instanceof ConstantString or primitive instanceof NumberLiteral or @@ -604,7 +604,7 @@ private class BuiltinCallNameCharacteristic extends ArgumentToBuiltinFunctionCha NotASinkCharacteristic { BuiltinCallNameCharacteristic() { this = "BuiltinCallName" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | call.getAnArgument() = n and call.getCalleeName() = @@ -633,7 +633,7 @@ abstract private class StandardEndpointFilterCharacteristic extends EndpointFilt bindingset[this] StandardEndpointFilterCharacteristic() { any() } - override predicate getImplications( + override predicate hasImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { endpointClass instanceof NegativeType and @@ -645,7 +645,7 @@ abstract private class StandardEndpointFilterCharacteristic extends EndpointFilt class IsArgumentToModeledFunctionCharacteristic extends StandardEndpointFilterCharacteristic { IsArgumentToModeledFunctionCharacteristic() { this = "argument to modeled function" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::InvokeNode invk, DataFlow::Node known | invk.getAnArgument() = n and invk.getAnArgument() = known and @@ -655,7 +655,7 @@ class IsArgumentToModeledFunctionCharacteristic extends StandardEndpointFilterCh isKnownStepSrc(known) or exists(OtherModeledArgumentCharacteristic characteristic | - characteristic.getEndpoints(known) + characteristic.appliesToEndpoint(known) ) ) ) @@ -665,7 +665,7 @@ class IsArgumentToModeledFunctionCharacteristic extends StandardEndpointFilterCh private class IsArgumentToSinklessLibraryCharacteristic extends StandardEndpointFilterCharacteristic { IsArgumentToSinklessLibraryCharacteristic() { this = "argument to sinkless library" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::InvokeNode invk, DataFlow::SourceNode commonSafeLibrary, string libraryName | libraryName = ["slugify", "striptags", "marked"] | @@ -679,7 +679,7 @@ private class IsArgumentToSinklessLibraryCharacteristic extends StandardEndpoint private class IsSanitizerCharacteristic extends StandardEndpointFilterCharacteristic { IsSanitizerCharacteristic() { this = "sanitizer" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | call.getCalleeName().regexpMatch("(?i).*(escape|valid(ate)?|sanitize|purify).*") ) @@ -689,7 +689,7 @@ private class IsSanitizerCharacteristic extends StandardEndpointFilterCharacteri private class IsPredicateCharacteristic extends StandardEndpointFilterCharacteristic { IsPredicateCharacteristic() { this = "predicate" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | call.getCalleeName().regexpMatch("(equals|(|is|has|can)(_|[A-Z])).*") ) @@ -699,7 +699,7 @@ private class IsPredicateCharacteristic extends StandardEndpointFilterCharacteri private class IsHashCharacteristic extends StandardEndpointFilterCharacteristic { IsHashCharacteristic() { this = "hash" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | call.getCalleeName().regexpMatch("(?i)^(sha\\d*|md5|hash)$") ) @@ -709,7 +709,7 @@ private class IsHashCharacteristic extends StandardEndpointFilterCharacteristic private class IsNumericCharacteristic extends StandardEndpointFilterCharacteristic { IsNumericCharacteristic() { this = "numeric" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { SyntacticHeuristics::isReadFrom(n, ".*index.*") } } @@ -721,7 +721,7 @@ private class InIrrelevantFileCharacteristic extends StandardEndpointFilterChara this = "in " + category + " file" and category = ["externs", "generated", "library", "test"] } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { // Ignore candidate sinks within externs, generated, library, and test code ClassifyFiles::classify(n.getFile(), category) } @@ -732,7 +732,7 @@ abstract private class NosqlInjectionSinkEndpointFilterCharacteristic extends En bindingset[this] NosqlInjectionSinkEndpointFilterCharacteristic() { any() } - override predicate getImplications( + override predicate hasImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { endpointClass instanceof NosqlInjectionSinkType and @@ -744,7 +744,7 @@ abstract private class NosqlInjectionSinkEndpointFilterCharacteristic extends En private class DatabaseAccessCallHeuristicCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { DatabaseAccessCallHeuristicCharacteristic() { this = "matches database access call heuristic" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::MethodCallNode call | n = call.getAnArgument() | // additional databases accesses that aren't modeled yet call.getMethodName() = ["create", "createCollection", "createIndexes"] @@ -764,7 +764,7 @@ private class ModeledSinkCharacteristic extends NosqlInjectionSinkEndpointFilter ) } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | // Remove modeled sinks isArgumentToKnownLibrarySinkFunction(n) @@ -775,7 +775,7 @@ private class ModeledSinkCharacteristic extends NosqlInjectionSinkEndpointFilter private class PredecessorInModeledFlowStepCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { PredecessorInModeledFlowStepCharacteristic() { this = "predecessor in a modeled flow step" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | // Remove common kinds of unlikely sinks isKnownStepSrc(n) @@ -786,7 +786,7 @@ private class PredecessorInModeledFlowStepCharacteristic extends NosqlInjectionS private class ModeledDatabaseAccessCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { ModeledDatabaseAccessCharacteristic() { this = "modeled database access" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | // Remove modeled database calls. Arguments to modeled calls are very likely to be modeled // as sinks if they are true positives. Therefore arguments that are not modeled as sinks @@ -799,7 +799,7 @@ private class ModeledDatabaseAccessCharacteristic extends NosqlInjectionSinkEndp private class ReceiverIsHttpRequestExpressionCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { ReceiverIsHttpRequestExpressionCharacteristic() { this = "receiver is a HTTP request expression" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | // Remove calls to APIs that aren't relevant to NoSQL injection call.getReceiver() instanceof Http::RequestNode @@ -812,7 +812,7 @@ private class ReceiverIsHttpResponseExpressionCharacteristic extends NosqlInject this = "receiver is a HTTP response expression" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | // Remove calls to APIs that aren't relevant to NoSQL injection call.getReceiver() instanceof Http::ResponseNode @@ -825,7 +825,7 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkNosqlCh this = "not a direct argument to a likely external library call or a heuristic sink (nosql)" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { // Require NoSQL injection sink candidates to be (a) direct arguments to external library calls // or (b) heuristic sinks for NoSQL injection. // @@ -867,7 +867,7 @@ abstract private class SqlInjectionSinkEndpointFilterCharacteristic extends Endp bindingset[this] SqlInjectionSinkEndpointFilterCharacteristic() { any() } - override predicate getImplications( + override predicate hasImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { endpointClass instanceof SqlInjectionSinkType and @@ -879,7 +879,7 @@ abstract private class SqlInjectionSinkEndpointFilterCharacteristic extends Endp private class PreparedSqlStatementCharacteristic extends SqlInjectionSinkEndpointFilterCharacteristic { PreparedSqlStatementCharacteristic() { this = "prepared SQL statement" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | // prepared statements for SQL any(DataFlow::CallNode cn | cn.getCalleeName() = "prepare") @@ -892,7 +892,7 @@ private class PreparedSqlStatementCharacteristic extends SqlInjectionSinkEndpoin private class ArrayCreationCharacteristic extends SqlInjectionSinkEndpointFilterCharacteristic { ArrayCreationCharacteristic() { this = "array creation" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | n instanceof DataFlow::ArrayCreationNode ) @@ -902,7 +902,7 @@ private class ArrayCreationCharacteristic extends SqlInjectionSinkEndpointFilter private class HtmlOrRenderingCharacteristic extends SqlInjectionSinkEndpointFilterCharacteristic { HtmlOrRenderingCharacteristic() { this = "HTML / rendering" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | // UI is unrelated to SQL call.getCalleeName().regexpMatch("(?i).*(render|html).*") @@ -915,7 +915,7 @@ private class NotAnArgumentToLikelyExternalLibraryCallOrHeuristicSinkCharacteris this = "not an argument to a likely external library call or a heuristic sink" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { // Require SQL injection sink candidates to be (a) arguments to external library calls // (possibly indirectly), or (b) heuristic sinks. // @@ -938,7 +938,7 @@ abstract private class TaintedPathSinkEndpointFilterCharacteristic extends Endpo bindingset[this] TaintedPathSinkEndpointFilterCharacteristic() { any() } - override predicate getImplications( + override predicate hasImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { endpointClass instanceof TaintedPathSinkType and @@ -953,7 +953,7 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkTainted "not a direct argument to a likely external library call or a heuristic sink (tainted path)" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { // Require path injection sink candidates to be (a) arguments to external library calls // (possibly indirectly), or (b) heuristic sinks. // @@ -990,7 +990,7 @@ abstract private class XssSinkEndpointFilterCharacteristic extends EndpointFilte bindingset[this] XssSinkEndpointFilterCharacteristic() { any() } - override predicate getImplications( + override predicate hasImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { endpointClass instanceof XssSinkType and @@ -1004,7 +1004,7 @@ private class SetStateCallsInReactApplicationsCharacteristic extends XssSinkEndp this = "setState calls ought to be safe in react applications" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { exists(DataFlow::CallNode call | n = call.getAnArgument() | call.getCalleeName() = "setState") } } @@ -1014,7 +1014,7 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkXssChar this = "not a direct argument to a likely external library call or a heuristic sink (xss)" } - override predicate getEndpoints(DataFlow::Node n) { + override predicate appliesToEndpoint(DataFlow::Node n) { // Require XSS sink candidates to be (a) arguments to external library calls (possibly // indirectly), or (b) heuristic sinks. // diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll index 325809e085f..99cba794cfa 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll @@ -53,7 +53,7 @@ predicate tokenFeatures(DataFlow::Node endpoint, string featureName, string feat query predicate trainingEndpoints( DataFlow::Node endpoint, EndpointType endpointClass, EndpointCharacteristic characteristic ) { - characteristic.getEndpoints(endpoint) and + characteristic.appliesToEndpoint(endpoint) and // Only consider the source code for the project being analyzed. exists(endpoint.getFile().getRelativePath()) and // Only select endpoints that can be part of a tainted flow: Constant expressions always evaluate to a constant @@ -69,7 +69,7 @@ query predicate trainingEndpoints( not ( endpointClass instanceof NegativeType and exists(EndpointCharacteristic c | - c.getEndpoints(endpoint) and + c.appliesToEndpoint(endpoint) and c instanceof LikelyNotASinkCharacteristic ) ) and @@ -81,8 +81,8 @@ query predicate trainingEndpoints( // If the list of characteristics includes positive indicators with high confidence for this class, select this as a // training sample belonging to the class. exists(EndpointCharacteristic characteristic2, float confidence | - characteristic2.getEndpoints(endpoint) and - characteristic2.getImplications(endpointClass, true, confidence) and + characteristic2.appliesToEndpoint(endpoint) and + characteristic2.hasImplications(endpointClass, true, confidence) and confidence >= characteristic2.getHighConfidenceThreshold() ) and ( @@ -93,8 +93,8 @@ query predicate trainingEndpoints( not endpointClass instanceof NegativeType or not exists(EndpointCharacteristic characteristic3, float confidence3, EndpointType posClass | - characteristic3.getEndpoints(endpoint) and - characteristic3.getImplications(posClass, true, confidence3) and + characteristic3.appliesToEndpoint(endpoint) and + characteristic3.hasImplications(posClass, true, confidence3) and confidence3 >= characteristic3.getHighConfidenceThreshold() and not posClass instanceof NegativeType ) @@ -106,8 +106,8 @@ query predicate trainingEndpoints( endpointClass instanceof NegativeType and forall(EndpointType otherClass | not otherClass instanceof NegativeType | exists(EndpointCharacteristic characteristic2, float confidence | - characteristic2.getEndpoints(endpoint) and - characteristic2.getImplications(otherClass, false, confidence) and + characteristic2.appliesToEndpoint(endpoint) and + characteristic2.hasImplications(otherClass, false, confidence) and confidence >= characteristic2.getHighConfidenceThreshold() ) ) @@ -180,15 +180,15 @@ query predicate reformattedTrainingEndpoints( // The reason, or reasons, why the endpoint was labeled NotASink for this query, only for negative examples. key = "notASinkReason" and exists(EndpointCharacteristic characteristic, EndpointType endpointClass | - characteristic.getEndpoints(endpoint) and - characteristic.getImplications(endpointClass, true, _) and + characteristic.appliesToEndpoint(endpoint) and + characteristic.hasImplications(endpointClass, true, _) and endpointClass instanceof NegativeType and value = characteristic ) and // Don't include a notASinkReason for endpoints that are also known sinks. not exists(EndpointCharacteristic characteristic3, float confidence3, EndpointType posClass | - characteristic3.getEndpoints(endpoint) and - characteristic3.getImplications(posClass, true, confidence3) and + characteristic3.appliesToEndpoint(endpoint) and + characteristic3.hasImplications(posClass, true, confidence3) and confidence3 >= characteristic3.getHighConfidenceThreshold() and not posClass instanceof NegativeType ) and diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/NosqlInjectionATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/NosqlInjectionATM.ql index 8ec315c3d9c..47aca8843b4 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/NosqlInjectionATM.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/NosqlInjectionATM.ql @@ -18,7 +18,7 @@ import DataFlow::PathGraph import experimental.adaptivethreatmodeling.NosqlInjectionATM from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score -where cfg.getAlerts(source, sink, score) +where cfg.hasAlert(source, sink, score) select sink.getNode(), source, sink, "(Experimental) This may be a database query that depends on $@. Identified using machine learning.", source.getNode(), "a user-provided value", score diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/SqlInjectionATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/SqlInjectionATM.ql index 16921565707..c51367c6fcb 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/SqlInjectionATM.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/SqlInjectionATM.ql @@ -18,7 +18,7 @@ import ATM::ResultsInfo import DataFlow::PathGraph from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score -where cfg.getAlerts(source, sink, score) +where cfg.hasAlert(source, sink, score) select sink.getNode(), source, sink, "(Experimental) This may be a database query that depends on $@. Identified using machine learning.", source.getNode(), "a user-provided value", score diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/TaintedPathATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/TaintedPathATM.ql index e4e4db0bf32..cb9aca19192 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/TaintedPathATM.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/TaintedPathATM.ql @@ -22,7 +22,7 @@ import DataFlow::PathGraph import experimental.adaptivethreatmodeling.TaintedPathATM from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score -where cfg.getAlerts(source, sink, score) +where cfg.hasAlert(source, sink, score) select sink.getNode(), source, sink, "(Experimental) This may be a path that depends on $@. Identified using machine learning.", source.getNode(), "a user-provided value", score diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/XssATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/XssATM.ql index deac86922ab..01f0418888f 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/XssATM.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/XssATM.ql @@ -19,7 +19,7 @@ import DataFlow::PathGraph import experimental.adaptivethreatmodeling.XssATM from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score -where cfg.getAlerts(source, sink, score) +where cfg.hasAlert(source, sink, score) select sink.getNode(), source, sink, "(Experimental) This may be a cross-site scripting vulnerability due to $@. Identified using machine learning.", source.getNode(), "a user-provided value", score diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql index 9439fda8ab2..a68cebb41da 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql @@ -22,7 +22,7 @@ query predicate tokenFeatures(DataFlow::Node endpoint, string featureName, strin not exists(any(TaintedPathAtm::TaintedPathAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or not exists(any(XssAtm::DomBasedXssAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or any(EndpointCharacteristics::IsArgumentToModeledFunctionCharacteristic characteristic) - .getEndpoints(endpoint) + .appliesToEndpoint(endpoint) ) and EndpointFeatures::tokenFeatures(endpoint, featureName, featureValue) } From 4a6de3e444dc793a57e8c43a91c382edd7ab3cd5 Mon Sep 17 00:00:00 2001 From: tiferet Date: Wed, 30 Nov 2022 17:25:19 -0800 Subject: [PATCH 746/796] Apply suggestion from code review --- .../lib/experimental/adaptivethreatmodeling/ATMConfig.qll | 4 +++- .../adaptivethreatmodeling/src/NosqlInjectionATM.ql | 2 +- .../adaptivethreatmodeling/src/SqlInjectionATM.ql | 2 +- .../experimental/adaptivethreatmodeling/src/TaintedPathATM.ql | 2 +- .../ql/experimental/adaptivethreatmodeling/src/XssATM.ql | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index b4a92bf1010..d6582eb969e 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -147,7 +147,9 @@ abstract class AtmConfig extends JS::TaintTracking::Configuration { * to this ML-boosted configuration, whereas the unboosted base query does not contain this source and sink * combination. */ - predicate hasAlert(JS::DataFlow::PathNode source, JS::DataFlow::PathNode sink, float score) { + predicate hasBoostedFlowPath( + JS::DataFlow::PathNode source, JS::DataFlow::PathNode sink, float score + ) { this.hasFlowPath(source, sink) and not AtmResultsInfo::isFlowLikelyInBaseQuery(source.getNode(), sink.getNode()) and score = AtmResultsInfo::getScoreForFlow(source.getNode(), sink.getNode()) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/NosqlInjectionATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/NosqlInjectionATM.ql index 47aca8843b4..6d5428f7c91 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/NosqlInjectionATM.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/NosqlInjectionATM.ql @@ -18,7 +18,7 @@ import DataFlow::PathGraph import experimental.adaptivethreatmodeling.NosqlInjectionATM from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score -where cfg.hasAlert(source, sink, score) +where cfg.hasBoostedFlowPath(source, sink, score) select sink.getNode(), source, sink, "(Experimental) This may be a database query that depends on $@. Identified using machine learning.", source.getNode(), "a user-provided value", score diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/SqlInjectionATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/SqlInjectionATM.ql index c51367c6fcb..fdeb79de145 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/SqlInjectionATM.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/SqlInjectionATM.ql @@ -18,7 +18,7 @@ import ATM::ResultsInfo import DataFlow::PathGraph from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score -where cfg.hasAlert(source, sink, score) +where cfg.hasBoostedFlowPath(source, sink, score) select sink.getNode(), source, sink, "(Experimental) This may be a database query that depends on $@. Identified using machine learning.", source.getNode(), "a user-provided value", score diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/TaintedPathATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/TaintedPathATM.ql index cb9aca19192..b505a381971 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/TaintedPathATM.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/TaintedPathATM.ql @@ -22,7 +22,7 @@ import DataFlow::PathGraph import experimental.adaptivethreatmodeling.TaintedPathATM from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score -where cfg.hasAlert(source, sink, score) +where cfg.hasBoostedFlowPath(source, sink, score) select sink.getNode(), source, sink, "(Experimental) This may be a path that depends on $@. Identified using machine learning.", source.getNode(), "a user-provided value", score diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/XssATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/XssATM.ql index 01f0418888f..449f450f3ce 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/XssATM.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/XssATM.ql @@ -19,7 +19,7 @@ import DataFlow::PathGraph import experimental.adaptivethreatmodeling.XssATM from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score -where cfg.hasAlert(source, sink, score) +where cfg.hasBoostedFlowPath(source, sink, score) select sink.getNode(), source, sink, "(Experimental) This may be a cross-site scripting vulnerability due to $@. Identified using machine learning.", source.getNode(), "a user-provided value", score From cd0d09d806cb84b5c1a34ff992711818eede552d Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 1 Dec 2022 13:06:18 +0100 Subject: [PATCH 747/796] Java: Refactor to avoid using SummaryModelCsv. --- .../src/utils/flowtestcasegenerator/FlowTestCase.qll | 4 ++-- .../flowtestcasegenerator/GenerateFlowTestCase.py | 10 +++++----- .../flowtestcasegenerator/GenerateFlowTestCase.qll | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll b/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll index de4bae52065..0339ca4f233 100644 --- a/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll +++ b/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll @@ -12,7 +12,7 @@ private import FlowTestCaseSupportMethods /** * A CSV row to generate tests for. Users should extend this to define which - * tests to generate. Rows specified here should also satisfy `SummaryModelCsv.row`. + * tests to generate. There should already exist a summaries for the rows specified here. */ class TargetSummaryModelCsv extends Unit { /** @@ -44,7 +44,7 @@ predicate summaryModelRow( /** * Gets a CSV row for which a test has been requested, but where a summary has not already been defined. */ -query string missingSummaryModelCsv() { +query string missingSummaryModel() { any(TargetSummaryModelCsv target).row(result) and not summaryModelRow(_, _, _, _, _, _, _, _, _, _, result) } diff --git a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py index 65c485c19cc..c3a590b1ccc 100755 --- a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py +++ b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py @@ -173,9 +173,9 @@ def getTuples(queryName, jsonResult, fname): with open(generatedJson, "r") as f: generateOutput = json.load(f) expectedTables = ("getTestCase", "getASupportMethodModel", - "missingSummaryModelCsv", "getAParseFailure", "noTestCaseGenerated") + "missingSummaryModel", "getAParseFailure", "noTestCaseGenerated") - testCaseRows, supportModelRows, missingSummaryModelCsvRows, parseFailureRows, noTestCaseGeneratedRows = \ + testCaseRows, supportModelRows, missingSummaryModelRows, parseFailureRows, noTestCaseGeneratedRows = \ tuple([getTuples(k, generateOutput, generatedJson) for k in expectedTables]) @@ -192,9 +192,9 @@ with open(generatedJson, "r") as f: print("Expected exactly one column in noTestCaseGenerated relation (got: %s)" % json.dumps(noTestCaseGeneratedRows), file=sys.stderr) - if len(missingSummaryModelCsvRows) != 0: - print("Tests for some CSV rows were requested that were not in scope (SummaryModelCsv.row does not hold):\n" + - "\n".join(r[0] for r in missingSummaryModelCsvRows)) + if len(missingSummaryModelRows) != 0: + print("Tests for some CSV rows were requested that were not in scope (a summary doesn't already exist):\n" + + "\n".join(r[0] for r in missingSummaryModelRows)) sys.exit(1) if len(parseFailureRows) != 0: print("The following rows failed to generate any test case. Check package, class and method name spelling, and argument and result specifications:\n%s" % diff --git a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll index 5d9aa884ecc..2025affabf0 100644 --- a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll +++ b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll @@ -13,13 +13,13 @@ private import FlowTestCaseSupportMethods private import FlowTestCaseUtils /** - * Gets a CSV row for which a test has been requested, and `SummaryModelCsv.row` does hold, but + * Gets a CSV row for which a test has been requested, and where there exist a summary, but * nonetheless we can't generate a test case for it, indicating we cannot resolve either the callable * spec or an input or output spec. */ query string getAParseFailure(string reason) { any(TargetSummaryModelCsv target).row(result) and - any(SummaryModelCsv model).row(result) and + summaryModelRow(_, _, _, _, _, _, _, _, _, _, result) and ( not summaryModelRow(_, _, _, _, _, _, _, _, _, _, result) and reason = "row could not be parsed" @@ -52,7 +52,7 @@ query string getAParseFailure(string reason) { */ query string noTestCaseGenerated() { any(TargetSummaryModelCsv target).row(result) and - any(SummaryModelCsv model).row(result) and + summaryModelRow(_, _, _, _, _, _, _, _, _, _, result) and not exists(getAParseFailure(_)) and not exists(any(TestCase tc).getATestSnippetForRow(result)) } From d47b3265c42b27e79873fc3ce9d005135dedc786 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 1 Dec 2022 14:56:10 +0100 Subject: [PATCH 748/796] Python: Fix `py/meta/points-to-call-graph` --- python/ql/src/meta/analysis-quality/CallGraph.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/meta/analysis-quality/CallGraph.ql b/python/ql/src/meta/analysis-quality/CallGraph.ql index 49be0157b05..2872912bb51 100644 --- a/python/ql/src/meta/analysis-quality/CallGraph.ql +++ b/python/ql/src/meta/analysis-quality/CallGraph.ql @@ -16,5 +16,5 @@ from DataFlowCall c, DataFlowCallableValue f where c.getCallable() = f and not c.getLocation().getFile() instanceof IgnoredFile and - not f.getLocation().getFile() instanceof IgnoredFile + not f.getScope().getLocation().getFile() instanceof IgnoredFile select c, "Call to $@", f.getScope(), f.toString() From eb9bee23a0c2b0f35eb8d066c0c344d0933e662d Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 30 Nov 2022 11:27:58 +0100 Subject: [PATCH 749/796] JS: Remove MkAsyncFunctionResult --- .../ql/lib/semmle/javascript/ApiGraphs.qll | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/ApiGraphs.qll b/javascript/ql/lib/semmle/javascript/ApiGraphs.qll index 72d5a50cebe..085a8ca9fba 100644 --- a/javascript/ql/lib/semmle/javascript/ApiGraphs.qll +++ b/javascript/ql/lib/semmle/javascript/ApiGraphs.qll @@ -460,7 +460,6 @@ module API { this = Impl::MkClassInstance(result) or this = Impl::MkUse(result) or this = Impl::MkDef(result) or - this = Impl::MkAsyncFuncResult(result) or this = Impl::MkSyntheticCallbackArg(_, _, result) } @@ -671,9 +670,6 @@ module API { cls.getAnInstanceReference() = trackDefNode(_) ) } or - MkAsyncFuncResult(DataFlow::FunctionNode f) { - f = trackDefNode(_) and f.getFunction().isAsync() and hasSemantics(f) - } or MkDef(DataFlow::Node nd) { rhs(_, _, nd) } or MkUse(DataFlow::Node nd) { use(_, _, nd) } or /** A use of a TypeScript type. */ @@ -688,8 +684,7 @@ module API { class TDef = MkModuleDef or TNonModuleDef; - class TNonModuleDef = - MkModuleExport or MkClassInstance or MkAsyncFuncResult or MkDef or MkSyntheticCallbackArg; + class TNonModuleDef = MkModuleExport or MkClassInstance or MkDef or MkSyntheticCallbackArg; class TUse = MkModuleUse or MkModuleImport or MkUse or MkTypeUse; @@ -740,10 +735,11 @@ module API { rhs = m.getAnExportedValue(prop) ) or - exists(DataFlow::FunctionNode fn | fn = pred | - not fn.getFunction().isAsync() and - lbl = Label::return() and - rhs = fn.getAReturn() + exists(DataFlow::FunctionNode fn | + fn = pred and + lbl = Label::return() + | + if fn.getFunction().isAsync() then rhs = fn.getReturnNode() else rhs = fn.getAReturn() ) or lbl = Label::promised() and @@ -774,13 +770,12 @@ module API { ) or exists(DataFlow::FunctionNode f | - base = MkAsyncFuncResult(f) and + f.getFunction().isAsync() and + base = MkDef(f.getReturnNode()) + | lbl = Label::promised() and rhs = f.getAReturn() - ) - or - exists(DataFlow::FunctionNode f | - base = MkAsyncFuncResult(f) and + or lbl = Label::promisedError() and rhs = f.getExceptionalReturn() ) @@ -1272,10 +1267,11 @@ module API { ) or exists(DataFlow::Node nd, DataFlow::FunctionNode f | + f.getFunction().isAsync() and pred = MkDef(nd) and f = trackDefNode(nd) and lbl = Label::return() and - succ = MkAsyncFuncResult(f) + succ = MkDef(f.getReturnNode()) ) or exists(int bound, DataFlow::InvokeNode call | From 6289ae329bf6765844ecc1b30e48a303ce682470 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 1 Dec 2022 15:27:41 +0100 Subject: [PATCH 750/796] fix a race-condition --- .../extractor/src/com/semmle/js/extractor/AutoBuild.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java index 445f1116ec7..bf5b4e8cb03 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java +++ b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java @@ -446,7 +446,8 @@ public class AutoBuild { public int run() throws IOException { startThreadPool(); try { - extractSource(); + CompletableFuture sourceFuture = extractSource(); + sourceFuture.join(); // wait for source extraction to complete if (hasSeenCode()) { // don't bother with the externs if no code was seen extractExterns(); } @@ -589,7 +590,7 @@ public class AutoBuild { } /** Extract all supported candidate files that pass the filters. */ - private void extractSource() throws IOException { + private CompletableFuture extractSource() throws IOException { // default extractor FileExtractor defaultExtractor = new FileExtractor(mkExtractorConfig(), outputConfig, trapCache); @@ -636,7 +637,7 @@ public class AutoBuild { boolean hasTypeScriptFiles = extractedFiles.size() > 0; // extract remaining files - extractFiles( + return extractFiles( filesToExtract, extractedFiles, extractors, f -> !(hasTypeScriptFiles && isFileDerivedFromTypeScriptFile(f, extractedFiles))); } From b4382855faff82ba087dce0335199033c63f8db8 Mon Sep 17 00:00:00 2001 From: Gustav Munkby Date: Thu, 1 Dec 2022 15:43:51 +0100 Subject: [PATCH 751/796] Fallback to package dir for discovering go.mod This reverts to the old behavior of reusing the package directory when looking for go.mod. It seems unlikely that this is the right thing to do since we failed to find the module directory, but this behavior should be consistent with what we had before. --- go/extractor/extractor.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/go/extractor/extractor.go b/go/extractor/extractor.go index 4d479f6384b..4b087d82947 100644 --- a/go/extractor/extractor.go +++ b/go/extractor/extractor.go @@ -186,8 +186,12 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error { extraction.extractPackage(pkg) - if pkgInfo.ModDir != "" { - modPath := filepath.Join(pkgInfo.ModDir, "go.mod") + modDir := pkgInfo.ModDir + if modDir == "" { + modDir = pkgInfo.PkgDir + } + if modDir != "" { + modPath := filepath.Join(modDir, "go.mod") if util.FileExists(modPath) { log.Printf("Extracting %s", modPath) start := time.Now() From 68504c097cd2e133ba155c34d1169b93b1ef9e4e Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 1 Dec 2022 17:07:54 +0100 Subject: [PATCH 752/796] Swift: remove obsolete file --- swift/ql/lib/codeql/swift/elements/expr/ArrowExpr.qll | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 swift/ql/lib/codeql/swift/elements/expr/ArrowExpr.qll diff --git a/swift/ql/lib/codeql/swift/elements/expr/ArrowExpr.qll b/swift/ql/lib/codeql/swift/elements/expr/ArrowExpr.qll deleted file mode 100644 index 220aaa883c2..00000000000 --- a/swift/ql/lib/codeql/swift/elements/expr/ArrowExpr.qll +++ /dev/null @@ -1,5 +0,0 @@ -private import codeql.swift.generated.expr.ArrowExpr - -class ArrowExpr extends Generated::ArrowExpr { - override string toString() { result = "... -> ..." } -} From cd6d00e760e4a2ee5dd7e2707e1225fd4ec65fea Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 1 Dec 2022 15:28:59 +0100 Subject: [PATCH 753/796] Swift: add xcode integration test --- swift/integration-tests/.gitignore | 1 - .../osx-only/hello-xcode/Files.expected | 2 + .../osx-only/hello-xcode/Files.ql | 4 + .../project.pbxproj | 310 ++++++++++++++++++ .../AppDelegate.swift | 4 + .../osx-only/hello-xcode/test.py | 9 + 6 files changed, 329 insertions(+), 1 deletion(-) create mode 100644 swift/integration-tests/osx-only/hello-xcode/Files.expected create mode 100644 swift/integration-tests/osx-only/hello-xcode/Files.ql create mode 100644 swift/integration-tests/osx-only/hello-xcode/codeql-swift-autobuild-test.xcodeproj/project.pbxproj create mode 100644 swift/integration-tests/osx-only/hello-xcode/codeql-swift-autobuild-test/AppDelegate.swift create mode 100644 swift/integration-tests/osx-only/hello-xcode/test.py diff --git a/swift/integration-tests/.gitignore b/swift/integration-tests/.gitignore index b613644a5ae..56a73ade7d3 100644 --- a/swift/integration-tests/.gitignore +++ b/swift/integration-tests/.gitignore @@ -1,7 +1,6 @@ .DS_Store .build Packages -*.xcodeproj xcuserdata/ DerivedData/ .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata diff --git a/swift/integration-tests/osx-only/hello-xcode/Files.expected b/swift/integration-tests/osx-only/hello-xcode/Files.expected new file mode 100644 index 00000000000..217aa9e933b --- /dev/null +++ b/swift/integration-tests/osx-only/hello-xcode/Files.expected @@ -0,0 +1,2 @@ +| codeql-swift-autobuild-test/AppDelegate.swift:0:0:0:0 | codeql-swift-autobuild-test/AppDelegate.swift | +| file://:0:0:0:0 | | diff --git a/swift/integration-tests/osx-only/hello-xcode/Files.ql b/swift/integration-tests/osx-only/hello-xcode/Files.ql new file mode 100644 index 00000000000..9782ea4ce0b --- /dev/null +++ b/swift/integration-tests/osx-only/hello-xcode/Files.ql @@ -0,0 +1,4 @@ +import swift + +from File f +select f diff --git a/swift/integration-tests/osx-only/hello-xcode/codeql-swift-autobuild-test.xcodeproj/project.pbxproj b/swift/integration-tests/osx-only/hello-xcode/codeql-swift-autobuild-test.xcodeproj/project.pbxproj new file mode 100644 index 00000000000..efc35405363 --- /dev/null +++ b/swift/integration-tests/osx-only/hello-xcode/codeql-swift-autobuild-test.xcodeproj/project.pbxproj @@ -0,0 +1,310 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 46D4896F291B98000029E1E2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46D4896E291B98000029E1E2 /* AppDelegate.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 46D4896B291B98000029E1E2 /* codeql-swift-autobuild-test.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "codeql-swift-autobuild-test.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 46D4896E291B98000029E1E2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 46D48968291B98000029E1E2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 46D48962291B98000029E1E2 = { + isa = PBXGroup; + children = ( + 46D4896D291B98000029E1E2 /* codeql-swift-autobuild-test */, + 46D4896C291B98000029E1E2 /* Products */, + ); + sourceTree = ""; + }; + 46D4896C291B98000029E1E2 /* Products */ = { + isa = PBXGroup; + children = ( + 46D4896B291B98000029E1E2 /* codeql-swift-autobuild-test.app */, + ); + name = Products; + sourceTree = ""; + }; + 46D4896D291B98000029E1E2 /* codeql-swift-autobuild-test */ = { + isa = PBXGroup; + children = ( + 46D4896E291B98000029E1E2 /* AppDelegate.swift */, + ); + path = "codeql-swift-autobuild-test"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 46D4896A291B98000029E1E2 /* codeql-swift-autobuild-test */ = { + isa = PBXNativeTarget; + buildConfigurationList = 46D4897A291B98020029E1E2 /* Build configuration list for PBXNativeTarget "codeql-swift-autobuild-test" */; + buildPhases = ( + 46D48967291B98000029E1E2 /* Sources */, + 46D48968291B98000029E1E2 /* Frameworks */, + 46D48969291B98000029E1E2 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "codeql-swift-autobuild-test"; + productName = "codeql-swift-autobuild-test"; + productReference = 46D4896B291B98000029E1E2 /* codeql-swift-autobuild-test.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 46D48963291B98000029E1E2 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1400; + LastUpgradeCheck = 1400; + TargetAttributes = { + 46D4896A291B98000029E1E2 = { + CreatedOnToolsVersion = 14.0; + }; + }; + }; + buildConfigurationList = 46D48966291B98000029E1E2 /* Build configuration list for PBXProject "codeql-swift-autobuild-test" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 46D48962291B98000029E1E2; + productRefGroup = 46D4896C291B98000029E1E2 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 46D4896A291B98000029E1E2 /* codeql-swift-autobuild-test */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 46D48969291B98000029E1E2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 46D48967291B98000029E1E2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 46D4896F291B98000029E1E2 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 46D48978291B98020029E1E2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 46D48979291B98020029E1E2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 46D4897B291B98020029E1E2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INFOPLIST_KEY_NSMainStoryboardFile = Main; + INFOPLIST_KEY_NSPrincipalClass = NSApplication; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.github.codeql-swift-autobuild-test"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 46D4897C291B98020029E1E2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INFOPLIST_KEY_NSMainStoryboardFile = Main; + INFOPLIST_KEY_NSPrincipalClass = NSApplication; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.github.codeql-swift-autobuild-test"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 46D48966291B98000029E1E2 /* Build configuration list for PBXProject "codeql-swift-autobuild-test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 46D48978291B98020029E1E2 /* Debug */, + 46D48979291B98020029E1E2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 46D4897A291B98020029E1E2 /* Build configuration list for PBXNativeTarget "codeql-swift-autobuild-test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 46D4897B291B98020029E1E2 /* Debug */, + 46D4897C291B98020029E1E2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 46D48963291B98000029E1E2 /* Project object */; +} diff --git a/swift/integration-tests/osx-only/hello-xcode/codeql-swift-autobuild-test/AppDelegate.swift b/swift/integration-tests/osx-only/hello-xcode/codeql-swift-autobuild-test/AppDelegate.swift new file mode 100644 index 00000000000..b098bd9fcf5 --- /dev/null +++ b/swift/integration-tests/osx-only/hello-xcode/codeql-swift-autobuild-test/AppDelegate.swift @@ -0,0 +1,4 @@ +import Cocoa + +@main +class AppDelegate: NSObject, NSApplicationDelegate {} diff --git a/swift/integration-tests/osx-only/hello-xcode/test.py b/swift/integration-tests/osx-only/hello-xcode/test.py new file mode 100644 index 00000000000..6c5630bfb6a --- /dev/null +++ b/swift/integration-tests/osx-only/hello-xcode/test.py @@ -0,0 +1,9 @@ +from create_database_utils import * + +run_codeql_database_create([ + 'xcodebuild clean', + 'xcodebuild build ' + '-project codeql-swift-autobuild-test.xcodeproj ' + '-target codeql-swift-autobuild-test ' + 'CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO', +], lang='swift', keep_trap=True) From c374a5301ed62cca169fa065cbd8c0caca7968ae Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 1 Dec 2022 16:28:43 +0100 Subject: [PATCH 754/796] Swift: upload test DBs as artifacts for integration tests --- swift/actions/run-integration-tests/action.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/swift/actions/run-integration-tests/action.yml b/swift/actions/run-integration-tests/action.yml index 27ea6cde433..68189f5484f 100644 --- a/swift/actions/run-integration-tests/action.yml +++ b/swift/actions/run-integration-tests/action.yml @@ -25,3 +25,12 @@ runs: shell: bash run: | python swift/integration-tests/runner.py --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" + env: + SEMMLE_DEBUG_TRACER: 10000 + - name: Upload test logs + uses: actions/upload-artifact@v3 + with: + name: swift-integration-tests-logs-${{ runner.os }} + path: | + swift/integration-tests/**/db/log + retention-days: 1 From f388703a3d5a007ba5aa0381108f2c6779e689be Mon Sep 17 00:00:00 2001 From: Jean Helie Date: Thu, 1 Dec 2022 17:45:07 +0100 Subject: [PATCH 755/796] ATM: update further files following the addition of XssThroughDom query --- .../modelbuilding/DebugResultInclusion.ql | 4 ++++ .../modelbuilding/extraction/Queries.qll | 7 ++++++- .../test/endpoint_large_scale/EndpointFeatures.ql | 2 ++ .../test/endpoint_large_scale/FilteredTruePositives.ql | 7 +++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql index 444f682304d..ac2f2f1d817 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql @@ -16,6 +16,7 @@ private import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInj private import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm private import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm private import experimental.adaptivethreatmodeling.XssATM as XssAtm +private import experimental.adaptivethreatmodeling.XssThroughDomATM as XssThroughDomAtm string getAReasonSinkExcluded(DataFlow::Node sinkCandidate, Query query) { query instanceof NosqlInjectionQuery and @@ -29,6 +30,9 @@ string getAReasonSinkExcluded(DataFlow::Node sinkCandidate, Query query) { or query instanceof XssQuery and result = any(XssAtm::DomBasedXssAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) + or + query instanceof XssThroughDomQuery and + result = any(XssThroughDomAtm::XssThroughDomAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) } pragma[inline] diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/Queries.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/Queries.qll index 51dd3ffec84..a75e01b99cd 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/Queries.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/Queries.qll @@ -8,7 +8,8 @@ newtype TQuery = TNosqlInjectionQuery() or TSqlInjectionQuery() or TTaintedPathQuery() or - TXssQuery() + TXssQuery() or + TXssThroughDomQuery() abstract class Query extends TQuery { abstract string getName(); @@ -31,3 +32,7 @@ class TaintedPathQuery extends Query, TTaintedPathQuery { class XssQuery extends Query, TXssQuery { override string getName() { result = "Xss" } } + +class XssThroughDomQuery extends Query, TXssThroughDomQuery { + override string getName() { result = "XssThroughDom" } +} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql index 9439fda8ab2..5c19ec53dcd 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.ql @@ -11,6 +11,7 @@ import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAt import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm import experimental.adaptivethreatmodeling.XssATM as XssAtm +import experimental.adaptivethreatmodeling.XssThroughDomATM as XssThroughDomAtm import experimental.adaptivethreatmodeling.EndpointFeatures as EndpointFeatures import extraction.NoFeaturizationRestrictionsConfig private import experimental.adaptivethreatmodeling.EndpointCharacteristics as EndpointCharacteristics @@ -21,6 +22,7 @@ query predicate tokenFeatures(DataFlow::Node endpoint, string featureName, strin not exists(any(SqlInjectionAtm::SqlInjectionAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or not exists(any(TaintedPathAtm::TaintedPathAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or not exists(any(XssAtm::DomBasedXssAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or + not exists(any(XssThroughDomAtm::XssThroughDomAtmConfig cfg).getAReasonSinkExcluded(endpoint)) or any(EndpointCharacteristics::IsArgumentToModeledFunctionCharacteristic characteristic) .getEndpoints(endpoint) ) and diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql index d8de88e3454..0e382df6ba9 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql @@ -20,6 +20,7 @@ import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAt import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm import experimental.adaptivethreatmodeling.XssATM as XssAtm +import experimental.adaptivethreatmodeling.XssThroughDomATM as XssThroughDomAtm query predicate nosqlFilteredTruePositives(DataFlow::Node endpoint, string reason) { endpoint instanceof NosqlInjection::Sink and @@ -44,3 +45,9 @@ query predicate xssFilteredTruePositives(DataFlow::Node endpoint, string reason) reason = any(XssAtm::DomBasedXssAtmConfig cfg).getAReasonSinkExcluded(endpoint) and reason != "argument to modeled function" } + +query predicate xssThroughDomFilteredTruePositives(DataFlow::Node endpoint, string reason) { + endpoint instanceof DomBasedXss::Sink and + reason = any(XssThroughDomAtm::XssThroughDomAtmConfig cfg).getAReasonSinkExcluded(endpoint) and + reason != "argument to modeled function" +} From 50a3c0d725084011bcc334ae0addcb2def9d8a04 Mon Sep 17 00:00:00 2001 From: Jean Helie Date: Thu, 1 Dec 2022 17:53:09 +0100 Subject: [PATCH 756/796] ATM: update expected ML test values --- .../ExtractEndpointDataTraining.expected | 741 ++++++++++++++++++ .../FilteredTruePositives.expected | 8 + .../ExtractEndpointDataTraining.expected | 16 + 3 files changed, 765 insertions(+) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataTraining.expected b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataTraining.expected index 822e8c7f34a..378827bd6d4 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataTraining.expected +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataTraining.expected @@ -103,6 +103,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:11:45:17:1 | {\\n t ... tring\\n} | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:11:45:17:1 | {\\n t ... tring\\n} | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:11:45:17:1 | {\\n t ... tring\\n} | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:11:45:17:1 | {\\n t ... tring\\n} | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:11:45:17:1 | {\\n t ... tring\\n} | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:11:45:17:1 | {\\n t ... tring\\n} | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:11:45:17:1 | {\\n t ... tring\\n} | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:11:45:17:1 | {\\n t ... tring\\n} | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:24:24:24:30 | [query] | NosqlInjection | hasFlowFromSource | true | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:24:24:24:30 | [query] | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:24:24:24:30 | [query] | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -179,6 +184,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:63:33:63:33 | X | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:63:33:63:33 | X | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:63:33:63:33 | X | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:63:33:63:33 | X | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:63:33:63:33 | X | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:63:33:63:33 | X | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:63:33:63:33 | X | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:63:33:63:33 | X | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:65:29:65:29 | X | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:65:29:65:29 | X | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:65:29:65:29 | X | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -207,6 +217,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:65:39:65:50 | function(){} | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:65:39:65:50 | function(){} | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:65:39:65:50 | function(){} | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:65:39:65:50 | function(){} | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:65:39:65:50 | function(){} | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:65:39:65:50 | function(){} | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:65:39:65:50 | function(){} | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:65:39:65:50 | function(){} | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:67:27:67:31 | query | NosqlInjection | hasFlowFromSource | true | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:67:27:67:31 | query | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:67:27:67:31 | query | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -235,6 +250,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:68:15:68:26 | function(){} | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:68:15:68:26 | function(){} | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:68:15:68:26 | function(){} | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:68:15:68:26 | function(){} | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:68:15:68:26 | function(){} | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:68:15:68:26 | function(){} | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:68:15:68:26 | function(){} | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:68:15:68:26 | function(){} | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:71:20:71:24 | query | NosqlInjection | hasFlowFromSource | true | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:71:20:71:24 | query | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:71:20:71:24 | query | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -291,6 +311,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:85:22:85:51 | (err, r ... (query) | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:85:22:85:51 | (err, r ... (query) | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:85:22:85:51 | (err, r ... (query) | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:85:22:85:51 | (err, r ... (query) | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:85:22:85:51 | (err, r ... (query) | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:85:22:85:51 | (err, r ... (query) | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:85:22:85:51 | (err, r ... (query) | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:85:22:85:51 | (err, r ... (query) | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:85:46:85:50 | query | NosqlInjection | hasFlowFromSource | true | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:85:46:85:50 | query | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:85:46:85:50 | query | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -319,6 +344,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:86:22:86:51 | (err, r ... (query) | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:86:22:86:51 | (err, r ... (query) | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:86:22:86:51 | (err, r ... (query) | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:86:22:86:51 | (err, r ... (query) | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:86:22:86:51 | (err, r ... (query) | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:86:22:86:51 | (err, r ... (query) | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:86:22:86:51 | (err, r ... (query) | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:86:22:86:51 | (err, r ... (query) | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:87:19:87:19 | X | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:87:19:87:19 | X | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:87:19:87:19 | X | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -343,6 +373,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:87:27:87:56 | (err, r ... (query) | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:87:27:87:56 | (err, r ... (query) | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:87:27:87:56 | (err, r ... (query) | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:87:27:87:56 | (err, r ... (query) | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:87:27:87:56 | (err, r ... (query) | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:87:27:87:56 | (err, r ... (query) | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:87:27:87:56 | (err, r ... (query) | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:87:27:87:56 | (err, r ... (query) | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:87:51:87:55 | query | NosqlInjection | hasFlowFromSource | true | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:87:51:87:55 | query | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:87:51:87:55 | query | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -371,6 +406,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:88:27:88:56 | (err, r ... (query) | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:88:27:88:56 | (err, r ... (query) | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:88:27:88:56 | (err, r ... (query) | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:88:27:88:56 | (err, r ... (query) | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:88:27:88:56 | (err, r ... (query) | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:88:27:88:56 | (err, r ... (query) | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:88:27:88:56 | (err, r ... (query) | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:88:27:88:56 | (err, r ... (query) | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:89:19:89:19 | X | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:89:19:89:19 | X | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:89:19:89:19 | X | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -395,6 +435,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:89:27:89:51 | (res) = ... (query) | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:89:27:89:51 | (res) = ... (query) | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:89:27:89:51 | (res) = ... (query) | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:89:27:89:51 | (res) = ... (query) | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:89:27:89:51 | (res) = ... (query) | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:89:27:89:51 | (res) = ... (query) | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:89:27:89:51 | (res) = ... (query) | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:89:27:89:51 | (res) = ... (query) | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:89:46:89:50 | query | NosqlInjection | hasFlowFromSource | true | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:89:46:89:50 | query | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:89:46:89:50 | query | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -423,6 +468,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:27:90:27 | Y | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:27:90:27 | Y | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:27:90:27 | Y | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:27:90:27 | Y | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:27:90:27 | Y | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:27:90:27 | Y | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:27:90:27 | Y | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:27:90:27 | Y | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:30:90:54 | (err) = ... (query) | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:30:90:54 | (err) = ... (query) | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:30:90:54 | (err) = ... (query) | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -443,6 +493,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:30:90:54 | (err) = ... (query) | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:30:90:54 | (err) = ... (query) | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:30:90:54 | (err) = ... (query) | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:30:90:54 | (err) = ... (query) | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:30:90:54 | (err) = ... (query) | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:30:90:54 | (err) = ... (query) | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:30:90:54 | (err) = ... (query) | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:30:90:54 | (err) = ... (query) | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:92:16:92:16 | X | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:92:16:92:16 | X | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:92:16:92:16 | X | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -467,6 +522,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:92:19:92:51 | (err, r ... (query) | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:92:19:92:51 | (err, r ... (query) | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:92:19:92:51 | (err, r ... (query) | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:92:19:92:51 | (err, r ... (query) | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:92:19:92:51 | (err, r ... (query) | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:92:19:92:51 | (err, r ... (query) | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:92:19:92:51 | (err, r ... (query) | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:92:19:92:51 | (err, r ... (query) | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:92:46:92:50 | query | NosqlInjection | hasFlowFromSource | true | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:92:46:92:50 | query | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:92:46:92:50 | query | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -495,6 +555,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:93:19:93:48 | (err, r ... (query) | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:93:19:93:48 | (err, r ... (query) | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:93:19:93:48 | (err, r ... (query) | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:93:19:93:48 | (err, r ... (query) | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:93:19:93:48 | (err, r ... (query) | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:93:19:93:48 | (err, r ... (query) | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:93:19:93:48 | (err, r ... (query) | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:93:19:93:48 | (err, r ... (query) | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:94:16:94:16 | X | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:94:16:94:16 | X | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:94:16:94:16 | X | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -519,6 +584,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:94:24:94:56 | (err, r ... (query) | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:94:24:94:56 | (err, r ... (query) | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:94:24:94:56 | (err, r ... (query) | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:94:24:94:56 | (err, r ... (query) | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:94:24:94:56 | (err, r ... (query) | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:94:24:94:56 | (err, r ... (query) | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:94:24:94:56 | (err, r ... (query) | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:94:24:94:56 | (err, r ... (query) | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:94:51:94:55 | query | NosqlInjection | hasFlowFromSource | true | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:94:51:94:55 | query | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:94:51:94:55 | query | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -547,6 +617,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:95:24:95:53 | (err, r ... (query) | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:95:24:95:53 | (err, r ... (query) | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:95:24:95:53 | (err, r ... (query) | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:95:24:95:53 | (err, r ... (query) | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:95:24:95:53 | (err, r ... (query) | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:95:24:95:53 | (err, r ... (query) | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:95:24:95:53 | (err, r ... (query) | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:95:24:95:53 | (err, r ... (query) | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:96:16:96:16 | X | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:96:16:96:16 | X | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:96:16:96:16 | X | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -571,6 +646,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:96:24:96:51 | (res) = ... (query) | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:96:24:96:51 | (res) = ... (query) | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:96:24:96:51 | (res) = ... (query) | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:96:24:96:51 | (res) = ... (query) | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:96:24:96:51 | (res) = ... (query) | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:96:24:96:51 | (res) = ... (query) | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:96:24:96:51 | (res) = ... (query) | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:96:24:96:51 | (res) = ... (query) | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:96:46:96:50 | query | NosqlInjection | hasFlowFromSource | true | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:96:46:96:50 | query | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:96:46:96:50 | query | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -599,6 +679,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:24:97:24 | Y | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:24:97:24 | Y | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:24:97:24 | Y | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:24:97:24 | Y | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:24:97:24 | Y | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:24:97:24 | Y | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:24:97:24 | Y | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:24:97:24 | Y | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:27:97:51 | (err) = ... (query) | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:27:97:51 | (err) = ... (query) | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:27:97:51 | (err) = ... (query) | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -619,6 +704,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:27:97:51 | (err) = ... (query) | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:27:97:51 | (err) = ... (query) | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:27:97:51 | (err) = ... (query) | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:27:97:51 | (err) = ... (query) | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:27:97:51 | (err) = ... (query) | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:27:97:51 | (err) = ... (query) | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:27:97:51 | (err) = ... (query) | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:27:97:51 | (err) = ... (query) | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:99:17:99:17 | X | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:99:17:99:17 | X | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:99:17:99:17 | X | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -643,6 +733,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:99:20:99:49 | (err, r ... (query) | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:99:20:99:49 | (err, r ... (query) | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:99:20:99:49 | (err, r ... (query) | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:99:20:99:49 | (err, r ... (query) | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:99:20:99:49 | (err, r ... (query) | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:99:20:99:49 | (err, r ... (query) | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:99:20:99:49 | (err, r ... (query) | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:99:20:99:49 | (err, r ... (query) | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:111:14:111:18 | query | NosqlInjection | hasFlowFromSource | true | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:111:14:111:18 | query | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:111:14:111:18 | query | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -675,6 +770,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:113:38:113:52 | function () { } | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:113:38:113:52 | function () { } | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:113:38:113:52 | function () { } | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:113:38:113:52 | function () { } | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:113:38:113:52 | function () { } | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:113:38:113:52 | function () { } | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:113:38:113:52 | function () { } | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:113:38:113:52 | function () { } | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:116:22:116:25 | cond | NosqlInjection | hasFlowFromSource | true | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:116:22:116:25 | cond | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:116:22:116:25 | cond | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -795,6 +895,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:4:18:4:52 | process ... TRING'] | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:4:18:4:52 | process ... TRING'] | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:4:18:4:52 | process ... TRING'] | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:4:18:4:52 | process ... TRING'] | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:4:18:4:52 | process ... TRING'] | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:4:18:4:52 | process ... TRING'] | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:4:18:4:52 | process ... TRING'] | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:4:18:4:52 | process ... TRING'] | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:9:10:9:14 | query | SqlInjection | hasFlowFromSource | true | boolean | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:9:10:9:14 | query | SqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:9:10:9:14 | query | SqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -955,6 +1060,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:27:15:27:41 | functio ... es) { } | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:27:15:27:41 | functio ... es) { } | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:27:15:27:41 | functio ... es) { } | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -975,6 +1085,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/redis.js:27:15:27:41 | functio ... es) { } | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:27:15:27:41 | functio ... es) { } | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:27:15:27:41 | functio ... es) { } | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:27:15:27:41 | functio ... es) { } | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:27:15:27:41 | functio ... es) { } | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:27:15:27:41 | functio ... es) { } | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:27:15:27:41 | functio ... es) { } | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:27:15:27:41 | functio ... es) { } | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:29:22:31:5 | (err, n ... K\\n } | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:29:22:31:5 | (err, n ... K\\n } | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:29:22:31:5 | (err, n ... K\\n } | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -995,6 +1110,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/redis.js:29:22:31:5 | (err, n ... K\\n } | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:29:22:31:5 | (err, n ... K\\n } | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:29:22:31:5 | (err, n ... K\\n } | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:29:22:31:5 | (err, n ... K\\n } | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:29:22:31:5 | (err, n ... K\\n } | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:29:22:31:5 | (err, n ... K\\n } | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:29:22:31:5 | (err, n ... K\\n } | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:29:22:31:5 | (err, n ... K\\n } | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:30:23:30:25 | key | NosqlInjection | hasFlowFromSource | true | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:30:23:30:25 | key | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:30:23:30:25 | key | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1035,6 +1155,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/redis.js:49:35:49:37 | key | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:49:35:49:37 | key | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:49:35:49:37 | key | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:49:35:49:37 | key | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:49:35:49:37 | key | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:49:35:49:37 | key | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:49:35:49:37 | key | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:49:35:49:37 | key | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/socketio.js:10:24:12:3 | (handle ... `);\\n } | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/socketio.js:10:24:12:3 | (handle ... `);\\n } | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/socketio.js:10:24:12:3 | (handle ... `);\\n } | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1055,6 +1180,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/socketio.js:10:24:12:3 | (handle ... `);\\n } | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/socketio.js:10:24:12:3 | (handle ... `);\\n } | Xss | notASinkReason | EventRegistration | string | | autogenerated/NosqlAndSqlInjection/untyped/socketio.js:10:24:12:3 | (handle ... `);\\n } | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/socketio.js:10:24:12:3 | (handle ... `);\\n } | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/socketio.js:10:24:12:3 | (handle ... `);\\n } | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/socketio.js:10:24:12:3 | (handle ... `);\\n } | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/socketio.js:10:24:12:3 | (handle ... `);\\n } | XssThroughDom | notASinkReason | EventRegistration | string | +| autogenerated/NosqlAndSqlInjection/untyped/socketio.js:10:24:12:3 | (handle ... `);\\n } | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/socketio.js:11:12:11:53 | `INSERT ... andle}` | SqlInjection | hasFlowFromSource | true | boolean | | autogenerated/NosqlAndSqlInjection/untyped/socketio.js:11:12:11:53 | `INSERT ... andle}` | SqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/socketio.js:11:12:11:53 | `INSERT ... andle}` | SqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1091,6 +1221,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:22:9:23 | [] | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:22:9:23 | [] | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:22:9:23 | [] | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:22:9:23 | [] | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:22:9:23 | [] | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:22:9:23 | [] | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:22:9:23 | [] | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:22:9:23 | [] | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:26:11:3 | functio ... lts\\n } | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:26:11:3 | functio ... lts\\n } | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:26:11:3 | functio ... lts\\n } | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1111,6 +1246,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:26:11:3 | functio ... lts\\n } | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:26:11:3 | functio ... lts\\n } | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:26:11:3 | functio ... lts\\n } | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:26:11:3 | functio ... lts\\n } | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:26:11:3 | functio ... lts\\n } | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:26:11:3 | functio ... lts\\n } | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:26:11:3 | functio ... lts\\n } | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:9:26:11:3 | functio ... lts\\n } | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:14:16:19 | query2 | SqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:14:16:19 | query2 | SqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:14:16:19 | query2 | SqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1135,6 +1275,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:22:16:42 | [req.pa ... tegory] | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:22:16:42 | [req.pa ... tegory] | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:22:16:42 | [req.pa ... tegory] | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:22:16:42 | [req.pa ... tegory] | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:22:16:42 | [req.pa ... tegory] | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:22:16:42 | [req.pa ... tegory] | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:22:16:42 | [req.pa ... tegory] | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:22:16:42 | [req.pa ... tegory] | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:45:18:3 | functio ... lts\\n } | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:45:18:3 | functio ... lts\\n } | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:45:18:3 | functio ... lts\\n } | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1155,6 +1300,11 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:45:18:3 | functio ... lts\\n } | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:45:18:3 | functio ... lts\\n } | Xss | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:45:18:3 | functio ... lts\\n } | Xss | sinkLabel | NotASink | string | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:45:18:3 | functio ... lts\\n } | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:45:18:3 | functio ... lts\\n } | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:45:18:3 | functio ... lts\\n } | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:45:18:3 | functio ... lts\\n } | XssThroughDom | notASinkReason | DatabaseAccess | string | +| autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:45:18:3 | functio ... lts\\n } | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/NosqlAndSqlInjection/untyped/tst4.js:8:10:8:66 | 'SELECT ... d + '"' | SqlInjection | hasFlowFromSource | true | boolean | | autogenerated/NosqlAndSqlInjection/untyped/tst4.js:8:10:8:66 | 'SELECT ... d + '"' | SqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/tst4.js:8:10:8:66 | 'SELECT ... d + '"' | SqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1203,6 +1353,11 @@ endpoints | autogenerated/TaintedPath/TaintedPath.js:23:21:23:24 | path | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/TaintedPath.js:23:21:23:24 | path | Xss | notASinkReason | FileSystemAccess | string | | autogenerated/TaintedPath/TaintedPath.js:23:21:23:24 | path | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/TaintedPath.js:23:21:23:24 | path | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/TaintedPath.js:23:21:23:24 | path | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/TaintedPath.js:23:21:23:24 | path | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/TaintedPath.js:23:21:23:24 | path | XssThroughDom | notASinkReason | FileSystemAccess | string | +| autogenerated/TaintedPath/TaintedPath.js:23:21:23:24 | path | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/TaintedPath.js:24:33:24:36 | path | TaintedPath | hasFlowFromSource | true | boolean | | autogenerated/TaintedPath/TaintedPath.js:24:33:24:36 | path | TaintedPath | isConstantExpression | false | boolean | | autogenerated/TaintedPath/TaintedPath.js:24:33:24:36 | path | TaintedPath | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1311,6 +1466,11 @@ endpoints | autogenerated/TaintedPath/TaintedPath.js:102:44:102:47 | path | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/TaintedPath.js:102:44:102:47 | path | Xss | notASinkReason | FileSystemAccess | string | | autogenerated/TaintedPath/TaintedPath.js:102:44:102:47 | path | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/TaintedPath.js:102:44:102:47 | path | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/TaintedPath.js:102:44:102:47 | path | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/TaintedPath.js:102:44:102:47 | path | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/TaintedPath.js:102:44:102:47 | path | XssThroughDom | notASinkReason | FileSystemAccess | string | +| autogenerated/TaintedPath/TaintedPath.js:102:44:102:47 | path | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | NosqlInjection | hasFlowFromSource | true | boolean | | autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1331,6 +1491,11 @@ endpoints | autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | Xss | notASinkReason | FileSystemAccess | string | | autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | XssThroughDom | notASinkReason | FileSystemAccess | string | +| autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1351,6 +1516,11 @@ endpoints | autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | Xss | notASinkReason | FileSystemAccess | string | | autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | XssThroughDom | notASinkReason | FileSystemAccess | string | +| autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/TaintedPath.js:105:45:105:52 | realpath | TaintedPath | hasFlowFromSource | true | boolean | | autogenerated/TaintedPath/TaintedPath.js:105:45:105:52 | realpath | TaintedPath | isConstantExpression | false | boolean | | autogenerated/TaintedPath/TaintedPath.js:105:45:105:52 | realpath | TaintedPath | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1559,6 +1729,11 @@ endpoints | autogenerated/TaintedPath/normalizedPaths.js:49:24:49:44 | ".." + ... ule.sep | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:49:24:49:44 | ".." + ... ule.sep | Xss | notASinkReason | StringStartsWith | string | | autogenerated/TaintedPath/normalizedPaths.js:49:24:49:44 | ".." + ... ule.sep | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/normalizedPaths.js:49:24:49:44 | ".." + ... ule.sep | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:49:24:49:44 | ".." + ... ule.sep | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:49:24:49:44 | ".." + ... ule.sep | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:49:24:49:44 | ".." + ... ule.sep | XssThroughDom | notASinkReason | StringStartsWith | string | +| autogenerated/TaintedPath/normalizedPaths.js:49:24:49:44 | ".." + ... ule.sep | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/normalizedPaths.js:50:21:50:24 | path | TaintedPath | hasFlowFromSource | true | boolean | | autogenerated/TaintedPath/normalizedPaths.js:50:21:50:24 | path | TaintedPath | isConstantExpression | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:50:21:50:24 | path | TaintedPath | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1635,6 +1810,11 @@ endpoints | autogenerated/TaintedPath/normalizedPaths.js:117:30:117:43 | req.query.path | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:117:30:117:43 | req.query.path | Xss | notASinkReason | FileSystemAccess | string | | autogenerated/TaintedPath/normalizedPaths.js:117:30:117:43 | req.query.path | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/normalizedPaths.js:117:30:117:43 | req.query.path | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:117:30:117:43 | req.query.path | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:117:30:117:43 | req.query.path | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:117:30:117:43 | req.query.path | XssThroughDom | notASinkReason | FileSystemAccess | string | +| autogenerated/TaintedPath/normalizedPaths.js:117:30:117:43 | req.query.path | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/normalizedPaths.js:119:19:119:22 | path | TaintedPath | hasFlowFromSource | true | boolean | | autogenerated/TaintedPath/normalizedPaths.js:119:19:119:22 | path | TaintedPath | isConstantExpression | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:119:19:119:22 | path | TaintedPath | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1779,6 +1959,11 @@ endpoints | autogenerated/TaintedPath/normalizedPaths.js:242:25:242:39 | self.dir.length | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:242:25:242:39 | self.dir.length | Xss | notASinkReason | BuiltinCallName | string | | autogenerated/TaintedPath/normalizedPaths.js:242:25:242:39 | self.dir.length | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/normalizedPaths.js:242:25:242:39 | self.dir.length | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:242:25:242:39 | self.dir.length | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:242:25:242:39 | self.dir.length | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:242:25:242:39 | self.dir.length | XssThroughDom | notASinkReason | BuiltinCallName | string | +| autogenerated/TaintedPath/normalizedPaths.js:242:25:242:39 | self.dir.length | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/normalizedPaths.js:243:21:243:24 | path | TaintedPath | hasFlowFromSource | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:243:21:243:24 | path | TaintedPath | isConstantExpression | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:243:21:243:24 | path | TaintedPath | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1807,6 +1992,11 @@ endpoints | autogenerated/TaintedPath/normalizedPaths.js:247:21:247:35 | self.dir.length | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:247:21:247:35 | self.dir.length | Xss | notASinkReason | BuiltinCallName | string | | autogenerated/TaintedPath/normalizedPaths.js:247:21:247:35 | self.dir.length | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/normalizedPaths.js:247:21:247:35 | self.dir.length | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:247:21:247:35 | self.dir.length | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:247:21:247:35 | self.dir.length | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:247:21:247:35 | self.dir.length | XssThroughDom | notASinkReason | BuiltinCallName | string | +| autogenerated/TaintedPath/normalizedPaths.js:247:21:247:35 | self.dir.length | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/normalizedPaths.js:248:21:248:24 | path | TaintedPath | hasFlowFromSource | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:248:21:248:24 | path | TaintedPath | isConstantExpression | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:248:21:248:24 | path | TaintedPath | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1839,6 +2029,11 @@ endpoints | autogenerated/TaintedPath/normalizedPaths.js:261:26:261:46 | ".." + ... ule.sep | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:261:26:261:46 | ".." + ... ule.sep | Xss | notASinkReason | StringStartsWith | string | | autogenerated/TaintedPath/normalizedPaths.js:261:26:261:46 | ".." + ... ule.sep | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/normalizedPaths.js:261:26:261:46 | ".." + ... ule.sep | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:261:26:261:46 | ".." + ... ule.sep | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:261:26:261:46 | ".." + ... ule.sep | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:261:26:261:46 | ".." + ... ule.sep | XssThroughDom | notASinkReason | StringStartsWith | string | +| autogenerated/TaintedPath/normalizedPaths.js:261:26:261:46 | ".." + ... ule.sep | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/normalizedPaths.js:262:21:262:24 | path | TaintedPath | hasFlowFromSource | true | boolean | | autogenerated/TaintedPath/normalizedPaths.js:262:21:262:24 | path | TaintedPath | isConstantExpression | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:262:21:262:24 | path | TaintedPath | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1867,6 +2062,11 @@ endpoints | autogenerated/TaintedPath/normalizedPaths.js:269:28:269:48 | '..' + ... ule.sep | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:269:28:269:48 | '..' + ... ule.sep | Xss | notASinkReason | BuiltinCallName | string | | autogenerated/TaintedPath/normalizedPaths.js:269:28:269:48 | '..' + ... ule.sep | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/normalizedPaths.js:269:28:269:48 | '..' + ... ule.sep | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:269:28:269:48 | '..' + ... ule.sep | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:269:28:269:48 | '..' + ... ule.sep | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:269:28:269:48 | '..' + ... ule.sep | XssThroughDom | notASinkReason | BuiltinCallName | string | +| autogenerated/TaintedPath/normalizedPaths.js:269:28:269:48 | '..' + ... ule.sep | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/normalizedPaths.js:270:21:270:27 | newpath | TaintedPath | hasFlowFromSource | true | boolean | | autogenerated/TaintedPath/normalizedPaths.js:270:21:270:27 | newpath | TaintedPath | isConstantExpression | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:270:21:270:27 | newpath | TaintedPath | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1959,6 +2159,11 @@ endpoints | autogenerated/TaintedPath/normalizedPaths.js:345:18:345:21 | root | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:345:18:345:21 | root | Xss | notASinkReason | BuiltinCallName | string | | autogenerated/TaintedPath/normalizedPaths.js:345:18:345:21 | root | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/normalizedPaths.js:345:18:345:21 | root | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:345:18:345:21 | root | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:345:18:345:21 | root | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:345:18:345:21 | root | XssThroughDom | notASinkReason | BuiltinCallName | string | +| autogenerated/TaintedPath/normalizedPaths.js:345:18:345:21 | root | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/normalizedPaths.js:346:19:346:22 | path | TaintedPath | hasFlowFromSource | true | boolean | | autogenerated/TaintedPath/normalizedPaths.js:346:19:346:22 | path | TaintedPath | isConstantExpression | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:346:19:346:22 | path | TaintedPath | isExcludedFromEndToEndEvaluation | false | boolean | @@ -1991,6 +2196,11 @@ endpoints | autogenerated/TaintedPath/normalizedPaths.js:361:18:361:28 | requestPath | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:361:18:361:28 | requestPath | Xss | notASinkReason | StringStartsWith | string | | autogenerated/TaintedPath/normalizedPaths.js:361:18:361:28 | requestPath | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/normalizedPaths.js:361:18:361:28 | requestPath | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:361:18:361:28 | requestPath | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:361:18:361:28 | requestPath | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:361:18:361:28 | requestPath | XssThroughDom | notASinkReason | StringStartsWith | string | +| autogenerated/TaintedPath/normalizedPaths.js:361:18:361:28 | requestPath | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2011,6 +2221,11 @@ endpoints | autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | Xss | notASinkReason | StringStartsWith | string | | autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | XssThroughDom | notASinkReason | StringStartsWith | string | +| autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/normalizedPaths.js:363:21:363:31 | requestPath | TaintedPath | hasFlowFromSource | true | boolean | | autogenerated/TaintedPath/normalizedPaths.js:363:21:363:31 | requestPath | TaintedPath | isConstantExpression | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:363:21:363:31 | requestPath | TaintedPath | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2043,6 +2258,11 @@ endpoints | autogenerated/TaintedPath/normalizedPaths.js:371:32:371:39 | rootPath | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/normalizedPaths.js:371:32:371:39 | rootPath | Xss | notASinkReason | BuiltinCallName | string | | autogenerated/TaintedPath/normalizedPaths.js:371:32:371:39 | rootPath | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/normalizedPaths.js:371:32:371:39 | rootPath | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:371:32:371:39 | rootPath | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:371:32:371:39 | rootPath | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/normalizedPaths.js:371:32:371:39 | rootPath | XssThroughDom | notASinkReason | BuiltinCallName | string | +| autogenerated/TaintedPath/normalizedPaths.js:371:32:371:39 | rootPath | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/other-fs-libraries.js:11:19:11:22 | path | TaintedPath | hasFlowFromSource | true | boolean | | autogenerated/TaintedPath/other-fs-libraries.js:11:19:11:22 | path | TaintedPath | isConstantExpression | false | boolean | | autogenerated/TaintedPath/other-fs-libraries.js:11:19:11:22 | path | TaintedPath | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2179,6 +2399,11 @@ endpoints | autogenerated/TaintedPath/tainted-sendFile.js:13:16:13:33 | req.param("gimme") | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:13:16:13:33 | req.param("gimme") | Xss | notASinkReason | FileSystemAccess | string | | autogenerated/TaintedPath/tainted-sendFile.js:13:16:13:33 | req.param("gimme") | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/tainted-sendFile.js:13:16:13:33 | req.param("gimme") | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:13:16:13:33 | req.param("gimme") | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:13:16:13:33 | req.param("gimme") | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:13:16:13:33 | req.param("gimme") | XssThroughDom | notASinkReason | FileSystemAccess | string | +| autogenerated/TaintedPath/tainted-sendFile.js:13:16:13:33 | req.param("gimme") | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/tainted-sendFile.js:13:36:13:58 | { root: ... cwd() } | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:13:36:13:58 | { root: ... cwd() } | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:13:36:13:58 | { root: ... cwd() } | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2199,6 +2424,11 @@ endpoints | autogenerated/TaintedPath/tainted-sendFile.js:13:36:13:58 | { root: ... cwd() } | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:13:36:13:58 | { root: ... cwd() } | Xss | notASinkReason | FileSystemAccess | string | | autogenerated/TaintedPath/tainted-sendFile.js:13:36:13:58 | { root: ... cwd() } | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/tainted-sendFile.js:13:36:13:58 | { root: ... cwd() } | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:13:36:13:58 | { root: ... cwd() } | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:13:36:13:58 | { root: ... cwd() } | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:13:36:13:58 | { root: ... cwd() } | XssThroughDom | notASinkReason | FileSystemAccess | string | +| autogenerated/TaintedPath/tainted-sendFile.js:13:36:13:58 | { root: ... cwd() } | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/tainted-sendFile.js:13:44:13:56 | process.cwd() | TaintedPath | hasFlowFromSource | false | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:13:44:13:56 | process.cwd() | TaintedPath | isConstantExpression | false | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:13:44:13:56 | process.cwd() | TaintedPath | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2223,6 +2453,11 @@ endpoints | autogenerated/TaintedPath/tainted-sendFile.js:15:16:15:33 | req.param("gimme") | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:15:16:15:33 | req.param("gimme") | Xss | notASinkReason | FileSystemAccess | string | | autogenerated/TaintedPath/tainted-sendFile.js:15:16:15:33 | req.param("gimme") | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/tainted-sendFile.js:15:16:15:33 | req.param("gimme") | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:15:16:15:33 | req.param("gimme") | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:15:16:15:33 | req.param("gimme") | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:15:16:15:33 | req.param("gimme") | XssThroughDom | notASinkReason | FileSystemAccess | string | +| autogenerated/TaintedPath/tainted-sendFile.js:15:16:15:33 | req.param("gimme") | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/tainted-sendFile.js:15:36:15:58 | { root: ... cwd() } | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:15:36:15:58 | { root: ... cwd() } | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:15:36:15:58 | { root: ... cwd() } | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2243,6 +2478,11 @@ endpoints | autogenerated/TaintedPath/tainted-sendFile.js:15:36:15:58 | { root: ... cwd() } | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:15:36:15:58 | { root: ... cwd() } | Xss | notASinkReason | FileSystemAccess | string | | autogenerated/TaintedPath/tainted-sendFile.js:15:36:15:58 | { root: ... cwd() } | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/tainted-sendFile.js:15:36:15:58 | { root: ... cwd() } | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:15:36:15:58 | { root: ... cwd() } | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:15:36:15:58 | { root: ... cwd() } | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:15:36:15:58 | { root: ... cwd() } | XssThroughDom | notASinkReason | FileSystemAccess | string | +| autogenerated/TaintedPath/tainted-sendFile.js:15:36:15:58 | { root: ... cwd() } | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/tainted-sendFile.js:15:44:15:56 | process.cwd() | TaintedPath | hasFlowFromSource | false | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:15:44:15:56 | process.cwd() | TaintedPath | isConstantExpression | false | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:15:44:15:56 | process.cwd() | TaintedPath | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2267,6 +2507,11 @@ endpoints | autogenerated/TaintedPath/tainted-sendFile.js:18:16:18:32 | req.param("file") | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:18:16:18:32 | req.param("file") | Xss | notASinkReason | FileSystemAccess | string | | autogenerated/TaintedPath/tainted-sendFile.js:18:16:18:32 | req.param("file") | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/tainted-sendFile.js:18:16:18:32 | req.param("file") | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:18:16:18:32 | req.param("file") | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:18:16:18:32 | req.param("file") | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:18:16:18:32 | req.param("file") | XssThroughDom | notASinkReason | FileSystemAccess | string | +| autogenerated/TaintedPath/tainted-sendFile.js:18:16:18:32 | req.param("file") | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/tainted-sendFile.js:18:35:18:60 | { root: ... dir") } | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:18:35:18:60 | { root: ... dir") } | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:18:35:18:60 | { root: ... dir") } | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2287,6 +2532,11 @@ endpoints | autogenerated/TaintedPath/tainted-sendFile.js:18:35:18:60 | { root: ... dir") } | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:18:35:18:60 | { root: ... dir") } | Xss | notASinkReason | FileSystemAccess | string | | autogenerated/TaintedPath/tainted-sendFile.js:18:35:18:60 | { root: ... dir") } | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/tainted-sendFile.js:18:35:18:60 | { root: ... dir") } | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:18:35:18:60 | { root: ... dir") } | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:18:35:18:60 | { root: ... dir") } | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/tainted-sendFile.js:18:35:18:60 | { root: ... dir") } | XssThroughDom | notASinkReason | FileSystemAccess | string | +| autogenerated/TaintedPath/tainted-sendFile.js:18:35:18:60 | { root: ... dir") } | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/tainted-sendFile.js:18:43:18:58 | req.param("dir") | TaintedPath | hasFlowFromSource | true | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:18:43:18:58 | req.param("dir") | TaintedPath | isConstantExpression | false | boolean | | autogenerated/TaintedPath/tainted-sendFile.js:18:43:18:58 | req.param("dir") | TaintedPath | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2335,6 +2585,11 @@ endpoints | autogenerated/TaintedPath/tainted-string-steps.js:7:33:7:33 | i | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/tainted-string-steps.js:7:33:7:33 | i | Xss | notASinkReason | BuiltinCallName | string | | autogenerated/TaintedPath/tainted-string-steps.js:7:33:7:33 | i | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/tainted-string-steps.js:7:33:7:33 | i | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/tainted-string-steps.js:7:33:7:33 | i | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/tainted-string-steps.js:7:33:7:33 | i | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/tainted-string-steps.js:7:33:7:33 | i | XssThroughDom | notASinkReason | BuiltinCallName | string | +| autogenerated/TaintedPath/tainted-string-steps.js:7:33:7:33 | i | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/tainted-string-steps.js:7:36:7:36 | j | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/TaintedPath/tainted-string-steps.js:7:36:7:36 | j | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/TaintedPath/tainted-string-steps.js:7:36:7:36 | j | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2355,6 +2610,11 @@ endpoints | autogenerated/TaintedPath/tainted-string-steps.js:7:36:7:36 | j | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/tainted-string-steps.js:7:36:7:36 | j | Xss | notASinkReason | BuiltinCallName | string | | autogenerated/TaintedPath/tainted-string-steps.js:7:36:7:36 | j | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/tainted-string-steps.js:7:36:7:36 | j | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/tainted-string-steps.js:7:36:7:36 | j | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/tainted-string-steps.js:7:36:7:36 | j | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/tainted-string-steps.js:7:36:7:36 | j | XssThroughDom | notASinkReason | BuiltinCallName | string | +| autogenerated/TaintedPath/tainted-string-steps.js:7:36:7:36 | j | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/tainted-string-steps.js:8:18:8:34 | path.substring(4) | TaintedPath | hasFlowFromSource | true | boolean | | autogenerated/TaintedPath/tainted-string-steps.js:8:18:8:34 | path.substring(4) | TaintedPath | isConstantExpression | false | boolean | | autogenerated/TaintedPath/tainted-string-steps.js:8:18:8:34 | path.substring(4) | TaintedPath | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2383,6 +2643,11 @@ endpoints | autogenerated/TaintedPath/tainted-string-steps.js:9:36:9:36 | i | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/TaintedPath/tainted-string-steps.js:9:36:9:36 | i | Xss | notASinkReason | BuiltinCallName | string | | autogenerated/TaintedPath/tainted-string-steps.js:9:36:9:36 | i | Xss | sinkLabel | NotASink | string | +| autogenerated/TaintedPath/tainted-string-steps.js:9:36:9:36 | i | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/TaintedPath/tainted-string-steps.js:9:36:9:36 | i | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/TaintedPath/tainted-string-steps.js:9:36:9:36 | i | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/TaintedPath/tainted-string-steps.js:9:36:9:36 | i | XssThroughDom | notASinkReason | BuiltinCallName | string | +| autogenerated/TaintedPath/tainted-string-steps.js:9:36:9:36 | i | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/TaintedPath/tainted-string-steps.js:10:18:10:31 | path.substr(4) | TaintedPath | hasFlowFromSource | true | boolean | | autogenerated/TaintedPath/tainted-string-steps.js:10:18:10:31 | path.substr(4) | TaintedPath | isConstantExpression | false | boolean | | autogenerated/TaintedPath/tainted-string-steps.js:10:18:10:31 | path.substr(4) | TaintedPath | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2679,6 +2944,11 @@ endpoints | autogenerated/Xss/DomBasedXss/jquery.js:5:13:5:19 | tainted | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/jquery.js:5:13:5:19 | tainted | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/DomBasedXss/jquery.js:5:13:5:19 | tainted | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/jquery.js:5:13:5:19 | tainted | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/jquery.js:5:13:5:19 | tainted | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/jquery.js:5:13:5:19 | tainted | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/jquery.js:5:13:5:19 | tainted | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/DomBasedXss/jquery.js:5:13:5:19 | tainted | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | NosqlInjection | hasFlowFromSource | true | boolean | | autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2699,6 +2969,11 @@ endpoints | autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/jquery.js:7:5:7:34 | "
    " | Xss | hasFlowFromSource | true | boolean | | autogenerated/Xss/DomBasedXss/jquery.js:7:5:7:34 | "
    " | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/jquery.js:7:5:7:34 | "
    " | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2755,6 +3030,12 @@ endpoints | autogenerated/Xss/DomBasedXss/jwt.js:4:8:4:17 | loginUrl() | Xss | notASinkReason | ClientRequest | string | | autogenerated/Xss/DomBasedXss/jwt.js:4:8:4:17 | loginUrl() | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/DomBasedXss/jwt.js:4:8:4:17 | loginUrl() | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/jwt.js:4:8:4:17 | loginUrl() | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/jwt.js:4:8:4:17 | loginUrl() | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/jwt.js:4:8:4:17 | loginUrl() | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/jwt.js:4:8:4:17 | loginUrl() | XssThroughDom | notASinkReason | ClientRequest | string | +| autogenerated/Xss/DomBasedXss/jwt.js:4:8:4:17 | loginUrl() | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/DomBasedXss/jwt.js:4:8:4:17 | loginUrl() | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/jwt.js:4:20:4:32 | {data: "foo"} | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/Xss/DomBasedXss/jwt.js:4:20:4:32 | {data: "foo"} | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/jwt.js:4:20:4:32 | {data: "foo"} | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2779,6 +3060,12 @@ endpoints | autogenerated/Xss/DomBasedXss/jwt.js:4:20:4:32 | {data: "foo"} | Xss | notASinkReason | ClientRequest | string | | autogenerated/Xss/DomBasedXss/jwt.js:4:20:4:32 | {data: "foo"} | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/DomBasedXss/jwt.js:4:20:4:32 | {data: "foo"} | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/jwt.js:4:20:4:32 | {data: "foo"} | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/jwt.js:4:20:4:32 | {data: "foo"} | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/jwt.js:4:20:4:32 | {data: "foo"} | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/jwt.js:4:20:4:32 | {data: "foo"} | XssThroughDom | notASinkReason | ClientRequest | string | +| autogenerated/Xss/DomBasedXss/jwt.js:4:20:4:32 | {data: "foo"} | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/DomBasedXss/jwt.js:4:20:4:32 | {data: "foo"} | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/jwt.js:4:35:7:1 | (data, ... ENCY]\\n} | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/Xss/DomBasedXss/jwt.js:4:35:7:1 | (data, ... ENCY]\\n} | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/jwt.js:4:35:7:1 | (data, ... ENCY]\\n} | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2803,6 +3090,12 @@ endpoints | autogenerated/Xss/DomBasedXss/jwt.js:4:35:7:1 | (data, ... ENCY]\\n} | Xss | notASinkReason | ClientRequest | string | | autogenerated/Xss/DomBasedXss/jwt.js:4:35:7:1 | (data, ... ENCY]\\n} | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/DomBasedXss/jwt.js:4:35:7:1 | (data, ... ENCY]\\n} | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/jwt.js:4:35:7:1 | (data, ... ENCY]\\n} | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/jwt.js:4:35:7:1 | (data, ... ENCY]\\n} | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/jwt.js:4:35:7:1 | (data, ... ENCY]\\n} | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/jwt.js:4:35:7:1 | (data, ... ENCY]\\n} | XssThroughDom | notASinkReason | ClientRequest | string | +| autogenerated/Xss/DomBasedXss/jwt.js:4:35:7:1 | (data, ... ENCY]\\n} | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/DomBasedXss/jwt.js:4:35:7:1 | (data, ... ENCY]\\n} | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/jwt.js:6:14:6:20 | decoded | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/DomBasedXss/jwt.js:6:14:6:20 | decoded | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/jwt.js:6:14:6:20 | decoded | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2859,6 +3152,11 @@ endpoints | autogenerated/Xss/DomBasedXss/optionalSanitizer.js:34:28:34:35 | tainted2 | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/optionalSanitizer.js:34:28:34:35 | tainted2 | Xss | notASinkReason | DOM | string | | autogenerated/Xss/DomBasedXss/optionalSanitizer.js:34:28:34:35 | tainted2 | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/optionalSanitizer.js:34:28:34:35 | tainted2 | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/optionalSanitizer.js:34:28:34:35 | tainted2 | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/optionalSanitizer.js:34:28:34:35 | tainted2 | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/optionalSanitizer.js:34:28:34:35 | tainted2 | XssThroughDom | notASinkReason | DOM | string | +| autogenerated/Xss/DomBasedXss/optionalSanitizer.js:34:28:34:35 | tainted2 | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/optionalSanitizer.js:36:18:36:25 | tainted2 | Xss | hasFlowFromSource | true | boolean | | autogenerated/Xss/DomBasedXss/optionalSanitizer.js:36:18:36:25 | tainted2 | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/optionalSanitizer.js:36:18:36:25 | tainted2 | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2887,6 +3185,11 @@ endpoints | autogenerated/Xss/DomBasedXss/optionalSanitizer.js:41:28:41:35 | tainted3 | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/optionalSanitizer.js:41:28:41:35 | tainted3 | Xss | notASinkReason | DOM | string | | autogenerated/Xss/DomBasedXss/optionalSanitizer.js:41:28:41:35 | tainted3 | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/optionalSanitizer.js:41:28:41:35 | tainted3 | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/optionalSanitizer.js:41:28:41:35 | tainted3 | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/optionalSanitizer.js:41:28:41:35 | tainted3 | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/optionalSanitizer.js:41:28:41:35 | tainted3 | XssThroughDom | notASinkReason | DOM | string | +| autogenerated/Xss/DomBasedXss/optionalSanitizer.js:41:28:41:35 | tainted3 | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/optionalSanitizer.js:43:18:43:25 | tainted3 | Xss | hasFlowFromSource | true | boolean | | autogenerated/Xss/DomBasedXss/optionalSanitizer.js:43:18:43:25 | tainted3 | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/optionalSanitizer.js:43:18:43:25 | tainted3 | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2915,6 +3218,11 @@ endpoints | autogenerated/Xss/DomBasedXss/optionalSanitizer.js:45:41:45:46 | target | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/optionalSanitizer.js:45:41:45:46 | target | Xss | notASinkReason | DOM | string | | autogenerated/Xss/DomBasedXss/optionalSanitizer.js:45:41:45:46 | target | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/optionalSanitizer.js:45:41:45:46 | target | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/optionalSanitizer.js:45:41:45:46 | target | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/optionalSanitizer.js:45:41:45:46 | target | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/optionalSanitizer.js:45:41:45:46 | target | XssThroughDom | notASinkReason | DOM | string | +| autogenerated/Xss/DomBasedXss/optionalSanitizer.js:45:41:45:46 | target | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/react-native.js:8:18:8:24 | tainted | Xss | hasFlowFromSource | true | boolean | | autogenerated/Xss/DomBasedXss/react-native.js:8:18:8:24 | tainted | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/react-native.js:8:18:8:24 | tainted | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -2979,6 +3287,11 @@ endpoints | autogenerated/Xss/DomBasedXss/sanitiser.js:22:18:22:24 | tainted | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/sanitiser.js:22:18:22:24 | tainted | Xss | notASinkReason | StringRegExpTest | string | | autogenerated/Xss/DomBasedXss/sanitiser.js:22:18:22:24 | tainted | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/sanitiser.js:22:18:22:24 | tainted | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/sanitiser.js:22:18:22:24 | tainted | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/sanitiser.js:22:18:22:24 | tainted | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/sanitiser.js:22:18:22:24 | tainted | XssThroughDom | notASinkReason | StringRegExpTest | string | +| autogenerated/Xss/DomBasedXss/sanitiser.js:22:18:22:24 | tainted | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/sanitiser.js:23:21:23:44 | '' + ... '' | Xss | hasFlowFromSource | true | boolean | | autogenerated/Xss/DomBasedXss/sanitiser.js:23:21:23:44 | '' + ... '' | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/sanitiser.js:23:21:23:44 | '' + ... '' | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3007,6 +3320,11 @@ endpoints | autogenerated/Xss/DomBasedXss/sanitiser.js:27:19:27:25 | tainted | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/sanitiser.js:27:19:27:25 | tainted | Xss | notASinkReason | StringRegExpTest | string | | autogenerated/Xss/DomBasedXss/sanitiser.js:27:19:27:25 | tainted | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/sanitiser.js:27:19:27:25 | tainted | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/sanitiser.js:27:19:27:25 | tainted | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/sanitiser.js:27:19:27:25 | tainted | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/sanitiser.js:27:19:27:25 | tainted | XssThroughDom | notASinkReason | StringRegExpTest | string | +| autogenerated/Xss/DomBasedXss/sanitiser.js:27:19:27:25 | tainted | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/sanitiser.js:28:21:28:44 | '' + ... '' | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/DomBasedXss/sanitiser.js:28:21:28:44 | '' + ... '' | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/sanitiser.js:28:21:28:44 | '' + ... '' | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3035,6 +3353,11 @@ endpoints | autogenerated/Xss/DomBasedXss/sanitiser.js:32:18:32:24 | tainted | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/sanitiser.js:32:18:32:24 | tainted | Xss | notASinkReason | StringRegExpTest | string | | autogenerated/Xss/DomBasedXss/sanitiser.js:32:18:32:24 | tainted | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/sanitiser.js:32:18:32:24 | tainted | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/sanitiser.js:32:18:32:24 | tainted | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/sanitiser.js:32:18:32:24 | tainted | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/sanitiser.js:32:18:32:24 | tainted | XssThroughDom | notASinkReason | StringRegExpTest | string | +| autogenerated/Xss/DomBasedXss/sanitiser.js:32:18:32:24 | tainted | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/sanitiser.js:33:21:33:44 | '' + ... '' | Xss | hasFlowFromSource | true | boolean | | autogenerated/Xss/DomBasedXss/sanitiser.js:33:21:33:44 | '' + ... '' | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/sanitiser.js:33:21:33:44 | '' + ... '' | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3083,6 +3406,11 @@ endpoints | autogenerated/Xss/DomBasedXss/stored-xss.js:2:39:2:62 | documen ... .search | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/stored-xss.js:2:39:2:62 | documen ... .search | Xss | notASinkReason | ReceiverStorage | string | | autogenerated/Xss/DomBasedXss/stored-xss.js:2:39:2:62 | documen ... .search | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/stored-xss.js:2:39:2:62 | documen ... .search | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/stored-xss.js:2:39:2:62 | documen ... .search | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/stored-xss.js:2:39:2:62 | documen ... .search | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/stored-xss.js:2:39:2:62 | documen ... .search | XssThroughDom | notASinkReason | ReceiverStorage | string | +| autogenerated/Xss/DomBasedXss/stored-xss.js:2:39:2:62 | documen ... .search | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/stored-xss.js:3:35:3:58 | documen ... .search | NosqlInjection | hasFlowFromSource | true | boolean | | autogenerated/Xss/DomBasedXss/stored-xss.js:3:35:3:58 | documen ... .search | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/stored-xss.js:3:35:3:58 | documen ... .search | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3103,6 +3431,11 @@ endpoints | autogenerated/Xss/DomBasedXss/stored-xss.js:3:35:3:58 | documen ... .search | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/stored-xss.js:3:35:3:58 | documen ... .search | Xss | notASinkReason | ReceiverStorage | string | | autogenerated/Xss/DomBasedXss/stored-xss.js:3:35:3:58 | documen ... .search | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/stored-xss.js:3:35:3:58 | documen ... .search | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/stored-xss.js:3:35:3:58 | documen ... .search | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/stored-xss.js:3:35:3:58 | documen ... .search | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/stored-xss.js:3:35:3:58 | documen ... .search | XssThroughDom | notASinkReason | ReceiverStorage | string | +| autogenerated/Xss/DomBasedXss/stored-xss.js:3:35:3:58 | documen ... .search | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/stored-xss.js:5:20:5:52 | session ... ssion') | Xss | hasFlowFromSource | true | boolean | | autogenerated/Xss/DomBasedXss/stored-xss.js:5:20:5:52 | session ... ssion') | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/stored-xss.js:5:20:5:52 | session ... ssion') | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3235,6 +3568,11 @@ endpoints | autogenerated/Xss/DomBasedXss/tst.js:8:70:8:113 | documen ... lt=")+8 | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/tst.js:8:70:8:113 | documen ... lt=")+8 | Xss | notASinkReason | BuiltinCallName | string | | autogenerated/Xss/DomBasedXss/tst.js:8:70:8:113 | documen ... lt=")+8 | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/tst.js:8:70:8:113 | documen ... lt=")+8 | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:8:70:8:113 | documen ... lt=")+8 | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:8:70:8:113 | documen ... lt=")+8 | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:8:70:8:113 | documen ... lt=")+8 | XssThroughDom | notASinkReason | BuiltinCallName | string | +| autogenerated/Xss/DomBasedXss/tst.js:8:70:8:113 | documen ... lt=")+8 | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/tst.js:12:5:12:42 | '
    ' | Xss | hasFlowFromSource | true | boolean | | autogenerated/Xss/DomBasedXss/tst.js:12:5:12:42 | '
    ' | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/tst.js:12:5:12:42 | '
    ' | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3287,6 +3625,11 @@ endpoints | autogenerated/Xss/DomBasedXss/tst.js:40:20:40:43 | documen ... .search | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/tst.js:40:20:40:43 | documen ... .search | Xss | notASinkReason | DOM | string | | autogenerated/Xss/DomBasedXss/tst.js:40:20:40:43 | documen ... .search | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/tst.js:40:20:40:43 | documen ... .search | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:40:20:40:43 | documen ... .search | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:40:20:40:43 | documen ... .search | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:40:20:40:43 | documen ... .search | XssThroughDom | notASinkReason | DOM | string | +| autogenerated/Xss/DomBasedXss/tst.js:40:20:40:43 | documen ... .search | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/tst.js:46:16:46:45 | wrap(do ... search) | Xss | hasFlowFromSource | true | boolean | | autogenerated/Xss/DomBasedXss/tst.js:46:16:46:45 | wrap(do ... search) | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/tst.js:46:16:46:45 | wrap(do ... search) | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3375,6 +3718,12 @@ endpoints | autogenerated/Xss/DomBasedXss/tst.js:112:20:112:20 | v | Xss | notASinkReason | MembershipCandidateTest | string | | autogenerated/Xss/DomBasedXss/tst.js:112:20:112:20 | v | Xss | notASinkReason | StringRegExpTest | string | | autogenerated/Xss/DomBasedXss/tst.js:112:20:112:20 | v | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/tst.js:112:20:112:20 | v | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:112:20:112:20 | v | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:112:20:112:20 | v | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:112:20:112:20 | v | XssThroughDom | notASinkReason | MembershipCandidateTest | string | +| autogenerated/Xss/DomBasedXss/tst.js:112:20:112:20 | v | XssThroughDom | notASinkReason | StringRegExpTest | string | +| autogenerated/Xss/DomBasedXss/tst.js:112:20:112:20 | v | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/tst.js:114:20:114:20 | v | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/DomBasedXss/tst.js:114:20:114:20 | v | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/tst.js:114:20:114:20 | v | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3407,6 +3756,12 @@ endpoints | autogenerated/Xss/DomBasedXss/tst.js:122:15:122:21 | /^\\d+$/ | Xss | notASinkReason | MembershipCandidateTest | string | | autogenerated/Xss/DomBasedXss/tst.js:122:15:122:21 | /^\\d+$/ | Xss | notASinkReason | StringRegExpTest | string | | autogenerated/Xss/DomBasedXss/tst.js:122:15:122:21 | /^\\d+$/ | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/tst.js:122:15:122:21 | /^\\d+$/ | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:122:15:122:21 | /^\\d+$/ | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:122:15:122:21 | /^\\d+$/ | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:122:15:122:21 | /^\\d+$/ | XssThroughDom | notASinkReason | MembershipCandidateTest | string | +| autogenerated/Xss/DomBasedXss/tst.js:122:15:122:21 | /^\\d+$/ | XssThroughDom | notASinkReason | StringRegExpTest | string | +| autogenerated/Xss/DomBasedXss/tst.js:122:15:122:21 | /^\\d+$/ | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/tst.js:124:22:124:22 | v | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/DomBasedXss/tst.js:124:22:124:22 | v | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/tst.js:124:22:124:22 | v | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3435,6 +3790,11 @@ endpoints | autogenerated/Xss/DomBasedXss/tst.js:132:20:132:20 | v | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/tst.js:132:20:132:20 | v | Xss | notASinkReason | StringRegExpTest | string | | autogenerated/Xss/DomBasedXss/tst.js:132:20:132:20 | v | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/tst.js:132:20:132:20 | v | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:132:20:132:20 | v | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:132:20:132:20 | v | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:132:20:132:20 | v | XssThroughDom | notASinkReason | StringRegExpTest | string | +| autogenerated/Xss/DomBasedXss/tst.js:132:20:132:20 | v | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/tst.js:136:18:136:18 | v | Xss | hasFlowFromSource | true | boolean | | autogenerated/Xss/DomBasedXss/tst.js:136:18:136:18 | v | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/tst.js:136:18:136:18 | v | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3463,6 +3823,12 @@ endpoints | autogenerated/Xss/DomBasedXss/tst.js:138:22:138:22 | v | Xss | notASinkReason | MembershipCandidateTest | string | | autogenerated/Xss/DomBasedXss/tst.js:138:22:138:22 | v | Xss | notASinkReason | StringRegExpTest | string | | autogenerated/Xss/DomBasedXss/tst.js:138:22:138:22 | v | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/tst.js:138:22:138:22 | v | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:138:22:138:22 | v | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:138:22:138:22 | v | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:138:22:138:22 | v | XssThroughDom | notASinkReason | MembershipCandidateTest | string | +| autogenerated/Xss/DomBasedXss/tst.js:138:22:138:22 | v | XssThroughDom | notASinkReason | StringRegExpTest | string | +| autogenerated/Xss/DomBasedXss/tst.js:138:22:138:22 | v | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/tst.js:142:18:142:18 | v | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/DomBasedXss/tst.js:142:18:142:18 | v | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/tst.js:142:18:142:18 | v | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3675,6 +4041,11 @@ endpoints | autogenerated/Xss/DomBasedXss/tst.js:359:13:364:3 | functio ... OK.\\n\\t\\t} | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/tst.js:359:13:364:3 | functio ... OK.\\n\\t\\t} | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/DomBasedXss/tst.js:359:13:364:3 | functio ... OK.\\n\\t\\t} | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/tst.js:359:13:364:3 | functio ... OK.\\n\\t\\t} | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:359:13:364:3 | functio ... OK.\\n\\t\\t} | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:359:13:364:3 | functio ... OK.\\n\\t\\t} | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/tst.js:359:13:364:3 | functio ... OK.\\n\\t\\t} | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/DomBasedXss/tst.js:359:13:364:3 | functio ... OK.\\n\\t\\t} | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/tst.js:360:21:360:26 | target | Xss | hasFlowFromSource | true | boolean | | autogenerated/Xss/DomBasedXss/tst.js:360:21:360:26 | target | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/tst.js:360:21:360:26 | target | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3771,6 +4142,11 @@ endpoints | autogenerated/Xss/DomBasedXss/typeahead.js:2:38:4:3 | {\\n p ... Url\\n } | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:2:38:4:3 | {\\n p ... Url\\n } | Xss | notASinkReason | ClientRequest | string | | autogenerated/Xss/DomBasedXss/typeahead.js:2:38:4:3 | {\\n p ... Url\\n } | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/typeahead.js:2:38:4:3 | {\\n p ... Url\\n } | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:2:38:4:3 | {\\n p ... Url\\n } | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:2:38:4:3 | {\\n p ... Url\\n } | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:2:38:4:3 | {\\n p ... Url\\n } | XssThroughDom | notASinkReason | ClientRequest | string | +| autogenerated/Xss/DomBasedXss/typeahead.js:2:38:4:3 | {\\n p ... Url\\n } | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/typeahead.js:3:15:3:23 | remoteUrl | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:3:15:3:23 | remoteUrl | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:3:15:3:23 | remoteUrl | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3791,6 +4167,11 @@ endpoints | autogenerated/Xss/DomBasedXss/typeahead.js:3:15:3:23 | remoteUrl | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:3:15:3:23 | remoteUrl | Xss | notASinkReason | ClientRequest | string | | autogenerated/Xss/DomBasedXss/typeahead.js:3:15:3:23 | remoteUrl | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/typeahead.js:3:15:3:23 | remoteUrl | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:3:15:3:23 | remoteUrl | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:3:15:3:23 | remoteUrl | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:3:15:3:23 | remoteUrl | XssThroughDom | notASinkReason | ClientRequest | string | +| autogenerated/Xss/DomBasedXss/typeahead.js:3:15:3:23 | remoteUrl | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/typeahead.js:6:29:6:30 | {} | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:6:29:6:30 | {} | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:6:29:6:30 | {} | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3811,6 +4192,11 @@ endpoints | autogenerated/Xss/DomBasedXss/typeahead.js:6:29:6:30 | {} | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:6:29:6:30 | {} | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/DomBasedXss/typeahead.js:6:29:6:30 | {} | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/typeahead.js:6:29:6:30 | {} | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:6:29:6:30 | {} | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:6:29:6:30 | {} | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:6:29:6:30 | {} | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/DomBasedXss/typeahead.js:6:29:6:30 | {} | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/typeahead.js:6:33:13:3 | {\\n s ... }\\n } | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:6:33:13:3 | {\\n s ... }\\n } | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:6:33:13:3 | {\\n s ... }\\n } | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3831,6 +4217,11 @@ endpoints | autogenerated/Xss/DomBasedXss/typeahead.js:6:33:13:3 | {\\n s ... }\\n } | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:6:33:13:3 | {\\n s ... }\\n } | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/DomBasedXss/typeahead.js:6:33:13:3 | {\\n s ... }\\n } | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/typeahead.js:6:33:13:3 | {\\n s ... }\\n } | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:6:33:13:3 | {\\n s ... }\\n } | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:6:33:13:3 | {\\n s ... }\\n } | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:6:33:13:3 | {\\n s ... }\\n } | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/DomBasedXss/typeahead.js:6:33:13:3 | {\\n s ... }\\n } | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/typeahead.js:10:16:10:18 | loc | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:10:16:10:18 | loc | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:10:16:10:18 | loc | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3855,6 +4246,11 @@ endpoints | autogenerated/Xss/DomBasedXss/typeahead.js:16:29:16:30 | {} | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:16:29:16:30 | {} | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/DomBasedXss/typeahead.js:16:29:16:30 | {} | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/typeahead.js:16:29:16:30 | {} | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:16:29:16:30 | {} | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:16:29:16:30 | {} | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:16:29:16:30 | {} | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/DomBasedXss/typeahead.js:16:29:16:30 | {} | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/typeahead.js:17:5:28:5 | {\\n ... }\\n } | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:17:5:28:5 | {\\n ... }\\n } | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:17:5:28:5 | {\\n ... }\\n } | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3875,6 +4271,11 @@ endpoints | autogenerated/Xss/DomBasedXss/typeahead.js:17:5:28:5 | {\\n ... }\\n } | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:17:5:28:5 | {\\n ... }\\n } | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/DomBasedXss/typeahead.js:17:5:28:5 | {\\n ... }\\n } | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/typeahead.js:17:5:28:5 | {\\n ... }\\n } | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:17:5:28:5 | {\\n ... }\\n } | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:17:5:28:5 | {\\n ... }\\n } | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/typeahead.js:17:5:28:5 | {\\n ... }\\n } | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/DomBasedXss/typeahead.js:17:5:28:5 | {\\n ... }\\n } | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/typeahead.js:25:18:25:20 | val | Xss | hasFlowFromSource | true | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:25:18:25:20 | val | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/typeahead.js:25:18:25:20 | val | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3911,6 +4312,11 @@ endpoints | autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:6:19:6:25 | tainted | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:6:19:6:25 | tainted | Xss | notASinkReason | ConstantReceiver | string | | autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:6:19:6:25 | tainted | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:6:19:6:25 | tainted | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:6:19:6:25 | tainted | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:6:19:6:25 | tainted | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:6:19:6:25 | tainted | XssThroughDom | notASinkReason | ConstantReceiver | string | +| autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:6:19:6:25 | tainted | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:7:4:7:38 | ["
    ... .join() | Xss | hasFlowFromSource | true | boolean | | autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:7:4:7:38 | ["
    ... .join() | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:7:4:7:38 | ["
    ... .join() | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -3947,6 +4353,11 @@ endpoints | autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:11:24:11:30 | tainted | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:11:24:11:30 | tainted | Xss | notASinkReason | ConstantReceiver | string | | autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:11:24:11:30 | tainted | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:11:24:11:30 | tainted | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:11:24:11:30 | tainted | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:11:24:11:30 | tainted | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:11:24:11:30 | tainted | XssThroughDom | notASinkReason | ConstantReceiver | string | +| autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:11:24:11:30 | tainted | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:12:4:12:41 | ["
    " + ... "" | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeHtmlConstruction/main.js:62:11:62:40 | "" + ... "" | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeHtmlConstruction/main.js:62:11:62:40 | "" + ... "" | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -4939,6 +5535,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:18:6:18:11 | target | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:18:6:18:11 | target | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:18:6:18:11 | target | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:18:6:18:11 | target | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:18:6:18:11 | target | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:18:6:18:11 | target | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:18:6:18:11 | target | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:18:6:18:11 | target | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:22:6:22:11 | target | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:22:6:22:11 | target | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:22:6:22:11 | target | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5019,6 +5620,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:33:67:34 | {} | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:33:67:34 | {} | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:33:67:34 | {} | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:33:67:34 | {} | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:33:67:34 | {} | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:33:67:34 | {} | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:33:67:34 | {} | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:33:67:34 | {} | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:37:67:43 | options | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:37:67:43 | options | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:37:67:43 | options | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5039,6 +5645,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:37:67:43 | options | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:37:67:43 | options | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:37:67:43 | options | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:37:67:43 | options | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:37:67:43 | options | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:37:67:43 | options | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:37:67:43 | options | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:67:37:67:43 | options | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5079,6 +5690,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:81:5:81:24 | "#" + options.target | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:81:5:81:24 | "#" + options.target | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:81:5:81:24 | "#" + options.target | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:81:5:81:24 | "#" + options.target | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:81:5:81:24 | "#" + options.target | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:81:5:81:24 | "#" + options.target | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:81:5:81:24 | "#" + options.target | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:81:5:81:24 | "#" + options.target | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:22:86:23 | {} | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:22:86:23 | {} | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:22:86:23 | {} | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5099,6 +5715,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:22:86:23 | {} | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:22:86:23 | {} | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:22:86:23 | {} | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:22:86:23 | {} | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:22:86:23 | {} | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:22:86:23 | {} | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:22:86:23 | {} | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:22:86:23 | {} | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:26:86:26 | o | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:26:86:26 | o | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:26:86:26 | o | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5119,6 +5740,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:26:86:26 | o | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:26:86:26 | o | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:26:86:26 | o | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:26:86:26 | o | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:26:86:26 | o | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:26:86:26 | o | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:26:86:26 | o | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:86:26:86:26 | o | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:89:16:89:16 | t | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:89:16:89:16 | t | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:89:16:89:16 | t | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5139,6 +5765,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:89:16:89:16 | t | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:89:16:89:16 | t | Xss | notASinkReason | LoggerMethod | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:89:16:89:16 | t | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:89:16:89:16 | t | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:89:16:89:16 | t | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:89:16:89:16 | t | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:89:16:89:16 | t | XssThroughDom | notASinkReason | LoggerMethod | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:89:16:89:16 | t | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:90:6:90:6 | t | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:90:6:90:6 | t | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:90:6:90:6 | t | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5163,6 +5794,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:97:16:97:21 | target | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:97:16:97:21 | target | Xss | notASinkReason | MembershipCandidateTest | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:97:16:97:21 | target | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:97:16:97:21 | target | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:97:16:97:21 | target | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:97:16:97:21 | target | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:97:16:97:21 | target | XssThroughDom | notASinkReason | MembershipCandidateTest | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:97:16:97:21 | target | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:98:6:98:11 | target | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:98:6:98:11 | target | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:98:6:98:11 | target | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5187,6 +5823,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:102:22:105:3 | {\\n\\t\\t\\tme ... in'\\n\\t\\t} | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:102:22:105:3 | {\\n\\t\\t\\tme ... in'\\n\\t\\t} | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:102:22:105:3 | {\\n\\t\\t\\tme ... in'\\n\\t\\t} | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:102:22:105:3 | {\\n\\t\\t\\tme ... in'\\n\\t\\t} | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:102:22:105:3 | {\\n\\t\\t\\tme ... in'\\n\\t\\t} | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:102:22:105:3 | {\\n\\t\\t\\tme ... in'\\n\\t\\t} | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:102:22:105:3 | {\\n\\t\\t\\tme ... in'\\n\\t\\t} | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:102:22:105:3 | {\\n\\t\\t\\tme ... in'\\n\\t\\t} | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:105:6:105:12 | options | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:105:6:105:12 | options | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:105:6:105:12 | options | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5207,6 +5848,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:105:6:105:12 | options | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:105:6:105:12 | options | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:105:6:105:12 | options | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:105:6:105:12 | options | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:105:6:105:12 | options | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:105:6:105:12 | options | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:105:6:105:12 | options | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:105:6:105:12 | options | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:106:5:106:16 | options.menu | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:106:5:106:16 | options.menu | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:106:5:106:16 | options.menu | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5235,6 +5881,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:22:115:23 | {} | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:22:115:23 | {} | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:22:115:23 | {} | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:22:115:23 | {} | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:22:115:23 | {} | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:22:115:23 | {} | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:22:115:23 | {} | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:22:115:23 | {} | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:26:115:48 | $.fn.my ... efaults | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:26:115:48 | $.fn.my ... efaults | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:26:115:48 | $.fn.my ... efaults | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5255,6 +5906,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:26:115:48 | $.fn.my ... efaults | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:26:115:48 | $.fn.my ... efaults | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:26:115:48 | $.fn.my ... efaults | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:26:115:48 | $.fn.my ... efaults | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:26:115:48 | $.fn.my ... efaults | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:26:115:48 | $.fn.my ... efaults | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:26:115:48 | $.fn.my ... efaults | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:26:115:48 | $.fn.my ... efaults | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:51:115:57 | options | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:51:115:57 | options | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:51:115:57 | options | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5275,6 +5931,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:51:115:57 | options | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:51:115:57 | options | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:51:115:57 | options | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:51:115:57 | options | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:51:115:57 | options | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:51:115:57 | options | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:51:115:57 | options | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:115:51:115:57 | options | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:116:5:116:16 | options.menu | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:116:5:116:16 | options.menu | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:116:5:116:16 | options.menu | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5307,6 +5968,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:11:125:14 | $.fn | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:11:125:14 | $.fn | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:11:125:14 | $.fn | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:11:125:14 | $.fn | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:11:125:14 | $.fn | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:11:125:14 | $.fn | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:11:125:14 | $.fn | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:11:125:14 | $.fn | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:17:129:2 | {\\n\\t\\tmy_ ... \\n\\t\\t}\\n\\t} | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:17:129:2 | {\\n\\t\\tmy_ ... \\n\\t\\t}\\n\\t} | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:17:129:2 | {\\n\\t\\tmy_ ... \\n\\t\\t}\\n\\t} | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5327,6 +5993,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:17:129:2 | {\\n\\t\\tmy_ ... \\n\\t\\t}\\n\\t} | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:17:129:2 | {\\n\\t\\tmy_ ... \\n\\t\\t}\\n\\t} | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:17:129:2 | {\\n\\t\\tmy_ ... \\n\\t\\t}\\n\\t} | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:17:129:2 | {\\n\\t\\tmy_ ... \\n\\t\\t}\\n\\t} | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:17:129:2 | {\\n\\t\\tmy_ ... \\n\\t\\t}\\n\\t} | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:17:129:2 | {\\n\\t\\tmy_ ... \\n\\t\\t}\\n\\t} | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:17:129:2 | {\\n\\t\\tmy_ ... \\n\\t\\t}\\n\\t} | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:125:17:129:2 | {\\n\\t\\tmy_ ... \\n\\t\\t}\\n\\t} | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:127:6:127:19 | options.target | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:127:6:127:19 | options.target | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:127:6:127:19 | options.target | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5383,6 +6054,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:155:59:155:64 | target | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:155:59:155:64 | target | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:155:59:155:64 | target | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:155:59:155:64 | target | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:155:59:155:64 | target | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:155:59:155:64 | target | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:155:59:155:64 | target | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:155:59:155:64 | target | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:156:41:156:54 | options.target | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:156:41:156:54 | options.target | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:156:41:156:54 | options.target | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5411,6 +6087,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:156:75:156:88 | options.target | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:156:75:156:88 | options.target | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:156:75:156:88 | options.target | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:156:75:156:88 | options.target | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:156:75:156:88 | options.target | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:156:75:156:88 | options.target | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:156:75:156:88 | options.target | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:156:75:156:88 | options.target | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5439,6 +6120,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:157:80:157:95 | options.target.a | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:157:80:157:95 | options.target.a | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:157:80:157:95 | options.target.a | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:157:80:157:95 | options.target.a | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:157:80:157:95 | options.target.a | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:157:80:157:95 | options.target.a | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:157:80:157:95 | options.target.a | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:157:80:157:95 | options.target.a | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:161:5:161:30 | anyPref ... .target | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:161:5:161:30 | anyPref ... .target | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:161:5:161:30 | anyPref ... .target | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5483,6 +6169,11 @@ endpoints | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:182:20:182:33 | options.target | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:182:20:182:33 | options.target | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:182:20:182:33 | options.target | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:182:20:182:33 | options.target | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:182:20:182:33 | options.target | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:182:20:182:33 | options.target | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:182:20:182:33 | options.target | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/UnsafeJQueryPlugin/unsafe-jquery-plugin.js:182:20:182:33 | options.target | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/XssThroughDom/forms.js:9:31:9:40 | values.foo | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/XssThroughDom/forms.js:9:31:9:40 | values.foo | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/XssThroughDom/forms.js:9:31:9:40 | values.foo | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5567,6 +6258,11 @@ endpoints | autogenerated/Xss/XssThroughDom/xss-through-dom.js:7:40:7:53 | {"foo": "bar"} | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/XssThroughDom/xss-through-dom.js:7:40:7:53 | {"foo": "bar"} | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/XssThroughDom/xss-through-dom.js:7:40:7:53 | {"foo": "bar"} | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/XssThroughDom/xss-through-dom.js:7:40:7:53 | {"foo": "bar"} | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/XssThroughDom/xss-through-dom.js:7:40:7:53 | {"foo": "bar"} | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/XssThroughDom/xss-through-dom.js:7:40:7:53 | {"foo": "bar"} | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/XssThroughDom/xss-through-dom.js:7:40:7:53 | {"foo": "bar"} | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/XssThroughDom/xss-through-dom.js:7:40:7:53 | {"foo": "bar"} | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/XssThroughDom/xss-through-dom.js:8:16:8:53 | $(".som ... arget") | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/XssThroughDom/xss-through-dom.js:8:16:8:53 | $(".som ... arget") | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/XssThroughDom/xss-through-dom.js:8:16:8:53 | $(".som ... arget") | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5615,6 +6311,11 @@ endpoints | autogenerated/Xss/XssThroughDom/xss-through-dom.js:40:16:40:16 | x | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/XssThroughDom/xss-through-dom.js:40:16:40:16 | x | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/XssThroughDom/xss-through-dom.js:40:16:40:16 | x | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/XssThroughDom/xss-through-dom.js:40:16:40:16 | x | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/XssThroughDom/xss-through-dom.js:40:16:40:16 | x | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/XssThroughDom/xss-through-dom.js:40:16:40:16 | x | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/XssThroughDom/xss-through-dom.js:40:16:40:16 | x | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/XssThroughDom/xss-through-dom.js:40:16:40:16 | x | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/XssThroughDom/xss-through-dom.js:47:3:47:40 | $("

    " ... .text() | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/XssThroughDom/xss-through-dom.js:47:3:47:40 | $("

    " ... .text() | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/XssThroughDom/xss-through-dom.js:47:3:47:40 | $("

    " ... .text() | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5707,6 +6408,11 @@ endpoints | autogenerated/Xss/XssThroughDom/xss-through-dom.js:89:23:91:2 | functio ... / OK\\n\\t} | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/Xss/XssThroughDom/xss-through-dom.js:89:23:91:2 | functio ... / OK\\n\\t} | Xss | notASinkReason | JQueryArgument | string | | autogenerated/Xss/XssThroughDom/xss-through-dom.js:89:23:91:2 | functio ... / OK\\n\\t} | Xss | sinkLabel | NotASink | string | +| autogenerated/Xss/XssThroughDom/xss-through-dom.js:89:23:91:2 | functio ... / OK\\n\\t} | XssThroughDom | hasFlowFromSource | false | boolean | +| autogenerated/Xss/XssThroughDom/xss-through-dom.js:89:23:91:2 | functio ... / OK\\n\\t} | XssThroughDom | isConstantExpression | false | boolean | +| autogenerated/Xss/XssThroughDom/xss-through-dom.js:89:23:91:2 | functio ... / OK\\n\\t} | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| autogenerated/Xss/XssThroughDom/xss-through-dom.js:89:23:91:2 | functio ... / OK\\n\\t} | XssThroughDom | notASinkReason | JQueryArgument | string | +| autogenerated/Xss/XssThroughDom/xss-through-dom.js:89:23:91:2 | functio ... / OK\\n\\t} | XssThroughDom | sinkLabel | NotASink | string | | autogenerated/Xss/XssThroughDom/xss-through-dom.js:90:22:90:124 | "" | Xss | hasFlowFromSource | false | boolean | | autogenerated/Xss/XssThroughDom/xss-through-dom.js:90:22:90:124 | "" | Xss | isConstantExpression | false | boolean | | autogenerated/Xss/XssThroughDom/xss-through-dom.js:90:22:90:124 | "" | Xss | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5735,6 +6441,11 @@ endpoints | index.js:21:9:21:9 | x | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | index.js:21:9:21:9 | x | Xss | notASinkReason | LodashUnderscoreArgument | string | | index.js:21:9:21:9 | x | Xss | sinkLabel | NotASink | string | +| index.js:21:9:21:9 | x | XssThroughDom | hasFlowFromSource | false | boolean | +| index.js:21:9:21:9 | x | XssThroughDom | isConstantExpression | false | boolean | +| index.js:21:9:21:9 | x | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| index.js:21:9:21:9 | x | XssThroughDom | notASinkReason | LodashUnderscoreArgument | string | +| index.js:21:9:21:9 | x | XssThroughDom | sinkLabel | NotASink | string | | index.js:29:13:29:31 | { 'isAdmin': true } | NosqlInjection | hasFlowFromSource | false | boolean | | index.js:29:13:29:31 | { 'isAdmin': true } | NosqlInjection | isConstantExpression | false | boolean | | index.js:29:13:29:31 | { 'isAdmin': true } | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5759,6 +6470,11 @@ endpoints | index.js:30:11:38:5 | functio ... }\\n } | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | index.js:30:11:38:5 | functio ... }\\n } | Xss | notASinkReason | DatabaseAccess | string | | index.js:30:11:38:5 | functio ... }\\n } | Xss | sinkLabel | NotASink | string | +| index.js:30:11:38:5 | functio ... }\\n } | XssThroughDom | hasFlowFromSource | false | boolean | +| index.js:30:11:38:5 | functio ... }\\n } | XssThroughDom | isConstantExpression | false | boolean | +| index.js:30:11:38:5 | functio ... }\\n } | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| index.js:30:11:38:5 | functio ... }\\n } | XssThroughDom | notASinkReason | DatabaseAccess | string | +| index.js:30:11:38:5 | functio ... }\\n } | XssThroughDom | sinkLabel | NotASink | string | | index.js:36:21:36:33 | adminUsers[i] | NosqlInjection | hasFlowFromSource | false | boolean | | index.js:36:21:36:33 | adminUsers[i] | NosqlInjection | isConstantExpression | false | boolean | | index.js:36:21:36:33 | adminUsers[i] | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5779,6 +6495,11 @@ endpoints | index.js:36:21:36:33 | adminUsers[i] | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | index.js:36:21:36:33 | adminUsers[i] | Xss | notASinkReason | LoggerMethod | string | | index.js:36:21:36:33 | adminUsers[i] | Xss | sinkLabel | NotASink | string | +| index.js:36:21:36:33 | adminUsers[i] | XssThroughDom | hasFlowFromSource | false | boolean | +| index.js:36:21:36:33 | adminUsers[i] | XssThroughDom | isConstantExpression | false | boolean | +| index.js:36:21:36:33 | adminUsers[i] | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| index.js:36:21:36:33 | adminUsers[i] | XssThroughDom | notASinkReason | LoggerMethod | string | +| index.js:36:21:36:33 | adminUsers[i] | XssThroughDom | sinkLabel | NotASink | string | | index.js:46:35:46:69 | c > 100 ... ENERAL' | NosqlInjection | hasFlowFromSource | false | boolean | | index.js:46:35:46:69 | c > 100 ... ENERAL' | NosqlInjection | isConstantExpression | false | boolean | | index.js:46:35:46:69 | c > 100 ... ENERAL' | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5799,6 +6520,11 @@ endpoints | index.js:46:35:46:69 | c > 100 ... ENERAL' | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | index.js:46:35:46:69 | c > 100 ... ENERAL' | Xss | notASinkReason | LoggerMethod | string | | index.js:46:35:46:69 | c > 100 ... ENERAL' | Xss | sinkLabel | NotASink | string | +| index.js:46:35:46:69 | c > 100 ... ENERAL' | XssThroughDom | hasFlowFromSource | false | boolean | +| index.js:46:35:46:69 | c > 100 ... ENERAL' | XssThroughDom | isConstantExpression | false | boolean | +| index.js:46:35:46:69 | c > 100 ... ENERAL' | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| index.js:46:35:46:69 | c > 100 ... ENERAL' | XssThroughDom | notASinkReason | LoggerMethod | string | +| index.js:46:35:46:69 | c > 100 ... ENERAL' | XssThroughDom | sinkLabel | NotASink | string | | index.js:46:72:46:72 | x | NosqlInjection | hasFlowFromSource | false | boolean | | index.js:46:72:46:72 | x | NosqlInjection | isConstantExpression | false | boolean | | index.js:46:72:46:72 | x | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5819,6 +6545,11 @@ endpoints | index.js:46:72:46:72 | x | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | index.js:46:72:46:72 | x | Xss | notASinkReason | LoggerMethod | string | | index.js:46:72:46:72 | x | Xss | sinkLabel | NotASink | string | +| index.js:46:72:46:72 | x | XssThroughDom | hasFlowFromSource | false | boolean | +| index.js:46:72:46:72 | x | XssThroughDom | isConstantExpression | false | boolean | +| index.js:46:72:46:72 | x | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| index.js:46:72:46:72 | x | XssThroughDom | notASinkReason | LoggerMethod | string | +| index.js:46:72:46:72 | x | XssThroughDom | sinkLabel | NotASink | string | | index.js:46:75:46:75 | o | NosqlInjection | hasFlowFromSource | false | boolean | | index.js:46:75:46:75 | o | NosqlInjection | isConstantExpression | false | boolean | | index.js:46:75:46:75 | o | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5839,6 +6570,11 @@ endpoints | index.js:46:75:46:75 | o | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | index.js:46:75:46:75 | o | Xss | notASinkReason | LoggerMethod | string | | index.js:46:75:46:75 | o | Xss | sinkLabel | NotASink | string | +| index.js:46:75:46:75 | o | XssThroughDom | hasFlowFromSource | false | boolean | +| index.js:46:75:46:75 | o | XssThroughDom | isConstantExpression | false | boolean | +| index.js:46:75:46:75 | o | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| index.js:46:75:46:75 | o | XssThroughDom | notASinkReason | LoggerMethod | string | +| index.js:46:75:46:75 | o | XssThroughDom | sinkLabel | NotASink | string | | index.js:50:15:50:19 | ready | NosqlInjection | hasFlowFromSource | false | boolean | | index.js:50:15:50:19 | ready | NosqlInjection | isConstantExpression | false | boolean | | index.js:50:15:50:19 | ready | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -5859,6 +6595,11 @@ endpoints | index.js:50:15:50:19 | ready | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | index.js:50:15:50:19 | ready | Xss | notASinkReason | Timeout | string | | index.js:50:15:50:19 | ready | Xss | sinkLabel | NotASink | string | +| index.js:50:15:50:19 | ready | XssThroughDom | hasFlowFromSource | false | boolean | +| index.js:50:15:50:19 | ready | XssThroughDom | isConstantExpression | false | boolean | +| index.js:50:15:50:19 | ready | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| index.js:50:15:50:19 | ready | XssThroughDom | notASinkReason | Timeout | string | +| index.js:50:15:50:19 | ready | XssThroughDom | sinkLabel | NotASink | string | tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:27:22:27:26 | query | CalleeFlexibleAccessPath | doc.find | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:27:22:27:26 | query | InputAccessPathFromCallee | | diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.expected b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.expected index cb29a7ee955..f2e04cfa063 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.expected +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.expected @@ -14,3 +14,11 @@ xssFilteredTruePositives | autogenerated/Xss/DomBasedXss/tst.js:316:35:316:42 | location | not a direct argument to a likely external library call or a heuristic sink (xss) | | autogenerated/Xss/DomBasedXss/typeahead.js:10:16:10:18 | loc | not a direct argument to a likely external library call or a heuristic sink (xss) | | autogenerated/Xss/DomBasedXss/typeahead.js:25:18:25:20 | val | not a direct argument to a likely external library call or a heuristic sink (xss) | +xssThroughDomFilteredTruePositives +| autogenerated/Xss/DomBasedXss/d3.js:12:20:12:29 | getTaint() | not a direct argument to a likely external library call or a heuristic sink (xss) | +| autogenerated/Xss/DomBasedXss/d3.js:14:20:14:29 | getTaint() | not a direct argument to a likely external library call or a heuristic sink (xss) | +| autogenerated/Xss/DomBasedXss/express.js:7:15:7:33 | req.param("wobble") | not a direct argument to a likely external library call or a heuristic sink (xss) | +| autogenerated/Xss/DomBasedXss/jwt-server.js:11:19:11:29 | decoded.foo | not a direct argument to a likely external library call or a heuristic sink (xss) | +| autogenerated/Xss/DomBasedXss/tst.js:316:35:316:42 | location | not a direct argument to a likely external library call or a heuristic sink (xss) | +| autogenerated/Xss/DomBasedXss/typeahead.js:10:16:10:18 | loc | not a direct argument to a likely external library call or a heuristic sink (xss) | +| autogenerated/Xss/DomBasedXss/typeahead.js:25:18:25:20 | val | not a direct argument to a likely external library call or a heuristic sink (xss) | diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_unit_tests/ExtractEndpointDataTraining.expected b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_unit_tests/ExtractEndpointDataTraining.expected index bbdd33e8965..55423976708 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_unit_tests/ExtractEndpointDataTraining.expected +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_unit_tests/ExtractEndpointDataTraining.expected @@ -23,6 +23,11 @@ endpoints | index.js:15:17:15:32 | req.body.isAdmin | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | index.js:15:17:15:32 | req.body.isAdmin | Xss | notASinkReason | LoggerMethod | string | | index.js:15:17:15:32 | req.body.isAdmin | Xss | sinkLabel | NotASink | string | +| index.js:15:17:15:32 | req.body.isAdmin | XssThroughDom | hasFlowFromSource | false | boolean | +| index.js:15:17:15:32 | req.body.isAdmin | XssThroughDom | isConstantExpression | false | boolean | +| index.js:15:17:15:32 | req.body.isAdmin | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| index.js:15:17:15:32 | req.body.isAdmin | XssThroughDom | notASinkReason | LoggerMethod | string | +| index.js:15:17:15:32 | req.body.isAdmin | XssThroughDom | sinkLabel | NotASink | string | | index.js:20:13:20:31 | { 'isAdmin': true } | NosqlInjection | hasFlowFromSource | false | boolean | | index.js:20:13:20:31 | { 'isAdmin': true } | NosqlInjection | isConstantExpression | false | boolean | | index.js:20:13:20:31 | { 'isAdmin': true } | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -55,6 +60,12 @@ endpoints | index.js:83:10:85:3 | {\\n " ... ar,\\n } | Xss | notASinkReason | ClientRequest | string | | index.js:83:10:85:3 | {\\n " ... ar,\\n } | Xss | notASinkReason | JQueryArgument | string | | index.js:83:10:85:3 | {\\n " ... ar,\\n } | Xss | sinkLabel | NotASink | string | +| index.js:83:10:85:3 | {\\n " ... ar,\\n } | XssThroughDom | hasFlowFromSource | false | boolean | +| index.js:83:10:85:3 | {\\n " ... ar,\\n } | XssThroughDom | isConstantExpression | false | boolean | +| index.js:83:10:85:3 | {\\n " ... ar,\\n } | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| index.js:83:10:85:3 | {\\n " ... ar,\\n } | XssThroughDom | notASinkReason | ClientRequest | string | +| index.js:83:10:85:3 | {\\n " ... ar,\\n } | XssThroughDom | notASinkReason | JQueryArgument | string | +| index.js:83:10:85:3 | {\\n " ... ar,\\n } | XssThroughDom | sinkLabel | NotASink | string | | index.js:84:12:84:18 | foo.bar | NosqlInjection | hasFlowFromSource | false | boolean | | index.js:84:12:84:18 | foo.bar | NosqlInjection | isConstantExpression | false | boolean | | index.js:84:12:84:18 | foo.bar | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | @@ -75,6 +86,11 @@ endpoints | index.js:84:12:84:18 | foo.bar | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | index.js:84:12:84:18 | foo.bar | Xss | notASinkReason | ClientRequest | string | | index.js:84:12:84:18 | foo.bar | Xss | sinkLabel | NotASink | string | +| index.js:84:12:84:18 | foo.bar | XssThroughDom | hasFlowFromSource | false | boolean | +| index.js:84:12:84:18 | foo.bar | XssThroughDom | isConstantExpression | false | boolean | +| index.js:84:12:84:18 | foo.bar | XssThroughDom | isExcludedFromEndToEndEvaluation | false | boolean | +| index.js:84:12:84:18 | foo.bar | XssThroughDom | notASinkReason | ClientRequest | string | +| index.js:84:12:84:18 | foo.bar | XssThroughDom | sinkLabel | NotASink | string | tokenFeatures | index.js:9:15:9:45 | { 'isAd ... Admin } | CalleeFlexibleAccessPath | User.find | | index.js:9:15:9:45 | { 'isAd ... Admin } | InputAccessPathFromCallee | | From 65021e6ed9bfc833daf443d4796790eb854d7b13 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 1 Dec 2022 17:16:33 +0000 Subject: [PATCH 757/796] Add go.work file --- go.work | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 go.work diff --git a/go.work b/go.work new file mode 100644 index 00000000000..3dd8ff5b5e0 --- /dev/null +++ b/go.work @@ -0,0 +1,5 @@ +go 1.18 + +use ( + ./go +) From ae0d82efd881d2a835eb094af79c5b43d62901dd Mon Sep 17 00:00:00 2001 From: Jean Helie Date: Thu, 1 Dec 2022 18:22:33 +0100 Subject: [PATCH 758/796] ATM: update predicate name --- .../experimental/adaptivethreatmodeling/src/XssThroughDomATM.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/XssThroughDomATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/XssThroughDomATM.ql index 60df6941400..494b308893f 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/XssThroughDomATM.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/XssThroughDomATM.ql @@ -19,7 +19,7 @@ import DataFlow::PathGraph import experimental.adaptivethreatmodeling.XssThroughDomATM from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score -where cfg.getAlerts(source, sink, score) +where cfg.hasBoostedFlowPath(source, sink, score) select sink.getNode(), source, sink, "(Experimental) $@ may be reinterpreted as HTML without escaping meta-characters. Identified using machine learning.", source.getNode(), "DOM text", score From 98923cee94ebcfc0a9560456a3d2b829f8a7a6c7 Mon Sep 17 00:00:00 2001 From: Jean Helie Date: Thu, 1 Dec 2022 18:47:36 +0100 Subject: [PATCH 759/796] ATM: update missing .qll --- .../modelbuilding/extraction/ExtractEndpointDataTraining.qll | 3 +++ 1 file changed, 3 insertions(+) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll index 99cba794cfa..763c74c7cf3 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll @@ -14,6 +14,7 @@ private import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInj private import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm private import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm private import experimental.adaptivethreatmodeling.XssATM as XssAtm +private import experimental.adaptivethreatmodeling.XssThroughDomATM as XssThroughDomAtm /** * Gets the set of featureName-featureValue pairs for each endpoint in the training set. @@ -214,6 +215,8 @@ DataFlow::Configuration getDataFlowCfg(Query query) { query instanceof TaintedPathQuery and result instanceof TaintedPathAtm::TaintedPathAtmConfig or query instanceof XssQuery and result instanceof XssAtm::DomBasedXssAtmConfig + or + query instanceof XssThroughDomQuery and result instanceof XssThroughDomAtm::XssThroughDomAtmConfig } // TODO: Delete this once we are no longer surfacing `hasFlowFromSource`. From 352d1a7e8cb5c043e75fb0a87f79d124d22f9d45 Mon Sep 17 00:00:00 2001 From: Jean Helie Date: Thu, 1 Dec 2022 19:01:30 +0100 Subject: [PATCH 760/796] ATM: update tests --- .../ExtractEndpointDataTraining.expected | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataTraining.expected b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataTraining.expected index 378827bd6d4..18822ab887b 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataTraining.expected +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataTraining.expected @@ -1028,34 +1028,34 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/redis.js:15:20:15:35 | ["key", "value"] | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:15:20:15:35 | ["key", "value"] | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:15:20:15:35 | ["key", "value"] | NosqlInjection | sinkLabel | Sink | string | -| autogenerated/NosqlAndSqlInjection/untyped/redis.js:18:16:18:18 | key | NosqlInjection | hasFlowFromSource | true | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:18:16:18:18 | key | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:18:16:18:18 | key | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:18:16:18:18 | key | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:18:16:18:18 | key | NosqlInjection | sinkLabel | Sink | string | -| autogenerated/NosqlAndSqlInjection/untyped/redis.js:19:43:19:45 | key | NosqlInjection | hasFlowFromSource | true | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:19:43:19:45 | key | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:19:43:19:45 | key | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:19:43:19:45 | key | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:19:43:19:45 | key | NosqlInjection | sinkLabel | Sink | string | -| autogenerated/NosqlAndSqlInjection/untyped/redis.js:25:14:25:16 | key | NosqlInjection | hasFlowFromSource | true | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:25:14:25:16 | key | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:25:14:25:16 | key | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:25:14:25:16 | key | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:25:14:25:16 | key | NosqlInjection | sinkLabel | Sink | string | -| autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | NosqlInjection | hasFlowFromSource | true | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | NosqlInjection | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | NosqlInjection | sinkLabel | NotASink | string | -| autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | SqlInjection | hasFlowFromSource | true | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | SqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | SqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | SqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | SqlInjection | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | SqlInjection | sinkLabel | NotASink | string | -| autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | TaintedPath | hasFlowFromSource | true | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | TaintedPath | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | TaintedPath | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | TaintedPath | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | TaintedPath | notASinkReason | DatabaseAccess | string | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | TaintedPath | sinkLabel | NotASink | string | -| autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | Xss | hasFlowFromSource | true | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | Xss | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | Xss | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | Xss | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:26:14:26:16 | key | Xss | notASinkReason | DatabaseAccess | string | @@ -1119,7 +1119,7 @@ endpoints | autogenerated/NosqlAndSqlInjection/untyped/redis.js:30:23:30:25 | key | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:30:23:30:25 | key | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:30:23:30:25 | key | NosqlInjection | sinkLabel | Sink | string | -| autogenerated/NosqlAndSqlInjection/untyped/redis.js:32:28:32:30 | key | NosqlInjection | hasFlowFromSource | true | boolean | +| autogenerated/NosqlAndSqlInjection/untyped/redis.js:32:28:32:30 | key | NosqlInjection | hasFlowFromSource | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:32:28:32:30 | key | NosqlInjection | isConstantExpression | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:32:28:32:30 | key | NosqlInjection | isExcludedFromEndToEndEvaluation | false | boolean | | autogenerated/NosqlAndSqlInjection/untyped/redis.js:32:28:32:30 | key | NosqlInjection | sinkLabel | Sink | string | From f1ebaf1ae10ba13b66491424085fca60063a7a4d Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Thu, 1 Dec 2022 13:56:13 -0500 Subject: [PATCH 761/796] add csharp query --- .../ql/src/Telemetry/SupportedExternalApis.ql | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 csharp/ql/src/Telemetry/SupportedExternalApis.ql diff --git a/csharp/ql/src/Telemetry/SupportedExternalApis.ql b/csharp/ql/src/Telemetry/SupportedExternalApis.ql new file mode 100644 index 00000000000..039f2a24677 --- /dev/null +++ b/csharp/ql/src/Telemetry/SupportedExternalApis.ql @@ -0,0 +1,24 @@ +/** + * @name Usage of supported APIs coming from external libraries + * @description A list of supported 3rd party APIs used in the codebase. Excludes APIs exposed by test libraries. + * @kind metric + * @tags summary telemetry + * @id csharp/telemetry/supported-external-api + */ + +private import csharp +private import semmle.code.csharp.dispatch.Dispatch +private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl +private import ExternalApi + +private predicate relevant(ExternalApi api) { + not api.isUninteresting() and + ( + api.isSupported() or + api instanceof FlowSummaryImpl::Public::NegativeSummarizedCallable + ) +} + +from string info, int usages +where Results::restrict(info, usages) +select info, usages order by usages desc From b789534b6c0b6c34c201128cb09fc451870ab945 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Thu, 1 Dec 2022 15:11:16 -0500 Subject: [PATCH 762/796] add csharp tests --- .../SupportedExternalApis.cs | 48 +++++++++++++++++++ .../SupportedExternalApis.expected | 11 +++++ .../SupportedExternalApis.qlref | 1 + .../Telemetry/SupportedExternalApis/options | 2 + 4 files changed, 62 insertions(+) create mode 100644 csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.cs create mode 100644 csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected create mode 100644 csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref create mode 100644 csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/options diff --git a/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.cs b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.cs new file mode 100644 index 00000000000..6231ff6f61c --- /dev/null +++ b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Web; + +public class SupportedExternalApis +{ + public void M1() + { + var l = new List(); // Uninteresting parameterless constructor + var o = new object(); // Uninteresting parameterless constructor + l.Add(o); // Has flow summary + l.Add(o); // Has flow summary + } + + public void M2() + { + var d0 = new DateTime(); // Uninteresting parameterless constructor + var next0 = d0.AddYears(30); // Has no flow summary, supported as negative summary + + var d1 = new DateTime(2000, 1, 1); // Interesting constructor, supported as negative summary + var next1 = next0.AddDays(3); // Has no flow summary, supported as negative summary + var next2 = next1.AddYears(5); // Has no flow summary, supported as negative summary + } + + public void M3() + { + var guid1 = Guid.Parse("{12345678-1234-1234-1234-123456789012}"); // Has no flow summary, supported as negative summary + } + + public void M4() + { + var o = new object(); // Uninteresting parameterless constructor + var response = new HttpResponse(); // Uninteresting parameterless constructor + response.AddHeader("header", "value"); // Unsupported + response.AppendHeader("header", "value"); // Unsupported + response.Write(o); // Known sink + response.WriteFile("filename"); // Known sink + response.Write(o); // Known sink + } + + public void M5() + { + var l1 = Console.ReadLine(); // Known source + var l2 = Console.ReadLine(); // Known source + Console.SetError(Console.Out); // Has no flow summary, supported as negative summary + var x = Console.Read(); // Known source + } +} diff --git a/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected new file mode 100644 index 00000000000..f8b6feafb92 --- /dev/null +++ b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected @@ -0,0 +1,11 @@ +| System#Console.ReadLine() | 2 | +| System#DateTime.AddYears(System.Int32) | 2 | +| System.Collections.Generic#List<>.Add(T) | 2 | +| System.Web#HttpResponse.Write(System.Object) | 2 | +| System#Console.Read() | 1 | +| System#Console.SetError(System.IO.TextWriter) | 1 | +| System#Console.get_Out() | 1 | +| System#DateTime.AddDays(System.Double) | 1 | +| System#DateTime.DateTime(System.Int32,System.Int32,System.Int32) | 1 | +| System#Guid.Parse(System.String) | 1 | +| System.Web#HttpResponse.WriteFile(System.String) | 1 | diff --git a/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref new file mode 100644 index 00000000000..2e12499cf62 --- /dev/null +++ b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref @@ -0,0 +1 @@ +Telemetry/SupportedExternalApis.ql diff --git a/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/options b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/options new file mode 100644 index 00000000000..9bbedebd7a2 --- /dev/null +++ b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /r:System.Collections.Specialized.dll +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs From aa633412f45fb0a6de162338f2e624ee145c64cd Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Thu, 1 Dec 2022 15:25:45 -0500 Subject: [PATCH 763/796] add change notes --- .../change-notes/2022-12-01-supported-external-apis-query.md | 4 ++++ .../change-notes/2022-12-01-supported-external-apis-query.md | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 csharp/ql/src/change-notes/2022-12-01-supported-external-apis-query.md create mode 100644 java/ql/src/change-notes/2022-12-01-supported-external-apis-query.md diff --git a/csharp/ql/src/change-notes/2022-12-01-supported-external-apis-query.md b/csharp/ql/src/change-notes/2022-12-01-supported-external-apis-query.md new file mode 100644 index 00000000000..34bf2ef8409 --- /dev/null +++ b/csharp/ql/src/change-notes/2022-12-01-supported-external-apis-query.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `csharp/telemetry/supported-external-api`, to detect supported 3rd party APIs used in a codebase. diff --git a/java/ql/src/change-notes/2022-12-01-supported-external-apis-query.md b/java/ql/src/change-notes/2022-12-01-supported-external-apis-query.md new file mode 100644 index 00000000000..83bfcf96e20 --- /dev/null +++ b/java/ql/src/change-notes/2022-12-01-supported-external-apis-query.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `java/telemetry/supported-external-api`, to detect supported 3rd party APIs used in a codebase. From 0e3e849ead716ae734ed9defdce7b00cb73cfea8 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Thu, 1 Dec 2022 15:49:12 -0500 Subject: [PATCH 764/796] add negative summary test for java --- .../SupportedExternalApis/SupportedExternalApis.expected | 3 ++- .../Telemetry/SupportedExternalApis/SupportedExternalApis.java | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected index 6abe5a43232..8a20a6c6c7b 100644 --- a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected @@ -1,5 +1,5 @@ +| java.io.File#File(String) | 2 | | java.net.URL#URL(String) | 2 | -| java.io.File#File(String) | 1 | | java.io.FileWriter#FileWriter(File) | 1 | | java.lang.StringBuilder#append(String) | 1 | | java.lang.StringBuilder#toString() | 1 | @@ -7,3 +7,4 @@ | java.net.URL#openStream() | 1 | | java.net.URLConnection#getInputStream() | 1 | | java.util.Map#put(Object,Object) | 1 | +| org.apache.commons.io.FileUtils#deleteDirectory(File) | 1 | diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java index ec05018fd21..7dd289acbaa 100644 --- a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java @@ -5,6 +5,7 @@ import java.io.InputStream; import java.net.URL; import java.io.File; import java.io.FileWriter; +import org.apache.commons.io.FileUtils; class SupportedExternalApis { public static void main(String[] args) throws Exception { @@ -22,5 +23,7 @@ class SupportedExternalApis { new FileWriter(new File("foo")); // supported sink (FileWriter), supported summary (File) new URL("http://foo").openStream(); // supported sink (openStream), supported summary (URL) + + FileUtils.deleteDirectory(new File("foo")); // supported negative summary (deleteDirectory), supported summary (File) } } From 1e010499661fc6966dc95a082ee876985d84f593 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 1 Dec 2022 22:03:32 +0000 Subject: [PATCH 765/796] Revert testing with experimental `go list` usage --- .github/workflows/go-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index 208033f1dc1..685c28cf3e0 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -68,4 +68,4 @@ jobs: - name: Test run: | cd go - env CODEQL_EXTRACTOR_GO_FAST_PACKAGE_INFO=1 make test cache="${{ steps.query-cache.outputs.cache-dir }}" + make test cache="${{ steps.query-cache.outputs.cache-dir }}" From c145678323ab8badf712c9fd974c7678b2a8c8df Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 2 Dec 2022 09:46:39 +0100 Subject: [PATCH 766/796] Java: Address review comments. --- .../src/utils/flowtestcasegenerator/GenerateFlowTestCase.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py index c3a590b1ccc..64a86505db4 100755 --- a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py +++ b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py @@ -131,7 +131,7 @@ queryDir = os.path.join(workDir, "query") os.makedirs(queryDir) qlFile = os.path.join(queryDir, "gen.ql") with open(os.path.join(queryDir, "qlpack.yml"), "w") as f: - f.write(f"""name: test-generation-query + f.write("""name: test-generation-query version: 0.0.0 dependencies: codeql/java-all: '*' @@ -233,7 +233,7 @@ if len(supportModelRows) != 0: f.write(dataextensions) # Make a qlpack file such that the extension will be picked up with open(resultPack, "w") as f: - f.write(f"""name: example-test-pack + f.write("""name: example-test-pack version: 0.0.0 extractor: java dependencies: From 01307e1255cb81bd7a70654611250cfd37015650 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 2 Dec 2022 09:47:14 +0100 Subject: [PATCH 767/796] Update java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll Co-authored-by: Tony Torralba --- java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll b/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll index 0339ca4f233..f90bbf2c908 100644 --- a/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll +++ b/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll @@ -12,7 +12,7 @@ private import FlowTestCaseSupportMethods /** * A CSV row to generate tests for. Users should extend this to define which - * tests to generate. There should already exist a summaries for the rows specified here. + * tests to generate. There should already exist summaries for the rows specified here. */ class TargetSummaryModelCsv extends Unit { /** From 73b171eb2bb6482cb0964be67cd0806c821561d9 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 2 Dec 2022 09:47:28 +0100 Subject: [PATCH 768/796] Update java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll Co-authored-by: Tony Torralba --- .../ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll index 2025affabf0..b06d9c60220 100644 --- a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll +++ b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll @@ -13,7 +13,7 @@ private import FlowTestCaseSupportMethods private import FlowTestCaseUtils /** - * Gets a CSV row for which a test has been requested, and where there exist a summary, but + * Gets a CSV row for which a test has been requested, and where there exists a summary, but * nonetheless we can't generate a test case for it, indicating we cannot resolve either the callable * spec or an input or output spec. */ From e7a48b4c98ee8102415e44db2e8e6d7bd0335ed1 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Thu, 1 Dec 2022 13:49:09 +0100 Subject: [PATCH 769/796] Swift: add a test case for symlinks --- .../posix-only/symlinks/.gitignore | 1 + .../posix-only/symlinks/Files.expected | 4 ++++ .../posix-only/symlinks/Files.ql | 4 ++++ .../posix-only/symlinks/main.swift | 6 ++++++ .../symlinks/preserve/Package.swift | 18 +++++++++++++++++ .../symlinks/preserve/Sources/.gitkeep | 0 .../posix-only/symlinks/resolve/Package.swift | 18 +++++++++++++++++ .../symlinks/resolve/Sources/.gitkeep | 0 .../posix-only/symlinks/test.py | 20 +++++++++++++++++++ 9 files changed, 71 insertions(+) create mode 100644 swift/integration-tests/posix-only/symlinks/.gitignore create mode 100644 swift/integration-tests/posix-only/symlinks/Files.expected create mode 100644 swift/integration-tests/posix-only/symlinks/Files.ql create mode 100644 swift/integration-tests/posix-only/symlinks/main.swift create mode 100644 swift/integration-tests/posix-only/symlinks/preserve/Package.swift create mode 100644 swift/integration-tests/posix-only/symlinks/preserve/Sources/.gitkeep create mode 100644 swift/integration-tests/posix-only/symlinks/resolve/Package.swift create mode 100644 swift/integration-tests/posix-only/symlinks/resolve/Sources/.gitkeep create mode 100644 swift/integration-tests/posix-only/symlinks/test.py diff --git a/swift/integration-tests/posix-only/symlinks/.gitignore b/swift/integration-tests/posix-only/symlinks/.gitignore new file mode 100644 index 00000000000..4c9788d145d --- /dev/null +++ b/swift/integration-tests/posix-only/symlinks/.gitignore @@ -0,0 +1 @@ +*/Sources/A.swift diff --git a/swift/integration-tests/posix-only/symlinks/Files.expected b/swift/integration-tests/posix-only/symlinks/Files.expected new file mode 100644 index 00000000000..3229e6bd4d9 --- /dev/null +++ b/swift/integration-tests/posix-only/symlinks/Files.expected @@ -0,0 +1,4 @@ +| file://:0:0:0:0 | | +| main.swift:0:0:0:0 | main.swift | +| preserve/Package.swift:0:0:0:0 | preserve/Package.swift | +| resolve/Package.swift:0:0:0:0 | resolve/Package.swift | diff --git a/swift/integration-tests/posix-only/symlinks/Files.ql b/swift/integration-tests/posix-only/symlinks/Files.ql new file mode 100644 index 00000000000..9782ea4ce0b --- /dev/null +++ b/swift/integration-tests/posix-only/symlinks/Files.ql @@ -0,0 +1,4 @@ +import swift + +from File f +select f diff --git a/swift/integration-tests/posix-only/symlinks/main.swift b/swift/integration-tests/posix-only/symlinks/main.swift new file mode 100644 index 00000000000..b9bf0e5c2a4 --- /dev/null +++ b/swift/integration-tests/posix-only/symlinks/main.swift @@ -0,0 +1,6 @@ +public struct preserve { + public private(set) var text = "Hello, World!" + + public init() { + } +} diff --git a/swift/integration-tests/posix-only/symlinks/preserve/Package.swift b/swift/integration-tests/posix-only/symlinks/preserve/Package.swift new file mode 100644 index 00000000000..e6f1f09de17 --- /dev/null +++ b/swift/integration-tests/posix-only/symlinks/preserve/Package.swift @@ -0,0 +1,18 @@ +// swift-tools-version: 5.7 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "preserve", + products: [ + .library( + name: "preserve", + targets: ["preserve"]), + ], + targets: [ + .target( + name: "preserve", + path: "Sources"), + ] +) diff --git a/swift/integration-tests/posix-only/symlinks/preserve/Sources/.gitkeep b/swift/integration-tests/posix-only/symlinks/preserve/Sources/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/integration-tests/posix-only/symlinks/resolve/Package.swift b/swift/integration-tests/posix-only/symlinks/resolve/Package.swift new file mode 100644 index 00000000000..a22a94a5c23 --- /dev/null +++ b/swift/integration-tests/posix-only/symlinks/resolve/Package.swift @@ -0,0 +1,18 @@ +// swift-tools-version: 5.7 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "resolve", + products: [ + .library( + name: "resolve", + targets: ["resolve"]), + ], + targets: [ + .target( + name: "resolve", + path: "Sources"), + ] +) diff --git a/swift/integration-tests/posix-only/symlinks/resolve/Sources/.gitkeep b/swift/integration-tests/posix-only/symlinks/resolve/Sources/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/integration-tests/posix-only/symlinks/test.py b/swift/integration-tests/posix-only/symlinks/test.py new file mode 100644 index 00000000000..de96ae22957 --- /dev/null +++ b/swift/integration-tests/posix-only/symlinks/test.py @@ -0,0 +1,20 @@ +from create_database_utils import * +import os + +symlinks = ['preserve/Sources/A.swift', 'resolve/Sources/A.swift'] + +for s in symlinks: + try: + os.symlink(os.getcwd() + '/main.swift', s) + except: + pass + +run_codeql_database_create([ + 'swift package clean --package-path resolve', + 'swift build --package-path resolve', + 'swift package clean --package-path preserve', + 'env CODEQL_PRESERVE_SYMLINKS=true swift build --package-path preserve' +], lang='swift', keep_trap=True) + +for s in symlinks: + os.unlink(s) From 7a3beac494f31223c274ee4bc0c242afc2636a1a Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Thu, 1 Dec 2022 15:29:08 +0100 Subject: [PATCH 770/796] Swift: resolve symlinks conditionally --- swift/extractor/SwiftExtractor.cpp | 11 ++---- swift/extractor/infra/Path.cpp | 38 +++++++++++++++++++ swift/extractor/infra/Path.h | 7 ++++ .../infra/SwiftLocationExtractor.cpp | 18 ++------- .../posix-only/symlinks/Files.expected | 1 + 5 files changed, 53 insertions(+), 22 deletions(-) create mode 100644 swift/extractor/infra/Path.cpp create mode 100644 swift/extractor/infra/Path.h diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index 349943f2869..c9410d2f1f3 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -12,15 +12,12 @@ #include "swift/extractor/translators/SwiftVisitor.h" #include "swift/extractor/TargetTrapFile.h" #include "swift/extractor/SwiftBuiltinSymbols.h" +#include "swift/extractor/infra/Path.h" using namespace codeql; using namespace std::string_literals; namespace fs = std::filesystem; -static fs::path toPath(llvm::StringRef s) { - return {static_cast(s)}; -} - static void ensureDirectory(const char* label, const fs::path& dir) { std::error_code ec; fs::create_directories(dir, ec); @@ -34,7 +31,7 @@ static void archiveFile(const SwiftExtractorConfiguration& config, swift::Source ensureDirectory("TRAP", config.trapDir); ensureDirectory("source archive", config.sourceArchiveDir); - fs::path srcFilePath = fs::absolute(toPath(file.getFilename())); + fs::path srcFilePath = codeql::getCodeQLPath(file.getFilename()); auto dstFilePath = config.sourceArchiveDir; dstFilePath += srcFilePath; @@ -60,7 +57,7 @@ static fs::path getFilename(swift::ModuleDecl& module, swift::SourceFile* primar // Moreover, pcm files may come from caches located in different directories, but are // unambiguously identified by the base file name, so we can discard the absolute directory fs::path filename = "/pcms"; - filename /= toPath(module.getModuleFilename()).filename(); + filename /= getCodeQLPath(module.getModuleFilename()).filename(); filename += "-"; filename += module.getName().str(); return filename; @@ -69,7 +66,7 @@ static fs::path getFilename(swift::ModuleDecl& module, swift::SourceFile* primar // The Builtin module has an empty filename, let's fix that return "/__Builtin__"; } - auto filename = toPath(module.getModuleFilename()); + auto filename = getCodeQLPath(module.getModuleFilename()); // there is a special case of a module without an actual filename reporting ``: in this // case we want to avoid the `<>` characters, in case a dirty DB is imported on Windows if (filename == "") { diff --git a/swift/extractor/infra/Path.cpp b/swift/extractor/infra/Path.cpp new file mode 100644 index 00000000000..6d54321fcac --- /dev/null +++ b/swift/extractor/infra/Path.cpp @@ -0,0 +1,38 @@ +#include "swift/extractor/infra/Path.h" +#include +#include + +namespace codeql { + +static bool shouldCanonicalize() { + auto preserve = getenv("CODEQL_PRESERVE_SYMLINKS"); + if (preserve && std::string(preserve) == "true") { + return false; + } + preserve = getenv("SEMMLE_PRESERVE_SYMLINKS"); + if (preserve && std::string(preserve) == "true") { + return false; + } + return true; +} + +std::filesystem::path getCodeQLPath(std::string_view path) { + // TODO: this needs more testing + // TODO: check canonicalization of names on a case insensitive filesystems + std::error_code ec; + std::filesystem::path ret = {}; + static const auto canonicalize = shouldCanonicalize(); + if (canonicalize) { + ret = std::filesystem::canonical(path, ec); + } else { + ret = std::filesystem::absolute(path, ec); + } + if (ec) { + std::cerr << "Cannot get " << (canonicalize ? "canonical" : "absolute") + << " path: " << std::quoted(path) << ": " << ec.message() << "\n"; + return {}; + } + return ret; +} + +} // namespace codeql diff --git a/swift/extractor/infra/Path.h b/swift/extractor/infra/Path.h new file mode 100644 index 00000000000..09ab7ed1773 --- /dev/null +++ b/swift/extractor/infra/Path.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +namespace codeql { +std::filesystem::path getCodeQLPath(std::string_view path); +} diff --git a/swift/extractor/infra/SwiftLocationExtractor.cpp b/swift/extractor/infra/SwiftLocationExtractor.cpp index a1b138f1f95..a003519f4ce 100644 --- a/swift/extractor/infra/SwiftLocationExtractor.cpp +++ b/swift/extractor/infra/SwiftLocationExtractor.cpp @@ -5,22 +5,10 @@ #include "swift/extractor/trap/generated/TrapEntries.h" #include "swift/extractor/trap/generated/TrapClasses.h" #include "swift/extractor/infra/SwiftLocationExtractor.h" +#include "swift/extractor/infra/Path.h" using namespace codeql; -static std::filesystem::path getFilePath(std::string_view path) { - // TODO: this needs more testing - // TODO: check canonicalization of names on a case insensitive filesystems - // TODO: make symlink resolution conditional on CODEQL_PRESERVE_SYMLINKS=true - std::error_code ec; - auto ret = std::filesystem::canonical(path, ec); - if (ec) { - std::cerr << "Cannot get real path: " << std::quoted(path) << ": " << ec.message() << "\n"; - return {}; - } - return ret; -} - void SwiftLocationExtractor::attachLocation(const swift::SourceManager& sourceManager, swift::SourceLoc start, swift::SourceLoc end, @@ -29,7 +17,7 @@ void SwiftLocationExtractor::attachLocation(const swift::SourceManager& sourceMa // invalid locations seem to come from entities synthesized by the compiler return; } - auto file = getFilePath(sourceManager.getDisplayNameForLoc(start)); + auto file = getCodeQLPath(sourceManager.getDisplayNameForLoc(start)); DbLocation entry{{}}; entry.file = fetchFileLabel(file); std::tie(entry.start_line, entry.start_column) = sourceManager.getLineAndColumnInBuffer(start); @@ -42,7 +30,7 @@ void SwiftLocationExtractor::attachLocation(const swift::SourceManager& sourceMa } void SwiftLocationExtractor::emitFile(llvm::StringRef path) { - fetchFileLabel(getFilePath(path)); + fetchFileLabel(getCodeQLPath(path)); } TrapLabel SwiftLocationExtractor::fetchFileLabel(const std::filesystem::path& file) { diff --git a/swift/integration-tests/posix-only/symlinks/Files.expected b/swift/integration-tests/posix-only/symlinks/Files.expected index 3229e6bd4d9..1260184529b 100644 --- a/swift/integration-tests/posix-only/symlinks/Files.expected +++ b/swift/integration-tests/posix-only/symlinks/Files.expected @@ -1,4 +1,5 @@ | file://:0:0:0:0 | | | main.swift:0:0:0:0 | main.swift | | preserve/Package.swift:0:0:0:0 | preserve/Package.swift | +| preserve/Sources/A.swift:0:0:0:0 | preserve/Sources/A.swift | | resolve/Package.swift:0:0:0:0 | resolve/Package.swift | From d2bbb618855c834098625f4796710bd300482cb4 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 2 Dec 2022 10:29:30 +0100 Subject: [PATCH 771/796] Ruby: update syntax for more models --- ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll | 4 ++-- ruby/ql/lib/codeql/ruby/frameworks/Json.qll | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll index d967bfd91ca..8682a256f9b 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll @@ -392,8 +392,8 @@ module ActiveSupport { override predicate row(string row) { row = [ - "activesupport;;Member[ActiveSupport].Member[JSON].Method[encode,dump];Argument[0];ReturnValue;taint", - "activesupport;;Member[ActiveSupport].Member[JSON].Method[decode,load];Argument[0];ReturnValue;taint", + "ActiveSupport::JSON!;Method[encode,dump];Argument[0];ReturnValue;taint", + "ActiveSupport::JSON!;Method[decode,load];Argument[0];ReturnValue;taint", ] } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Json.qll b/ruby/ql/lib/codeql/ruby/frameworks/Json.qll index dacb9bf48b7..353d28c34bb 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Json.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Json.qll @@ -14,8 +14,8 @@ module Json { override predicate row(string row) { row = [ - "json;;Member[JSON].Method[parse,parse!,load,restore];Argument[0];ReturnValue;taint", - "json;;Member[JSON].Method[generate,fast_generate,pretty_generate,dump,unparse,fast_unparse];Argument[0];ReturnValue;taint", + "JSON!;Method[parse,parse!,load,restore];Argument[0];ReturnValue;taint", + "JSON!;Method[generate,fast_generate,pretty_generate,dump,unparse,fast_unparse];Argument[0];ReturnValue;taint", ] } } From 6e98c678699cfc71b52bec850eaf74cb7af2d7fe Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 2 Dec 2022 10:04:53 +0000 Subject: [PATCH 772/796] Java: fix syntax error in path-injection example fix --- java/ql/src/Security/CWE/CWE-022/TaintedPath.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPath.java b/java/ql/src/Security/CWE/CWE-022/TaintedPath.java index 9246a19dc8d..339640ccc32 100644 --- a/java/ql/src/Security/CWE/CWE-022/TaintedPath.java +++ b/java/ql/src/Security/CWE/CWE-022/TaintedPath.java @@ -16,9 +16,9 @@ public void sendUserFileFixed(Socket sock, String user) { // ... // GOOD: remove all dots and directory delimiters from the filename before using - String filename = filenameReader.readLine().replaceAll("\.", "").replaceAll("/", ""); + String filename = filenameReader.readLine().replaceAll("\\.", "").replaceAll("/", ""); BufferedReader fileReader = new BufferedReader( new FileReader("/home/" + user + "/" + filename)); // ... -} \ No newline at end of file +} From a2459770759fc00d8a556f7ec0a83d7c58f3519c Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 2 Dec 2022 08:20:31 +0000 Subject: [PATCH 773/796] C++: Change iterator models. --- .../cpp/models/implementations/Iterator.qll | 33 ++++++++++++++++--- .../models/implementations/StdContainer.qll | 25 +++++++++++--- .../cpp/models/implementations/StdString.qll | 7 ++-- .../code/cpp/models/interfaces/Iterator.qll | 14 +++++++- 4 files changed, 67 insertions(+), 12 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll index 2fa9803d053..599b2c47e22 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll @@ -31,7 +31,17 @@ private class IteratorTraits extends Class { * `std::iterator_traits` instantiation for it. */ private class IteratorByTraits extends Iterator { - IteratorByTraits() { exists(IteratorTraits it | it.getIteratorType() = this) } + IteratorTraits trait; + + IteratorByTraits() { trait.getIteratorType() = this } + + override Type getValueType() { + exists(TypedefType t | + trait.getAMember() = t and + t.getName() = "value_type" and + result = t.getUnderlyingType() + ) + } } /** @@ -42,20 +52,27 @@ private class IteratorByTraits extends Iterator { */ private class IteratorByPointer extends Iterator instanceof PointerType { IteratorByPointer() { not this instanceof IteratorByTraits } + + override Type getValueType() { result = super.getBaseType() } } /** * A type which has the typedefs expected for an iterator. */ private class IteratorByTypedefs extends Iterator, Class { + TypedefType valueType; + IteratorByTypedefs() { this.getAMember().(TypedefType).hasName("difference_type") and - this.getAMember().(TypedefType).hasName("value_type") and + valueType = this.getAMember() and + valueType.hasName("value_type") and this.getAMember().(TypedefType).hasName("pointer") and this.getAMember().(TypedefType).hasName("reference") and this.getAMember().(TypedefType).hasName("iterator_category") and not this.hasQualifiedName(["std", "bsl"], "iterator_traits") } + + override Type getValueType() { result = valueType.getUnderlyingType() } } /** @@ -63,6 +80,8 @@ private class IteratorByTypedefs extends Iterator, Class { */ private class StdIterator extends Iterator, Class { StdIterator() { this.hasQualifiedName(["std", "bsl"], "iterator") } + + override Type getValueType() { result = this.getTemplateArgument(1).(Type).getUnderlyingType() } } /** @@ -166,12 +185,15 @@ private class IteratorSubOperator extends Operator, TaintFunction { /** * A non-member `operator+=` or `operator-=` function for an iterator type. */ -private class IteratorAssignArithmeticOperator extends Operator, DataFlowFunction, TaintFunction { +class IteratorAssignArithmeticOperator extends Operator { IteratorAssignArithmeticOperator() { this.hasName(["operator+=", "operator-="]) and exists(getIteratorArgumentInput(this, 0)) } +} +private class IteratorAssignArithmeticOperatorModel extends IteratorAssignArithmeticOperator, + DataFlowFunction, TaintFunction { override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { input.isParameter(0) and output.isReturnValue() @@ -210,11 +232,14 @@ class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunc /** * An `operator++` or `operator--` member function for an iterator type. */ -private class IteratorCrementMemberOperator extends MemberFunction, DataFlowFunction, TaintFunction { +class IteratorCrementMemberOperator extends MemberFunction { IteratorCrementMemberOperator() { this.getClassAndName(["operator++", "operator--"]) instanceof Iterator } +} +private class IteratorCrementMemberOperatorModel extends IteratorCrementMemberOperator, + DataFlowFunction, TaintFunction { override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { input.isQualifierAddress() and output.isReturnValue() diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll index 8c531891bcd..9d74f4ac051 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll @@ -5,38 +5,53 @@ import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.Iterator +/** + * A sequence container template class (for example, `std::vector`) from the + * standard library. + */ +abstract class StdSequenceContainer extends Class { + Type getElementType() { result = this.getTemplateArgument(0) } +} + /** * The `std::array` template class. */ -private class Array extends Class { +private class Array extends StdSequenceContainer { Array() { this.hasQualifiedName(["std", "bsl"], "array") } } +/** + * The `std::string` template class. + */ +private class String extends StdSequenceContainer { + String() { this.hasQualifiedName(["std", "bsl"], "basic_string") } +} + /** * The `std::deque` template class. */ -private class Deque extends Class { +private class Deque extends StdSequenceContainer { Deque() { this.hasQualifiedName(["std", "bsl"], "deque") } } /** * The `std::forward_list` template class. */ -private class ForwardList extends Class { +private class ForwardList extends StdSequenceContainer { ForwardList() { this.hasQualifiedName(["std", "bsl"], "forward_list") } } /** * The `std::list` template class. */ -private class List extends Class { +private class List extends StdSequenceContainer { List() { this.hasQualifiedName(["std", "bsl"], "list") } } /** * The `std::vector` template class. */ -private class Vector extends Class { +private class Vector extends StdSequenceContainer { Vector() { this.hasQualifiedName(["std", "bsl"], "vector") } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll index 9ac92597b1a..ee3ae248994 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll @@ -18,9 +18,12 @@ private class StdBasicString extends ClassTemplateInstantiation { /** * The `std::basic_string::iterator` declaration. */ -private class StdBasicStringIterator extends Iterator, Type { +private class StdBasicStringIterator extends Type instanceof Iterator { StdBasicStringIterator() { - this.getEnclosingElement() instanceof StdBasicString and this.hasName("iterator") + exists(Type unspecified | + unspecified.getEnclosingElement() = any(StdBasicString s).getTemplate() and + unspecified.getUnspecifiedType() = this + ) } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Iterator.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Iterator.qll index 9a260a33255..d5d2b6ffe81 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Iterator.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Iterator.qll @@ -29,5 +29,17 @@ abstract class GetIteratorFunction extends Function { /** * A type which can be used as an iterator. + * + * Note: Do _not_ `extend` when inheriting from this class in queries. Always use `instanceof`: + * ``` + * class MyIterator instanceof Iterator { ... } + * ``` */ -abstract class Iterator extends Type { } +abstract class Iterator extends Type { + /** + * Gets the value type of this iterator, if any. + * + * For example, the value type of a `std::vector::iterator` is `int`. + */ + Type getValueType() { none() } +} From cef7224739d3402668d388704d6222a5acaf189c Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 2 Dec 2022 10:12:25 +0000 Subject: [PATCH 774/796] C++: Make QL-for-QL happy. --- .../code/cpp/models/implementations/StdString.qll | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll index ee3ae248994..cf3ecb5e892 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll @@ -15,18 +15,6 @@ private class StdBasicString extends ClassTemplateInstantiation { StdBasicString() { this.hasQualifiedName(["std", "bsl"], "basic_string") } } -/** - * The `std::basic_string::iterator` declaration. - */ -private class StdBasicStringIterator extends Type instanceof Iterator { - StdBasicStringIterator() { - exists(Type unspecified | - unspecified.getEnclosingElement() = any(StdBasicString s).getTemplate() and - unspecified.getUnspecifiedType() = this - ) - } -} - /** * A `std::string` function for which taint should be propagated. */ From fb670325d8ef93fc03df06742800c14846298d0e Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 30 Nov 2022 10:43:05 +0100 Subject: [PATCH 775/796] Java/C#: Add query for aiding the conversion of existing negative models. --- .../modelconverter/ExtractNegativeSummaries.ql | 14 ++++++++++++++ .../modelconverter/ExtractNegativeSummaries.ql | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 csharp/ql/src/utils/modelconverter/ExtractNegativeSummaries.ql create mode 100644 java/ql/src/utils/modelconverter/ExtractNegativeSummaries.ql diff --git a/csharp/ql/src/utils/modelconverter/ExtractNegativeSummaries.ql b/csharp/ql/src/utils/modelconverter/ExtractNegativeSummaries.ql new file mode 100644 index 00000000000..53681f5f684 --- /dev/null +++ b/csharp/ql/src/utils/modelconverter/ExtractNegativeSummaries.ql @@ -0,0 +1,14 @@ +/** + * @name Extract MaD negative summary model rows. + * @description This extracts the Models as data negative summary model rows. + * @id csharp/utils/modelconverter/generate-data-extensions-negative-summary + */ + +import csharp +import semmle.code.csharp.dataflow.ExternalFlow + +from string package, string type, string name, string signature, string provenance +where + negativeSummaryModel(package, type, name, signature, provenance) and + provenance != "generated" +select package, type, name, signature, provenance order by package, type, name, signature diff --git a/java/ql/src/utils/modelconverter/ExtractNegativeSummaries.ql b/java/ql/src/utils/modelconverter/ExtractNegativeSummaries.ql new file mode 100644 index 00000000000..e762b3ee6e5 --- /dev/null +++ b/java/ql/src/utils/modelconverter/ExtractNegativeSummaries.ql @@ -0,0 +1,14 @@ +/** + * @name Extract MaD negative summary model rows. + * @description This extracts the Models as data negative summary model rows. + * @id java/utils/modelconverter/generate-data-extensions-negative-summary + */ + +import java +import semmle.code.java.dataflow.ExternalFlow + +from string package, string type, string name, string signature, string provenance +where + negativeSummaryModel(package, type, name, signature, provenance) and + provenance != "generated" +select package, type, name, signature, provenance order by package, type, name, signature From b2dd29ff0590a8d89206d07113195f09a2402c77 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 30 Nov 2022 10:43:50 +0100 Subject: [PATCH 776/796] Java/C#: Update conversion script to also produce negative models. --- misc/scripts/models-as-data/convert_extensions.py | 3 ++- misc/scripts/models-as-data/generate_flow_model_extensions.py | 2 +- misc/scripts/models-as-data/helpers.py | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/misc/scripts/models-as-data/convert_extensions.py b/misc/scripts/models-as-data/convert_extensions.py index ff5d5ee6cd5..6a05ba62238 100644 --- a/misc/scripts/models-as-data/convert_extensions.py +++ b/misc/scripts/models-as-data/convert_extensions.py @@ -74,7 +74,8 @@ class Converter: summaries = self.getAddsTo("ExtractSummaries.ql", helpers.summaryModelPredicate) sources = self.getAddsTo("ExtractSources.ql", helpers.sourceModelPredicate) sinks = self.getAddsTo("ExtractSinks.ql", helpers.sinkModelPredicate) - return merge(sources, sinks, summaries) + negativeSummaries = self.getAddsTo("ExtractNegativeSummaries.ql", helpers.negativeSummaryModelPredicate) + return merge(sources, sinks, summaries, negativeSummaries) def save(self, extensions): diff --git a/misc/scripts/models-as-data/generate_flow_model_extensions.py b/misc/scripts/models-as-data/generate_flow_model_extensions.py index c06e4eaeb62..fd015ee419e 100644 --- a/misc/scripts/models-as-data/generate_flow_model_extensions.py +++ b/misc/scripts/models-as-data/generate_flow_model_extensions.py @@ -169,7 +169,7 @@ Requirements: `codeql` should both appear on your path. sourceAddsTo = "" if self.generateNegativeSummaries: - negativeSummaryAddsTo = self.getAddsTo("CaptureNegativeSummaryModels.ql", "extNegativeSummaryModel") + negativeSummaryAddsTo = self.getAddsTo("CaptureNegativeSummaryModels.ql", helpers.negativeSummaryModelPredicate) else: negativeSummaryAddsTo = "" diff --git a/misc/scripts/models-as-data/helpers.py b/misc/scripts/models-as-data/helpers.py index cc69cee53c0..94bf16527de 100644 --- a/misc/scripts/models-as-data/helpers.py +++ b/misc/scripts/models-as-data/helpers.py @@ -7,6 +7,7 @@ import subprocess summaryModelPredicate = "extSummaryModel" sinkModelPredicate = "extSinkModel" sourceModelPredicate = "extSourceModel" +negativeSummaryModelPredicate = "extNegativeSummaryModel" addsToTemplate = """ - addsTo: pack: {0} extensible: {1} From cd700dfe110ed691160cad5983e6387312e67e34 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 2 Dec 2022 12:20:14 +0100 Subject: [PATCH 777/796] Swift: upload integration test logs also on failure --- swift/actions/run-integration-tests/action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/swift/actions/run-integration-tests/action.yml b/swift/actions/run-integration-tests/action.yml index 68189f5484f..ab311fead5e 100644 --- a/swift/actions/run-integration-tests/action.yml +++ b/swift/actions/run-integration-tests/action.yml @@ -28,6 +28,7 @@ runs: env: SEMMLE_DEBUG_TRACER: 10000 - name: Upload test logs + if: ${{ !cancelled() }} uses: actions/upload-artifact@v3 with: name: swift-integration-tests-logs-${{ runner.os }} From 5194108233b14b4a1a0586f0321596bcd106aed8 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 1 Dec 2022 10:54:42 +0100 Subject: [PATCH 778/796] Java/C#: Improve the newlines in the generated model files. --- .../models-as-data/generate_flow_model_extensions.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/misc/scripts/models-as-data/generate_flow_model_extensions.py b/misc/scripts/models-as-data/generate_flow_model_extensions.py index fd015ee419e..eee328c6f15 100644 --- a/misc/scripts/models-as-data/generate_flow_model_extensions.py +++ b/misc/scripts/models-as-data/generate_flow_model_extensions.py @@ -180,8 +180,7 @@ extensions: {sinkAddsTo} {sourceAddsTo} {summaryAddsTo} -{negativeSummaryAddsTo} - """ +{negativeSummaryAddsTo}""" def makeTypeBasedContent(self): if self.generateTypeBasedSummaries: @@ -189,13 +188,11 @@ extensions: else: typeBasedSummaryAddsTo = "" - return f""" -# THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. + return f"""# THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. # Definitions of type based summaries in the {self.friendlyname} framework. extensions: -{typeBasedSummaryAddsTo} - """ +{typeBasedSummaryAddsTo}""" def save(self, content, target): with open(target, "w") as targetYml: From d9e4aafe3a4029576d5016e358d3b754a047f816 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 30 Nov 2022 14:04:01 +0100 Subject: [PATCH 779/796] Kotlin: Add Kotlin standard library models as Data extensions. --- .../lib/ext/generated/kotlinstdlib.model.yml | 6473 +++++++++++++++++ 1 file changed, 6473 insertions(+) create mode 100644 java/ql/lib/ext/generated/kotlinstdlib.model.yml diff --git a/java/ql/lib/ext/generated/kotlinstdlib.model.yml b/java/ql/lib/ext/generated/kotlinstdlib.model.yml new file mode 100644 index 00000000000..a561d5dd572 --- /dev/null +++ b/java/ql/lib/ext/generated/kotlinstdlib.model.yml @@ -0,0 +1,6473 @@ +# THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. +# Definitions of models in the Kotlin StdLib @30ce58cea74 framework. + +extensions: + - addsTo: + pack: codeql/java-all + extensible: extSinkModel + data: + - ["kotlin.io", "FilesKt", false, "appendBytes", "(File,byte[])", "", "Argument[0]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "appendText", "(File,String,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "bufferedWriter", "(File,Charset,int)", "", "Argument[0]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "copyRecursively", "(File,File,boolean,Function2)", "", "Argument[1]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "copyTo", "(File,File,boolean,int)", "", "Argument[1]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "outputStream", "(File)", "", "Argument[0]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "printWriter", "(File,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "writeBytes", "(File,byte[])", "", "Argument[0]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "writeText", "(File,String,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "writer", "(File,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "readBytes", "(URL)", "", "Argument[0]", "open-url", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "readText", "(URL,Charset)", "", "Argument[0]", "open-url", "generated"] + + + - addsTo: + pack: codeql/java-all + extensible: extSummaryModel + data: + - ["kotlin.collections", "AbstractCollection", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "ArrayDeque", "(Collection)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "addFirst", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "addLast", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "first", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "firstOrNull", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "last", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "lastOrNull", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "removeFirst", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "removeFirstOrNull", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "removeLast", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "removeLastOrNull", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "asList", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(Object[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(Object[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(boolean[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(boolean[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(byte[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(byte[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(char[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(char[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(double[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(double[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(float[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(float[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(int[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(int[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(long[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(long[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(short[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(short[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(Object[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(boolean[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(byte[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(char[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(double[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(float[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(int[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(long[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(short[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(Object[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(boolean[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(byte[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(char[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(double[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(float[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(int[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(long[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(short[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(Object[],Object[],int,int,int)", "", "Argument[0].ArrayElement", "Argument[1].ArrayElement", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(Object[],Object[],int,int,int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(Object[],Object[],int,int,int)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(byte[],byte[],int,int,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(byte[],byte[],int,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(byte[],byte[],int,int,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(char[],char[],int,int,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(char[],char[],int,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(char[],char[],int,int,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOf", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOf", "(Object[],int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOf", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOf", "(byte[],int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOf", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOf", "(char[],int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOfRangeInline", "(Object[],int,int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOfRangeInline", "(byte[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOfRangeInline", "(char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "drop", "(Object[],int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "dropLast", "(Object[],int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "dropLastWhile", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fill", "(Object[],Object,int,int)", "", "Argument[1]", "Argument[0].ArrayElement", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(Object[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(boolean[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(byte[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(char[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(double[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(float[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(int[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(long[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(short[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIsInstanceTo", "(Object[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIsInstanceTo", "(Object[],Collection,Class)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotNullTo", "(Object[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(Object[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(boolean[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(byte[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(char[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(double[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(float[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(int[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(long[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(short[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(Object[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(boolean[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(byte[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(char[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(double[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(float[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(int[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(long[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(short[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "findLast", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "first", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "firstOrNull", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(Object[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(boolean[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(byte[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(char[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(double[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(float[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(int[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(long[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(short[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedSequenceTo", "(Object[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapSequenceTo", "(Object[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(Object[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(boolean[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(byte[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(char[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(double[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(float[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(int[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(long[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(short[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(Object[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(boolean[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(byte[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(char[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(double[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(float[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(int[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(long[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(short[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(Object[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(boolean[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(byte[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(char[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(double[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(float[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(int[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(long[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(short[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(Object[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(boolean[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(byte[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(char[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(double[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(float[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(int[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(long[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(short[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(Object[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(boolean[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(byte[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(char[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(double[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(float[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(int[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(long[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(short[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(Object[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(Object[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(boolean[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(boolean[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(byte[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(byte[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(char[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(char[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(double[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(double[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(float[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(float[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(int[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(int[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(long[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(long[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(short[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(short[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "ifEmpty", "(Object[],Function0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(Object[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(Object[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(Object[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(Object[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(boolean[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(boolean[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(boolean[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(boolean[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(byte[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(byte[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(byte[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(byte[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(char[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(char[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(char[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(char[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(double[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(double[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(double[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(double[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(float[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(float[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(float[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(float[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(int[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(int[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(int[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(int[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(long[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(long[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(long[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(long[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(short[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(short[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(short[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(short[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "last", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "last", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "lastOrNull", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "lastOrNull", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedNotNullTo", "(Object[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(Object[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(boolean[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(byte[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(char[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(double[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(float[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(int[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(long[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(short[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapNotNullTo", "(Object[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(Object[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(boolean[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(byte[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(char[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(double[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(float[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(int[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(long[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(short[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "max", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxBy", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxByOrNull", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxByOrThrow", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxOfWith", "(Object[],Comparator,Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxOfWithOrNull", "(Object[],Comparator,Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxOrNull", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxOrThrow", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxWith", "(Object[],Comparator)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxWithOrNull", "(Object[],Comparator)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxWithOrThrow", "(Object[],Comparator)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "min", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minBy", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minByOrNull", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minByOrThrow", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minOfWith", "(Object[],Comparator,Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minOfWithOrNull", "(Object[],Comparator,Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minOrNull", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minOrThrow", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minWith", "(Object[],Comparator)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minWithOrNull", "(Object[],Comparator)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minWithOrThrow", "(Object[],Comparator)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "onEach", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "onEach", "(byte[],Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "onEach", "(char[],Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "onEachIndexed", "(Object[],Function2)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "onEachIndexed", "(byte[],Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "onEachIndexed", "(char[],Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "orEmpty", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(Object[],Collection)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(Object[],Object)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(Object[],Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(Object[],Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(byte[],Collection)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(byte[],byte)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(byte[],byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(byte[],byte[])", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(char[],Collection)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(char[],char)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(char[],char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(char[],char[])", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plusElement", "(Object[],Object)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "reduce", "(Object[],Function2)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "reduceIndexed", "(Object[],Function3)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "reduceIndexedOrNull", "(Object[],Function3)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "reduceOrNull", "(Object[],Function2)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "requireNoNulls", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "reversed", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "reversedArray", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "reversedArray", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "reversedArray", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(Object[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(boolean[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(byte[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(char[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(double[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(float[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(int[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(long[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(short[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(Object[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(boolean[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(byte[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(char[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(double[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(float[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(int[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(long[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(short[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(Object[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(boolean[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(byte[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(char[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(double[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(float[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(int[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(long[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(short[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(Object[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(boolean[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(byte[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(char[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(double[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(float[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(int[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(long[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(short[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "single", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "singleOrNull", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "slice", "(Object[],IntRange)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sliceArray", "(Object[],Collection)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sliceArray", "(Object[],IntRange)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sliceArray", "(byte[],IntRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sliceArray", "(char[],IntRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sorted", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedArray", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedArray", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedArray", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedArrayDescending", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedArrayDescending", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedArrayDescending", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedArrayWith", "(Object[],Comparator)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedBy", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedByDescending", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedDescending", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedWith", "(Object[],Comparator)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "take", "(Object[],int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "takeLast", "(Object[],int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "takeLastWhile", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(Object[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(boolean[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(byte[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(char[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(double[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(float[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(int[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(long[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(short[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toList", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toMutableList", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toSet", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toString", "(byte[],Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toTypedArray", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "union", "(Object[],Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "union", "(byte[],Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "union", "(char[],Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "zip", "(Object[],Iterable)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "zip", "(Object[],Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "zip", "(Object[],Iterable,Function2)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "zip", "(Object[],Iterable,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "zip", "(Object[],Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "zip", "(Object[],Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "zip", "(Object[],Object[],Function2)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "zip", "(Object[],Object[],Function2)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "addAll", "(Collection,Iterable)", "", "Argument[1].Element", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "addAll", "(Collection,Object[])", "", "Argument[1].ArrayElement", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "addAll", "(Collection,Sequence)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "arrayListOf", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "asIterable", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "asReversed", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "asReversedMutable", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associate", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateBy", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateBy", "(Iterable,Function1,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateByTo", "(Iterable,Map,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateByTo", "(Iterable,Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateByTo", "(Iterable,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateByTo", "(Iterable,Map,Function1,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateByTo", "(Iterable,Map,Function1,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateByTo", "(Iterable,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateTo", "(Iterable,Map,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateTo", "(Iterable,Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateTo", "(Iterable,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateWith", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateWithTo", "(Iterable,Map,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateWithTo", "(Iterable,Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateWithTo", "(Iterable,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "component1", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "component2", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "component3", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "component4", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "component5", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "distinct", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "distinctBy", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "drop", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "dropLast", "(List,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "dropLastWhile", "(List,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "dropWhile", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "elementAt", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "elementAt", "(List,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "elementAtOrElse", "(Iterable,int,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "elementAtOrElse", "(List,int,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "elementAtOrNull", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "elementAtOrNull", "(List,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "fill", "(List,Object)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filter", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIndexedTo", "(Iterable,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIsInstance", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIsInstance", "(Iterable,Class)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIsInstanceTo", "(Iterable,Collection)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIsInstanceTo", "(Iterable,Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIsInstanceTo", "(Iterable,Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIsInstanceTo", "(Iterable,Collection,Class)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIsInstanceTo", "(Iterable,Collection,Class)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIsInstanceTo", "(Iterable,Collection,Class)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterNot", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterNotNull", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterNotNullTo", "(Iterable,Collection)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterNotNullTo", "(Iterable,Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterNotNullTo", "(Iterable,Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterNotTo", "(Iterable,Collection,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterNotTo", "(Iterable,Collection,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterNotTo", "(Iterable,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterTo", "(Iterable,Collection,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterTo", "(Iterable,Collection,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterTo", "(Iterable,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "find", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "findLast", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "findLast", "(List,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "first", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "first", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "first", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "firstNotNullOf", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "firstNotNullOfOrNull", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "firstOrNull", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "firstOrNull", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "firstOrNull", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "flatMapIndexedIterableTo", "(Iterable,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "flatMapIndexedSequenceTo", "(Iterable,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "flatMapSequenceTo", "(Iterable,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "flatMapTo", "(Iterable,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "flatten", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "fold", "(Iterable,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "foldIndexed", "(Iterable,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "foldRight", "(List,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "foldRightIndexed", "(List,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "getOrElse", "(List,int,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "getOrNull", "(List,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "groupByTo", "(Iterable,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "groupByTo", "(Iterable,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "ifEmpty", "(Collection,Function0)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "intersect", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "iterator", "(Iterator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[0].Element", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinToString", "(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinToString", "(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinToString", "(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinToString", "(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinToString", "(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "last", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "last", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "last", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "last", "(List,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "lastOrNull", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "lastOrNull", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "lastOrNull", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "lastOrNull", "(List,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "listOf", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "listOf", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "listOfNotNull", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "map", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "mapIndexedNotNullTo", "(Iterable,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "mapIndexedTo", "(Iterable,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "mapNotNullTo", "(Iterable,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "mapTo", "(Iterable,Collection,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "mapTo", "(Iterable,Collection,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "mapTo", "(Iterable,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "max", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxBy", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxByOrNull", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxByOrThrow", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxOfWith", "(Iterable,Comparator,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxOfWithOrNull", "(Iterable,Comparator,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxOrNull", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxOrThrow", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxWith", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxWithOrNull", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxWithOrThrow", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "min", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minBy", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minByOrNull", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minByOrThrow", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minOfWith", "(Iterable,Comparator,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minOfWithOrNull", "(Iterable,Comparator,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minOrNull", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minOrThrow", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minWith", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minWithOrNull", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minWithOrThrow", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minus", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minus", "(Iterable,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minus", "(Iterable,Object[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minus", "(Iterable,Sequence)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minusElement", "(Iterable,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "mutableListOf", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "onEach", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "onEachIndexed", "(Iterable,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "orEmpty", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "orEmpty", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "partition", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Collection,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Collection,Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Collection,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Collection,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Collection,Object[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Collection,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Collection,Sequence)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Collection,Sequence)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Iterable,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Iterable,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Iterable,Object[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Iterable,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Iterable,Sequence)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Iterable,Sequence)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plusAssign", "(Collection,Iterable)", "", "Argument[1].Element", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plusAssign", "(Collection,Object)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plusAssign", "(Collection,Object[])", "", "Argument[1].ArrayElement", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plusAssign", "(Collection,Sequence)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plusElement", "(Collection,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plusElement", "(Collection,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plusElement", "(Iterable,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plusElement", "(Iterable,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "random", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "random", "(Collection,Random)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "randomOrNull", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "randomOrNull", "(Collection,Random)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reduce", "(Iterable,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reduceIndexed", "(Iterable,Function3)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reduceIndexedOrNull", "(Iterable,Function3)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reduceOrNull", "(Iterable,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reduceRight", "(List,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reduceRightIndexed", "(List,Function3)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reduceRightIndexedOrNull", "(List,Function3)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reduceRightOrNull", "(List,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "remove", "(List,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "removeFirst", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "removeFirstOrNull", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "removeLast", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "removeLastOrNull", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "requireNoNulls", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "requireNoNulls", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reversed", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "runningFold", "(Iterable,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "runningFoldIndexed", "(Iterable,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "scan", "(Iterable,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "scanIndexed", "(Iterable,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "shuffled", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "shuffled", "(Iterable,Random)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "single", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "single", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "single", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "singleOrNull", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "singleOrNull", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "singleOrNull", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "slice", "(List,IntRange)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "slice", "(List,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "sorted", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "sortedBy", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "sortedByDescending", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "sortedDescending", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "sortedWith", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "subtract", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "take", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "takeLast", "(List,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "takeLastWhile", "(List,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "takeWhile", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toCollection", "(Iterable,Collection)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toCollection", "(Iterable,Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toCollection", "(Iterable,Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toHashSet", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toList", "(Enumeration)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toList", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toMutableList", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toMutableList", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toMutableSet", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toSet", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toSortedSet", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toSortedSet", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "union", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "union", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "unzip", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "withIndex", "(Iterator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zip", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zip", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zip", "(Iterable,Iterable,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zip", "(Iterable,Iterable,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zip", "(Iterable,Object[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zip", "(Iterable,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zip", "(Iterable,Object[],Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zip", "(Iterable,Object[],Function2)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zipWithNext", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zipWithNext", "(Iterable,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "GroupingKt", false, "aggregateTo", "(Grouping,Map,Function4)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "GroupingKt", false, "eachCountTo", "(Grouping,Map)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "GroupingKt", false, "foldTo", "(Grouping,Map,Function2,Function3)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "GroupingKt", false, "foldTo", "(Grouping,Map,Object,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "GroupingKt", false, "reduceTo", "(Grouping,Map,Function3)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "IndexedValue", false, "IndexedValue", "(int,Object)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.collections", "IndexedValue", false, "component2", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "IndexedValue", false, "copy", "(int,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "IndexedValue", false, "getValue", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "IndexedValue", false, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapAccessorsKt", false, "getValue", "(Map,Object,KProperty)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapAccessorsKt", false, "getVar", "(Map,Object,KProperty)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapAccessorsKt", false, "setValue", "(Map,Object,KProperty,Object)", "", "Argument[2]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapAccessorsKt", false, "setValue", "(Map,Object,KProperty,Object)", "", "Argument[3]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "asIterable", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "component1", "(Entry)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "component2", "(Entry)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filter", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterKeys", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterNot", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterNotTo", "(Map,Map,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterNotTo", "(Map,Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterNotTo", "(Map,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterTo", "(Map,Map,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterTo", "(Map,Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterTo", "(Map,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterValues", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "firstNotNullOf", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "firstNotNullOfOrNull", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "flatMapSequenceTo", "(Map,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "flatMapTo", "(Map,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "get", "(Map,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "getOrElse", "(Map,Object,Function0)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "getOrPut", "(ConcurrentMap,Object,Function0)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "getOrPut", "(Map,Object,Function0)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "getOrPut", "(Map,Object,Function0)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "getValue", "(Map,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "ifEmpty", "(Map,Function0)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "iterator", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "map", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapKeys", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapKeysTo", "(Map,Map,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapKeysTo", "(Map,Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapKeysTo", "(Map,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapNotNullTo", "(Map,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapOf", "(Pair)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapTo", "(Map,Collection,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapTo", "(Map,Collection,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapTo", "(Map,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapValues", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapValuesTo", "(Map,Map,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapValuesTo", "(Map,Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapValuesTo", "(Map,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "maxBy", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "maxByOrNull", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "maxByOrThrow", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "maxOfWith", "(Map,Comparator,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "maxOfWithOrNull", "(Map,Comparator,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "maxWith", "(Map,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "maxWithOrNull", "(Map,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "maxWithOrThrow", "(Map,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minBy", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minByOrNull", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minByOrThrow", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minOfWith", "(Map,Comparator,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minOfWithOrNull", "(Map,Comparator,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minWith", "(Map,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minWithOrNull", "(Map,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minWithOrThrow", "(Map,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minus", "(Map,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minus", "(Map,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minus", "(Map,Object[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minus", "(Map,Sequence)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mutableIterator", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "onEach", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "onEachIndexed", "(Map,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "orEmpty", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plus", "(Map,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plus", "(Map,Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plus", "(Map,Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plus", "(Map,Pair)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plus", "(Map,Pair)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plus", "(Map,Pair[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plus", "(Map,Pair[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plus", "(Map,Sequence)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plusAssign", "(Map,Iterable)", "", "Argument[1].Element", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plusAssign", "(Map,Map)", "", "Argument[1].Element", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plusAssign", "(Map,Pair)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plusAssign", "(Map,Sequence)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "putAll", "(Map,Iterable)", "", "Argument[1].Element", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "putAll", "(Map,Sequence)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "remove", "(Map,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "set", "(Map,Object,Object)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "set", "(Map,Object,Object)", "", "Argument[2]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toList", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toMap", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toMap", "(Iterable,Map)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toMap", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toMap", "(Map,Map)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toMap", "(Pair[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toMap", "(Pair[],Map)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toMap", "(Sequence,Map)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toMutableMap", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toPair", "(Entry)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toSortedMap", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "withDefault", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "withDefault", "(Map,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "withDefaultMutable", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "withDefaultMutable", "(Map,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "minus", "(Set,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "minus", "(Set,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "minus", "(Set,Object[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "minus", "(Set,Sequence)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "minusElement", "(Set,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "orEmpty", "(Set)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plus", "(Set,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plus", "(Set,Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plus", "(Set,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plus", "(Set,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plus", "(Set,Object[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plus", "(Set,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plus", "(Set,Sequence)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plus", "(Set,Sequence)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plusElement", "(Set,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plusElement", "(Set,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "setOf", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "setOf", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "setOfNotNull", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "asByteArray", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "asUByteArray", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "associateWithTo", "(UByteArray,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "associateWithTo", "(UIntArray,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "associateWithTo", "(ULongArray,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "associateWithTo", "(UShortArray,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "contentToString", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "contentToString", "(UIntArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "contentToString", "(ULongArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "contentToString", "(UShortArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyInto", "(UByteArray,UByteArray,int,int,int)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyInto", "(UByteArray,UByteArray,int,int,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyInto", "(UByteArray,UByteArray,int,int,int)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyInto", "(UIntArray,UIntArray,int,int,int)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyInto", "(ULongArray,ULongArray,int,int,int)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyInto", "(UShortArray,UShortArray,int,int,int)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyOf", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyOf", "(UByteArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyOfRange", "(UByteArray,int,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "drop", "(UByteArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "drop", "(UIntArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "drop", "(ULongArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "drop", "(UShortArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "dropLast", "(UByteArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "dropLast", "(UIntArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "dropLast", "(ULongArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "dropLast", "(UShortArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "dropLastWhile", "(UByteArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "dropLastWhile", "(UIntArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "dropLastWhile", "(ULongArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "dropLastWhile", "(UShortArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterIndexedTo", "(UByteArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterIndexedTo", "(UIntArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterIndexedTo", "(ULongArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterIndexedTo", "(UShortArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterNotTo", "(UByteArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterNotTo", "(UIntArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterNotTo", "(ULongArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterNotTo", "(UShortArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterTo", "(UByteArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterTo", "(UIntArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterTo", "(ULongArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterTo", "(UShortArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "flatMapIndexedTo", "(UByteArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "flatMapIndexedTo", "(UIntArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "flatMapIndexedTo", "(ULongArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "flatMapIndexedTo", "(UShortArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "flatMapTo", "(UByteArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "flatMapTo", "(UIntArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "flatMapTo", "(ULongArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "flatMapTo", "(UShortArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "fold", "(UByteArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "fold", "(UIntArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "fold", "(ULongArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "fold", "(UShortArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldIndexed", "(UByteArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldIndexed", "(UIntArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldIndexed", "(ULongArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldIndexed", "(UShortArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldRight", "(UByteArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldRight", "(UIntArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldRight", "(ULongArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldRight", "(UShortArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldRightIndexed", "(UByteArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldRightIndexed", "(UIntArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldRightIndexed", "(ULongArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldRightIndexed", "(UShortArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "groupByTo", "(UByteArray,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "groupByTo", "(UByteArray,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "groupByTo", "(UIntArray,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "groupByTo", "(UIntArray,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "groupByTo", "(ULongArray,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "groupByTo", "(ULongArray,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "groupByTo", "(UShortArray,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "groupByTo", "(UShortArray,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "mapIndexedTo", "(UByteArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "mapIndexedTo", "(UIntArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "mapIndexedTo", "(ULongArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "mapIndexedTo", "(UShortArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "mapTo", "(UByteArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "mapTo", "(UIntArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "mapTo", "(ULongArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "mapTo", "(UShortArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "onEach", "(UByteArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "onEach", "(UIntArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "onEach", "(ULongArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "onEach", "(UShortArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "onEachIndexed", "(UByteArray,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "onEachIndexed", "(UIntArray,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "onEachIndexed", "(ULongArray,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "onEachIndexed", "(UShortArray,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "plus", "(UByteArray,Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "plus", "(UByteArray,UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "plus", "(UByteArray,UByteArray)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "plus", "(UByteArray,byte)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "reversed", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "reversed", "(UIntArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "reversed", "(ULongArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "reversed", "(UShortArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "reversedArray", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "runningFold", "(UByteArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "runningFold", "(UIntArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "runningFold", "(ULongArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "runningFold", "(UShortArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "runningFoldIndexed", "(UByteArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "runningFoldIndexed", "(UIntArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "runningFoldIndexed", "(ULongArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "runningFoldIndexed", "(UShortArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "scan", "(UByteArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "scan", "(UIntArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "scan", "(ULongArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "scan", "(UShortArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "scanIndexed", "(UByteArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "scanIndexed", "(UIntArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "scanIndexed", "(ULongArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "scanIndexed", "(UShortArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sliceArray", "(UByteArray,IntRange)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedArray", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedArray", "(UIntArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedArray", "(ULongArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedArray", "(UShortArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedArrayDescending", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedArrayDescending", "(UIntArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedArrayDescending", "(ULongArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedArrayDescending", "(UShortArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedDescending", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "take", "(UByteArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "take", "(UIntArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "take", "(ULongArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "take", "(UShortArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "takeLast", "(UByteArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "takeLast", "(UIntArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "takeLast", "(ULongArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "takeLast", "(UShortArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "takeLastWhile", "(UByteArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "takeLastWhile", "(UIntArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "takeLastWhile", "(ULongArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "takeLastWhile", "(UShortArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "toByteArray", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "toUByteArray", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Comparable,Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Comparable,Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Comparable,Comparable,Comparable)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Comparable,Comparable[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Object,Object,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Object,Object,Comparator)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Object,Object,Object,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Object,Object,Object,Comparator)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Object,Object,Object,Comparator)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Object,Object[],Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Comparable,Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Comparable,Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Comparable,Comparable,Comparable)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Comparable,Comparable[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Object,Object,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Object,Object,Comparator)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Object,Object,Object,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Object,Object,Object,Comparator)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Object,Object,Object,Comparator)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Object,Object[],Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "reversed", "(Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "AbstractCoroutineContextElement", true, "AbstractCoroutineContextElement", "(Key)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.coroutines", "AbstractCoroutineContextKey", true, "AbstractCoroutineContextKey", "(Key,Function1)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.coroutines", "AbstractCoroutineContextKey", true, "AbstractCoroutineContextKey", "(Key,Function1)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContext", true, "fold", "(Object,Function2)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContext", true, "fold", "(Object,Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContext", true, "get", "(Key)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContext", true, "minusKey", "(Key)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContext", true, "minusKey", "(Key)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["kotlin.coroutines", "CoroutineContext", true, "plus", "(CoroutineContext)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContext", true, "plus", "(CoroutineContext)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContext$Element", true, "getKey", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContextImplKt", false, "getPolymorphicElement", "(Element,Key)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContextImplKt", false, "minusPolymorphicKey", "(Element,Key)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines.intrinsics", "IntrinsicsKt", false, "intercepted", "(Continuation)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines.jvm.internal", "CoroutineStackFrame", true, "getCallerFrame", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "AccessDeniedException", false, "AccessDeniedException", "(File,File,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "AccessDeniedException", false, "AccessDeniedException", "(File,File,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "AccessDeniedException", false, "AccessDeniedException", "(File,File,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "buffered", "(InputStream,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "buffered", "(OutputStream,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "bufferedReader", "(InputStream,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "byteInputStream", "(String,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "copyTo", "(InputStream,OutputStream,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "inputStream", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "inputStream", "(byte[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "readBytes", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "readBytes", "(InputStream,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "reader", "(InputStream,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "CloseableKt", false, "use", "(Closeable,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileAlreadyExistsException", false, "FileAlreadyExistsException", "(File,File,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "FileAlreadyExistsException", false, "FileAlreadyExistsException", "(File,File,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "FileAlreadyExistsException", false, "FileAlreadyExistsException", "(File,File,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "FileSystemException", true, "FileSystemException", "(File,File,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "FileSystemException", true, "FileSystemException", "(File,File,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "FileSystemException", true, "FileSystemException", "(File,File,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "FileSystemException", true, "getFile", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileSystemException", true, "getOther", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileSystemException", true, "getReason", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileTreeWalk", false, "maxDepth", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileTreeWalk", false, "onEnter", "(Function1)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileTreeWalk", false, "onEnter", "(Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileTreeWalk", false, "onFail", "(Function2)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileTreeWalk", false, "onFail", "(Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileTreeWalk", false, "onLeave", "(Function1)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileTreeWalk", false, "onLeave", "(Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "copyTo", "(File,File,boolean,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "relativeToOrSelf", "(File,File)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "resolve", "(File,File)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "resolve", "(File,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "resolveSibling", "(File,File)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "resolveSibling", "(File,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "walk", "(File,FileWalkDirection)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "walkBottomUp", "(File)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "walkTopDown", "(File)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "NoSuchFileException", false, "NoSuchFileException", "(File,File,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "NoSuchFileException", false, "NoSuchFileException", "(File,File,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "NoSuchFileException", false, "NoSuchFileException", "(File,File,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "buffered", "(Reader,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "buffered", "(Writer,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "copyTo", "(Reader,Writer,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "forEachLine", "(Reader,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "lineSequence", "(BufferedReader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "readText", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "reader", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "useLines", "(Reader,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", true, "AdaptedFunctionReference", "(int,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", true, "AdaptedFunctionReference", "(int,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", true, "AdaptedFunctionReference", "(int,Object,Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", true, "AdaptedFunctionReference", "(int,Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", true, "AdaptedFunctionReference", "(int,Object,Class,String,String,int)", "", "Argument[4]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorKt", false, "iterator", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorsKt", false, "iterator", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorsKt", false, "iterator", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ByteSpreadBuilder", false, "toArray", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "CallableReference", true, "compute", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "CallableReference", true, "getBoundReceiver", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "CallableReference", true, "getSignature", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "CharSpreadBuilder", false, "toArray", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ClassReference$Companion", false, "getClassQualifiedName", "(Class)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ClassReference$Companion", false, "getClassSimpleName", "(Class)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "CollectionToArray", false, "toArray", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "CollectionToArray", false, "toArray", "(Collection,Object[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReference", true, "FunctionReference", "(int,Object)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReference", true, "FunctionReference", "(int,Object,Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReference", true, "FunctionReference", "(int,Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReference", true, "FunctionReference", "(int,Object,Class,String,String,int)", "", "Argument[4]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReference", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReferenceImpl", true, "FunctionReferenceImpl", "(int,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReferenceImpl", true, "FunctionReferenceImpl", "(int,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReferenceImpl", true, "FunctionReferenceImpl", "(int,KDeclarationContainer,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReferenceImpl", true, "FunctionReferenceImpl", "(int,KDeclarationContainer,String,String)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReferenceImpl", true, "FunctionReferenceImpl", "(int,Object,Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReferenceImpl", true, "FunctionReferenceImpl", "(int,Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReferenceImpl", true, "FunctionReferenceImpl", "(int,Object,Class,String,String,int)", "", "Argument[4]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", true, "stringPlus", "(String,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", true, "stringPlus", "(String,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference", true, "MutablePropertyReference", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference", true, "MutablePropertyReference", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference", true, "MutablePropertyReference", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference", true, "MutablePropertyReference", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0", true, "MutablePropertyReference0", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0", true, "MutablePropertyReference0", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0", true, "MutablePropertyReference0", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0", true, "MutablePropertyReference0", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0Impl", true, "MutablePropertyReference0Impl", "(Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0Impl", true, "MutablePropertyReference0Impl", "(Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0Impl", true, "MutablePropertyReference0Impl", "(KDeclarationContainer,String,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0Impl", true, "MutablePropertyReference0Impl", "(KDeclarationContainer,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0Impl", true, "MutablePropertyReference0Impl", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0Impl", true, "MutablePropertyReference0Impl", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0Impl", true, "MutablePropertyReference0Impl", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1", true, "MutablePropertyReference1", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1", true, "MutablePropertyReference1", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1", true, "MutablePropertyReference1", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1", true, "MutablePropertyReference1", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1Impl", true, "MutablePropertyReference1Impl", "(Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1Impl", true, "MutablePropertyReference1Impl", "(Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1Impl", true, "MutablePropertyReference1Impl", "(KDeclarationContainer,String,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1Impl", true, "MutablePropertyReference1Impl", "(KDeclarationContainer,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1Impl", true, "MutablePropertyReference1Impl", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1Impl", true, "MutablePropertyReference1Impl", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1Impl", true, "MutablePropertyReference1Impl", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference2", true, "MutablePropertyReference2", "(Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference2", true, "MutablePropertyReference2", "(Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference2Impl", true, "MutablePropertyReference2Impl", "(Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference2Impl", true, "MutablePropertyReference2Impl", "(Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference2Impl", true, "MutablePropertyReference2Impl", "(KDeclarationContainer,String,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference2Impl", true, "MutablePropertyReference2Impl", "(KDeclarationContainer,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PackageReference", false, "PackageReference", "(Class,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PrimitiveSpreadBuilder", true, "addSpread", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference", true, "PropertyReference", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference", true, "PropertyReference", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference", true, "PropertyReference", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference", true, "PropertyReference", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0", true, "PropertyReference0", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0", true, "PropertyReference0", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0", true, "PropertyReference0", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0", true, "PropertyReference0", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0Impl", true, "PropertyReference0Impl", "(Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0Impl", true, "PropertyReference0Impl", "(Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0Impl", true, "PropertyReference0Impl", "(KDeclarationContainer,String,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0Impl", true, "PropertyReference0Impl", "(KDeclarationContainer,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0Impl", true, "PropertyReference0Impl", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0Impl", true, "PropertyReference0Impl", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0Impl", true, "PropertyReference0Impl", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1", true, "PropertyReference1", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1", true, "PropertyReference1", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1", true, "PropertyReference1", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1", true, "PropertyReference1", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1Impl", true, "PropertyReference1Impl", "(Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1Impl", true, "PropertyReference1Impl", "(Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1Impl", true, "PropertyReference1Impl", "(KDeclarationContainer,String,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1Impl", true, "PropertyReference1Impl", "(KDeclarationContainer,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1Impl", true, "PropertyReference1Impl", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1Impl", true, "PropertyReference1Impl", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1Impl", true, "PropertyReference1Impl", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference2", true, "PropertyReference2", "(Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference2", true, "PropertyReference2", "(Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference2Impl", true, "PropertyReference2Impl", "(Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference2Impl", true, "PropertyReference2Impl", "(Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference2Impl", true, "PropertyReference2Impl", "(KDeclarationContainer,String,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference2Impl", true, "PropertyReference2Impl", "(KDeclarationContainer,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "function", "(FunctionReference)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "getOrCreateKotlinPackage", "(Class,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "mutableCollectionType", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "mutableProperty0", "(MutablePropertyReference0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "mutableProperty1", "(MutablePropertyReference1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "mutableProperty2", "(MutablePropertyReference2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "nothingType", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "nullableTypeOf", "(Class,KTypeProjection)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "nullableTypeOf", "(Class,KTypeProjection,KTypeProjection)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "nullableTypeOf", "(Class,KTypeProjection,KTypeProjection)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "nullableTypeOf", "(KClassifier)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "platformType", "(KType,KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "platformType", "(KType,KType)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "property0", "(PropertyReference0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "property1", "(PropertyReference1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "property2", "(PropertyReference2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "setUpperBounds", "(KTypeParameter,KType)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "typeOf", "(Class,KTypeProjection)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "typeOf", "(Class,KTypeProjection,KTypeProjection)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "typeOf", "(Class,KTypeProjection,KTypeProjection)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "typeOf", "(KClassifier)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "typeParameter", "(Object,String,KVariance,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "typeParameter", "(Object,String,KVariance,boolean)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "function", "(FunctionReference)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "getOrCreateKotlinPackage", "(Class,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "mutableCollectionType", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "mutableProperty0", "(MutablePropertyReference0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "mutableProperty1", "(MutablePropertyReference1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "mutableProperty2", "(MutablePropertyReference2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "nothingType", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "platformType", "(KType,KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "platformType", "(KType,KType)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "property0", "(PropertyReference0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "property1", "(PropertyReference1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "property2", "(PropertyReference2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "setUpperBounds", "(KTypeParameter,List)", "", "Argument[1].Element", "Argument[0]", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "typeOf", "(KClassifier,List,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "typeOf", "(KClassifier,List,boolean)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "typeParameter", "(Object,String,KVariance,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "typeParameter", "(Object,String,KVariance,boolean)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "SpreadBuilder", true, "add", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "SpreadBuilder", true, "addSpread", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "SpreadBuilder", true, "toArray", "(Object[])", "", "Argument[-1]", "Argument[0].ArrayElement", "taint", "generated"] + - ["kotlin.jvm.internal", "SpreadBuilder", true, "toArray", "(Object[])", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableCollection", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableCollection", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableIterable", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableIterable", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableIterator", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableIterator", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableList", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableList", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableListIterator", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableListIterator", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableMap", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableMap", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableMapEntry", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableMapEntry", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableSet", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableSet", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "beforeCheckcastToFunctionOfArity", "(Object,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "beforeCheckcastToFunctionOfArity", "(Object,int,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "castToCollection", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "castToIterable", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "castToIterator", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "castToList", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "castToListIterator", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "castToMap", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "castToMapEntry", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "castToSet", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeParameterReference", false, "TypeParameterReference", "(Object,String,KVariance,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeParameterReference", false, "TypeParameterReference", "(Object,String,KVariance,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeParameterReference", false, "setUpperBounds", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeReference", false, "TypeReference", "(KClassifier,List,KType,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeReference", false, "TypeReference", "(KClassifier,List,KType,int)", "", "Argument[1].Element", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeReference", false, "TypeReference", "(KClassifier,List,KType,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeReference", false, "TypeReference", "(KClassifier,List,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeReference", false, "TypeReference", "(KClassifier,List,boolean)", "", "Argument[1].Element", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeReference", false, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.properties", "ObservableProperty", true, "ObservableProperty", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.random", "PlatformRandomKt", false, "asJavaRandom", "(Random)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.random", "PlatformRandomKt", false, "asKotlinRandom", "(Random)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.random", "Random", true, "nextBytes", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.random", "Random", true, "nextBytes", "(byte[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.random", "URandomKt", false, "nextUBytes", "(Random,UByteArray)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.random", "URandomKt", false, "nextUBytes", "(Random,UByteArray,int,int)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "CharRange$Companion", false, "getEMPTY", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "IntRange$Companion", false, "getEMPTY", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "LongRange$Companion", false, "getEMPTY", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceAtLeast", "(Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceAtLeast", "(Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceAtMost", "(Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceAtMost", "(Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceIn", "(Comparable,ClosedFloatingPointRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceIn", "(Comparable,ClosedRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceIn", "(Comparable,Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceIn", "(Comparable,Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceIn", "(Comparable,Comparable,Comparable)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "rangeTo", "(Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "rangeTo", "(Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "rangeUntil", "(Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "rangeUntil", "(Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "UIntRange$Companion", false, "getEMPTY", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "ULongRange$Companion", false, "getEMPTY", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KClasses", false, "cast", "(KClass,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KClasses", false, "safeCast", "(KClass,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KType", true, "getArguments", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KType", true, "getClassifier", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeParameter", true, "getName", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeParameter", true, "getUpperBounds", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection", false, "KTypeProjection", "(KVariance,KType)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection", false, "component2", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection", false, "contravariant", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection", false, "copy", "(KVariance,KType)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection", false, "covariant", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection", false, "getType", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection", false, "invariant", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection", false, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection$Companion", false, "contravariant", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection$Companion", false, "covariant", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection$Companion", false, "invariant", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "TypesJVMKt", false, "getJavaType", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "WildcardTypeImpl$Companion", false, "getSTAR", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequenceScope", true, "yieldAll", "(Sequence)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "asSequence", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateBy", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateByTo", "(Sequence,Map,Function1)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateByTo", "(Sequence,Map,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateByTo", "(Sequence,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateByTo", "(Sequence,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateTo", "(Sequence,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateWith", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateWithTo", "(Sequence,Map,Function1)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateWithTo", "(Sequence,Map,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateWithTo", "(Sequence,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "chunked", "(Sequence,int,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "constrainOnce", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "distinct", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "distinctBy", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "distinctBy", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "drop", "(Sequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "dropWhile", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "dropWhile", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "elementAt", "(Sequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "elementAtOrElse", "(Sequence,int,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "elementAtOrNull", "(Sequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filter", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filter", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIndexedTo", "(Sequence,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIsInstance", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIsInstance", "(Sequence,Class)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIsInstanceTo", "(Sequence,Collection)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIsInstanceTo", "(Sequence,Collection)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIsInstanceTo", "(Sequence,Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIsInstanceTo", "(Sequence,Collection,Class)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIsInstanceTo", "(Sequence,Collection,Class)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIsInstanceTo", "(Sequence,Collection,Class)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNot", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNot", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNotNull", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNotNullTo", "(Sequence,Collection)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNotNullTo", "(Sequence,Collection)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNotNullTo", "(Sequence,Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNotTo", "(Sequence,Collection,Function1)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNotTo", "(Sequence,Collection,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNotTo", "(Sequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterTo", "(Sequence,Collection,Function1)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterTo", "(Sequence,Collection,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterTo", "(Sequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "find", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "findLast", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "first", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "first", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "firstNotNullOf", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "firstNotNullOfOrNull", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "firstOrNull", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "firstOrNull", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatMap", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatMap", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatMapIndexedIterableTo", "(Sequence,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatMapIndexedSequenceTo", "(Sequence,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatMapIterable", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatMapIterable", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatMapIterableTo", "(Sequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatMapTo", "(Sequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatten", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flattenSequenceOfIterable", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "fold", "(Sequence,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "foldIndexed", "(Sequence,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "generateSequence", "(Function0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "generateSequence", "(Function0,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "generateSequence", "(Function0,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "generateSequence", "(Object,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "groupByTo", "(Sequence,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "groupByTo", "(Sequence,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinToString", "(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinToString", "(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinToString", "(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinToString", "(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinToString", "(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "last", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "last", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "lastOrNull", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "lastOrNull", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "map", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "map", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapIndexed", "(Sequence,Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapIndexed", "(Sequence,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapIndexedNotNull", "(Sequence,Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapIndexedNotNull", "(Sequence,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapIndexedNotNullTo", "(Sequence,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapIndexedTo", "(Sequence,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapNotNull", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapNotNull", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapNotNullTo", "(Sequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapTo", "(Sequence,Collection,Function1)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapTo", "(Sequence,Collection,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapTo", "(Sequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "max", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxBy", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxByOrNull", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxByOrThrow", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxOfWith", "(Sequence,Comparator,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxOfWithOrNull", "(Sequence,Comparator,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxOrNull", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxOrThrow", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxWith", "(Sequence,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxWithOrNull", "(Sequence,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxWithOrThrow", "(Sequence,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "min", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minBy", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minByOrNull", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minByOrThrow", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minOfWith", "(Sequence,Comparator,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minOfWithOrNull", "(Sequence,Comparator,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minOrNull", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minOrThrow", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minWith", "(Sequence,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minWithOrNull", "(Sequence,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minWithOrThrow", "(Sequence,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minus", "(Sequence,Object[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "onEach", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "onEachIndexed", "(Sequence,Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "orEmpty", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "partition", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "reduce", "(Sequence,Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "reduceIndexed", "(Sequence,Function3)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "reduceIndexedOrNull", "(Sequence,Function3)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "reduceOrNull", "(Sequence,Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "requireNoNulls", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "single", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "single", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "singleOrNull", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "singleOrNull", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "take", "(Sequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "takeWhile", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "takeWhile", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toCollection", "(Sequence,Collection)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toCollection", "(Sequence,Collection)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toCollection", "(Sequence,Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toHashSet", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toList", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toMutableList", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toMutableSet", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toSet", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toSortedSet", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toSortedSet", "(Sequence,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "unzip", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "windowed", "(Sequence,int,int,boolean,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "withIndex", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "zip", "(Sequence,Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "zip", "(Sequence,Sequence)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "zip", "(Sequence,Sequence,Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "zip", "(Sequence,Sequence,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "zip", "(Sequence,Sequence,Function2)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "CharsKt", false, "plus", "(char,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "MatchGroup", "(String,IntRange)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "MatchGroup", "(String,IntRange)", "", "Argument[1].Element", "Argument[-1]", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "component1", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "component2", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "copy", "(String,IntRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "copy", "(String,IntRange)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "getRange", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "getValue", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult", true, "getDestructured", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult", true, "getGroupValues", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult", true, "getGroups", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult", true, "next", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component1", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component10", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component2", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component3", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component4", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component5", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component6", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component7", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component8", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component9", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "getMatch", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "toList", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "find", "(CharSequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "getOptions", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "matchEntire", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "replace", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "replace", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "replace", "(CharSequence,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "replaceFirst", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "replaceFirst", "(CharSequence,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "toPattern", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex$Companion", false, "escape", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "String", "(StringBuffer)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "String", "(StringBuilder)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "String", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "String", "(byte[],Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "String", "(byte[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "String", "(byte[],int,int,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "String", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "String", "(char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "append", "(Appendable,CharSequence[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "append", "(StringBuilder,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "append", "(StringBuilder,Object)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "append", "(StringBuilder,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "append", "(StringBuilder,Object[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "append", "(StringBuilder,String[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(Appendable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(Appendable,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(Appendable,CharSequence)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(Appendable,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(Appendable,char)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,CharSequence)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,Object)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,String)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,StringBuffer)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,StringBuffer)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,StringBuffer)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,StringBuilder)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,StringBuilder)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,StringBuilder)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,byte)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,char)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,char[])", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,char[])", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,double)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,float)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,long)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,short)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(Appendable,CharSequence,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(Appendable,CharSequence,int,int)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(Appendable,CharSequence,int,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(StringBuilder,CharSequence,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(StringBuilder,CharSequence,int,int)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(StringBuilder,CharSequence,int,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(StringBuilder,char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(StringBuilder,char[],int,int)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(StringBuilder,char[],int,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(Appendable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(Appendable,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(Appendable,CharSequence)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(Appendable,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(Appendable,char)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,CharSequence)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,Object)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,String)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,StringBuffer)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,StringBuffer)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,StringBuffer)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,StringBuilder)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,StringBuilder)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,StringBuilder)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,byte)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,char)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,char[])", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,char[])", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,double)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,float)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,long)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,short)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "associateByTo", "(CharSequence,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "associateByTo", "(CharSequence,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "associateTo", "(CharSequence,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "associateWithTo", "(CharSequence,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "capitalize", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "capitalize", "(String,Locale)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "clear", "(StringBuilder)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "concatToString", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "concatToString", "(char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "decapitalize", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "decapitalize", "(String,Locale)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "decodeToString", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "decodeToString", "(byte[],int,int,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "drop", "(CharSequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "drop", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "dropLast", "(CharSequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "dropLast", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "dropLastWhile", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "dropLastWhile", "(String,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "dropWhile", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "dropWhile", "(String,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "encodeToByteArray", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "encodeToByteArray", "(String,int,int,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "filterIndexedTo", "(CharSequence,Appendable,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "filterNotTo", "(CharSequence,Appendable,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "filterTo", "(CharSequence,Appendable,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "findAnyOf", "(CharSequence,Collection,int,boolean)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "findLastAnyOf", "(CharSequence,Collection,int,boolean)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "flatMapIndexedIterableTo", "(CharSequence,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "flatMapTo", "(CharSequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "fold", "(CharSequence,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "foldIndexed", "(CharSequence,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "foldRight", "(CharSequence,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "foldRightIndexed", "(CharSequence,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "format", "(String,Locale,Object[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "format", "(String,Locale,Object[])", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "format", "(String,Object[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "format", "(String,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "format", "(StringCompanionObject,Locale,String,Object[])", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "format", "(StringCompanionObject,Locale,String,Object[])", "", "Argument[3].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "format", "(StringCompanionObject,String,Object[])", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "format", "(StringCompanionObject,String,Object[])", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "formatNullable", "(String,Locale,Object[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "formatNullable", "(String,Locale,Object[])", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "formatNullable", "(StringCompanionObject,Locale,String,Object[])", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "formatNullable", "(StringCompanionObject,Locale,String,Object[])", "", "Argument[3].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "groupByTo", "(CharSequence,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "groupByTo", "(CharSequence,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "ifBlank", "(CharSequence,Function0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "ifEmpty", "(CharSequence,Function0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "insertRange", "(StringBuilder,int,CharSequence,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "insertRange", "(StringBuilder,int,CharSequence,int,int)", "", "Argument[2]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "insertRange", "(StringBuilder,int,CharSequence,int,int)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "insertRange", "(StringBuilder,int,char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "insertRange", "(StringBuilder,int,char[],int,int)", "", "Argument[2]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "insertRange", "(StringBuilder,int,char[],int,int)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "intern", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "lineSequence", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "lines", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "lowercase", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "lowercase", "(String,Locale)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "mapIndexedNotNullTo", "(CharSequence,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "mapIndexedTo", "(CharSequence,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "mapNotNullTo", "(CharSequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "mapTo", "(CharSequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "onEach", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "onEachIndexed", "(CharSequence,Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "orEmpty", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "padEnd", "(CharSequence,int,char)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "padStart", "(CharSequence,int,char)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "prependIndent", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removePrefix", "(CharSequence,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removePrefix", "(String,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removeRange", "(CharSequence,IntRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removeRange", "(CharSequence,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removeSuffix", "(CharSequence,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removeSuffix", "(String,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removeSurrounding", "(CharSequence,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removeSurrounding", "(CharSequence,CharSequence,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removeSurrounding", "(String,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removeSurrounding", "(String,CharSequence,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "repeat", "(CharSequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replace", "(CharSequence,Regex,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replace", "(CharSequence,Regex,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replace", "(CharSequence,Regex,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replace", "(String,char,char,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceAfter", "(String,String,String,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceAfter", "(String,char,String,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceAfterLast", "(String,String,String,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceAfterLast", "(String,char,String,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceBefore", "(String,String,String,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceBefore", "(String,char,String,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceBeforeLast", "(String,String,String,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceBeforeLast", "(String,char,String,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceFirst", "(CharSequence,Regex,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceFirst", "(CharSequence,Regex,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceFirst", "(String,String,String,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceFirst", "(String,char,char,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceFirstCharWithChar", "(String,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceFirstCharWithCharSequence", "(String,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceRange", "(CharSequence,IntRange,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceRange", "(CharSequence,IntRange,CharSequence)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceRange", "(CharSequence,int,int,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceRange", "(CharSequence,int,int,CharSequence)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "reversed", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "runningFold", "(CharSequence,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "runningFoldIndexed", "(CharSequence,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "scan", "(CharSequence,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "scanIndexed", "(CharSequence,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "setRange", "(StringBuilder,int,int,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "setRange", "(StringBuilder,int,int,String)", "", "Argument[3]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "setRange", "(StringBuilder,int,int,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "slice", "(CharSequence,IntRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "slice", "(String,IntRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "split", "(CharSequence,Pattern,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "splitToSequence", "(CharSequence,String[],boolean,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "splitToSequence", "(CharSequence,char[],boolean,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "subSequence", "(CharSequence,IntRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "subSequence", "(String,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substring", "(String,IntRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substring", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substring", "(String,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringAfter", "(String,String,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringAfter", "(String,String,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringAfter", "(String,char,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringAfter", "(String,char,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringAfterLast", "(String,String,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringAfterLast", "(String,String,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringAfterLast", "(String,char,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringAfterLast", "(String,char,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringBefore", "(String,String,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringBefore", "(String,String,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringBefore", "(String,char,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringBefore", "(String,char,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringBeforeLast", "(String,String,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringBeforeLast", "(String,String,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringBeforeLast", "(String,char,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringBeforeLast", "(String,char,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "take", "(CharSequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "take", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "takeLast", "(CharSequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "takeLast", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "takeLastWhile", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "takeLastWhile", "(String,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "takeWhile", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "takeWhile", "(String,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toByteArray", "(String,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toCharArray", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toCharArray", "(String,char[],int,int,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toCharArray", "(String,char[],int,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toCharArray", "(String,char[],int,int,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toCharArray", "(String,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toCharArray", "(StringBuilder,char[],int,int,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toCollection", "(CharSequence,Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toLowerCase", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toLowerCase", "(String,Locale)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toRegex", "(Pattern)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toUpperCase", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toUpperCase", "(String,Locale)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trim", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trim", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trim", "(CharSequence,char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trimEnd", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trimEnd", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trimEnd", "(CharSequence,char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trimStart", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trimStart", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trimStart", "(CharSequence,char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "uppercase", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "uppercase", "(String,Locale)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "Duration", false, "div", "(double)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "Duration", false, "div", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "Duration", false, "getAbsoluteValue", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "Duration", false, "minus", "(Duration)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "Duration", false, "plus", "(Duration)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["kotlin.time", "Duration", false, "times", "(double)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "Duration", false, "times", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "Duration$Companion", false, "getINFINITE", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "Duration$Companion", false, "getZERO", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "DurationKt", false, "times", "(double,Duration)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "DurationKt", false, "times", "(int,Duration)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimeMark", true, "minus", "(Duration)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimeMark", true, "plus", "(Duration)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimeMark", true, "plus", "(Duration)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimeSource", true, "markNow", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "TimedValue", "(Object,Duration)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "TimedValue", "(Object,Duration)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "component1", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "component2", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "copy", "(Object,Duration)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "copy", "(Object,Duration)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "getDuration", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "getValue", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "DeepRecursiveFunction", false, "DeepRecursiveFunction", "(SuspendFunction2)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin", "KotlinVersion$Companion", false, "getCURRENT", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "LazyKt", false, "getValue", "(Lazy,Object,KProperty)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "LazyKt", false, "lazy", "(Function0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "LazyKt", false, "lazy", "(LazyThreadSafetyMode,Function0)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "LazyKt", false, "lazy", "(Object,Function0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "LazyKt", false, "lazy", "(Object,Function0)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "LazyKt", false, "lazyOf", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Pair", false, "Pair", "(Object,Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin", "Pair", false, "Pair", "(Object,Object)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin", "Pair", false, "component1", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Pair", false, "component2", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Pair", false, "copy", "(Object,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Pair", false, "copy", "(Object,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Pair", false, "getFirst", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Pair", false, "getSecond", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Pair", false, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "PreconditionsKt", false, "checkNotNull", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "PreconditionsKt", false, "checkNotNull", "(Object,Function0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "PreconditionsKt", false, "requireNotNull", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "PreconditionsKt", false, "requireNotNull", "(Object,Function0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Result", false, "exceptionOrNull", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Result", false, "getOrNull", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Result", false, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Result$Companion", false, "failure", "(Throwable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Result$Companion", false, "success", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "fold", "(Result,Function1,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "getOrDefault", "(Result,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "getOrDefault", "(Result,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "getOrElse", "(Result,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "getOrThrow", "(Result)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "map", "(Result,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "mapCatching", "(Result,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "onFailure", "(Result,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "onSuccess", "(Result,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "recover", "(Result,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "recoverCatching", "(Result,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "StandardKt", false, "also", "(Object,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "StandardKt", false, "apply", "(Object,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "StandardKt", false, "let", "(Object,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "StandardKt", false, "run", "(Object,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "StandardKt", false, "takeIf", "(Object,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "StandardKt", false, "takeUnless", "(Object,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "StandardKt", false, "with", "(Object,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "SuspendKt", false, "suspend", "(SuspendFunction0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "Triple", "(Object,Object,Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin", "Triple", false, "Triple", "(Object,Object,Object)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin", "Triple", false, "Triple", "(Object,Object,Object)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin", "Triple", false, "component1", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "component2", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "component3", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "copy", "(Object,Object,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "copy", "(Object,Object,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "copy", "(Object,Object,Object)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "getFirst", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "getSecond", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "getThird", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "TuplesKt", false, "to", "(Object,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "TuplesKt", false, "to", "(Object,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "TuplesKt", false, "toList", "(Pair)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "TuplesKt", false, "toList", "(Triple)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "UByte", false, "toUByte", "()", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["kotlin", "UByteArrayKt", false, "ubyteArrayOf", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin", "UInt", false, "toUInt", "()", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["kotlin", "UIntArrayKt", false, "uintArrayOf", "(UIntArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin", "ULong", false, "toULong", "()", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["kotlin", "ULongArrayKt", false, "ulongArrayOf", "(ULongArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin", "UShort", false, "toUShort", "()", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["kotlin", "UShortArrayKt", false, "ushortArrayOf", "(UShortArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + + + - addsTo: + pack: codeql/java-all + extensible: extNegativeSummaryModel + data: + - ["kotlin.annotation", "AnnotationRetention", "valueOf", "(String)", "generated"] + - ["kotlin.annotation", "AnnotationRetention", "values", "()", "generated"] + - ["kotlin.annotation", "AnnotationTarget", "valueOf", "(String)", "generated"] + - ["kotlin.annotation", "AnnotationTarget", "values", "()", "generated"] + - ["kotlin.annotation", "MustBeDocumented", "MustBeDocumented", "()", "generated"] + - ["kotlin.annotation", "Repeatable", "Repeatable", "()", "generated"] + - ["kotlin.annotation", "Retention", "Retention", "(AnnotationRetention)", "generated"] + - ["kotlin.annotation", "Retention", "value", "()", "generated"] + - ["kotlin.annotation", "Target", "Target", "(AnnotationTarget[])", "generated"] + - ["kotlin.annotation", "Target", "allowedTargets", "()", "generated"] + - ["kotlin.collections", "AbstractIterator", "AbstractIterator", "()", "generated"] + - ["kotlin.collections", "AbstractList", "equals", "(Object)", "generated"] + - ["kotlin.collections", "AbstractList", "hashCode", "()", "generated"] + - ["kotlin.collections", "AbstractMap", "equals", "(Object)", "generated"] + - ["kotlin.collections", "AbstractMap", "hashCode", "()", "generated"] + - ["kotlin.collections", "AbstractMap", "toString", "()", "generated"] + - ["kotlin.collections", "AbstractSet", "equals", "(Object)", "generated"] + - ["kotlin.collections", "AbstractSet", "hashCode", "()", "generated"] + - ["kotlin.collections", "ArrayDeque", "ArrayDeque", "()", "generated"] + - ["kotlin.collections", "ArrayDeque", "ArrayDeque", "(int)", "generated"] + - ["kotlin.collections", "ArrayList", "ArrayList", "()", "generated"] + - ["kotlin.collections", "ArrayList", "ArrayList", "(Collection)", "generated"] + - ["kotlin.collections", "ArrayList", "ArrayList", "(int)", "generated"] + - ["kotlin.collections", "ArrayList", "ensureCapacity", "(int)", "generated"] + - ["kotlin.collections", "ArrayList", "trimToSize", "()", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asList", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asList", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asList", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asList", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asList", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asList", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asList", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asList", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(Object[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(boolean[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(byte[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(char[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(double[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(float[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(int[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(long[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(short[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "average", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "average", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "average", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "average", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "average", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "average", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "averageOfByte", "(Byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "averageOfDouble", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "averageOfFloat", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "averageOfInt", "(Integer[])", "generated"] + - ["kotlin.collections", "ArraysKt", "averageOfLong", "(Long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "averageOfShort", "(Short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(Object[],Object,Comparator,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(Object[],Object,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(byte[],byte,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(char[],char,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(double[],double,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(float[],float,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(int[],int,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(long[],long,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(short[],short,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(Object[],Object)", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(boolean[],boolean)", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(byte[],byte)", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(char[],char)", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(double[],double)", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(float[],float)", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(long[],long)", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(short[],short)", "generated"] + - ["kotlin.collections", "ArraysKt", "contentDeepEqualsInline", "(Object[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentDeepEqualsNullable", "(Object[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentDeepHashCodeInline", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentDeepHashCodeNullable", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentDeepToStringInline", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentDeepToStringNullable", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(Object[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(boolean[],boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(byte[],byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(char[],char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(double[],double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(float[],float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(int[],int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(long[],long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(short[],short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(Object[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(boolean[],boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(byte[],byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(char[],char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(double[],double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(float[],float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(int[],int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(long[],long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(short[],short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "copyInto", "(boolean[],boolean[],int,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyInto", "(double[],double[],int,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyInto", "(float[],float[],int,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyInto", "(int[],int[],int,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyInto", "(long[],long[],int,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyInto", "(short[],short[],int,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(boolean[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(double[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(float[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(long[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(short[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOfRangeInline", "(boolean[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOfRangeInline", "(double[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOfRangeInline", "(float[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOfRangeInline", "(int[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOfRangeInline", "(long[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOfRangeInline", "(short[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "drop", "(boolean[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "drop", "(byte[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "drop", "(char[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "drop", "(double[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "drop", "(float[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "drop", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "drop", "(long[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "drop", "(short[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLast", "(boolean[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLast", "(byte[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLast", "(char[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLast", "(double[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLast", "(float[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLast", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLast", "(long[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLast", "(short[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLastWhile", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLastWhile", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLastWhile", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLastWhile", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLastWhile", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLastWhile", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLastWhile", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLastWhile", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(Object[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(boolean[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(byte[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(char[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(double[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(float[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(long[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(short[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(Object[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(boolean[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(byte[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(char[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(double[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(float[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(int[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(long[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(short[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(Object[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(boolean[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(byte[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(char[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(double[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(float[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(long[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(short[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "fill", "(boolean[],boolean,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "fill", "(byte[],byte,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "fill", "(char[],char,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "fill", "(double[],double,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "fill", "(float[],float,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "fill", "(int[],int,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "fill", "(long[],long,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "fill", "(short[],short,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIsInstance", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIsInstance", "(Object[],Class)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNotNull", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "findLast", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "findLast", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "findLast", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "findLast", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "findLast", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "findLast", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "findLast", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "findLast", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstNotNullOf", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstNotNullOfOrNull", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedSequence", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapSequence", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatten", "(Object[][])", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(Object[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(boolean[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(byte[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(char[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(double[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(float[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(int[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(long[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(short[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(Object[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(boolean[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(byte[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(char[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(double[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(float[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(long[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(short[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(Object[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(boolean[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(byte[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(char[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(double[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(float[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(int[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(long[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(short[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupingBy", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(Object[],Object)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(boolean[],boolean)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(byte[],byte)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(char[],char)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(double[],double)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(float[],float)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(long[],long)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(short[],short)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(Object[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(boolean[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(byte[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(char[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(double[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(float[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(int[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(long[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(short[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNullOrEmpty", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(Object[],Object)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(boolean[],boolean)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(byte[],byte)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(char[],char)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(double[],double)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(float[],float)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(long[],long)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(short[],short)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexedNotNull", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapNotNull", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxBy", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxBy", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxBy", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxBy", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxBy", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxBy", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxBy", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxBy", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrNull", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrNull", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrNull", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrNull", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrNull", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrNull", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrNull", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrNull", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrThrow", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrThrow", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrThrow", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrThrow", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrThrow", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrThrow", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrThrow", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrThrow", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWith", "(boolean[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWith", "(byte[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWith", "(char[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWith", "(double[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWith", "(float[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWith", "(int[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWith", "(long[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWith", "(short[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWithOrNull", "(boolean[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWithOrNull", "(byte[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWithOrNull", "(char[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWithOrNull", "(double[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWithOrNull", "(float[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWithOrNull", "(int[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWithOrNull", "(long[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWithOrNull", "(short[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWith", "(boolean[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWith", "(byte[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWith", "(char[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWith", "(double[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWith", "(float[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWith", "(int[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWith", "(long[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWith", "(short[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrNull", "(boolean[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrNull", "(byte[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrNull", "(char[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrNull", "(double[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrNull", "(float[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrNull", "(int[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrNull", "(long[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrNull", "(short[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrThrow", "(boolean[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrThrow", "(byte[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrThrow", "(char[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrThrow", "(double[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrThrow", "(float[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrThrow", "(int[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrThrow", "(long[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrThrow", "(short[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minBy", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minBy", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minBy", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minBy", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minBy", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minBy", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minBy", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minBy", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrNull", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrNull", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrNull", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrNull", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrNull", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrNull", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrNull", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrNull", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrThrow", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrThrow", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrThrow", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrThrow", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrThrow", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrThrow", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrThrow", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrThrow", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWith", "(boolean[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWith", "(byte[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWith", "(char[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWith", "(double[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWith", "(float[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWith", "(int[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWith", "(long[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWith", "(short[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWithOrNull", "(boolean[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWithOrNull", "(byte[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWithOrNull", "(char[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWithOrNull", "(double[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWithOrNull", "(float[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWithOrNull", "(int[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWithOrNull", "(long[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWithOrNull", "(short[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minWith", "(boolean[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWith", "(byte[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWith", "(char[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWith", "(double[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWith", "(float[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWith", "(int[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWith", "(long[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWith", "(short[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrNull", "(boolean[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrNull", "(byte[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrNull", "(char[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrNull", "(double[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrNull", "(float[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrNull", "(int[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrNull", "(long[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrNull", "(short[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrThrow", "(boolean[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrThrow", "(byte[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrThrow", "(char[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrThrow", "(double[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrThrow", "(float[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrThrow", "(int[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrThrow", "(long[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrThrow", "(short[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEach", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEach", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEach", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEach", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEach", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEach", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEachIndexed", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEachIndexed", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEachIndexed", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEachIndexed", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEachIndexed", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEachIndexed", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(boolean[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(boolean[],boolean)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(boolean[],boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(double[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(double[],double)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(double[],double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(float[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(float[],float)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(float[],float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(int[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(int[],int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(long[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(long[],long)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(long[],long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(short[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(short[],short)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(short[],short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(Object[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(boolean[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(byte[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(char[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(double[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(float[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(int[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(long[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(short[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(Object[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(boolean[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(byte[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(char[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(double[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(float[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(int[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(long[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(short[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduce", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduce", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduce", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduce", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduce", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduce", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduce", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduce", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexed", "(boolean[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexed", "(byte[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexed", "(char[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexed", "(double[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexed", "(float[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexed", "(int[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexed", "(long[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexed", "(short[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexedOrNull", "(boolean[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexedOrNull", "(byte[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexedOrNull", "(char[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexedOrNull", "(double[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexedOrNull", "(float[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexedOrNull", "(int[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexedOrNull", "(long[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexedOrNull", "(short[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceOrNull", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceOrNull", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceOrNull", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceOrNull", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceOrNull", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceOrNull", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceOrNull", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceOrNull", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(Object[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(boolean[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(byte[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(char[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(double[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(float[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(int[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(long[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(short[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(Object[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(boolean[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(byte[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(char[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(double[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(float[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(int[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(long[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(short[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(Object[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(boolean[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(byte[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(char[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(double[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(float[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(int[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(long[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(short[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reversed", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversed", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversed", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversed", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversed", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversed", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversed", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversed", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversedArray", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversedArray", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversedArray", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversedArray", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversedArray", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversedArray", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(Object[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(boolean[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(byte[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(char[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(double[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(float[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(int[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(long[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(short[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(Object[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(boolean[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(byte[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(char[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(double[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(float[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(int[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(long[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(short[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(Object[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(boolean[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(boolean[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(byte[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(byte[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(char[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(char[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(double[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(double[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(float[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(float[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(int[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(int[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(long[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(long[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(short[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(short[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(boolean[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(boolean[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(byte[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(char[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(double[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(double[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(float[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(float[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(int[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(int[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(long[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(long[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(short[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(short[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(Comparable[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(Comparable[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(Object[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(byte[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(char[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(double[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(float[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(int[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(long[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(short[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortBy", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortByDescending", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(Comparable[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(Comparable[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(byte[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(char[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(double[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(float[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(int[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(long[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(short[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortWith", "(Object[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortWith", "(Object[],Comparator,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sorted", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sorted", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sorted", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sorted", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sorted", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sorted", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sorted", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArray", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArray", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArray", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArray", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArray", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArrayDescending", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArrayDescending", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArrayDescending", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArrayDescending", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArrayDescending", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedBy", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedBy", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedBy", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedBy", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedBy", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedBy", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedBy", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedBy", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedByDescending", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedByDescending", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedByDescending", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedByDescending", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedByDescending", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedByDescending", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedByDescending", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedByDescending", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedDescending", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedDescending", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedDescending", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedDescending", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedDescending", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedDescending", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedDescending", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedWith", "(boolean[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedWith", "(byte[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedWith", "(char[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedWith", "(double[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedWith", "(float[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedWith", "(int[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedWith", "(long[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedWith", "(short[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(Object[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(boolean[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(byte[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(char[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(double[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(float[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(int[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(long[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(short[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "sum", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sum", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sum", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sum", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sum", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sum", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfByte", "(Byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfFloat", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(Integer[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(Long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfShort", "(Short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "take", "(boolean[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "take", "(byte[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "take", "(char[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "take", "(double[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "take", "(float[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "take", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "take", "(long[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "take", "(short[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLast", "(boolean[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLast", "(byte[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLast", "(char[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLast", "(double[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLast", "(float[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLast", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLast", "(long[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLast", "(short[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLastWhile", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLastWhile", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLastWhile", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLastWhile", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLastWhile", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLastWhile", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLastWhile", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLastWhile", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "toBooleanArray", "(Boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toByteArray", "(Byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toCharArray", "(Character[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toDoubleArray", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toFloatArray", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toIntArray", "(Integer[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toList", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toList", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toList", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toList", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toList", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toList", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toList", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toList", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toLongArray", "(Long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableList", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableList", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableList", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableList", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableList", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableList", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableList", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableList", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSet", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSet", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSet", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSet", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSet", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSet", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSet", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSet", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toShortArray", "(Short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(Comparable[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(Object[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toTypedArray", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toTypedArray", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toTypedArray", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toTypedArray", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toTypedArray", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toTypedArray", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toTypedArray", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toTypedArray", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "union", "(boolean[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "union", "(double[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "union", "(float[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "union", "(int[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "union", "(long[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "union", "(short[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "unzip", "(Pair[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(boolean[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(boolean[],Iterable,Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(boolean[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(boolean[],Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(boolean[],boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(boolean[],boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(byte[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(byte[],Iterable,Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(byte[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(byte[],Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(byte[],byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(byte[],byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(char[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(char[],Iterable,Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(char[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(char[],Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(char[],char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(char[],char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(double[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(double[],Iterable,Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(double[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(double[],Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(double[],double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(double[],double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(float[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(float[],Iterable,Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(float[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(float[],Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(float[],float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(float[],float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(int[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(int[],Iterable,Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(int[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(int[],Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(int[],int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(int[],int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(long[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(long[],Iterable,Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(long[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(long[],Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(long[],long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(long[],long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(short[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(short[],Iterable,Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(short[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(short[],Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(short[],short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(short[],short[],Function2)", "generated"] + - ["kotlin.collections", "BooleanIterator", "BooleanIterator", "()", "generated"] + - ["kotlin.collections", "BooleanIterator", "nextBoolean", "()", "generated"] + - ["kotlin.collections", "ByteIterator", "ByteIterator", "()", "generated"] + - ["kotlin.collections", "ByteIterator", "nextByte", "()", "generated"] + - ["kotlin.collections", "CharIterator", "CharIterator", "()", "generated"] + - ["kotlin.collections", "CharIterator", "nextChar", "()", "generated"] + - ["kotlin.collections", "CollectionsHKt", "eachCount", "(Grouping)", "generated"] + - ["kotlin.collections", "CollectionsHKt", "fill", "(List,Object)", "generated"] + - ["kotlin.collections", "CollectionsHKt", "orEmpty", "(Object[])", "generated"] + - ["kotlin.collections", "CollectionsHKt", "shuffle", "(List)", "generated"] + - ["kotlin.collections", "CollectionsHKt", "shuffled", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsHKt", "sort", "(List)", "generated"] + - ["kotlin.collections", "CollectionsHKt", "sortWith", "(List,Comparator)", "generated"] + - ["kotlin.collections", "CollectionsHKt", "toTypedArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "Iterable", "(Function0)", "generated"] + - ["kotlin.collections", "CollectionsKt", "List", "(int,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "MutableList", "(int,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "all", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "any", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "any", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "arrayListOf", "()", "generated"] + - ["kotlin.collections", "CollectionsKt", "asSequence", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "averageOfByte", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "averageOfDouble", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "averageOfFloat", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "averageOfInt", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "averageOfLong", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "averageOfShort", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "binarySearch", "(List,Comparable,int,int)", "generated"] + - ["kotlin.collections", "CollectionsKt", "binarySearch", "(List,Object,Comparator,int,int)", "generated"] + - ["kotlin.collections", "CollectionsKt", "binarySearch", "(List,int,int,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "binarySearchBy", "(List,Comparable,int,int,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "buildList", "(Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "buildList", "(int,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "chunked", "(Iterable,int)", "generated"] + - ["kotlin.collections", "CollectionsKt", "chunked", "(Iterable,int,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "contains", "(Iterable,Object)", "generated"] + - ["kotlin.collections", "CollectionsKt", "containsAll", "(Collection,Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "count", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "count", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "count", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "emptyList", "()", "generated"] + - ["kotlin.collections", "CollectionsKt", "filterIndexed", "(Iterable,Function2)", "generated"] + - ["kotlin.collections", "CollectionsKt", "flatMap", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "flatMapIndexedIterable", "(Iterable,Function2)", "generated"] + - ["kotlin.collections", "CollectionsKt", "flatMapIndexedSequence", "(Iterable,Function2)", "generated"] + - ["kotlin.collections", "CollectionsKt", "flatMapSequence", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "forEach", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "forEach", "(Iterator,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "forEachIndexed", "(Iterable,Function2)", "generated"] + - ["kotlin.collections", "CollectionsKt", "getIndices", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "getLastIndex", "(List)", "generated"] + - ["kotlin.collections", "CollectionsKt", "groupBy", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "groupBy", "(Iterable,Function1,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "groupingBy", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "indexOf", "(Iterable,Object)", "generated"] + - ["kotlin.collections", "CollectionsKt", "indexOf", "(List,Object)", "generated"] + - ["kotlin.collections", "CollectionsKt", "indexOfFirst", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "indexOfFirst", "(List,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "indexOfLast", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "indexOfLast", "(List,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "isNotEmpty", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "isNullOrEmpty", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "iterator", "(Enumeration)", "generated"] + - ["kotlin.collections", "CollectionsKt", "lastIndexOf", "(Iterable,Object)", "generated"] + - ["kotlin.collections", "CollectionsKt", "lastIndexOf", "(List,Object)", "generated"] + - ["kotlin.collections", "CollectionsKt", "listOf", "()", "generated"] + - ["kotlin.collections", "CollectionsKt", "listOfNotNull", "(Object[])", "generated"] + - ["kotlin.collections", "CollectionsKt", "mapIndexed", "(Iterable,Function2)", "generated"] + - ["kotlin.collections", "CollectionsKt", "mapIndexedNotNull", "(Iterable,Function2)", "generated"] + - ["kotlin.collections", "CollectionsKt", "mapNotNull", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "max", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "maxOf", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "maxOfOrNull", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "maxOrNull", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "maxOrThrow", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "min", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "minOf", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "minOfOrNull", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "minOrNull", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "minOrThrow", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "minusAssign", "(Collection,Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "minusAssign", "(Collection,Object)", "generated"] + - ["kotlin.collections", "CollectionsKt", "minusAssign", "(Collection,Object[])", "generated"] + - ["kotlin.collections", "CollectionsKt", "minusAssign", "(Collection,Sequence)", "generated"] + - ["kotlin.collections", "CollectionsKt", "mutableListOf", "()", "generated"] + - ["kotlin.collections", "CollectionsKt", "none", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "none", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "remove", "(Collection,Object)", "generated"] + - ["kotlin.collections", "CollectionsKt", "removeAll", "(Collection,Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "removeAll", "(Collection,Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "removeAll", "(Collection,Object[])", "generated"] + - ["kotlin.collections", "CollectionsKt", "removeAll", "(Collection,Sequence)", "generated"] + - ["kotlin.collections", "CollectionsKt", "removeAll", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "removeAll", "(List,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "retainAll", "(Collection,Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "retainAll", "(Collection,Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "retainAll", "(Collection,Object[])", "generated"] + - ["kotlin.collections", "CollectionsKt", "retainAll", "(Collection,Sequence)", "generated"] + - ["kotlin.collections", "CollectionsKt", "retainAll", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "retainAll", "(List,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "reverse", "(List)", "generated"] + - ["kotlin.collections", "CollectionsKt", "runningReduce", "(Iterable,Function2)", "generated"] + - ["kotlin.collections", "CollectionsKt", "runningReduceIndexed", "(Iterable,Function3)", "generated"] + - ["kotlin.collections", "CollectionsKt", "shuffle", "(List)", "generated"] + - ["kotlin.collections", "CollectionsKt", "shuffle", "(List,Random)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sort", "(List)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sort", "(List,Comparator)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sort", "(List,Function2)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sortBy", "(List,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sortByDescending", "(List,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sortDescending", "(List)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sortWith", "(List,Comparator)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumBy", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumByDouble", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfBigDecimal", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfBigInteger", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfByte", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfDouble", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfDouble", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfFloat", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfInt", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfInt", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfLong", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfLong", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfShort", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfUInt", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfULong", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "toBooleanArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "toByteArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "toCharArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "toDoubleArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "toFloatArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "toIntArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "toLongArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "toShortArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "windowed", "(Iterable,int,int,boolean)", "generated"] + - ["kotlin.collections", "CollectionsKt", "windowed", "(Iterable,int,int,boolean,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "withIndex", "(Iterable)", "generated"] + - ["kotlin.collections", "DoubleIterator", "DoubleIterator", "()", "generated"] + - ["kotlin.collections", "DoubleIterator", "nextDouble", "()", "generated"] + - ["kotlin.collections", "FloatIterator", "FloatIterator", "()", "generated"] + - ["kotlin.collections", "FloatIterator", "nextFloat", "()", "generated"] + - ["kotlin.collections", "Grouping", "keyOf", "(Object)", "generated"] + - ["kotlin.collections", "Grouping", "sourceIterator", "()", "generated"] + - ["kotlin.collections", "GroupingKt", "aggregate", "(Grouping,Function4)", "generated"] + - ["kotlin.collections", "GroupingKt", "eachCount", "(Grouping)", "generated"] + - ["kotlin.collections", "GroupingKt", "fold", "(Grouping,Function2,Function3)", "generated"] + - ["kotlin.collections", "GroupingKt", "fold", "(Grouping,Object,Function2)", "generated"] + - ["kotlin.collections", "GroupingKt", "reduce", "(Grouping,Function3)", "generated"] + - ["kotlin.collections", "HashMap", "HashMap", "()", "generated"] + - ["kotlin.collections", "HashMap", "HashMap", "(Map)", "generated"] + - ["kotlin.collections", "HashMap", "HashMap", "(int)", "generated"] + - ["kotlin.collections", "HashMap", "HashMap", "(int,float)", "generated"] + - ["kotlin.collections", "HashSet", "HashSet", "()", "generated"] + - ["kotlin.collections", "HashSet", "HashSet", "(Collection)", "generated"] + - ["kotlin.collections", "HashSet", "HashSet", "(int)", "generated"] + - ["kotlin.collections", "HashSet", "HashSet", "(int,float)", "generated"] + - ["kotlin.collections", "IndexedValue", "component1", "()", "generated"] + - ["kotlin.collections", "IndexedValue", "equals", "(Object)", "generated"] + - ["kotlin.collections", "IndexedValue", "getIndex", "()", "generated"] + - ["kotlin.collections", "IndexedValue", "hashCode", "()", "generated"] + - ["kotlin.collections", "IntIterator", "IntIterator", "()", "generated"] + - ["kotlin.collections", "IntIterator", "nextInt", "()", "generated"] + - ["kotlin.collections", "LinkedHashMap", "LinkedHashMap", "()", "generated"] + - ["kotlin.collections", "LinkedHashMap", "LinkedHashMap", "(Map)", "generated"] + - ["kotlin.collections", "LinkedHashMap", "LinkedHashMap", "(int)", "generated"] + - ["kotlin.collections", "LinkedHashMap", "LinkedHashMap", "(int,float)", "generated"] + - ["kotlin.collections", "LinkedHashSet", "LinkedHashSet", "()", "generated"] + - ["kotlin.collections", "LinkedHashSet", "LinkedHashSet", "(Collection)", "generated"] + - ["kotlin.collections", "LinkedHashSet", "LinkedHashSet", "(int)", "generated"] + - ["kotlin.collections", "LinkedHashSet", "LinkedHashSet", "(int,float)", "generated"] + - ["kotlin.collections", "LongIterator", "LongIterator", "()", "generated"] + - ["kotlin.collections", "LongIterator", "nextLong", "()", "generated"] + - ["kotlin.collections", "MapsKt", "all", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "any", "(Map)", "generated"] + - ["kotlin.collections", "MapsKt", "any", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "asSequence", "(Map)", "generated"] + - ["kotlin.collections", "MapsKt", "buildMap", "(Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "buildMap", "(int,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "contains", "(Map,Object)", "generated"] + - ["kotlin.collections", "MapsKt", "containsKey", "(Map,Object)", "generated"] + - ["kotlin.collections", "MapsKt", "containsValue", "(Map,Object)", "generated"] + - ["kotlin.collections", "MapsKt", "count", "(Map)", "generated"] + - ["kotlin.collections", "MapsKt", "count", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "emptyMap", "()", "generated"] + - ["kotlin.collections", "MapsKt", "flatMap", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "flatMapSequence", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "forEach", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "hashMapOf", "()", "generated"] + - ["kotlin.collections", "MapsKt", "hashMapOf", "(Pair[])", "generated"] + - ["kotlin.collections", "MapsKt", "isNotEmpty", "(Map)", "generated"] + - ["kotlin.collections", "MapsKt", "isNullOrEmpty", "(Map)", "generated"] + - ["kotlin.collections", "MapsKt", "linkedMapOf", "()", "generated"] + - ["kotlin.collections", "MapsKt", "linkedMapOf", "(Pair[])", "generated"] + - ["kotlin.collections", "MapsKt", "mapNotNull", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "mapOf", "()", "generated"] + - ["kotlin.collections", "MapsKt", "mapOf", "(Pair[])", "generated"] + - ["kotlin.collections", "MapsKt", "maxOf", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "maxOfOrNull", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "minOf", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "minOfOrNull", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "minusAssign", "(Map,Iterable)", "generated"] + - ["kotlin.collections", "MapsKt", "minusAssign", "(Map,Object)", "generated"] + - ["kotlin.collections", "MapsKt", "minusAssign", "(Map,Object[])", "generated"] + - ["kotlin.collections", "MapsKt", "minusAssign", "(Map,Sequence)", "generated"] + - ["kotlin.collections", "MapsKt", "mutableMapOf", "()", "generated"] + - ["kotlin.collections", "MapsKt", "mutableMapOf", "(Pair[])", "generated"] + - ["kotlin.collections", "MapsKt", "none", "(Map)", "generated"] + - ["kotlin.collections", "MapsKt", "none", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "plusAssign", "(Map,Pair[])", "generated"] + - ["kotlin.collections", "MapsKt", "putAll", "(Map,Pair[])", "generated"] + - ["kotlin.collections", "MapsKt", "sortedMapOf", "(Comparator,Pair[])", "generated"] + - ["kotlin.collections", "MapsKt", "sortedMapOf", "(Pair[])", "generated"] + - ["kotlin.collections", "MapsKt", "toMap", "(Sequence)", "generated"] + - ["kotlin.collections", "MapsKt", "toProperties", "(Map)", "generated"] + - ["kotlin.collections", "MapsKt", "toSortedMap", "(Map,Comparator)", "generated"] + - ["kotlin.collections", "SetsKt", "buildSet", "(Function1)", "generated"] + - ["kotlin.collections", "SetsKt", "buildSet", "(int,Function1)", "generated"] + - ["kotlin.collections", "SetsKt", "emptySet", "()", "generated"] + - ["kotlin.collections", "SetsKt", "hashSetOf", "()", "generated"] + - ["kotlin.collections", "SetsKt", "hashSetOf", "(Object[])", "generated"] + - ["kotlin.collections", "SetsKt", "linkedSetOf", "()", "generated"] + - ["kotlin.collections", "SetsKt", "linkedSetOf", "(Object[])", "generated"] + - ["kotlin.collections", "SetsKt", "mutableSetOf", "()", "generated"] + - ["kotlin.collections", "SetsKt", "mutableSetOf", "(Object[])", "generated"] + - ["kotlin.collections", "SetsKt", "setOf", "()", "generated"] + - ["kotlin.collections", "SetsKt", "setOfNotNull", "(Object[])", "generated"] + - ["kotlin.collections", "SetsKt", "sortedSetOf", "(Comparator,Object[])", "generated"] + - ["kotlin.collections", "SetsKt", "sortedSetOf", "(Object[])", "generated"] + - ["kotlin.collections", "ShortIterator", "ShortIterator", "()", "generated"] + - ["kotlin.collections", "ShortIterator", "nextShort", "()", "generated"] + - ["kotlin.collections", "UArraysKt", "all", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "all", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "all", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "all", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "any", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "any", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "any", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "any", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "any", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "any", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "any", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "any", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "asIntArray", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "asList", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "asList", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "asList", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "asList", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "asLongArray", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "asShortArray", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "asUIntArray", "(int[])", "generated"] + - ["kotlin.collections", "UArraysKt", "asULongArray", "(long[])", "generated"] + - ["kotlin.collections", "UArraysKt", "asUShortArray", "(short[])", "generated"] + - ["kotlin.collections", "UArraysKt", "associateWith", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "associateWith", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "associateWith", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "associateWith", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "binarySearch", "(UByteArray,byte,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "binarySearch", "(UIntArray,int,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "binarySearch", "(ULongArray,long,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "binarySearch", "(UShortArray,short,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "component1", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component1", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component1", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component1", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component2", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component2", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component2", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component2", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component3", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component3", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component3", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component3", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component4", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component4", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component4", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component4", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component5", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component5", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component5", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component5", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "contentEquals", "(UByteArray,UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "contentEquals", "(UIntArray,UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "contentEquals", "(ULongArray,ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "contentEquals", "(UShortArray,UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "contentHashCode", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "contentHashCode", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "contentHashCode", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "contentHashCode", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOf", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOf", "(UIntArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOf", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOf", "(ULongArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOf", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOf", "(UShortArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOfRange", "(UIntArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOfRange", "(ULongArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOfRange", "(UShortArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "count", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "count", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "count", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "count", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "dropWhile", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "dropWhile", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "dropWhile", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "dropWhile", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAt", "(UByteArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAt", "(UIntArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAt", "(ULongArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAt", "(UShortArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAtOrElse", "(UByteArray,int,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAtOrElse", "(UIntArray,int,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAtOrElse", "(ULongArray,int,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAtOrElse", "(UShortArray,int,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAtOrNull", "(UByteArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAtOrNull", "(UIntArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAtOrNull", "(ULongArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAtOrNull", "(UShortArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "fill", "(UByteArray,byte,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "fill", "(UIntArray,int,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "fill", "(ULongArray,long,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "fill", "(UShortArray,short,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "filter", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "filter", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "filter", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "filter", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "filterIndexed", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "filterIndexed", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "filterIndexed", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "filterIndexed", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "filterNot", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "filterNot", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "filterNot", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "filterNot", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "find", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "find", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "find", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "find", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "findLast", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "findLast", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "findLast", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "findLast", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "first", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "first", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "first", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "first", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "first", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "first", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "first", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "first", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "firstOrNull", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "firstOrNull", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "firstOrNull", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "firstOrNull", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "firstOrNull", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "firstOrNull", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "firstOrNull", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "firstOrNull", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "flatMap", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "flatMap", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "flatMap", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "flatMap", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "flatMapIndexed", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "flatMapIndexed", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "flatMapIndexed", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "flatMapIndexed", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "forEach", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "forEach", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "forEach", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "forEach", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "forEachIndexed", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "forEachIndexed", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "forEachIndexed", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "forEachIndexed", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "getIndices", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "getIndices", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "getIndices", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "getIndices", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "getLastIndex", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "getLastIndex", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "getLastIndex", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "getLastIndex", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "getOrElse", "(UByteArray,int,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "getOrElse", "(UIntArray,int,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "getOrElse", "(ULongArray,int,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "getOrElse", "(UShortArray,int,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "getOrNull", "(UByteArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "getOrNull", "(UIntArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "getOrNull", "(ULongArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "getOrNull", "(UShortArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "groupBy", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "groupBy", "(UByteArray,Function1,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "groupBy", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "groupBy", "(UIntArray,Function1,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "groupBy", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "groupBy", "(ULongArray,Function1,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "groupBy", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "groupBy", "(UShortArray,Function1,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOf", "(UByteArray,byte)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOf", "(UIntArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOf", "(ULongArray,long)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOf", "(UShortArray,short)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOfFirst", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOfFirst", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOfFirst", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOfFirst", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOfLast", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOfLast", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOfLast", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOfLast", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "last", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "last", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "last", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "last", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "last", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "last", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "last", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "last", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastIndexOf", "(UByteArray,byte)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastIndexOf", "(UIntArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastIndexOf", "(ULongArray,long)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastIndexOf", "(UShortArray,short)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastOrNull", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastOrNull", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastOrNull", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastOrNull", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastOrNull", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastOrNull", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastOrNull", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastOrNull", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "map", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "map", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "map", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "map", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "mapIndexed", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "mapIndexed", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "mapIndexed", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "mapIndexed", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "max", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "max", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "max", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "max", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxBy", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxBy", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxBy", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxBy", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxByOrNull", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxByOrNull", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxByOrNull", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxByOrNull", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxByOrThrow-U", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxByOrThrow-U", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxByOrThrow-U", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxByOrThrow-U", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOf", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOf", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOf", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOf", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfOrNull", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfOrNull", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfOrNull", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfOrNull", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfWith", "(UByteArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfWith", "(UIntArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfWith", "(ULongArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfWith", "(UShortArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfWithOrNull", "(UByteArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfWithOrNull", "(UIntArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfWithOrNull", "(ULongArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfWithOrNull", "(UShortArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOrNull", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOrNull", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOrNull", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOrNull", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOrThrow-U", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOrThrow-U", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOrThrow-U", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOrThrow-U", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWith", "(UByteArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWith", "(UIntArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWith", "(ULongArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWith", "(UShortArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWithOrNull", "(UByteArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWithOrNull", "(UIntArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWithOrNull", "(ULongArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWithOrNull", "(UShortArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWithOrThrow-U", "(UByteArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWithOrThrow-U", "(UIntArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWithOrThrow-U", "(ULongArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWithOrThrow-U", "(UShortArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "min", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "min", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "min", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "min", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minBy", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minBy", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minBy", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minBy", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minByOrNull", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minByOrNull", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minByOrNull", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minByOrNull", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minByOrThrow-U", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minByOrThrow-U", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minByOrThrow-U", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minByOrThrow-U", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOf", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOf", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOf", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOf", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfOrNull", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfOrNull", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfOrNull", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfOrNull", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfWith", "(UByteArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfWith", "(UIntArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfWith", "(ULongArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfWith", "(UShortArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfWithOrNull", "(UByteArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfWithOrNull", "(UIntArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfWithOrNull", "(ULongArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfWithOrNull", "(UShortArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOrNull", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOrNull", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOrNull", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOrNull", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOrThrow-U", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOrThrow-U", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOrThrow-U", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOrThrow-U", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWith", "(UByteArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWith", "(UIntArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWith", "(ULongArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWith", "(UShortArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWithOrNull", "(UByteArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWithOrNull", "(UIntArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWithOrNull", "(ULongArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWithOrNull", "(UShortArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWithOrThrow-U", "(UByteArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWithOrThrow-U", "(UIntArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWithOrThrow-U", "(ULongArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWithOrThrow-U", "(UShortArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "none", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "none", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "none", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "none", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "none", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "none", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "none", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "none", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(UIntArray,Collection)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(UIntArray,UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(UIntArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(ULongArray,Collection)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(ULongArray,ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(ULongArray,long)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(UShortArray,Collection)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(UShortArray,UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(UShortArray,short)", "generated"] + - ["kotlin.collections", "UArraysKt", "random", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "random", "(UByteArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "random", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "random", "(UIntArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "random", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "random", "(ULongArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "random", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "random", "(UShortArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "randomOrNull", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "randomOrNull", "(UByteArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "randomOrNull", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "randomOrNull", "(UIntArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "randomOrNull", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "randomOrNull", "(ULongArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "randomOrNull", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "randomOrNull", "(UShortArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduce", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduce", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduce", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduce", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceIndexed", "(UByteArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceIndexed", "(UIntArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceIndexed", "(ULongArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceIndexed", "(UShortArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceIndexedOrNull", "(UByteArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceIndexedOrNull", "(UIntArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceIndexedOrNull", "(ULongArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceIndexedOrNull", "(UShortArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceOrNull", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceOrNull", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceOrNull", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceOrNull", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRight", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRight", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRight", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRight", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightIndexed", "(UByteArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightIndexed", "(UIntArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightIndexed", "(ULongArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightIndexed", "(UShortArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightIndexedOrNull", "(UByteArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightIndexedOrNull", "(UIntArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightIndexedOrNull", "(ULongArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightIndexedOrNull", "(UShortArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightOrNull", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightOrNull", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightOrNull", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightOrNull", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reverse", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "reverse", "(UByteArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "reverse", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "reverse", "(UIntArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "reverse", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "reverse", "(ULongArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "reverse", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "reverse", "(UShortArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "reversedArray", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "reversedArray", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "reversedArray", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "runningReduce", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "runningReduce", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "runningReduce", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "runningReduce", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "runningReduceIndexed", "(UByteArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "runningReduceIndexed", "(UIntArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "runningReduceIndexed", "(ULongArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "runningReduceIndexed", "(UShortArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "shuffle", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "shuffle", "(UByteArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "shuffle", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "shuffle", "(UIntArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "shuffle", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "shuffle", "(ULongArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "shuffle", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "shuffle", "(UShortArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "single", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "single", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "single", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "single", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "single", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "single", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "single", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "single", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "singleOrNull", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "singleOrNull", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "singleOrNull", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "singleOrNull", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "singleOrNull", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "singleOrNull", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "singleOrNull", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "singleOrNull", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "slice", "(UByteArray,IntRange)", "generated"] + - ["kotlin.collections", "UArraysKt", "slice", "(UByteArray,Iterable)", "generated"] + - ["kotlin.collections", "UArraysKt", "slice", "(UIntArray,IntRange)", "generated"] + - ["kotlin.collections", "UArraysKt", "slice", "(UIntArray,Iterable)", "generated"] + - ["kotlin.collections", "UArraysKt", "slice", "(ULongArray,IntRange)", "generated"] + - ["kotlin.collections", "UArraysKt", "slice", "(ULongArray,Iterable)", "generated"] + - ["kotlin.collections", "UArraysKt", "slice", "(UShortArray,IntRange)", "generated"] + - ["kotlin.collections", "UArraysKt", "slice", "(UShortArray,Iterable)", "generated"] + - ["kotlin.collections", "UArraysKt", "sliceArray", "(UByteArray,Collection)", "generated"] + - ["kotlin.collections", "UArraysKt", "sliceArray", "(UIntArray,Collection)", "generated"] + - ["kotlin.collections", "UArraysKt", "sliceArray", "(UIntArray,IntRange)", "generated"] + - ["kotlin.collections", "UArraysKt", "sliceArray", "(ULongArray,Collection)", "generated"] + - ["kotlin.collections", "UArraysKt", "sliceArray", "(ULongArray,IntRange)", "generated"] + - ["kotlin.collections", "UArraysKt", "sliceArray", "(UShortArray,Collection)", "generated"] + - ["kotlin.collections", "UArraysKt", "sliceArray", "(UShortArray,IntRange)", "generated"] + - ["kotlin.collections", "UArraysKt", "sort", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sort", "(UByteArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "sort", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sort", "(UIntArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "sort", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sort", "(ULongArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "sort", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sort", "(UShortArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortDescending", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortDescending", "(UByteArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortDescending", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortDescending", "(UIntArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortDescending", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortDescending", "(ULongArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortDescending", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortDescending", "(UShortArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "sorted", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sorted", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sorted", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sorted", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortedDescending", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortedDescending", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortedDescending", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sum", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sum", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sum", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sum", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumBy", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumBy", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumBy", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumBy", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumByDouble", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumByDouble", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumByDouble", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumByDouble", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfBigDecimal", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfBigDecimal", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfBigDecimal", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfBigDecimal", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfBigInteger", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfBigInteger", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfBigInteger", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfBigInteger", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfDouble", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfDouble", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfDouble", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfDouble", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfInt", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfInt", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfInt", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfInt", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfLong", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfLong", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfLong", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfLong", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfUByte", "(byte[])", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfUInt", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfUInt", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfUInt", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfUInt", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfUInt", "(int[])", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfULong", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfULong", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfULong", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfULong", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfULong", "(long[])", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfUShort", "(short[])", "generated"] + - ["kotlin.collections", "UArraysKt", "takeWhile", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "takeWhile", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "takeWhile", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "takeWhile", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "toIntArray", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "toLongArray", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "toShortArray", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "toTypedArray", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "toTypedArray", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "toTypedArray", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "toTypedArray", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "toUIntArray", "(int[])", "generated"] + - ["kotlin.collections", "UArraysKt", "toULongArray", "(long[])", "generated"] + - ["kotlin.collections", "UArraysKt", "toUShortArray", "(short[])", "generated"] + - ["kotlin.collections", "UArraysKt", "withIndex", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "withIndex", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "withIndex", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "withIndex", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UByteArray,Iterable)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UByteArray,Iterable,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UByteArray,Object[])", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UByteArray,Object[],Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UByteArray,UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UByteArray,UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UIntArray,Iterable)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UIntArray,Iterable,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UIntArray,Object[])", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UIntArray,Object[],Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UIntArray,UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UIntArray,UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(ULongArray,Iterable)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(ULongArray,Iterable,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(ULongArray,Object[])", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(ULongArray,Object[],Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(ULongArray,ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(ULongArray,ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UShortArray,Iterable)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UShortArray,Iterable,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UShortArray,Object[])", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UShortArray,Object[],Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UShortArray,UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UShortArray,UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UCollectionsKt", "sumOfUByte", "(Iterable)", "generated"] + - ["kotlin.collections", "UCollectionsKt", "sumOfUInt", "(Iterable)", "generated"] + - ["kotlin.collections", "UCollectionsKt", "sumOfULong", "(Iterable)", "generated"] + - ["kotlin.collections", "UCollectionsKt", "sumOfUShort", "(Iterable)", "generated"] + - ["kotlin.collections", "UCollectionsKt", "toUByteArray", "(Collection)", "generated"] + - ["kotlin.collections", "UCollectionsKt", "toUIntArray", "(Collection)", "generated"] + - ["kotlin.collections", "UCollectionsKt", "toULongArray", "(Collection)", "generated"] + - ["kotlin.collections", "UCollectionsKt", "toUShortArray", "(Collection)", "generated"] + - ["kotlin.collections.builders", "SerializedCollection$Companion", "getTagList", "()", "generated"] + - ["kotlin.collections.builders", "SerializedCollection$Companion", "getTagSet", "()", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareBy", "()", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareBy", "(Comparator,Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareBy", "(Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareByDescending", "(Comparator,Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareByDescending", "(Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareValues", "(Comparable,Comparable)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareValuesBy", "(Object,Object)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareValuesBy", "(Object,Object,Comparator,Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareValuesBy", "(Object,Object,Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(byte,byte)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(byte,byte,byte)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(byte,byte[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(double,double)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(double,double,double)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(double,double[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(float,float)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(float,float,float)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(float,float[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(int,int)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(int,int,int)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(int,int[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(long,long)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(long,long,long)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(long,long[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(short,short)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(short,short,short)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(short,short[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(byte,byte)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(byte,byte,byte)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(byte,byte[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(double,double)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(double,double,double)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(double,double[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(float,float)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(float,float,float)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(float,float[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(int,int)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(int,int,int)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(int,int[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(long,long)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(long,long,long)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(long,long[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(short,short)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(short,short,short)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(short,short[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "naturalOrder", "()", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "nullsFirst", "()", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "nullsFirst", "(Comparator)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "nullsLast", "()", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "nullsLast", "(Comparator)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "reverseOrder", "()", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "then", "(Comparator,Comparator)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "thenBy", "(Comparator,Comparator,Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "thenBy", "(Comparator,Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "thenByDescending", "(Comparator,Comparator,Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "thenByDescending", "(Comparator,Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "thenComparator", "(Comparator,Function2)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "thenDescending", "(Comparator,Comparator)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(byte,UByteArray)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(byte,byte)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(byte,byte,byte)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(int,UIntArray)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(int,int)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(int,int,int)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(long,ULongArray)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(long,long)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(long,long,long)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(short,UShortArray)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(short,short)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(short,short,short)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(byte,UByteArray)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(byte,byte)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(byte,byte,byte)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(int,UIntArray)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(int,int)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(int,int,int)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(long,ULongArray)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(long,long)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(long,long,long)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(short,UShortArray)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(short,short)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(short,short,short)", "generated"] + - ["kotlin.concurrent", "LocksKt", "read", "(ReentrantReadWriteLock,Function0)", "generated"] + - ["kotlin.concurrent", "LocksKt", "withLock", "(Lock,Function0)", "generated"] + - ["kotlin.concurrent", "LocksKt", "write", "(ReentrantReadWriteLock,Function0)", "generated"] + - ["kotlin.concurrent", "ThreadsKt", "getOrSet", "(ThreadLocal,Function0)", "generated"] + - ["kotlin.concurrent", "ThreadsKt", "thread", "(boolean,boolean,ClassLoader,String,int,Function0)", "generated"] + - ["kotlin.concurrent", "TimersKt", "fixedRateTimer", "(String,boolean,Date,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "fixedRateTimer", "(String,boolean,long,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "schedule", "(Timer,Date,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "schedule", "(Timer,Date,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "schedule", "(Timer,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "schedule", "(Timer,long,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "scheduleAtFixedRate", "(Timer,Date,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "scheduleAtFixedRate", "(Timer,long,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "timer", "(String,boolean,Date,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "timer", "(String,boolean,long,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "timerTask", "(Function1)", "generated"] + - ["kotlin.contracts", "ContractBuilder", "callsInPlace", "(Function,InvocationKind)", "generated"] + - ["kotlin.contracts", "ContractBuilder", "returns", "()", "generated"] + - ["kotlin.contracts", "ContractBuilder", "returns", "(Object)", "generated"] + - ["kotlin.contracts", "ContractBuilder", "returnsNotNull", "()", "generated"] + - ["kotlin.contracts", "ContractBuilderKt", "contract", "(Function1)", "generated"] + - ["kotlin.contracts", "ExperimentalContracts", "ExperimentalContracts", "()", "generated"] + - ["kotlin.contracts", "InvocationKind", "valueOf", "(String)", "generated"] + - ["kotlin.contracts", "InvocationKind", "values", "()", "generated"] + - ["kotlin.contracts", "SimpleEffect", "implies", "(boolean)", "generated"] + - ["kotlin.coroutines", "Continuation", "getContext", "()", "generated"] + - ["kotlin.coroutines", "Continuation", "resumeWith", "(Result)", "generated"] + - ["kotlin.coroutines", "ContinuationInterceptor", "interceptContinuation", "(Continuation)", "generated"] + - ["kotlin.coroutines", "ContinuationInterceptor", "releaseInterceptedContinuation", "(Continuation)", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "Continuation", "(CoroutineContext,Function1)", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "createCoroutine", "(SuspendFunction0,Continuation)", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "createCoroutine", "(SuspendFunction1,Object,Continuation)", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "getCoroutineContext", "()", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "resume", "(Continuation,Object)", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "resumeWithException", "(Continuation,Throwable)", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "startCoroutine", "(SuspendFunction0,Continuation)", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "startCoroutine", "(SuspendFunction1,Object,Continuation)", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "suspendCoroutine", "(Function1)", "generated"] + - ["kotlin.coroutines", "CoroutineContext", "fold", "(Object,Function2)", "generated"] + - ["kotlin.coroutines", "CoroutineContext", "get", "(Key)", "generated"] + - ["kotlin.coroutines", "CoroutineContext", "minusKey", "(Key)", "generated"] + - ["kotlin.coroutines", "CoroutineContext$Element", "getKey", "()", "generated"] + - ["kotlin.coroutines", "EmptyCoroutineContext", "hashCode", "()", "generated"] + - ["kotlin.coroutines", "EmptyCoroutineContext", "toString", "()", "generated"] + - ["kotlin.coroutines", "RestrictsSuspension", "RestrictsSuspension", "()", "generated"] + - ["kotlin.coroutines.cancellation", "CancellationException", "CancellationException", "()", "generated"] + - ["kotlin.coroutines.cancellation", "CancellationException", "CancellationException", "(String)", "generated"] + - ["kotlin.coroutines.cancellation", "CancellationExceptionHKt", "CancellationException", "(String,Throwable)", "generated"] + - ["kotlin.coroutines.cancellation", "CancellationExceptionHKt", "CancellationException", "(Throwable)", "generated"] + - ["kotlin.coroutines.cancellation", "CancellationExceptionKt", "CancellationException", "(String,Throwable)", "generated"] + - ["kotlin.coroutines.cancellation", "CancellationExceptionKt", "CancellationException", "(Throwable)", "generated"] + - ["kotlin.coroutines.intrinsics", "CoroutinesIntrinsicsHKt", "createCoroutineUnintercepted", "(SuspendFunction0,Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "CoroutinesIntrinsicsHKt", "createCoroutineUnintercepted", "(SuspendFunction1,Object,Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "CoroutinesIntrinsicsHKt", "intercepted", "(Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "CoroutinesIntrinsicsHKt", "startCoroutineUninterceptedOrReturn", "(SuspendFunction0,Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "CoroutinesIntrinsicsHKt", "startCoroutineUninterceptedOrReturn", "(SuspendFunction1,Object,Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "IntrinsicsKt", "createCoroutineUnintercepted", "(SuspendFunction0,Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "IntrinsicsKt", "createCoroutineUnintercepted", "(SuspendFunction1,Object,Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "IntrinsicsKt", "getCOROUTINE_SUSPENDED", "()", "generated"] + - ["kotlin.coroutines.intrinsics", "IntrinsicsKt", "startCoroutineUninterceptedOrReturn", "(SuspendFunction0,Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "IntrinsicsKt", "startCoroutineUninterceptedOrReturn", "(SuspendFunction1,Object,Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "IntrinsicsKt", "suspendCoroutineUninterceptedOrReturn", "(Function1)", "generated"] + - ["kotlin.coroutines.jvm.internal", "CoroutineStackFrame", "getCallerFrame", "()", "generated"] + - ["kotlin.coroutines.jvm.internal", "CoroutineStackFrame", "getStackTraceElement", "()", "generated"] + - ["kotlin.experimental", "BitwiseOperationsKt", "and", "(byte,byte)", "generated"] + - ["kotlin.experimental", "BitwiseOperationsKt", "and", "(short,short)", "generated"] + - ["kotlin.experimental", "BitwiseOperationsKt", "inv", "(byte)", "generated"] + - ["kotlin.experimental", "BitwiseOperationsKt", "inv", "(short)", "generated"] + - ["kotlin.experimental", "BitwiseOperationsKt", "or", "(byte,byte)", "generated"] + - ["kotlin.experimental", "BitwiseOperationsKt", "or", "(short,short)", "generated"] + - ["kotlin.experimental", "BitwiseOperationsKt", "xor", "(byte,byte)", "generated"] + - ["kotlin.experimental", "BitwiseOperationsKt", "xor", "(short,short)", "generated"] + - ["kotlin.experimental", "ExperimentalTypeInference", "ExperimentalTypeInference", "()", "generated"] + - ["kotlin.io", "ByteStreamsKt", "bufferedWriter", "(OutputStream,Charset)", "generated"] + - ["kotlin.io", "ByteStreamsKt", "iterator", "(BufferedInputStream)", "generated"] + - ["kotlin.io", "ByteStreamsKt", "writer", "(OutputStream,Charset)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(Object)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(boolean)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(byte)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(char)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(char[])", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(double)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(float)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(int)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(long)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(short)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "()", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(Object)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(boolean)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(byte)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(char)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(char[])", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(double)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(float)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(int)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(long)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(short)", "generated"] + - ["kotlin.io", "ConsoleKt", "readLine", "()", "generated"] + - ["kotlin.io", "ConsoleKt", "readln", "()", "generated"] + - ["kotlin.io", "ConsoleKt", "readlnOrNull", "()", "generated"] + - ["kotlin.io", "ConstantsKt", "getDEFAULT_BUFFER_SIZE", "()", "generated"] + - ["kotlin.io", "FileWalkDirection", "valueOf", "(String)", "generated"] + - ["kotlin.io", "FileWalkDirection", "values", "()", "generated"] + - ["kotlin.io", "FilesKt", "appendBytes", "(File,byte[])", "generated"] + - ["kotlin.io", "FilesKt", "appendText", "(File,String,Charset)", "generated"] + - ["kotlin.io", "FilesKt", "bufferedReader", "(File,Charset,int)", "generated"] + - ["kotlin.io", "FilesKt", "bufferedWriter", "(File,Charset,int)", "generated"] + - ["kotlin.io", "FilesKt", "copyRecursively", "(File,File,boolean,Function2)", "generated"] + - ["kotlin.io", "FilesKt", "createTempDir", "(String,String,File)", "generated"] + - ["kotlin.io", "FilesKt", "createTempFile", "(String,String,File)", "generated"] + - ["kotlin.io", "FilesKt", "deleteRecursively", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "endsWith", "(File,File)", "generated"] + - ["kotlin.io", "FilesKt", "endsWith", "(File,String)", "generated"] + - ["kotlin.io", "FilesKt", "forEachBlock", "(File,Function2)", "generated"] + - ["kotlin.io", "FilesKt", "forEachBlock", "(File,int,Function2)", "generated"] + - ["kotlin.io", "FilesKt", "forEachLine", "(File,Charset,Function1)", "generated"] + - ["kotlin.io", "FilesKt", "getExtension", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "getInvariantSeparatorsPath", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "getNameWithoutExtension", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "inputStream", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "isRooted", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "normalize", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "outputStream", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "printWriter", "(File,Charset)", "generated"] + - ["kotlin.io", "FilesKt", "readBytes", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "readLines", "(File,Charset)", "generated"] + - ["kotlin.io", "FilesKt", "readText", "(File,Charset)", "generated"] + - ["kotlin.io", "FilesKt", "reader", "(File,Charset)", "generated"] + - ["kotlin.io", "FilesKt", "relativeTo", "(File,File)", "generated"] + - ["kotlin.io", "FilesKt", "relativeToOrNull", "(File,File)", "generated"] + - ["kotlin.io", "FilesKt", "startsWith", "(File,File)", "generated"] + - ["kotlin.io", "FilesKt", "startsWith", "(File,String)", "generated"] + - ["kotlin.io", "FilesKt", "toRelativeString", "(File,File)", "generated"] + - ["kotlin.io", "FilesKt", "useLines", "(File,Charset,Function1)", "generated"] + - ["kotlin.io", "FilesKt", "writeBytes", "(File,byte[])", "generated"] + - ["kotlin.io", "FilesKt", "writeText", "(File,String,Charset)", "generated"] + - ["kotlin.io", "FilesKt", "writer", "(File,Charset)", "generated"] + - ["kotlin.io", "IoHKt", "print", "(Object)", "generated"] + - ["kotlin.io", "IoHKt", "println", "()", "generated"] + - ["kotlin.io", "IoHKt", "println", "(Object)", "generated"] + - ["kotlin.io", "IoHKt", "readln", "()", "generated"] + - ["kotlin.io", "IoHKt", "readlnOrNull", "()", "generated"] + - ["kotlin.io", "OnErrorAction", "valueOf", "(String)", "generated"] + - ["kotlin.io", "OnErrorAction", "values", "()", "generated"] + - ["kotlin.io", "TextStreamsKt", "readBytes", "(URL)", "generated"] + - ["kotlin.io", "TextStreamsKt", "readLines", "(Reader)", "generated"] + - ["kotlin.io", "TextStreamsKt", "readText", "(URL,Charset)", "generated"] + - ["kotlin.js", "ExperimentalJsExport", "ExperimentalJsExport", "()", "generated"] + - ["kotlin.js", "JsExport", "JsExport", "()", "generated"] + - ["kotlin.js", "JsName", "JsName", "(String)", "generated"] + - ["kotlin.js", "JsName", "name", "()", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "getAnnotationClass", "(Annotation)", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "getDeclaringJavaClass", "(Enum)", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "getJavaClass", "(KClass)", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "getJavaClass", "(Object)", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "getJavaObjectType", "(KClass)", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "getJavaPrimitiveType", "(KClass)", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "getKotlinClass", "(Class)", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "getRuntimeClassOfKClassInstance", "(KClass)", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "isArrayOf", "(Object[])", "generated"] + - ["kotlin.jvm", "JvmDefault", "JvmDefault", "()", "generated"] + - ["kotlin.jvm", "JvmDefaultWithCompatibility", "JvmDefaultWithCompatibility", "()", "generated"] + - ["kotlin.jvm", "JvmDefaultWithoutCompatibility", "JvmDefaultWithoutCompatibility", "()", "generated"] + - ["kotlin.jvm", "JvmField", "JvmField", "()", "generated"] + - ["kotlin.jvm", "JvmInline", "JvmInline", "()", "generated"] + - ["kotlin.jvm", "JvmMultifileClass", "JvmMultifileClass", "()", "generated"] + - ["kotlin.jvm", "JvmName", "JvmName", "(String)", "generated"] + - ["kotlin.jvm", "JvmName", "name", "()", "generated"] + - ["kotlin.jvm", "JvmOverloads", "JvmOverloads", "()", "generated"] + - ["kotlin.jvm", "JvmRecord", "JvmRecord", "()", "generated"] + - ["kotlin.jvm", "JvmStatic", "JvmStatic", "()", "generated"] + - ["kotlin.jvm", "JvmSuppressWildcards", "JvmSuppressWildcards", "(boolean)", "generated"] + - ["kotlin.jvm", "JvmSuppressWildcards", "suppress", "()", "generated"] + - ["kotlin.jvm", "JvmSynthetic", "JvmSynthetic", "()", "generated"] + - ["kotlin.jvm", "JvmWildcard", "JvmWildcard", "()", "generated"] + - ["kotlin.jvm", "KotlinReflectionNotSupportedError", "KotlinReflectionNotSupportedError", "()", "generated"] + - ["kotlin.jvm", "KotlinReflectionNotSupportedError", "KotlinReflectionNotSupportedError", "(String)", "generated"] + - ["kotlin.jvm", "KotlinReflectionNotSupportedError", "KotlinReflectionNotSupportedError", "(String,Throwable)", "generated"] + - ["kotlin.jvm", "KotlinReflectionNotSupportedError", "KotlinReflectionNotSupportedError", "(Throwable)", "generated"] + - ["kotlin.jvm", "PurelyImplements", "PurelyImplements", "(String)", "generated"] + - ["kotlin.jvm", "PurelyImplements", "value", "()", "generated"] + - ["kotlin.jvm", "Strictfp", "Strictfp", "()", "generated"] + - ["kotlin.jvm", "Synchronized", "Synchronized", "()", "generated"] + - ["kotlin.jvm", "Throws", "Throws", "(KClass[])", "generated"] + - ["kotlin.jvm", "Throws", "exceptionClasses", "()", "generated"] + - ["kotlin.jvm", "Transient", "Transient", "()", "generated"] + - ["kotlin.jvm", "Volatile", "Volatile", "()", "generated"] + - ["kotlin.jvm.functions", "Function0", "invoke", "()", "generated"] + - ["kotlin.jvm.functions", "Function1", "invoke", "(Object)", "generated"] + - ["kotlin.jvm.functions", "Function10", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function11", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function12", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function13", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function14", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function15", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function16", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function17", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function18", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function19", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function2", "invoke", "(Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function20", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function21", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function22", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function3", "invoke", "(Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function4", "invoke", "(Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function5", "invoke", "(Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function6", "invoke", "(Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function7", "invoke", "(Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function8", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function9", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "FunctionN", "invoke", "(Object[])", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", "equals", "(Object)", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", "getOwner", "()", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", "hashCode", "()", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorsKt", "iterator", "(boolean[])", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorsKt", "iterator", "(double[])", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorsKt", "iterator", "(float[])", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorsKt", "iterator", "(int[])", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorsKt", "iterator", "(long[])", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorsKt", "iterator", "(short[])", "generated"] + - ["kotlin.jvm.internal", "BooleanSpreadBuilder", "BooleanSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "BooleanSpreadBuilder", "add", "(boolean)", "generated"] + - ["kotlin.jvm.internal", "BooleanSpreadBuilder", "toArray", "()", "generated"] + - ["kotlin.jvm.internal", "ByteSpreadBuilder", "ByteSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "ByteSpreadBuilder", "add", "(byte)", "generated"] + - ["kotlin.jvm.internal", "CallableReference", "CallableReference", "()", "generated"] + - ["kotlin.jvm.internal", "CallableReference", "getOwner", "()", "generated"] + - ["kotlin.jvm.internal", "CharSpreadBuilder", "CharSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "CharSpreadBuilder", "add", "(char)", "generated"] + - ["kotlin.jvm.internal", "ClassBasedDeclarationContainer", "getJClass", "()", "generated"] + - ["kotlin.jvm.internal", "ClassReference", "ClassReference", "(Class)", "generated"] + - ["kotlin.jvm.internal", "ClassReference", "equals", "(Object)", "generated"] + - ["kotlin.jvm.internal", "ClassReference", "hashCode", "()", "generated"] + - ["kotlin.jvm.internal", "ClassReference", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "ClassReference$Companion", "isInstance", "(Object,Class)", "generated"] + - ["kotlin.jvm.internal", "DoubleSpreadBuilder", "DoubleSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "DoubleSpreadBuilder", "add", "(double)", "generated"] + - ["kotlin.jvm.internal", "DoubleSpreadBuilder", "toArray", "()", "generated"] + - ["kotlin.jvm.internal", "FloatSpreadBuilder", "FloatSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "FloatSpreadBuilder", "add", "(float)", "generated"] + - ["kotlin.jvm.internal", "FloatSpreadBuilder", "toArray", "()", "generated"] + - ["kotlin.jvm.internal", "FunInterfaceConstructorReference", "FunInterfaceConstructorReference", "(Class)", "generated"] + - ["kotlin.jvm.internal", "FunInterfaceConstructorReference", "equals", "(Object)", "generated"] + - ["kotlin.jvm.internal", "FunInterfaceConstructorReference", "hashCode", "()", "generated"] + - ["kotlin.jvm.internal", "FunInterfaceConstructorReference", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "FunctionAdapter", "getFunctionDelegate", "()", "generated"] + - ["kotlin.jvm.internal", "FunctionBase", "getArity", "()", "generated"] + - ["kotlin.jvm.internal", "FunctionImpl", "FunctionImpl", "()", "generated"] + - ["kotlin.jvm.internal", "FunctionImpl", "getArity", "()", "generated"] + - ["kotlin.jvm.internal", "FunctionImpl", "invokeVararg", "(Object[])", "generated"] + - ["kotlin.jvm.internal", "FunctionReference", "FunctionReference", "(int)", "generated"] + - ["kotlin.jvm.internal", "FunctionReference", "equals", "(Object)", "generated"] + - ["kotlin.jvm.internal", "FunctionReference", "hashCode", "()", "generated"] + - ["kotlin.jvm.internal", "InlineMarker", "InlineMarker", "()", "generated"] + - ["kotlin.jvm.internal", "InlineMarker", "afterInlineCall", "()", "generated"] + - ["kotlin.jvm.internal", "InlineMarker", "beforeInlineCall", "()", "generated"] + - ["kotlin.jvm.internal", "InlineMarker", "finallyEnd", "(int)", "generated"] + - ["kotlin.jvm.internal", "InlineMarker", "finallyStart", "(int)", "generated"] + - ["kotlin.jvm.internal", "InlineMarker", "mark", "(String)", "generated"] + - ["kotlin.jvm.internal", "InlineMarker", "mark", "(int)", "generated"] + - ["kotlin.jvm.internal", "IntSpreadBuilder", "IntSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "IntSpreadBuilder", "add", "(int)", "generated"] + - ["kotlin.jvm.internal", "IntSpreadBuilder", "toArray", "()", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "areEqual", "(Double,Double)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "areEqual", "(Double,double)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "areEqual", "(Float,Float)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "areEqual", "(Float,float)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "areEqual", "(Object,Object)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "areEqual", "(double,Double)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "areEqual", "(float,Float)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkExpressionValueIsNotNull", "(Object,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkFieldIsNotNull", "(Object,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkFieldIsNotNull", "(Object,String,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkHasClass", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkHasClass", "(String,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkNotNull", "(Object)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkNotNull", "(Object,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkNotNullExpressionValue", "(Object,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkNotNullParameter", "(Object,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkParameterIsNotNull", "(Object,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkReturnedValueIsNotNull", "(Object,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkReturnedValueIsNotNull", "(Object,String,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "compare", "(int,int)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "compare", "(long,long)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "needClassReification", "()", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "needClassReification", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "reifiedOperationMarker", "(int,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "reifiedOperationMarker", "(int,String,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwAssert", "()", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwAssert", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwIllegalArgument", "()", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwIllegalArgument", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwIllegalState", "()", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwIllegalState", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwJavaNpe", "()", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwJavaNpe", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwNpe", "()", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwNpe", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwUndefinedForReified", "()", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwUndefinedForReified", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwUninitializedProperty", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwUninitializedPropertyAccessException", "(String)", "generated"] + - ["kotlin.jvm.internal", "KTypeBase", "getJavaType", "()", "generated"] + - ["kotlin.jvm.internal", "Lambda", "Lambda", "(int)", "generated"] + - ["kotlin.jvm.internal", "Lambda", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "LocalVariableReference", "LocalVariableReference", "()", "generated"] + - ["kotlin.jvm.internal", "LongSpreadBuilder", "LongSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "LongSpreadBuilder", "add", "(long)", "generated"] + - ["kotlin.jvm.internal", "LongSpreadBuilder", "toArray", "()", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "MagicApiIntrinsics", "()", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "anyMagicApiCall", "(Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "anyMagicApiCall", "(int)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "anyMagicApiCall", "(int,Object,Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "anyMagicApiCall", "(int,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "anyMagicApiCall", "(int,long,Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "anyMagicApiCall", "(int,long,long,Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "intMagicApiCall", "(Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "intMagicApiCall", "(int)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "intMagicApiCall", "(int,Object,Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "intMagicApiCall", "(int,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "intMagicApiCall", "(int,long,Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "intMagicApiCall", "(int,long,long,Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "voidMagicApiCall", "(Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "voidMagicApiCall", "(int)", "generated"] + - ["kotlin.jvm.internal", "MutableLocalVariableReference", "MutableLocalVariableReference", "()", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference", "MutablePropertyReference", "()", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0", "MutablePropertyReference0", "()", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1", "MutablePropertyReference1", "()", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference2", "MutablePropertyReference2", "()", "generated"] + - ["kotlin.jvm.internal", "PackageReference", "equals", "(Object)", "generated"] + - ["kotlin.jvm.internal", "PackageReference", "hashCode", "()", "generated"] + - ["kotlin.jvm.internal", "PackageReference", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "PrimitiveSpreadBuilder", "PrimitiveSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "PropertyReference", "PropertyReference", "()", "generated"] + - ["kotlin.jvm.internal", "PropertyReference", "equals", "(Object)", "generated"] + - ["kotlin.jvm.internal", "PropertyReference", "hashCode", "()", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0", "PropertyReference0", "()", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1", "PropertyReference1", "()", "generated"] + - ["kotlin.jvm.internal", "PropertyReference2", "PropertyReference2", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$BooleanRef", "BooleanRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$BooleanRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$ByteRef", "ByteRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$ByteRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$CharRef", "CharRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$CharRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$DoubleRef", "DoubleRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$DoubleRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$FloatRef", "FloatRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$FloatRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$IntRef", "IntRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$IntRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$LongRef", "LongRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$LongRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$ObjectRef", "ObjectRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$ObjectRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$ShortRef", "ShortRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$ShortRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Reflection", "Reflection", "()", "generated"] + - ["kotlin.jvm.internal", "Reflection", "createKotlinClass", "(Class)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "createKotlinClass", "(Class,String)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "getOrCreateKotlinClass", "(Class)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "getOrCreateKotlinClass", "(Class,String)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "getOrCreateKotlinClasses", "(Class[])", "generated"] + - ["kotlin.jvm.internal", "Reflection", "getOrCreateKotlinPackage", "(Class)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "nullableTypeOf", "(Class)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "nullableTypeOf", "(Class,KTypeProjection[])", "generated"] + - ["kotlin.jvm.internal", "Reflection", "renderLambdaToString", "(FunctionBase)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "renderLambdaToString", "(Lambda)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "setUpperBounds", "(KTypeParameter,KType[])", "generated"] + - ["kotlin.jvm.internal", "Reflection", "typeOf", "(Class)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "typeOf", "(Class,KTypeProjection[])", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", "ReflectionFactory", "()", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", "createKotlinClass", "(Class)", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", "createKotlinClass", "(Class,String)", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", "getOrCreateKotlinClass", "(Class)", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", "getOrCreateKotlinClass", "(Class,String)", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", "renderLambdaToString", "(FunctionBase)", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", "renderLambdaToString", "(Lambda)", "generated"] + - ["kotlin.jvm.internal", "SerializedIr", "SerializedIr", "(String[])", "generated"] + - ["kotlin.jvm.internal", "SerializedIr", "b", "()", "generated"] + - ["kotlin.jvm.internal", "ShortSpreadBuilder", "ShortSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "ShortSpreadBuilder", "add", "(short)", "generated"] + - ["kotlin.jvm.internal", "ShortSpreadBuilder", "toArray", "()", "generated"] + - ["kotlin.jvm.internal", "SpreadBuilder", "SpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "SpreadBuilder", "size", "()", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "TypeIntrinsics", "()", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "getFunctionArity", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isFunctionOfArity", "(Object,int)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isMutableCollection", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isMutableIterable", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isMutableIterator", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isMutableList", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isMutableListIterator", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isMutableMap", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isMutableMapEntry", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isMutableSet", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "throwCce", "(ClassCastException)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "throwCce", "(Object,String)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "throwCce", "(String)", "generated"] + - ["kotlin.jvm.internal", "TypeParameterReference", "equals", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeParameterReference", "hashCode", "()", "generated"] + - ["kotlin.jvm.internal", "TypeParameterReference", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "TypeParameterReference$Companion", "toString", "(KTypeParameter)", "generated"] + - ["kotlin.jvm.internal", "TypeReference", "equals", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeReference", "hashCode", "()", "generated"] + - ["kotlin.math", "MathKt", "IEEErem", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "IEEErem", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "abs", "(double)", "generated"] + - ["kotlin.math", "MathKt", "abs", "(float)", "generated"] + - ["kotlin.math", "MathKt", "abs", "(int)", "generated"] + - ["kotlin.math", "MathKt", "abs", "(long)", "generated"] + - ["kotlin.math", "MathKt", "acos", "(double)", "generated"] + - ["kotlin.math", "MathKt", "acos", "(float)", "generated"] + - ["kotlin.math", "MathKt", "acosh", "(double)", "generated"] + - ["kotlin.math", "MathKt", "acosh", "(float)", "generated"] + - ["kotlin.math", "MathKt", "asin", "(double)", "generated"] + - ["kotlin.math", "MathKt", "asin", "(float)", "generated"] + - ["kotlin.math", "MathKt", "asinh", "(double)", "generated"] + - ["kotlin.math", "MathKt", "asinh", "(float)", "generated"] + - ["kotlin.math", "MathKt", "atan", "(double)", "generated"] + - ["kotlin.math", "MathKt", "atan", "(float)", "generated"] + - ["kotlin.math", "MathKt", "atan2", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "atan2", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "atanh", "(double)", "generated"] + - ["kotlin.math", "MathKt", "atanh", "(float)", "generated"] + - ["kotlin.math", "MathKt", "cbrt", "(double)", "generated"] + - ["kotlin.math", "MathKt", "cbrt", "(float)", "generated"] + - ["kotlin.math", "MathKt", "ceil", "(double)", "generated"] + - ["kotlin.math", "MathKt", "ceil", "(float)", "generated"] + - ["kotlin.math", "MathKt", "cos", "(double)", "generated"] + - ["kotlin.math", "MathKt", "cos", "(float)", "generated"] + - ["kotlin.math", "MathKt", "cosh", "(double)", "generated"] + - ["kotlin.math", "MathKt", "cosh", "(float)", "generated"] + - ["kotlin.math", "MathKt", "exp", "(double)", "generated"] + - ["kotlin.math", "MathKt", "exp", "(float)", "generated"] + - ["kotlin.math", "MathKt", "expm1", "(double)", "generated"] + - ["kotlin.math", "MathKt", "expm1", "(float)", "generated"] + - ["kotlin.math", "MathKt", "floor", "(double)", "generated"] + - ["kotlin.math", "MathKt", "floor", "(float)", "generated"] + - ["kotlin.math", "MathKt", "getAbsoluteValue", "(double)", "generated"] + - ["kotlin.math", "MathKt", "getAbsoluteValue", "(float)", "generated"] + - ["kotlin.math", "MathKt", "getAbsoluteValue", "(int)", "generated"] + - ["kotlin.math", "MathKt", "getAbsoluteValue", "(long)", "generated"] + - ["kotlin.math", "MathKt", "getE", "()", "generated"] + - ["kotlin.math", "MathKt", "getPI", "()", "generated"] + - ["kotlin.math", "MathKt", "getSign", "(double)", "generated"] + - ["kotlin.math", "MathKt", "getSign", "(float)", "generated"] + - ["kotlin.math", "MathKt", "getSign", "(int)", "generated"] + - ["kotlin.math", "MathKt", "getSign", "(long)", "generated"] + - ["kotlin.math", "MathKt", "getUlp", "(double)", "generated"] + - ["kotlin.math", "MathKt", "getUlp", "(float)", "generated"] + - ["kotlin.math", "MathKt", "hypot", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "hypot", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "ln", "(double)", "generated"] + - ["kotlin.math", "MathKt", "ln", "(float)", "generated"] + - ["kotlin.math", "MathKt", "ln1p", "(double)", "generated"] + - ["kotlin.math", "MathKt", "ln1p", "(float)", "generated"] + - ["kotlin.math", "MathKt", "log", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "log", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "log10", "(double)", "generated"] + - ["kotlin.math", "MathKt", "log10", "(float)", "generated"] + - ["kotlin.math", "MathKt", "log2", "(double)", "generated"] + - ["kotlin.math", "MathKt", "log2", "(float)", "generated"] + - ["kotlin.math", "MathKt", "max", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "max", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "max", "(int,int)", "generated"] + - ["kotlin.math", "MathKt", "max", "(long,long)", "generated"] + - ["kotlin.math", "MathKt", "min", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "min", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "min", "(int,int)", "generated"] + - ["kotlin.math", "MathKt", "min", "(long,long)", "generated"] + - ["kotlin.math", "MathKt", "nextDown", "(double)", "generated"] + - ["kotlin.math", "MathKt", "nextDown", "(float)", "generated"] + - ["kotlin.math", "MathKt", "nextTowards", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "nextTowards", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "nextUp", "(double)", "generated"] + - ["kotlin.math", "MathKt", "nextUp", "(float)", "generated"] + - ["kotlin.math", "MathKt", "pow", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "pow", "(double,int)", "generated"] + - ["kotlin.math", "MathKt", "pow", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "pow", "(float,int)", "generated"] + - ["kotlin.math", "MathKt", "round", "(double)", "generated"] + - ["kotlin.math", "MathKt", "round", "(float)", "generated"] + - ["kotlin.math", "MathKt", "roundToInt", "(double)", "generated"] + - ["kotlin.math", "MathKt", "roundToInt", "(float)", "generated"] + - ["kotlin.math", "MathKt", "roundToLong", "(double)", "generated"] + - ["kotlin.math", "MathKt", "roundToLong", "(float)", "generated"] + - ["kotlin.math", "MathKt", "sign", "(double)", "generated"] + - ["kotlin.math", "MathKt", "sign", "(float)", "generated"] + - ["kotlin.math", "MathKt", "sin", "(double)", "generated"] + - ["kotlin.math", "MathKt", "sin", "(float)", "generated"] + - ["kotlin.math", "MathKt", "sinh", "(double)", "generated"] + - ["kotlin.math", "MathKt", "sinh", "(float)", "generated"] + - ["kotlin.math", "MathKt", "sqrt", "(double)", "generated"] + - ["kotlin.math", "MathKt", "sqrt", "(float)", "generated"] + - ["kotlin.math", "MathKt", "tan", "(double)", "generated"] + - ["kotlin.math", "MathKt", "tan", "(float)", "generated"] + - ["kotlin.math", "MathKt", "tanh", "(double)", "generated"] + - ["kotlin.math", "MathKt", "tanh", "(float)", "generated"] + - ["kotlin.math", "MathKt", "truncate", "(double)", "generated"] + - ["kotlin.math", "MathKt", "truncate", "(float)", "generated"] + - ["kotlin.math", "MathKt", "withSign", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "withSign", "(double,int)", "generated"] + - ["kotlin.math", "MathKt", "withSign", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "withSign", "(float,int)", "generated"] + - ["kotlin.math", "UMathKt", "max", "(int,int)", "generated"] + - ["kotlin.math", "UMathKt", "max", "(long,long)", "generated"] + - ["kotlin.math", "UMathKt", "min", "(int,int)", "generated"] + - ["kotlin.math", "UMathKt", "min", "(long,long)", "generated"] + - ["kotlin.native", "CName", "CName", "(String,String)", "generated"] + - ["kotlin.native", "CName", "externName", "()", "generated"] + - ["kotlin.native", "CName", "shortName", "()", "generated"] + - ["kotlin.native.concurrent", "SharedImmutable", "SharedImmutable", "()", "generated"] + - ["kotlin.native.concurrent", "ThreadLocal", "ThreadLocal", "()", "generated"] + - ["kotlin.properties", "Delegates", "notNull", "()", "generated"] + - ["kotlin.properties", "Delegates", "observable", "(Object,Function3)", "generated"] + - ["kotlin.properties", "Delegates", "vetoable", "(Object,Function3)", "generated"] + - ["kotlin.properties", "PropertyDelegateProvider", "provideDelegate", "(Object,KProperty)", "generated"] + - ["kotlin.properties", "ReadOnlyProperty", "getValue", "(Object,KProperty)", "generated"] + - ["kotlin.properties", "ReadWriteProperty", "setValue", "(Object,KProperty,Object)", "generated"] + - ["kotlin.random", "Random", "Random", "()", "generated"] + - ["kotlin.random", "Random", "nextBits", "(int)", "generated"] + - ["kotlin.random", "Random", "nextBoolean", "()", "generated"] + - ["kotlin.random", "Random", "nextBytes", "(int)", "generated"] + - ["kotlin.random", "Random", "nextDouble", "()", "generated"] + - ["kotlin.random", "Random", "nextDouble", "(double)", "generated"] + - ["kotlin.random", "Random", "nextDouble", "(double,double)", "generated"] + - ["kotlin.random", "Random", "nextFloat", "()", "generated"] + - ["kotlin.random", "Random", "nextInt", "()", "generated"] + - ["kotlin.random", "Random", "nextInt", "(int)", "generated"] + - ["kotlin.random", "Random", "nextInt", "(int,int)", "generated"] + - ["kotlin.random", "Random", "nextLong", "()", "generated"] + - ["kotlin.random", "Random", "nextLong", "(long)", "generated"] + - ["kotlin.random", "Random", "nextLong", "(long,long)", "generated"] + - ["kotlin.random", "RandomKt", "Random", "(int)", "generated"] + - ["kotlin.random", "RandomKt", "Random", "(long)", "generated"] + - ["kotlin.random", "RandomKt", "nextInt", "(Random,IntRange)", "generated"] + - ["kotlin.random", "RandomKt", "nextLong", "(Random,LongRange)", "generated"] + - ["kotlin.random", "URandomKt", "nextUBytes", "(Random,int)", "generated"] + - ["kotlin.random", "URandomKt", "nextUInt", "(Random)", "generated"] + - ["kotlin.random", "URandomKt", "nextUInt", "(Random,UIntRange)", "generated"] + - ["kotlin.random", "URandomKt", "nextUInt", "(Random,int)", "generated"] + - ["kotlin.random", "URandomKt", "nextUInt", "(Random,int,int)", "generated"] + - ["kotlin.random", "URandomKt", "nextULong", "(Random)", "generated"] + - ["kotlin.random", "URandomKt", "nextULong", "(Random,ULongRange)", "generated"] + - ["kotlin.random", "URandomKt", "nextULong", "(Random,long)", "generated"] + - ["kotlin.random", "URandomKt", "nextULong", "(Random,long,long)", "generated"] + - ["kotlin.ranges", "CharProgression", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "CharProgression", "getFirst", "()", "generated"] + - ["kotlin.ranges", "CharProgression", "getLast", "()", "generated"] + - ["kotlin.ranges", "CharProgression", "getStep", "()", "generated"] + - ["kotlin.ranges", "CharProgression", "hashCode", "()", "generated"] + - ["kotlin.ranges", "CharProgression", "isEmpty", "()", "generated"] + - ["kotlin.ranges", "CharProgression", "toString", "()", "generated"] + - ["kotlin.ranges", "CharProgression$Companion", "fromClosedRange", "(char,char,int)", "generated"] + - ["kotlin.ranges", "CharRange", "CharRange", "(char,char)", "generated"] + - ["kotlin.ranges", "CharRange", "contains", "(char)", "generated"] + - ["kotlin.ranges", "CharRange", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "CharRange", "hashCode", "()", "generated"] + - ["kotlin.ranges", "CharRange", "toString", "()", "generated"] + - ["kotlin.ranges", "ClosedFloatingPointRange", "lessThanOrEquals", "(Comparable,Comparable)", "generated"] + - ["kotlin.ranges", "ClosedRange", "contains", "(Comparable)", "generated"] + - ["kotlin.ranges", "ClosedRange", "getEndInclusive", "()", "generated"] + - ["kotlin.ranges", "ClosedRange", "getStart", "()", "generated"] + - ["kotlin.ranges", "ClosedRange", "isEmpty", "()", "generated"] + - ["kotlin.ranges", "IntProgression", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "IntProgression", "getFirst", "()", "generated"] + - ["kotlin.ranges", "IntProgression", "getLast", "()", "generated"] + - ["kotlin.ranges", "IntProgression", "getStep", "()", "generated"] + - ["kotlin.ranges", "IntProgression", "hashCode", "()", "generated"] + - ["kotlin.ranges", "IntProgression", "isEmpty", "()", "generated"] + - ["kotlin.ranges", "IntProgression", "toString", "()", "generated"] + - ["kotlin.ranges", "IntProgression$Companion", "fromClosedRange", "(int,int,int)", "generated"] + - ["kotlin.ranges", "IntRange", "IntRange", "(int,int)", "generated"] + - ["kotlin.ranges", "IntRange", "contains", "(int)", "generated"] + - ["kotlin.ranges", "IntRange", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "IntRange", "hashCode", "()", "generated"] + - ["kotlin.ranges", "IntRange", "toString", "()", "generated"] + - ["kotlin.ranges", "LongProgression", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "LongProgression", "getFirst", "()", "generated"] + - ["kotlin.ranges", "LongProgression", "getLast", "()", "generated"] + - ["kotlin.ranges", "LongProgression", "getStep", "()", "generated"] + - ["kotlin.ranges", "LongProgression", "hashCode", "()", "generated"] + - ["kotlin.ranges", "LongProgression", "isEmpty", "()", "generated"] + - ["kotlin.ranges", "LongProgression", "toString", "()", "generated"] + - ["kotlin.ranges", "LongProgression$Companion", "fromClosedRange", "(long,long,long)", "generated"] + - ["kotlin.ranges", "LongRange", "LongRange", "(long,long)", "generated"] + - ["kotlin.ranges", "LongRange", "contains", "(long)", "generated"] + - ["kotlin.ranges", "LongRange", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "LongRange", "hashCode", "()", "generated"] + - ["kotlin.ranges", "LongRange", "toString", "()", "generated"] + - ["kotlin.ranges", "OpenEndRange", "contains", "(Comparable)", "generated"] + - ["kotlin.ranges", "OpenEndRange", "getEndExclusive", "()", "generated"] + - ["kotlin.ranges", "OpenEndRange", "getStart", "()", "generated"] + - ["kotlin.ranges", "OpenEndRange", "isEmpty", "()", "generated"] + - ["kotlin.ranges", "RangesKt", "byteRangeContains", "(ClosedRange,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "byteRangeContains", "(ClosedRange,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "byteRangeContains", "(ClosedRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "byteRangeContains", "(ClosedRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "byteRangeContains", "(ClosedRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "byteRangeContains", "(OpenEndRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "byteRangeContains", "(OpenEndRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "byteRangeContains", "(OpenEndRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtLeast", "(byte,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtLeast", "(double,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtLeast", "(float,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtLeast", "(int,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtLeast", "(long,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtLeast", "(short,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtMost", "(byte,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtMost", "(double,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtMost", "(float,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtMost", "(int,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtMost", "(long,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtMost", "(short,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceIn", "(byte,byte,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceIn", "(double,double,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceIn", "(float,float,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceIn", "(int,ClosedRange)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceIn", "(int,int,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceIn", "(long,ClosedRange)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceIn", "(long,long,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceIn", "(short,short,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(CharRange,Character)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(ClosedRange,Object)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(IntRange,Integer)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(IntRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(IntRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(IntRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(LongRange,Long)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(LongRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(LongRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(LongRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(OpenEndRange,Object)", "generated"] + - ["kotlin.ranges", "RangesKt", "doubleRangeContains", "(ClosedRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "doubleRangeContains", "(ClosedRange,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "doubleRangeContains", "(ClosedRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "doubleRangeContains", "(ClosedRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "doubleRangeContains", "(ClosedRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "doubleRangeContains", "(OpenEndRange,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(byte,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(byte,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(byte,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(byte,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(char,char)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(int,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(int,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(int,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(int,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(long,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(long,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(long,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(long,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(short,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(short,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(short,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(short,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "first", "(CharProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "first", "(IntProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "first", "(LongProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "firstOrNull", "(CharProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "firstOrNull", "(IntProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "firstOrNull", "(LongProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "floatRangeContains", "(ClosedRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "floatRangeContains", "(ClosedRange,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "floatRangeContains", "(ClosedRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "floatRangeContains", "(ClosedRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "floatRangeContains", "(ClosedRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "intRangeContains", "(ClosedRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "intRangeContains", "(ClosedRange,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "intRangeContains", "(ClosedRange,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "intRangeContains", "(ClosedRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "intRangeContains", "(ClosedRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "intRangeContains", "(OpenEndRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "intRangeContains", "(OpenEndRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "intRangeContains", "(OpenEndRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "last", "(CharProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "last", "(IntProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "last", "(LongProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "lastOrNull", "(CharProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "lastOrNull", "(IntProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "lastOrNull", "(LongProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "longRangeContains", "(ClosedRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "longRangeContains", "(ClosedRange,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "longRangeContains", "(ClosedRange,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "longRangeContains", "(ClosedRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "longRangeContains", "(ClosedRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "longRangeContains", "(OpenEndRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "longRangeContains", "(OpenEndRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "longRangeContains", "(OpenEndRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "random", "(CharRange)", "generated"] + - ["kotlin.ranges", "RangesKt", "random", "(CharRange,Random)", "generated"] + - ["kotlin.ranges", "RangesKt", "random", "(IntRange)", "generated"] + - ["kotlin.ranges", "RangesKt", "random", "(IntRange,Random)", "generated"] + - ["kotlin.ranges", "RangesKt", "random", "(LongRange)", "generated"] + - ["kotlin.ranges", "RangesKt", "random", "(LongRange,Random)", "generated"] + - ["kotlin.ranges", "RangesKt", "randomOrNull", "(CharRange)", "generated"] + - ["kotlin.ranges", "RangesKt", "randomOrNull", "(CharRange,Random)", "generated"] + - ["kotlin.ranges", "RangesKt", "randomOrNull", "(IntRange)", "generated"] + - ["kotlin.ranges", "RangesKt", "randomOrNull", "(IntRange,Random)", "generated"] + - ["kotlin.ranges", "RangesKt", "randomOrNull", "(LongRange)", "generated"] + - ["kotlin.ranges", "RangesKt", "randomOrNull", "(LongRange,Random)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeTo", "(double,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeTo", "(float,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(byte,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(byte,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(byte,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(byte,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(char,char)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(double,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(float,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(int,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(int,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(int,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(int,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(long,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(long,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(long,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(long,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(short,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(short,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(short,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(short,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "reversed", "(CharProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "reversed", "(IntProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "reversed", "(LongProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "shortRangeContains", "(ClosedRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "shortRangeContains", "(ClosedRange,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "shortRangeContains", "(ClosedRange,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "shortRangeContains", "(ClosedRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "shortRangeContains", "(ClosedRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "shortRangeContains", "(OpenEndRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "shortRangeContains", "(OpenEndRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "shortRangeContains", "(OpenEndRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "step", "(CharProgression,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "step", "(IntProgression,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "step", "(LongProgression,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(byte,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(byte,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(byte,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(byte,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(char,char)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(int,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(int,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(int,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(int,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(long,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(long,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(long,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(long,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(short,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(short,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(short,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(short,short)", "generated"] + - ["kotlin.ranges", "UIntProgression", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "UIntProgression", "getFirst", "()", "generated"] + - ["kotlin.ranges", "UIntProgression", "getLast", "()", "generated"] + - ["kotlin.ranges", "UIntProgression", "getStep", "()", "generated"] + - ["kotlin.ranges", "UIntProgression", "hashCode", "()", "generated"] + - ["kotlin.ranges", "UIntProgression", "isEmpty", "()", "generated"] + - ["kotlin.ranges", "UIntProgression", "toString", "()", "generated"] + - ["kotlin.ranges", "UIntProgression$Companion", "fromClosedRange", "(int,int,int)", "generated"] + - ["kotlin.ranges", "UIntRange", "UIntRange", "(int,int)", "generated"] + - ["kotlin.ranges", "UIntRange", "contains", "(int)", "generated"] + - ["kotlin.ranges", "UIntRange", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "UIntRange", "hashCode", "()", "generated"] + - ["kotlin.ranges", "UIntRange", "toString", "()", "generated"] + - ["kotlin.ranges", "ULongProgression", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "ULongProgression", "getFirst", "()", "generated"] + - ["kotlin.ranges", "ULongProgression", "getLast", "()", "generated"] + - ["kotlin.ranges", "ULongProgression", "getStep", "()", "generated"] + - ["kotlin.ranges", "ULongProgression", "hashCode", "()", "generated"] + - ["kotlin.ranges", "ULongProgression", "isEmpty", "()", "generated"] + - ["kotlin.ranges", "ULongProgression", "toString", "()", "generated"] + - ["kotlin.ranges", "ULongProgression$Companion", "fromClosedRange", "(long,long,long)", "generated"] + - ["kotlin.ranges", "ULongRange", "ULongRange", "(long,long)", "generated"] + - ["kotlin.ranges", "ULongRange", "contains", "(long)", "generated"] + - ["kotlin.ranges", "ULongRange", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "ULongRange", "hashCode", "()", "generated"] + - ["kotlin.ranges", "ULongRange", "toString", "()", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceAtLeast", "(byte,byte)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceAtLeast", "(int,int)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceAtLeast", "(long,long)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceAtLeast", "(short,short)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceAtMost", "(byte,byte)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceAtMost", "(int,int)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceAtMost", "(long,long)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceAtMost", "(short,short)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceIn", "(byte,byte,byte)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceIn", "(int,ClosedRange)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceIn", "(int,int,int)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceIn", "(long,ClosedRange)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceIn", "(long,long,long)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceIn", "(short,short,short)", "generated"] + - ["kotlin.ranges", "URangesKt", "contains", "(UIntRange,UInt)", "generated"] + - ["kotlin.ranges", "URangesKt", "contains", "(UIntRange,byte)", "generated"] + - ["kotlin.ranges", "URangesKt", "contains", "(UIntRange,long)", "generated"] + - ["kotlin.ranges", "URangesKt", "contains", "(UIntRange,short)", "generated"] + - ["kotlin.ranges", "URangesKt", "contains", "(ULongRange,ULong)", "generated"] + - ["kotlin.ranges", "URangesKt", "contains", "(ULongRange,byte)", "generated"] + - ["kotlin.ranges", "URangesKt", "contains", "(ULongRange,int)", "generated"] + - ["kotlin.ranges", "URangesKt", "contains", "(ULongRange,short)", "generated"] + - ["kotlin.ranges", "URangesKt", "downTo", "(byte,byte)", "generated"] + - ["kotlin.ranges", "URangesKt", "downTo", "(int,int)", "generated"] + - ["kotlin.ranges", "URangesKt", "downTo", "(long,long)", "generated"] + - ["kotlin.ranges", "URangesKt", "downTo", "(short,short)", "generated"] + - ["kotlin.ranges", "URangesKt", "first", "(UIntProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "first", "(ULongProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "firstOrNull", "(UIntProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "firstOrNull", "(ULongProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "last", "(UIntProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "last", "(ULongProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "lastOrNull", "(UIntProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "lastOrNull", "(ULongProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "random", "(UIntRange)", "generated"] + - ["kotlin.ranges", "URangesKt", "random", "(UIntRange,Random)", "generated"] + - ["kotlin.ranges", "URangesKt", "random", "(ULongRange)", "generated"] + - ["kotlin.ranges", "URangesKt", "random", "(ULongRange,Random)", "generated"] + - ["kotlin.ranges", "URangesKt", "randomOrNull", "(UIntRange)", "generated"] + - ["kotlin.ranges", "URangesKt", "randomOrNull", "(UIntRange,Random)", "generated"] + - ["kotlin.ranges", "URangesKt", "randomOrNull", "(ULongRange)", "generated"] + - ["kotlin.ranges", "URangesKt", "randomOrNull", "(ULongRange,Random)", "generated"] + - ["kotlin.ranges", "URangesKt", "rangeUntil", "(byte,byte)", "generated"] + - ["kotlin.ranges", "URangesKt", "rangeUntil", "(int,int)", "generated"] + - ["kotlin.ranges", "URangesKt", "rangeUntil", "(long,long)", "generated"] + - ["kotlin.ranges", "URangesKt", "rangeUntil", "(short,short)", "generated"] + - ["kotlin.ranges", "URangesKt", "reversed", "(UIntProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "reversed", "(ULongProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "step", "(UIntProgression,int)", "generated"] + - ["kotlin.ranges", "URangesKt", "step", "(ULongProgression,long)", "generated"] + - ["kotlin.ranges", "URangesKt", "until", "(byte,byte)", "generated"] + - ["kotlin.ranges", "URangesKt", "until", "(int,int)", "generated"] + - ["kotlin.ranges", "URangesKt", "until", "(long,long)", "generated"] + - ["kotlin.ranges", "URangesKt", "until", "(short,short)", "generated"] + - ["kotlin.reflect", "KAnnotatedElement", "getAnnotations", "()", "generated"] + - ["kotlin.reflect", "KCallable", "call", "(Object[])", "generated"] + - ["kotlin.reflect", "KCallable", "callBy", "(Map)", "generated"] + - ["kotlin.reflect", "KCallable", "getName", "()", "generated"] + - ["kotlin.reflect", "KCallable", "getParameters", "()", "generated"] + - ["kotlin.reflect", "KCallable", "getReturnType", "()", "generated"] + - ["kotlin.reflect", "KCallable", "getTypeParameters", "()", "generated"] + - ["kotlin.reflect", "KCallable", "getVisibility", "()", "generated"] + - ["kotlin.reflect", "KCallable", "isAbstract", "()", "generated"] + - ["kotlin.reflect", "KCallable", "isFinal", "()", "generated"] + - ["kotlin.reflect", "KCallable", "isOpen", "()", "generated"] + - ["kotlin.reflect", "KCallable", "isSuspend", "()", "generated"] + - ["kotlin.reflect", "KClass", "equals", "(Object)", "generated"] + - ["kotlin.reflect", "KClass", "getConstructors", "()", "generated"] + - ["kotlin.reflect", "KClass", "getNestedClasses", "()", "generated"] + - ["kotlin.reflect", "KClass", "getObjectInstance", "()", "generated"] + - ["kotlin.reflect", "KClass", "getQualifiedName", "()", "generated"] + - ["kotlin.reflect", "KClass", "getSealedSubclasses", "()", "generated"] + - ["kotlin.reflect", "KClass", "getSimpleName", "()", "generated"] + - ["kotlin.reflect", "KClass", "getSupertypes", "()", "generated"] + - ["kotlin.reflect", "KClass", "getTypeParameters", "()", "generated"] + - ["kotlin.reflect", "KClass", "getVisibility", "()", "generated"] + - ["kotlin.reflect", "KClass", "hashCode", "()", "generated"] + - ["kotlin.reflect", "KClass", "isAbstract", "()", "generated"] + - ["kotlin.reflect", "KClass", "isCompanion", "()", "generated"] + - ["kotlin.reflect", "KClass", "isData", "()", "generated"] + - ["kotlin.reflect", "KClass", "isFinal", "()", "generated"] + - ["kotlin.reflect", "KClass", "isFun", "()", "generated"] + - ["kotlin.reflect", "KClass", "isInner", "()", "generated"] + - ["kotlin.reflect", "KClass", "isInstance", "(Object)", "generated"] + - ["kotlin.reflect", "KClass", "isOpen", "()", "generated"] + - ["kotlin.reflect", "KClass", "isSealed", "()", "generated"] + - ["kotlin.reflect", "KClass", "isValue", "()", "generated"] + - ["kotlin.reflect", "KDeclarationContainer", "getMembers", "()", "generated"] + - ["kotlin.reflect", "KFunction", "isExternal", "()", "generated"] + - ["kotlin.reflect", "KFunction", "isInfix", "()", "generated"] + - ["kotlin.reflect", "KFunction", "isInline", "()", "generated"] + - ["kotlin.reflect", "KFunction", "isOperator", "()", "generated"] + - ["kotlin.reflect", "KMutableProperty", "getSetter", "()", "generated"] + - ["kotlin.reflect", "KMutableProperty0", "set", "(Object)", "generated"] + - ["kotlin.reflect", "KMutableProperty1", "set", "(Object,Object)", "generated"] + - ["kotlin.reflect", "KMutableProperty2", "set", "(Object,Object,Object)", "generated"] + - ["kotlin.reflect", "KParameter", "getIndex", "()", "generated"] + - ["kotlin.reflect", "KParameter", "getKind", "()", "generated"] + - ["kotlin.reflect", "KParameter", "getName", "()", "generated"] + - ["kotlin.reflect", "KParameter", "getType", "()", "generated"] + - ["kotlin.reflect", "KParameter", "isOptional", "()", "generated"] + - ["kotlin.reflect", "KParameter", "isVararg", "()", "generated"] + - ["kotlin.reflect", "KParameter$Kind", "valueOf", "(String)", "generated"] + - ["kotlin.reflect", "KParameter$Kind", "values", "()", "generated"] + - ["kotlin.reflect", "KProperty", "getGetter", "()", "generated"] + - ["kotlin.reflect", "KProperty", "isConst", "()", "generated"] + - ["kotlin.reflect", "KProperty", "isLateinit", "()", "generated"] + - ["kotlin.reflect", "KProperty$Accessor", "getProperty", "()", "generated"] + - ["kotlin.reflect", "KProperty0", "get", "()", "generated"] + - ["kotlin.reflect", "KProperty0", "getDelegate", "()", "generated"] + - ["kotlin.reflect", "KProperty1", "get", "(Object)", "generated"] + - ["kotlin.reflect", "KProperty1", "getDelegate", "(Object)", "generated"] + - ["kotlin.reflect", "KProperty2", "get", "(Object,Object)", "generated"] + - ["kotlin.reflect", "KProperty2", "getDelegate", "(Object,Object)", "generated"] + - ["kotlin.reflect", "KType", "getArguments", "()", "generated"] + - ["kotlin.reflect", "KType", "getClassifier", "()", "generated"] + - ["kotlin.reflect", "KType", "isMarkedNullable", "()", "generated"] + - ["kotlin.reflect", "KTypeParameter", "getName", "()", "generated"] + - ["kotlin.reflect", "KTypeParameter", "getUpperBounds", "()", "generated"] + - ["kotlin.reflect", "KTypeParameter", "getVariance", "()", "generated"] + - ["kotlin.reflect", "KTypeParameter", "isReified", "()", "generated"] + - ["kotlin.reflect", "KTypeProjection", "component1", "()", "generated"] + - ["kotlin.reflect", "KTypeProjection", "equals", "(Object)", "generated"] + - ["kotlin.reflect", "KTypeProjection", "getVariance", "()", "generated"] + - ["kotlin.reflect", "KTypeProjection", "hashCode", "()", "generated"] + - ["kotlin.reflect", "KTypeProjection$Companion", "getSTAR", "()", "generated"] + - ["kotlin.reflect", "KVariance", "valueOf", "(String)", "generated"] + - ["kotlin.reflect", "KVariance", "values", "()", "generated"] + - ["kotlin.reflect", "KVisibility", "valueOf", "(String)", "generated"] + - ["kotlin.reflect", "KVisibility", "values", "()", "generated"] + - ["kotlin.reflect", "TypeOfKt", "typeOf", "()", "generated"] + - ["kotlin.sequences", "Sequence", "iterator", "()", "generated"] + - ["kotlin.sequences", "SequenceScope", "yield", "(Object)", "generated"] + - ["kotlin.sequences", "SequenceScope", "yieldAll", "(Iterable)", "generated"] + - ["kotlin.sequences", "SequenceScope", "yieldAll", "(Iterator)", "generated"] + - ["kotlin.sequences", "SequencesKt", "Sequence", "(Function0)", "generated"] + - ["kotlin.sequences", "SequencesKt", "all", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "any", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "any", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "asIterable", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "asSequence", "(Enumeration)", "generated"] + - ["kotlin.sequences", "SequencesKt", "asSequence", "(Iterator)", "generated"] + - ["kotlin.sequences", "SequencesKt", "associate", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "associateBy", "(Sequence,Function1,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "averageOfByte", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "averageOfDouble", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "averageOfFloat", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "averageOfInt", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "averageOfLong", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "averageOfShort", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "chunked", "(Sequence,int)", "generated"] + - ["kotlin.sequences", "SequencesKt", "contains", "(Sequence,Object)", "generated"] + - ["kotlin.sequences", "SequencesKt", "count", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "count", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "emptySequence", "()", "generated"] + - ["kotlin.sequences", "SequencesKt", "filterIndexed", "(Sequence,Function2)", "generated"] + - ["kotlin.sequences", "SequencesKt", "flatMapIndexedIterable", "(Sequence,Function2)", "generated"] + - ["kotlin.sequences", "SequencesKt", "flatMapIndexedSequence", "(Sequence,Function2)", "generated"] + - ["kotlin.sequences", "SequencesKt", "forEach", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "forEachIndexed", "(Sequence,Function2)", "generated"] + - ["kotlin.sequences", "SequencesKt", "groupBy", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "groupBy", "(Sequence,Function1,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "groupingBy", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "ifEmpty", "(Sequence,Function0)", "generated"] + - ["kotlin.sequences", "SequencesKt", "indexOf", "(Sequence,Object)", "generated"] + - ["kotlin.sequences", "SequencesKt", "indexOfFirst", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "indexOfLast", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "iterator", "(SuspendFunction1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "lastIndexOf", "(Sequence,Object)", "generated"] + - ["kotlin.sequences", "SequencesKt", "max", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "maxOf", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "maxOfOrNull", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "maxOrNull", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "maxOrThrow", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "min", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "minOf", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "minOfOrNull", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "minOrNull", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "minOrThrow", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "minus", "(Sequence,Iterable)", "generated"] + - ["kotlin.sequences", "SequencesKt", "minus", "(Sequence,Object)", "generated"] + - ["kotlin.sequences", "SequencesKt", "minus", "(Sequence,Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "minusElement", "(Sequence,Object)", "generated"] + - ["kotlin.sequences", "SequencesKt", "none", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "none", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "plus", "(Sequence,Iterable)", "generated"] + - ["kotlin.sequences", "SequencesKt", "plus", "(Sequence,Object)", "generated"] + - ["kotlin.sequences", "SequencesKt", "plus", "(Sequence,Object[])", "generated"] + - ["kotlin.sequences", "SequencesKt", "plus", "(Sequence,Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "plusElement", "(Sequence,Object)", "generated"] + - ["kotlin.sequences", "SequencesKt", "runningFold", "(Sequence,Object,Function2)", "generated"] + - ["kotlin.sequences", "SequencesKt", "runningFoldIndexed", "(Sequence,Object,Function3)", "generated"] + - ["kotlin.sequences", "SequencesKt", "runningReduce", "(Sequence,Function2)", "generated"] + - ["kotlin.sequences", "SequencesKt", "runningReduceIndexed", "(Sequence,Function3)", "generated"] + - ["kotlin.sequences", "SequencesKt", "scan", "(Sequence,Object,Function2)", "generated"] + - ["kotlin.sequences", "SequencesKt", "scanIndexed", "(Sequence,Object,Function3)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sequence", "(SuspendFunction1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sequenceOf", "(Object[])", "generated"] + - ["kotlin.sequences", "SequencesKt", "shuffled", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "shuffled", "(Sequence,Random)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sorted", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sortedBy", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sortedByDescending", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sortedDescending", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sortedWith", "(Sequence,Comparator)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumBy", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumByDouble", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfBigDecimal", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfBigInteger", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfByte", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfDouble", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfDouble", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfFloat", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfInt", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfInt", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfLong", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfLong", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfShort", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfUInt", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfULong", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "windowed", "(Sequence,int,int,boolean)", "generated"] + - ["kotlin.sequences", "SequencesKt", "zipWithNext", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "zipWithNext", "(Sequence,Function2)", "generated"] + - ["kotlin.sequences", "USequencesKt", "sumOfUByte", "(Sequence)", "generated"] + - ["kotlin.sequences", "USequencesKt", "sumOfUInt", "(Sequence)", "generated"] + - ["kotlin.sequences", "USequencesKt", "sumOfULong", "(Sequence)", "generated"] + - ["kotlin.sequences", "USequencesKt", "sumOfUShort", "(Sequence)", "generated"] + - ["kotlin.system", "ProcessKt", "exitProcess", "(int)", "generated"] + - ["kotlin.system", "TimingKt", "measureNanoTime", "(Function0)", "generated"] + - ["kotlin.system", "TimingKt", "measureTimeMillis", "(Function0)", "generated"] + - ["kotlin.text", "Appendable", "append", "(CharSequence)", "generated"] + - ["kotlin.text", "Appendable", "append", "(CharSequence,int,int)", "generated"] + - ["kotlin.text", "Appendable", "append", "(char)", "generated"] + - ["kotlin.text", "CharCategory", "contains", "(char)", "generated"] + - ["kotlin.text", "CharCategory", "getCode", "()", "generated"] + - ["kotlin.text", "CharCategory", "getValue", "()", "generated"] + - ["kotlin.text", "CharCategory", "valueOf", "(String)", "generated"] + - ["kotlin.text", "CharCategory", "values", "()", "generated"] + - ["kotlin.text", "CharCategory$Companion", "valueOf", "(int)", "generated"] + - ["kotlin.text", "CharDirectionality", "getValue", "()", "generated"] + - ["kotlin.text", "CharDirectionality", "valueOf", "(String)", "generated"] + - ["kotlin.text", "CharDirectionality", "values", "()", "generated"] + - ["kotlin.text", "CharDirectionality$Companion", "valueOf", "(int)", "generated"] + - ["kotlin.text", "CharacterCodingException", "CharacterCodingException", "()", "generated"] + - ["kotlin.text", "CharsKt", "digitToChar", "(int)", "generated"] + - ["kotlin.text", "CharsKt", "digitToChar", "(int,int)", "generated"] + - ["kotlin.text", "CharsKt", "digitToInt", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "digitToInt", "(char,int)", "generated"] + - ["kotlin.text", "CharsKt", "digitToIntOrNull", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "digitToIntOrNull", "(char,int)", "generated"] + - ["kotlin.text", "CharsKt", "equals", "(char,char,boolean)", "generated"] + - ["kotlin.text", "CharsKt", "getCategory", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "getDirectionality", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isDefined", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isDigit", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isHighSurrogate", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isISOControl", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isIdentifierIgnorable", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isJavaIdentifierPart", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isJavaIdentifierStart", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isLetter", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isLetterOrDigit", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isLowSurrogate", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isLowerCase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isSurrogate", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isTitleCase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isUpperCase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isWhitespace", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "lowercase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "lowercase", "(char,Locale)", "generated"] + - ["kotlin.text", "CharsKt", "lowercaseChar", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "titlecase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "titlecase", "(char,Locale)", "generated"] + - ["kotlin.text", "CharsKt", "titlecaseChar", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "toLowerCase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "toTitleCase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "toUpperCase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "uppercase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "uppercase", "(char,Locale)", "generated"] + - ["kotlin.text", "CharsKt", "uppercaseChar", "(char)", "generated"] + - ["kotlin.text", "Charsets", "UTF32", "()", "generated"] + - ["kotlin.text", "Charsets", "UTF32_BE", "()", "generated"] + - ["kotlin.text", "Charsets", "UTF32_LE", "()", "generated"] + - ["kotlin.text", "Charsets", "getISO_8859_1", "()", "generated"] + - ["kotlin.text", "Charsets", "getUS_ASCII", "()", "generated"] + - ["kotlin.text", "Charsets", "getUTF_16", "()", "generated"] + - ["kotlin.text", "Charsets", "getUTF_16BE", "()", "generated"] + - ["kotlin.text", "Charsets", "getUTF_16LE", "()", "generated"] + - ["kotlin.text", "Charsets", "getUTF_8", "()", "generated"] + - ["kotlin.text", "CharsetsKt", "charset", "(String)", "generated"] + - ["kotlin.text", "FlagEnum", "getMask", "()", "generated"] + - ["kotlin.text", "FlagEnum", "getValue", "()", "generated"] + - ["kotlin.text", "MatchGroup", "equals", "(Object)", "generated"] + - ["kotlin.text", "MatchGroup", "hashCode", "()", "generated"] + - ["kotlin.text", "MatchGroupCollection", "get", "(int)", "generated"] + - ["kotlin.text", "MatchNamedGroupCollection", "get", "(String)", "generated"] + - ["kotlin.text", "MatchResult", "getGroupValues", "()", "generated"] + - ["kotlin.text", "MatchResult", "getGroups", "()", "generated"] + - ["kotlin.text", "MatchResult", "getRange", "()", "generated"] + - ["kotlin.text", "MatchResult", "getValue", "()", "generated"] + - ["kotlin.text", "MatchResult", "next", "()", "generated"] + - ["kotlin.text", "Regex", "Regex", "(String)", "generated"] + - ["kotlin.text", "Regex", "Regex", "(String,RegexOption)", "generated"] + - ["kotlin.text", "Regex", "Regex", "(String,Set)", "generated"] + - ["kotlin.text", "Regex", "containsMatchIn", "(CharSequence)", "generated"] + - ["kotlin.text", "Regex", "findAll", "(CharSequence,int)", "generated"] + - ["kotlin.text", "Regex", "getPattern", "()", "generated"] + - ["kotlin.text", "Regex", "matchAt", "(CharSequence,int)", "generated"] + - ["kotlin.text", "Regex", "matches", "(CharSequence)", "generated"] + - ["kotlin.text", "Regex", "matchesAt", "(CharSequence,int)", "generated"] + - ["kotlin.text", "Regex", "split", "(CharSequence,int)", "generated"] + - ["kotlin.text", "Regex", "splitToSequence", "(CharSequence,int)", "generated"] + - ["kotlin.text", "Regex", "toString", "()", "generated"] + - ["kotlin.text", "Regex$Companion", "escapeReplacement", "(String)", "generated"] + - ["kotlin.text", "Regex$Companion", "fromLiteral", "(String)", "generated"] + - ["kotlin.text", "RegexOption", "valueOf", "(String)", "generated"] + - ["kotlin.text", "RegexOption", "values", "()", "generated"] + - ["kotlin.text", "StringBuilder", "StringBuilder", "()", "generated"] + - ["kotlin.text", "StringBuilder", "StringBuilder", "(CharSequence)", "generated"] + - ["kotlin.text", "StringBuilder", "StringBuilder", "(String)", "generated"] + - ["kotlin.text", "StringBuilder", "StringBuilder", "(int)", "generated"] + - ["kotlin.text", "StringBuilder", "append", "(Object)", "generated"] + - ["kotlin.text", "StringBuilder", "append", "(String)", "generated"] + - ["kotlin.text", "StringBuilder", "append", "(boolean)", "generated"] + - ["kotlin.text", "StringBuilder", "append", "(char[])", "generated"] + - ["kotlin.text", "StringBuilder", "capacity", "()", "generated"] + - ["kotlin.text", "StringBuilder", "ensureCapacity", "(int)", "generated"] + - ["kotlin.text", "StringBuilder", "get", "(int)", "generated"] + - ["kotlin.text", "StringBuilder", "indexOf", "(String)", "generated"] + - ["kotlin.text", "StringBuilder", "indexOf", "(String,int)", "generated"] + - ["kotlin.text", "StringBuilder", "insert", "(int,CharSequence)", "generated"] + - ["kotlin.text", "StringBuilder", "insert", "(int,Object)", "generated"] + - ["kotlin.text", "StringBuilder", "insert", "(int,String)", "generated"] + - ["kotlin.text", "StringBuilder", "insert", "(int,boolean)", "generated"] + - ["kotlin.text", "StringBuilder", "insert", "(int,char)", "generated"] + - ["kotlin.text", "StringBuilder", "insert", "(int,char[])", "generated"] + - ["kotlin.text", "StringBuilder", "lastIndexOf", "(String)", "generated"] + - ["kotlin.text", "StringBuilder", "lastIndexOf", "(String,int)", "generated"] + - ["kotlin.text", "StringBuilder", "reverse", "()", "generated"] + - ["kotlin.text", "StringBuilder", "setLength", "(int)", "generated"] + - ["kotlin.text", "StringBuilder", "substring", "(int)", "generated"] + - ["kotlin.text", "StringBuilder", "substring", "(int,int)", "generated"] + - ["kotlin.text", "StringBuilder", "trimToSize", "()", "generated"] + - ["kotlin.text", "StringsKt", "String", "(int[],int,int)", "generated"] + - ["kotlin.text", "StringsKt", "all", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "any", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "any", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "asIterable", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "asSequence", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "associate", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "associateBy", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "associateBy", "(CharSequence,Function1,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "associateWith", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "buildString", "(Function1)", "generated"] + - ["kotlin.text", "StringsKt", "buildString", "(int,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "chunked", "(CharSequence,int)", "generated"] + - ["kotlin.text", "StringsKt", "chunked", "(CharSequence,int,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "chunkedSequence", "(CharSequence,int)", "generated"] + - ["kotlin.text", "StringsKt", "chunkedSequence", "(CharSequence,int,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "codePointAt", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "codePointBefore", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "codePointCount", "(String,int,int)", "generated"] + - ["kotlin.text", "StringsKt", "commonPrefixWith", "(CharSequence,CharSequence,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "commonSuffixWith", "(CharSequence,CharSequence,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "compareTo", "(String,String,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "contains", "(CharSequence,CharSequence,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "contains", "(CharSequence,Regex)", "generated"] + - ["kotlin.text", "StringsKt", "contains", "(CharSequence,char,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "contentEquals", "(CharSequence,CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "contentEquals", "(CharSequence,CharSequence,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "contentEquals", "(String,CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "contentEquals", "(String,StringBuffer)", "generated"] + - ["kotlin.text", "StringsKt", "count", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "count", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "deleteAt", "(StringBuilder,int)", "generated"] + - ["kotlin.text", "StringsKt", "deleteRange", "(StringBuilder,int,int)", "generated"] + - ["kotlin.text", "StringsKt", "elementAt", "(CharSequence,int)", "generated"] + - ["kotlin.text", "StringsKt", "elementAtOrElse", "(CharSequence,int,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "elementAtOrNull", "(CharSequence,int)", "generated"] + - ["kotlin.text", "StringsKt", "endsWith", "(CharSequence,CharSequence,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "endsWith", "(CharSequence,char,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "endsWith", "(String,String,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "equals", "(String,String,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "filter", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "filter", "(String,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "filterIndexed", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "filterIndexed", "(String,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "filterNot", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "filterNot", "(String,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "find", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "findLast", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "first", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "first", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "firstNotNullOf", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "firstNotNullOfOrNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "firstOrNull", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "firstOrNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "flatMap", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "flatMapIndexedIterable", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "forEach", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "forEachIndexed", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "getCASE_INSENSITIVE_ORDER", "(StringCompanionObject)", "generated"] + - ["kotlin.text", "StringsKt", "getIndices", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "getLastIndex", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "getOrElse", "(CharSequence,int,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "getOrNull", "(CharSequence,int)", "generated"] + - ["kotlin.text", "StringsKt", "groupBy", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "groupBy", "(CharSequence,Function1,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "groupingBy", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "hasSurrogatePairAt", "(CharSequence,int)", "generated"] + - ["kotlin.text", "StringsKt", "indexOf", "(CharSequence,String,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "indexOf", "(CharSequence,char,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "indexOfAny", "(CharSequence,Collection,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "indexOfAny", "(CharSequence,char[],int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "indexOfFirst", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "indexOfLast", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "isBlank", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "isEmpty", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "isNotBlank", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "isNotEmpty", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "isNullOrBlank", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "isNullOrEmpty", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "iterator", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "last", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "last", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "lastIndexOf", "(CharSequence,String,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "lastIndexOf", "(CharSequence,char,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "lastIndexOfAny", "(CharSequence,Collection,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "lastIndexOfAny", "(CharSequence,char[],int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "lastOrNull", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "lastOrNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "map", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "mapIndexed", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "mapIndexedNotNull", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "mapNotNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "matches", "(CharSequence,Regex)", "generated"] + - ["kotlin.text", "StringsKt", "max", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "maxBy", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "maxByOrNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "maxByOrThrow", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "maxOf", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "maxOfOrNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "maxOfWith", "(CharSequence,Comparator,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "maxOfWithOrNull", "(CharSequence,Comparator,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "maxOrNull", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "maxOrThrow", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "maxWith", "(CharSequence,Comparator)", "generated"] + - ["kotlin.text", "StringsKt", "maxWithOrNull", "(CharSequence,Comparator)", "generated"] + - ["kotlin.text", "StringsKt", "maxWithOrThrow", "(CharSequence,Comparator)", "generated"] + - ["kotlin.text", "StringsKt", "min", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "minBy", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "minByOrNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "minByOrThrow", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "minOf", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "minOfOrNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "minOfWith", "(CharSequence,Comparator,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "minOfWithOrNull", "(CharSequence,Comparator,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "minOrNull", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "minOrThrow", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "minWith", "(CharSequence,Comparator)", "generated"] + - ["kotlin.text", "StringsKt", "minWithOrNull", "(CharSequence,Comparator)", "generated"] + - ["kotlin.text", "StringsKt", "minWithOrThrow", "(CharSequence,Comparator)", "generated"] + - ["kotlin.text", "StringsKt", "none", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "none", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "offsetByCodePoints", "(String,int,int)", "generated"] + - ["kotlin.text", "StringsKt", "padEnd", "(String,int,char)", "generated"] + - ["kotlin.text", "StringsKt", "padStart", "(String,int,char)", "generated"] + - ["kotlin.text", "StringsKt", "partition", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "partition", "(String,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "random", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "random", "(CharSequence,Random)", "generated"] + - ["kotlin.text", "StringsKt", "randomOrNull", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "randomOrNull", "(CharSequence,Random)", "generated"] + - ["kotlin.text", "StringsKt", "reduce", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "reduceIndexed", "(CharSequence,Function3)", "generated"] + - ["kotlin.text", "StringsKt", "reduceIndexedOrNull", "(CharSequence,Function3)", "generated"] + - ["kotlin.text", "StringsKt", "reduceOrNull", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "reduceRight", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "reduceRightIndexed", "(CharSequence,Function3)", "generated"] + - ["kotlin.text", "StringsKt", "reduceRightIndexedOrNull", "(CharSequence,Function3)", "generated"] + - ["kotlin.text", "StringsKt", "reduceRightOrNull", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "regionMatches", "(CharSequence,int,CharSequence,int,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "regionMatches", "(String,int,String,int,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "removeRange", "(String,IntRange)", "generated"] + - ["kotlin.text", "StringsKt", "removeRange", "(String,int,int)", "generated"] + - ["kotlin.text", "StringsKt", "replace", "(String,String,String,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "replaceIndent", "(String,String)", "generated"] + - ["kotlin.text", "StringsKt", "replaceIndentByMargin", "(String,String,String)", "generated"] + - ["kotlin.text", "StringsKt", "replaceRange", "(String,IntRange,CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "replaceRange", "(String,int,int,CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "reversed", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "runningReduce", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "runningReduceIndexed", "(CharSequence,Function3)", "generated"] + - ["kotlin.text", "StringsKt", "set", "(StringBuilder,int,char)", "generated"] + - ["kotlin.text", "StringsKt", "single", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "single", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "singleOrNull", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "singleOrNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "slice", "(CharSequence,Iterable)", "generated"] + - ["kotlin.text", "StringsKt", "slice", "(String,Iterable)", "generated"] + - ["kotlin.text", "StringsKt", "split", "(CharSequence,Regex,int)", "generated"] + - ["kotlin.text", "StringsKt", "split", "(CharSequence,String[],boolean,int)", "generated"] + - ["kotlin.text", "StringsKt", "split", "(CharSequence,char[],boolean,int)", "generated"] + - ["kotlin.text", "StringsKt", "splitToSequence", "(CharSequence,Regex,int)", "generated"] + - ["kotlin.text", "StringsKt", "startsWith", "(CharSequence,CharSequence,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "startsWith", "(CharSequence,CharSequence,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "startsWith", "(CharSequence,char,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "startsWith", "(String,String,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "startsWith", "(String,String,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "substring", "(CharSequence,IntRange)", "generated"] + - ["kotlin.text", "StringsKt", "substring", "(CharSequence,int,int)", "generated"] + - ["kotlin.text", "StringsKt", "sumBy", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "sumByDouble", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "sumOfBigDecimal", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "sumOfBigInteger", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "sumOfDouble", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "sumOfInt", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "sumOfLong", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "sumOfUInt", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "sumOfULong", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "toBigDecimal", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toBigDecimal", "(String,MathContext)", "generated"] + - ["kotlin.text", "StringsKt", "toBigDecimalOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toBigDecimalOrNull", "(String,MathContext)", "generated"] + - ["kotlin.text", "StringsKt", "toBigInteger", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toBigInteger", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toBigIntegerOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toBigIntegerOrNull", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toBoolean", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toBooleanNullable", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toBooleanStrict", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toBooleanStrictOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toByte", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toByte", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toByteOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toByteOrNull", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toDouble", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toDoubleOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toFloat", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toFloatOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toHashSet", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "toInt", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toInt", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toIntOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toIntOrNull", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toList", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "toLong", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toLong", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toLongOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toLongOrNull", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toMutableList", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "toPattern", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toRegex", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toRegex", "(String,RegexOption)", "generated"] + - ["kotlin.text", "StringsKt", "toRegex", "(String,Set)", "generated"] + - ["kotlin.text", "StringsKt", "toSet", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "toShort", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toShort", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toShortOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toShortOrNull", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toSortedSet", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "toString", "(byte,int)", "generated"] + - ["kotlin.text", "StringsKt", "toString", "(int,int)", "generated"] + - ["kotlin.text", "StringsKt", "toString", "(long,int)", "generated"] + - ["kotlin.text", "StringsKt", "toString", "(short,int)", "generated"] + - ["kotlin.text", "StringsKt", "trim", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "trim", "(String,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "trim", "(String,char[])", "generated"] + - ["kotlin.text", "StringsKt", "trimEnd", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "trimEnd", "(String,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "trimEnd", "(String,char[])", "generated"] + - ["kotlin.text", "StringsKt", "trimIndent", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "trimMargin", "(String,String)", "generated"] + - ["kotlin.text", "StringsKt", "trimStart", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "trimStart", "(String,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "trimStart", "(String,char[])", "generated"] + - ["kotlin.text", "StringsKt", "windowed", "(CharSequence,int,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "windowed", "(CharSequence,int,int,boolean,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "windowedSequence", "(CharSequence,int,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "windowedSequence", "(CharSequence,int,int,boolean,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "withIndex", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "zip", "(CharSequence,CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "zip", "(CharSequence,CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "zipWithNext", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "zipWithNext", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "TextHKt", "String", "(char[])", "generated"] + - ["kotlin.text", "TextHKt", "String", "(char[],int,int)", "generated"] + - ["kotlin.text", "TextHKt", "compareTo", "(String,String,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "concatToString", "(char[])", "generated"] + - ["kotlin.text", "TextHKt", "concatToString", "(char[],int,int)", "generated"] + - ["kotlin.text", "TextHKt", "decodeToString", "(byte[])", "generated"] + - ["kotlin.text", "TextHKt", "decodeToString", "(byte[],int,int,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "encodeToByteArray", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "encodeToByteArray", "(String,int,int,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "endsWith", "(String,String,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "equals", "(String,String,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "getCASE_INSENSITIVE_ORDER", "(StringCompanionObject)", "generated"] + - ["kotlin.text", "TextHKt", "isBlank", "(CharSequence)", "generated"] + - ["kotlin.text", "TextHKt", "isHighSurrogate", "(char)", "generated"] + - ["kotlin.text", "TextHKt", "isLowSurrogate", "(char)", "generated"] + - ["kotlin.text", "TextHKt", "regionMatches", "(CharSequence,int,CharSequence,int,int,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "repeat", "(CharSequence,int)", "generated"] + - ["kotlin.text", "TextHKt", "replace", "(String,String,String,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "replace", "(String,char,char,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "replaceFirst", "(String,String,String,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "replaceFirst", "(String,char,char,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "startsWith", "(String,String,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "startsWith", "(String,String,int,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "substring", "(String,int)", "generated"] + - ["kotlin.text", "TextHKt", "substring", "(String,int,int)", "generated"] + - ["kotlin.text", "TextHKt", "toBoolean", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toByte", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toByte", "(String,int)", "generated"] + - ["kotlin.text", "TextHKt", "toCharArray", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toCharArray", "(String,int,int)", "generated"] + - ["kotlin.text", "TextHKt", "toDouble", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toDoubleOrNull", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toFloat", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toFloatOrNull", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toInt", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toInt", "(String,int)", "generated"] + - ["kotlin.text", "TextHKt", "toLong", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toLong", "(String,int)", "generated"] + - ["kotlin.text", "TextHKt", "toShort", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toShort", "(String,int)", "generated"] + - ["kotlin.text", "TextHKt", "toString", "(byte,int)", "generated"] + - ["kotlin.text", "TextHKt", "toString", "(int,int)", "generated"] + - ["kotlin.text", "TextHKt", "toString", "(long,int)", "generated"] + - ["kotlin.text", "TextHKt", "toString", "(short,int)", "generated"] + - ["kotlin.text", "Typography", "getAlmostEqual", "()", "generated"] + - ["kotlin.text", "Typography", "getAmp", "()", "generated"] + - ["kotlin.text", "Typography", "getBullet", "()", "generated"] + - ["kotlin.text", "Typography", "getCent", "()", "generated"] + - ["kotlin.text", "Typography", "getCopyright", "()", "generated"] + - ["kotlin.text", "Typography", "getDagger", "()", "generated"] + - ["kotlin.text", "Typography", "getDegree", "()", "generated"] + - ["kotlin.text", "Typography", "getDollar", "()", "generated"] + - ["kotlin.text", "Typography", "getDoubleDagger", "()", "generated"] + - ["kotlin.text", "Typography", "getDoublePrime", "()", "generated"] + - ["kotlin.text", "Typography", "getEllipsis", "()", "generated"] + - ["kotlin.text", "Typography", "getEuro", "()", "generated"] + - ["kotlin.text", "Typography", "getGreater", "()", "generated"] + - ["kotlin.text", "Typography", "getGreaterOrEqual", "()", "generated"] + - ["kotlin.text", "Typography", "getHalf", "()", "generated"] + - ["kotlin.text", "Typography", "getLeftDoubleQuote", "()", "generated"] + - ["kotlin.text", "Typography", "getLeftGuillemet", "()", "generated"] + - ["kotlin.text", "Typography", "getLeftGuillemete", "()", "generated"] + - ["kotlin.text", "Typography", "getLeftSingleQuote", "()", "generated"] + - ["kotlin.text", "Typography", "getLess", "()", "generated"] + - ["kotlin.text", "Typography", "getLessOrEqual", "()", "generated"] + - ["kotlin.text", "Typography", "getLowDoubleQuote", "()", "generated"] + - ["kotlin.text", "Typography", "getLowSingleQuote", "()", "generated"] + - ["kotlin.text", "Typography", "getMdash", "()", "generated"] + - ["kotlin.text", "Typography", "getMiddleDot", "()", "generated"] + - ["kotlin.text", "Typography", "getNbsp", "()", "generated"] + - ["kotlin.text", "Typography", "getNdash", "()", "generated"] + - ["kotlin.text", "Typography", "getNotEqual", "()", "generated"] + - ["kotlin.text", "Typography", "getParagraph", "()", "generated"] + - ["kotlin.text", "Typography", "getPlusMinus", "()", "generated"] + - ["kotlin.text", "Typography", "getPound", "()", "generated"] + - ["kotlin.text", "Typography", "getPrime", "()", "generated"] + - ["kotlin.text", "Typography", "getQuote", "()", "generated"] + - ["kotlin.text", "Typography", "getRegistered", "()", "generated"] + - ["kotlin.text", "Typography", "getRightDoubleQuote", "()", "generated"] + - ["kotlin.text", "Typography", "getRightGuillemet", "()", "generated"] + - ["kotlin.text", "Typography", "getRightGuillemete", "()", "generated"] + - ["kotlin.text", "Typography", "getRightSingleQuote", "()", "generated"] + - ["kotlin.text", "Typography", "getSection", "()", "generated"] + - ["kotlin.text", "Typography", "getTimes", "()", "generated"] + - ["kotlin.text", "Typography", "getTm", "()", "generated"] + - ["kotlin.text", "UStringsKt", "toString", "(byte,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toString", "(int,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toString", "(long,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toString", "(short,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toUByte", "(String)", "generated"] + - ["kotlin.text", "UStringsKt", "toUByte", "(String,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toUByteOrNull", "(String)", "generated"] + - ["kotlin.text", "UStringsKt", "toUByteOrNull", "(String,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toUInt", "(String)", "generated"] + - ["kotlin.text", "UStringsKt", "toUInt", "(String,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toUIntOrNull", "(String)", "generated"] + - ["kotlin.text", "UStringsKt", "toUIntOrNull", "(String,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toULong", "(String)", "generated"] + - ["kotlin.text", "UStringsKt", "toULong", "(String,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toULongOrNull", "(String)", "generated"] + - ["kotlin.text", "UStringsKt", "toULongOrNull", "(String,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toUShort", "(String)", "generated"] + - ["kotlin.text", "UStringsKt", "toUShort", "(String,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toUShortOrNull", "(String)", "generated"] + - ["kotlin.text", "UStringsKt", "toUShortOrNull", "(String,int)", "generated"] + - ["kotlin.time", "AbstractDoubleTimeSource", "AbstractDoubleTimeSource", "(DurationUnit)", "generated"] + - ["kotlin.time", "AbstractLongTimeSource", "AbstractLongTimeSource", "(DurationUnit)", "generated"] + - ["kotlin.time", "Duration", "div", "(Duration)", "generated"] + - ["kotlin.time", "Duration", "equals", "(Object)", "generated"] + - ["kotlin.time", "Duration", "getInDays", "()", "generated"] + - ["kotlin.time", "Duration", "getInHours", "()", "generated"] + - ["kotlin.time", "Duration", "getInMicroseconds", "()", "generated"] + - ["kotlin.time", "Duration", "getInMilliseconds", "()", "generated"] + - ["kotlin.time", "Duration", "getInMinutes", "()", "generated"] + - ["kotlin.time", "Duration", "getInNanoseconds", "()", "generated"] + - ["kotlin.time", "Duration", "getInSeconds", "()", "generated"] + - ["kotlin.time", "Duration", "getInWholeDays", "()", "generated"] + - ["kotlin.time", "Duration", "getInWholeHours", "()", "generated"] + - ["kotlin.time", "Duration", "getInWholeMicroseconds", "()", "generated"] + - ["kotlin.time", "Duration", "getInWholeMilliseconds", "()", "generated"] + - ["kotlin.time", "Duration", "getInWholeMinutes", "()", "generated"] + - ["kotlin.time", "Duration", "getInWholeNanoseconds", "()", "generated"] + - ["kotlin.time", "Duration", "getInWholeSeconds", "()", "generated"] + - ["kotlin.time", "Duration", "hashCode", "()", "generated"] + - ["kotlin.time", "Duration", "isFinite", "()", "generated"] + - ["kotlin.time", "Duration", "isInfinite", "()", "generated"] + - ["kotlin.time", "Duration", "isNegative", "()", "generated"] + - ["kotlin.time", "Duration", "isPositive", "()", "generated"] + - ["kotlin.time", "Duration", "toComponents", "(Function2)", "generated"] + - ["kotlin.time", "Duration", "toComponents", "(Function3)", "generated"] + - ["kotlin.time", "Duration", "toComponents", "(Function4)", "generated"] + - ["kotlin.time", "Duration", "toComponents", "(Function5)", "generated"] + - ["kotlin.time", "Duration", "toDouble", "(DurationUnit)", "generated"] + - ["kotlin.time", "Duration", "toInt", "(DurationUnit)", "generated"] + - ["kotlin.time", "Duration", "toIsoString", "()", "generated"] + - ["kotlin.time", "Duration", "toLong", "(DurationUnit)", "generated"] + - ["kotlin.time", "Duration", "toLongMilliseconds", "()", "generated"] + - ["kotlin.time", "Duration", "toLongNanoseconds", "()", "generated"] + - ["kotlin.time", "Duration", "toString", "()", "generated"] + - ["kotlin.time", "Duration", "toString", "(DurationUnit,int)", "generated"] + - ["kotlin.time", "Duration", "unaryMinus", "()", "generated"] + - ["kotlin.time", "Duration$Companion", "convert", "(double,DurationUnit,DurationUnit)", "generated"] + - ["kotlin.time", "Duration$Companion", "days", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "days", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "days", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "getDays", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "getDays", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "getDays", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "getHours", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "getHours", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "getHours", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMicroseconds", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMicroseconds", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMicroseconds", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMilliseconds", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMilliseconds", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMilliseconds", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMinutes", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMinutes", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMinutes", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "getNanoseconds", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "getNanoseconds", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "getNanoseconds", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "getSeconds", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "getSeconds", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "getSeconds", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "hours", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "hours", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "hours", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "microseconds", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "microseconds", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "microseconds", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "milliseconds", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "milliseconds", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "milliseconds", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "minutes", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "minutes", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "minutes", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "nanoseconds", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "nanoseconds", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "nanoseconds", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "parse", "(String)", "generated"] + - ["kotlin.time", "Duration$Companion", "parseIsoString", "(String)", "generated"] + - ["kotlin.time", "Duration$Companion", "parseIsoStringOrNull", "(String)", "generated"] + - ["kotlin.time", "Duration$Companion", "parseOrNull", "(String)", "generated"] + - ["kotlin.time", "Duration$Companion", "seconds", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "seconds", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "seconds", "(long)", "generated"] + - ["kotlin.time", "DurationKt", "getDays", "(double)", "generated"] + - ["kotlin.time", "DurationKt", "getDays", "(int)", "generated"] + - ["kotlin.time", "DurationKt", "getDays", "(long)", "generated"] + - ["kotlin.time", "DurationKt", "getHours", "(double)", "generated"] + - ["kotlin.time", "DurationKt", "getHours", "(int)", "generated"] + - ["kotlin.time", "DurationKt", "getHours", "(long)", "generated"] + - ["kotlin.time", "DurationKt", "getMicroseconds", "(double)", "generated"] + - ["kotlin.time", "DurationKt", "getMicroseconds", "(int)", "generated"] + - ["kotlin.time", "DurationKt", "getMicroseconds", "(long)", "generated"] + - ["kotlin.time", "DurationKt", "getMilliseconds", "(double)", "generated"] + - ["kotlin.time", "DurationKt", "getMilliseconds", "(int)", "generated"] + - ["kotlin.time", "DurationKt", "getMilliseconds", "(long)", "generated"] + - ["kotlin.time", "DurationKt", "getMinutes", "(double)", "generated"] + - ["kotlin.time", "DurationKt", "getMinutes", "(int)", "generated"] + - ["kotlin.time", "DurationKt", "getMinutes", "(long)", "generated"] + - ["kotlin.time", "DurationKt", "getNanoseconds", "(double)", "generated"] + - ["kotlin.time", "DurationKt", "getNanoseconds", "(int)", "generated"] + - ["kotlin.time", "DurationKt", "getNanoseconds", "(long)", "generated"] + - ["kotlin.time", "DurationKt", "getSeconds", "(double)", "generated"] + - ["kotlin.time", "DurationKt", "getSeconds", "(int)", "generated"] + - ["kotlin.time", "DurationKt", "getSeconds", "(long)", "generated"] + - ["kotlin.time", "DurationKt", "toDuration", "(double,DurationUnit)", "generated"] + - ["kotlin.time", "DurationKt", "toDuration", "(int,DurationUnit)", "generated"] + - ["kotlin.time", "DurationKt", "toDuration", "(long,DurationUnit)", "generated"] + - ["kotlin.time", "DurationUnit", "valueOf", "(String)", "generated"] + - ["kotlin.time", "DurationUnit", "values", "()", "generated"] + - ["kotlin.time", "DurationUnitKt", "toDurationUnit", "(TimeUnit)", "generated"] + - ["kotlin.time", "DurationUnitKt", "toTimeUnit", "(DurationUnit)", "generated"] + - ["kotlin.time", "ExperimentalTime", "ExperimentalTime", "()", "generated"] + - ["kotlin.time", "MeasureTimeKt", "measureTime", "(Function0)", "generated"] + - ["kotlin.time", "MeasureTimeKt", "measureTime", "(Monotonic,Function0)", "generated"] + - ["kotlin.time", "MeasureTimeKt", "measureTime", "(TimeSource,Function0)", "generated"] + - ["kotlin.time", "MeasureTimeKt", "measureTimedValue", "(Function0)", "generated"] + - ["kotlin.time", "MeasureTimeKt", "measureTimedValue", "(Monotonic,Function0)", "generated"] + - ["kotlin.time", "MeasureTimeKt", "measureTimedValue", "(TimeSource,Function0)", "generated"] + - ["kotlin.time", "TestTimeSource", "TestTimeSource", "()", "generated"] + - ["kotlin.time", "TestTimeSource", "plusAssign", "(Duration)", "generated"] + - ["kotlin.time", "TimeMark", "elapsedNow", "()", "generated"] + - ["kotlin.time", "TimeMark", "hasNotPassedNow", "()", "generated"] + - ["kotlin.time", "TimeMark", "hasPassedNow", "()", "generated"] + - ["kotlin.time", "TimeMark", "minus", "(Duration)", "generated"] + - ["kotlin.time", "TimeMark", "plus", "(Duration)", "generated"] + - ["kotlin.time", "TimeSource", "markNow", "()", "generated"] + - ["kotlin.time", "TimeSource$Monotonic", "toString", "()", "generated"] + - ["kotlin.time", "TimeSource$Monotonic$ValueTimeMark", "equals", "(Object)", "generated"] + - ["kotlin.time", "TimeSource$Monotonic$ValueTimeMark", "hashCode", "()", "generated"] + - ["kotlin.time", "TimeSource$Monotonic$ValueTimeMark", "toString", "()", "generated"] + - ["kotlin.time", "TimeSourceKt", "compareTo", "(TimeMark,TimeMark)", "generated"] + - ["kotlin.time", "TimeSourceKt", "minus", "(TimeMark,TimeMark)", "generated"] + - ["kotlin.time", "TimedValue", "equals", "(Object)", "generated"] + - ["kotlin.time", "TimedValue", "hashCode", "()", "generated"] + - ["kotlin", "ArithmeticException", "ArithmeticException", "()", "generated"] + - ["kotlin", "ArithmeticException", "ArithmeticException", "(String)", "generated"] + - ["kotlin", "ArrayIntrinsicsKt", "emptyArray", "()", "generated"] + - ["kotlin", "AssertionError", "AssertionError", "()", "generated"] + - ["kotlin", "AssertionError", "AssertionError", "(Object)", "generated"] + - ["kotlin", "BuilderInference", "BuilderInference", "()", "generated"] + - ["kotlin", "CharCodeJVMKt", "Char", "(short)", "generated"] + - ["kotlin", "CharCodeKt", "Char", "(int)", "generated"] + - ["kotlin", "CharCodeKt", "Char", "(short)", "generated"] + - ["kotlin", "CharCodeKt", "getCode", "(char)", "generated"] + - ["kotlin", "ClassCastException", "ClassCastException", "()", "generated"] + - ["kotlin", "ClassCastException", "ClassCastException", "(String)", "generated"] + - ["kotlin", "Comparator", "compare", "(Object,Object)", "generated"] + - ["kotlin", "CompareToKt", "compareTo", "(Comparable,Object)", "generated"] + - ["kotlin", "ConcurrentModificationException", "ConcurrentModificationException", "()", "generated"] + - ["kotlin", "ConcurrentModificationException", "ConcurrentModificationException", "(String)", "generated"] + - ["kotlin", "ConcurrentModificationException", "ConcurrentModificationException", "(String,Throwable)", "generated"] + - ["kotlin", "ConcurrentModificationException", "ConcurrentModificationException", "(Throwable)", "generated"] + - ["kotlin", "ContextFunctionTypeParams", "ContextFunctionTypeParams", "(int)", "generated"] + - ["kotlin", "ContextFunctionTypeParams", "count", "()", "generated"] + - ["kotlin", "DeepRecursiveKt", "invoke", "(DeepRecursiveFunction,Object)", "generated"] + - ["kotlin", "DeepRecursiveScope", "callRecursive", "(DeepRecursiveFunction,Object)", "generated"] + - ["kotlin", "DeepRecursiveScope", "callRecursive", "(Object)", "generated"] + - ["kotlin", "DeepRecursiveScope", "invoke", "(DeepRecursiveFunction,Object)", "generated"] + - ["kotlin", "Deprecated", "Deprecated", "(String,ReplaceWith,DeprecationLevel)", "generated"] + - ["kotlin", "Deprecated", "level", "()", "generated"] + - ["kotlin", "Deprecated", "message", "()", "generated"] + - ["kotlin", "Deprecated", "replaceWith", "()", "generated"] + - ["kotlin", "DeprecatedSinceKotlin", "DeprecatedSinceKotlin", "(String,String,String)", "generated"] + - ["kotlin", "DeprecatedSinceKotlin", "errorSince", "()", "generated"] + - ["kotlin", "DeprecatedSinceKotlin", "hiddenSince", "()", "generated"] + - ["kotlin", "DeprecatedSinceKotlin", "warningSince", "()", "generated"] + - ["kotlin", "DeprecationLevel", "valueOf", "(String)", "generated"] + - ["kotlin", "DeprecationLevel", "values", "()", "generated"] + - ["kotlin", "DslMarker", "DslMarker", "()", "generated"] + - ["kotlin", "Error", "Error", "()", "generated"] + - ["kotlin", "Error", "Error", "(String)", "generated"] + - ["kotlin", "Error", "Error", "(String,Throwable)", "generated"] + - ["kotlin", "Error", "Error", "(Throwable)", "generated"] + - ["kotlin", "Exception", "Exception", "()", "generated"] + - ["kotlin", "Exception", "Exception", "(String)", "generated"] + - ["kotlin", "Exception", "Exception", "(String,Throwable)", "generated"] + - ["kotlin", "Exception", "Exception", "(Throwable)", "generated"] + - ["kotlin", "ExceptionsHKt", "addSuppressed", "(Throwable,Throwable)", "generated"] + - ["kotlin", "ExceptionsHKt", "getSuppressedExceptions", "(Throwable)", "generated"] + - ["kotlin", "ExceptionsHKt", "printStackTrace", "(Throwable)", "generated"] + - ["kotlin", "ExceptionsHKt", "stackTraceToString", "(Throwable)", "generated"] + - ["kotlin", "ExceptionsKt", "addSuppressed", "(Throwable,Throwable)", "generated"] + - ["kotlin", "ExceptionsKt", "getStackTrace", "(Throwable)", "generated"] + - ["kotlin", "ExceptionsKt", "getSuppressedExceptions", "(Throwable)", "generated"] + - ["kotlin", "ExceptionsKt", "printStackTrace", "(Throwable)", "generated"] + - ["kotlin", "ExceptionsKt", "printStackTrace", "(Throwable,PrintStream)", "generated"] + - ["kotlin", "ExceptionsKt", "printStackTrace", "(Throwable,PrintWriter)", "generated"] + - ["kotlin", "ExceptionsKt", "stackTraceToString", "(Throwable)", "generated"] + - ["kotlin", "Experimental", "Experimental", "(Level)", "generated"] + - ["kotlin", "Experimental", "level", "()", "generated"] + - ["kotlin", "Experimental$Level", "valueOf", "(String)", "generated"] + - ["kotlin", "Experimental$Level", "values", "()", "generated"] + - ["kotlin", "ExperimentalMultiplatform", "ExperimentalMultiplatform", "()", "generated"] + - ["kotlin", "ExperimentalStdlibApi", "ExperimentalStdlibApi", "()", "generated"] + - ["kotlin", "ExperimentalUnsignedTypes", "ExperimentalUnsignedTypes", "()", "generated"] + - ["kotlin", "ExtensionFunctionType", "ExtensionFunctionType", "()", "generated"] + - ["kotlin", "HashCodeKt", "hashCode", "(Object)", "generated"] + - ["kotlin", "IllegalArgumentException", "IllegalArgumentException", "()", "generated"] + - ["kotlin", "IllegalArgumentException", "IllegalArgumentException", "(String)", "generated"] + - ["kotlin", "IllegalArgumentException", "IllegalArgumentException", "(String,Throwable)", "generated"] + - ["kotlin", "IllegalArgumentException", "IllegalArgumentException", "(Throwable)", "generated"] + - ["kotlin", "IllegalStateException", "IllegalStateException", "()", "generated"] + - ["kotlin", "IllegalStateException", "IllegalStateException", "(String)", "generated"] + - ["kotlin", "IllegalStateException", "IllegalStateException", "(String,Throwable)", "generated"] + - ["kotlin", "IllegalStateException", "IllegalStateException", "(Throwable)", "generated"] + - ["kotlin", "IndexOutOfBoundsException", "IndexOutOfBoundsException", "()", "generated"] + - ["kotlin", "IndexOutOfBoundsException", "IndexOutOfBoundsException", "(String)", "generated"] + - ["kotlin", "KotlinHKt", "fromBits", "(DoubleCompanionObject,long)", "generated"] + - ["kotlin", "KotlinHKt", "fromBits", "(FloatCompanionObject,int)", "generated"] + - ["kotlin", "KotlinHKt", "isFinite", "(double)", "generated"] + - ["kotlin", "KotlinHKt", "isFinite", "(float)", "generated"] + - ["kotlin", "KotlinHKt", "isInfinite", "(double)", "generated"] + - ["kotlin", "KotlinHKt", "isInfinite", "(float)", "generated"] + - ["kotlin", "KotlinHKt", "isNaN", "(double)", "generated"] + - ["kotlin", "KotlinHKt", "isNaN", "(float)", "generated"] + - ["kotlin", "KotlinHKt", "lazy", "(Function0)", "generated"] + - ["kotlin", "KotlinHKt", "lazy", "(LazyThreadSafetyMode,Function0)", "generated"] + - ["kotlin", "KotlinHKt", "lazy", "(Object,Function0)", "generated"] + - ["kotlin", "KotlinHKt", "toBits", "(double)", "generated"] + - ["kotlin", "KotlinHKt", "toBits", "(float)", "generated"] + - ["kotlin", "KotlinHKt", "toRawBits", "(double)", "generated"] + - ["kotlin", "KotlinHKt", "toRawBits", "(float)", "generated"] + - ["kotlin", "KotlinNullPointerException", "KotlinNullPointerException", "()", "generated"] + - ["kotlin", "KotlinNullPointerException", "KotlinNullPointerException", "(String)", "generated"] + - ["kotlin", "KotlinVersion", "KotlinVersion", "(int,int)", "generated"] + - ["kotlin", "KotlinVersion", "KotlinVersion", "(int,int,int)", "generated"] + - ["kotlin", "KotlinVersion", "equals", "(Object)", "generated"] + - ["kotlin", "KotlinVersion", "getMajor", "()", "generated"] + - ["kotlin", "KotlinVersion", "getMinor", "()", "generated"] + - ["kotlin", "KotlinVersion", "getPatch", "()", "generated"] + - ["kotlin", "KotlinVersion", "hashCode", "()", "generated"] + - ["kotlin", "KotlinVersion", "isAtLeast", "(int,int)", "generated"] + - ["kotlin", "KotlinVersion", "isAtLeast", "(int,int,int)", "generated"] + - ["kotlin", "KotlinVersion", "toString", "()", "generated"] + - ["kotlin", "KotlinVersion$Companion", "getMAX_COMPONENT_VALUE", "()", "generated"] + - ["kotlin", "LateinitKt", "isInitialized", "(KProperty0)", "generated"] + - ["kotlin", "Lazy", "getValue", "()", "generated"] + - ["kotlin", "Lazy", "isInitialized", "()", "generated"] + - ["kotlin", "LazyThreadSafetyMode", "valueOf", "(String)", "generated"] + - ["kotlin", "LazyThreadSafetyMode", "values", "()", "generated"] + - ["kotlin", "Metadata", "Metadata", "(int,int[],int[],String[],String[],String,String,int)", "generated"] + - ["kotlin", "Metadata", "bv", "()", "generated"] + - ["kotlin", "Metadata", "d1", "()", "generated"] + - ["kotlin", "Metadata", "d2", "()", "generated"] + - ["kotlin", "Metadata", "k", "()", "generated"] + - ["kotlin", "Metadata", "mv", "()", "generated"] + - ["kotlin", "Metadata", "pn", "()", "generated"] + - ["kotlin", "Metadata", "xi", "()", "generated"] + - ["kotlin", "Metadata", "xs", "()", "generated"] + - ["kotlin", "NoSuchElementException", "NoSuchElementException", "()", "generated"] + - ["kotlin", "NoSuchElementException", "NoSuchElementException", "(String)", "generated"] + - ["kotlin", "NoWhenBranchMatchedException", "NoWhenBranchMatchedException", "()", "generated"] + - ["kotlin", "NoWhenBranchMatchedException", "NoWhenBranchMatchedException", "(String)", "generated"] + - ["kotlin", "NoWhenBranchMatchedException", "NoWhenBranchMatchedException", "(String,Throwable)", "generated"] + - ["kotlin", "NoWhenBranchMatchedException", "NoWhenBranchMatchedException", "(Throwable)", "generated"] + - ["kotlin", "NotImplementedError", "NotImplementedError", "(String)", "generated"] + - ["kotlin", "NullPointerException", "NullPointerException", "()", "generated"] + - ["kotlin", "NullPointerException", "NullPointerException", "(String)", "generated"] + - ["kotlin", "NumberFormatException", "NumberFormatException", "()", "generated"] + - ["kotlin", "NumberFormatException", "NumberFormatException", "(String)", "generated"] + - ["kotlin", "NumbersKt", "and", "(BigInteger,BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "countLeadingZeroBits", "(byte)", "generated"] + - ["kotlin", "NumbersKt", "countLeadingZeroBits", "(int)", "generated"] + - ["kotlin", "NumbersKt", "countLeadingZeroBits", "(long)", "generated"] + - ["kotlin", "NumbersKt", "countLeadingZeroBits", "(short)", "generated"] + - ["kotlin", "NumbersKt", "countOneBits", "(byte)", "generated"] + - ["kotlin", "NumbersKt", "countOneBits", "(int)", "generated"] + - ["kotlin", "NumbersKt", "countOneBits", "(long)", "generated"] + - ["kotlin", "NumbersKt", "countOneBits", "(short)", "generated"] + - ["kotlin", "NumbersKt", "countTrailingZeroBits", "(byte)", "generated"] + - ["kotlin", "NumbersKt", "countTrailingZeroBits", "(int)", "generated"] + - ["kotlin", "NumbersKt", "countTrailingZeroBits", "(long)", "generated"] + - ["kotlin", "NumbersKt", "countTrailingZeroBits", "(short)", "generated"] + - ["kotlin", "NumbersKt", "dec", "(BigDecimal)", "generated"] + - ["kotlin", "NumbersKt", "dec", "(BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "div", "(BigDecimal,BigDecimal)", "generated"] + - ["kotlin", "NumbersKt", "div", "(BigInteger,BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(byte,byte)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(byte,int)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(byte,long)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(byte,short)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(int,byte)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(int,int)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(int,long)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(int,short)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(long,byte)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(long,int)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(long,long)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(long,short)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(short,byte)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(short,int)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(short,long)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(short,short)", "generated"] + - ["kotlin", "NumbersKt", "fromBits", "(DoubleCompanionObject,long)", "generated"] + - ["kotlin", "NumbersKt", "fromBits", "(FloatCompanionObject,int)", "generated"] + - ["kotlin", "NumbersKt", "inc", "(BigDecimal)", "generated"] + - ["kotlin", "NumbersKt", "inc", "(BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "inv", "(BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "isFinite", "(double)", "generated"] + - ["kotlin", "NumbersKt", "isFinite", "(float)", "generated"] + - ["kotlin", "NumbersKt", "isInfinite", "(double)", "generated"] + - ["kotlin", "NumbersKt", "isInfinite", "(float)", "generated"] + - ["kotlin", "NumbersKt", "isNaN", "(double)", "generated"] + - ["kotlin", "NumbersKt", "isNaN", "(float)", "generated"] + - ["kotlin", "NumbersKt", "minus", "(BigDecimal,BigDecimal)", "generated"] + - ["kotlin", "NumbersKt", "minus", "(BigInteger,BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(byte,byte)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(byte,int)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(byte,long)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(byte,short)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(double,double)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(double,float)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(float,double)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(float,float)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(int,byte)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(int,int)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(int,long)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(int,short)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(long,byte)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(long,int)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(long,long)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(long,short)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(short,byte)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(short,int)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(short,long)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(short,short)", "generated"] + - ["kotlin", "NumbersKt", "or", "(BigInteger,BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "plus", "(BigDecimal,BigDecimal)", "generated"] + - ["kotlin", "NumbersKt", "plus", "(BigInteger,BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "rem", "(BigDecimal,BigDecimal)", "generated"] + - ["kotlin", "NumbersKt", "rem", "(BigInteger,BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "rotateLeft", "(byte,int)", "generated"] + - ["kotlin", "NumbersKt", "rotateLeft", "(int,int)", "generated"] + - ["kotlin", "NumbersKt", "rotateLeft", "(long,int)", "generated"] + - ["kotlin", "NumbersKt", "rotateLeft", "(short,int)", "generated"] + - ["kotlin", "NumbersKt", "rotateRight", "(byte,int)", "generated"] + - ["kotlin", "NumbersKt", "rotateRight", "(int,int)", "generated"] + - ["kotlin", "NumbersKt", "rotateRight", "(long,int)", "generated"] + - ["kotlin", "NumbersKt", "rotateRight", "(short,int)", "generated"] + - ["kotlin", "NumbersKt", "shl", "(BigInteger,int)", "generated"] + - ["kotlin", "NumbersKt", "shr", "(BigInteger,int)", "generated"] + - ["kotlin", "NumbersKt", "takeHighestOneBit", "(byte)", "generated"] + - ["kotlin", "NumbersKt", "takeHighestOneBit", "(int)", "generated"] + - ["kotlin", "NumbersKt", "takeHighestOneBit", "(long)", "generated"] + - ["kotlin", "NumbersKt", "takeHighestOneBit", "(short)", "generated"] + - ["kotlin", "NumbersKt", "takeLowestOneBit", "(byte)", "generated"] + - ["kotlin", "NumbersKt", "takeLowestOneBit", "(int)", "generated"] + - ["kotlin", "NumbersKt", "takeLowestOneBit", "(long)", "generated"] + - ["kotlin", "NumbersKt", "takeLowestOneBit", "(short)", "generated"] + - ["kotlin", "NumbersKt", "times", "(BigDecimal,BigDecimal)", "generated"] + - ["kotlin", "NumbersKt", "times", "(BigInteger,BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(BigInteger,int,MathContext)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(double)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(double,MathContext)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(float)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(float,MathContext)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(int)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(int,MathContext)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(long)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(long,MathContext)", "generated"] + - ["kotlin", "NumbersKt", "toBigInteger", "(int)", "generated"] + - ["kotlin", "NumbersKt", "toBigInteger", "(long)", "generated"] + - ["kotlin", "NumbersKt", "toBits", "(double)", "generated"] + - ["kotlin", "NumbersKt", "toBits", "(float)", "generated"] + - ["kotlin", "NumbersKt", "toRawBits", "(double)", "generated"] + - ["kotlin", "NumbersKt", "toRawBits", "(float)", "generated"] + - ["kotlin", "NumbersKt", "unaryMinus", "(BigDecimal)", "generated"] + - ["kotlin", "NumbersKt", "unaryMinus", "(BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "xor", "(BigInteger,BigInteger)", "generated"] + - ["kotlin", "OptIn", "OptIn", "(KClass[])", "generated"] + - ["kotlin", "OptIn", "markerClass", "()", "generated"] + - ["kotlin", "OptionalExpectation", "OptionalExpectation", "()", "generated"] + - ["kotlin", "OverloadResolutionByLambdaReturnType", "OverloadResolutionByLambdaReturnType", "()", "generated"] + - ["kotlin", "Pair", "equals", "(Object)", "generated"] + - ["kotlin", "Pair", "hashCode", "()", "generated"] + - ["kotlin", "ParameterName", "ParameterName", "(String)", "generated"] + - ["kotlin", "ParameterName", "name", "()", "generated"] + - ["kotlin", "PreconditionsKt", "assert", "(boolean)", "generated"] + - ["kotlin", "PreconditionsKt", "assert", "(boolean,Function0)", "generated"] + - ["kotlin", "PreconditionsKt", "check", "(boolean)", "generated"] + - ["kotlin", "PreconditionsKt", "check", "(boolean,Function0)", "generated"] + - ["kotlin", "PreconditionsKt", "error", "(Object)", "generated"] + - ["kotlin", "PreconditionsKt", "require", "(boolean)", "generated"] + - ["kotlin", "PreconditionsKt", "require", "(boolean,Function0)", "generated"] + - ["kotlin", "PropertyReferenceDelegatesKt", "getValue", "(KProperty0,Object,KProperty)", "generated"] + - ["kotlin", "PropertyReferenceDelegatesKt", "getValue", "(KProperty1,Object,KProperty)", "generated"] + - ["kotlin", "PropertyReferenceDelegatesKt", "setValue", "(KMutableProperty0,Object,KProperty,Object)", "generated"] + - ["kotlin", "PropertyReferenceDelegatesKt", "setValue", "(KMutableProperty1,Object,KProperty,Object)", "generated"] + - ["kotlin", "PublishedApi", "PublishedApi", "()", "generated"] + - ["kotlin", "ReplaceWith", "ReplaceWith", "(String,String[])", "generated"] + - ["kotlin", "ReplaceWith", "expression", "()", "generated"] + - ["kotlin", "ReplaceWith", "imports", "()", "generated"] + - ["kotlin", "RequiresOptIn", "RequiresOptIn", "(String,Level)", "generated"] + - ["kotlin", "RequiresOptIn", "level", "()", "generated"] + - ["kotlin", "RequiresOptIn", "message", "()", "generated"] + - ["kotlin", "RequiresOptIn$Level", "valueOf", "(String)", "generated"] + - ["kotlin", "RequiresOptIn$Level", "values", "()", "generated"] + - ["kotlin", "Result", "equals", "(Object)", "generated"] + - ["kotlin", "Result", "hashCode", "()", "generated"] + - ["kotlin", "Result", "isFailure", "()", "generated"] + - ["kotlin", "Result", "isSuccess", "()", "generated"] + - ["kotlin", "ResultKt", "runCatching", "(Function0)", "generated"] + - ["kotlin", "ResultKt", "runCatching", "(Object,Function1)", "generated"] + - ["kotlin", "RuntimeException", "RuntimeException", "()", "generated"] + - ["kotlin", "RuntimeException", "RuntimeException", "(String)", "generated"] + - ["kotlin", "RuntimeException", "RuntimeException", "(String,Throwable)", "generated"] + - ["kotlin", "RuntimeException", "RuntimeException", "(Throwable)", "generated"] + - ["kotlin", "SinceKotlin", "SinceKotlin", "(String)", "generated"] + - ["kotlin", "SinceKotlin", "version", "()", "generated"] + - ["kotlin", "StandardKt", "TODO", "()", "generated"] + - ["kotlin", "StandardKt", "TODO", "(String)", "generated"] + - ["kotlin", "StandardKt", "repeat", "(int,Function1)", "generated"] + - ["kotlin", "StandardKt", "run", "(Function0)", "generated"] + - ["kotlin", "StandardKt", "synchronized", "(Object,Function0)", "generated"] + - ["kotlin", "Suppress", "Suppress", "(String[])", "generated"] + - ["kotlin", "Suppress", "names", "()", "generated"] + - ["kotlin", "Throws", "Throws", "(KClass[])", "generated"] + - ["kotlin", "Throws", "exceptionClasses", "()", "generated"] + - ["kotlin", "Triple", "equals", "(Object)", "generated"] + - ["kotlin", "Triple", "hashCode", "()", "generated"] + - ["kotlin", "TypeCastException", "TypeCastException", "()", "generated"] + - ["kotlin", "TypeCastException", "TypeCastException", "(String)", "generated"] + - ["kotlin", "UByte", "and", "(byte)", "generated"] + - ["kotlin", "UByte", "compareTo", "(byte)", "generated"] + - ["kotlin", "UByte", "compareTo", "(int)", "generated"] + - ["kotlin", "UByte", "compareTo", "(long)", "generated"] + - ["kotlin", "UByte", "compareTo", "(short)", "generated"] + - ["kotlin", "UByte", "dec", "()", "generated"] + - ["kotlin", "UByte", "div", "(byte)", "generated"] + - ["kotlin", "UByte", "div", "(int)", "generated"] + - ["kotlin", "UByte", "div", "(long)", "generated"] + - ["kotlin", "UByte", "div", "(short)", "generated"] + - ["kotlin", "UByte", "equals", "(Object)", "generated"] + - ["kotlin", "UByte", "floorDiv", "(byte)", "generated"] + - ["kotlin", "UByte", "floorDiv", "(int)", "generated"] + - ["kotlin", "UByte", "floorDiv", "(long)", "generated"] + - ["kotlin", "UByte", "floorDiv", "(short)", "generated"] + - ["kotlin", "UByte", "hashCode", "()", "generated"] + - ["kotlin", "UByte", "inc", "()", "generated"] + - ["kotlin", "UByte", "inv", "()", "generated"] + - ["kotlin", "UByte", "minus", "(byte)", "generated"] + - ["kotlin", "UByte", "minus", "(int)", "generated"] + - ["kotlin", "UByte", "minus", "(long)", "generated"] + - ["kotlin", "UByte", "minus", "(short)", "generated"] + - ["kotlin", "UByte", "mod", "(byte)", "generated"] + - ["kotlin", "UByte", "mod", "(int)", "generated"] + - ["kotlin", "UByte", "mod", "(long)", "generated"] + - ["kotlin", "UByte", "mod", "(short)", "generated"] + - ["kotlin", "UByte", "or", "(byte)", "generated"] + - ["kotlin", "UByte", "plus", "(byte)", "generated"] + - ["kotlin", "UByte", "plus", "(int)", "generated"] + - ["kotlin", "UByte", "plus", "(long)", "generated"] + - ["kotlin", "UByte", "plus", "(short)", "generated"] + - ["kotlin", "UByte", "rangeTo", "(byte)", "generated"] + - ["kotlin", "UByte", "rem", "(byte)", "generated"] + - ["kotlin", "UByte", "rem", "(int)", "generated"] + - ["kotlin", "UByte", "rem", "(long)", "generated"] + - ["kotlin", "UByte", "rem", "(short)", "generated"] + - ["kotlin", "UByte", "times", "(byte)", "generated"] + - ["kotlin", "UByte", "times", "(int)", "generated"] + - ["kotlin", "UByte", "times", "(long)", "generated"] + - ["kotlin", "UByte", "times", "(short)", "generated"] + - ["kotlin", "UByte", "toByte", "()", "generated"] + - ["kotlin", "UByte", "toDouble", "()", "generated"] + - ["kotlin", "UByte", "toFloat", "()", "generated"] + - ["kotlin", "UByte", "toInt", "()", "generated"] + - ["kotlin", "UByte", "toLong", "()", "generated"] + - ["kotlin", "UByte", "toShort", "()", "generated"] + - ["kotlin", "UByte", "toString", "()", "generated"] + - ["kotlin", "UByte", "toUInt", "()", "generated"] + - ["kotlin", "UByte", "toULong", "()", "generated"] + - ["kotlin", "UByte", "toUShort", "()", "generated"] + - ["kotlin", "UByte", "xor", "(byte)", "generated"] + - ["kotlin", "UByte$Companion", "getMAX_VALUE", "()", "generated"] + - ["kotlin", "UByte$Companion", "getMIN_VALUE", "()", "generated"] + - ["kotlin", "UByte$Companion", "getSIZE_BITS", "()", "generated"] + - ["kotlin", "UByte$Companion", "getSIZE_BYTES", "()", "generated"] + - ["kotlin", "UByteArray", "UByteArray", "(int)", "generated"] + - ["kotlin", "UByteArray", "equals", "(Object)", "generated"] + - ["kotlin", "UByteArray", "get", "(int)", "generated"] + - ["kotlin", "UByteArray", "hashCode", "()", "generated"] + - ["kotlin", "UByteArray", "set", "(int,byte)", "generated"] + - ["kotlin", "UByteArray", "toString", "()", "generated"] + - ["kotlin", "UByteArrayKt", "UByteArray", "(int,Function1)", "generated"] + - ["kotlin", "UByteKt", "toUByte", "(byte)", "generated"] + - ["kotlin", "UByteKt", "toUByte", "(int)", "generated"] + - ["kotlin", "UByteKt", "toUByte", "(long)", "generated"] + - ["kotlin", "UByteKt", "toUByte", "(short)", "generated"] + - ["kotlin", "UInt", "and", "(int)", "generated"] + - ["kotlin", "UInt", "compareTo", "(byte)", "generated"] + - ["kotlin", "UInt", "compareTo", "(int)", "generated"] + - ["kotlin", "UInt", "compareTo", "(long)", "generated"] + - ["kotlin", "UInt", "compareTo", "(short)", "generated"] + - ["kotlin", "UInt", "dec", "()", "generated"] + - ["kotlin", "UInt", "div", "(byte)", "generated"] + - ["kotlin", "UInt", "div", "(int)", "generated"] + - ["kotlin", "UInt", "div", "(long)", "generated"] + - ["kotlin", "UInt", "div", "(short)", "generated"] + - ["kotlin", "UInt", "equals", "(Object)", "generated"] + - ["kotlin", "UInt", "floorDiv", "(byte)", "generated"] + - ["kotlin", "UInt", "floorDiv", "(int)", "generated"] + - ["kotlin", "UInt", "floorDiv", "(long)", "generated"] + - ["kotlin", "UInt", "floorDiv", "(short)", "generated"] + - ["kotlin", "UInt", "hashCode", "()", "generated"] + - ["kotlin", "UInt", "inc", "()", "generated"] + - ["kotlin", "UInt", "inv", "()", "generated"] + - ["kotlin", "UInt", "minus", "(byte)", "generated"] + - ["kotlin", "UInt", "minus", "(int)", "generated"] + - ["kotlin", "UInt", "minus", "(long)", "generated"] + - ["kotlin", "UInt", "minus", "(short)", "generated"] + - ["kotlin", "UInt", "mod", "(byte)", "generated"] + - ["kotlin", "UInt", "mod", "(int)", "generated"] + - ["kotlin", "UInt", "mod", "(long)", "generated"] + - ["kotlin", "UInt", "mod", "(short)", "generated"] + - ["kotlin", "UInt", "or", "(int)", "generated"] + - ["kotlin", "UInt", "plus", "(byte)", "generated"] + - ["kotlin", "UInt", "plus", "(int)", "generated"] + - ["kotlin", "UInt", "plus", "(long)", "generated"] + - ["kotlin", "UInt", "plus", "(short)", "generated"] + - ["kotlin", "UInt", "rangeTo", "(int)", "generated"] + - ["kotlin", "UInt", "rem", "(byte)", "generated"] + - ["kotlin", "UInt", "rem", "(int)", "generated"] + - ["kotlin", "UInt", "rem", "(long)", "generated"] + - ["kotlin", "UInt", "rem", "(short)", "generated"] + - ["kotlin", "UInt", "shl", "(int)", "generated"] + - ["kotlin", "UInt", "shr", "(int)", "generated"] + - ["kotlin", "UInt", "times", "(byte)", "generated"] + - ["kotlin", "UInt", "times", "(int)", "generated"] + - ["kotlin", "UInt", "times", "(long)", "generated"] + - ["kotlin", "UInt", "times", "(short)", "generated"] + - ["kotlin", "UInt", "toByte", "()", "generated"] + - ["kotlin", "UInt", "toDouble", "()", "generated"] + - ["kotlin", "UInt", "toFloat", "()", "generated"] + - ["kotlin", "UInt", "toInt", "()", "generated"] + - ["kotlin", "UInt", "toLong", "()", "generated"] + - ["kotlin", "UInt", "toShort", "()", "generated"] + - ["kotlin", "UInt", "toString", "()", "generated"] + - ["kotlin", "UInt", "toUByte", "()", "generated"] + - ["kotlin", "UInt", "toULong", "()", "generated"] + - ["kotlin", "UInt", "toUShort", "()", "generated"] + - ["kotlin", "UInt", "xor", "(int)", "generated"] + - ["kotlin", "UInt$Companion", "getMAX_VALUE", "()", "generated"] + - ["kotlin", "UInt$Companion", "getMIN_VALUE", "()", "generated"] + - ["kotlin", "UInt$Companion", "getSIZE_BITS", "()", "generated"] + - ["kotlin", "UInt$Companion", "getSIZE_BYTES", "()", "generated"] + - ["kotlin", "UIntArray", "UIntArray", "(int)", "generated"] + - ["kotlin", "UIntArray", "equals", "(Object)", "generated"] + - ["kotlin", "UIntArray", "get", "(int)", "generated"] + - ["kotlin", "UIntArray", "hashCode", "()", "generated"] + - ["kotlin", "UIntArray", "set", "(int,int)", "generated"] + - ["kotlin", "UIntArray", "toString", "()", "generated"] + - ["kotlin", "UIntArrayKt", "UIntArray", "(int,Function1)", "generated"] + - ["kotlin", "UIntKt", "toUInt", "(byte)", "generated"] + - ["kotlin", "UIntKt", "toUInt", "(double)", "generated"] + - ["kotlin", "UIntKt", "toUInt", "(float)", "generated"] + - ["kotlin", "UIntKt", "toUInt", "(int)", "generated"] + - ["kotlin", "UIntKt", "toUInt", "(long)", "generated"] + - ["kotlin", "UIntKt", "toUInt", "(short)", "generated"] + - ["kotlin", "ULong", "and", "(long)", "generated"] + - ["kotlin", "ULong", "compareTo", "(byte)", "generated"] + - ["kotlin", "ULong", "compareTo", "(int)", "generated"] + - ["kotlin", "ULong", "compareTo", "(long)", "generated"] + - ["kotlin", "ULong", "compareTo", "(short)", "generated"] + - ["kotlin", "ULong", "dec", "()", "generated"] + - ["kotlin", "ULong", "div", "(byte)", "generated"] + - ["kotlin", "ULong", "div", "(int)", "generated"] + - ["kotlin", "ULong", "div", "(long)", "generated"] + - ["kotlin", "ULong", "div", "(short)", "generated"] + - ["kotlin", "ULong", "equals", "(Object)", "generated"] + - ["kotlin", "ULong", "floorDiv", "(byte)", "generated"] + - ["kotlin", "ULong", "floorDiv", "(int)", "generated"] + - ["kotlin", "ULong", "floorDiv", "(long)", "generated"] + - ["kotlin", "ULong", "floorDiv", "(short)", "generated"] + - ["kotlin", "ULong", "hashCode", "()", "generated"] + - ["kotlin", "ULong", "inc", "()", "generated"] + - ["kotlin", "ULong", "inv", "()", "generated"] + - ["kotlin", "ULong", "minus", "(byte)", "generated"] + - ["kotlin", "ULong", "minus", "(int)", "generated"] + - ["kotlin", "ULong", "minus", "(long)", "generated"] + - ["kotlin", "ULong", "minus", "(short)", "generated"] + - ["kotlin", "ULong", "mod", "(byte)", "generated"] + - ["kotlin", "ULong", "mod", "(int)", "generated"] + - ["kotlin", "ULong", "mod", "(long)", "generated"] + - ["kotlin", "ULong", "mod", "(short)", "generated"] + - ["kotlin", "ULong", "or", "(long)", "generated"] + - ["kotlin", "ULong", "plus", "(byte)", "generated"] + - ["kotlin", "ULong", "plus", "(int)", "generated"] + - ["kotlin", "ULong", "plus", "(long)", "generated"] + - ["kotlin", "ULong", "plus", "(short)", "generated"] + - ["kotlin", "ULong", "rangeTo", "(long)", "generated"] + - ["kotlin", "ULong", "rem", "(byte)", "generated"] + - ["kotlin", "ULong", "rem", "(int)", "generated"] + - ["kotlin", "ULong", "rem", "(long)", "generated"] + - ["kotlin", "ULong", "rem", "(short)", "generated"] + - ["kotlin", "ULong", "shl", "(int)", "generated"] + - ["kotlin", "ULong", "shr", "(int)", "generated"] + - ["kotlin", "ULong", "times", "(byte)", "generated"] + - ["kotlin", "ULong", "times", "(int)", "generated"] + - ["kotlin", "ULong", "times", "(long)", "generated"] + - ["kotlin", "ULong", "times", "(short)", "generated"] + - ["kotlin", "ULong", "toByte", "()", "generated"] + - ["kotlin", "ULong", "toDouble", "()", "generated"] + - ["kotlin", "ULong", "toFloat", "()", "generated"] + - ["kotlin", "ULong", "toInt", "()", "generated"] + - ["kotlin", "ULong", "toLong", "()", "generated"] + - ["kotlin", "ULong", "toShort", "()", "generated"] + - ["kotlin", "ULong", "toString", "()", "generated"] + - ["kotlin", "ULong", "toUByte", "()", "generated"] + - ["kotlin", "ULong", "toUInt", "()", "generated"] + - ["kotlin", "ULong", "toUShort", "()", "generated"] + - ["kotlin", "ULong", "xor", "(long)", "generated"] + - ["kotlin", "ULong$Companion", "getMAX_VALUE", "()", "generated"] + - ["kotlin", "ULong$Companion", "getMIN_VALUE", "()", "generated"] + - ["kotlin", "ULong$Companion", "getSIZE_BITS", "()", "generated"] + - ["kotlin", "ULong$Companion", "getSIZE_BYTES", "()", "generated"] + - ["kotlin", "ULongArray", "ULongArray", "(int)", "generated"] + - ["kotlin", "ULongArray", "equals", "(Object)", "generated"] + - ["kotlin", "ULongArray", "get", "(int)", "generated"] + - ["kotlin", "ULongArray", "hashCode", "()", "generated"] + - ["kotlin", "ULongArray", "set", "(int,long)", "generated"] + - ["kotlin", "ULongArray", "toString", "()", "generated"] + - ["kotlin", "ULongArrayKt", "ULongArray", "(int,Function1)", "generated"] + - ["kotlin", "ULongKt", "toULong", "(byte)", "generated"] + - ["kotlin", "ULongKt", "toULong", "(double)", "generated"] + - ["kotlin", "ULongKt", "toULong", "(float)", "generated"] + - ["kotlin", "ULongKt", "toULong", "(int)", "generated"] + - ["kotlin", "ULongKt", "toULong", "(long)", "generated"] + - ["kotlin", "ULongKt", "toULong", "(short)", "generated"] + - ["kotlin", "UNumbersKt", "countLeadingZeroBits", "(byte)", "generated"] + - ["kotlin", "UNumbersKt", "countLeadingZeroBits", "(int)", "generated"] + - ["kotlin", "UNumbersKt", "countLeadingZeroBits", "(long)", "generated"] + - ["kotlin", "UNumbersKt", "countLeadingZeroBits", "(short)", "generated"] + - ["kotlin", "UNumbersKt", "countOneBits", "(byte)", "generated"] + - ["kotlin", "UNumbersKt", "countOneBits", "(int)", "generated"] + - ["kotlin", "UNumbersKt", "countOneBits", "(long)", "generated"] + - ["kotlin", "UNumbersKt", "countOneBits", "(short)", "generated"] + - ["kotlin", "UNumbersKt", "countTrailingZeroBits", "(byte)", "generated"] + - ["kotlin", "UNumbersKt", "countTrailingZeroBits", "(int)", "generated"] + - ["kotlin", "UNumbersKt", "countTrailingZeroBits", "(long)", "generated"] + - ["kotlin", "UNumbersKt", "countTrailingZeroBits", "(short)", "generated"] + - ["kotlin", "UNumbersKt", "rotateLeft", "(byte,int)", "generated"] + - ["kotlin", "UNumbersKt", "rotateLeft", "(int,int)", "generated"] + - ["kotlin", "UNumbersKt", "rotateLeft", "(long,int)", "generated"] + - ["kotlin", "UNumbersKt", "rotateLeft", "(short,int)", "generated"] + - ["kotlin", "UNumbersKt", "rotateRight", "(byte,int)", "generated"] + - ["kotlin", "UNumbersKt", "rotateRight", "(int,int)", "generated"] + - ["kotlin", "UNumbersKt", "rotateRight", "(long,int)", "generated"] + - ["kotlin", "UNumbersKt", "rotateRight", "(short,int)", "generated"] + - ["kotlin", "UNumbersKt", "takeHighestOneBit", "(byte)", "generated"] + - ["kotlin", "UNumbersKt", "takeHighestOneBit", "(int)", "generated"] + - ["kotlin", "UNumbersKt", "takeHighestOneBit", "(long)", "generated"] + - ["kotlin", "UNumbersKt", "takeHighestOneBit", "(short)", "generated"] + - ["kotlin", "UNumbersKt", "takeLowestOneBit", "(byte)", "generated"] + - ["kotlin", "UNumbersKt", "takeLowestOneBit", "(int)", "generated"] + - ["kotlin", "UNumbersKt", "takeLowestOneBit", "(long)", "generated"] + - ["kotlin", "UNumbersKt", "takeLowestOneBit", "(short)", "generated"] + - ["kotlin", "UShort", "and", "(short)", "generated"] + - ["kotlin", "UShort", "compareTo", "(byte)", "generated"] + - ["kotlin", "UShort", "compareTo", "(int)", "generated"] + - ["kotlin", "UShort", "compareTo", "(long)", "generated"] + - ["kotlin", "UShort", "compareTo", "(short)", "generated"] + - ["kotlin", "UShort", "dec", "()", "generated"] + - ["kotlin", "UShort", "div", "(byte)", "generated"] + - ["kotlin", "UShort", "div", "(int)", "generated"] + - ["kotlin", "UShort", "div", "(long)", "generated"] + - ["kotlin", "UShort", "div", "(short)", "generated"] + - ["kotlin", "UShort", "equals", "(Object)", "generated"] + - ["kotlin", "UShort", "floorDiv", "(byte)", "generated"] + - ["kotlin", "UShort", "floorDiv", "(int)", "generated"] + - ["kotlin", "UShort", "floorDiv", "(long)", "generated"] + - ["kotlin", "UShort", "floorDiv", "(short)", "generated"] + - ["kotlin", "UShort", "hashCode", "()", "generated"] + - ["kotlin", "UShort", "inc", "()", "generated"] + - ["kotlin", "UShort", "inv", "()", "generated"] + - ["kotlin", "UShort", "minus", "(byte)", "generated"] + - ["kotlin", "UShort", "minus", "(int)", "generated"] + - ["kotlin", "UShort", "minus", "(long)", "generated"] + - ["kotlin", "UShort", "minus", "(short)", "generated"] + - ["kotlin", "UShort", "mod", "(byte)", "generated"] + - ["kotlin", "UShort", "mod", "(int)", "generated"] + - ["kotlin", "UShort", "mod", "(long)", "generated"] + - ["kotlin", "UShort", "mod", "(short)", "generated"] + - ["kotlin", "UShort", "or", "(short)", "generated"] + - ["kotlin", "UShort", "plus", "(byte)", "generated"] + - ["kotlin", "UShort", "plus", "(int)", "generated"] + - ["kotlin", "UShort", "plus", "(long)", "generated"] + - ["kotlin", "UShort", "plus", "(short)", "generated"] + - ["kotlin", "UShort", "rangeTo", "(short)", "generated"] + - ["kotlin", "UShort", "rem", "(byte)", "generated"] + - ["kotlin", "UShort", "rem", "(int)", "generated"] + - ["kotlin", "UShort", "rem", "(long)", "generated"] + - ["kotlin", "UShort", "rem", "(short)", "generated"] + - ["kotlin", "UShort", "times", "(byte)", "generated"] + - ["kotlin", "UShort", "times", "(int)", "generated"] + - ["kotlin", "UShort", "times", "(long)", "generated"] + - ["kotlin", "UShort", "times", "(short)", "generated"] + - ["kotlin", "UShort", "toByte", "()", "generated"] + - ["kotlin", "UShort", "toDouble", "()", "generated"] + - ["kotlin", "UShort", "toFloat", "()", "generated"] + - ["kotlin", "UShort", "toInt", "()", "generated"] + - ["kotlin", "UShort", "toLong", "()", "generated"] + - ["kotlin", "UShort", "toShort", "()", "generated"] + - ["kotlin", "UShort", "toString", "()", "generated"] + - ["kotlin", "UShort", "toUByte", "()", "generated"] + - ["kotlin", "UShort", "toUInt", "()", "generated"] + - ["kotlin", "UShort", "toULong", "()", "generated"] + - ["kotlin", "UShort", "xor", "(short)", "generated"] + - ["kotlin", "UShort$Companion", "getMAX_VALUE", "()", "generated"] + - ["kotlin", "UShort$Companion", "getMIN_VALUE", "()", "generated"] + - ["kotlin", "UShort$Companion", "getSIZE_BITS", "()", "generated"] + - ["kotlin", "UShort$Companion", "getSIZE_BYTES", "()", "generated"] + - ["kotlin", "UShortArray", "UShortArray", "(int)", "generated"] + - ["kotlin", "UShortArray", "equals", "(Object)", "generated"] + - ["kotlin", "UShortArray", "get", "(int)", "generated"] + - ["kotlin", "UShortArray", "hashCode", "()", "generated"] + - ["kotlin", "UShortArray", "set", "(int,short)", "generated"] + - ["kotlin", "UShortArray", "toString", "()", "generated"] + - ["kotlin", "UShortArrayKt", "UShortArray", "(int,Function1)", "generated"] + - ["kotlin", "UShortKt", "toUShort", "(byte)", "generated"] + - ["kotlin", "UShortKt", "toUShort", "(int)", "generated"] + - ["kotlin", "UShortKt", "toUShort", "(long)", "generated"] + - ["kotlin", "UShortKt", "toUShort", "(short)", "generated"] + - ["kotlin", "UninitializedPropertyAccessException", "UninitializedPropertyAccessException", "()", "generated"] + - ["kotlin", "UninitializedPropertyAccessException", "UninitializedPropertyAccessException", "(String)", "generated"] + - ["kotlin", "UninitializedPropertyAccessException", "UninitializedPropertyAccessException", "(String,Throwable)", "generated"] + - ["kotlin", "UninitializedPropertyAccessException", "UninitializedPropertyAccessException", "(Throwable)", "generated"] + - ["kotlin", "Unit", "toString", "()", "generated"] + - ["kotlin", "UnsafeVariance", "UnsafeVariance", "()", "generated"] + - ["kotlin", "UnsupportedOperationException", "UnsupportedOperationException", "()", "generated"] + - ["kotlin", "UnsupportedOperationException", "UnsupportedOperationException", "(String)", "generated"] + - ["kotlin", "UnsupportedOperationException", "UnsupportedOperationException", "(String,Throwable)", "generated"] + - ["kotlin", "UnsupportedOperationException", "UnsupportedOperationException", "(Throwable)", "generated"] + - ["kotlin", "UseExperimental", "UseExperimental", "(KClass[])", "generated"] + - ["kotlin", "UseExperimental", "markerClass", "()", "generated"] From 42411fd455973950500ffa7f44a90658338b77f0 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 30 Nov 2022 15:11:13 +0100 Subject: [PATCH 780/796] Java/Kotlin: Allow dashes in callable names (the Kotlin standard library contains methods with dashes). --- java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 186c7ed168d..b7bb10fd6f8 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -555,7 +555,7 @@ module ModelValidation { not type.regexpMatch("[a-zA-Z0-9_\\$<>]+") and result = "Dubious type \"" + type + "\" in " + pred + " model." or - not name.regexpMatch("[a-zA-Z0-9_]*") and + not name.regexpMatch("[a-zA-Z0-9_\\-]*") and result = "Dubious name \"" + name + "\" in " + pred + " model." or not signature.regexpMatch("|\\([a-zA-Z0-9_\\.\\$<>,\\[\\]]*\\)") and From f5069ffc1ff22271d1d9a0225bd4fcb5c7c302c2 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 30 Nov 2022 15:27:16 +0100 Subject: [PATCH 781/796] Kotlin: Remove the inlined models. --- .../kotlin/NegativeStdLibGenerated.qll | 4407 ----------------- .../frameworks/kotlin/StdLibGenerated.qll | 1861 ------- 2 files changed, 6268 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/kotlin/NegativeStdLibGenerated.qll b/java/ql/lib/semmle/code/java/frameworks/kotlin/NegativeStdLibGenerated.qll index 412390f139e..9301e4f0c6f 100644 --- a/java/ql/lib/semmle/code/java/frameworks/kotlin/NegativeStdLibGenerated.qll +++ b/java/ql/lib/semmle/code/java/frameworks/kotlin/NegativeStdLibGenerated.qll @@ -5,4410 +5,3 @@ import java private import semmle.code.java.dataflow.ExternalFlow - -private class StdLibGeneratedNegativesummaryCsv extends NegativeSummaryModelCsv { - override predicate row(string row) { - row = - [ - "kotlin.annotation;AnnotationRetention;valueOf;(String);generated", - "kotlin.annotation;AnnotationRetention;values;();generated", - "kotlin.annotation;AnnotationTarget;valueOf;(String);generated", - "kotlin.annotation;AnnotationTarget;values;();generated", - "kotlin.annotation;MustBeDocumented;MustBeDocumented;();generated", - "kotlin.annotation;Repeatable;Repeatable;();generated", - "kotlin.annotation;Retention;Retention;(AnnotationRetention);generated", - "kotlin.annotation;Retention;value;();generated", - "kotlin.annotation;Target;Target;(AnnotationTarget[]);generated", - "kotlin.annotation;Target;allowedTargets;();generated", - "kotlin.collections.builders;SerializedCollection$Companion;getTagList;();generated", - "kotlin.collections.builders;SerializedCollection$Companion;getTagSet;();generated", - "kotlin.collections;AbstractIterator;AbstractIterator;();generated", - "kotlin.collections;AbstractList;equals;(Object);generated", - "kotlin.collections;AbstractList;hashCode;();generated", - "kotlin.collections;AbstractMap;equals;(Object);generated", - "kotlin.collections;AbstractMap;hashCode;();generated", - "kotlin.collections;AbstractMap;toString;();generated", - "kotlin.collections;AbstractSet;equals;(Object);generated", - "kotlin.collections;AbstractSet;hashCode;();generated", - "kotlin.collections;ArrayDeque;ArrayDeque;();generated", - "kotlin.collections;ArrayDeque;ArrayDeque;(int);generated", - "kotlin.collections;ArrayList;ArrayList;();generated", - "kotlin.collections;ArrayList;ArrayList;(Collection);generated", - "kotlin.collections;ArrayList;ArrayList;(int);generated", - "kotlin.collections;ArrayList;ensureCapacity;(int);generated", - "kotlin.collections;ArrayList;trimToSize;();generated", - "kotlin.collections;ArraysKt;all;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;all;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;all;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;all;(char[],Function1);generated", - "kotlin.collections;ArraysKt;all;(double[],Function1);generated", - "kotlin.collections;ArraysKt;all;(float[],Function1);generated", - "kotlin.collections;ArraysKt;all;(int[],Function1);generated", - "kotlin.collections;ArraysKt;all;(long[],Function1);generated", - "kotlin.collections;ArraysKt;all;(short[],Function1);generated", - "kotlin.collections;ArraysKt;any;(Object[]);generated", - "kotlin.collections;ArraysKt;any;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;any;(boolean[]);generated", - "kotlin.collections;ArraysKt;any;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;any;(byte[]);generated", - "kotlin.collections;ArraysKt;any;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;any;(char[]);generated", - "kotlin.collections;ArraysKt;any;(char[],Function1);generated", - "kotlin.collections;ArraysKt;any;(double[]);generated", - "kotlin.collections;ArraysKt;any;(double[],Function1);generated", - "kotlin.collections;ArraysKt;any;(float[]);generated", - "kotlin.collections;ArraysKt;any;(float[],Function1);generated", - "kotlin.collections;ArraysKt;any;(int[]);generated", - "kotlin.collections;ArraysKt;any;(int[],Function1);generated", - "kotlin.collections;ArraysKt;any;(long[]);generated", - "kotlin.collections;ArraysKt;any;(long[],Function1);generated", - "kotlin.collections;ArraysKt;any;(short[]);generated", - "kotlin.collections;ArraysKt;any;(short[],Function1);generated", - "kotlin.collections;ArraysKt;asIterable;(Object[]);generated", - "kotlin.collections;ArraysKt;asIterable;(boolean[]);generated", - "kotlin.collections;ArraysKt;asIterable;(byte[]);generated", - "kotlin.collections;ArraysKt;asIterable;(char[]);generated", - "kotlin.collections;ArraysKt;asIterable;(double[]);generated", - "kotlin.collections;ArraysKt;asIterable;(float[]);generated", - "kotlin.collections;ArraysKt;asIterable;(int[]);generated", - "kotlin.collections;ArraysKt;asIterable;(long[]);generated", - "kotlin.collections;ArraysKt;asIterable;(short[]);generated", - "kotlin.collections;ArraysKt;asList;(boolean[]);generated", - "kotlin.collections;ArraysKt;asList;(byte[]);generated", - "kotlin.collections;ArraysKt;asList;(char[]);generated", - "kotlin.collections;ArraysKt;asList;(double[]);generated", - "kotlin.collections;ArraysKt;asList;(float[]);generated", - "kotlin.collections;ArraysKt;asList;(int[]);generated", - "kotlin.collections;ArraysKt;asList;(long[]);generated", - "kotlin.collections;ArraysKt;asList;(short[]);generated", - "kotlin.collections;ArraysKt;asSequence;(Object[]);generated", - "kotlin.collections;ArraysKt;asSequence;(boolean[]);generated", - "kotlin.collections;ArraysKt;asSequence;(byte[]);generated", - "kotlin.collections;ArraysKt;asSequence;(char[]);generated", - "kotlin.collections;ArraysKt;asSequence;(double[]);generated", - "kotlin.collections;ArraysKt;asSequence;(float[]);generated", - "kotlin.collections;ArraysKt;asSequence;(int[]);generated", - "kotlin.collections;ArraysKt;asSequence;(long[]);generated", - "kotlin.collections;ArraysKt;asSequence;(short[]);generated", - "kotlin.collections;ArraysKt;associate;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;associate;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;associate;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;associate;(char[],Function1);generated", - "kotlin.collections;ArraysKt;associate;(double[],Function1);generated", - "kotlin.collections;ArraysKt;associate;(float[],Function1);generated", - "kotlin.collections;ArraysKt;associate;(int[],Function1);generated", - "kotlin.collections;ArraysKt;associate;(long[],Function1);generated", - "kotlin.collections;ArraysKt;associate;(short[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(Object[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(boolean[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(byte[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(char[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(char[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(double[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(double[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(float[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(float[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(int[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(int[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(long[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(long[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(short[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(short[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(char[],Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(double[],Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(float[],Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(int[],Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(long[],Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(short[],Function1);generated", - "kotlin.collections;ArraysKt;average;(byte[]);generated", - "kotlin.collections;ArraysKt;average;(double[]);generated", - "kotlin.collections;ArraysKt;average;(float[]);generated", - "kotlin.collections;ArraysKt;average;(int[]);generated", - "kotlin.collections;ArraysKt;average;(long[]);generated", - "kotlin.collections;ArraysKt;average;(short[]);generated", - "kotlin.collections;ArraysKt;averageOfByte;(Byte[]);generated", - "kotlin.collections;ArraysKt;averageOfDouble;(Double[]);generated", - "kotlin.collections;ArraysKt;averageOfFloat;(Float[]);generated", - "kotlin.collections;ArraysKt;averageOfInt;(Integer[]);generated", - "kotlin.collections;ArraysKt;averageOfLong;(Long[]);generated", - "kotlin.collections;ArraysKt;averageOfShort;(Short[]);generated", - "kotlin.collections;ArraysKt;binarySearch;(Object[],Object,Comparator,int,int);generated", - "kotlin.collections;ArraysKt;binarySearch;(Object[],Object,int,int);generated", - "kotlin.collections;ArraysKt;binarySearch;(byte[],byte,int,int);generated", - "kotlin.collections;ArraysKt;binarySearch;(char[],char,int,int);generated", - "kotlin.collections;ArraysKt;binarySearch;(double[],double,int,int);generated", - "kotlin.collections;ArraysKt;binarySearch;(float[],float,int,int);generated", - "kotlin.collections;ArraysKt;binarySearch;(int[],int,int,int);generated", - "kotlin.collections;ArraysKt;binarySearch;(long[],long,int,int);generated", - "kotlin.collections;ArraysKt;binarySearch;(short[],short,int,int);generated", - "kotlin.collections;ArraysKt;component1;(Object[]);generated", - "kotlin.collections;ArraysKt;component1;(boolean[]);generated", - "kotlin.collections;ArraysKt;component1;(byte[]);generated", - "kotlin.collections;ArraysKt;component1;(char[]);generated", - "kotlin.collections;ArraysKt;component1;(double[]);generated", - "kotlin.collections;ArraysKt;component1;(float[]);generated", - "kotlin.collections;ArraysKt;component1;(int[]);generated", - "kotlin.collections;ArraysKt;component1;(long[]);generated", - "kotlin.collections;ArraysKt;component1;(short[]);generated", - "kotlin.collections;ArraysKt;component2;(Object[]);generated", - "kotlin.collections;ArraysKt;component2;(boolean[]);generated", - "kotlin.collections;ArraysKt;component2;(byte[]);generated", - "kotlin.collections;ArraysKt;component2;(char[]);generated", - "kotlin.collections;ArraysKt;component2;(double[]);generated", - "kotlin.collections;ArraysKt;component2;(float[]);generated", - "kotlin.collections;ArraysKt;component2;(int[]);generated", - "kotlin.collections;ArraysKt;component2;(long[]);generated", - "kotlin.collections;ArraysKt;component2;(short[]);generated", - "kotlin.collections;ArraysKt;component3;(Object[]);generated", - "kotlin.collections;ArraysKt;component3;(boolean[]);generated", - "kotlin.collections;ArraysKt;component3;(byte[]);generated", - "kotlin.collections;ArraysKt;component3;(char[]);generated", - "kotlin.collections;ArraysKt;component3;(double[]);generated", - "kotlin.collections;ArraysKt;component3;(float[]);generated", - "kotlin.collections;ArraysKt;component3;(int[]);generated", - "kotlin.collections;ArraysKt;component3;(long[]);generated", - "kotlin.collections;ArraysKt;component3;(short[]);generated", - "kotlin.collections;ArraysKt;component4;(Object[]);generated", - "kotlin.collections;ArraysKt;component4;(boolean[]);generated", - "kotlin.collections;ArraysKt;component4;(byte[]);generated", - "kotlin.collections;ArraysKt;component4;(char[]);generated", - "kotlin.collections;ArraysKt;component4;(double[]);generated", - "kotlin.collections;ArraysKt;component4;(float[]);generated", - "kotlin.collections;ArraysKt;component4;(int[]);generated", - "kotlin.collections;ArraysKt;component4;(long[]);generated", - "kotlin.collections;ArraysKt;component4;(short[]);generated", - "kotlin.collections;ArraysKt;component5;(Object[]);generated", - "kotlin.collections;ArraysKt;component5;(boolean[]);generated", - "kotlin.collections;ArraysKt;component5;(byte[]);generated", - "kotlin.collections;ArraysKt;component5;(char[]);generated", - "kotlin.collections;ArraysKt;component5;(double[]);generated", - "kotlin.collections;ArraysKt;component5;(float[]);generated", - "kotlin.collections;ArraysKt;component5;(int[]);generated", - "kotlin.collections;ArraysKt;component5;(long[]);generated", - "kotlin.collections;ArraysKt;component5;(short[]);generated", - "kotlin.collections;ArraysKt;contains;(Object[],Object);generated", - "kotlin.collections;ArraysKt;contains;(boolean[],boolean);generated", - "kotlin.collections;ArraysKt;contains;(byte[],byte);generated", - "kotlin.collections;ArraysKt;contains;(char[],char);generated", - "kotlin.collections;ArraysKt;contains;(double[],double);generated", - "kotlin.collections;ArraysKt;contains;(float[],float);generated", - "kotlin.collections;ArraysKt;contains;(int[],int);generated", - "kotlin.collections;ArraysKt;contains;(long[],long);generated", - "kotlin.collections;ArraysKt;contains;(short[],short);generated", - "kotlin.collections;ArraysKt;contentDeepEqualsInline;(Object[],Object[]);generated", - "kotlin.collections;ArraysKt;contentDeepEqualsNullable;(Object[],Object[]);generated", - "kotlin.collections;ArraysKt;contentDeepHashCodeInline;(Object[]);generated", - "kotlin.collections;ArraysKt;contentDeepHashCodeNullable;(Object[]);generated", - "kotlin.collections;ArraysKt;contentDeepToStringInline;(Object[]);generated", - "kotlin.collections;ArraysKt;contentDeepToStringNullable;(Object[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(Object[],Object[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(boolean[],boolean[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(byte[],byte[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(char[],char[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(double[],double[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(float[],float[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(int[],int[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(long[],long[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(short[],short[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(Object[],Object[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(boolean[],boolean[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(byte[],byte[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(char[],char[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(double[],double[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(float[],float[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(int[],int[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(long[],long[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(short[],short[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(Object[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(boolean[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(byte[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(char[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(double[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(float[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(int[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(long[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(short[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(Object[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(boolean[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(byte[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(char[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(double[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(float[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(int[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(long[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(short[]);generated", - "kotlin.collections;ArraysKt;contentToString;(Object[]);generated", - "kotlin.collections;ArraysKt;contentToString;(boolean[]);generated", - "kotlin.collections;ArraysKt;contentToString;(byte[]);generated", - "kotlin.collections;ArraysKt;contentToString;(char[]);generated", - "kotlin.collections;ArraysKt;contentToString;(double[]);generated", - "kotlin.collections;ArraysKt;contentToString;(float[]);generated", - "kotlin.collections;ArraysKt;contentToString;(int[]);generated", - "kotlin.collections;ArraysKt;contentToString;(long[]);generated", - "kotlin.collections;ArraysKt;contentToString;(short[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(Object[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(boolean[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(byte[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(char[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(double[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(float[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(int[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(long[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(short[]);generated", - "kotlin.collections;ArraysKt;copyInto;(boolean[],boolean[],int,int,int);generated", - "kotlin.collections;ArraysKt;copyInto;(double[],double[],int,int,int);generated", - "kotlin.collections;ArraysKt;copyInto;(float[],float[],int,int,int);generated", - "kotlin.collections;ArraysKt;copyInto;(int[],int[],int,int,int);generated", - "kotlin.collections;ArraysKt;copyInto;(long[],long[],int,int,int);generated", - "kotlin.collections;ArraysKt;copyInto;(short[],short[],int,int,int);generated", - "kotlin.collections;ArraysKt;copyOf;(boolean[]);generated", - "kotlin.collections;ArraysKt;copyOf;(boolean[],int);generated", - "kotlin.collections;ArraysKt;copyOf;(double[]);generated", - "kotlin.collections;ArraysKt;copyOf;(double[],int);generated", - "kotlin.collections;ArraysKt;copyOf;(float[]);generated", - "kotlin.collections;ArraysKt;copyOf;(float[],int);generated", - "kotlin.collections;ArraysKt;copyOf;(int[]);generated", - "kotlin.collections;ArraysKt;copyOf;(int[],int);generated", - "kotlin.collections;ArraysKt;copyOf;(long[]);generated", - "kotlin.collections;ArraysKt;copyOf;(long[],int);generated", - "kotlin.collections;ArraysKt;copyOf;(short[]);generated", - "kotlin.collections;ArraysKt;copyOf;(short[],int);generated", - "kotlin.collections;ArraysKt;copyOfRangeInline;(boolean[],int,int);generated", - "kotlin.collections;ArraysKt;copyOfRangeInline;(double[],int,int);generated", - "kotlin.collections;ArraysKt;copyOfRangeInline;(float[],int,int);generated", - "kotlin.collections;ArraysKt;copyOfRangeInline;(int[],int,int);generated", - "kotlin.collections;ArraysKt;copyOfRangeInline;(long[],int,int);generated", - "kotlin.collections;ArraysKt;copyOfRangeInline;(short[],int,int);generated", - "kotlin.collections;ArraysKt;count;(Object[]);generated", - "kotlin.collections;ArraysKt;count;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;count;(boolean[]);generated", - "kotlin.collections;ArraysKt;count;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;count;(byte[]);generated", - "kotlin.collections;ArraysKt;count;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;count;(char[]);generated", - "kotlin.collections;ArraysKt;count;(char[],Function1);generated", - "kotlin.collections;ArraysKt;count;(double[]);generated", - "kotlin.collections;ArraysKt;count;(double[],Function1);generated", - "kotlin.collections;ArraysKt;count;(float[]);generated", - "kotlin.collections;ArraysKt;count;(float[],Function1);generated", - "kotlin.collections;ArraysKt;count;(int[]);generated", - "kotlin.collections;ArraysKt;count;(int[],Function1);generated", - "kotlin.collections;ArraysKt;count;(long[]);generated", - "kotlin.collections;ArraysKt;count;(long[],Function1);generated", - "kotlin.collections;ArraysKt;count;(short[]);generated", - "kotlin.collections;ArraysKt;count;(short[],Function1);generated", - "kotlin.collections;ArraysKt;distinct;(Object[]);generated", - "kotlin.collections;ArraysKt;distinct;(boolean[]);generated", - "kotlin.collections;ArraysKt;distinct;(byte[]);generated", - "kotlin.collections;ArraysKt;distinct;(char[]);generated", - "kotlin.collections;ArraysKt;distinct;(double[]);generated", - "kotlin.collections;ArraysKt;distinct;(float[]);generated", - "kotlin.collections;ArraysKt;distinct;(int[]);generated", - "kotlin.collections;ArraysKt;distinct;(long[]);generated", - "kotlin.collections;ArraysKt;distinct;(short[]);generated", - "kotlin.collections;ArraysKt;distinctBy;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;distinctBy;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;distinctBy;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;distinctBy;(char[],Function1);generated", - "kotlin.collections;ArraysKt;distinctBy;(double[],Function1);generated", - "kotlin.collections;ArraysKt;distinctBy;(float[],Function1);generated", - "kotlin.collections;ArraysKt;distinctBy;(int[],Function1);generated", - "kotlin.collections;ArraysKt;distinctBy;(long[],Function1);generated", - "kotlin.collections;ArraysKt;distinctBy;(short[],Function1);generated", - "kotlin.collections;ArraysKt;drop;(boolean[],int);generated", - "kotlin.collections;ArraysKt;drop;(byte[],int);generated", - "kotlin.collections;ArraysKt;drop;(char[],int);generated", - "kotlin.collections;ArraysKt;drop;(double[],int);generated", - "kotlin.collections;ArraysKt;drop;(float[],int);generated", - "kotlin.collections;ArraysKt;drop;(int[],int);generated", - "kotlin.collections;ArraysKt;drop;(long[],int);generated", - "kotlin.collections;ArraysKt;drop;(short[],int);generated", - "kotlin.collections;ArraysKt;dropLast;(boolean[],int);generated", - "kotlin.collections;ArraysKt;dropLast;(byte[],int);generated", - "kotlin.collections;ArraysKt;dropLast;(char[],int);generated", - "kotlin.collections;ArraysKt;dropLast;(double[],int);generated", - "kotlin.collections;ArraysKt;dropLast;(float[],int);generated", - "kotlin.collections;ArraysKt;dropLast;(int[],int);generated", - "kotlin.collections;ArraysKt;dropLast;(long[],int);generated", - "kotlin.collections;ArraysKt;dropLast;(short[],int);generated", - "kotlin.collections;ArraysKt;dropLastWhile;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;dropLastWhile;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;dropLastWhile;(char[],Function1);generated", - "kotlin.collections;ArraysKt;dropLastWhile;(double[],Function1);generated", - "kotlin.collections;ArraysKt;dropLastWhile;(float[],Function1);generated", - "kotlin.collections;ArraysKt;dropLastWhile;(int[],Function1);generated", - "kotlin.collections;ArraysKt;dropLastWhile;(long[],Function1);generated", - "kotlin.collections;ArraysKt;dropLastWhile;(short[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(char[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(double[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(float[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(int[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(long[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(short[],Function1);generated", - "kotlin.collections;ArraysKt;elementAt;(Object[],int);generated", - "kotlin.collections;ArraysKt;elementAt;(boolean[],int);generated", - "kotlin.collections;ArraysKt;elementAt;(byte[],int);generated", - "kotlin.collections;ArraysKt;elementAt;(char[],int);generated", - "kotlin.collections;ArraysKt;elementAt;(double[],int);generated", - "kotlin.collections;ArraysKt;elementAt;(float[],int);generated", - "kotlin.collections;ArraysKt;elementAt;(int[],int);generated", - "kotlin.collections;ArraysKt;elementAt;(long[],int);generated", - "kotlin.collections;ArraysKt;elementAt;(short[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(Object[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(boolean[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(byte[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(char[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(double[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(float[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(int[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(long[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(short[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(Object[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(boolean[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(byte[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(char[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(double[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(float[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(int[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(long[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(short[],int);generated", - "kotlin.collections;ArraysKt;fill;(boolean[],boolean,int,int);generated", - "kotlin.collections;ArraysKt;fill;(byte[],byte,int,int);generated", - "kotlin.collections;ArraysKt;fill;(char[],char,int,int);generated", - "kotlin.collections;ArraysKt;fill;(double[],double,int,int);generated", - "kotlin.collections;ArraysKt;fill;(float[],float,int,int);generated", - "kotlin.collections;ArraysKt;fill;(int[],int,int,int);generated", - "kotlin.collections;ArraysKt;fill;(long[],long,int,int);generated", - "kotlin.collections;ArraysKt;fill;(short[],short,int,int);generated", - "kotlin.collections;ArraysKt;filter;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;filter;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;filter;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;filter;(char[],Function1);generated", - "kotlin.collections;ArraysKt;filter;(double[],Function1);generated", - "kotlin.collections;ArraysKt;filter;(float[],Function1);generated", - "kotlin.collections;ArraysKt;filter;(int[],Function1);generated", - "kotlin.collections;ArraysKt;filter;(long[],Function1);generated", - "kotlin.collections;ArraysKt;filter;(short[],Function1);generated", - "kotlin.collections;ArraysKt;filterIndexed;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;filterIndexed;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;filterIndexed;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;filterIndexed;(char[],Function2);generated", - "kotlin.collections;ArraysKt;filterIndexed;(double[],Function2);generated", - "kotlin.collections;ArraysKt;filterIndexed;(float[],Function2);generated", - "kotlin.collections;ArraysKt;filterIndexed;(int[],Function2);generated", - "kotlin.collections;ArraysKt;filterIndexed;(long[],Function2);generated", - "kotlin.collections;ArraysKt;filterIndexed;(short[],Function2);generated", - "kotlin.collections;ArraysKt;filterIsInstance;(Object[]);generated", - "kotlin.collections;ArraysKt;filterIsInstance;(Object[],Class);generated", - "kotlin.collections;ArraysKt;filterNot;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;filterNot;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;filterNot;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;filterNot;(char[],Function1);generated", - "kotlin.collections;ArraysKt;filterNot;(double[],Function1);generated", - "kotlin.collections;ArraysKt;filterNot;(float[],Function1);generated", - "kotlin.collections;ArraysKt;filterNot;(int[],Function1);generated", - "kotlin.collections;ArraysKt;filterNot;(long[],Function1);generated", - "kotlin.collections;ArraysKt;filterNot;(short[],Function1);generated", - "kotlin.collections;ArraysKt;filterNotNull;(Object[]);generated", - "kotlin.collections;ArraysKt;find;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;find;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;find;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;find;(char[],Function1);generated", - "kotlin.collections;ArraysKt;find;(double[],Function1);generated", - "kotlin.collections;ArraysKt;find;(float[],Function1);generated", - "kotlin.collections;ArraysKt;find;(int[],Function1);generated", - "kotlin.collections;ArraysKt;find;(long[],Function1);generated", - "kotlin.collections;ArraysKt;find;(short[],Function1);generated", - "kotlin.collections;ArraysKt;findLast;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;findLast;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;findLast;(char[],Function1);generated", - "kotlin.collections;ArraysKt;findLast;(double[],Function1);generated", - "kotlin.collections;ArraysKt;findLast;(float[],Function1);generated", - "kotlin.collections;ArraysKt;findLast;(int[],Function1);generated", - "kotlin.collections;ArraysKt;findLast;(long[],Function1);generated", - "kotlin.collections;ArraysKt;findLast;(short[],Function1);generated", - "kotlin.collections;ArraysKt;first;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;first;(boolean[]);generated", - "kotlin.collections;ArraysKt;first;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;first;(byte[]);generated", - "kotlin.collections;ArraysKt;first;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;first;(char[]);generated", - "kotlin.collections;ArraysKt;first;(char[],Function1);generated", - "kotlin.collections;ArraysKt;first;(double[]);generated", - "kotlin.collections;ArraysKt;first;(double[],Function1);generated", - "kotlin.collections;ArraysKt;first;(float[]);generated", - "kotlin.collections;ArraysKt;first;(float[],Function1);generated", - "kotlin.collections;ArraysKt;first;(int[]);generated", - "kotlin.collections;ArraysKt;first;(int[],Function1);generated", - "kotlin.collections;ArraysKt;first;(long[]);generated", - "kotlin.collections;ArraysKt;first;(long[],Function1);generated", - "kotlin.collections;ArraysKt;first;(short[]);generated", - "kotlin.collections;ArraysKt;first;(short[],Function1);generated", - "kotlin.collections;ArraysKt;firstNotNullOf;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;firstNotNullOfOrNull;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(boolean[]);generated", - "kotlin.collections;ArraysKt;firstOrNull;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(byte[]);generated", - "kotlin.collections;ArraysKt;firstOrNull;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(char[]);generated", - "kotlin.collections;ArraysKt;firstOrNull;(char[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(double[]);generated", - "kotlin.collections;ArraysKt;firstOrNull;(double[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(float[]);generated", - "kotlin.collections;ArraysKt;firstOrNull;(float[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(int[]);generated", - "kotlin.collections;ArraysKt;firstOrNull;(int[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(long[]);generated", - "kotlin.collections;ArraysKt;firstOrNull;(long[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(short[]);generated", - "kotlin.collections;ArraysKt;firstOrNull;(short[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(char[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(double[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(float[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(int[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(long[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(short[],Function1);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(char[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(double[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(float[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(int[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(long[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(short[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedSequence;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapSequence;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;flatten;(Object[][]);generated", - "kotlin.collections;ArraysKt;forEach;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;forEach;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;forEach;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;forEach;(char[],Function1);generated", - "kotlin.collections;ArraysKt;forEach;(double[],Function1);generated", - "kotlin.collections;ArraysKt;forEach;(float[],Function1);generated", - "kotlin.collections;ArraysKt;forEach;(int[],Function1);generated", - "kotlin.collections;ArraysKt;forEach;(long[],Function1);generated", - "kotlin.collections;ArraysKt;forEach;(short[],Function1);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(char[],Function2);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(double[],Function2);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(float[],Function2);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(int[],Function2);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(long[],Function2);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(short[],Function2);generated", - "kotlin.collections;ArraysKt;getIndices;(Object[]);generated", - "kotlin.collections;ArraysKt;getIndices;(boolean[]);generated", - "kotlin.collections;ArraysKt;getIndices;(byte[]);generated", - "kotlin.collections;ArraysKt;getIndices;(char[]);generated", - "kotlin.collections;ArraysKt;getIndices;(double[]);generated", - "kotlin.collections;ArraysKt;getIndices;(float[]);generated", - "kotlin.collections;ArraysKt;getIndices;(int[]);generated", - "kotlin.collections;ArraysKt;getIndices;(long[]);generated", - "kotlin.collections;ArraysKt;getIndices;(short[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(Object[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(boolean[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(byte[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(char[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(double[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(float[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(int[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(long[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(short[]);generated", - "kotlin.collections;ArraysKt;getOrElse;(Object[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrElse;(boolean[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrElse;(byte[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrElse;(char[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrElse;(double[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrElse;(float[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrElse;(int[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrElse;(long[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrElse;(short[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrNull;(Object[],int);generated", - "kotlin.collections;ArraysKt;getOrNull;(boolean[],int);generated", - "kotlin.collections;ArraysKt;getOrNull;(byte[],int);generated", - "kotlin.collections;ArraysKt;getOrNull;(char[],int);generated", - "kotlin.collections;ArraysKt;getOrNull;(double[],int);generated", - "kotlin.collections;ArraysKt;getOrNull;(float[],int);generated", - "kotlin.collections;ArraysKt;getOrNull;(int[],int);generated", - "kotlin.collections;ArraysKt;getOrNull;(long[],int);generated", - "kotlin.collections;ArraysKt;getOrNull;(short[],int);generated", - "kotlin.collections;ArraysKt;groupBy;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(Object[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(boolean[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(byte[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(char[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(char[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(double[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(double[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(float[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(float[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(int[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(int[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(long[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(long[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(short[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(short[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupingBy;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;indexOf;(Object[],Object);generated", - "kotlin.collections;ArraysKt;indexOf;(boolean[],boolean);generated", - "kotlin.collections;ArraysKt;indexOf;(byte[],byte);generated", - "kotlin.collections;ArraysKt;indexOf;(char[],char);generated", - "kotlin.collections;ArraysKt;indexOf;(double[],double);generated", - "kotlin.collections;ArraysKt;indexOf;(float[],float);generated", - "kotlin.collections;ArraysKt;indexOf;(int[],int);generated", - "kotlin.collections;ArraysKt;indexOf;(long[],long);generated", - "kotlin.collections;ArraysKt;indexOf;(short[],short);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(char[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(double[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(float[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(int[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(long[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(short[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(char[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(double[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(float[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(int[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(long[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(short[],Function1);generated", - "kotlin.collections;ArraysKt;intersect;(Object[],Iterable);generated", - "kotlin.collections;ArraysKt;intersect;(boolean[],Iterable);generated", - "kotlin.collections;ArraysKt;intersect;(byte[],Iterable);generated", - "kotlin.collections;ArraysKt;intersect;(char[],Iterable);generated", - "kotlin.collections;ArraysKt;intersect;(double[],Iterable);generated", - "kotlin.collections;ArraysKt;intersect;(float[],Iterable);generated", - "kotlin.collections;ArraysKt;intersect;(int[],Iterable);generated", - "kotlin.collections;ArraysKt;intersect;(long[],Iterable);generated", - "kotlin.collections;ArraysKt;intersect;(short[],Iterable);generated", - "kotlin.collections;ArraysKt;isEmpty;(Object[]);generated", - "kotlin.collections;ArraysKt;isEmpty;(boolean[]);generated", - "kotlin.collections;ArraysKt;isEmpty;(byte[]);generated", - "kotlin.collections;ArraysKt;isEmpty;(char[]);generated", - "kotlin.collections;ArraysKt;isEmpty;(double[]);generated", - "kotlin.collections;ArraysKt;isEmpty;(float[]);generated", - "kotlin.collections;ArraysKt;isEmpty;(int[]);generated", - "kotlin.collections;ArraysKt;isEmpty;(long[]);generated", - "kotlin.collections;ArraysKt;isEmpty;(short[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(Object[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(boolean[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(byte[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(char[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(double[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(float[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(int[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(long[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(short[]);generated", - "kotlin.collections;ArraysKt;isNullOrEmpty;(Object[]);generated", - "kotlin.collections;ArraysKt;last;(boolean[]);generated", - "kotlin.collections;ArraysKt;last;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;last;(byte[]);generated", - "kotlin.collections;ArraysKt;last;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;last;(char[]);generated", - "kotlin.collections;ArraysKt;last;(char[],Function1);generated", - "kotlin.collections;ArraysKt;last;(double[]);generated", - "kotlin.collections;ArraysKt;last;(double[],Function1);generated", - "kotlin.collections;ArraysKt;last;(float[]);generated", - "kotlin.collections;ArraysKt;last;(float[],Function1);generated", - "kotlin.collections;ArraysKt;last;(int[]);generated", - "kotlin.collections;ArraysKt;last;(int[],Function1);generated", - "kotlin.collections;ArraysKt;last;(long[]);generated", - "kotlin.collections;ArraysKt;last;(long[],Function1);generated", - "kotlin.collections;ArraysKt;last;(short[]);generated", - "kotlin.collections;ArraysKt;last;(short[],Function1);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(Object[],Object);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(boolean[],boolean);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(byte[],byte);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(char[],char);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(double[],double);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(float[],float);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(int[],int);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(long[],long);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(short[],short);generated", - "kotlin.collections;ArraysKt;lastOrNull;(boolean[]);generated", - "kotlin.collections;ArraysKt;lastOrNull;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;lastOrNull;(byte[]);generated", - "kotlin.collections;ArraysKt;lastOrNull;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;lastOrNull;(char[]);generated", - "kotlin.collections;ArraysKt;lastOrNull;(char[],Function1);generated", - "kotlin.collections;ArraysKt;lastOrNull;(double[]);generated", - "kotlin.collections;ArraysKt;lastOrNull;(double[],Function1);generated", - "kotlin.collections;ArraysKt;lastOrNull;(float[]);generated", - "kotlin.collections;ArraysKt;lastOrNull;(float[],Function1);generated", - "kotlin.collections;ArraysKt;lastOrNull;(int[]);generated", - "kotlin.collections;ArraysKt;lastOrNull;(int[],Function1);generated", - "kotlin.collections;ArraysKt;lastOrNull;(long[]);generated", - "kotlin.collections;ArraysKt;lastOrNull;(long[],Function1);generated", - "kotlin.collections;ArraysKt;lastOrNull;(short[]);generated", - "kotlin.collections;ArraysKt;lastOrNull;(short[],Function1);generated", - "kotlin.collections;ArraysKt;map;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;map;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;map;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;map;(char[],Function1);generated", - "kotlin.collections;ArraysKt;map;(double[],Function1);generated", - "kotlin.collections;ArraysKt;map;(float[],Function1);generated", - "kotlin.collections;ArraysKt;map;(int[],Function1);generated", - "kotlin.collections;ArraysKt;map;(long[],Function1);generated", - "kotlin.collections;ArraysKt;map;(short[],Function1);generated", - "kotlin.collections;ArraysKt;mapIndexed;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexed;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexed;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexed;(char[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexed;(double[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexed;(float[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexed;(int[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexed;(long[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexed;(short[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexedNotNull;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;mapNotNull;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;max;(Double[]);generated", - "kotlin.collections;ArraysKt;max;(Float[]);generated", - "kotlin.collections;ArraysKt;max;(byte[]);generated", - "kotlin.collections;ArraysKt;max;(char[]);generated", - "kotlin.collections;ArraysKt;max;(double[]);generated", - "kotlin.collections;ArraysKt;max;(float[]);generated", - "kotlin.collections;ArraysKt;max;(int[]);generated", - "kotlin.collections;ArraysKt;max;(long[]);generated", - "kotlin.collections;ArraysKt;max;(short[]);generated", - "kotlin.collections;ArraysKt;maxBy;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;maxBy;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;maxBy;(char[],Function1);generated", - "kotlin.collections;ArraysKt;maxBy;(double[],Function1);generated", - "kotlin.collections;ArraysKt;maxBy;(float[],Function1);generated", - "kotlin.collections;ArraysKt;maxBy;(int[],Function1);generated", - "kotlin.collections;ArraysKt;maxBy;(long[],Function1);generated", - "kotlin.collections;ArraysKt;maxBy;(short[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrNull;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrNull;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrNull;(char[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrNull;(double[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrNull;(float[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrNull;(int[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrNull;(long[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrNull;(short[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrThrow;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrThrow;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrThrow;(char[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrThrow;(double[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrThrow;(float[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrThrow;(int[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrThrow;(long[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrThrow;(short[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(char[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(double[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(float[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(int[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(long[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(short[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(char[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(double[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(float[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(int[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(long[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(short[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfWith;(boolean[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWith;(byte[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWith;(char[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWith;(double[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWith;(float[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWith;(int[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWith;(long[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWith;(short[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWithOrNull;(boolean[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWithOrNull;(byte[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWithOrNull;(char[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWithOrNull;(double[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWithOrNull;(float[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWithOrNull;(int[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWithOrNull;(long[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWithOrNull;(short[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOrNull;(Double[]);generated", - "kotlin.collections;ArraysKt;maxOrNull;(Float[]);generated", - "kotlin.collections;ArraysKt;maxOrNull;(byte[]);generated", - "kotlin.collections;ArraysKt;maxOrNull;(char[]);generated", - "kotlin.collections;ArraysKt;maxOrNull;(double[]);generated", - "kotlin.collections;ArraysKt;maxOrNull;(float[]);generated", - "kotlin.collections;ArraysKt;maxOrNull;(int[]);generated", - "kotlin.collections;ArraysKt;maxOrNull;(long[]);generated", - "kotlin.collections;ArraysKt;maxOrNull;(short[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(Double[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(Float[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(byte[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(char[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(double[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(float[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(int[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(long[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(short[]);generated", - "kotlin.collections;ArraysKt;maxWith;(boolean[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWith;(byte[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWith;(char[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWith;(double[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWith;(float[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWith;(int[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWith;(long[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWith;(short[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrNull;(boolean[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrNull;(byte[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrNull;(char[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrNull;(double[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrNull;(float[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrNull;(int[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrNull;(long[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrNull;(short[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrThrow;(boolean[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrThrow;(byte[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrThrow;(char[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrThrow;(double[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrThrow;(float[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrThrow;(int[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrThrow;(long[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrThrow;(short[],Comparator);generated", - "kotlin.collections;ArraysKt;min;(Double[]);generated", - "kotlin.collections;ArraysKt;min;(Float[]);generated", - "kotlin.collections;ArraysKt;min;(byte[]);generated", - "kotlin.collections;ArraysKt;min;(char[]);generated", - "kotlin.collections;ArraysKt;min;(double[]);generated", - "kotlin.collections;ArraysKt;min;(float[]);generated", - "kotlin.collections;ArraysKt;min;(int[]);generated", - "kotlin.collections;ArraysKt;min;(long[]);generated", - "kotlin.collections;ArraysKt;min;(short[]);generated", - "kotlin.collections;ArraysKt;minBy;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;minBy;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;minBy;(char[],Function1);generated", - "kotlin.collections;ArraysKt;minBy;(double[],Function1);generated", - "kotlin.collections;ArraysKt;minBy;(float[],Function1);generated", - "kotlin.collections;ArraysKt;minBy;(int[],Function1);generated", - "kotlin.collections;ArraysKt;minBy;(long[],Function1);generated", - "kotlin.collections;ArraysKt;minBy;(short[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrNull;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrNull;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrNull;(char[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrNull;(double[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrNull;(float[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrNull;(int[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrNull;(long[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrNull;(short[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrThrow;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrThrow;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrThrow;(char[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrThrow;(double[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrThrow;(float[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrThrow;(int[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrThrow;(long[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrThrow;(short[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(char[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(double[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(float[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(int[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(long[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(short[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(char[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(double[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(float[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(int[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(long[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(short[],Function1);generated", - "kotlin.collections;ArraysKt;minOfWith;(boolean[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWith;(byte[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWith;(char[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWith;(double[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWith;(float[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWith;(int[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWith;(long[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWith;(short[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWithOrNull;(boolean[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWithOrNull;(byte[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWithOrNull;(char[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWithOrNull;(double[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWithOrNull;(float[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWithOrNull;(int[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWithOrNull;(long[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWithOrNull;(short[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOrNull;(Double[]);generated", - "kotlin.collections;ArraysKt;minOrNull;(Float[]);generated", - "kotlin.collections;ArraysKt;minOrNull;(byte[]);generated", - "kotlin.collections;ArraysKt;minOrNull;(char[]);generated", - "kotlin.collections;ArraysKt;minOrNull;(double[]);generated", - "kotlin.collections;ArraysKt;minOrNull;(float[]);generated", - "kotlin.collections;ArraysKt;minOrNull;(int[]);generated", - "kotlin.collections;ArraysKt;minOrNull;(long[]);generated", - "kotlin.collections;ArraysKt;minOrNull;(short[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(Double[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(Float[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(byte[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(char[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(double[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(float[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(int[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(long[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(short[]);generated", - "kotlin.collections;ArraysKt;minWith;(boolean[],Comparator);generated", - "kotlin.collections;ArraysKt;minWith;(byte[],Comparator);generated", - "kotlin.collections;ArraysKt;minWith;(char[],Comparator);generated", - "kotlin.collections;ArraysKt;minWith;(double[],Comparator);generated", - "kotlin.collections;ArraysKt;minWith;(float[],Comparator);generated", - "kotlin.collections;ArraysKt;minWith;(int[],Comparator);generated", - "kotlin.collections;ArraysKt;minWith;(long[],Comparator);generated", - "kotlin.collections;ArraysKt;minWith;(short[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrNull;(boolean[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrNull;(byte[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrNull;(char[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrNull;(double[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrNull;(float[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrNull;(int[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrNull;(long[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrNull;(short[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrThrow;(boolean[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrThrow;(byte[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrThrow;(char[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrThrow;(double[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrThrow;(float[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrThrow;(int[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrThrow;(long[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrThrow;(short[],Comparator);generated", - "kotlin.collections;ArraysKt;none;(Object[]);generated", - "kotlin.collections;ArraysKt;none;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;none;(boolean[]);generated", - "kotlin.collections;ArraysKt;none;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;none;(byte[]);generated", - "kotlin.collections;ArraysKt;none;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;none;(char[]);generated", - "kotlin.collections;ArraysKt;none;(char[],Function1);generated", - "kotlin.collections;ArraysKt;none;(double[]);generated", - "kotlin.collections;ArraysKt;none;(double[],Function1);generated", - "kotlin.collections;ArraysKt;none;(float[]);generated", - "kotlin.collections;ArraysKt;none;(float[],Function1);generated", - "kotlin.collections;ArraysKt;none;(int[]);generated", - "kotlin.collections;ArraysKt;none;(int[],Function1);generated", - "kotlin.collections;ArraysKt;none;(long[]);generated", - "kotlin.collections;ArraysKt;none;(long[],Function1);generated", - "kotlin.collections;ArraysKt;none;(short[]);generated", - "kotlin.collections;ArraysKt;none;(short[],Function1);generated", - "kotlin.collections;ArraysKt;onEach;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;onEach;(double[],Function1);generated", - "kotlin.collections;ArraysKt;onEach;(float[],Function1);generated", - "kotlin.collections;ArraysKt;onEach;(int[],Function1);generated", - "kotlin.collections;ArraysKt;onEach;(long[],Function1);generated", - "kotlin.collections;ArraysKt;onEach;(short[],Function1);generated", - "kotlin.collections;ArraysKt;onEachIndexed;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;onEachIndexed;(double[],Function2);generated", - "kotlin.collections;ArraysKt;onEachIndexed;(float[],Function2);generated", - "kotlin.collections;ArraysKt;onEachIndexed;(int[],Function2);generated", - "kotlin.collections;ArraysKt;onEachIndexed;(long[],Function2);generated", - "kotlin.collections;ArraysKt;onEachIndexed;(short[],Function2);generated", - "kotlin.collections;ArraysKt;partition;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;partition;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;partition;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;partition;(char[],Function1);generated", - "kotlin.collections;ArraysKt;partition;(double[],Function1);generated", - "kotlin.collections;ArraysKt;partition;(float[],Function1);generated", - "kotlin.collections;ArraysKt;partition;(int[],Function1);generated", - "kotlin.collections;ArraysKt;partition;(long[],Function1);generated", - "kotlin.collections;ArraysKt;partition;(short[],Function1);generated", - "kotlin.collections;ArraysKt;plus;(boolean[],Collection);generated", - "kotlin.collections;ArraysKt;plus;(boolean[],boolean);generated", - "kotlin.collections;ArraysKt;plus;(boolean[],boolean[]);generated", - "kotlin.collections;ArraysKt;plus;(double[],Collection);generated", - "kotlin.collections;ArraysKt;plus;(double[],double);generated", - "kotlin.collections;ArraysKt;plus;(double[],double[]);generated", - "kotlin.collections;ArraysKt;plus;(float[],Collection);generated", - "kotlin.collections;ArraysKt;plus;(float[],float);generated", - "kotlin.collections;ArraysKt;plus;(float[],float[]);generated", - "kotlin.collections;ArraysKt;plus;(int[],Collection);generated", - "kotlin.collections;ArraysKt;plus;(int[],int);generated", - "kotlin.collections;ArraysKt;plus;(int[],int[]);generated", - "kotlin.collections;ArraysKt;plus;(long[],Collection);generated", - "kotlin.collections;ArraysKt;plus;(long[],long);generated", - "kotlin.collections;ArraysKt;plus;(long[],long[]);generated", - "kotlin.collections;ArraysKt;plus;(short[],Collection);generated", - "kotlin.collections;ArraysKt;plus;(short[],short);generated", - "kotlin.collections;ArraysKt;plus;(short[],short[]);generated", - "kotlin.collections;ArraysKt;random;(Object[]);generated", - "kotlin.collections;ArraysKt;random;(Object[],Random);generated", - "kotlin.collections;ArraysKt;random;(boolean[]);generated", - "kotlin.collections;ArraysKt;random;(boolean[],Random);generated", - "kotlin.collections;ArraysKt;random;(byte[]);generated", - "kotlin.collections;ArraysKt;random;(byte[],Random);generated", - "kotlin.collections;ArraysKt;random;(char[]);generated", - "kotlin.collections;ArraysKt;random;(char[],Random);generated", - "kotlin.collections;ArraysKt;random;(double[]);generated", - "kotlin.collections;ArraysKt;random;(double[],Random);generated", - "kotlin.collections;ArraysKt;random;(float[]);generated", - "kotlin.collections;ArraysKt;random;(float[],Random);generated", - "kotlin.collections;ArraysKt;random;(int[]);generated", - "kotlin.collections;ArraysKt;random;(int[],Random);generated", - "kotlin.collections;ArraysKt;random;(long[]);generated", - "kotlin.collections;ArraysKt;random;(long[],Random);generated", - "kotlin.collections;ArraysKt;random;(short[]);generated", - "kotlin.collections;ArraysKt;random;(short[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(Object[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(Object[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(boolean[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(boolean[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(byte[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(byte[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(char[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(char[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(double[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(double[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(float[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(float[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(int[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(int[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(long[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(long[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(short[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(short[],Random);generated", - "kotlin.collections;ArraysKt;reduce;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;reduce;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;reduce;(char[],Function2);generated", - "kotlin.collections;ArraysKt;reduce;(double[],Function2);generated", - "kotlin.collections;ArraysKt;reduce;(float[],Function2);generated", - "kotlin.collections;ArraysKt;reduce;(int[],Function2);generated", - "kotlin.collections;ArraysKt;reduce;(long[],Function2);generated", - "kotlin.collections;ArraysKt;reduce;(short[],Function2);generated", - "kotlin.collections;ArraysKt;reduceIndexed;(boolean[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexed;(byte[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexed;(char[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexed;(double[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexed;(float[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexed;(int[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexed;(long[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexed;(short[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexedOrNull;(boolean[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexedOrNull;(byte[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexedOrNull;(char[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexedOrNull;(double[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexedOrNull;(float[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexedOrNull;(int[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexedOrNull;(long[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexedOrNull;(short[],Function3);generated", - "kotlin.collections;ArraysKt;reduceOrNull;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;reduceOrNull;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;reduceOrNull;(char[],Function2);generated", - "kotlin.collections;ArraysKt;reduceOrNull;(double[],Function2);generated", - "kotlin.collections;ArraysKt;reduceOrNull;(float[],Function2);generated", - "kotlin.collections;ArraysKt;reduceOrNull;(int[],Function2);generated", - "kotlin.collections;ArraysKt;reduceOrNull;(long[],Function2);generated", - "kotlin.collections;ArraysKt;reduceOrNull;(short[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(char[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(double[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(float[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(int[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(long[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(short[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(Object[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(boolean[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(byte[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(char[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(double[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(float[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(int[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(long[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(short[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(Object[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(boolean[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(byte[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(char[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(double[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(float[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(int[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(long[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(short[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(char[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(double[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(float[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(int[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(long[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(short[],Function2);generated", - "kotlin.collections;ArraysKt;reverse;(Object[]);generated", - "kotlin.collections;ArraysKt;reverse;(Object[],int,int);generated", - "kotlin.collections;ArraysKt;reverse;(boolean[]);generated", - "kotlin.collections;ArraysKt;reverse;(boolean[],int,int);generated", - "kotlin.collections;ArraysKt;reverse;(byte[]);generated", - "kotlin.collections;ArraysKt;reverse;(byte[],int,int);generated", - "kotlin.collections;ArraysKt;reverse;(char[]);generated", - "kotlin.collections;ArraysKt;reverse;(char[],int,int);generated", - "kotlin.collections;ArraysKt;reverse;(double[]);generated", - "kotlin.collections;ArraysKt;reverse;(double[],int,int);generated", - "kotlin.collections;ArraysKt;reverse;(float[]);generated", - "kotlin.collections;ArraysKt;reverse;(float[],int,int);generated", - "kotlin.collections;ArraysKt;reverse;(int[]);generated", - "kotlin.collections;ArraysKt;reverse;(int[],int,int);generated", - "kotlin.collections;ArraysKt;reverse;(long[]);generated", - "kotlin.collections;ArraysKt;reverse;(long[],int,int);generated", - "kotlin.collections;ArraysKt;reverse;(short[]);generated", - "kotlin.collections;ArraysKt;reverse;(short[],int,int);generated", - "kotlin.collections;ArraysKt;reversed;(boolean[]);generated", - "kotlin.collections;ArraysKt;reversed;(byte[]);generated", - "kotlin.collections;ArraysKt;reversed;(char[]);generated", - "kotlin.collections;ArraysKt;reversed;(double[]);generated", - "kotlin.collections;ArraysKt;reversed;(float[]);generated", - "kotlin.collections;ArraysKt;reversed;(int[]);generated", - "kotlin.collections;ArraysKt;reversed;(long[]);generated", - "kotlin.collections;ArraysKt;reversed;(short[]);generated", - "kotlin.collections;ArraysKt;reversedArray;(boolean[]);generated", - "kotlin.collections;ArraysKt;reversedArray;(double[]);generated", - "kotlin.collections;ArraysKt;reversedArray;(float[]);generated", - "kotlin.collections;ArraysKt;reversedArray;(int[]);generated", - "kotlin.collections;ArraysKt;reversedArray;(long[]);generated", - "kotlin.collections;ArraysKt;reversedArray;(short[]);generated", - "kotlin.collections;ArraysKt;runningReduce;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduce;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduce;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduce;(char[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduce;(double[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduce;(float[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduce;(int[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduce;(long[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduce;(short[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(Object[],Function3);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(boolean[],Function3);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(byte[],Function3);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(char[],Function3);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(double[],Function3);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(float[],Function3);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(int[],Function3);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(long[],Function3);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(short[],Function3);generated", - "kotlin.collections;ArraysKt;shuffle;(Object[]);generated", - "kotlin.collections;ArraysKt;shuffle;(Object[],Random);generated", - "kotlin.collections;ArraysKt;shuffle;(boolean[]);generated", - "kotlin.collections;ArraysKt;shuffle;(boolean[],Random);generated", - "kotlin.collections;ArraysKt;shuffle;(byte[]);generated", - "kotlin.collections;ArraysKt;shuffle;(byte[],Random);generated", - "kotlin.collections;ArraysKt;shuffle;(char[]);generated", - "kotlin.collections;ArraysKt;shuffle;(char[],Random);generated", - "kotlin.collections;ArraysKt;shuffle;(double[]);generated", - "kotlin.collections;ArraysKt;shuffle;(double[],Random);generated", - "kotlin.collections;ArraysKt;shuffle;(float[]);generated", - "kotlin.collections;ArraysKt;shuffle;(float[],Random);generated", - "kotlin.collections;ArraysKt;shuffle;(int[]);generated", - "kotlin.collections;ArraysKt;shuffle;(int[],Random);generated", - "kotlin.collections;ArraysKt;shuffle;(long[]);generated", - "kotlin.collections;ArraysKt;shuffle;(long[],Random);generated", - "kotlin.collections;ArraysKt;shuffle;(short[]);generated", - "kotlin.collections;ArraysKt;shuffle;(short[],Random);generated", - "kotlin.collections;ArraysKt;single;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;single;(boolean[]);generated", - "kotlin.collections;ArraysKt;single;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;single;(byte[]);generated", - "kotlin.collections;ArraysKt;single;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;single;(char[]);generated", - "kotlin.collections;ArraysKt;single;(char[],Function1);generated", - "kotlin.collections;ArraysKt;single;(double[]);generated", - "kotlin.collections;ArraysKt;single;(double[],Function1);generated", - "kotlin.collections;ArraysKt;single;(float[]);generated", - "kotlin.collections;ArraysKt;single;(float[],Function1);generated", - "kotlin.collections;ArraysKt;single;(int[]);generated", - "kotlin.collections;ArraysKt;single;(int[],Function1);generated", - "kotlin.collections;ArraysKt;single;(long[]);generated", - "kotlin.collections;ArraysKt;single;(long[],Function1);generated", - "kotlin.collections;ArraysKt;single;(short[]);generated", - "kotlin.collections;ArraysKt;single;(short[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(boolean[]);generated", - "kotlin.collections;ArraysKt;singleOrNull;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(byte[]);generated", - "kotlin.collections;ArraysKt;singleOrNull;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(char[]);generated", - "kotlin.collections;ArraysKt;singleOrNull;(char[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(double[]);generated", - "kotlin.collections;ArraysKt;singleOrNull;(double[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(float[]);generated", - "kotlin.collections;ArraysKt;singleOrNull;(float[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(int[]);generated", - "kotlin.collections;ArraysKt;singleOrNull;(int[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(long[]);generated", - "kotlin.collections;ArraysKt;singleOrNull;(long[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(short[]);generated", - "kotlin.collections;ArraysKt;singleOrNull;(short[],Function1);generated", - "kotlin.collections;ArraysKt;slice;(Object[],Iterable);generated", - "kotlin.collections;ArraysKt;slice;(boolean[],IntRange);generated", - "kotlin.collections;ArraysKt;slice;(boolean[],Iterable);generated", - "kotlin.collections;ArraysKt;slice;(byte[],IntRange);generated", - "kotlin.collections;ArraysKt;slice;(byte[],Iterable);generated", - "kotlin.collections;ArraysKt;slice;(char[],IntRange);generated", - "kotlin.collections;ArraysKt;slice;(char[],Iterable);generated", - "kotlin.collections;ArraysKt;slice;(double[],IntRange);generated", - "kotlin.collections;ArraysKt;slice;(double[],Iterable);generated", - "kotlin.collections;ArraysKt;slice;(float[],IntRange);generated", - "kotlin.collections;ArraysKt;slice;(float[],Iterable);generated", - "kotlin.collections;ArraysKt;slice;(int[],IntRange);generated", - "kotlin.collections;ArraysKt;slice;(int[],Iterable);generated", - "kotlin.collections;ArraysKt;slice;(long[],IntRange);generated", - "kotlin.collections;ArraysKt;slice;(long[],Iterable);generated", - "kotlin.collections;ArraysKt;slice;(short[],IntRange);generated", - "kotlin.collections;ArraysKt;slice;(short[],Iterable);generated", - "kotlin.collections;ArraysKt;sliceArray;(boolean[],Collection);generated", - "kotlin.collections;ArraysKt;sliceArray;(boolean[],IntRange);generated", - "kotlin.collections;ArraysKt;sliceArray;(byte[],Collection);generated", - "kotlin.collections;ArraysKt;sliceArray;(char[],Collection);generated", - "kotlin.collections;ArraysKt;sliceArray;(double[],Collection);generated", - "kotlin.collections;ArraysKt;sliceArray;(double[],IntRange);generated", - "kotlin.collections;ArraysKt;sliceArray;(float[],Collection);generated", - "kotlin.collections;ArraysKt;sliceArray;(float[],IntRange);generated", - "kotlin.collections;ArraysKt;sliceArray;(int[],Collection);generated", - "kotlin.collections;ArraysKt;sliceArray;(int[],IntRange);generated", - "kotlin.collections;ArraysKt;sliceArray;(long[],Collection);generated", - "kotlin.collections;ArraysKt;sliceArray;(long[],IntRange);generated", - "kotlin.collections;ArraysKt;sliceArray;(short[],Collection);generated", - "kotlin.collections;ArraysKt;sliceArray;(short[],IntRange);generated", - "kotlin.collections;ArraysKt;sort;(Comparable[]);generated", - "kotlin.collections;ArraysKt;sort;(Comparable[],int,int);generated", - "kotlin.collections;ArraysKt;sort;(Object[]);generated", - "kotlin.collections;ArraysKt;sort;(Object[],int,int);generated", - "kotlin.collections;ArraysKt;sort;(byte[]);generated", - "kotlin.collections;ArraysKt;sort;(byte[],int,int);generated", - "kotlin.collections;ArraysKt;sort;(char[]);generated", - "kotlin.collections;ArraysKt;sort;(char[],int,int);generated", - "kotlin.collections;ArraysKt;sort;(double[]);generated", - "kotlin.collections;ArraysKt;sort;(double[],int,int);generated", - "kotlin.collections;ArraysKt;sort;(float[]);generated", - "kotlin.collections;ArraysKt;sort;(float[],int,int);generated", - "kotlin.collections;ArraysKt;sort;(int[]);generated", - "kotlin.collections;ArraysKt;sort;(int[],int,int);generated", - "kotlin.collections;ArraysKt;sort;(long[]);generated", - "kotlin.collections;ArraysKt;sort;(long[],int,int);generated", - "kotlin.collections;ArraysKt;sort;(short[]);generated", - "kotlin.collections;ArraysKt;sort;(short[],int,int);generated", - "kotlin.collections;ArraysKt;sortBy;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sortByDescending;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sortDescending;(Comparable[]);generated", - "kotlin.collections;ArraysKt;sortDescending;(Comparable[],int,int);generated", - "kotlin.collections;ArraysKt;sortDescending;(byte[]);generated", - "kotlin.collections;ArraysKt;sortDescending;(byte[],int,int);generated", - "kotlin.collections;ArraysKt;sortDescending;(char[]);generated", - "kotlin.collections;ArraysKt;sortDescending;(char[],int,int);generated", - "kotlin.collections;ArraysKt;sortDescending;(double[]);generated", - "kotlin.collections;ArraysKt;sortDescending;(double[],int,int);generated", - "kotlin.collections;ArraysKt;sortDescending;(float[]);generated", - "kotlin.collections;ArraysKt;sortDescending;(float[],int,int);generated", - "kotlin.collections;ArraysKt;sortDescending;(int[]);generated", - "kotlin.collections;ArraysKt;sortDescending;(int[],int,int);generated", - "kotlin.collections;ArraysKt;sortDescending;(long[]);generated", - "kotlin.collections;ArraysKt;sortDescending;(long[],int,int);generated", - "kotlin.collections;ArraysKt;sortDescending;(short[]);generated", - "kotlin.collections;ArraysKt;sortDescending;(short[],int,int);generated", - "kotlin.collections;ArraysKt;sortWith;(Object[],Comparator);generated", - "kotlin.collections;ArraysKt;sortWith;(Object[],Comparator,int,int);generated", - "kotlin.collections;ArraysKt;sorted;(byte[]);generated", - "kotlin.collections;ArraysKt;sorted;(char[]);generated", - "kotlin.collections;ArraysKt;sorted;(double[]);generated", - "kotlin.collections;ArraysKt;sorted;(float[]);generated", - "kotlin.collections;ArraysKt;sorted;(int[]);generated", - "kotlin.collections;ArraysKt;sorted;(long[]);generated", - "kotlin.collections;ArraysKt;sorted;(short[]);generated", - "kotlin.collections;ArraysKt;sortedArray;(double[]);generated", - "kotlin.collections;ArraysKt;sortedArray;(float[]);generated", - "kotlin.collections;ArraysKt;sortedArray;(int[]);generated", - "kotlin.collections;ArraysKt;sortedArray;(long[]);generated", - "kotlin.collections;ArraysKt;sortedArray;(short[]);generated", - "kotlin.collections;ArraysKt;sortedArrayDescending;(double[]);generated", - "kotlin.collections;ArraysKt;sortedArrayDescending;(float[]);generated", - "kotlin.collections;ArraysKt;sortedArrayDescending;(int[]);generated", - "kotlin.collections;ArraysKt;sortedArrayDescending;(long[]);generated", - "kotlin.collections;ArraysKt;sortedArrayDescending;(short[]);generated", - "kotlin.collections;ArraysKt;sortedBy;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sortedBy;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sortedBy;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sortedBy;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sortedBy;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sortedBy;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sortedBy;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sortedBy;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sortedByDescending;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sortedByDescending;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sortedByDescending;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sortedByDescending;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sortedByDescending;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sortedByDescending;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sortedByDescending;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sortedByDescending;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sortedDescending;(byte[]);generated", - "kotlin.collections;ArraysKt;sortedDescending;(char[]);generated", - "kotlin.collections;ArraysKt;sortedDescending;(double[]);generated", - "kotlin.collections;ArraysKt;sortedDescending;(float[]);generated", - "kotlin.collections;ArraysKt;sortedDescending;(int[]);generated", - "kotlin.collections;ArraysKt;sortedDescending;(long[]);generated", - "kotlin.collections;ArraysKt;sortedDescending;(short[]);generated", - "kotlin.collections;ArraysKt;sortedWith;(boolean[],Comparator);generated", - "kotlin.collections;ArraysKt;sortedWith;(byte[],Comparator);generated", - "kotlin.collections;ArraysKt;sortedWith;(char[],Comparator);generated", - "kotlin.collections;ArraysKt;sortedWith;(double[],Comparator);generated", - "kotlin.collections;ArraysKt;sortedWith;(float[],Comparator);generated", - "kotlin.collections;ArraysKt;sortedWith;(int[],Comparator);generated", - "kotlin.collections;ArraysKt;sortedWith;(long[],Comparator);generated", - "kotlin.collections;ArraysKt;sortedWith;(short[],Comparator);generated", - "kotlin.collections;ArraysKt;subtract;(Object[],Iterable);generated", - "kotlin.collections;ArraysKt;subtract;(boolean[],Iterable);generated", - "kotlin.collections;ArraysKt;subtract;(byte[],Iterable);generated", - "kotlin.collections;ArraysKt;subtract;(char[],Iterable);generated", - "kotlin.collections;ArraysKt;subtract;(double[],Iterable);generated", - "kotlin.collections;ArraysKt;subtract;(float[],Iterable);generated", - "kotlin.collections;ArraysKt;subtract;(int[],Iterable);generated", - "kotlin.collections;ArraysKt;subtract;(long[],Iterable);generated", - "kotlin.collections;ArraysKt;subtract;(short[],Iterable);generated", - "kotlin.collections;ArraysKt;sum;(byte[]);generated", - "kotlin.collections;ArraysKt;sum;(double[]);generated", - "kotlin.collections;ArraysKt;sum;(float[]);generated", - "kotlin.collections;ArraysKt;sum;(int[]);generated", - "kotlin.collections;ArraysKt;sum;(long[]);generated", - "kotlin.collections;ArraysKt;sum;(short[]);generated", - "kotlin.collections;ArraysKt;sumBy;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumBy;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumBy;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumBy;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumBy;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumBy;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumBy;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumBy;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumBy;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfByte;(Byte[]);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(Double[]);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfFloat;(Float[]);generated", - "kotlin.collections;ArraysKt;sumOfInt;(Integer[]);generated", - "kotlin.collections;ArraysKt;sumOfInt;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfInt;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfInt;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfInt;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfInt;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfInt;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfInt;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfInt;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfInt;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(Long[]);generated", - "kotlin.collections;ArraysKt;sumOfLong;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfShort;(Short[]);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(short[],Function1);generated", - "kotlin.collections;ArraysKt;take;(boolean[],int);generated", - "kotlin.collections;ArraysKt;take;(byte[],int);generated", - "kotlin.collections;ArraysKt;take;(char[],int);generated", - "kotlin.collections;ArraysKt;take;(double[],int);generated", - "kotlin.collections;ArraysKt;take;(float[],int);generated", - "kotlin.collections;ArraysKt;take;(int[],int);generated", - "kotlin.collections;ArraysKt;take;(long[],int);generated", - "kotlin.collections;ArraysKt;take;(short[],int);generated", - "kotlin.collections;ArraysKt;takeLast;(boolean[],int);generated", - "kotlin.collections;ArraysKt;takeLast;(byte[],int);generated", - "kotlin.collections;ArraysKt;takeLast;(char[],int);generated", - "kotlin.collections;ArraysKt;takeLast;(double[],int);generated", - "kotlin.collections;ArraysKt;takeLast;(float[],int);generated", - "kotlin.collections;ArraysKt;takeLast;(int[],int);generated", - "kotlin.collections;ArraysKt;takeLast;(long[],int);generated", - "kotlin.collections;ArraysKt;takeLast;(short[],int);generated", - "kotlin.collections;ArraysKt;takeLastWhile;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;takeLastWhile;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;takeLastWhile;(char[],Function1);generated", - "kotlin.collections;ArraysKt;takeLastWhile;(double[],Function1);generated", - "kotlin.collections;ArraysKt;takeLastWhile;(float[],Function1);generated", - "kotlin.collections;ArraysKt;takeLastWhile;(int[],Function1);generated", - "kotlin.collections;ArraysKt;takeLastWhile;(long[],Function1);generated", - "kotlin.collections;ArraysKt;takeLastWhile;(short[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(char[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(double[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(float[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(int[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(long[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(short[],Function1);generated", - "kotlin.collections;ArraysKt;toBooleanArray;(Boolean[]);generated", - "kotlin.collections;ArraysKt;toByteArray;(Byte[]);generated", - "kotlin.collections;ArraysKt;toCharArray;(Character[]);generated", - "kotlin.collections;ArraysKt;toDoubleArray;(Double[]);generated", - "kotlin.collections;ArraysKt;toFloatArray;(Float[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(Object[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(boolean[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(byte[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(char[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(double[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(float[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(int[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(long[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(short[]);generated", - "kotlin.collections;ArraysKt;toIntArray;(Integer[]);generated", - "kotlin.collections;ArraysKt;toList;(boolean[]);generated", - "kotlin.collections;ArraysKt;toList;(byte[]);generated", - "kotlin.collections;ArraysKt;toList;(char[]);generated", - "kotlin.collections;ArraysKt;toList;(double[]);generated", - "kotlin.collections;ArraysKt;toList;(float[]);generated", - "kotlin.collections;ArraysKt;toList;(int[]);generated", - "kotlin.collections;ArraysKt;toList;(long[]);generated", - "kotlin.collections;ArraysKt;toList;(short[]);generated", - "kotlin.collections;ArraysKt;toLongArray;(Long[]);generated", - "kotlin.collections;ArraysKt;toMutableList;(boolean[]);generated", - "kotlin.collections;ArraysKt;toMutableList;(byte[]);generated", - "kotlin.collections;ArraysKt;toMutableList;(char[]);generated", - "kotlin.collections;ArraysKt;toMutableList;(double[]);generated", - "kotlin.collections;ArraysKt;toMutableList;(float[]);generated", - "kotlin.collections;ArraysKt;toMutableList;(int[]);generated", - "kotlin.collections;ArraysKt;toMutableList;(long[]);generated", - "kotlin.collections;ArraysKt;toMutableList;(short[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(Object[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(boolean[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(byte[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(char[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(double[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(float[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(int[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(long[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(short[]);generated", - "kotlin.collections;ArraysKt;toSet;(boolean[]);generated", - "kotlin.collections;ArraysKt;toSet;(byte[]);generated", - "kotlin.collections;ArraysKt;toSet;(char[]);generated", - "kotlin.collections;ArraysKt;toSet;(double[]);generated", - "kotlin.collections;ArraysKt;toSet;(float[]);generated", - "kotlin.collections;ArraysKt;toSet;(int[]);generated", - "kotlin.collections;ArraysKt;toSet;(long[]);generated", - "kotlin.collections;ArraysKt;toSet;(short[]);generated", - "kotlin.collections;ArraysKt;toShortArray;(Short[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(Comparable[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(Object[],Comparator);generated", - "kotlin.collections;ArraysKt;toSortedSet;(boolean[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(byte[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(char[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(double[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(float[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(int[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(long[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(short[]);generated", - "kotlin.collections;ArraysKt;toTypedArray;(boolean[]);generated", - "kotlin.collections;ArraysKt;toTypedArray;(byte[]);generated", - "kotlin.collections;ArraysKt;toTypedArray;(char[]);generated", - "kotlin.collections;ArraysKt;toTypedArray;(double[]);generated", - "kotlin.collections;ArraysKt;toTypedArray;(float[]);generated", - "kotlin.collections;ArraysKt;toTypedArray;(int[]);generated", - "kotlin.collections;ArraysKt;toTypedArray;(long[]);generated", - "kotlin.collections;ArraysKt;toTypedArray;(short[]);generated", - "kotlin.collections;ArraysKt;union;(boolean[],Iterable);generated", - "kotlin.collections;ArraysKt;union;(double[],Iterable);generated", - "kotlin.collections;ArraysKt;union;(float[],Iterable);generated", - "kotlin.collections;ArraysKt;union;(int[],Iterable);generated", - "kotlin.collections;ArraysKt;union;(long[],Iterable);generated", - "kotlin.collections;ArraysKt;union;(short[],Iterable);generated", - "kotlin.collections;ArraysKt;unzip;(Pair[]);generated", - "kotlin.collections;ArraysKt;withIndex;(Object[]);generated", - "kotlin.collections;ArraysKt;withIndex;(boolean[]);generated", - "kotlin.collections;ArraysKt;withIndex;(byte[]);generated", - "kotlin.collections;ArraysKt;withIndex;(char[]);generated", - "kotlin.collections;ArraysKt;withIndex;(double[]);generated", - "kotlin.collections;ArraysKt;withIndex;(float[]);generated", - "kotlin.collections;ArraysKt;withIndex;(int[]);generated", - "kotlin.collections;ArraysKt;withIndex;(long[]);generated", - "kotlin.collections;ArraysKt;withIndex;(short[]);generated", - "kotlin.collections;ArraysKt;zip;(boolean[],Iterable);generated", - "kotlin.collections;ArraysKt;zip;(boolean[],Iterable,Function2);generated", - "kotlin.collections;ArraysKt;zip;(boolean[],Object[]);generated", - "kotlin.collections;ArraysKt;zip;(boolean[],Object[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(boolean[],boolean[]);generated", - "kotlin.collections;ArraysKt;zip;(boolean[],boolean[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(byte[],Iterable);generated", - "kotlin.collections;ArraysKt;zip;(byte[],Iterable,Function2);generated", - "kotlin.collections;ArraysKt;zip;(byte[],Object[]);generated", - "kotlin.collections;ArraysKt;zip;(byte[],Object[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(byte[],byte[]);generated", - "kotlin.collections;ArraysKt;zip;(byte[],byte[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(char[],Iterable);generated", - "kotlin.collections;ArraysKt;zip;(char[],Iterable,Function2);generated", - "kotlin.collections;ArraysKt;zip;(char[],Object[]);generated", - "kotlin.collections;ArraysKt;zip;(char[],Object[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(char[],char[]);generated", - "kotlin.collections;ArraysKt;zip;(char[],char[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(double[],Iterable);generated", - "kotlin.collections;ArraysKt;zip;(double[],Iterable,Function2);generated", - "kotlin.collections;ArraysKt;zip;(double[],Object[]);generated", - "kotlin.collections;ArraysKt;zip;(double[],Object[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(double[],double[]);generated", - "kotlin.collections;ArraysKt;zip;(double[],double[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(float[],Iterable);generated", - "kotlin.collections;ArraysKt;zip;(float[],Iterable,Function2);generated", - "kotlin.collections;ArraysKt;zip;(float[],Object[]);generated", - "kotlin.collections;ArraysKt;zip;(float[],Object[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(float[],float[]);generated", - "kotlin.collections;ArraysKt;zip;(float[],float[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(int[],Iterable);generated", - "kotlin.collections;ArraysKt;zip;(int[],Iterable,Function2);generated", - "kotlin.collections;ArraysKt;zip;(int[],Object[]);generated", - "kotlin.collections;ArraysKt;zip;(int[],Object[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(int[],int[]);generated", - "kotlin.collections;ArraysKt;zip;(int[],int[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(long[],Iterable);generated", - "kotlin.collections;ArraysKt;zip;(long[],Iterable,Function2);generated", - "kotlin.collections;ArraysKt;zip;(long[],Object[]);generated", - "kotlin.collections;ArraysKt;zip;(long[],Object[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(long[],long[]);generated", - "kotlin.collections;ArraysKt;zip;(long[],long[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(short[],Iterable);generated", - "kotlin.collections;ArraysKt;zip;(short[],Iterable,Function2);generated", - "kotlin.collections;ArraysKt;zip;(short[],Object[]);generated", - "kotlin.collections;ArraysKt;zip;(short[],Object[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(short[],short[]);generated", - "kotlin.collections;ArraysKt;zip;(short[],short[],Function2);generated", - "kotlin.collections;BooleanIterator;BooleanIterator;();generated", - "kotlin.collections;BooleanIterator;nextBoolean;();generated", - "kotlin.collections;ByteIterator;ByteIterator;();generated", - "kotlin.collections;ByteIterator;nextByte;();generated", - "kotlin.collections;CharIterator;CharIterator;();generated", - "kotlin.collections;CharIterator;nextChar;();generated", - "kotlin.collections;CollectionsHKt;eachCount;(Grouping);generated", - "kotlin.collections;CollectionsHKt;fill;(List,Object);generated", - "kotlin.collections;CollectionsHKt;orEmpty;(Object[]);generated", - "kotlin.collections;CollectionsHKt;shuffle;(List);generated", - "kotlin.collections;CollectionsHKt;shuffled;(Iterable);generated", - "kotlin.collections;CollectionsHKt;sort;(List);generated", - "kotlin.collections;CollectionsHKt;sortWith;(List,Comparator);generated", - "kotlin.collections;CollectionsHKt;toTypedArray;(Collection);generated", - "kotlin.collections;CollectionsKt;Iterable;(Function0);generated", - "kotlin.collections;CollectionsKt;List;(int,Function1);generated", - "kotlin.collections;CollectionsKt;MutableList;(int,Function1);generated", - "kotlin.collections;CollectionsKt;all;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;any;(Iterable);generated", - "kotlin.collections;CollectionsKt;any;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;arrayListOf;();generated", - "kotlin.collections;CollectionsKt;asSequence;(Iterable);generated", - "kotlin.collections;CollectionsKt;averageOfByte;(Iterable);generated", - "kotlin.collections;CollectionsKt;averageOfDouble;(Iterable);generated", - "kotlin.collections;CollectionsKt;averageOfFloat;(Iterable);generated", - "kotlin.collections;CollectionsKt;averageOfInt;(Iterable);generated", - "kotlin.collections;CollectionsKt;averageOfLong;(Iterable);generated", - "kotlin.collections;CollectionsKt;averageOfShort;(Iterable);generated", - "kotlin.collections;CollectionsKt;binarySearch;(List,Comparable,int,int);generated", - "kotlin.collections;CollectionsKt;binarySearch;(List,Object,Comparator,int,int);generated", - "kotlin.collections;CollectionsKt;binarySearch;(List,int,int,Function1);generated", - "kotlin.collections;CollectionsKt;binarySearchBy;(List,Comparable,int,int,Function1);generated", - "kotlin.collections;CollectionsKt;buildList;(Function1);generated", - "kotlin.collections;CollectionsKt;buildList;(int,Function1);generated", - "kotlin.collections;CollectionsKt;chunked;(Iterable,int);generated", - "kotlin.collections;CollectionsKt;chunked;(Iterable,int,Function1);generated", - "kotlin.collections;CollectionsKt;contains;(Iterable,Object);generated", - "kotlin.collections;CollectionsKt;containsAll;(Collection,Collection);generated", - "kotlin.collections;CollectionsKt;count;(Collection);generated", - "kotlin.collections;CollectionsKt;count;(Iterable);generated", - "kotlin.collections;CollectionsKt;count;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;emptyList;();generated", - "kotlin.collections;CollectionsKt;filterIndexed;(Iterable,Function2);generated", - "kotlin.collections;CollectionsKt;flatMap;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;flatMapIndexedIterable;(Iterable,Function2);generated", - "kotlin.collections;CollectionsKt;flatMapIndexedSequence;(Iterable,Function2);generated", - "kotlin.collections;CollectionsKt;flatMapSequence;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;forEach;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;forEach;(Iterator,Function1);generated", - "kotlin.collections;CollectionsKt;forEachIndexed;(Iterable,Function2);generated", - "kotlin.collections;CollectionsKt;getIndices;(Collection);generated", - "kotlin.collections;CollectionsKt;getLastIndex;(List);generated", - "kotlin.collections;CollectionsKt;groupBy;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;groupBy;(Iterable,Function1,Function1);generated", - "kotlin.collections;CollectionsKt;groupingBy;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;indexOf;(Iterable,Object);generated", - "kotlin.collections;CollectionsKt;indexOf;(List,Object);generated", - "kotlin.collections;CollectionsKt;indexOfFirst;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;indexOfFirst;(List,Function1);generated", - "kotlin.collections;CollectionsKt;indexOfLast;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;indexOfLast;(List,Function1);generated", - "kotlin.collections;CollectionsKt;isNotEmpty;(Collection);generated", - "kotlin.collections;CollectionsKt;isNullOrEmpty;(Collection);generated", - "kotlin.collections;CollectionsKt;iterator;(Enumeration);generated", - "kotlin.collections;CollectionsKt;lastIndexOf;(Iterable,Object);generated", - "kotlin.collections;CollectionsKt;lastIndexOf;(List,Object);generated", - "kotlin.collections;CollectionsKt;listOf;();generated", - "kotlin.collections;CollectionsKt;listOfNotNull;(Object[]);generated", - "kotlin.collections;CollectionsKt;mapIndexed;(Iterable,Function2);generated", - "kotlin.collections;CollectionsKt;mapIndexedNotNull;(Iterable,Function2);generated", - "kotlin.collections;CollectionsKt;mapNotNull;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;max;(Iterable);generated", - "kotlin.collections;CollectionsKt;maxOf;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;maxOfOrNull;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;maxOrNull;(Iterable);generated", - "kotlin.collections;CollectionsKt;maxOrThrow;(Iterable);generated", - "kotlin.collections;CollectionsKt;min;(Iterable);generated", - "kotlin.collections;CollectionsKt;minOf;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;minOfOrNull;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;minOrNull;(Iterable);generated", - "kotlin.collections;CollectionsKt;minOrThrow;(Iterable);generated", - "kotlin.collections;CollectionsKt;minusAssign;(Collection,Iterable);generated", - "kotlin.collections;CollectionsKt;minusAssign;(Collection,Object);generated", - "kotlin.collections;CollectionsKt;minusAssign;(Collection,Object[]);generated", - "kotlin.collections;CollectionsKt;minusAssign;(Collection,Sequence);generated", - "kotlin.collections;CollectionsKt;mutableListOf;();generated", - "kotlin.collections;CollectionsKt;none;(Iterable);generated", - "kotlin.collections;CollectionsKt;none;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;remove;(Collection,Object);generated", - "kotlin.collections;CollectionsKt;removeAll;(Collection,Collection);generated", - "kotlin.collections;CollectionsKt;removeAll;(Collection,Iterable);generated", - "kotlin.collections;CollectionsKt;removeAll;(Collection,Object[]);generated", - "kotlin.collections;CollectionsKt;removeAll;(Collection,Sequence);generated", - "kotlin.collections;CollectionsKt;removeAll;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;removeAll;(List,Function1);generated", - "kotlin.collections;CollectionsKt;retainAll;(Collection,Collection);generated", - "kotlin.collections;CollectionsKt;retainAll;(Collection,Iterable);generated", - "kotlin.collections;CollectionsKt;retainAll;(Collection,Object[]);generated", - "kotlin.collections;CollectionsKt;retainAll;(Collection,Sequence);generated", - "kotlin.collections;CollectionsKt;retainAll;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;retainAll;(List,Function1);generated", - "kotlin.collections;CollectionsKt;reverse;(List);generated", - "kotlin.collections;CollectionsKt;runningReduce;(Iterable,Function2);generated", - "kotlin.collections;CollectionsKt;runningReduceIndexed;(Iterable,Function3);generated", - "kotlin.collections;CollectionsKt;shuffle;(List);generated", - "kotlin.collections;CollectionsKt;shuffle;(List,Random);generated", - "kotlin.collections;CollectionsKt;sort;(List);generated", - "kotlin.collections;CollectionsKt;sort;(List,Comparator);generated", - "kotlin.collections;CollectionsKt;sort;(List,Function2);generated", - "kotlin.collections;CollectionsKt;sortBy;(List,Function1);generated", - "kotlin.collections;CollectionsKt;sortByDescending;(List,Function1);generated", - "kotlin.collections;CollectionsKt;sortDescending;(List);generated", - "kotlin.collections;CollectionsKt;sortWith;(List,Comparator);generated", - "kotlin.collections;CollectionsKt;sumBy;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;sumByDouble;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;sumOfBigDecimal;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;sumOfBigInteger;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;sumOfByte;(Iterable);generated", - "kotlin.collections;CollectionsKt;sumOfDouble;(Iterable);generated", - "kotlin.collections;CollectionsKt;sumOfDouble;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;sumOfFloat;(Iterable);generated", - "kotlin.collections;CollectionsKt;sumOfInt;(Iterable);generated", - "kotlin.collections;CollectionsKt;sumOfInt;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;sumOfLong;(Iterable);generated", - "kotlin.collections;CollectionsKt;sumOfLong;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;sumOfShort;(Iterable);generated", - "kotlin.collections;CollectionsKt;sumOfUInt;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;sumOfULong;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;toBooleanArray;(Collection);generated", - "kotlin.collections;CollectionsKt;toByteArray;(Collection);generated", - "kotlin.collections;CollectionsKt;toCharArray;(Collection);generated", - "kotlin.collections;CollectionsKt;toDoubleArray;(Collection);generated", - "kotlin.collections;CollectionsKt;toFloatArray;(Collection);generated", - "kotlin.collections;CollectionsKt;toIntArray;(Collection);generated", - "kotlin.collections;CollectionsKt;toLongArray;(Collection);generated", - "kotlin.collections;CollectionsKt;toShortArray;(Collection);generated", - "kotlin.collections;CollectionsKt;windowed;(Iterable,int,int,boolean);generated", - "kotlin.collections;CollectionsKt;windowed;(Iterable,int,int,boolean,Function1);generated", - "kotlin.collections;CollectionsKt;withIndex;(Iterable);generated", - "kotlin.collections;DoubleIterator;DoubleIterator;();generated", - "kotlin.collections;DoubleIterator;nextDouble;();generated", - "kotlin.collections;FloatIterator;FloatIterator;();generated", - "kotlin.collections;FloatIterator;nextFloat;();generated", - "kotlin.collections;Grouping;keyOf;(Object);generated", - "kotlin.collections;Grouping;sourceIterator;();generated", - "kotlin.collections;GroupingKt;aggregate;(Grouping,Function4);generated", - "kotlin.collections;GroupingKt;eachCount;(Grouping);generated", - "kotlin.collections;GroupingKt;fold;(Grouping,Function2,Function3);generated", - "kotlin.collections;GroupingKt;fold;(Grouping,Object,Function2);generated", - "kotlin.collections;GroupingKt;reduce;(Grouping,Function3);generated", - "kotlin.collections;HashMap;HashMap;();generated", - "kotlin.collections;HashMap;HashMap;(Map);generated", - "kotlin.collections;HashMap;HashMap;(int);generated", - "kotlin.collections;HashMap;HashMap;(int,float);generated", - "kotlin.collections;HashSet;HashSet;();generated", - "kotlin.collections;HashSet;HashSet;(Collection);generated", - "kotlin.collections;HashSet;HashSet;(int);generated", - "kotlin.collections;HashSet;HashSet;(int,float);generated", - "kotlin.collections;IndexedValue;component1;();generated", - "kotlin.collections;IndexedValue;equals;(Object);generated", - "kotlin.collections;IndexedValue;getIndex;();generated", - "kotlin.collections;IndexedValue;hashCode;();generated", - "kotlin.collections;IntIterator;IntIterator;();generated", - "kotlin.collections;IntIterator;nextInt;();generated", - "kotlin.collections;LinkedHashMap;LinkedHashMap;();generated", - "kotlin.collections;LinkedHashMap;LinkedHashMap;(Map);generated", - "kotlin.collections;LinkedHashMap;LinkedHashMap;(int);generated", - "kotlin.collections;LinkedHashMap;LinkedHashMap;(int,float);generated", - "kotlin.collections;LinkedHashSet;LinkedHashSet;();generated", - "kotlin.collections;LinkedHashSet;LinkedHashSet;(Collection);generated", - "kotlin.collections;LinkedHashSet;LinkedHashSet;(int);generated", - "kotlin.collections;LinkedHashSet;LinkedHashSet;(int,float);generated", - "kotlin.collections;LongIterator;LongIterator;();generated", - "kotlin.collections;LongIterator;nextLong;();generated", - "kotlin.collections;MapsKt;all;(Map,Function1);generated", - "kotlin.collections;MapsKt;any;(Map);generated", - "kotlin.collections;MapsKt;any;(Map,Function1);generated", - "kotlin.collections;MapsKt;asSequence;(Map);generated", - "kotlin.collections;MapsKt;buildMap;(Function1);generated", - "kotlin.collections;MapsKt;buildMap;(int,Function1);generated", - "kotlin.collections;MapsKt;contains;(Map,Object);generated", - "kotlin.collections;MapsKt;containsKey;(Map,Object);generated", - "kotlin.collections;MapsKt;containsValue;(Map,Object);generated", - "kotlin.collections;MapsKt;count;(Map);generated", - "kotlin.collections;MapsKt;count;(Map,Function1);generated", - "kotlin.collections;MapsKt;emptyMap;();generated", - "kotlin.collections;MapsKt;flatMap;(Map,Function1);generated", - "kotlin.collections;MapsKt;flatMapSequence;(Map,Function1);generated", - "kotlin.collections;MapsKt;forEach;(Map,Function1);generated", - "kotlin.collections;MapsKt;hashMapOf;();generated", - "kotlin.collections;MapsKt;hashMapOf;(Pair[]);generated", - "kotlin.collections;MapsKt;isNotEmpty;(Map);generated", - "kotlin.collections;MapsKt;isNullOrEmpty;(Map);generated", - "kotlin.collections;MapsKt;linkedMapOf;();generated", - "kotlin.collections;MapsKt;linkedMapOf;(Pair[]);generated", - "kotlin.collections;MapsKt;mapNotNull;(Map,Function1);generated", - "kotlin.collections;MapsKt;mapOf;();generated", - "kotlin.collections;MapsKt;mapOf;(Pair[]);generated", - "kotlin.collections;MapsKt;maxOf;(Map,Function1);generated", - "kotlin.collections;MapsKt;maxOfOrNull;(Map,Function1);generated", - "kotlin.collections;MapsKt;minOf;(Map,Function1);generated", - "kotlin.collections;MapsKt;minOfOrNull;(Map,Function1);generated", - "kotlin.collections;MapsKt;minusAssign;(Map,Iterable);generated", - "kotlin.collections;MapsKt;minusAssign;(Map,Object);generated", - "kotlin.collections;MapsKt;minusAssign;(Map,Object[]);generated", - "kotlin.collections;MapsKt;minusAssign;(Map,Sequence);generated", - "kotlin.collections;MapsKt;mutableMapOf;();generated", - "kotlin.collections;MapsKt;mutableMapOf;(Pair[]);generated", - "kotlin.collections;MapsKt;none;(Map);generated", - "kotlin.collections;MapsKt;none;(Map,Function1);generated", - "kotlin.collections;MapsKt;plusAssign;(Map,Pair[]);generated", - "kotlin.collections;MapsKt;putAll;(Map,Pair[]);generated", - "kotlin.collections;MapsKt;sortedMapOf;(Comparator,Pair[]);generated", - "kotlin.collections;MapsKt;sortedMapOf;(Pair[]);generated", - "kotlin.collections;MapsKt;toMap;(Sequence);generated", - "kotlin.collections;MapsKt;toProperties;(Map);generated", - "kotlin.collections;MapsKt;toSortedMap;(Map,Comparator);generated", - "kotlin.collections;SetsKt;buildSet;(Function1);generated", - "kotlin.collections;SetsKt;buildSet;(int,Function1);generated", - "kotlin.collections;SetsKt;emptySet;();generated", - "kotlin.collections;SetsKt;hashSetOf;();generated", - "kotlin.collections;SetsKt;hashSetOf;(Object[]);generated", - "kotlin.collections;SetsKt;linkedSetOf;();generated", - "kotlin.collections;SetsKt;linkedSetOf;(Object[]);generated", - "kotlin.collections;SetsKt;mutableSetOf;();generated", - "kotlin.collections;SetsKt;mutableSetOf;(Object[]);generated", - "kotlin.collections;SetsKt;setOf;();generated", - "kotlin.collections;SetsKt;setOfNotNull;(Object[]);generated", - "kotlin.collections;SetsKt;sortedSetOf;(Comparator,Object[]);generated", - "kotlin.collections;SetsKt;sortedSetOf;(Object[]);generated", - "kotlin.collections;ShortIterator;ShortIterator;();generated", - "kotlin.collections;ShortIterator;nextShort;();generated", - "kotlin.collections;UArraysKt;all;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;all;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;all;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;all;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;any;(UByteArray);generated", - "kotlin.collections;UArraysKt;any;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;any;(UIntArray);generated", - "kotlin.collections;UArraysKt;any;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;any;(ULongArray);generated", - "kotlin.collections;UArraysKt;any;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;any;(UShortArray);generated", - "kotlin.collections;UArraysKt;any;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;asIntArray;(UIntArray);generated", - "kotlin.collections;UArraysKt;asList;(UByteArray);generated", - "kotlin.collections;UArraysKt;asList;(UIntArray);generated", - "kotlin.collections;UArraysKt;asList;(ULongArray);generated", - "kotlin.collections;UArraysKt;asList;(UShortArray);generated", - "kotlin.collections;UArraysKt;asLongArray;(ULongArray);generated", - "kotlin.collections;UArraysKt;asShortArray;(UShortArray);generated", - "kotlin.collections;UArraysKt;asUIntArray;(int[]);generated", - "kotlin.collections;UArraysKt;asULongArray;(long[]);generated", - "kotlin.collections;UArraysKt;asUShortArray;(short[]);generated", - "kotlin.collections;UArraysKt;associateWith;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;associateWith;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;associateWith;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;associateWith;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;binarySearch;(UByteArray,byte,int,int);generated", - "kotlin.collections;UArraysKt;binarySearch;(UIntArray,int,int,int);generated", - "kotlin.collections;UArraysKt;binarySearch;(ULongArray,long,int,int);generated", - "kotlin.collections;UArraysKt;binarySearch;(UShortArray,short,int,int);generated", - "kotlin.collections;UArraysKt;component1;(UByteArray);generated", - "kotlin.collections;UArraysKt;component1;(UIntArray);generated", - "kotlin.collections;UArraysKt;component1;(ULongArray);generated", - "kotlin.collections;UArraysKt;component1;(UShortArray);generated", - "kotlin.collections;UArraysKt;component2;(UByteArray);generated", - "kotlin.collections;UArraysKt;component2;(UIntArray);generated", - "kotlin.collections;UArraysKt;component2;(ULongArray);generated", - "kotlin.collections;UArraysKt;component2;(UShortArray);generated", - "kotlin.collections;UArraysKt;component3;(UByteArray);generated", - "kotlin.collections;UArraysKt;component3;(UIntArray);generated", - "kotlin.collections;UArraysKt;component3;(ULongArray);generated", - "kotlin.collections;UArraysKt;component3;(UShortArray);generated", - "kotlin.collections;UArraysKt;component4;(UByteArray);generated", - "kotlin.collections;UArraysKt;component4;(UIntArray);generated", - "kotlin.collections;UArraysKt;component4;(ULongArray);generated", - "kotlin.collections;UArraysKt;component4;(UShortArray);generated", - "kotlin.collections;UArraysKt;component5;(UByteArray);generated", - "kotlin.collections;UArraysKt;component5;(UIntArray);generated", - "kotlin.collections;UArraysKt;component5;(ULongArray);generated", - "kotlin.collections;UArraysKt;component5;(UShortArray);generated", - "kotlin.collections;UArraysKt;contentEquals;(UByteArray,UByteArray);generated", - "kotlin.collections;UArraysKt;contentEquals;(UIntArray,UIntArray);generated", - "kotlin.collections;UArraysKt;contentEquals;(ULongArray,ULongArray);generated", - "kotlin.collections;UArraysKt;contentEquals;(UShortArray,UShortArray);generated", - "kotlin.collections;UArraysKt;contentHashCode;(UByteArray);generated", - "kotlin.collections;UArraysKt;contentHashCode;(UIntArray);generated", - "kotlin.collections;UArraysKt;contentHashCode;(ULongArray);generated", - "kotlin.collections;UArraysKt;contentHashCode;(UShortArray);generated", - "kotlin.collections;UArraysKt;copyOf;(UIntArray);generated", - "kotlin.collections;UArraysKt;copyOf;(UIntArray,int);generated", - "kotlin.collections;UArraysKt;copyOf;(ULongArray);generated", - "kotlin.collections;UArraysKt;copyOf;(ULongArray,int);generated", - "kotlin.collections;UArraysKt;copyOf;(UShortArray);generated", - "kotlin.collections;UArraysKt;copyOf;(UShortArray,int);generated", - "kotlin.collections;UArraysKt;copyOfRange;(UIntArray,int,int);generated", - "kotlin.collections;UArraysKt;copyOfRange;(ULongArray,int,int);generated", - "kotlin.collections;UArraysKt;copyOfRange;(UShortArray,int,int);generated", - "kotlin.collections;UArraysKt;count;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;count;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;count;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;count;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;dropWhile;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;dropWhile;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;dropWhile;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;dropWhile;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;elementAt;(UByteArray,int);generated", - "kotlin.collections;UArraysKt;elementAt;(UIntArray,int);generated", - "kotlin.collections;UArraysKt;elementAt;(ULongArray,int);generated", - "kotlin.collections;UArraysKt;elementAt;(UShortArray,int);generated", - "kotlin.collections;UArraysKt;elementAtOrElse;(UByteArray,int,Function1);generated", - "kotlin.collections;UArraysKt;elementAtOrElse;(UIntArray,int,Function1);generated", - "kotlin.collections;UArraysKt;elementAtOrElse;(ULongArray,int,Function1);generated", - "kotlin.collections;UArraysKt;elementAtOrElse;(UShortArray,int,Function1);generated", - "kotlin.collections;UArraysKt;elementAtOrNull;(UByteArray,int);generated", - "kotlin.collections;UArraysKt;elementAtOrNull;(UIntArray,int);generated", - "kotlin.collections;UArraysKt;elementAtOrNull;(ULongArray,int);generated", - "kotlin.collections;UArraysKt;elementAtOrNull;(UShortArray,int);generated", - "kotlin.collections;UArraysKt;fill;(UByteArray,byte,int,int);generated", - "kotlin.collections;UArraysKt;fill;(UIntArray,int,int,int);generated", - "kotlin.collections;UArraysKt;fill;(ULongArray,long,int,int);generated", - "kotlin.collections;UArraysKt;fill;(UShortArray,short,int,int);generated", - "kotlin.collections;UArraysKt;filter;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;filter;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;filter;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;filter;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;filterIndexed;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;filterIndexed;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;filterIndexed;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;filterIndexed;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;filterNot;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;filterNot;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;filterNot;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;filterNot;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;find;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;find;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;find;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;find;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;findLast;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;findLast;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;findLast;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;findLast;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;first;(UByteArray);generated", - "kotlin.collections;UArraysKt;first;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;first;(UIntArray);generated", - "kotlin.collections;UArraysKt;first;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;first;(ULongArray);generated", - "kotlin.collections;UArraysKt;first;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;first;(UShortArray);generated", - "kotlin.collections;UArraysKt;first;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;firstOrNull;(UByteArray);generated", - "kotlin.collections;UArraysKt;firstOrNull;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;firstOrNull;(UIntArray);generated", - "kotlin.collections;UArraysKt;firstOrNull;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;firstOrNull;(ULongArray);generated", - "kotlin.collections;UArraysKt;firstOrNull;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;firstOrNull;(UShortArray);generated", - "kotlin.collections;UArraysKt;firstOrNull;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;flatMap;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;flatMap;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;flatMap;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;flatMap;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;flatMapIndexed;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;flatMapIndexed;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;flatMapIndexed;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;flatMapIndexed;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;forEach;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;forEach;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;forEach;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;forEach;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;forEachIndexed;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;forEachIndexed;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;forEachIndexed;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;forEachIndexed;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;getIndices;(UByteArray);generated", - "kotlin.collections;UArraysKt;getIndices;(UIntArray);generated", - "kotlin.collections;UArraysKt;getIndices;(ULongArray);generated", - "kotlin.collections;UArraysKt;getIndices;(UShortArray);generated", - "kotlin.collections;UArraysKt;getLastIndex;(UByteArray);generated", - "kotlin.collections;UArraysKt;getLastIndex;(UIntArray);generated", - "kotlin.collections;UArraysKt;getLastIndex;(ULongArray);generated", - "kotlin.collections;UArraysKt;getLastIndex;(UShortArray);generated", - "kotlin.collections;UArraysKt;getOrElse;(UByteArray,int,Function1);generated", - "kotlin.collections;UArraysKt;getOrElse;(UIntArray,int,Function1);generated", - "kotlin.collections;UArraysKt;getOrElse;(ULongArray,int,Function1);generated", - "kotlin.collections;UArraysKt;getOrElse;(UShortArray,int,Function1);generated", - "kotlin.collections;UArraysKt;getOrNull;(UByteArray,int);generated", - "kotlin.collections;UArraysKt;getOrNull;(UIntArray,int);generated", - "kotlin.collections;UArraysKt;getOrNull;(ULongArray,int);generated", - "kotlin.collections;UArraysKt;getOrNull;(UShortArray,int);generated", - "kotlin.collections;UArraysKt;groupBy;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;groupBy;(UByteArray,Function1,Function1);generated", - "kotlin.collections;UArraysKt;groupBy;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;groupBy;(UIntArray,Function1,Function1);generated", - "kotlin.collections;UArraysKt;groupBy;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;groupBy;(ULongArray,Function1,Function1);generated", - "kotlin.collections;UArraysKt;groupBy;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;groupBy;(UShortArray,Function1,Function1);generated", - "kotlin.collections;UArraysKt;indexOf;(UByteArray,byte);generated", - "kotlin.collections;UArraysKt;indexOf;(UIntArray,int);generated", - "kotlin.collections;UArraysKt;indexOf;(ULongArray,long);generated", - "kotlin.collections;UArraysKt;indexOf;(UShortArray,short);generated", - "kotlin.collections;UArraysKt;indexOfFirst;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;indexOfFirst;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;indexOfFirst;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;indexOfFirst;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;indexOfLast;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;indexOfLast;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;indexOfLast;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;indexOfLast;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;last;(UByteArray);generated", - "kotlin.collections;UArraysKt;last;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;last;(UIntArray);generated", - "kotlin.collections;UArraysKt;last;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;last;(ULongArray);generated", - "kotlin.collections;UArraysKt;last;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;last;(UShortArray);generated", - "kotlin.collections;UArraysKt;last;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;lastIndexOf;(UByteArray,byte);generated", - "kotlin.collections;UArraysKt;lastIndexOf;(UIntArray,int);generated", - "kotlin.collections;UArraysKt;lastIndexOf;(ULongArray,long);generated", - "kotlin.collections;UArraysKt;lastIndexOf;(UShortArray,short);generated", - "kotlin.collections;UArraysKt;lastOrNull;(UByteArray);generated", - "kotlin.collections;UArraysKt;lastOrNull;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;lastOrNull;(UIntArray);generated", - "kotlin.collections;UArraysKt;lastOrNull;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;lastOrNull;(ULongArray);generated", - "kotlin.collections;UArraysKt;lastOrNull;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;lastOrNull;(UShortArray);generated", - "kotlin.collections;UArraysKt;lastOrNull;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;map;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;map;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;map;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;map;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;mapIndexed;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;mapIndexed;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;mapIndexed;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;mapIndexed;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;max;(UByteArray);generated", - "kotlin.collections;UArraysKt;max;(UIntArray);generated", - "kotlin.collections;UArraysKt;max;(ULongArray);generated", - "kotlin.collections;UArraysKt;max;(UShortArray);generated", - "kotlin.collections;UArraysKt;maxBy;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;maxBy;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;maxBy;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;maxBy;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;maxByOrNull;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;maxByOrNull;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;maxByOrNull;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;maxByOrNull;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;maxByOrThrow-U;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;maxByOrThrow-U;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;maxByOrThrow-U;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;maxByOrThrow-U;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOf;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOf;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOf;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOf;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOfOrNull;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOfOrNull;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOfOrNull;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOfOrNull;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOfWith;(UByteArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;maxOfWith;(UIntArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;maxOfWith;(ULongArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;maxOfWith;(UShortArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;maxOfWithOrNull;(UByteArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;maxOfWithOrNull;(UIntArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;maxOfWithOrNull;(ULongArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;maxOfWithOrNull;(UShortArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;maxOrNull;(UByteArray);generated", - "kotlin.collections;UArraysKt;maxOrNull;(UIntArray);generated", - "kotlin.collections;UArraysKt;maxOrNull;(ULongArray);generated", - "kotlin.collections;UArraysKt;maxOrNull;(UShortArray);generated", - "kotlin.collections;UArraysKt;maxOrThrow-U;(UByteArray);generated", - "kotlin.collections;UArraysKt;maxOrThrow-U;(UIntArray);generated", - "kotlin.collections;UArraysKt;maxOrThrow-U;(ULongArray);generated", - "kotlin.collections;UArraysKt;maxOrThrow-U;(UShortArray);generated", - "kotlin.collections;UArraysKt;maxWith;(UByteArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWith;(UIntArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWith;(ULongArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWith;(UShortArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWithOrNull;(UByteArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWithOrNull;(UIntArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWithOrNull;(ULongArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWithOrNull;(UShortArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWithOrThrow-U;(UByteArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWithOrThrow-U;(UIntArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWithOrThrow-U;(ULongArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWithOrThrow-U;(UShortArray,Comparator);generated", - "kotlin.collections;UArraysKt;min;(UByteArray);generated", - "kotlin.collections;UArraysKt;min;(UIntArray);generated", - "kotlin.collections;UArraysKt;min;(ULongArray);generated", - "kotlin.collections;UArraysKt;min;(UShortArray);generated", - "kotlin.collections;UArraysKt;minBy;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;minBy;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;minBy;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;minBy;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;minByOrNull;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;minByOrNull;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;minByOrNull;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;minByOrNull;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;minByOrThrow-U;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;minByOrThrow-U;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;minByOrThrow-U;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;minByOrThrow-U;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;minOf;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;minOf;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;minOf;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;minOf;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;minOfOrNull;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;minOfOrNull;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;minOfOrNull;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;minOfOrNull;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;minOfWith;(UByteArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;minOfWith;(UIntArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;minOfWith;(ULongArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;minOfWith;(UShortArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;minOfWithOrNull;(UByteArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;minOfWithOrNull;(UIntArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;minOfWithOrNull;(ULongArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;minOfWithOrNull;(UShortArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;minOrNull;(UByteArray);generated", - "kotlin.collections;UArraysKt;minOrNull;(UIntArray);generated", - "kotlin.collections;UArraysKt;minOrNull;(ULongArray);generated", - "kotlin.collections;UArraysKt;minOrNull;(UShortArray);generated", - "kotlin.collections;UArraysKt;minOrThrow-U;(UByteArray);generated", - "kotlin.collections;UArraysKt;minOrThrow-U;(UIntArray);generated", - "kotlin.collections;UArraysKt;minOrThrow-U;(ULongArray);generated", - "kotlin.collections;UArraysKt;minOrThrow-U;(UShortArray);generated", - "kotlin.collections;UArraysKt;minWith;(UByteArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWith;(UIntArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWith;(ULongArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWith;(UShortArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWithOrNull;(UByteArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWithOrNull;(UIntArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWithOrNull;(ULongArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWithOrNull;(UShortArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWithOrThrow-U;(UByteArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWithOrThrow-U;(UIntArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWithOrThrow-U;(ULongArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWithOrThrow-U;(UShortArray,Comparator);generated", - "kotlin.collections;UArraysKt;none;(UByteArray);generated", - "kotlin.collections;UArraysKt;none;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;none;(UIntArray);generated", - "kotlin.collections;UArraysKt;none;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;none;(ULongArray);generated", - "kotlin.collections;UArraysKt;none;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;none;(UShortArray);generated", - "kotlin.collections;UArraysKt;none;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;plus;(UIntArray,Collection);generated", - "kotlin.collections;UArraysKt;plus;(UIntArray,UIntArray);generated", - "kotlin.collections;UArraysKt;plus;(UIntArray,int);generated", - "kotlin.collections;UArraysKt;plus;(ULongArray,Collection);generated", - "kotlin.collections;UArraysKt;plus;(ULongArray,ULongArray);generated", - "kotlin.collections;UArraysKt;plus;(ULongArray,long);generated", - "kotlin.collections;UArraysKt;plus;(UShortArray,Collection);generated", - "kotlin.collections;UArraysKt;plus;(UShortArray,UShortArray);generated", - "kotlin.collections;UArraysKt;plus;(UShortArray,short);generated", - "kotlin.collections;UArraysKt;random;(UByteArray);generated", - "kotlin.collections;UArraysKt;random;(UByteArray,Random);generated", - "kotlin.collections;UArraysKt;random;(UIntArray);generated", - "kotlin.collections;UArraysKt;random;(UIntArray,Random);generated", - "kotlin.collections;UArraysKt;random;(ULongArray);generated", - "kotlin.collections;UArraysKt;random;(ULongArray,Random);generated", - "kotlin.collections;UArraysKt;random;(UShortArray);generated", - "kotlin.collections;UArraysKt;random;(UShortArray,Random);generated", - "kotlin.collections;UArraysKt;randomOrNull;(UByteArray);generated", - "kotlin.collections;UArraysKt;randomOrNull;(UByteArray,Random);generated", - "kotlin.collections;UArraysKt;randomOrNull;(UIntArray);generated", - "kotlin.collections;UArraysKt;randomOrNull;(UIntArray,Random);generated", - "kotlin.collections;UArraysKt;randomOrNull;(ULongArray);generated", - "kotlin.collections;UArraysKt;randomOrNull;(ULongArray,Random);generated", - "kotlin.collections;UArraysKt;randomOrNull;(UShortArray);generated", - "kotlin.collections;UArraysKt;randomOrNull;(UShortArray,Random);generated", - "kotlin.collections;UArraysKt;reduce;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;reduce;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;reduce;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;reduce;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceIndexed;(UByteArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceIndexed;(UIntArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceIndexed;(ULongArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceIndexed;(UShortArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceIndexedOrNull;(UByteArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceIndexedOrNull;(UIntArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceIndexedOrNull;(ULongArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceIndexedOrNull;(UShortArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceOrNull;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceOrNull;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceOrNull;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceOrNull;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceRight;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceRight;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceRight;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceRight;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceRightIndexed;(UByteArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceRightIndexed;(UIntArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceRightIndexed;(ULongArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceRightIndexed;(UShortArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceRightIndexedOrNull;(UByteArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceRightIndexedOrNull;(UIntArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceRightIndexedOrNull;(ULongArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceRightIndexedOrNull;(UShortArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceRightOrNull;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceRightOrNull;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceRightOrNull;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceRightOrNull;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;reverse;(UByteArray);generated", - "kotlin.collections;UArraysKt;reverse;(UByteArray,int,int);generated", - "kotlin.collections;UArraysKt;reverse;(UIntArray);generated", - "kotlin.collections;UArraysKt;reverse;(UIntArray,int,int);generated", - "kotlin.collections;UArraysKt;reverse;(ULongArray);generated", - "kotlin.collections;UArraysKt;reverse;(ULongArray,int,int);generated", - "kotlin.collections;UArraysKt;reverse;(UShortArray);generated", - "kotlin.collections;UArraysKt;reverse;(UShortArray,int,int);generated", - "kotlin.collections;UArraysKt;reversedArray;(UIntArray);generated", - "kotlin.collections;UArraysKt;reversedArray;(ULongArray);generated", - "kotlin.collections;UArraysKt;reversedArray;(UShortArray);generated", - "kotlin.collections;UArraysKt;runningReduce;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;runningReduce;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;runningReduce;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;runningReduce;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;runningReduceIndexed;(UByteArray,Function3);generated", - "kotlin.collections;UArraysKt;runningReduceIndexed;(UIntArray,Function3);generated", - "kotlin.collections;UArraysKt;runningReduceIndexed;(ULongArray,Function3);generated", - "kotlin.collections;UArraysKt;runningReduceIndexed;(UShortArray,Function3);generated", - "kotlin.collections;UArraysKt;shuffle;(UByteArray);generated", - "kotlin.collections;UArraysKt;shuffle;(UByteArray,Random);generated", - "kotlin.collections;UArraysKt;shuffle;(UIntArray);generated", - "kotlin.collections;UArraysKt;shuffle;(UIntArray,Random);generated", - "kotlin.collections;UArraysKt;shuffle;(ULongArray);generated", - "kotlin.collections;UArraysKt;shuffle;(ULongArray,Random);generated", - "kotlin.collections;UArraysKt;shuffle;(UShortArray);generated", - "kotlin.collections;UArraysKt;shuffle;(UShortArray,Random);generated", - "kotlin.collections;UArraysKt;single;(UByteArray);generated", - "kotlin.collections;UArraysKt;single;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;single;(UIntArray);generated", - "kotlin.collections;UArraysKt;single;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;single;(ULongArray);generated", - "kotlin.collections;UArraysKt;single;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;single;(UShortArray);generated", - "kotlin.collections;UArraysKt;single;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;singleOrNull;(UByteArray);generated", - "kotlin.collections;UArraysKt;singleOrNull;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;singleOrNull;(UIntArray);generated", - "kotlin.collections;UArraysKt;singleOrNull;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;singleOrNull;(ULongArray);generated", - "kotlin.collections;UArraysKt;singleOrNull;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;singleOrNull;(UShortArray);generated", - "kotlin.collections;UArraysKt;singleOrNull;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;slice;(UByteArray,IntRange);generated", - "kotlin.collections;UArraysKt;slice;(UByteArray,Iterable);generated", - "kotlin.collections;UArraysKt;slice;(UIntArray,IntRange);generated", - "kotlin.collections;UArraysKt;slice;(UIntArray,Iterable);generated", - "kotlin.collections;UArraysKt;slice;(ULongArray,IntRange);generated", - "kotlin.collections;UArraysKt;slice;(ULongArray,Iterable);generated", - "kotlin.collections;UArraysKt;slice;(UShortArray,IntRange);generated", - "kotlin.collections;UArraysKt;slice;(UShortArray,Iterable);generated", - "kotlin.collections;UArraysKt;sliceArray;(UByteArray,Collection);generated", - "kotlin.collections;UArraysKt;sliceArray;(UIntArray,Collection);generated", - "kotlin.collections;UArraysKt;sliceArray;(UIntArray,IntRange);generated", - "kotlin.collections;UArraysKt;sliceArray;(ULongArray,Collection);generated", - "kotlin.collections;UArraysKt;sliceArray;(ULongArray,IntRange);generated", - "kotlin.collections;UArraysKt;sliceArray;(UShortArray,Collection);generated", - "kotlin.collections;UArraysKt;sliceArray;(UShortArray,IntRange);generated", - "kotlin.collections;UArraysKt;sort;(UByteArray);generated", - "kotlin.collections;UArraysKt;sort;(UByteArray,int,int);generated", - "kotlin.collections;UArraysKt;sort;(UIntArray);generated", - "kotlin.collections;UArraysKt;sort;(UIntArray,int,int);generated", - "kotlin.collections;UArraysKt;sort;(ULongArray);generated", - "kotlin.collections;UArraysKt;sort;(ULongArray,int,int);generated", - "kotlin.collections;UArraysKt;sort;(UShortArray);generated", - "kotlin.collections;UArraysKt;sort;(UShortArray,int,int);generated", - "kotlin.collections;UArraysKt;sortDescending;(UByteArray);generated", - "kotlin.collections;UArraysKt;sortDescending;(UByteArray,int,int);generated", - "kotlin.collections;UArraysKt;sortDescending;(UIntArray);generated", - "kotlin.collections;UArraysKt;sortDescending;(UIntArray,int,int);generated", - "kotlin.collections;UArraysKt;sortDescending;(ULongArray);generated", - "kotlin.collections;UArraysKt;sortDescending;(ULongArray,int,int);generated", - "kotlin.collections;UArraysKt;sortDescending;(UShortArray);generated", - "kotlin.collections;UArraysKt;sortDescending;(UShortArray,int,int);generated", - "kotlin.collections;UArraysKt;sorted;(UByteArray);generated", - "kotlin.collections;UArraysKt;sorted;(UIntArray);generated", - "kotlin.collections;UArraysKt;sorted;(ULongArray);generated", - "kotlin.collections;UArraysKt;sorted;(UShortArray);generated", - "kotlin.collections;UArraysKt;sortedDescending;(UIntArray);generated", - "kotlin.collections;UArraysKt;sortedDescending;(ULongArray);generated", - "kotlin.collections;UArraysKt;sortedDescending;(UShortArray);generated", - "kotlin.collections;UArraysKt;sum;(UByteArray);generated", - "kotlin.collections;UArraysKt;sum;(UIntArray);generated", - "kotlin.collections;UArraysKt;sum;(ULongArray);generated", - "kotlin.collections;UArraysKt;sum;(UShortArray);generated", - "kotlin.collections;UArraysKt;sumBy;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumBy;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumBy;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumBy;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumByDouble;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumByDouble;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumByDouble;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumByDouble;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfBigDecimal;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfBigDecimal;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfBigDecimal;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfBigDecimal;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfBigInteger;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfBigInteger;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfBigInteger;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfBigInteger;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfDouble;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfDouble;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfDouble;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfDouble;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfInt;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfInt;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfInt;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfInt;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfLong;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfLong;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfLong;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfLong;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfUByte;(byte[]);generated", - "kotlin.collections;UArraysKt;sumOfUInt;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfUInt;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfUInt;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfUInt;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfUInt;(int[]);generated", - "kotlin.collections;UArraysKt;sumOfULong;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfULong;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfULong;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfULong;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfULong;(long[]);generated", - "kotlin.collections;UArraysKt;sumOfUShort;(short[]);generated", - "kotlin.collections;UArraysKt;takeWhile;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;takeWhile;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;takeWhile;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;takeWhile;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;toIntArray;(UIntArray);generated", - "kotlin.collections;UArraysKt;toLongArray;(ULongArray);generated", - "kotlin.collections;UArraysKt;toShortArray;(UShortArray);generated", - "kotlin.collections;UArraysKt;toTypedArray;(UByteArray);generated", - "kotlin.collections;UArraysKt;toTypedArray;(UIntArray);generated", - "kotlin.collections;UArraysKt;toTypedArray;(ULongArray);generated", - "kotlin.collections;UArraysKt;toTypedArray;(UShortArray);generated", - "kotlin.collections;UArraysKt;toUIntArray;(int[]);generated", - "kotlin.collections;UArraysKt;toULongArray;(long[]);generated", - "kotlin.collections;UArraysKt;toUShortArray;(short[]);generated", - "kotlin.collections;UArraysKt;withIndex;(UByteArray);generated", - "kotlin.collections;UArraysKt;withIndex;(UIntArray);generated", - "kotlin.collections;UArraysKt;withIndex;(ULongArray);generated", - "kotlin.collections;UArraysKt;withIndex;(UShortArray);generated", - "kotlin.collections;UArraysKt;zip;(UByteArray,Iterable);generated", - "kotlin.collections;UArraysKt;zip;(UByteArray,Iterable,Function2);generated", - "kotlin.collections;UArraysKt;zip;(UByteArray,Object[]);generated", - "kotlin.collections;UArraysKt;zip;(UByteArray,Object[],Function2);generated", - "kotlin.collections;UArraysKt;zip;(UByteArray,UByteArray);generated", - "kotlin.collections;UArraysKt;zip;(UByteArray,UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;zip;(UIntArray,Iterable);generated", - "kotlin.collections;UArraysKt;zip;(UIntArray,Iterable,Function2);generated", - "kotlin.collections;UArraysKt;zip;(UIntArray,Object[]);generated", - "kotlin.collections;UArraysKt;zip;(UIntArray,Object[],Function2);generated", - "kotlin.collections;UArraysKt;zip;(UIntArray,UIntArray);generated", - "kotlin.collections;UArraysKt;zip;(UIntArray,UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;zip;(ULongArray,Iterable);generated", - "kotlin.collections;UArraysKt;zip;(ULongArray,Iterable,Function2);generated", - "kotlin.collections;UArraysKt;zip;(ULongArray,Object[]);generated", - "kotlin.collections;UArraysKt;zip;(ULongArray,Object[],Function2);generated", - "kotlin.collections;UArraysKt;zip;(ULongArray,ULongArray);generated", - "kotlin.collections;UArraysKt;zip;(ULongArray,ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;zip;(UShortArray,Iterable);generated", - "kotlin.collections;UArraysKt;zip;(UShortArray,Iterable,Function2);generated", - "kotlin.collections;UArraysKt;zip;(UShortArray,Object[]);generated", - "kotlin.collections;UArraysKt;zip;(UShortArray,Object[],Function2);generated", - "kotlin.collections;UArraysKt;zip;(UShortArray,UShortArray);generated", - "kotlin.collections;UArraysKt;zip;(UShortArray,UShortArray,Function2);generated", - "kotlin.collections;UCollectionsKt;sumOfUByte;(Iterable);generated", - "kotlin.collections;UCollectionsKt;sumOfUInt;(Iterable);generated", - "kotlin.collections;UCollectionsKt;sumOfULong;(Iterable);generated", - "kotlin.collections;UCollectionsKt;sumOfUShort;(Iterable);generated", - "kotlin.collections;UCollectionsKt;toUByteArray;(Collection);generated", - "kotlin.collections;UCollectionsKt;toUIntArray;(Collection);generated", - "kotlin.collections;UCollectionsKt;toULongArray;(Collection);generated", - "kotlin.collections;UCollectionsKt;toUShortArray;(Collection);generated", - "kotlin.comparisons;ComparisonsKt;compareBy;();generated", - "kotlin.comparisons;ComparisonsKt;compareBy;(Comparator,Function1);generated", - "kotlin.comparisons;ComparisonsKt;compareBy;(Function1);generated", - "kotlin.comparisons;ComparisonsKt;compareByDescending;(Comparator,Function1);generated", - "kotlin.comparisons;ComparisonsKt;compareByDescending;(Function1);generated", - "kotlin.comparisons;ComparisonsKt;compareValues;(Comparable,Comparable);generated", - "kotlin.comparisons;ComparisonsKt;compareValuesBy;(Object,Object);generated", - "kotlin.comparisons;ComparisonsKt;compareValuesBy;(Object,Object,Comparator,Function1);generated", - "kotlin.comparisons;ComparisonsKt;compareValuesBy;(Object,Object,Function1);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(byte,byte);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(byte,byte,byte);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(byte,byte[]);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(double,double);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(double,double,double);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(double,double[]);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(float,float);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(float,float,float);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(float,float[]);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(int,int);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(int,int,int);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(int,int[]);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(long,long);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(long,long,long);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(long,long[]);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(short,short);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(short,short,short);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(short,short[]);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(byte,byte);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(byte,byte,byte);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(byte,byte[]);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(double,double);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(double,double,double);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(double,double[]);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(float,float);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(float,float,float);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(float,float[]);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(int,int);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(int,int,int);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(int,int[]);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(long,long);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(long,long,long);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(long,long[]);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(short,short);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(short,short,short);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(short,short[]);generated", - "kotlin.comparisons;ComparisonsKt;naturalOrder;();generated", - "kotlin.comparisons;ComparisonsKt;nullsFirst;();generated", - "kotlin.comparisons;ComparisonsKt;nullsFirst;(Comparator);generated", - "kotlin.comparisons;ComparisonsKt;nullsLast;();generated", - "kotlin.comparisons;ComparisonsKt;nullsLast;(Comparator);generated", - "kotlin.comparisons;ComparisonsKt;reverseOrder;();generated", - "kotlin.comparisons;ComparisonsKt;then;(Comparator,Comparator);generated", - "kotlin.comparisons;ComparisonsKt;thenBy;(Comparator,Comparator,Function1);generated", - "kotlin.comparisons;ComparisonsKt;thenBy;(Comparator,Function1);generated", - "kotlin.comparisons;ComparisonsKt;thenByDescending;(Comparator,Comparator,Function1);generated", - "kotlin.comparisons;ComparisonsKt;thenByDescending;(Comparator,Function1);generated", - "kotlin.comparisons;ComparisonsKt;thenComparator;(Comparator,Function2);generated", - "kotlin.comparisons;ComparisonsKt;thenDescending;(Comparator,Comparator);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(byte,UByteArray);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(byte,byte);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(byte,byte,byte);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(int,UIntArray);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(int,int);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(int,int,int);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(long,ULongArray);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(long,long);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(long,long,long);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(short,UShortArray);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(short,short);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(short,short,short);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(byte,UByteArray);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(byte,byte);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(byte,byte,byte);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(int,UIntArray);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(int,int);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(int,int,int);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(long,ULongArray);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(long,long);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(long,long,long);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(short,UShortArray);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(short,short);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(short,short,short);generated", - "kotlin.concurrent;LocksKt;read;(ReentrantReadWriteLock,Function0);generated", - "kotlin.concurrent;LocksKt;withLock;(Lock,Function0);generated", - "kotlin.concurrent;LocksKt;write;(ReentrantReadWriteLock,Function0);generated", - "kotlin.concurrent;ThreadsKt;getOrSet;(ThreadLocal,Function0);generated", - "kotlin.concurrent;ThreadsKt;thread;(boolean,boolean,ClassLoader,String,int,Function0);generated", - "kotlin.concurrent;TimersKt;fixedRateTimer;(String,boolean,Date,long,Function1);generated", - "kotlin.concurrent;TimersKt;fixedRateTimer;(String,boolean,long,long,Function1);generated", - "kotlin.concurrent;TimersKt;schedule;(Timer,Date,Function1);generated", - "kotlin.concurrent;TimersKt;schedule;(Timer,Date,long,Function1);generated", - "kotlin.concurrent;TimersKt;schedule;(Timer,long,Function1);generated", - "kotlin.concurrent;TimersKt;schedule;(Timer,long,long,Function1);generated", - "kotlin.concurrent;TimersKt;scheduleAtFixedRate;(Timer,Date,long,Function1);generated", - "kotlin.concurrent;TimersKt;scheduleAtFixedRate;(Timer,long,long,Function1);generated", - "kotlin.concurrent;TimersKt;timer;(String,boolean,Date,long,Function1);generated", - "kotlin.concurrent;TimersKt;timer;(String,boolean,long,long,Function1);generated", - "kotlin.concurrent;TimersKt;timerTask;(Function1);generated", - "kotlin.contracts;ContractBuilder;callsInPlace;(Function,InvocationKind);generated", - "kotlin.contracts;ContractBuilder;returns;();generated", - "kotlin.contracts;ContractBuilder;returns;(Object);generated", - "kotlin.contracts;ContractBuilder;returnsNotNull;();generated", - "kotlin.contracts;ContractBuilderKt;contract;(Function1);generated", - "kotlin.contracts;ExperimentalContracts;ExperimentalContracts;();generated", - "kotlin.contracts;InvocationKind;valueOf;(String);generated", - "kotlin.contracts;InvocationKind;values;();generated", - "kotlin.contracts;SimpleEffect;implies;(boolean);generated", - "kotlin.coroutines.cancellation;CancellationException;CancellationException;();generated", - "kotlin.coroutines.cancellation;CancellationException;CancellationException;(String);generated", - "kotlin.coroutines.cancellation;CancellationExceptionHKt;CancellationException;(String,Throwable);generated", - "kotlin.coroutines.cancellation;CancellationExceptionHKt;CancellationException;(Throwable);generated", - "kotlin.coroutines.cancellation;CancellationExceptionKt;CancellationException;(String,Throwable);generated", - "kotlin.coroutines.cancellation;CancellationExceptionKt;CancellationException;(Throwable);generated", - "kotlin.coroutines.intrinsics;CoroutinesIntrinsicsHKt;createCoroutineUnintercepted;(SuspendFunction0,Continuation);generated", - "kotlin.coroutines.intrinsics;CoroutinesIntrinsicsHKt;createCoroutineUnintercepted;(SuspendFunction1,Object,Continuation);generated", - "kotlin.coroutines.intrinsics;CoroutinesIntrinsicsHKt;intercepted;(Continuation);generated", - "kotlin.coroutines.intrinsics;CoroutinesIntrinsicsHKt;startCoroutineUninterceptedOrReturn;(SuspendFunction0,Continuation);generated", - "kotlin.coroutines.intrinsics;CoroutinesIntrinsicsHKt;startCoroutineUninterceptedOrReturn;(SuspendFunction1,Object,Continuation);generated", - "kotlin.coroutines.intrinsics;IntrinsicsKt;createCoroutineUnintercepted;(SuspendFunction0,Continuation);generated", - "kotlin.coroutines.intrinsics;IntrinsicsKt;createCoroutineUnintercepted;(SuspendFunction1,Object,Continuation);generated", - "kotlin.coroutines.intrinsics;IntrinsicsKt;getCOROUTINE_SUSPENDED;();generated", - "kotlin.coroutines.intrinsics;IntrinsicsKt;startCoroutineUninterceptedOrReturn;(SuspendFunction0,Continuation);generated", - "kotlin.coroutines.intrinsics;IntrinsicsKt;startCoroutineUninterceptedOrReturn;(SuspendFunction1,Object,Continuation);generated", - "kotlin.coroutines.intrinsics;IntrinsicsKt;suspendCoroutineUninterceptedOrReturn;(Function1);generated", - "kotlin.coroutines.jvm.internal;CoroutineStackFrame;getCallerFrame;();generated", - "kotlin.coroutines.jvm.internal;CoroutineStackFrame;getStackTraceElement;();generated", - "kotlin.coroutines;Continuation;getContext;();generated", - "kotlin.coroutines;Continuation;resumeWith;(Result);generated", - "kotlin.coroutines;ContinuationInterceptor;interceptContinuation;(Continuation);generated", - "kotlin.coroutines;ContinuationInterceptor;releaseInterceptedContinuation;(Continuation);generated", - "kotlin.coroutines;ContinuationKt;Continuation;(CoroutineContext,Function1);generated", - "kotlin.coroutines;ContinuationKt;createCoroutine;(SuspendFunction0,Continuation);generated", - "kotlin.coroutines;ContinuationKt;createCoroutine;(SuspendFunction1,Object,Continuation);generated", - "kotlin.coroutines;ContinuationKt;getCoroutineContext;();generated", - "kotlin.coroutines;ContinuationKt;resume;(Continuation,Object);generated", - "kotlin.coroutines;ContinuationKt;resumeWithException;(Continuation,Throwable);generated", - "kotlin.coroutines;ContinuationKt;startCoroutine;(SuspendFunction0,Continuation);generated", - "kotlin.coroutines;ContinuationKt;startCoroutine;(SuspendFunction1,Object,Continuation);generated", - "kotlin.coroutines;ContinuationKt;suspendCoroutine;(Function1);generated", - "kotlin.coroutines;CoroutineContext$Element;getKey;();generated", - "kotlin.coroutines;CoroutineContext;fold;(Object,Function2);generated", - "kotlin.coroutines;CoroutineContext;get;(Key);generated", - "kotlin.coroutines;CoroutineContext;minusKey;(Key);generated", - "kotlin.coroutines;EmptyCoroutineContext;hashCode;();generated", - "kotlin.coroutines;EmptyCoroutineContext;toString;();generated", - "kotlin.coroutines;RestrictsSuspension;RestrictsSuspension;();generated", - "kotlin.experimental;BitwiseOperationsKt;and;(byte,byte);generated", - "kotlin.experimental;BitwiseOperationsKt;and;(short,short);generated", - "kotlin.experimental;BitwiseOperationsKt;inv;(byte);generated", - "kotlin.experimental;BitwiseOperationsKt;inv;(short);generated", - "kotlin.experimental;BitwiseOperationsKt;or;(byte,byte);generated", - "kotlin.experimental;BitwiseOperationsKt;or;(short,short);generated", - "kotlin.experimental;BitwiseOperationsKt;xor;(byte,byte);generated", - "kotlin.experimental;BitwiseOperationsKt;xor;(short,short);generated", - "kotlin.experimental;ExperimentalTypeInference;ExperimentalTypeInference;();generated", - "kotlin.io;ByteStreamsKt;bufferedWriter;(OutputStream,Charset);generated", - "kotlin.io;ByteStreamsKt;iterator;(BufferedInputStream);generated", - "kotlin.io;ByteStreamsKt;writer;(OutputStream,Charset);generated", - "kotlin.io;ConsoleKt;print;(Object);generated", - "kotlin.io;ConsoleKt;print;(boolean);generated", - "kotlin.io;ConsoleKt;print;(byte);generated", "kotlin.io;ConsoleKt;print;(char);generated", - "kotlin.io;ConsoleKt;print;(char[]);generated", - "kotlin.io;ConsoleKt;print;(double);generated", - "kotlin.io;ConsoleKt;print;(float);generated", "kotlin.io;ConsoleKt;print;(int);generated", - "kotlin.io;ConsoleKt;print;(long);generated", "kotlin.io;ConsoleKt;print;(short);generated", - "kotlin.io;ConsoleKt;println;();generated", - "kotlin.io;ConsoleKt;println;(Object);generated", - "kotlin.io;ConsoleKt;println;(boolean);generated", - "kotlin.io;ConsoleKt;println;(byte);generated", - "kotlin.io;ConsoleKt;println;(char);generated", - "kotlin.io;ConsoleKt;println;(char[]);generated", - "kotlin.io;ConsoleKt;println;(double);generated", - "kotlin.io;ConsoleKt;println;(float);generated", - "kotlin.io;ConsoleKt;println;(int);generated", - "kotlin.io;ConsoleKt;println;(long);generated", - "kotlin.io;ConsoleKt;println;(short);generated", - "kotlin.io;ConsoleKt;readLine;();generated", "kotlin.io;ConsoleKt;readln;();generated", - "kotlin.io;ConsoleKt;readlnOrNull;();generated", - "kotlin.io;ConstantsKt;getDEFAULT_BUFFER_SIZE;();generated", - "kotlin.io;FileWalkDirection;valueOf;(String);generated", - "kotlin.io;FileWalkDirection;values;();generated", - "kotlin.io;FilesKt;appendBytes;(File,byte[]);generated", - "kotlin.io;FilesKt;appendText;(File,String,Charset);generated", - "kotlin.io;FilesKt;bufferedReader;(File,Charset,int);generated", - "kotlin.io;FilesKt;bufferedWriter;(File,Charset,int);generated", - "kotlin.io;FilesKt;copyRecursively;(File,File,boolean,Function2);generated", - "kotlin.io;FilesKt;createTempDir;(String,String,File);generated", - "kotlin.io;FilesKt;createTempFile;(String,String,File);generated", - "kotlin.io;FilesKt;deleteRecursively;(File);generated", - "kotlin.io;FilesKt;endsWith;(File,File);generated", - "kotlin.io;FilesKt;endsWith;(File,String);generated", - "kotlin.io;FilesKt;forEachBlock;(File,Function2);generated", - "kotlin.io;FilesKt;forEachBlock;(File,int,Function2);generated", - "kotlin.io;FilesKt;forEachLine;(File,Charset,Function1);generated", - "kotlin.io;FilesKt;getExtension;(File);generated", - "kotlin.io;FilesKt;getInvariantSeparatorsPath;(File);generated", - "kotlin.io;FilesKt;getNameWithoutExtension;(File);generated", - "kotlin.io;FilesKt;inputStream;(File);generated", - "kotlin.io;FilesKt;isRooted;(File);generated", - "kotlin.io;FilesKt;normalize;(File);generated", - "kotlin.io;FilesKt;outputStream;(File);generated", - "kotlin.io;FilesKt;printWriter;(File,Charset);generated", - "kotlin.io;FilesKt;readBytes;(File);generated", - "kotlin.io;FilesKt;readLines;(File,Charset);generated", - "kotlin.io;FilesKt;readText;(File,Charset);generated", - "kotlin.io;FilesKt;reader;(File,Charset);generated", - "kotlin.io;FilesKt;relativeTo;(File,File);generated", - "kotlin.io;FilesKt;relativeToOrNull;(File,File);generated", - "kotlin.io;FilesKt;startsWith;(File,File);generated", - "kotlin.io;FilesKt;startsWith;(File,String);generated", - "kotlin.io;FilesKt;toRelativeString;(File,File);generated", - "kotlin.io;FilesKt;useLines;(File,Charset,Function1);generated", - "kotlin.io;FilesKt;writeBytes;(File,byte[]);generated", - "kotlin.io;FilesKt;writeText;(File,String,Charset);generated", - "kotlin.io;FilesKt;writer;(File,Charset);generated", - "kotlin.io;IoHKt;print;(Object);generated", "kotlin.io;IoHKt;println;();generated", - "kotlin.io;IoHKt;println;(Object);generated", "kotlin.io;IoHKt;readln;();generated", - "kotlin.io;IoHKt;readlnOrNull;();generated", - "kotlin.io;OnErrorAction;valueOf;(String);generated", - "kotlin.io;OnErrorAction;values;();generated", - "kotlin.io;TextStreamsKt;readBytes;(URL);generated", - "kotlin.io;TextStreamsKt;readLines;(Reader);generated", - "kotlin.io;TextStreamsKt;readText;(URL,Charset);generated", - "kotlin.js;ExperimentalJsExport;ExperimentalJsExport;();generated", - "kotlin.js;JsExport;JsExport;();generated", "kotlin.js;JsName;JsName;(String);generated", - "kotlin.js;JsName;name;();generated", "kotlin.jvm.functions;Function0;invoke;();generated", - "kotlin.jvm.functions;Function10;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function11;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function12;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function13;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function14;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function15;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function16;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function17;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function18;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function19;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function1;invoke;(Object);generated", - "kotlin.jvm.functions;Function20;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function21;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function22;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function2;invoke;(Object,Object);generated", - "kotlin.jvm.functions;Function3;invoke;(Object,Object,Object);generated", - "kotlin.jvm.functions;Function4;invoke;(Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function5;invoke;(Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function6;invoke;(Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function7;invoke;(Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function8;invoke;(Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function9;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;FunctionN;invoke;(Object[]);generated", - "kotlin.jvm.internal;AdaptedFunctionReference;equals;(Object);generated", - "kotlin.jvm.internal;AdaptedFunctionReference;getOwner;();generated", - "kotlin.jvm.internal;AdaptedFunctionReference;hashCode;();generated", - "kotlin.jvm.internal;AdaptedFunctionReference;toString;();generated", - "kotlin.jvm.internal;ArrayIteratorsKt;iterator;(boolean[]);generated", - "kotlin.jvm.internal;ArrayIteratorsKt;iterator;(double[]);generated", - "kotlin.jvm.internal;ArrayIteratorsKt;iterator;(float[]);generated", - "kotlin.jvm.internal;ArrayIteratorsKt;iterator;(int[]);generated", - "kotlin.jvm.internal;ArrayIteratorsKt;iterator;(long[]);generated", - "kotlin.jvm.internal;ArrayIteratorsKt;iterator;(short[]);generated", - "kotlin.jvm.internal;BooleanSpreadBuilder;BooleanSpreadBuilder;(int);generated", - "kotlin.jvm.internal;BooleanSpreadBuilder;add;(boolean);generated", - "kotlin.jvm.internal;BooleanSpreadBuilder;toArray;();generated", - "kotlin.jvm.internal;ByteSpreadBuilder;ByteSpreadBuilder;(int);generated", - "kotlin.jvm.internal;ByteSpreadBuilder;add;(byte);generated", - "kotlin.jvm.internal;CallableReference;CallableReference;();generated", - "kotlin.jvm.internal;CallableReference;getOwner;();generated", - "kotlin.jvm.internal;CharSpreadBuilder;CharSpreadBuilder;(int);generated", - "kotlin.jvm.internal;CharSpreadBuilder;add;(char);generated", - "kotlin.jvm.internal;ClassBasedDeclarationContainer;getJClass;();generated", - "kotlin.jvm.internal;ClassReference$Companion;isInstance;(Object,Class);generated", - "kotlin.jvm.internal;ClassReference;ClassReference;(Class);generated", - "kotlin.jvm.internal;ClassReference;equals;(Object);generated", - "kotlin.jvm.internal;ClassReference;hashCode;();generated", - "kotlin.jvm.internal;ClassReference;toString;();generated", - "kotlin.jvm.internal;DoubleSpreadBuilder;DoubleSpreadBuilder;(int);generated", - "kotlin.jvm.internal;DoubleSpreadBuilder;add;(double);generated", - "kotlin.jvm.internal;DoubleSpreadBuilder;toArray;();generated", - "kotlin.jvm.internal;FloatSpreadBuilder;FloatSpreadBuilder;(int);generated", - "kotlin.jvm.internal;FloatSpreadBuilder;add;(float);generated", - "kotlin.jvm.internal;FloatSpreadBuilder;toArray;();generated", - "kotlin.jvm.internal;FunInterfaceConstructorReference;FunInterfaceConstructorReference;(Class);generated", - "kotlin.jvm.internal;FunInterfaceConstructorReference;equals;(Object);generated", - "kotlin.jvm.internal;FunInterfaceConstructorReference;hashCode;();generated", - "kotlin.jvm.internal;FunInterfaceConstructorReference;toString;();generated", - "kotlin.jvm.internal;FunctionAdapter;getFunctionDelegate;();generated", - "kotlin.jvm.internal;FunctionBase;getArity;();generated", - "kotlin.jvm.internal;FunctionImpl;FunctionImpl;();generated", - "kotlin.jvm.internal;FunctionImpl;getArity;();generated", - "kotlin.jvm.internal;FunctionImpl;invokeVararg;(Object[]);generated", - "kotlin.jvm.internal;FunctionReference;FunctionReference;(int);generated", - "kotlin.jvm.internal;FunctionReference;equals;(Object);generated", - "kotlin.jvm.internal;FunctionReference;hashCode;();generated", - "kotlin.jvm.internal;InlineMarker;InlineMarker;();generated", - "kotlin.jvm.internal;InlineMarker;afterInlineCall;();generated", - "kotlin.jvm.internal;InlineMarker;beforeInlineCall;();generated", - "kotlin.jvm.internal;InlineMarker;finallyEnd;(int);generated", - "kotlin.jvm.internal;InlineMarker;finallyStart;(int);generated", - "kotlin.jvm.internal;InlineMarker;mark;(String);generated", - "kotlin.jvm.internal;InlineMarker;mark;(int);generated", - "kotlin.jvm.internal;IntSpreadBuilder;IntSpreadBuilder;(int);generated", - "kotlin.jvm.internal;IntSpreadBuilder;add;(int);generated", - "kotlin.jvm.internal;IntSpreadBuilder;toArray;();generated", - "kotlin.jvm.internal;Intrinsics;areEqual;(Double,Double);generated", - "kotlin.jvm.internal;Intrinsics;areEqual;(Double,double);generated", - "kotlin.jvm.internal;Intrinsics;areEqual;(Float,Float);generated", - "kotlin.jvm.internal;Intrinsics;areEqual;(Float,float);generated", - "kotlin.jvm.internal;Intrinsics;areEqual;(Object,Object);generated", - "kotlin.jvm.internal;Intrinsics;areEqual;(double,Double);generated", - "kotlin.jvm.internal;Intrinsics;areEqual;(float,Float);generated", - "kotlin.jvm.internal;Intrinsics;checkExpressionValueIsNotNull;(Object,String);generated", - "kotlin.jvm.internal;Intrinsics;checkFieldIsNotNull;(Object,String);generated", - "kotlin.jvm.internal;Intrinsics;checkFieldIsNotNull;(Object,String,String);generated", - "kotlin.jvm.internal;Intrinsics;checkHasClass;(String);generated", - "kotlin.jvm.internal;Intrinsics;checkHasClass;(String,String);generated", - "kotlin.jvm.internal;Intrinsics;checkNotNull;(Object);generated", - "kotlin.jvm.internal;Intrinsics;checkNotNull;(Object,String);generated", - "kotlin.jvm.internal;Intrinsics;checkNotNullExpressionValue;(Object,String);generated", - "kotlin.jvm.internal;Intrinsics;checkNotNullParameter;(Object,String);generated", - "kotlin.jvm.internal;Intrinsics;checkParameterIsNotNull;(Object,String);generated", - "kotlin.jvm.internal;Intrinsics;checkReturnedValueIsNotNull;(Object,String);generated", - "kotlin.jvm.internal;Intrinsics;checkReturnedValueIsNotNull;(Object,String,String);generated", - "kotlin.jvm.internal;Intrinsics;compare;(int,int);generated", - "kotlin.jvm.internal;Intrinsics;compare;(long,long);generated", - "kotlin.jvm.internal;Intrinsics;needClassReification;();generated", - "kotlin.jvm.internal;Intrinsics;needClassReification;(String);generated", - "kotlin.jvm.internal;Intrinsics;reifiedOperationMarker;(int,String);generated", - "kotlin.jvm.internal;Intrinsics;reifiedOperationMarker;(int,String,String);generated", - "kotlin.jvm.internal;Intrinsics;throwAssert;();generated", - "kotlin.jvm.internal;Intrinsics;throwAssert;(String);generated", - "kotlin.jvm.internal;Intrinsics;throwIllegalArgument;();generated", - "kotlin.jvm.internal;Intrinsics;throwIllegalArgument;(String);generated", - "kotlin.jvm.internal;Intrinsics;throwIllegalState;();generated", - "kotlin.jvm.internal;Intrinsics;throwIllegalState;(String);generated", - "kotlin.jvm.internal;Intrinsics;throwJavaNpe;();generated", - "kotlin.jvm.internal;Intrinsics;throwJavaNpe;(String);generated", - "kotlin.jvm.internal;Intrinsics;throwNpe;();generated", - "kotlin.jvm.internal;Intrinsics;throwNpe;(String);generated", - "kotlin.jvm.internal;Intrinsics;throwUndefinedForReified;();generated", - "kotlin.jvm.internal;Intrinsics;throwUndefinedForReified;(String);generated", - "kotlin.jvm.internal;Intrinsics;throwUninitializedProperty;(String);generated", - "kotlin.jvm.internal;Intrinsics;throwUninitializedPropertyAccessException;(String);generated", - "kotlin.jvm.internal;KTypeBase;getJavaType;();generated", - "kotlin.jvm.internal;Lambda;Lambda;(int);generated", - "kotlin.jvm.internal;Lambda;toString;();generated", - "kotlin.jvm.internal;LocalVariableReference;LocalVariableReference;();generated", - "kotlin.jvm.internal;LongSpreadBuilder;LongSpreadBuilder;(int);generated", - "kotlin.jvm.internal;LongSpreadBuilder;add;(long);generated", - "kotlin.jvm.internal;LongSpreadBuilder;toArray;();generated", - "kotlin.jvm.internal;MagicApiIntrinsics;MagicApiIntrinsics;();generated", - "kotlin.jvm.internal;MagicApiIntrinsics;anyMagicApiCall;(Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;anyMagicApiCall;(int);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;anyMagicApiCall;(int,Object,Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;anyMagicApiCall;(int,Object,Object,Object,Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;anyMagicApiCall;(int,long,Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;anyMagicApiCall;(int,long,long,Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;intMagicApiCall;(Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;intMagicApiCall;(int);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;intMagicApiCall;(int,Object,Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;intMagicApiCall;(int,Object,Object,Object,Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;intMagicApiCall;(int,long,Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;intMagicApiCall;(int,long,long,Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;voidMagicApiCall;(Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;voidMagicApiCall;(int);generated", - "kotlin.jvm.internal;MutableLocalVariableReference;MutableLocalVariableReference;();generated", - "kotlin.jvm.internal;MutablePropertyReference0;MutablePropertyReference0;();generated", - "kotlin.jvm.internal;MutablePropertyReference1;MutablePropertyReference1;();generated", - "kotlin.jvm.internal;MutablePropertyReference2;MutablePropertyReference2;();generated", - "kotlin.jvm.internal;MutablePropertyReference;MutablePropertyReference;();generated", - "kotlin.jvm.internal;PackageReference;equals;(Object);generated", - "kotlin.jvm.internal;PackageReference;hashCode;();generated", - "kotlin.jvm.internal;PackageReference;toString;();generated", - "kotlin.jvm.internal;PrimitiveSpreadBuilder;PrimitiveSpreadBuilder;(int);generated", - "kotlin.jvm.internal;PropertyReference0;PropertyReference0;();generated", - "kotlin.jvm.internal;PropertyReference1;PropertyReference1;();generated", - "kotlin.jvm.internal;PropertyReference2;PropertyReference2;();generated", - "kotlin.jvm.internal;PropertyReference;PropertyReference;();generated", - "kotlin.jvm.internal;PropertyReference;equals;(Object);generated", - "kotlin.jvm.internal;PropertyReference;hashCode;();generated", - "kotlin.jvm.internal;Ref$BooleanRef;BooleanRef;();generated", - "kotlin.jvm.internal;Ref$BooleanRef;toString;();generated", - "kotlin.jvm.internal;Ref$ByteRef;ByteRef;();generated", - "kotlin.jvm.internal;Ref$ByteRef;toString;();generated", - "kotlin.jvm.internal;Ref$CharRef;CharRef;();generated", - "kotlin.jvm.internal;Ref$CharRef;toString;();generated", - "kotlin.jvm.internal;Ref$DoubleRef;DoubleRef;();generated", - "kotlin.jvm.internal;Ref$DoubleRef;toString;();generated", - "kotlin.jvm.internal;Ref$FloatRef;FloatRef;();generated", - "kotlin.jvm.internal;Ref$FloatRef;toString;();generated", - "kotlin.jvm.internal;Ref$IntRef;IntRef;();generated", - "kotlin.jvm.internal;Ref$IntRef;toString;();generated", - "kotlin.jvm.internal;Ref$LongRef;LongRef;();generated", - "kotlin.jvm.internal;Ref$LongRef;toString;();generated", - "kotlin.jvm.internal;Ref$ObjectRef;ObjectRef;();generated", - "kotlin.jvm.internal;Ref$ObjectRef;toString;();generated", - "kotlin.jvm.internal;Ref$ShortRef;ShortRef;();generated", - "kotlin.jvm.internal;Ref$ShortRef;toString;();generated", - "kotlin.jvm.internal;Reflection;Reflection;();generated", - "kotlin.jvm.internal;Reflection;createKotlinClass;(Class);generated", - "kotlin.jvm.internal;Reflection;createKotlinClass;(Class,String);generated", - "kotlin.jvm.internal;Reflection;getOrCreateKotlinClass;(Class);generated", - "kotlin.jvm.internal;Reflection;getOrCreateKotlinClass;(Class,String);generated", - "kotlin.jvm.internal;Reflection;getOrCreateKotlinClasses;(Class[]);generated", - "kotlin.jvm.internal;Reflection;getOrCreateKotlinPackage;(Class);generated", - "kotlin.jvm.internal;Reflection;nullableTypeOf;(Class);generated", - "kotlin.jvm.internal;Reflection;nullableTypeOf;(Class,KTypeProjection[]);generated", - "kotlin.jvm.internal;Reflection;renderLambdaToString;(FunctionBase);generated", - "kotlin.jvm.internal;Reflection;renderLambdaToString;(Lambda);generated", - "kotlin.jvm.internal;Reflection;setUpperBounds;(KTypeParameter,KType[]);generated", - "kotlin.jvm.internal;Reflection;typeOf;(Class);generated", - "kotlin.jvm.internal;Reflection;typeOf;(Class,KTypeProjection[]);generated", - "kotlin.jvm.internal;ReflectionFactory;ReflectionFactory;();generated", - "kotlin.jvm.internal;ReflectionFactory;createKotlinClass;(Class);generated", - "kotlin.jvm.internal;ReflectionFactory;createKotlinClass;(Class,String);generated", - "kotlin.jvm.internal;ReflectionFactory;getOrCreateKotlinClass;(Class);generated", - "kotlin.jvm.internal;ReflectionFactory;getOrCreateKotlinClass;(Class,String);generated", - "kotlin.jvm.internal;ReflectionFactory;renderLambdaToString;(FunctionBase);generated", - "kotlin.jvm.internal;ReflectionFactory;renderLambdaToString;(Lambda);generated", - "kotlin.jvm.internal;SerializedIr;SerializedIr;(String[]);generated", - "kotlin.jvm.internal;SerializedIr;b;();generated", - "kotlin.jvm.internal;ShortSpreadBuilder;ShortSpreadBuilder;(int);generated", - "kotlin.jvm.internal;ShortSpreadBuilder;add;(short);generated", - "kotlin.jvm.internal;ShortSpreadBuilder;toArray;();generated", - "kotlin.jvm.internal;SpreadBuilder;SpreadBuilder;(int);generated", - "kotlin.jvm.internal;SpreadBuilder;size;();generated", - "kotlin.jvm.internal;TypeIntrinsics;TypeIntrinsics;();generated", - "kotlin.jvm.internal;TypeIntrinsics;getFunctionArity;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;isFunctionOfArity;(Object,int);generated", - "kotlin.jvm.internal;TypeIntrinsics;isMutableCollection;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;isMutableIterable;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;isMutableIterator;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;isMutableList;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;isMutableListIterator;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;isMutableMap;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;isMutableMapEntry;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;isMutableSet;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;throwCce;(ClassCastException);generated", - "kotlin.jvm.internal;TypeIntrinsics;throwCce;(Object,String);generated", - "kotlin.jvm.internal;TypeIntrinsics;throwCce;(String);generated", - "kotlin.jvm.internal;TypeParameterReference$Companion;toString;(KTypeParameter);generated", - "kotlin.jvm.internal;TypeParameterReference;equals;(Object);generated", - "kotlin.jvm.internal;TypeParameterReference;hashCode;();generated", - "kotlin.jvm.internal;TypeParameterReference;toString;();generated", - "kotlin.jvm.internal;TypeReference;equals;(Object);generated", - "kotlin.jvm.internal;TypeReference;hashCode;();generated", - "kotlin.jvm;JvmClassMappingKt;getAnnotationClass;(Annotation);generated", - "kotlin.jvm;JvmClassMappingKt;getDeclaringJavaClass;(Enum);generated", - "kotlin.jvm;JvmClassMappingKt;getJavaClass;(KClass);generated", - "kotlin.jvm;JvmClassMappingKt;getJavaClass;(Object);generated", - "kotlin.jvm;JvmClassMappingKt;getJavaObjectType;(KClass);generated", - "kotlin.jvm;JvmClassMappingKt;getJavaPrimitiveType;(KClass);generated", - "kotlin.jvm;JvmClassMappingKt;getKotlinClass;(Class);generated", - "kotlin.jvm;JvmClassMappingKt;getRuntimeClassOfKClassInstance;(KClass);generated", - "kotlin.jvm;JvmClassMappingKt;isArrayOf;(Object[]);generated", - "kotlin.jvm;JvmDefault;JvmDefault;();generated", - "kotlin.jvm;JvmDefaultWithCompatibility;JvmDefaultWithCompatibility;();generated", - "kotlin.jvm;JvmDefaultWithoutCompatibility;JvmDefaultWithoutCompatibility;();generated", - "kotlin.jvm;JvmField;JvmField;();generated", "kotlin.jvm;JvmInline;JvmInline;();generated", - "kotlin.jvm;JvmMultifileClass;JvmMultifileClass;();generated", - "kotlin.jvm;JvmName;JvmName;(String);generated", "kotlin.jvm;JvmName;name;();generated", - "kotlin.jvm;JvmOverloads;JvmOverloads;();generated", - "kotlin.jvm;JvmRecord;JvmRecord;();generated", - "kotlin.jvm;JvmStatic;JvmStatic;();generated", - "kotlin.jvm;JvmSuppressWildcards;JvmSuppressWildcards;(boolean);generated", - "kotlin.jvm;JvmSuppressWildcards;suppress;();generated", - "kotlin.jvm;JvmSynthetic;JvmSynthetic;();generated", - "kotlin.jvm;JvmWildcard;JvmWildcard;();generated", - "kotlin.jvm;KotlinReflectionNotSupportedError;KotlinReflectionNotSupportedError;();generated", - "kotlin.jvm;KotlinReflectionNotSupportedError;KotlinReflectionNotSupportedError;(String);generated", - "kotlin.jvm;KotlinReflectionNotSupportedError;KotlinReflectionNotSupportedError;(String,Throwable);generated", - "kotlin.jvm;KotlinReflectionNotSupportedError;KotlinReflectionNotSupportedError;(Throwable);generated", - "kotlin.jvm;PurelyImplements;PurelyImplements;(String);generated", - "kotlin.jvm;PurelyImplements;value;();generated", - "kotlin.jvm;Strictfp;Strictfp;();generated", - "kotlin.jvm;Synchronized;Synchronized;();generated", - "kotlin.jvm;Throws;Throws;(KClass[]);generated", - "kotlin.jvm;Throws;exceptionClasses;();generated", - "kotlin.jvm;Transient;Transient;();generated", "kotlin.jvm;Volatile;Volatile;();generated", - "kotlin.math;MathKt;IEEErem;(double,double);generated", - "kotlin.math;MathKt;IEEErem;(float,float);generated", - "kotlin.math;MathKt;abs;(double);generated", "kotlin.math;MathKt;abs;(float);generated", - "kotlin.math;MathKt;abs;(int);generated", "kotlin.math;MathKt;abs;(long);generated", - "kotlin.math;MathKt;acos;(double);generated", "kotlin.math;MathKt;acos;(float);generated", - "kotlin.math;MathKt;acosh;(double);generated", "kotlin.math;MathKt;acosh;(float);generated", - "kotlin.math;MathKt;asin;(double);generated", "kotlin.math;MathKt;asin;(float);generated", - "kotlin.math;MathKt;asinh;(double);generated", "kotlin.math;MathKt;asinh;(float);generated", - "kotlin.math;MathKt;atan2;(double,double);generated", - "kotlin.math;MathKt;atan2;(float,float);generated", - "kotlin.math;MathKt;atan;(double);generated", "kotlin.math;MathKt;atan;(float);generated", - "kotlin.math;MathKt;atanh;(double);generated", "kotlin.math;MathKt;atanh;(float);generated", - "kotlin.math;MathKt;cbrt;(double);generated", "kotlin.math;MathKt;cbrt;(float);generated", - "kotlin.math;MathKt;ceil;(double);generated", "kotlin.math;MathKt;ceil;(float);generated", - "kotlin.math;MathKt;cos;(double);generated", "kotlin.math;MathKt;cos;(float);generated", - "kotlin.math;MathKt;cosh;(double);generated", "kotlin.math;MathKt;cosh;(float);generated", - "kotlin.math;MathKt;exp;(double);generated", "kotlin.math;MathKt;exp;(float);generated", - "kotlin.math;MathKt;expm1;(double);generated", "kotlin.math;MathKt;expm1;(float);generated", - "kotlin.math;MathKt;floor;(double);generated", "kotlin.math;MathKt;floor;(float);generated", - "kotlin.math;MathKt;getAbsoluteValue;(double);generated", - "kotlin.math;MathKt;getAbsoluteValue;(float);generated", - "kotlin.math;MathKt;getAbsoluteValue;(int);generated", - "kotlin.math;MathKt;getAbsoluteValue;(long);generated", - "kotlin.math;MathKt;getE;();generated", "kotlin.math;MathKt;getPI;();generated", - "kotlin.math;MathKt;getSign;(double);generated", - "kotlin.math;MathKt;getSign;(float);generated", - "kotlin.math;MathKt;getSign;(int);generated", "kotlin.math;MathKt;getSign;(long);generated", - "kotlin.math;MathKt;getUlp;(double);generated", - "kotlin.math;MathKt;getUlp;(float);generated", - "kotlin.math;MathKt;hypot;(double,double);generated", - "kotlin.math;MathKt;hypot;(float,float);generated", - "kotlin.math;MathKt;ln1p;(double);generated", "kotlin.math;MathKt;ln1p;(float);generated", - "kotlin.math;MathKt;ln;(double);generated", "kotlin.math;MathKt;ln;(float);generated", - "kotlin.math;MathKt;log10;(double);generated", "kotlin.math;MathKt;log10;(float);generated", - "kotlin.math;MathKt;log2;(double);generated", "kotlin.math;MathKt;log2;(float);generated", - "kotlin.math;MathKt;log;(double,double);generated", - "kotlin.math;MathKt;log;(float,float);generated", - "kotlin.math;MathKt;max;(double,double);generated", - "kotlin.math;MathKt;max;(float,float);generated", - "kotlin.math;MathKt;max;(int,int);generated", - "kotlin.math;MathKt;max;(long,long);generated", - "kotlin.math;MathKt;min;(double,double);generated", - "kotlin.math;MathKt;min;(float,float);generated", - "kotlin.math;MathKt;min;(int,int);generated", - "kotlin.math;MathKt;min;(long,long);generated", - "kotlin.math;MathKt;nextDown;(double);generated", - "kotlin.math;MathKt;nextDown;(float);generated", - "kotlin.math;MathKt;nextTowards;(double,double);generated", - "kotlin.math;MathKt;nextTowards;(float,float);generated", - "kotlin.math;MathKt;nextUp;(double);generated", - "kotlin.math;MathKt;nextUp;(float);generated", - "kotlin.math;MathKt;pow;(double,double);generated", - "kotlin.math;MathKt;pow;(double,int);generated", - "kotlin.math;MathKt;pow;(float,float);generated", - "kotlin.math;MathKt;pow;(float,int);generated", - "kotlin.math;MathKt;round;(double);generated", "kotlin.math;MathKt;round;(float);generated", - "kotlin.math;MathKt;roundToInt;(double);generated", - "kotlin.math;MathKt;roundToInt;(float);generated", - "kotlin.math;MathKt;roundToLong;(double);generated", - "kotlin.math;MathKt;roundToLong;(float);generated", - "kotlin.math;MathKt;sign;(double);generated", "kotlin.math;MathKt;sign;(float);generated", - "kotlin.math;MathKt;sin;(double);generated", "kotlin.math;MathKt;sin;(float);generated", - "kotlin.math;MathKt;sinh;(double);generated", "kotlin.math;MathKt;sinh;(float);generated", - "kotlin.math;MathKt;sqrt;(double);generated", "kotlin.math;MathKt;sqrt;(float);generated", - "kotlin.math;MathKt;tan;(double);generated", "kotlin.math;MathKt;tan;(float);generated", - "kotlin.math;MathKt;tanh;(double);generated", "kotlin.math;MathKt;tanh;(float);generated", - "kotlin.math;MathKt;truncate;(double);generated", - "kotlin.math;MathKt;truncate;(float);generated", - "kotlin.math;MathKt;withSign;(double,double);generated", - "kotlin.math;MathKt;withSign;(double,int);generated", - "kotlin.math;MathKt;withSign;(float,float);generated", - "kotlin.math;MathKt;withSign;(float,int);generated", - "kotlin.math;UMathKt;max;(int,int);generated", - "kotlin.math;UMathKt;max;(long,long);generated", - "kotlin.math;UMathKt;min;(int,int);generated", - "kotlin.math;UMathKt;min;(long,long);generated", - "kotlin.native.concurrent;SharedImmutable;SharedImmutable;();generated", - "kotlin.native.concurrent;ThreadLocal;ThreadLocal;();generated", - "kotlin.native;CName;CName;(String,String);generated", - "kotlin.native;CName;externName;();generated", "kotlin.native;CName;shortName;();generated", - "kotlin.properties;Delegates;notNull;();generated", - "kotlin.properties;Delegates;observable;(Object,Function3);generated", - "kotlin.properties;Delegates;vetoable;(Object,Function3);generated", - "kotlin.properties;PropertyDelegateProvider;provideDelegate;(Object,KProperty);generated", - "kotlin.properties;ReadOnlyProperty;getValue;(Object,KProperty);generated", - "kotlin.properties;ReadWriteProperty;setValue;(Object,KProperty,Object);generated", - "kotlin.random;Random;Random;();generated", "kotlin.random;Random;nextBits;(int);generated", - "kotlin.random;Random;nextBoolean;();generated", - "kotlin.random;Random;nextBytes;(int);generated", - "kotlin.random;Random;nextDouble;();generated", - "kotlin.random;Random;nextDouble;(double);generated", - "kotlin.random;Random;nextDouble;(double,double);generated", - "kotlin.random;Random;nextFloat;();generated", "kotlin.random;Random;nextInt;();generated", - "kotlin.random;Random;nextInt;(int);generated", - "kotlin.random;Random;nextInt;(int,int);generated", - "kotlin.random;Random;nextLong;();generated", - "kotlin.random;Random;nextLong;(long);generated", - "kotlin.random;Random;nextLong;(long,long);generated", - "kotlin.random;RandomKt;Random;(int);generated", - "kotlin.random;RandomKt;Random;(long);generated", - "kotlin.random;RandomKt;nextInt;(Random,IntRange);generated", - "kotlin.random;RandomKt;nextLong;(Random,LongRange);generated", - "kotlin.random;URandomKt;nextUBytes;(Random,int);generated", - "kotlin.random;URandomKt;nextUInt;(Random);generated", - "kotlin.random;URandomKt;nextUInt;(Random,UIntRange);generated", - "kotlin.random;URandomKt;nextUInt;(Random,int);generated", - "kotlin.random;URandomKt;nextUInt;(Random,int,int);generated", - "kotlin.random;URandomKt;nextULong;(Random);generated", - "kotlin.random;URandomKt;nextULong;(Random,ULongRange);generated", - "kotlin.random;URandomKt;nextULong;(Random,long);generated", - "kotlin.random;URandomKt;nextULong;(Random,long,long);generated", - "kotlin.ranges;CharProgression$Companion;fromClosedRange;(char,char,int);generated", - "kotlin.ranges;CharProgression;equals;(Object);generated", - "kotlin.ranges;CharProgression;getFirst;();generated", - "kotlin.ranges;CharProgression;getLast;();generated", - "kotlin.ranges;CharProgression;getStep;();generated", - "kotlin.ranges;CharProgression;hashCode;();generated", - "kotlin.ranges;CharProgression;isEmpty;();generated", - "kotlin.ranges;CharProgression;toString;();generated", - "kotlin.ranges;CharRange;CharRange;(char,char);generated", - "kotlin.ranges;CharRange;contains;(char);generated", - "kotlin.ranges;CharRange;equals;(Object);generated", - "kotlin.ranges;CharRange;hashCode;();generated", - "kotlin.ranges;CharRange;toString;();generated", - "kotlin.ranges;ClosedFloatingPointRange;lessThanOrEquals;(Comparable,Comparable);generated", - "kotlin.ranges;ClosedRange;contains;(Comparable);generated", - "kotlin.ranges;ClosedRange;getEndInclusive;();generated", - "kotlin.ranges;ClosedRange;getStart;();generated", - "kotlin.ranges;ClosedRange;isEmpty;();generated", - "kotlin.ranges;IntProgression$Companion;fromClosedRange;(int,int,int);generated", - "kotlin.ranges;IntProgression;equals;(Object);generated", - "kotlin.ranges;IntProgression;getFirst;();generated", - "kotlin.ranges;IntProgression;getLast;();generated", - "kotlin.ranges;IntProgression;getStep;();generated", - "kotlin.ranges;IntProgression;hashCode;();generated", - "kotlin.ranges;IntProgression;isEmpty;();generated", - "kotlin.ranges;IntProgression;toString;();generated", - "kotlin.ranges;IntRange;IntRange;(int,int);generated", - "kotlin.ranges;IntRange;contains;(int);generated", - "kotlin.ranges;IntRange;equals;(Object);generated", - "kotlin.ranges;IntRange;hashCode;();generated", - "kotlin.ranges;IntRange;toString;();generated", - "kotlin.ranges;LongProgression$Companion;fromClosedRange;(long,long,long);generated", - "kotlin.ranges;LongProgression;equals;(Object);generated", - "kotlin.ranges;LongProgression;getFirst;();generated", - "kotlin.ranges;LongProgression;getLast;();generated", - "kotlin.ranges;LongProgression;getStep;();generated", - "kotlin.ranges;LongProgression;hashCode;();generated", - "kotlin.ranges;LongProgression;isEmpty;();generated", - "kotlin.ranges;LongProgression;toString;();generated", - "kotlin.ranges;LongRange;LongRange;(long,long);generated", - "kotlin.ranges;LongRange;contains;(long);generated", - "kotlin.ranges;LongRange;equals;(Object);generated", - "kotlin.ranges;LongRange;hashCode;();generated", - "kotlin.ranges;LongRange;toString;();generated", - "kotlin.ranges;OpenEndRange;contains;(Comparable);generated", - "kotlin.ranges;OpenEndRange;getEndExclusive;();generated", - "kotlin.ranges;OpenEndRange;getStart;();generated", - "kotlin.ranges;OpenEndRange;isEmpty;();generated", - "kotlin.ranges;RangesKt;byteRangeContains;(ClosedRange,double);generated", - "kotlin.ranges;RangesKt;byteRangeContains;(ClosedRange,float);generated", - "kotlin.ranges;RangesKt;byteRangeContains;(ClosedRange,int);generated", - "kotlin.ranges;RangesKt;byteRangeContains;(ClosedRange,long);generated", - "kotlin.ranges;RangesKt;byteRangeContains;(ClosedRange,short);generated", - "kotlin.ranges;RangesKt;byteRangeContains;(OpenEndRange,int);generated", - "kotlin.ranges;RangesKt;byteRangeContains;(OpenEndRange,long);generated", - "kotlin.ranges;RangesKt;byteRangeContains;(OpenEndRange,short);generated", - "kotlin.ranges;RangesKt;coerceAtLeast;(byte,byte);generated", - "kotlin.ranges;RangesKt;coerceAtLeast;(double,double);generated", - "kotlin.ranges;RangesKt;coerceAtLeast;(float,float);generated", - "kotlin.ranges;RangesKt;coerceAtLeast;(int,int);generated", - "kotlin.ranges;RangesKt;coerceAtLeast;(long,long);generated", - "kotlin.ranges;RangesKt;coerceAtLeast;(short,short);generated", - "kotlin.ranges;RangesKt;coerceAtMost;(byte,byte);generated", - "kotlin.ranges;RangesKt;coerceAtMost;(double,double);generated", - "kotlin.ranges;RangesKt;coerceAtMost;(float,float);generated", - "kotlin.ranges;RangesKt;coerceAtMost;(int,int);generated", - "kotlin.ranges;RangesKt;coerceAtMost;(long,long);generated", - "kotlin.ranges;RangesKt;coerceAtMost;(short,short);generated", - "kotlin.ranges;RangesKt;coerceIn;(byte,byte,byte);generated", - "kotlin.ranges;RangesKt;coerceIn;(double,double,double);generated", - "kotlin.ranges;RangesKt;coerceIn;(float,float,float);generated", - "kotlin.ranges;RangesKt;coerceIn;(int,ClosedRange);generated", - "kotlin.ranges;RangesKt;coerceIn;(int,int,int);generated", - "kotlin.ranges;RangesKt;coerceIn;(long,ClosedRange);generated", - "kotlin.ranges;RangesKt;coerceIn;(long,long,long);generated", - "kotlin.ranges;RangesKt;coerceIn;(short,short,short);generated", - "kotlin.ranges;RangesKt;contains;(CharRange,Character);generated", - "kotlin.ranges;RangesKt;contains;(ClosedRange,Object);generated", - "kotlin.ranges;RangesKt;contains;(IntRange,Integer);generated", - "kotlin.ranges;RangesKt;contains;(IntRange,byte);generated", - "kotlin.ranges;RangesKt;contains;(IntRange,long);generated", - "kotlin.ranges;RangesKt;contains;(IntRange,short);generated", - "kotlin.ranges;RangesKt;contains;(LongRange,Long);generated", - "kotlin.ranges;RangesKt;contains;(LongRange,byte);generated", - "kotlin.ranges;RangesKt;contains;(LongRange,int);generated", - "kotlin.ranges;RangesKt;contains;(LongRange,short);generated", - "kotlin.ranges;RangesKt;contains;(OpenEndRange,Object);generated", - "kotlin.ranges;RangesKt;doubleRangeContains;(ClosedRange,byte);generated", - "kotlin.ranges;RangesKt;doubleRangeContains;(ClosedRange,float);generated", - "kotlin.ranges;RangesKt;doubleRangeContains;(ClosedRange,int);generated", - "kotlin.ranges;RangesKt;doubleRangeContains;(ClosedRange,long);generated", - "kotlin.ranges;RangesKt;doubleRangeContains;(ClosedRange,short);generated", - "kotlin.ranges;RangesKt;doubleRangeContains;(OpenEndRange,float);generated", - "kotlin.ranges;RangesKt;downTo;(byte,byte);generated", - "kotlin.ranges;RangesKt;downTo;(byte,int);generated", - "kotlin.ranges;RangesKt;downTo;(byte,long);generated", - "kotlin.ranges;RangesKt;downTo;(byte,short);generated", - "kotlin.ranges;RangesKt;downTo;(char,char);generated", - "kotlin.ranges;RangesKt;downTo;(int,byte);generated", - "kotlin.ranges;RangesKt;downTo;(int,int);generated", - "kotlin.ranges;RangesKt;downTo;(int,long);generated", - "kotlin.ranges;RangesKt;downTo;(int,short);generated", - "kotlin.ranges;RangesKt;downTo;(long,byte);generated", - "kotlin.ranges;RangesKt;downTo;(long,int);generated", - "kotlin.ranges;RangesKt;downTo;(long,long);generated", - "kotlin.ranges;RangesKt;downTo;(long,short);generated", - "kotlin.ranges;RangesKt;downTo;(short,byte);generated", - "kotlin.ranges;RangesKt;downTo;(short,int);generated", - "kotlin.ranges;RangesKt;downTo;(short,long);generated", - "kotlin.ranges;RangesKt;downTo;(short,short);generated", - "kotlin.ranges;RangesKt;first;(CharProgression);generated", - "kotlin.ranges;RangesKt;first;(IntProgression);generated", - "kotlin.ranges;RangesKt;first;(LongProgression);generated", - "kotlin.ranges;RangesKt;firstOrNull;(CharProgression);generated", - "kotlin.ranges;RangesKt;firstOrNull;(IntProgression);generated", - "kotlin.ranges;RangesKt;firstOrNull;(LongProgression);generated", - "kotlin.ranges;RangesKt;floatRangeContains;(ClosedRange,byte);generated", - "kotlin.ranges;RangesKt;floatRangeContains;(ClosedRange,double);generated", - "kotlin.ranges;RangesKt;floatRangeContains;(ClosedRange,int);generated", - "kotlin.ranges;RangesKt;floatRangeContains;(ClosedRange,long);generated", - "kotlin.ranges;RangesKt;floatRangeContains;(ClosedRange,short);generated", - "kotlin.ranges;RangesKt;intRangeContains;(ClosedRange,byte);generated", - "kotlin.ranges;RangesKt;intRangeContains;(ClosedRange,double);generated", - "kotlin.ranges;RangesKt;intRangeContains;(ClosedRange,float);generated", - "kotlin.ranges;RangesKt;intRangeContains;(ClosedRange,long);generated", - "kotlin.ranges;RangesKt;intRangeContains;(ClosedRange,short);generated", - "kotlin.ranges;RangesKt;intRangeContains;(OpenEndRange,byte);generated", - "kotlin.ranges;RangesKt;intRangeContains;(OpenEndRange,long);generated", - "kotlin.ranges;RangesKt;intRangeContains;(OpenEndRange,short);generated", - "kotlin.ranges;RangesKt;last;(CharProgression);generated", - "kotlin.ranges;RangesKt;last;(IntProgression);generated", - "kotlin.ranges;RangesKt;last;(LongProgression);generated", - "kotlin.ranges;RangesKt;lastOrNull;(CharProgression);generated", - "kotlin.ranges;RangesKt;lastOrNull;(IntProgression);generated", - "kotlin.ranges;RangesKt;lastOrNull;(LongProgression);generated", - "kotlin.ranges;RangesKt;longRangeContains;(ClosedRange,byte);generated", - "kotlin.ranges;RangesKt;longRangeContains;(ClosedRange,double);generated", - "kotlin.ranges;RangesKt;longRangeContains;(ClosedRange,float);generated", - "kotlin.ranges;RangesKt;longRangeContains;(ClosedRange,int);generated", - "kotlin.ranges;RangesKt;longRangeContains;(ClosedRange,short);generated", - "kotlin.ranges;RangesKt;longRangeContains;(OpenEndRange,byte);generated", - "kotlin.ranges;RangesKt;longRangeContains;(OpenEndRange,int);generated", - "kotlin.ranges;RangesKt;longRangeContains;(OpenEndRange,short);generated", - "kotlin.ranges;RangesKt;random;(CharRange);generated", - "kotlin.ranges;RangesKt;random;(CharRange,Random);generated", - "kotlin.ranges;RangesKt;random;(IntRange);generated", - "kotlin.ranges;RangesKt;random;(IntRange,Random);generated", - "kotlin.ranges;RangesKt;random;(LongRange);generated", - "kotlin.ranges;RangesKt;random;(LongRange,Random);generated", - "kotlin.ranges;RangesKt;randomOrNull;(CharRange);generated", - "kotlin.ranges;RangesKt;randomOrNull;(CharRange,Random);generated", - "kotlin.ranges;RangesKt;randomOrNull;(IntRange);generated", - "kotlin.ranges;RangesKt;randomOrNull;(IntRange,Random);generated", - "kotlin.ranges;RangesKt;randomOrNull;(LongRange);generated", - "kotlin.ranges;RangesKt;randomOrNull;(LongRange,Random);generated", - "kotlin.ranges;RangesKt;rangeTo;(double,double);generated", - "kotlin.ranges;RangesKt;rangeTo;(float,float);generated", - "kotlin.ranges;RangesKt;rangeUntil;(byte,byte);generated", - "kotlin.ranges;RangesKt;rangeUntil;(byte,int);generated", - "kotlin.ranges;RangesKt;rangeUntil;(byte,long);generated", - "kotlin.ranges;RangesKt;rangeUntil;(byte,short);generated", - "kotlin.ranges;RangesKt;rangeUntil;(char,char);generated", - "kotlin.ranges;RangesKt;rangeUntil;(double,double);generated", - "kotlin.ranges;RangesKt;rangeUntil;(float,float);generated", - "kotlin.ranges;RangesKt;rangeUntil;(int,byte);generated", - "kotlin.ranges;RangesKt;rangeUntil;(int,int);generated", - "kotlin.ranges;RangesKt;rangeUntil;(int,long);generated", - "kotlin.ranges;RangesKt;rangeUntil;(int,short);generated", - "kotlin.ranges;RangesKt;rangeUntil;(long,byte);generated", - "kotlin.ranges;RangesKt;rangeUntil;(long,int);generated", - "kotlin.ranges;RangesKt;rangeUntil;(long,long);generated", - "kotlin.ranges;RangesKt;rangeUntil;(long,short);generated", - "kotlin.ranges;RangesKt;rangeUntil;(short,byte);generated", - "kotlin.ranges;RangesKt;rangeUntil;(short,int);generated", - "kotlin.ranges;RangesKt;rangeUntil;(short,long);generated", - "kotlin.ranges;RangesKt;rangeUntil;(short,short);generated", - "kotlin.ranges;RangesKt;reversed;(CharProgression);generated", - "kotlin.ranges;RangesKt;reversed;(IntProgression);generated", - "kotlin.ranges;RangesKt;reversed;(LongProgression);generated", - "kotlin.ranges;RangesKt;shortRangeContains;(ClosedRange,byte);generated", - "kotlin.ranges;RangesKt;shortRangeContains;(ClosedRange,double);generated", - "kotlin.ranges;RangesKt;shortRangeContains;(ClosedRange,float);generated", - "kotlin.ranges;RangesKt;shortRangeContains;(ClosedRange,int);generated", - "kotlin.ranges;RangesKt;shortRangeContains;(ClosedRange,long);generated", - "kotlin.ranges;RangesKt;shortRangeContains;(OpenEndRange,byte);generated", - "kotlin.ranges;RangesKt;shortRangeContains;(OpenEndRange,int);generated", - "kotlin.ranges;RangesKt;shortRangeContains;(OpenEndRange,long);generated", - "kotlin.ranges;RangesKt;step;(CharProgression,int);generated", - "kotlin.ranges;RangesKt;step;(IntProgression,int);generated", - "kotlin.ranges;RangesKt;step;(LongProgression,long);generated", - "kotlin.ranges;RangesKt;until;(byte,byte);generated", - "kotlin.ranges;RangesKt;until;(byte,int);generated", - "kotlin.ranges;RangesKt;until;(byte,long);generated", - "kotlin.ranges;RangesKt;until;(byte,short);generated", - "kotlin.ranges;RangesKt;until;(char,char);generated", - "kotlin.ranges;RangesKt;until;(int,byte);generated", - "kotlin.ranges;RangesKt;until;(int,int);generated", - "kotlin.ranges;RangesKt;until;(int,long);generated", - "kotlin.ranges;RangesKt;until;(int,short);generated", - "kotlin.ranges;RangesKt;until;(long,byte);generated", - "kotlin.ranges;RangesKt;until;(long,int);generated", - "kotlin.ranges;RangesKt;until;(long,long);generated", - "kotlin.ranges;RangesKt;until;(long,short);generated", - "kotlin.ranges;RangesKt;until;(short,byte);generated", - "kotlin.ranges;RangesKt;until;(short,int);generated", - "kotlin.ranges;RangesKt;until;(short,long);generated", - "kotlin.ranges;RangesKt;until;(short,short);generated", - "kotlin.ranges;UIntProgression$Companion;fromClosedRange;(int,int,int);generated", - "kotlin.ranges;UIntProgression;equals;(Object);generated", - "kotlin.ranges;UIntProgression;getFirst;();generated", - "kotlin.ranges;UIntProgression;getLast;();generated", - "kotlin.ranges;UIntProgression;getStep;();generated", - "kotlin.ranges;UIntProgression;hashCode;();generated", - "kotlin.ranges;UIntProgression;isEmpty;();generated", - "kotlin.ranges;UIntProgression;toString;();generated", - "kotlin.ranges;UIntRange;UIntRange;(int,int);generated", - "kotlin.ranges;UIntRange;contains;(int);generated", - "kotlin.ranges;UIntRange;equals;(Object);generated", - "kotlin.ranges;UIntRange;hashCode;();generated", - "kotlin.ranges;UIntRange;toString;();generated", - "kotlin.ranges;ULongProgression$Companion;fromClosedRange;(long,long,long);generated", - "kotlin.ranges;ULongProgression;equals;(Object);generated", - "kotlin.ranges;ULongProgression;getFirst;();generated", - "kotlin.ranges;ULongProgression;getLast;();generated", - "kotlin.ranges;ULongProgression;getStep;();generated", - "kotlin.ranges;ULongProgression;hashCode;();generated", - "kotlin.ranges;ULongProgression;isEmpty;();generated", - "kotlin.ranges;ULongProgression;toString;();generated", - "kotlin.ranges;ULongRange;ULongRange;(long,long);generated", - "kotlin.ranges;ULongRange;contains;(long);generated", - "kotlin.ranges;ULongRange;equals;(Object);generated", - "kotlin.ranges;ULongRange;hashCode;();generated", - "kotlin.ranges;ULongRange;toString;();generated", - "kotlin.ranges;URangesKt;coerceAtLeast;(byte,byte);generated", - "kotlin.ranges;URangesKt;coerceAtLeast;(int,int);generated", - "kotlin.ranges;URangesKt;coerceAtLeast;(long,long);generated", - "kotlin.ranges;URangesKt;coerceAtLeast;(short,short);generated", - "kotlin.ranges;URangesKt;coerceAtMost;(byte,byte);generated", - "kotlin.ranges;URangesKt;coerceAtMost;(int,int);generated", - "kotlin.ranges;URangesKt;coerceAtMost;(long,long);generated", - "kotlin.ranges;URangesKt;coerceAtMost;(short,short);generated", - "kotlin.ranges;URangesKt;coerceIn;(byte,byte,byte);generated", - "kotlin.ranges;URangesKt;coerceIn;(int,ClosedRange);generated", - "kotlin.ranges;URangesKt;coerceIn;(int,int,int);generated", - "kotlin.ranges;URangesKt;coerceIn;(long,ClosedRange);generated", - "kotlin.ranges;URangesKt;coerceIn;(long,long,long);generated", - "kotlin.ranges;URangesKt;coerceIn;(short,short,short);generated", - "kotlin.ranges;URangesKt;contains;(UIntRange,UInt);generated", - "kotlin.ranges;URangesKt;contains;(UIntRange,byte);generated", - "kotlin.ranges;URangesKt;contains;(UIntRange,long);generated", - "kotlin.ranges;URangesKt;contains;(UIntRange,short);generated", - "kotlin.ranges;URangesKt;contains;(ULongRange,ULong);generated", - "kotlin.ranges;URangesKt;contains;(ULongRange,byte);generated", - "kotlin.ranges;URangesKt;contains;(ULongRange,int);generated", - "kotlin.ranges;URangesKt;contains;(ULongRange,short);generated", - "kotlin.ranges;URangesKt;downTo;(byte,byte);generated", - "kotlin.ranges;URangesKt;downTo;(int,int);generated", - "kotlin.ranges;URangesKt;downTo;(long,long);generated", - "kotlin.ranges;URangesKt;downTo;(short,short);generated", - "kotlin.ranges;URangesKt;first;(UIntProgression);generated", - "kotlin.ranges;URangesKt;first;(ULongProgression);generated", - "kotlin.ranges;URangesKt;firstOrNull;(UIntProgression);generated", - "kotlin.ranges;URangesKt;firstOrNull;(ULongProgression);generated", - "kotlin.ranges;URangesKt;last;(UIntProgression);generated", - "kotlin.ranges;URangesKt;last;(ULongProgression);generated", - "kotlin.ranges;URangesKt;lastOrNull;(UIntProgression);generated", - "kotlin.ranges;URangesKt;lastOrNull;(ULongProgression);generated", - "kotlin.ranges;URangesKt;random;(UIntRange);generated", - "kotlin.ranges;URangesKt;random;(UIntRange,Random);generated", - "kotlin.ranges;URangesKt;random;(ULongRange);generated", - "kotlin.ranges;URangesKt;random;(ULongRange,Random);generated", - "kotlin.ranges;URangesKt;randomOrNull;(UIntRange);generated", - "kotlin.ranges;URangesKt;randomOrNull;(UIntRange,Random);generated", - "kotlin.ranges;URangesKt;randomOrNull;(ULongRange);generated", - "kotlin.ranges;URangesKt;randomOrNull;(ULongRange,Random);generated", - "kotlin.ranges;URangesKt;rangeUntil;(byte,byte);generated", - "kotlin.ranges;URangesKt;rangeUntil;(int,int);generated", - "kotlin.ranges;URangesKt;rangeUntil;(long,long);generated", - "kotlin.ranges;URangesKt;rangeUntil;(short,short);generated", - "kotlin.ranges;URangesKt;reversed;(UIntProgression);generated", - "kotlin.ranges;URangesKt;reversed;(ULongProgression);generated", - "kotlin.ranges;URangesKt;step;(UIntProgression,int);generated", - "kotlin.ranges;URangesKt;step;(ULongProgression,long);generated", - "kotlin.ranges;URangesKt;until;(byte,byte);generated", - "kotlin.ranges;URangesKt;until;(int,int);generated", - "kotlin.ranges;URangesKt;until;(long,long);generated", - "kotlin.ranges;URangesKt;until;(short,short);generated", - "kotlin.reflect;KAnnotatedElement;getAnnotations;();generated", - "kotlin.reflect;KCallable;call;(Object[]);generated", - "kotlin.reflect;KCallable;callBy;(Map);generated", - "kotlin.reflect;KCallable;getName;();generated", - "kotlin.reflect;KCallable;getParameters;();generated", - "kotlin.reflect;KCallable;getReturnType;();generated", - "kotlin.reflect;KCallable;getTypeParameters;();generated", - "kotlin.reflect;KCallable;getVisibility;();generated", - "kotlin.reflect;KCallable;isAbstract;();generated", - "kotlin.reflect;KCallable;isFinal;();generated", - "kotlin.reflect;KCallable;isOpen;();generated", - "kotlin.reflect;KCallable;isSuspend;();generated", - "kotlin.reflect;KClass;equals;(Object);generated", - "kotlin.reflect;KClass;getConstructors;();generated", - "kotlin.reflect;KClass;getNestedClasses;();generated", - "kotlin.reflect;KClass;getObjectInstance;();generated", - "kotlin.reflect;KClass;getQualifiedName;();generated", - "kotlin.reflect;KClass;getSealedSubclasses;();generated", - "kotlin.reflect;KClass;getSimpleName;();generated", - "kotlin.reflect;KClass;getSupertypes;();generated", - "kotlin.reflect;KClass;getTypeParameters;();generated", - "kotlin.reflect;KClass;getVisibility;();generated", - "kotlin.reflect;KClass;hashCode;();generated", - "kotlin.reflect;KClass;isAbstract;();generated", - "kotlin.reflect;KClass;isCompanion;();generated", - "kotlin.reflect;KClass;isData;();generated", "kotlin.reflect;KClass;isFinal;();generated", - "kotlin.reflect;KClass;isFun;();generated", "kotlin.reflect;KClass;isInner;();generated", - "kotlin.reflect;KClass;isInstance;(Object);generated", - "kotlin.reflect;KClass;isOpen;();generated", "kotlin.reflect;KClass;isSealed;();generated", - "kotlin.reflect;KClass;isValue;();generated", - "kotlin.reflect;KDeclarationContainer;getMembers;();generated", - "kotlin.reflect;KFunction;isExternal;();generated", - "kotlin.reflect;KFunction;isInfix;();generated", - "kotlin.reflect;KFunction;isInline;();generated", - "kotlin.reflect;KFunction;isOperator;();generated", - "kotlin.reflect;KMutableProperty0;set;(Object);generated", - "kotlin.reflect;KMutableProperty1;set;(Object,Object);generated", - "kotlin.reflect;KMutableProperty2;set;(Object,Object,Object);generated", - "kotlin.reflect;KMutableProperty;getSetter;();generated", - "kotlin.reflect;KParameter$Kind;valueOf;(String);generated", - "kotlin.reflect;KParameter$Kind;values;();generated", - "kotlin.reflect;KParameter;getIndex;();generated", - "kotlin.reflect;KParameter;getKind;();generated", - "kotlin.reflect;KParameter;getName;();generated", - "kotlin.reflect;KParameter;getType;();generated", - "kotlin.reflect;KParameter;isOptional;();generated", - "kotlin.reflect;KParameter;isVararg;();generated", - "kotlin.reflect;KProperty$Accessor;getProperty;();generated", - "kotlin.reflect;KProperty0;get;();generated", - "kotlin.reflect;KProperty0;getDelegate;();generated", - "kotlin.reflect;KProperty1;get;(Object);generated", - "kotlin.reflect;KProperty1;getDelegate;(Object);generated", - "kotlin.reflect;KProperty2;get;(Object,Object);generated", - "kotlin.reflect;KProperty2;getDelegate;(Object,Object);generated", - "kotlin.reflect;KProperty;getGetter;();generated", - "kotlin.reflect;KProperty;isConst;();generated", - "kotlin.reflect;KProperty;isLateinit;();generated", - "kotlin.reflect;KType;getArguments;();generated", - "kotlin.reflect;KType;getClassifier;();generated", - "kotlin.reflect;KType;isMarkedNullable;();generated", - "kotlin.reflect;KTypeParameter;getName;();generated", - "kotlin.reflect;KTypeParameter;getUpperBounds;();generated", - "kotlin.reflect;KTypeParameter;getVariance;();generated", - "kotlin.reflect;KTypeParameter;isReified;();generated", - "kotlin.reflect;KTypeProjection$Companion;getSTAR;();generated", - "kotlin.reflect;KTypeProjection;component1;();generated", - "kotlin.reflect;KTypeProjection;equals;(Object);generated", - "kotlin.reflect;KTypeProjection;getVariance;();generated", - "kotlin.reflect;KTypeProjection;hashCode;();generated", - "kotlin.reflect;KVariance;valueOf;(String);generated", - "kotlin.reflect;KVariance;values;();generated", - "kotlin.reflect;KVisibility;valueOf;(String);generated", - "kotlin.reflect;KVisibility;values;();generated", - "kotlin.reflect;TypeOfKt;typeOf;();generated", - "kotlin.sequences;Sequence;iterator;();generated", - "kotlin.sequences;SequenceScope;yield;(Object);generated", - "kotlin.sequences;SequenceScope;yieldAll;(Iterable);generated", - "kotlin.sequences;SequenceScope;yieldAll;(Iterator);generated", - "kotlin.sequences;SequencesKt;Sequence;(Function0);generated", - "kotlin.sequences;SequencesKt;all;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;any;(Sequence);generated", - "kotlin.sequences;SequencesKt;any;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;asIterable;(Sequence);generated", - "kotlin.sequences;SequencesKt;asSequence;(Enumeration);generated", - "kotlin.sequences;SequencesKt;asSequence;(Iterator);generated", - "kotlin.sequences;SequencesKt;associate;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;associateBy;(Sequence,Function1,Function1);generated", - "kotlin.sequences;SequencesKt;averageOfByte;(Sequence);generated", - "kotlin.sequences;SequencesKt;averageOfDouble;(Sequence);generated", - "kotlin.sequences;SequencesKt;averageOfFloat;(Sequence);generated", - "kotlin.sequences;SequencesKt;averageOfInt;(Sequence);generated", - "kotlin.sequences;SequencesKt;averageOfLong;(Sequence);generated", - "kotlin.sequences;SequencesKt;averageOfShort;(Sequence);generated", - "kotlin.sequences;SequencesKt;chunked;(Sequence,int);generated", - "kotlin.sequences;SequencesKt;contains;(Sequence,Object);generated", - "kotlin.sequences;SequencesKt;count;(Sequence);generated", - "kotlin.sequences;SequencesKt;count;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;emptySequence;();generated", - "kotlin.sequences;SequencesKt;filterIndexed;(Sequence,Function2);generated", - "kotlin.sequences;SequencesKt;flatMapIndexedIterable;(Sequence,Function2);generated", - "kotlin.sequences;SequencesKt;flatMapIndexedSequence;(Sequence,Function2);generated", - "kotlin.sequences;SequencesKt;forEach;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;forEachIndexed;(Sequence,Function2);generated", - "kotlin.sequences;SequencesKt;groupBy;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;groupBy;(Sequence,Function1,Function1);generated", - "kotlin.sequences;SequencesKt;groupingBy;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;ifEmpty;(Sequence,Function0);generated", - "kotlin.sequences;SequencesKt;indexOf;(Sequence,Object);generated", - "kotlin.sequences;SequencesKt;indexOfFirst;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;indexOfLast;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;iterator;(SuspendFunction1);generated", - "kotlin.sequences;SequencesKt;lastIndexOf;(Sequence,Object);generated", - "kotlin.sequences;SequencesKt;max;(Sequence);generated", - "kotlin.sequences;SequencesKt;maxOf;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;maxOfOrNull;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;maxOrNull;(Sequence);generated", - "kotlin.sequences;SequencesKt;maxOrThrow;(Sequence);generated", - "kotlin.sequences;SequencesKt;min;(Sequence);generated", - "kotlin.sequences;SequencesKt;minOf;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;minOfOrNull;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;minOrNull;(Sequence);generated", - "kotlin.sequences;SequencesKt;minOrThrow;(Sequence);generated", - "kotlin.sequences;SequencesKt;minus;(Sequence,Iterable);generated", - "kotlin.sequences;SequencesKt;minus;(Sequence,Object);generated", - "kotlin.sequences;SequencesKt;minus;(Sequence,Sequence);generated", - "kotlin.sequences;SequencesKt;minusElement;(Sequence,Object);generated", - "kotlin.sequences;SequencesKt;none;(Sequence);generated", - "kotlin.sequences;SequencesKt;none;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;plus;(Sequence,Iterable);generated", - "kotlin.sequences;SequencesKt;plus;(Sequence,Object);generated", - "kotlin.sequences;SequencesKt;plus;(Sequence,Object[]);generated", - "kotlin.sequences;SequencesKt;plus;(Sequence,Sequence);generated", - "kotlin.sequences;SequencesKt;plusElement;(Sequence,Object);generated", - "kotlin.sequences;SequencesKt;runningFold;(Sequence,Object,Function2);generated", - "kotlin.sequences;SequencesKt;runningFoldIndexed;(Sequence,Object,Function3);generated", - "kotlin.sequences;SequencesKt;runningReduce;(Sequence,Function2);generated", - "kotlin.sequences;SequencesKt;runningReduceIndexed;(Sequence,Function3);generated", - "kotlin.sequences;SequencesKt;scan;(Sequence,Object,Function2);generated", - "kotlin.sequences;SequencesKt;scanIndexed;(Sequence,Object,Function3);generated", - "kotlin.sequences;SequencesKt;sequence;(SuspendFunction1);generated", - "kotlin.sequences;SequencesKt;sequenceOf;(Object[]);generated", - "kotlin.sequences;SequencesKt;shuffled;(Sequence);generated", - "kotlin.sequences;SequencesKt;shuffled;(Sequence,Random);generated", - "kotlin.sequences;SequencesKt;sorted;(Sequence);generated", - "kotlin.sequences;SequencesKt;sortedBy;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sortedByDescending;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sortedDescending;(Sequence);generated", - "kotlin.sequences;SequencesKt;sortedWith;(Sequence,Comparator);generated", - "kotlin.sequences;SequencesKt;sumBy;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sumByDouble;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sumOfBigDecimal;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sumOfBigInteger;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sumOfByte;(Sequence);generated", - "kotlin.sequences;SequencesKt;sumOfDouble;(Sequence);generated", - "kotlin.sequences;SequencesKt;sumOfDouble;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sumOfFloat;(Sequence);generated", - "kotlin.sequences;SequencesKt;sumOfInt;(Sequence);generated", - "kotlin.sequences;SequencesKt;sumOfInt;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sumOfLong;(Sequence);generated", - "kotlin.sequences;SequencesKt;sumOfLong;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sumOfShort;(Sequence);generated", - "kotlin.sequences;SequencesKt;sumOfUInt;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sumOfULong;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;windowed;(Sequence,int,int,boolean);generated", - "kotlin.sequences;SequencesKt;zipWithNext;(Sequence);generated", - "kotlin.sequences;SequencesKt;zipWithNext;(Sequence,Function2);generated", - "kotlin.sequences;USequencesKt;sumOfUByte;(Sequence);generated", - "kotlin.sequences;USequencesKt;sumOfUInt;(Sequence);generated", - "kotlin.sequences;USequencesKt;sumOfULong;(Sequence);generated", - "kotlin.sequences;USequencesKt;sumOfUShort;(Sequence);generated", - "kotlin.system;ProcessKt;exitProcess;(int);generated", - "kotlin.system;TimingKt;measureNanoTime;(Function0);generated", - "kotlin.system;TimingKt;measureTimeMillis;(Function0);generated", - "kotlin.text;Appendable;append;(CharSequence);generated", - "kotlin.text;Appendable;append;(CharSequence,int,int);generated", - "kotlin.text;Appendable;append;(char);generated", - "kotlin.text;CharCategory$Companion;valueOf;(int);generated", - "kotlin.text;CharCategory;contains;(char);generated", - "kotlin.text;CharCategory;getCode;();generated", - "kotlin.text;CharCategory;getValue;();generated", - "kotlin.text;CharCategory;valueOf;(String);generated", - "kotlin.text;CharCategory;values;();generated", - "kotlin.text;CharDirectionality$Companion;valueOf;(int);generated", - "kotlin.text;CharDirectionality;getValue;();generated", - "kotlin.text;CharDirectionality;valueOf;(String);generated", - "kotlin.text;CharDirectionality;values;();generated", - "kotlin.text;CharacterCodingException;CharacterCodingException;();generated", - "kotlin.text;CharsKt;digitToChar;(int);generated", - "kotlin.text;CharsKt;digitToChar;(int,int);generated", - "kotlin.text;CharsKt;digitToInt;(char);generated", - "kotlin.text;CharsKt;digitToInt;(char,int);generated", - "kotlin.text;CharsKt;digitToIntOrNull;(char);generated", - "kotlin.text;CharsKt;digitToIntOrNull;(char,int);generated", - "kotlin.text;CharsKt;equals;(char,char,boolean);generated", - "kotlin.text;CharsKt;getCategory;(char);generated", - "kotlin.text;CharsKt;getDirectionality;(char);generated", - "kotlin.text;CharsKt;isDefined;(char);generated", - "kotlin.text;CharsKt;isDigit;(char);generated", - "kotlin.text;CharsKt;isHighSurrogate;(char);generated", - "kotlin.text;CharsKt;isISOControl;(char);generated", - "kotlin.text;CharsKt;isIdentifierIgnorable;(char);generated", - "kotlin.text;CharsKt;isJavaIdentifierPart;(char);generated", - "kotlin.text;CharsKt;isJavaIdentifierStart;(char);generated", - "kotlin.text;CharsKt;isLetter;(char);generated", - "kotlin.text;CharsKt;isLetterOrDigit;(char);generated", - "kotlin.text;CharsKt;isLowSurrogate;(char);generated", - "kotlin.text;CharsKt;isLowerCase;(char);generated", - "kotlin.text;CharsKt;isSurrogate;(char);generated", - "kotlin.text;CharsKt;isTitleCase;(char);generated", - "kotlin.text;CharsKt;isUpperCase;(char);generated", - "kotlin.text;CharsKt;isWhitespace;(char);generated", - "kotlin.text;CharsKt;lowercase;(char);generated", - "kotlin.text;CharsKt;lowercase;(char,Locale);generated", - "kotlin.text;CharsKt;lowercaseChar;(char);generated", - "kotlin.text;CharsKt;titlecase;(char);generated", - "kotlin.text;CharsKt;titlecase;(char,Locale);generated", - "kotlin.text;CharsKt;titlecaseChar;(char);generated", - "kotlin.text;CharsKt;toLowerCase;(char);generated", - "kotlin.text;CharsKt;toTitleCase;(char);generated", - "kotlin.text;CharsKt;toUpperCase;(char);generated", - "kotlin.text;CharsKt;uppercase;(char);generated", - "kotlin.text;CharsKt;uppercase;(char,Locale);generated", - "kotlin.text;CharsKt;uppercaseChar;(char);generated", - "kotlin.text;Charsets;UTF32;();generated", "kotlin.text;Charsets;UTF32_BE;();generated", - "kotlin.text;Charsets;UTF32_LE;();generated", - "kotlin.text;Charsets;getISO_8859_1;();generated", - "kotlin.text;Charsets;getUS_ASCII;();generated", - "kotlin.text;Charsets;getUTF_16;();generated", - "kotlin.text;Charsets;getUTF_16BE;();generated", - "kotlin.text;Charsets;getUTF_16LE;();generated", - "kotlin.text;Charsets;getUTF_8;();generated", - "kotlin.text;CharsetsKt;charset;(String);generated", - "kotlin.text;FlagEnum;getMask;();generated", "kotlin.text;FlagEnum;getValue;();generated", - "kotlin.text;MatchGroup;equals;(Object);generated", - "kotlin.text;MatchGroup;hashCode;();generated", - "kotlin.text;MatchGroupCollection;get;(int);generated", - "kotlin.text;MatchNamedGroupCollection;get;(String);generated", - "kotlin.text;MatchResult;getGroupValues;();generated", - "kotlin.text;MatchResult;getGroups;();generated", - "kotlin.text;MatchResult;getRange;();generated", - "kotlin.text;MatchResult;getValue;();generated", - "kotlin.text;MatchResult;next;();generated", - "kotlin.text;Regex$Companion;escapeReplacement;(String);generated", - "kotlin.text;Regex$Companion;fromLiteral;(String);generated", - "kotlin.text;Regex;Regex;(String);generated", - "kotlin.text;Regex;Regex;(String,RegexOption);generated", - "kotlin.text;Regex;Regex;(String,Set);generated", - "kotlin.text;Regex;containsMatchIn;(CharSequence);generated", - "kotlin.text;Regex;findAll;(CharSequence,int);generated", - "kotlin.text;Regex;getPattern;();generated", - "kotlin.text;Regex;matchAt;(CharSequence,int);generated", - "kotlin.text;Regex;matches;(CharSequence);generated", - "kotlin.text;Regex;matchesAt;(CharSequence,int);generated", - "kotlin.text;Regex;split;(CharSequence,int);generated", - "kotlin.text;Regex;splitToSequence;(CharSequence,int);generated", - "kotlin.text;Regex;toString;();generated", - "kotlin.text;RegexOption;valueOf;(String);generated", - "kotlin.text;RegexOption;values;();generated", - "kotlin.text;StringBuilder;StringBuilder;();generated", - "kotlin.text;StringBuilder;StringBuilder;(CharSequence);generated", - "kotlin.text;StringBuilder;StringBuilder;(String);generated", - "kotlin.text;StringBuilder;StringBuilder;(int);generated", - "kotlin.text;StringBuilder;append;(Object);generated", - "kotlin.text;StringBuilder;append;(String);generated", - "kotlin.text;StringBuilder;append;(boolean);generated", - "kotlin.text;StringBuilder;append;(char[]);generated", - "kotlin.text;StringBuilder;capacity;();generated", - "kotlin.text;StringBuilder;ensureCapacity;(int);generated", - "kotlin.text;StringBuilder;get;(int);generated", - "kotlin.text;StringBuilder;indexOf;(String);generated", - "kotlin.text;StringBuilder;indexOf;(String,int);generated", - "kotlin.text;StringBuilder;insert;(int,CharSequence);generated", - "kotlin.text;StringBuilder;insert;(int,Object);generated", - "kotlin.text;StringBuilder;insert;(int,String);generated", - "kotlin.text;StringBuilder;insert;(int,boolean);generated", - "kotlin.text;StringBuilder;insert;(int,char);generated", - "kotlin.text;StringBuilder;insert;(int,char[]);generated", - "kotlin.text;StringBuilder;lastIndexOf;(String);generated", - "kotlin.text;StringBuilder;lastIndexOf;(String,int);generated", - "kotlin.text;StringBuilder;reverse;();generated", - "kotlin.text;StringBuilder;setLength;(int);generated", - "kotlin.text;StringBuilder;substring;(int);generated", - "kotlin.text;StringBuilder;substring;(int,int);generated", - "kotlin.text;StringBuilder;trimToSize;();generated", - "kotlin.text;StringsKt;String;(int[],int,int);generated", - "kotlin.text;StringsKt;all;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;any;(CharSequence);generated", - "kotlin.text;StringsKt;any;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;asIterable;(CharSequence);generated", - "kotlin.text;StringsKt;asSequence;(CharSequence);generated", - "kotlin.text;StringsKt;associate;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;associateBy;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;associateBy;(CharSequence,Function1,Function1);generated", - "kotlin.text;StringsKt;associateWith;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;buildString;(Function1);generated", - "kotlin.text;StringsKt;buildString;(int,Function1);generated", - "kotlin.text;StringsKt;chunked;(CharSequence,int);generated", - "kotlin.text;StringsKt;chunked;(CharSequence,int,Function1);generated", - "kotlin.text;StringsKt;chunkedSequence;(CharSequence,int);generated", - "kotlin.text;StringsKt;chunkedSequence;(CharSequence,int,Function1);generated", - "kotlin.text;StringsKt;codePointAt;(String,int);generated", - "kotlin.text;StringsKt;codePointBefore;(String,int);generated", - "kotlin.text;StringsKt;codePointCount;(String,int,int);generated", - "kotlin.text;StringsKt;commonPrefixWith;(CharSequence,CharSequence,boolean);generated", - "kotlin.text;StringsKt;commonSuffixWith;(CharSequence,CharSequence,boolean);generated", - "kotlin.text;StringsKt;compareTo;(String,String,boolean);generated", - "kotlin.text;StringsKt;contains;(CharSequence,CharSequence,boolean);generated", - "kotlin.text;StringsKt;contains;(CharSequence,Regex);generated", - "kotlin.text;StringsKt;contains;(CharSequence,char,boolean);generated", - "kotlin.text;StringsKt;contentEquals;(CharSequence,CharSequence);generated", - "kotlin.text;StringsKt;contentEquals;(CharSequence,CharSequence,boolean);generated", - "kotlin.text;StringsKt;contentEquals;(String,CharSequence);generated", - "kotlin.text;StringsKt;contentEquals;(String,StringBuffer);generated", - "kotlin.text;StringsKt;count;(CharSequence);generated", - "kotlin.text;StringsKt;count;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;deleteAt;(StringBuilder,int);generated", - "kotlin.text;StringsKt;deleteRange;(StringBuilder,int,int);generated", - "kotlin.text;StringsKt;elementAt;(CharSequence,int);generated", - "kotlin.text;StringsKt;elementAtOrElse;(CharSequence,int,Function1);generated", - "kotlin.text;StringsKt;elementAtOrNull;(CharSequence,int);generated", - "kotlin.text;StringsKt;endsWith;(CharSequence,CharSequence,boolean);generated", - "kotlin.text;StringsKt;endsWith;(CharSequence,char,boolean);generated", - "kotlin.text;StringsKt;endsWith;(String,String,boolean);generated", - "kotlin.text;StringsKt;equals;(String,String,boolean);generated", - "kotlin.text;StringsKt;filter;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;filter;(String,Function1);generated", - "kotlin.text;StringsKt;filterIndexed;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;filterIndexed;(String,Function2);generated", - "kotlin.text;StringsKt;filterNot;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;filterNot;(String,Function1);generated", - "kotlin.text;StringsKt;find;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;findLast;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;first;(CharSequence);generated", - "kotlin.text;StringsKt;first;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;firstNotNullOf;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;firstNotNullOfOrNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;firstOrNull;(CharSequence);generated", - "kotlin.text;StringsKt;firstOrNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;flatMap;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;flatMapIndexedIterable;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;forEach;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;forEachIndexed;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;getCASE_INSENSITIVE_ORDER;(StringCompanionObject);generated", - "kotlin.text;StringsKt;getIndices;(CharSequence);generated", - "kotlin.text;StringsKt;getLastIndex;(CharSequence);generated", - "kotlin.text;StringsKt;getOrElse;(CharSequence,int,Function1);generated", - "kotlin.text;StringsKt;getOrNull;(CharSequence,int);generated", - "kotlin.text;StringsKt;groupBy;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;groupBy;(CharSequence,Function1,Function1);generated", - "kotlin.text;StringsKt;groupingBy;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;hasSurrogatePairAt;(CharSequence,int);generated", - "kotlin.text;StringsKt;indexOf;(CharSequence,String,int,boolean);generated", - "kotlin.text;StringsKt;indexOf;(CharSequence,char,int,boolean);generated", - "kotlin.text;StringsKt;indexOfAny;(CharSequence,Collection,int,boolean);generated", - "kotlin.text;StringsKt;indexOfAny;(CharSequence,char[],int,boolean);generated", - "kotlin.text;StringsKt;indexOfFirst;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;indexOfLast;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;isBlank;(CharSequence);generated", - "kotlin.text;StringsKt;isEmpty;(CharSequence);generated", - "kotlin.text;StringsKt;isNotBlank;(CharSequence);generated", - "kotlin.text;StringsKt;isNotEmpty;(CharSequence);generated", - "kotlin.text;StringsKt;isNullOrBlank;(CharSequence);generated", - "kotlin.text;StringsKt;isNullOrEmpty;(CharSequence);generated", - "kotlin.text;StringsKt;iterator;(CharSequence);generated", - "kotlin.text;StringsKt;last;(CharSequence);generated", - "kotlin.text;StringsKt;last;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;lastIndexOf;(CharSequence,String,int,boolean);generated", - "kotlin.text;StringsKt;lastIndexOf;(CharSequence,char,int,boolean);generated", - "kotlin.text;StringsKt;lastIndexOfAny;(CharSequence,Collection,int,boolean);generated", - "kotlin.text;StringsKt;lastIndexOfAny;(CharSequence,char[],int,boolean);generated", - "kotlin.text;StringsKt;lastOrNull;(CharSequence);generated", - "kotlin.text;StringsKt;lastOrNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;map;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;mapIndexed;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;mapIndexedNotNull;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;mapNotNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;matches;(CharSequence,Regex);generated", - "kotlin.text;StringsKt;max;(CharSequence);generated", - "kotlin.text;StringsKt;maxBy;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;maxByOrNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;maxByOrThrow;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;maxOf;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;maxOfOrNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;maxOfWith;(CharSequence,Comparator,Function1);generated", - "kotlin.text;StringsKt;maxOfWithOrNull;(CharSequence,Comparator,Function1);generated", - "kotlin.text;StringsKt;maxOrNull;(CharSequence);generated", - "kotlin.text;StringsKt;maxOrThrow;(CharSequence);generated", - "kotlin.text;StringsKt;maxWith;(CharSequence,Comparator);generated", - "kotlin.text;StringsKt;maxWithOrNull;(CharSequence,Comparator);generated", - "kotlin.text;StringsKt;maxWithOrThrow;(CharSequence,Comparator);generated", - "kotlin.text;StringsKt;min;(CharSequence);generated", - "kotlin.text;StringsKt;minBy;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;minByOrNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;minByOrThrow;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;minOf;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;minOfOrNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;minOfWith;(CharSequence,Comparator,Function1);generated", - "kotlin.text;StringsKt;minOfWithOrNull;(CharSequence,Comparator,Function1);generated", - "kotlin.text;StringsKt;minOrNull;(CharSequence);generated", - "kotlin.text;StringsKt;minOrThrow;(CharSequence);generated", - "kotlin.text;StringsKt;minWith;(CharSequence,Comparator);generated", - "kotlin.text;StringsKt;minWithOrNull;(CharSequence,Comparator);generated", - "kotlin.text;StringsKt;minWithOrThrow;(CharSequence,Comparator);generated", - "kotlin.text;StringsKt;none;(CharSequence);generated", - "kotlin.text;StringsKt;none;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;offsetByCodePoints;(String,int,int);generated", - "kotlin.text;StringsKt;padEnd;(String,int,char);generated", - "kotlin.text;StringsKt;padStart;(String,int,char);generated", - "kotlin.text;StringsKt;partition;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;partition;(String,Function1);generated", - "kotlin.text;StringsKt;random;(CharSequence);generated", - "kotlin.text;StringsKt;random;(CharSequence,Random);generated", - "kotlin.text;StringsKt;randomOrNull;(CharSequence);generated", - "kotlin.text;StringsKt;randomOrNull;(CharSequence,Random);generated", - "kotlin.text;StringsKt;reduce;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;reduceIndexed;(CharSequence,Function3);generated", - "kotlin.text;StringsKt;reduceIndexedOrNull;(CharSequence,Function3);generated", - "kotlin.text;StringsKt;reduceOrNull;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;reduceRight;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;reduceRightIndexed;(CharSequence,Function3);generated", - "kotlin.text;StringsKt;reduceRightIndexedOrNull;(CharSequence,Function3);generated", - "kotlin.text;StringsKt;reduceRightOrNull;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;regionMatches;(CharSequence,int,CharSequence,int,int,boolean);generated", - "kotlin.text;StringsKt;regionMatches;(String,int,String,int,int,boolean);generated", - "kotlin.text;StringsKt;removeRange;(String,IntRange);generated", - "kotlin.text;StringsKt;removeRange;(String,int,int);generated", - "kotlin.text;StringsKt;replace;(String,String,String,boolean);generated", - "kotlin.text;StringsKt;replaceIndent;(String,String);generated", - "kotlin.text;StringsKt;replaceIndentByMargin;(String,String,String);generated", - "kotlin.text;StringsKt;replaceRange;(String,IntRange,CharSequence);generated", - "kotlin.text;StringsKt;replaceRange;(String,int,int,CharSequence);generated", - "kotlin.text;StringsKt;reversed;(String);generated", - "kotlin.text;StringsKt;runningReduce;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;runningReduceIndexed;(CharSequence,Function3);generated", - "kotlin.text;StringsKt;set;(StringBuilder,int,char);generated", - "kotlin.text;StringsKt;single;(CharSequence);generated", - "kotlin.text;StringsKt;single;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;singleOrNull;(CharSequence);generated", - "kotlin.text;StringsKt;singleOrNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;slice;(CharSequence,Iterable);generated", - "kotlin.text;StringsKt;slice;(String,Iterable);generated", - "kotlin.text;StringsKt;split;(CharSequence,Regex,int);generated", - "kotlin.text;StringsKt;split;(CharSequence,String[],boolean,int);generated", - "kotlin.text;StringsKt;split;(CharSequence,char[],boolean,int);generated", - "kotlin.text;StringsKt;splitToSequence;(CharSequence,Regex,int);generated", - "kotlin.text;StringsKt;startsWith;(CharSequence,CharSequence,boolean);generated", - "kotlin.text;StringsKt;startsWith;(CharSequence,CharSequence,int,boolean);generated", - "kotlin.text;StringsKt;startsWith;(CharSequence,char,boolean);generated", - "kotlin.text;StringsKt;startsWith;(String,String,boolean);generated", - "kotlin.text;StringsKt;startsWith;(String,String,int,boolean);generated", - "kotlin.text;StringsKt;substring;(CharSequence,IntRange);generated", - "kotlin.text;StringsKt;substring;(CharSequence,int,int);generated", - "kotlin.text;StringsKt;sumBy;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;sumByDouble;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;sumOfBigDecimal;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;sumOfBigInteger;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;sumOfDouble;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;sumOfInt;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;sumOfLong;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;sumOfUInt;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;sumOfULong;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;toBigDecimal;(String);generated", - "kotlin.text;StringsKt;toBigDecimal;(String,MathContext);generated", - "kotlin.text;StringsKt;toBigDecimalOrNull;(String);generated", - "kotlin.text;StringsKt;toBigDecimalOrNull;(String,MathContext);generated", - "kotlin.text;StringsKt;toBigInteger;(String);generated", - "kotlin.text;StringsKt;toBigInteger;(String,int);generated", - "kotlin.text;StringsKt;toBigIntegerOrNull;(String);generated", - "kotlin.text;StringsKt;toBigIntegerOrNull;(String,int);generated", - "kotlin.text;StringsKt;toBoolean;(String);generated", - "kotlin.text;StringsKt;toBooleanNullable;(String);generated", - "kotlin.text;StringsKt;toBooleanStrict;(String);generated", - "kotlin.text;StringsKt;toBooleanStrictOrNull;(String);generated", - "kotlin.text;StringsKt;toByte;(String);generated", - "kotlin.text;StringsKt;toByte;(String,int);generated", - "kotlin.text;StringsKt;toByteOrNull;(String);generated", - "kotlin.text;StringsKt;toByteOrNull;(String,int);generated", - "kotlin.text;StringsKt;toDouble;(String);generated", - "kotlin.text;StringsKt;toDoubleOrNull;(String);generated", - "kotlin.text;StringsKt;toFloat;(String);generated", - "kotlin.text;StringsKt;toFloatOrNull;(String);generated", - "kotlin.text;StringsKt;toHashSet;(CharSequence);generated", - "kotlin.text;StringsKt;toInt;(String);generated", - "kotlin.text;StringsKt;toInt;(String,int);generated", - "kotlin.text;StringsKt;toIntOrNull;(String);generated", - "kotlin.text;StringsKt;toIntOrNull;(String,int);generated", - "kotlin.text;StringsKt;toList;(CharSequence);generated", - "kotlin.text;StringsKt;toLong;(String);generated", - "kotlin.text;StringsKt;toLong;(String,int);generated", - "kotlin.text;StringsKt;toLongOrNull;(String);generated", - "kotlin.text;StringsKt;toLongOrNull;(String,int);generated", - "kotlin.text;StringsKt;toMutableList;(CharSequence);generated", - "kotlin.text;StringsKt;toPattern;(String,int);generated", - "kotlin.text;StringsKt;toRegex;(String);generated", - "kotlin.text;StringsKt;toRegex;(String,RegexOption);generated", - "kotlin.text;StringsKt;toRegex;(String,Set);generated", - "kotlin.text;StringsKt;toSet;(CharSequence);generated", - "kotlin.text;StringsKt;toShort;(String);generated", - "kotlin.text;StringsKt;toShort;(String,int);generated", - "kotlin.text;StringsKt;toShortOrNull;(String);generated", - "kotlin.text;StringsKt;toShortOrNull;(String,int);generated", - "kotlin.text;StringsKt;toSortedSet;(CharSequence);generated", - "kotlin.text;StringsKt;toString;(byte,int);generated", - "kotlin.text;StringsKt;toString;(int,int);generated", - "kotlin.text;StringsKt;toString;(long,int);generated", - "kotlin.text;StringsKt;toString;(short,int);generated", - "kotlin.text;StringsKt;trim;(String);generated", - "kotlin.text;StringsKt;trim;(String,Function1);generated", - "kotlin.text;StringsKt;trim;(String,char[]);generated", - "kotlin.text;StringsKt;trimEnd;(String);generated", - "kotlin.text;StringsKt;trimEnd;(String,Function1);generated", - "kotlin.text;StringsKt;trimEnd;(String,char[]);generated", - "kotlin.text;StringsKt;trimIndent;(String);generated", - "kotlin.text;StringsKt;trimMargin;(String,String);generated", - "kotlin.text;StringsKt;trimStart;(String);generated", - "kotlin.text;StringsKt;trimStart;(String,Function1);generated", - "kotlin.text;StringsKt;trimStart;(String,char[]);generated", - "kotlin.text;StringsKt;windowed;(CharSequence,int,int,boolean);generated", - "kotlin.text;StringsKt;windowed;(CharSequence,int,int,boolean,Function1);generated", - "kotlin.text;StringsKt;windowedSequence;(CharSequence,int,int,boolean);generated", - "kotlin.text;StringsKt;windowedSequence;(CharSequence,int,int,boolean,Function1);generated", - "kotlin.text;StringsKt;withIndex;(CharSequence);generated", - "kotlin.text;StringsKt;zip;(CharSequence,CharSequence);generated", - "kotlin.text;StringsKt;zip;(CharSequence,CharSequence,Function2);generated", - "kotlin.text;StringsKt;zipWithNext;(CharSequence);generated", - "kotlin.text;StringsKt;zipWithNext;(CharSequence,Function2);generated", - "kotlin.text;TextHKt;String;(char[]);generated", - "kotlin.text;TextHKt;String;(char[],int,int);generated", - "kotlin.text;TextHKt;compareTo;(String,String,boolean);generated", - "kotlin.text;TextHKt;concatToString;(char[]);generated", - "kotlin.text;TextHKt;concatToString;(char[],int,int);generated", - "kotlin.text;TextHKt;decodeToString;(byte[]);generated", - "kotlin.text;TextHKt;decodeToString;(byte[],int,int,boolean);generated", - "kotlin.text;TextHKt;encodeToByteArray;(String);generated", - "kotlin.text;TextHKt;encodeToByteArray;(String,int,int,boolean);generated", - "kotlin.text;TextHKt;endsWith;(String,String,boolean);generated", - "kotlin.text;TextHKt;equals;(String,String,boolean);generated", - "kotlin.text;TextHKt;getCASE_INSENSITIVE_ORDER;(StringCompanionObject);generated", - "kotlin.text;TextHKt;isBlank;(CharSequence);generated", - "kotlin.text;TextHKt;isHighSurrogate;(char);generated", - "kotlin.text;TextHKt;isLowSurrogate;(char);generated", - "kotlin.text;TextHKt;regionMatches;(CharSequence,int,CharSequence,int,int,boolean);generated", - "kotlin.text;TextHKt;repeat;(CharSequence,int);generated", - "kotlin.text;TextHKt;replace;(String,String,String,boolean);generated", - "kotlin.text;TextHKt;replace;(String,char,char,boolean);generated", - "kotlin.text;TextHKt;replaceFirst;(String,String,String,boolean);generated", - "kotlin.text;TextHKt;replaceFirst;(String,char,char,boolean);generated", - "kotlin.text;TextHKt;startsWith;(String,String,boolean);generated", - "kotlin.text;TextHKt;startsWith;(String,String,int,boolean);generated", - "kotlin.text;TextHKt;substring;(String,int);generated", - "kotlin.text;TextHKt;substring;(String,int,int);generated", - "kotlin.text;TextHKt;toBoolean;(String);generated", - "kotlin.text;TextHKt;toByte;(String);generated", - "kotlin.text;TextHKt;toByte;(String,int);generated", - "kotlin.text;TextHKt;toCharArray;(String);generated", - "kotlin.text;TextHKt;toCharArray;(String,int,int);generated", - "kotlin.text;TextHKt;toDouble;(String);generated", - "kotlin.text;TextHKt;toDoubleOrNull;(String);generated", - "kotlin.text;TextHKt;toFloat;(String);generated", - "kotlin.text;TextHKt;toFloatOrNull;(String);generated", - "kotlin.text;TextHKt;toInt;(String);generated", - "kotlin.text;TextHKt;toInt;(String,int);generated", - "kotlin.text;TextHKt;toLong;(String);generated", - "kotlin.text;TextHKt;toLong;(String,int);generated", - "kotlin.text;TextHKt;toShort;(String);generated", - "kotlin.text;TextHKt;toShort;(String,int);generated", - "kotlin.text;TextHKt;toString;(byte,int);generated", - "kotlin.text;TextHKt;toString;(int,int);generated", - "kotlin.text;TextHKt;toString;(long,int);generated", - "kotlin.text;TextHKt;toString;(short,int);generated", - "kotlin.text;Typography;getAlmostEqual;();generated", - "kotlin.text;Typography;getAmp;();generated", - "kotlin.text;Typography;getBullet;();generated", - "kotlin.text;Typography;getCent;();generated", - "kotlin.text;Typography;getCopyright;();generated", - "kotlin.text;Typography;getDagger;();generated", - "kotlin.text;Typography;getDegree;();generated", - "kotlin.text;Typography;getDollar;();generated", - "kotlin.text;Typography;getDoubleDagger;();generated", - "kotlin.text;Typography;getDoublePrime;();generated", - "kotlin.text;Typography;getEllipsis;();generated", - "kotlin.text;Typography;getEuro;();generated", - "kotlin.text;Typography;getGreater;();generated", - "kotlin.text;Typography;getGreaterOrEqual;();generated", - "kotlin.text;Typography;getHalf;();generated", - "kotlin.text;Typography;getLeftDoubleQuote;();generated", - "kotlin.text;Typography;getLeftGuillemet;();generated", - "kotlin.text;Typography;getLeftGuillemete;();generated", - "kotlin.text;Typography;getLeftSingleQuote;();generated", - "kotlin.text;Typography;getLess;();generated", - "kotlin.text;Typography;getLessOrEqual;();generated", - "kotlin.text;Typography;getLowDoubleQuote;();generated", - "kotlin.text;Typography;getLowSingleQuote;();generated", - "kotlin.text;Typography;getMdash;();generated", - "kotlin.text;Typography;getMiddleDot;();generated", - "kotlin.text;Typography;getNbsp;();generated", - "kotlin.text;Typography;getNdash;();generated", - "kotlin.text;Typography;getNotEqual;();generated", - "kotlin.text;Typography;getParagraph;();generated", - "kotlin.text;Typography;getPlusMinus;();generated", - "kotlin.text;Typography;getPound;();generated", - "kotlin.text;Typography;getPrime;();generated", - "kotlin.text;Typography;getQuote;();generated", - "kotlin.text;Typography;getRegistered;();generated", - "kotlin.text;Typography;getRightDoubleQuote;();generated", - "kotlin.text;Typography;getRightGuillemet;();generated", - "kotlin.text;Typography;getRightGuillemete;();generated", - "kotlin.text;Typography;getRightSingleQuote;();generated", - "kotlin.text;Typography;getSection;();generated", - "kotlin.text;Typography;getTimes;();generated", "kotlin.text;Typography;getTm;();generated", - "kotlin.text;UStringsKt;toString;(byte,int);generated", - "kotlin.text;UStringsKt;toString;(int,int);generated", - "kotlin.text;UStringsKt;toString;(long,int);generated", - "kotlin.text;UStringsKt;toString;(short,int);generated", - "kotlin.text;UStringsKt;toUByte;(String);generated", - "kotlin.text;UStringsKt;toUByte;(String,int);generated", - "kotlin.text;UStringsKt;toUByteOrNull;(String);generated", - "kotlin.text;UStringsKt;toUByteOrNull;(String,int);generated", - "kotlin.text;UStringsKt;toUInt;(String);generated", - "kotlin.text;UStringsKt;toUInt;(String,int);generated", - "kotlin.text;UStringsKt;toUIntOrNull;(String);generated", - "kotlin.text;UStringsKt;toUIntOrNull;(String,int);generated", - "kotlin.text;UStringsKt;toULong;(String);generated", - "kotlin.text;UStringsKt;toULong;(String,int);generated", - "kotlin.text;UStringsKt;toULongOrNull;(String);generated", - "kotlin.text;UStringsKt;toULongOrNull;(String,int);generated", - "kotlin.text;UStringsKt;toUShort;(String);generated", - "kotlin.text;UStringsKt;toUShort;(String,int);generated", - "kotlin.text;UStringsKt;toUShortOrNull;(String);generated", - "kotlin.text;UStringsKt;toUShortOrNull;(String,int);generated", - "kotlin.time;AbstractDoubleTimeSource;AbstractDoubleTimeSource;(DurationUnit);generated", - "kotlin.time;AbstractLongTimeSource;AbstractLongTimeSource;(DurationUnit);generated", - "kotlin.time;Duration$Companion;convert;(double,DurationUnit,DurationUnit);generated", - "kotlin.time;Duration$Companion;days;(double);generated", - "kotlin.time;Duration$Companion;days;(int);generated", - "kotlin.time;Duration$Companion;days;(long);generated", - "kotlin.time;Duration$Companion;getDays;(double);generated", - "kotlin.time;Duration$Companion;getDays;(int);generated", - "kotlin.time;Duration$Companion;getDays;(long);generated", - "kotlin.time;Duration$Companion;getHours;(double);generated", - "kotlin.time;Duration$Companion;getHours;(int);generated", - "kotlin.time;Duration$Companion;getHours;(long);generated", - "kotlin.time;Duration$Companion;getMicroseconds;(double);generated", - "kotlin.time;Duration$Companion;getMicroseconds;(int);generated", - "kotlin.time;Duration$Companion;getMicroseconds;(long);generated", - "kotlin.time;Duration$Companion;getMilliseconds;(double);generated", - "kotlin.time;Duration$Companion;getMilliseconds;(int);generated", - "kotlin.time;Duration$Companion;getMilliseconds;(long);generated", - "kotlin.time;Duration$Companion;getMinutes;(double);generated", - "kotlin.time;Duration$Companion;getMinutes;(int);generated", - "kotlin.time;Duration$Companion;getMinutes;(long);generated", - "kotlin.time;Duration$Companion;getNanoseconds;(double);generated", - "kotlin.time;Duration$Companion;getNanoseconds;(int);generated", - "kotlin.time;Duration$Companion;getNanoseconds;(long);generated", - "kotlin.time;Duration$Companion;getSeconds;(double);generated", - "kotlin.time;Duration$Companion;getSeconds;(int);generated", - "kotlin.time;Duration$Companion;getSeconds;(long);generated", - "kotlin.time;Duration$Companion;hours;(double);generated", - "kotlin.time;Duration$Companion;hours;(int);generated", - "kotlin.time;Duration$Companion;hours;(long);generated", - "kotlin.time;Duration$Companion;microseconds;(double);generated", - "kotlin.time;Duration$Companion;microseconds;(int);generated", - "kotlin.time;Duration$Companion;microseconds;(long);generated", - "kotlin.time;Duration$Companion;milliseconds;(double);generated", - "kotlin.time;Duration$Companion;milliseconds;(int);generated", - "kotlin.time;Duration$Companion;milliseconds;(long);generated", - "kotlin.time;Duration$Companion;minutes;(double);generated", - "kotlin.time;Duration$Companion;minutes;(int);generated", - "kotlin.time;Duration$Companion;minutes;(long);generated", - "kotlin.time;Duration$Companion;nanoseconds;(double);generated", - "kotlin.time;Duration$Companion;nanoseconds;(int);generated", - "kotlin.time;Duration$Companion;nanoseconds;(long);generated", - "kotlin.time;Duration$Companion;parse;(String);generated", - "kotlin.time;Duration$Companion;parseIsoString;(String);generated", - "kotlin.time;Duration$Companion;parseIsoStringOrNull;(String);generated", - "kotlin.time;Duration$Companion;parseOrNull;(String);generated", - "kotlin.time;Duration$Companion;seconds;(double);generated", - "kotlin.time;Duration$Companion;seconds;(int);generated", - "kotlin.time;Duration$Companion;seconds;(long);generated", - "kotlin.time;Duration;div;(Duration);generated", - "kotlin.time;Duration;equals;(Object);generated", - "kotlin.time;Duration;getInDays;();generated", - "kotlin.time;Duration;getInHours;();generated", - "kotlin.time;Duration;getInMicroseconds;();generated", - "kotlin.time;Duration;getInMilliseconds;();generated", - "kotlin.time;Duration;getInMinutes;();generated", - "kotlin.time;Duration;getInNanoseconds;();generated", - "kotlin.time;Duration;getInSeconds;();generated", - "kotlin.time;Duration;getInWholeDays;();generated", - "kotlin.time;Duration;getInWholeHours;();generated", - "kotlin.time;Duration;getInWholeMicroseconds;();generated", - "kotlin.time;Duration;getInWholeMilliseconds;();generated", - "kotlin.time;Duration;getInWholeMinutes;();generated", - "kotlin.time;Duration;getInWholeNanoseconds;();generated", - "kotlin.time;Duration;getInWholeSeconds;();generated", - "kotlin.time;Duration;hashCode;();generated", "kotlin.time;Duration;isFinite;();generated", - "kotlin.time;Duration;isInfinite;();generated", - "kotlin.time;Duration;isNegative;();generated", - "kotlin.time;Duration;isPositive;();generated", - "kotlin.time;Duration;toComponents;(Function2);generated", - "kotlin.time;Duration;toComponents;(Function3);generated", - "kotlin.time;Duration;toComponents;(Function4);generated", - "kotlin.time;Duration;toComponents;(Function5);generated", - "kotlin.time;Duration;toDouble;(DurationUnit);generated", - "kotlin.time;Duration;toInt;(DurationUnit);generated", - "kotlin.time;Duration;toIsoString;();generated", - "kotlin.time;Duration;toLong;(DurationUnit);generated", - "kotlin.time;Duration;toLongMilliseconds;();generated", - "kotlin.time;Duration;toLongNanoseconds;();generated", - "kotlin.time;Duration;toString;();generated", - "kotlin.time;Duration;toString;(DurationUnit,int);generated", - "kotlin.time;Duration;unaryMinus;();generated", - "kotlin.time;DurationKt;getDays;(double);generated", - "kotlin.time;DurationKt;getDays;(int);generated", - "kotlin.time;DurationKt;getDays;(long);generated", - "kotlin.time;DurationKt;getHours;(double);generated", - "kotlin.time;DurationKt;getHours;(int);generated", - "kotlin.time;DurationKt;getHours;(long);generated", - "kotlin.time;DurationKt;getMicroseconds;(double);generated", - "kotlin.time;DurationKt;getMicroseconds;(int);generated", - "kotlin.time;DurationKt;getMicroseconds;(long);generated", - "kotlin.time;DurationKt;getMilliseconds;(double);generated", - "kotlin.time;DurationKt;getMilliseconds;(int);generated", - "kotlin.time;DurationKt;getMilliseconds;(long);generated", - "kotlin.time;DurationKt;getMinutes;(double);generated", - "kotlin.time;DurationKt;getMinutes;(int);generated", - "kotlin.time;DurationKt;getMinutes;(long);generated", - "kotlin.time;DurationKt;getNanoseconds;(double);generated", - "kotlin.time;DurationKt;getNanoseconds;(int);generated", - "kotlin.time;DurationKt;getNanoseconds;(long);generated", - "kotlin.time;DurationKt;getSeconds;(double);generated", - "kotlin.time;DurationKt;getSeconds;(int);generated", - "kotlin.time;DurationKt;getSeconds;(long);generated", - "kotlin.time;DurationKt;toDuration;(double,DurationUnit);generated", - "kotlin.time;DurationKt;toDuration;(int,DurationUnit);generated", - "kotlin.time;DurationKt;toDuration;(long,DurationUnit);generated", - "kotlin.time;DurationUnit;valueOf;(String);generated", - "kotlin.time;DurationUnit;values;();generated", - "kotlin.time;DurationUnitKt;toDurationUnit;(TimeUnit);generated", - "kotlin.time;DurationUnitKt;toTimeUnit;(DurationUnit);generated", - "kotlin.time;ExperimentalTime;ExperimentalTime;();generated", - "kotlin.time;MeasureTimeKt;measureTime;(Function0);generated", - "kotlin.time;MeasureTimeKt;measureTime;(Monotonic,Function0);generated", - "kotlin.time;MeasureTimeKt;measureTime;(TimeSource,Function0);generated", - "kotlin.time;MeasureTimeKt;measureTimedValue;(Function0);generated", - "kotlin.time;MeasureTimeKt;measureTimedValue;(Monotonic,Function0);generated", - "kotlin.time;MeasureTimeKt;measureTimedValue;(TimeSource,Function0);generated", - "kotlin.time;TestTimeSource;TestTimeSource;();generated", - "kotlin.time;TestTimeSource;plusAssign;(Duration);generated", - "kotlin.time;TimeMark;elapsedNow;();generated", - "kotlin.time;TimeMark;hasNotPassedNow;();generated", - "kotlin.time;TimeMark;hasPassedNow;();generated", - "kotlin.time;TimeMark;minus;(Duration);generated", - "kotlin.time;TimeMark;plus;(Duration);generated", - "kotlin.time;TimeSource$Monotonic$ValueTimeMark;equals;(Object);generated", - "kotlin.time;TimeSource$Monotonic$ValueTimeMark;hashCode;();generated", - "kotlin.time;TimeSource$Monotonic$ValueTimeMark;toString;();generated", - "kotlin.time;TimeSource$Monotonic;toString;();generated", - "kotlin.time;TimeSource;markNow;();generated", - "kotlin.time;TimeSourceKt;compareTo;(TimeMark,TimeMark);generated", - "kotlin.time;TimeSourceKt;minus;(TimeMark,TimeMark);generated", - "kotlin.time;TimedValue;equals;(Object);generated", - "kotlin.time;TimedValue;hashCode;();generated", - "kotlin;ArithmeticException;ArithmeticException;();generated", - "kotlin;ArithmeticException;ArithmeticException;(String);generated", - "kotlin;ArrayIntrinsicsKt;emptyArray;();generated", - "kotlin;AssertionError;AssertionError;();generated", - "kotlin;AssertionError;AssertionError;(Object);generated", - "kotlin;BuilderInference;BuilderInference;();generated", - "kotlin;CharCodeJVMKt;Char;(short);generated", "kotlin;CharCodeKt;Char;(int);generated", - "kotlin;CharCodeKt;Char;(short);generated", "kotlin;CharCodeKt;getCode;(char);generated", - "kotlin;ClassCastException;ClassCastException;();generated", - "kotlin;ClassCastException;ClassCastException;(String);generated", - "kotlin;Comparator;compare;(Object,Object);generated", - "kotlin;CompareToKt;compareTo;(Comparable,Object);generated", - "kotlin;ConcurrentModificationException;ConcurrentModificationException;();generated", - "kotlin;ConcurrentModificationException;ConcurrentModificationException;(String);generated", - "kotlin;ConcurrentModificationException;ConcurrentModificationException;(String,Throwable);generated", - "kotlin;ConcurrentModificationException;ConcurrentModificationException;(Throwable);generated", - "kotlin;ContextFunctionTypeParams;ContextFunctionTypeParams;(int);generated", - "kotlin;ContextFunctionTypeParams;count;();generated", - "kotlin;DeepRecursiveKt;invoke;(DeepRecursiveFunction,Object);generated", - "kotlin;DeepRecursiveScope;callRecursive;(DeepRecursiveFunction,Object);generated", - "kotlin;DeepRecursiveScope;callRecursive;(Object);generated", - "kotlin;DeepRecursiveScope;invoke;(DeepRecursiveFunction,Object);generated", - "kotlin;Deprecated;Deprecated;(String,ReplaceWith,DeprecationLevel);generated", - "kotlin;Deprecated;level;();generated", "kotlin;Deprecated;message;();generated", - "kotlin;Deprecated;replaceWith;();generated", - "kotlin;DeprecatedSinceKotlin;DeprecatedSinceKotlin;(String,String,String);generated", - "kotlin;DeprecatedSinceKotlin;errorSince;();generated", - "kotlin;DeprecatedSinceKotlin;hiddenSince;();generated", - "kotlin;DeprecatedSinceKotlin;warningSince;();generated", - "kotlin;DeprecationLevel;valueOf;(String);generated", - "kotlin;DeprecationLevel;values;();generated", "kotlin;DslMarker;DslMarker;();generated", - "kotlin;Error;Error;();generated", "kotlin;Error;Error;(String);generated", - "kotlin;Error;Error;(String,Throwable);generated", - "kotlin;Error;Error;(Throwable);generated", "kotlin;Exception;Exception;();generated", - "kotlin;Exception;Exception;(String);generated", - "kotlin;Exception;Exception;(String,Throwable);generated", - "kotlin;Exception;Exception;(Throwable);generated", - "kotlin;ExceptionsHKt;addSuppressed;(Throwable,Throwable);generated", - "kotlin;ExceptionsHKt;getSuppressedExceptions;(Throwable);generated", - "kotlin;ExceptionsHKt;printStackTrace;(Throwable);generated", - "kotlin;ExceptionsHKt;stackTraceToString;(Throwable);generated", - "kotlin;ExceptionsKt;addSuppressed;(Throwable,Throwable);generated", - "kotlin;ExceptionsKt;getStackTrace;(Throwable);generated", - "kotlin;ExceptionsKt;getSuppressedExceptions;(Throwable);generated", - "kotlin;ExceptionsKt;printStackTrace;(Throwable);generated", - "kotlin;ExceptionsKt;printStackTrace;(Throwable,PrintStream);generated", - "kotlin;ExceptionsKt;printStackTrace;(Throwable,PrintWriter);generated", - "kotlin;ExceptionsKt;stackTraceToString;(Throwable);generated", - "kotlin;Experimental$Level;valueOf;(String);generated", - "kotlin;Experimental$Level;values;();generated", - "kotlin;Experimental;Experimental;(Level);generated", - "kotlin;Experimental;level;();generated", - "kotlin;ExperimentalMultiplatform;ExperimentalMultiplatform;();generated", - "kotlin;ExperimentalStdlibApi;ExperimentalStdlibApi;();generated", - "kotlin;ExperimentalUnsignedTypes;ExperimentalUnsignedTypes;();generated", - "kotlin;ExtensionFunctionType;ExtensionFunctionType;();generated", - "kotlin;HashCodeKt;hashCode;(Object);generated", - "kotlin;IllegalArgumentException;IllegalArgumentException;();generated", - "kotlin;IllegalArgumentException;IllegalArgumentException;(String);generated", - "kotlin;IllegalArgumentException;IllegalArgumentException;(String,Throwable);generated", - "kotlin;IllegalArgumentException;IllegalArgumentException;(Throwable);generated", - "kotlin;IllegalStateException;IllegalStateException;();generated", - "kotlin;IllegalStateException;IllegalStateException;(String);generated", - "kotlin;IllegalStateException;IllegalStateException;(String,Throwable);generated", - "kotlin;IllegalStateException;IllegalStateException;(Throwable);generated", - "kotlin;IndexOutOfBoundsException;IndexOutOfBoundsException;();generated", - "kotlin;IndexOutOfBoundsException;IndexOutOfBoundsException;(String);generated", - "kotlin;KotlinHKt;fromBits;(DoubleCompanionObject,long);generated", - "kotlin;KotlinHKt;fromBits;(FloatCompanionObject,int);generated", - "kotlin;KotlinHKt;isFinite;(double);generated", - "kotlin;KotlinHKt;isFinite;(float);generated", - "kotlin;KotlinHKt;isInfinite;(double);generated", - "kotlin;KotlinHKt;isInfinite;(float);generated", - "kotlin;KotlinHKt;isNaN;(double);generated", "kotlin;KotlinHKt;isNaN;(float);generated", - "kotlin;KotlinHKt;lazy;(Function0);generated", - "kotlin;KotlinHKt;lazy;(LazyThreadSafetyMode,Function0);generated", - "kotlin;KotlinHKt;lazy;(Object,Function0);generated", - "kotlin;KotlinHKt;toBits;(double);generated", "kotlin;KotlinHKt;toBits;(float);generated", - "kotlin;KotlinHKt;toRawBits;(double);generated", - "kotlin;KotlinHKt;toRawBits;(float);generated", - "kotlin;KotlinNullPointerException;KotlinNullPointerException;();generated", - "kotlin;KotlinNullPointerException;KotlinNullPointerException;(String);generated", - "kotlin;KotlinVersion$Companion;getMAX_COMPONENT_VALUE;();generated", - "kotlin;KotlinVersion;KotlinVersion;(int,int);generated", - "kotlin;KotlinVersion;KotlinVersion;(int,int,int);generated", - "kotlin;KotlinVersion;equals;(Object);generated", - "kotlin;KotlinVersion;getMajor;();generated", "kotlin;KotlinVersion;getMinor;();generated", - "kotlin;KotlinVersion;getPatch;();generated", "kotlin;KotlinVersion;hashCode;();generated", - "kotlin;KotlinVersion;isAtLeast;(int,int);generated", - "kotlin;KotlinVersion;isAtLeast;(int,int,int);generated", - "kotlin;KotlinVersion;toString;();generated", - "kotlin;LateinitKt;isInitialized;(KProperty0);generated", - "kotlin;Lazy;getValue;();generated", "kotlin;Lazy;isInitialized;();generated", - "kotlin;LazyThreadSafetyMode;valueOf;(String);generated", - "kotlin;LazyThreadSafetyMode;values;();generated", - "kotlin;Metadata;Metadata;(int,int[],int[],String[],String[],String,String,int);generated", - "kotlin;Metadata;bv;();generated", "kotlin;Metadata;d1;();generated", - "kotlin;Metadata;d2;();generated", "kotlin;Metadata;k;();generated", - "kotlin;Metadata;mv;();generated", "kotlin;Metadata;pn;();generated", - "kotlin;Metadata;xi;();generated", "kotlin;Metadata;xs;();generated", - "kotlin;NoSuchElementException;NoSuchElementException;();generated", - "kotlin;NoSuchElementException;NoSuchElementException;(String);generated", - "kotlin;NoWhenBranchMatchedException;NoWhenBranchMatchedException;();generated", - "kotlin;NoWhenBranchMatchedException;NoWhenBranchMatchedException;(String);generated", - "kotlin;NoWhenBranchMatchedException;NoWhenBranchMatchedException;(String,Throwable);generated", - "kotlin;NoWhenBranchMatchedException;NoWhenBranchMatchedException;(Throwable);generated", - "kotlin;NotImplementedError;NotImplementedError;(String);generated", - "kotlin;NullPointerException;NullPointerException;();generated", - "kotlin;NullPointerException;NullPointerException;(String);generated", - "kotlin;NumberFormatException;NumberFormatException;();generated", - "kotlin;NumberFormatException;NumberFormatException;(String);generated", - "kotlin;NumbersKt;and;(BigInteger,BigInteger);generated", - "kotlin;NumbersKt;countLeadingZeroBits;(byte);generated", - "kotlin;NumbersKt;countLeadingZeroBits;(int);generated", - "kotlin;NumbersKt;countLeadingZeroBits;(long);generated", - "kotlin;NumbersKt;countLeadingZeroBits;(short);generated", - "kotlin;NumbersKt;countOneBits;(byte);generated", - "kotlin;NumbersKt;countOneBits;(int);generated", - "kotlin;NumbersKt;countOneBits;(long);generated", - "kotlin;NumbersKt;countOneBits;(short);generated", - "kotlin;NumbersKt;countTrailingZeroBits;(byte);generated", - "kotlin;NumbersKt;countTrailingZeroBits;(int);generated", - "kotlin;NumbersKt;countTrailingZeroBits;(long);generated", - "kotlin;NumbersKt;countTrailingZeroBits;(short);generated", - "kotlin;NumbersKt;dec;(BigDecimal);generated", - "kotlin;NumbersKt;dec;(BigInteger);generated", - "kotlin;NumbersKt;div;(BigDecimal,BigDecimal);generated", - "kotlin;NumbersKt;div;(BigInteger,BigInteger);generated", - "kotlin;NumbersKt;floorDiv;(byte,byte);generated", - "kotlin;NumbersKt;floorDiv;(byte,int);generated", - "kotlin;NumbersKt;floorDiv;(byte,long);generated", - "kotlin;NumbersKt;floorDiv;(byte,short);generated", - "kotlin;NumbersKt;floorDiv;(int,byte);generated", - "kotlin;NumbersKt;floorDiv;(int,int);generated", - "kotlin;NumbersKt;floorDiv;(int,long);generated", - "kotlin;NumbersKt;floorDiv;(int,short);generated", - "kotlin;NumbersKt;floorDiv;(long,byte);generated", - "kotlin;NumbersKt;floorDiv;(long,int);generated", - "kotlin;NumbersKt;floorDiv;(long,long);generated", - "kotlin;NumbersKt;floorDiv;(long,short);generated", - "kotlin;NumbersKt;floorDiv;(short,byte);generated", - "kotlin;NumbersKt;floorDiv;(short,int);generated", - "kotlin;NumbersKt;floorDiv;(short,long);generated", - "kotlin;NumbersKt;floorDiv;(short,short);generated", - "kotlin;NumbersKt;fromBits;(DoubleCompanionObject,long);generated", - "kotlin;NumbersKt;fromBits;(FloatCompanionObject,int);generated", - "kotlin;NumbersKt;inc;(BigDecimal);generated", - "kotlin;NumbersKt;inc;(BigInteger);generated", - "kotlin;NumbersKt;inv;(BigInteger);generated", - "kotlin;NumbersKt;isFinite;(double);generated", - "kotlin;NumbersKt;isFinite;(float);generated", - "kotlin;NumbersKt;isInfinite;(double);generated", - "kotlin;NumbersKt;isInfinite;(float);generated", - "kotlin;NumbersKt;isNaN;(double);generated", "kotlin;NumbersKt;isNaN;(float);generated", - "kotlin;NumbersKt;minus;(BigDecimal,BigDecimal);generated", - "kotlin;NumbersKt;minus;(BigInteger,BigInteger);generated", - "kotlin;NumbersKt;mod;(byte,byte);generated", "kotlin;NumbersKt;mod;(byte,int);generated", - "kotlin;NumbersKt;mod;(byte,long);generated", "kotlin;NumbersKt;mod;(byte,short);generated", - "kotlin;NumbersKt;mod;(double,double);generated", - "kotlin;NumbersKt;mod;(double,float);generated", - "kotlin;NumbersKt;mod;(float,double);generated", - "kotlin;NumbersKt;mod;(float,float);generated", "kotlin;NumbersKt;mod;(int,byte);generated", - "kotlin;NumbersKt;mod;(int,int);generated", "kotlin;NumbersKt;mod;(int,long);generated", - "kotlin;NumbersKt;mod;(int,short);generated", "kotlin;NumbersKt;mod;(long,byte);generated", - "kotlin;NumbersKt;mod;(long,int);generated", "kotlin;NumbersKt;mod;(long,long);generated", - "kotlin;NumbersKt;mod;(long,short);generated", - "kotlin;NumbersKt;mod;(short,byte);generated", "kotlin;NumbersKt;mod;(short,int);generated", - "kotlin;NumbersKt;mod;(short,long);generated", - "kotlin;NumbersKt;mod;(short,short);generated", - "kotlin;NumbersKt;or;(BigInteger,BigInteger);generated", - "kotlin;NumbersKt;plus;(BigDecimal,BigDecimal);generated", - "kotlin;NumbersKt;plus;(BigInteger,BigInteger);generated", - "kotlin;NumbersKt;rem;(BigDecimal,BigDecimal);generated", - "kotlin;NumbersKt;rem;(BigInteger,BigInteger);generated", - "kotlin;NumbersKt;rotateLeft;(byte,int);generated", - "kotlin;NumbersKt;rotateLeft;(int,int);generated", - "kotlin;NumbersKt;rotateLeft;(long,int);generated", - "kotlin;NumbersKt;rotateLeft;(short,int);generated", - "kotlin;NumbersKt;rotateRight;(byte,int);generated", - "kotlin;NumbersKt;rotateRight;(int,int);generated", - "kotlin;NumbersKt;rotateRight;(long,int);generated", - "kotlin;NumbersKt;rotateRight;(short,int);generated", - "kotlin;NumbersKt;shl;(BigInteger,int);generated", - "kotlin;NumbersKt;shr;(BigInteger,int);generated", - "kotlin;NumbersKt;takeHighestOneBit;(byte);generated", - "kotlin;NumbersKt;takeHighestOneBit;(int);generated", - "kotlin;NumbersKt;takeHighestOneBit;(long);generated", - "kotlin;NumbersKt;takeHighestOneBit;(short);generated", - "kotlin;NumbersKt;takeLowestOneBit;(byte);generated", - "kotlin;NumbersKt;takeLowestOneBit;(int);generated", - "kotlin;NumbersKt;takeLowestOneBit;(long);generated", - "kotlin;NumbersKt;takeLowestOneBit;(short);generated", - "kotlin;NumbersKt;times;(BigDecimal,BigDecimal);generated", - "kotlin;NumbersKt;times;(BigInteger,BigInteger);generated", - "kotlin;NumbersKt;toBigDecimal;(BigInteger);generated", - "kotlin;NumbersKt;toBigDecimal;(BigInteger,int,MathContext);generated", - "kotlin;NumbersKt;toBigDecimal;(double);generated", - "kotlin;NumbersKt;toBigDecimal;(double,MathContext);generated", - "kotlin;NumbersKt;toBigDecimal;(float);generated", - "kotlin;NumbersKt;toBigDecimal;(float,MathContext);generated", - "kotlin;NumbersKt;toBigDecimal;(int);generated", - "kotlin;NumbersKt;toBigDecimal;(int,MathContext);generated", - "kotlin;NumbersKt;toBigDecimal;(long);generated", - "kotlin;NumbersKt;toBigDecimal;(long,MathContext);generated", - "kotlin;NumbersKt;toBigInteger;(int);generated", - "kotlin;NumbersKt;toBigInteger;(long);generated", - "kotlin;NumbersKt;toBits;(double);generated", "kotlin;NumbersKt;toBits;(float);generated", - "kotlin;NumbersKt;toRawBits;(double);generated", - "kotlin;NumbersKt;toRawBits;(float);generated", - "kotlin;NumbersKt;unaryMinus;(BigDecimal);generated", - "kotlin;NumbersKt;unaryMinus;(BigInteger);generated", - "kotlin;NumbersKt;xor;(BigInteger,BigInteger);generated", - "kotlin;OptIn;OptIn;(KClass[]);generated", "kotlin;OptIn;markerClass;();generated", - "kotlin;OptionalExpectation;OptionalExpectation;();generated", - "kotlin;OverloadResolutionByLambdaReturnType;OverloadResolutionByLambdaReturnType;();generated", - "kotlin;Pair;equals;(Object);generated", "kotlin;Pair;hashCode;();generated", - "kotlin;ParameterName;ParameterName;(String);generated", - "kotlin;ParameterName;name;();generated", - "kotlin;PreconditionsKt;assert;(boolean);generated", - "kotlin;PreconditionsKt;assert;(boolean,Function0);generated", - "kotlin;PreconditionsKt;check;(boolean);generated", - "kotlin;PreconditionsKt;check;(boolean,Function0);generated", - "kotlin;PreconditionsKt;error;(Object);generated", - "kotlin;PreconditionsKt;require;(boolean);generated", - "kotlin;PreconditionsKt;require;(boolean,Function0);generated", - "kotlin;PropertyReferenceDelegatesKt;getValue;(KProperty0,Object,KProperty);generated", - "kotlin;PropertyReferenceDelegatesKt;getValue;(KProperty1,Object,KProperty);generated", - "kotlin;PropertyReferenceDelegatesKt;setValue;(KMutableProperty0,Object,KProperty,Object);generated", - "kotlin;PropertyReferenceDelegatesKt;setValue;(KMutableProperty1,Object,KProperty,Object);generated", - "kotlin;PublishedApi;PublishedApi;();generated", - "kotlin;ReplaceWith;ReplaceWith;(String,String[]);generated", - "kotlin;ReplaceWith;expression;();generated", "kotlin;ReplaceWith;imports;();generated", - "kotlin;RequiresOptIn$Level;valueOf;(String);generated", - "kotlin;RequiresOptIn$Level;values;();generated", - "kotlin;RequiresOptIn;RequiresOptIn;(String,Level);generated", - "kotlin;RequiresOptIn;level;();generated", "kotlin;RequiresOptIn;message;();generated", - "kotlin;Result;equals;(Object);generated", "kotlin;Result;hashCode;();generated", - "kotlin;Result;isFailure;();generated", "kotlin;Result;isSuccess;();generated", - "kotlin;ResultKt;runCatching;(Function0);generated", - "kotlin;ResultKt;runCatching;(Object,Function1);generated", - "kotlin;RuntimeException;RuntimeException;();generated", - "kotlin;RuntimeException;RuntimeException;(String);generated", - "kotlin;RuntimeException;RuntimeException;(String,Throwable);generated", - "kotlin;RuntimeException;RuntimeException;(Throwable);generated", - "kotlin;SinceKotlin;SinceKotlin;(String);generated", - "kotlin;SinceKotlin;version;();generated", "kotlin;StandardKt;TODO;();generated", - "kotlin;StandardKt;TODO;(String);generated", - "kotlin;StandardKt;repeat;(int,Function1);generated", - "kotlin;StandardKt;run;(Function0);generated", - "kotlin;StandardKt;synchronized;(Object,Function0);generated", - "kotlin;Suppress;Suppress;(String[]);generated", "kotlin;Suppress;names;();generated", - "kotlin;Throws;Throws;(KClass[]);generated", "kotlin;Throws;exceptionClasses;();generated", - "kotlin;Triple;equals;(Object);generated", "kotlin;Triple;hashCode;();generated", - "kotlin;TypeCastException;TypeCastException;();generated", - "kotlin;TypeCastException;TypeCastException;(String);generated", - "kotlin;UByte$Companion;getMAX_VALUE;();generated", - "kotlin;UByte$Companion;getMIN_VALUE;();generated", - "kotlin;UByte$Companion;getSIZE_BITS;();generated", - "kotlin;UByte$Companion;getSIZE_BYTES;();generated", "kotlin;UByte;and;(byte);generated", - "kotlin;UByte;compareTo;(byte);generated", "kotlin;UByte;compareTo;(int);generated", - "kotlin;UByte;compareTo;(long);generated", "kotlin;UByte;compareTo;(short);generated", - "kotlin;UByte;dec;();generated", "kotlin;UByte;div;(byte);generated", - "kotlin;UByte;div;(int);generated", "kotlin;UByte;div;(long);generated", - "kotlin;UByte;div;(short);generated", "kotlin;UByte;equals;(Object);generated", - "kotlin;UByte;floorDiv;(byte);generated", "kotlin;UByte;floorDiv;(int);generated", - "kotlin;UByte;floorDiv;(long);generated", "kotlin;UByte;floorDiv;(short);generated", - "kotlin;UByte;hashCode;();generated", "kotlin;UByte;inc;();generated", - "kotlin;UByte;inv;();generated", "kotlin;UByte;minus;(byte);generated", - "kotlin;UByte;minus;(int);generated", "kotlin;UByte;minus;(long);generated", - "kotlin;UByte;minus;(short);generated", "kotlin;UByte;mod;(byte);generated", - "kotlin;UByte;mod;(int);generated", "kotlin;UByte;mod;(long);generated", - "kotlin;UByte;mod;(short);generated", "kotlin;UByte;or;(byte);generated", - "kotlin;UByte;plus;(byte);generated", "kotlin;UByte;plus;(int);generated", - "kotlin;UByte;plus;(long);generated", "kotlin;UByte;plus;(short);generated", - "kotlin;UByte;rangeTo;(byte);generated", "kotlin;UByte;rem;(byte);generated", - "kotlin;UByte;rem;(int);generated", "kotlin;UByte;rem;(long);generated", - "kotlin;UByte;rem;(short);generated", "kotlin;UByte;times;(byte);generated", - "kotlin;UByte;times;(int);generated", "kotlin;UByte;times;(long);generated", - "kotlin;UByte;times;(short);generated", "kotlin;UByte;toByte;();generated", - "kotlin;UByte;toDouble;();generated", "kotlin;UByte;toFloat;();generated", - "kotlin;UByte;toInt;();generated", "kotlin;UByte;toLong;();generated", - "kotlin;UByte;toShort;();generated", "kotlin;UByte;toString;();generated", - "kotlin;UByte;toUInt;();generated", "kotlin;UByte;toULong;();generated", - "kotlin;UByte;toUShort;();generated", "kotlin;UByte;xor;(byte);generated", - "kotlin;UByteArray;UByteArray;(int);generated", - "kotlin;UByteArray;equals;(Object);generated", "kotlin;UByteArray;get;(int);generated", - "kotlin;UByteArray;hashCode;();generated", "kotlin;UByteArray;set;(int,byte);generated", - "kotlin;UByteArray;toString;();generated", - "kotlin;UByteArrayKt;UByteArray;(int,Function1);generated", - "kotlin;UByteKt;toUByte;(byte);generated", "kotlin;UByteKt;toUByte;(int);generated", - "kotlin;UByteKt;toUByte;(long);generated", "kotlin;UByteKt;toUByte;(short);generated", - "kotlin;UInt$Companion;getMAX_VALUE;();generated", - "kotlin;UInt$Companion;getMIN_VALUE;();generated", - "kotlin;UInt$Companion;getSIZE_BITS;();generated", - "kotlin;UInt$Companion;getSIZE_BYTES;();generated", "kotlin;UInt;and;(int);generated", - "kotlin;UInt;compareTo;(byte);generated", "kotlin;UInt;compareTo;(int);generated", - "kotlin;UInt;compareTo;(long);generated", "kotlin;UInt;compareTo;(short);generated", - "kotlin;UInt;dec;();generated", "kotlin;UInt;div;(byte);generated", - "kotlin;UInt;div;(int);generated", "kotlin;UInt;div;(long);generated", - "kotlin;UInt;div;(short);generated", "kotlin;UInt;equals;(Object);generated", - "kotlin;UInt;floorDiv;(byte);generated", "kotlin;UInt;floorDiv;(int);generated", - "kotlin;UInt;floorDiv;(long);generated", "kotlin;UInt;floorDiv;(short);generated", - "kotlin;UInt;hashCode;();generated", "kotlin;UInt;inc;();generated", - "kotlin;UInt;inv;();generated", "kotlin;UInt;minus;(byte);generated", - "kotlin;UInt;minus;(int);generated", "kotlin;UInt;minus;(long);generated", - "kotlin;UInt;minus;(short);generated", "kotlin;UInt;mod;(byte);generated", - "kotlin;UInt;mod;(int);generated", "kotlin;UInt;mod;(long);generated", - "kotlin;UInt;mod;(short);generated", "kotlin;UInt;or;(int);generated", - "kotlin;UInt;plus;(byte);generated", "kotlin;UInt;plus;(int);generated", - "kotlin;UInt;plus;(long);generated", "kotlin;UInt;plus;(short);generated", - "kotlin;UInt;rangeTo;(int);generated", "kotlin;UInt;rem;(byte);generated", - "kotlin;UInt;rem;(int);generated", "kotlin;UInt;rem;(long);generated", - "kotlin;UInt;rem;(short);generated", "kotlin;UInt;shl;(int);generated", - "kotlin;UInt;shr;(int);generated", "kotlin;UInt;times;(byte);generated", - "kotlin;UInt;times;(int);generated", "kotlin;UInt;times;(long);generated", - "kotlin;UInt;times;(short);generated", "kotlin;UInt;toByte;();generated", - "kotlin;UInt;toDouble;();generated", "kotlin;UInt;toFloat;();generated", - "kotlin;UInt;toInt;();generated", "kotlin;UInt;toLong;();generated", - "kotlin;UInt;toShort;();generated", "kotlin;UInt;toString;();generated", - "kotlin;UInt;toUByte;();generated", "kotlin;UInt;toULong;();generated", - "kotlin;UInt;toUShort;();generated", "kotlin;UInt;xor;(int);generated", - "kotlin;UIntArray;UIntArray;(int);generated", "kotlin;UIntArray;equals;(Object);generated", - "kotlin;UIntArray;get;(int);generated", "kotlin;UIntArray;hashCode;();generated", - "kotlin;UIntArray;set;(int,int);generated", "kotlin;UIntArray;toString;();generated", - "kotlin;UIntArrayKt;UIntArray;(int,Function1);generated", - "kotlin;UIntKt;toUInt;(byte);generated", "kotlin;UIntKt;toUInt;(double);generated", - "kotlin;UIntKt;toUInt;(float);generated", "kotlin;UIntKt;toUInt;(int);generated", - "kotlin;UIntKt;toUInt;(long);generated", "kotlin;UIntKt;toUInt;(short);generated", - "kotlin;ULong$Companion;getMAX_VALUE;();generated", - "kotlin;ULong$Companion;getMIN_VALUE;();generated", - "kotlin;ULong$Companion;getSIZE_BITS;();generated", - "kotlin;ULong$Companion;getSIZE_BYTES;();generated", "kotlin;ULong;and;(long);generated", - "kotlin;ULong;compareTo;(byte);generated", "kotlin;ULong;compareTo;(int);generated", - "kotlin;ULong;compareTo;(long);generated", "kotlin;ULong;compareTo;(short);generated", - "kotlin;ULong;dec;();generated", "kotlin;ULong;div;(byte);generated", - "kotlin;ULong;div;(int);generated", "kotlin;ULong;div;(long);generated", - "kotlin;ULong;div;(short);generated", "kotlin;ULong;equals;(Object);generated", - "kotlin;ULong;floorDiv;(byte);generated", "kotlin;ULong;floorDiv;(int);generated", - "kotlin;ULong;floorDiv;(long);generated", "kotlin;ULong;floorDiv;(short);generated", - "kotlin;ULong;hashCode;();generated", "kotlin;ULong;inc;();generated", - "kotlin;ULong;inv;();generated", "kotlin;ULong;minus;(byte);generated", - "kotlin;ULong;minus;(int);generated", "kotlin;ULong;minus;(long);generated", - "kotlin;ULong;minus;(short);generated", "kotlin;ULong;mod;(byte);generated", - "kotlin;ULong;mod;(int);generated", "kotlin;ULong;mod;(long);generated", - "kotlin;ULong;mod;(short);generated", "kotlin;ULong;or;(long);generated", - "kotlin;ULong;plus;(byte);generated", "kotlin;ULong;plus;(int);generated", - "kotlin;ULong;plus;(long);generated", "kotlin;ULong;plus;(short);generated", - "kotlin;ULong;rangeTo;(long);generated", "kotlin;ULong;rem;(byte);generated", - "kotlin;ULong;rem;(int);generated", "kotlin;ULong;rem;(long);generated", - "kotlin;ULong;rem;(short);generated", "kotlin;ULong;shl;(int);generated", - "kotlin;ULong;shr;(int);generated", "kotlin;ULong;times;(byte);generated", - "kotlin;ULong;times;(int);generated", "kotlin;ULong;times;(long);generated", - "kotlin;ULong;times;(short);generated", "kotlin;ULong;toByte;();generated", - "kotlin;ULong;toDouble;();generated", "kotlin;ULong;toFloat;();generated", - "kotlin;ULong;toInt;();generated", "kotlin;ULong;toLong;();generated", - "kotlin;ULong;toShort;();generated", "kotlin;ULong;toString;();generated", - "kotlin;ULong;toUByte;();generated", "kotlin;ULong;toUInt;();generated", - "kotlin;ULong;toUShort;();generated", "kotlin;ULong;xor;(long);generated", - "kotlin;ULongArray;ULongArray;(int);generated", - "kotlin;ULongArray;equals;(Object);generated", "kotlin;ULongArray;get;(int);generated", - "kotlin;ULongArray;hashCode;();generated", "kotlin;ULongArray;set;(int,long);generated", - "kotlin;ULongArray;toString;();generated", - "kotlin;ULongArrayKt;ULongArray;(int,Function1);generated", - "kotlin;ULongKt;toULong;(byte);generated", "kotlin;ULongKt;toULong;(double);generated", - "kotlin;ULongKt;toULong;(float);generated", "kotlin;ULongKt;toULong;(int);generated", - "kotlin;ULongKt;toULong;(long);generated", "kotlin;ULongKt;toULong;(short);generated", - "kotlin;UNumbersKt;countLeadingZeroBits;(byte);generated", - "kotlin;UNumbersKt;countLeadingZeroBits;(int);generated", - "kotlin;UNumbersKt;countLeadingZeroBits;(long);generated", - "kotlin;UNumbersKt;countLeadingZeroBits;(short);generated", - "kotlin;UNumbersKt;countOneBits;(byte);generated", - "kotlin;UNumbersKt;countOneBits;(int);generated", - "kotlin;UNumbersKt;countOneBits;(long);generated", - "kotlin;UNumbersKt;countOneBits;(short);generated", - "kotlin;UNumbersKt;countTrailingZeroBits;(byte);generated", - "kotlin;UNumbersKt;countTrailingZeroBits;(int);generated", - "kotlin;UNumbersKt;countTrailingZeroBits;(long);generated", - "kotlin;UNumbersKt;countTrailingZeroBits;(short);generated", - "kotlin;UNumbersKt;rotateLeft;(byte,int);generated", - "kotlin;UNumbersKt;rotateLeft;(int,int);generated", - "kotlin;UNumbersKt;rotateLeft;(long,int);generated", - "kotlin;UNumbersKt;rotateLeft;(short,int);generated", - "kotlin;UNumbersKt;rotateRight;(byte,int);generated", - "kotlin;UNumbersKt;rotateRight;(int,int);generated", - "kotlin;UNumbersKt;rotateRight;(long,int);generated", - "kotlin;UNumbersKt;rotateRight;(short,int);generated", - "kotlin;UNumbersKt;takeHighestOneBit;(byte);generated", - "kotlin;UNumbersKt;takeHighestOneBit;(int);generated", - "kotlin;UNumbersKt;takeHighestOneBit;(long);generated", - "kotlin;UNumbersKt;takeHighestOneBit;(short);generated", - "kotlin;UNumbersKt;takeLowestOneBit;(byte);generated", - "kotlin;UNumbersKt;takeLowestOneBit;(int);generated", - "kotlin;UNumbersKt;takeLowestOneBit;(long);generated", - "kotlin;UNumbersKt;takeLowestOneBit;(short);generated", - "kotlin;UShort$Companion;getMAX_VALUE;();generated", - "kotlin;UShort$Companion;getMIN_VALUE;();generated", - "kotlin;UShort$Companion;getSIZE_BITS;();generated", - "kotlin;UShort$Companion;getSIZE_BYTES;();generated", "kotlin;UShort;and;(short);generated", - "kotlin;UShort;compareTo;(byte);generated", "kotlin;UShort;compareTo;(int);generated", - "kotlin;UShort;compareTo;(long);generated", "kotlin;UShort;compareTo;(short);generated", - "kotlin;UShort;dec;();generated", "kotlin;UShort;div;(byte);generated", - "kotlin;UShort;div;(int);generated", "kotlin;UShort;div;(long);generated", - "kotlin;UShort;div;(short);generated", "kotlin;UShort;equals;(Object);generated", - "kotlin;UShort;floorDiv;(byte);generated", "kotlin;UShort;floorDiv;(int);generated", - "kotlin;UShort;floorDiv;(long);generated", "kotlin;UShort;floorDiv;(short);generated", - "kotlin;UShort;hashCode;();generated", "kotlin;UShort;inc;();generated", - "kotlin;UShort;inv;();generated", "kotlin;UShort;minus;(byte);generated", - "kotlin;UShort;minus;(int);generated", "kotlin;UShort;minus;(long);generated", - "kotlin;UShort;minus;(short);generated", "kotlin;UShort;mod;(byte);generated", - "kotlin;UShort;mod;(int);generated", "kotlin;UShort;mod;(long);generated", - "kotlin;UShort;mod;(short);generated", "kotlin;UShort;or;(short);generated", - "kotlin;UShort;plus;(byte);generated", "kotlin;UShort;plus;(int);generated", - "kotlin;UShort;plus;(long);generated", "kotlin;UShort;plus;(short);generated", - "kotlin;UShort;rangeTo;(short);generated", "kotlin;UShort;rem;(byte);generated", - "kotlin;UShort;rem;(int);generated", "kotlin;UShort;rem;(long);generated", - "kotlin;UShort;rem;(short);generated", "kotlin;UShort;times;(byte);generated", - "kotlin;UShort;times;(int);generated", "kotlin;UShort;times;(long);generated", - "kotlin;UShort;times;(short);generated", "kotlin;UShort;toByte;();generated", - "kotlin;UShort;toDouble;();generated", "kotlin;UShort;toFloat;();generated", - "kotlin;UShort;toInt;();generated", "kotlin;UShort;toLong;();generated", - "kotlin;UShort;toShort;();generated", "kotlin;UShort;toString;();generated", - "kotlin;UShort;toUByte;();generated", "kotlin;UShort;toUInt;();generated", - "kotlin;UShort;toULong;();generated", "kotlin;UShort;xor;(short);generated", - "kotlin;UShortArray;UShortArray;(int);generated", - "kotlin;UShortArray;equals;(Object);generated", "kotlin;UShortArray;get;(int);generated", - "kotlin;UShortArray;hashCode;();generated", "kotlin;UShortArray;set;(int,short);generated", - "kotlin;UShortArray;toString;();generated", - "kotlin;UShortArrayKt;UShortArray;(int,Function1);generated", - "kotlin;UShortKt;toUShort;(byte);generated", "kotlin;UShortKt;toUShort;(int);generated", - "kotlin;UShortKt;toUShort;(long);generated", "kotlin;UShortKt;toUShort;(short);generated", - "kotlin;UninitializedPropertyAccessException;UninitializedPropertyAccessException;();generated", - "kotlin;UninitializedPropertyAccessException;UninitializedPropertyAccessException;(String);generated", - "kotlin;UninitializedPropertyAccessException;UninitializedPropertyAccessException;(String,Throwable);generated", - "kotlin;UninitializedPropertyAccessException;UninitializedPropertyAccessException;(Throwable);generated", - "kotlin;Unit;toString;();generated", "kotlin;UnsafeVariance;UnsafeVariance;();generated", - "kotlin;UnsupportedOperationException;UnsupportedOperationException;();generated", - "kotlin;UnsupportedOperationException;UnsupportedOperationException;(String);generated", - "kotlin;UnsupportedOperationException;UnsupportedOperationException;(String,Throwable);generated", - "kotlin;UnsupportedOperationException;UnsupportedOperationException;(Throwable);generated", - "kotlin;UseExperimental;UseExperimental;(KClass[]);generated", - "kotlin;UseExperimental;markerClass;();generated" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/kotlin/StdLibGenerated.qll b/java/ql/lib/semmle/code/java/frameworks/kotlin/StdLibGenerated.qll index ed2b0165f47..e4a66f67762 100644 --- a/java/ql/lib/semmle/code/java/frameworks/kotlin/StdLibGenerated.qll +++ b/java/ql/lib/semmle/code/java/frameworks/kotlin/StdLibGenerated.qll @@ -5,1864 +5,3 @@ import java private import semmle.code.java.dataflow.ExternalFlow - -private class StdLibGeneratedSinksCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "kotlin.io;FilesKt;false;appendBytes;(File,byte[]);;Argument[0];create-file;generated", - "kotlin.io;FilesKt;false;appendText;(File,String,Charset);;Argument[0];create-file;generated", - "kotlin.io;FilesKt;false;bufferedWriter;(File,Charset,int);;Argument[0];create-file;generated", - "kotlin.io;FilesKt;false;copyRecursively;(File,File,boolean,Function2);;Argument[1];create-file;generated", - "kotlin.io;FilesKt;false;copyTo;(File,File,boolean,int);;Argument[1];create-file;generated", - "kotlin.io;FilesKt;false;outputStream;(File);;Argument[0];create-file;generated", - "kotlin.io;FilesKt;false;printWriter;(File,Charset);;Argument[0];create-file;generated", - "kotlin.io;FilesKt;false;writeBytes;(File,byte[]);;Argument[0];create-file;generated", - "kotlin.io;FilesKt;false;writeText;(File,String,Charset);;Argument[0];create-file;generated", - "kotlin.io;FilesKt;false;writer;(File,Charset);;Argument[0];create-file;generated", - "kotlin.io;TextStreamsKt;false;readBytes;(URL);;Argument[0];open-url;generated", - "kotlin.io;TextStreamsKt;false;readText;(URL,Charset);;Argument[0];open-url;generated" - ] - } -} - -private class StdLibGeneratedSummaryCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "kotlin.collections;AbstractCollection;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArrayDeque;false;ArrayDeque;(Collection);;Argument[0].Element;Argument[-1];taint;generated", - "kotlin.collections;ArrayDeque;false;addFirst;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.collections;ArrayDeque;false;addLast;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.collections;ArrayDeque;false;first;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArrayDeque;false;firstOrNull;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArrayDeque;false;last;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArrayDeque;false;lastOrNull;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArrayDeque;false;removeFirst;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArrayDeque;false;removeFirstOrNull;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArrayDeque;false;removeLast;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArrayDeque;false;removeLastOrNull;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;asList;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(Object[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(Object[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(boolean[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(boolean[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(byte[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(byte[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(char[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(char[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(double[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(double[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(float[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(float[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(int[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(int[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(long[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(long[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(short[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(short[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(Object[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(boolean[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(byte[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(char[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(double[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(float[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(int[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(long[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(short[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(Object[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(boolean[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(byte[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(char[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(double[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(float[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(int[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(long[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(short[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(Object[],Object[],int,int,int);;Argument[0].ArrayElement;Argument[1].ArrayElement;taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(Object[],Object[],int,int,int);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(Object[],Object[],int,int,int);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(byte[],byte[],int,int,int);;Argument[0];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(byte[],byte[],int,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(byte[],byte[],int,int,int);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(char[],char[],int,int,int);;Argument[0];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(char[],char[],int,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(char[],char[],int,int,int);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOf;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOf;(Object[],int);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOf;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOf;(byte[],int);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOf;(char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOf;(char[],int);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOfRangeInline;(Object[],int,int);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOfRangeInline;(byte[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOfRangeInline;(char[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;drop;(Object[],int);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;dropLast;(Object[],int);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;dropLastWhile;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fill;(Object[],Object,int,int);;Argument[1];Argument[0].ArrayElement;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(Object[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(boolean[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(byte[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(char[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(double[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(float[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(int[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(long[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(short[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIsInstanceTo;(Object[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIsInstanceTo;(Object[],Collection,Class);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotNullTo;(Object[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(Object[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(boolean[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(byte[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(char[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(double[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(float[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(int[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(long[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(short[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(Object[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(boolean[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(byte[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(char[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(double[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(float[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(int[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(long[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(short[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;findLast;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;first;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;firstOrNull;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(Object[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(boolean[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(byte[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(char[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(double[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(float[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(int[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(long[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(short[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedSequenceTo;(Object[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapSequenceTo;(Object[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(Object[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(boolean[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(byte[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(char[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(double[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(float[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(int[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(long[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(short[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(Object[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(boolean[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(byte[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(char[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(double[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(float[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(int[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(long[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(short[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(Object[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(boolean[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(byte[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(char[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(double[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(float[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(int[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(long[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(short[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(Object[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(boolean[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(byte[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(char[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(double[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(float[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(int[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(long[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(short[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(Object[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(boolean[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(byte[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(char[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(double[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(float[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(int[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(long[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(short[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(Object[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(Object[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(boolean[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(boolean[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(byte[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(byte[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(char[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(char[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(double[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(double[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(float[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(float[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(int[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(int[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(long[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(long[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(short[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(short[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;ifEmpty;(Object[],Function0);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(Object[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(Object[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(Object[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(Object[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(boolean[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(boolean[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(boolean[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(boolean[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(byte[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(byte[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(byte[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(byte[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(char[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(char[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(char[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(char[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(double[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(double[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(double[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(double[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(float[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(float[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(float[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(float[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(int[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(int[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(int[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(int[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(long[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(long[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(long[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(long[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(short[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(short[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(short[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(short[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;last;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;last;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;lastOrNull;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;lastOrNull;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedNotNullTo;(Object[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(Object[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(boolean[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(byte[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(char[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(double[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(float[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(int[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(long[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(short[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapNotNullTo;(Object[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(Object[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(boolean[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(byte[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(char[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(double[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(float[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(int[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(long[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(short[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;max;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxBy;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxByOrNull;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxByOrThrow;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxOfWith;(Object[],Comparator,Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxOfWithOrNull;(Object[],Comparator,Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxOrNull;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxOrThrow;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxWith;(Object[],Comparator);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxWithOrNull;(Object[],Comparator);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxWithOrThrow;(Object[],Comparator);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;min;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minBy;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minByOrNull;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minByOrThrow;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minOfWith;(Object[],Comparator,Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minOfWithOrNull;(Object[],Comparator,Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minOrNull;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minOrThrow;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minWith;(Object[],Comparator);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minWithOrNull;(Object[],Comparator);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minWithOrThrow;(Object[],Comparator);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;onEach;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;onEach;(byte[],Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;onEach;(char[],Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;onEachIndexed;(Object[],Function2);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;onEachIndexed;(byte[],Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;onEachIndexed;(char[],Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;orEmpty;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(Object[],Collection);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(Object[],Object);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(Object[],Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(Object[],Object[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(byte[],Collection);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(byte[],byte);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(byte[],byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(byte[],byte[]);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(char[],Collection);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(char[],char);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(char[],char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(char[],char[]);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plusElement;(Object[],Object);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;reduce;(Object[],Function2);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;reduceIndexed;(Object[],Function3);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;reduceIndexedOrNull;(Object[],Function3);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;reduceOrNull;(Object[],Function2);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;requireNoNulls;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;reversed;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;reversedArray;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;reversedArray;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;reversedArray;(char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(Object[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(boolean[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(byte[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(char[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(double[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(float[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(int[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(long[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(short[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(Object[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(boolean[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(byte[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(char[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(double[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(float[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(int[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(long[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(short[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(Object[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(boolean[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(byte[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(char[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(double[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(float[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(int[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(long[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(short[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(Object[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(boolean[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(byte[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(char[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(double[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(float[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(int[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(long[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(short[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;single;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;singleOrNull;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;slice;(Object[],IntRange);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sliceArray;(Object[],Collection);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sliceArray;(Object[],IntRange);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sliceArray;(byte[],IntRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sliceArray;(char[],IntRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sorted;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedArray;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedArray;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedArray;(char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedArrayDescending;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedArrayDescending;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedArrayDescending;(char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedArrayWith;(Object[],Comparator);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedBy;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedByDescending;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedDescending;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedWith;(Object[],Comparator);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;take;(Object[],int);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;takeLast;(Object[],int);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;takeLastWhile;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(Object[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(boolean[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(byte[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(char[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(double[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(float[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(int[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(long[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(short[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toList;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toMutableList;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toSet;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toString;(byte[],Charset);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toTypedArray;(Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;union;(Object[],Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;union;(byte[],Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;union;(char[],Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;zip;(Object[],Iterable);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;zip;(Object[],Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;zip;(Object[],Iterable,Function2);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;zip;(Object[],Iterable,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;zip;(Object[],Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;zip;(Object[],Object[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;zip;(Object[],Object[],Function2);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;zip;(Object[],Object[],Function2);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;addAll;(Collection,Iterable);;Argument[1].Element;Argument[0].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;addAll;(Collection,Object[]);;Argument[1].ArrayElement;Argument[0].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;addAll;(Collection,Sequence);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;arrayListOf;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;asIterable;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;asReversed;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;asReversedMutable;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associate;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateBy;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateBy;(Iterable,Function1,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateByTo;(Iterable,Map,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;associateByTo;(Iterable,Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateByTo;(Iterable,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateByTo;(Iterable,Map,Function1,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;associateByTo;(Iterable,Map,Function1,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateByTo;(Iterable,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateTo;(Iterable,Map,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;associateTo;(Iterable,Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateTo;(Iterable,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateWith;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateWithTo;(Iterable,Map,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;associateWithTo;(Iterable,Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateWithTo;(Iterable,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;component1;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;component2;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;component3;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;component4;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;component5;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;distinct;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;distinctBy;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;drop;(Iterable,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;dropLast;(List,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;dropLastWhile;(List,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;dropWhile;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;elementAt;(Iterable,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;elementAt;(List,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;elementAtOrElse;(Iterable,int,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;elementAtOrElse;(List,int,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;elementAtOrNull;(Iterable,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;elementAtOrNull;(List,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;fill;(List,Object);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;filter;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIndexedTo;(Iterable,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIsInstance;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIsInstance;(Iterable,Class);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIsInstanceTo;(Iterable,Collection);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIsInstanceTo;(Iterable,Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIsInstanceTo;(Iterable,Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIsInstanceTo;(Iterable,Collection,Class);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIsInstanceTo;(Iterable,Collection,Class);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIsInstanceTo;(Iterable,Collection,Class);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterNot;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterNotNull;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterNotNullTo;(Iterable,Collection);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;filterNotNullTo;(Iterable,Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterNotNullTo;(Iterable,Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterNotTo;(Iterable,Collection,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;filterNotTo;(Iterable,Collection,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterNotTo;(Iterable,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterTo;(Iterable,Collection,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;filterTo;(Iterable,Collection,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterTo;(Iterable,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;find;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;findLast;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;findLast;(List,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;first;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;first;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;first;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;firstNotNullOf;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;firstNotNullOfOrNull;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;firstOrNull;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;firstOrNull;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;firstOrNull;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;flatMapIndexedIterableTo;(Iterable,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;flatMapIndexedSequenceTo;(Iterable,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;flatMapSequenceTo;(Iterable,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;flatMapTo;(Iterable,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;flatten;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;fold;(Iterable,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;foldIndexed;(Iterable,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;foldRight;(List,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;foldRightIndexed;(List,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;getOrElse;(List,int,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;getOrNull;(List,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;groupByTo;(Iterable,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;groupByTo;(Iterable,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;ifEmpty;(Collection,Function0);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;intersect;(Iterable,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;iterator;(Iterator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[0].Element;Argument[1];taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinToString;(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinToString;(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinToString;(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinToString;(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinToString;(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;last;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;last;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;last;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;last;(List,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;lastOrNull;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;lastOrNull;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;lastOrNull;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;lastOrNull;(List,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;listOf;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;listOf;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;listOfNotNull;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;map;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;mapIndexedNotNullTo;(Iterable,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;mapIndexedTo;(Iterable,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;mapNotNullTo;(Iterable,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;mapTo;(Iterable,Collection,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;mapTo;(Iterable,Collection,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;mapTo;(Iterable,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;max;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxBy;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxByOrNull;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxByOrThrow;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxOfWith;(Iterable,Comparator,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxOfWithOrNull;(Iterable,Comparator,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxOrNull;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxOrThrow;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxWith;(Iterable,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxWithOrNull;(Iterable,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxWithOrThrow;(Iterable,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;min;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minBy;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minByOrNull;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minByOrThrow;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minOfWith;(Iterable,Comparator,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minOfWithOrNull;(Iterable,Comparator,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minOrNull;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minOrThrow;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minWith;(Iterable,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minWithOrNull;(Iterable,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minWithOrThrow;(Iterable,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minus;(Iterable,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minus;(Iterable,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minus;(Iterable,Object[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minus;(Iterable,Sequence);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minusElement;(Iterable,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;mutableListOf;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;onEach;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;onEachIndexed;(Iterable,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;orEmpty;(Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;orEmpty;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;partition;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Collection,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Collection,Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Collection,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Collection,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Collection,Object[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Collection,Object[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Collection,Sequence);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Collection,Sequence);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Iterable,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Iterable,Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Iterable,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Iterable,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Iterable,Object[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Iterable,Object[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Iterable,Sequence);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Iterable,Sequence);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plusAssign;(Collection,Iterable);;Argument[1].Element;Argument[0].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;plusAssign;(Collection,Object);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;plusAssign;(Collection,Object[]);;Argument[1].ArrayElement;Argument[0].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;plusAssign;(Collection,Sequence);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;plusElement;(Collection,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plusElement;(Collection,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plusElement;(Iterable,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plusElement;(Iterable,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;random;(Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;random;(Collection,Random);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;randomOrNull;(Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;randomOrNull;(Collection,Random);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reduce;(Iterable,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reduceIndexed;(Iterable,Function3);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reduceIndexedOrNull;(Iterable,Function3);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reduceOrNull;(Iterable,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reduceRight;(List,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reduceRightIndexed;(List,Function3);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reduceRightIndexedOrNull;(List,Function3);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reduceRightOrNull;(List,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;remove;(List,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;removeFirst;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;removeFirstOrNull;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;removeLast;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;removeLastOrNull;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;requireNoNulls;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;requireNoNulls;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reversed;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;runningFold;(Iterable,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;runningFoldIndexed;(Iterable,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;scan;(Iterable,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;scanIndexed;(Iterable,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;shuffled;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;shuffled;(Iterable,Random);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;single;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;single;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;single;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;singleOrNull;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;singleOrNull;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;singleOrNull;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;slice;(List,IntRange);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;slice;(List,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;sorted;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;sortedBy;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;sortedByDescending;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;sortedDescending;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;sortedWith;(Iterable,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;subtract;(Iterable,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;take;(Iterable,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;takeLast;(List,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;takeLastWhile;(List,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;takeWhile;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toCollection;(Iterable,Collection);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;toCollection;(Iterable,Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toCollection;(Iterable,Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toHashSet;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toList;(Enumeration);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toList;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toMutableList;(Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toMutableList;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toMutableSet;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toSet;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toSortedSet;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toSortedSet;(Iterable,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;union;(Iterable,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;union;(Iterable,Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;unzip;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;withIndex;(Iterator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zip;(Iterable,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zip;(Iterable,Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zip;(Iterable,Iterable,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zip;(Iterable,Iterable,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zip;(Iterable,Object[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zip;(Iterable,Object[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zip;(Iterable,Object[],Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zip;(Iterable,Object[],Function2);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zipWithNext;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zipWithNext;(Iterable,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;GroupingKt;false;aggregateTo;(Grouping,Map,Function4);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;GroupingKt;false;eachCountTo;(Grouping,Map);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;GroupingKt;false;foldTo;(Grouping,Map,Function2,Function3);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;GroupingKt;false;foldTo;(Grouping,Map,Object,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;GroupingKt;false;reduceTo;(Grouping,Map,Function3);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;IndexedValue;false;IndexedValue;(int,Object);;Argument[1];Argument[-1];taint;generated", - "kotlin.collections;IndexedValue;false;component2;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;IndexedValue;false;copy;(int,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;IndexedValue;false;getValue;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;IndexedValue;false;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;MapAccessorsKt;false;getValue;(Map,Object,KProperty);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapAccessorsKt;false;getVar;(Map,Object,KProperty);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapAccessorsKt;false;setValue;(Map,Object,KProperty,Object);;Argument[2];Argument[0].Element;taint;generated", - "kotlin.collections;MapAccessorsKt;false;setValue;(Map,Object,KProperty,Object);;Argument[3];Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;asIterable;(Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;component1;(Entry);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;component2;(Entry);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;filter;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;filterKeys;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;filterNot;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;filterNotTo;(Map,Map,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;MapsKt;false;filterNotTo;(Map,Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;filterNotTo;(Map,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;filterTo;(Map,Map,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;MapsKt;false;filterTo;(Map,Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;filterTo;(Map,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;filterValues;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;firstNotNullOf;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;firstNotNullOfOrNull;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;flatMapSequenceTo;(Map,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;flatMapTo;(Map,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;get;(Map,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;getOrElse;(Map,Object,Function0);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;getOrPut;(ConcurrentMap,Object,Function0);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;getOrPut;(Map,Object,Function0);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;getOrPut;(Map,Object,Function0);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;getValue;(Map,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;ifEmpty;(Map,Function0);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;iterator;(Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;map;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapKeys;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapKeysTo;(Map,Map,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;MapsKt;false;mapKeysTo;(Map,Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapKeysTo;(Map,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapNotNullTo;(Map,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapOf;(Pair);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapTo;(Map,Collection,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;MapsKt;false;mapTo;(Map,Collection,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapTo;(Map,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapValues;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapValuesTo;(Map,Map,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;MapsKt;false;mapValuesTo;(Map,Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapValuesTo;(Map,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;maxBy;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;maxByOrNull;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;maxByOrThrow;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;maxOfWith;(Map,Comparator,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;maxOfWithOrNull;(Map,Comparator,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;maxWith;(Map,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;maxWithOrNull;(Map,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;maxWithOrThrow;(Map,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minBy;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minByOrNull;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minByOrThrow;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minOfWith;(Map,Comparator,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minOfWithOrNull;(Map,Comparator,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minWith;(Map,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minWithOrNull;(Map,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minWithOrThrow;(Map,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minus;(Map,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minus;(Map,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minus;(Map,Object[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minus;(Map,Sequence);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mutableIterator;(Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;onEach;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;onEachIndexed;(Map,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;orEmpty;(Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plus;(Map,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plus;(Map,Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plus;(Map,Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plus;(Map,Pair);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plus;(Map,Pair);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plus;(Map,Pair[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plus;(Map,Pair[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plus;(Map,Sequence);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plusAssign;(Map,Iterable);;Argument[1].Element;Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;plusAssign;(Map,Map);;Argument[1].Element;Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;plusAssign;(Map,Pair);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;plusAssign;(Map,Sequence);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;putAll;(Map,Iterable);;Argument[1].Element;Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;putAll;(Map,Sequence);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;remove;(Map,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;set;(Map,Object,Object);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;set;(Map,Object,Object);;Argument[2];Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;toList;(Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toMap;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toMap;(Iterable,Map);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toMap;(Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toMap;(Map,Map);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toMap;(Pair[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toMap;(Pair[],Map);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toMap;(Sequence,Map);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toMutableMap;(Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toPair;(Entry);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toSortedMap;(Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;withDefault;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;withDefault;(Map,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;withDefaultMutable;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;withDefaultMutable;(Map,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;minus;(Set,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;minus;(Set,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;minus;(Set,Object[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;minus;(Set,Sequence);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;minusElement;(Set,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;orEmpty;(Set);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plus;(Set,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plus;(Set,Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plus;(Set,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plus;(Set,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plus;(Set,Object[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plus;(Set,Object[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plus;(Set,Sequence);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plus;(Set,Sequence);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plusElement;(Set,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plusElement;(Set,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;setOf;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;setOf;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;setOfNotNull;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;asByteArray;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;asUByteArray;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;associateWithTo;(UByteArray,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;associateWithTo;(UIntArray,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;associateWithTo;(ULongArray,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;associateWithTo;(UShortArray,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;contentToString;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;contentToString;(UIntArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;contentToString;(ULongArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;contentToString;(UShortArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;copyInto;(UByteArray,UByteArray,int,int,int);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;UArraysKt;false;copyInto;(UByteArray,UByteArray,int,int,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;copyInto;(UByteArray,UByteArray,int,int,int);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;copyInto;(UIntArray,UIntArray,int,int,int);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;copyInto;(ULongArray,ULongArray,int,int,int);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;copyInto;(UShortArray,UShortArray,int,int,int);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;copyOf;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;copyOf;(UByteArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;copyOfRange;(UByteArray,int,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;drop;(UByteArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;drop;(UIntArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;drop;(ULongArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;drop;(UShortArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;dropLast;(UByteArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;dropLast;(UIntArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;dropLast;(ULongArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;dropLast;(UShortArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;dropLastWhile;(UByteArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;dropLastWhile;(UIntArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;dropLastWhile;(ULongArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;dropLastWhile;(UShortArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterIndexedTo;(UByteArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterIndexedTo;(UIntArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterIndexedTo;(ULongArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterIndexedTo;(UShortArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterNotTo;(UByteArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterNotTo;(UIntArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterNotTo;(ULongArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterNotTo;(UShortArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterTo;(UByteArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterTo;(UIntArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterTo;(ULongArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterTo;(UShortArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;flatMapIndexedTo;(UByteArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;flatMapIndexedTo;(UIntArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;flatMapIndexedTo;(ULongArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;flatMapIndexedTo;(UShortArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;flatMapTo;(UByteArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;flatMapTo;(UIntArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;flatMapTo;(ULongArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;flatMapTo;(UShortArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;fold;(UByteArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;fold;(UIntArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;fold;(ULongArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;fold;(UShortArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldIndexed;(UByteArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldIndexed;(UIntArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldIndexed;(ULongArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldIndexed;(UShortArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldRight;(UByteArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldRight;(UIntArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldRight;(ULongArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldRight;(UShortArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldRightIndexed;(UByteArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldRightIndexed;(UIntArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldRightIndexed;(ULongArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldRightIndexed;(UShortArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;groupByTo;(UByteArray,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;groupByTo;(UByteArray,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;groupByTo;(UIntArray,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;groupByTo;(UIntArray,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;groupByTo;(ULongArray,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;groupByTo;(ULongArray,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;groupByTo;(UShortArray,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;groupByTo;(UShortArray,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;mapIndexedTo;(UByteArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;mapIndexedTo;(UIntArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;mapIndexedTo;(ULongArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;mapIndexedTo;(UShortArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;mapTo;(UByteArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;mapTo;(UIntArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;mapTo;(ULongArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;mapTo;(UShortArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;onEach;(UByteArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;onEach;(UIntArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;onEach;(ULongArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;onEach;(UShortArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;onEachIndexed;(UByteArray,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;onEachIndexed;(UIntArray,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;onEachIndexed;(ULongArray,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;onEachIndexed;(UShortArray,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;plus;(UByteArray,Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;plus;(UByteArray,UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;plus;(UByteArray,UByteArray);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;plus;(UByteArray,byte);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;reversed;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;reversed;(UIntArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;reversed;(ULongArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;reversed;(UShortArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;reversedArray;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;runningFold;(UByteArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;runningFold;(UIntArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;runningFold;(ULongArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;runningFold;(UShortArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;runningFoldIndexed;(UByteArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;runningFoldIndexed;(UIntArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;runningFoldIndexed;(ULongArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;runningFoldIndexed;(UShortArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;scan;(UByteArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;scan;(UIntArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;scan;(ULongArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;scan;(UShortArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;scanIndexed;(UByteArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;scanIndexed;(UIntArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;scanIndexed;(ULongArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;scanIndexed;(UShortArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sliceArray;(UByteArray,IntRange);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedArray;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedArray;(UIntArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedArray;(ULongArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedArray;(UShortArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedArrayDescending;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedArrayDescending;(UIntArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedArrayDescending;(ULongArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedArrayDescending;(UShortArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedDescending;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;take;(UByteArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;take;(UIntArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;take;(ULongArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;take;(UShortArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;takeLast;(UByteArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;takeLast;(UIntArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;takeLast;(ULongArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;takeLast;(UShortArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;takeLastWhile;(UByteArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;takeLastWhile;(UIntArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;takeLastWhile;(ULongArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;takeLastWhile;(UShortArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;toByteArray;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;toUByteArray;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Comparable,Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Comparable,Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Comparable,Comparable,Comparable);;Argument[2];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Comparable,Comparable[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Object,Object,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Object,Object,Comparator);;Argument[1];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Object,Object,Object,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Object,Object,Object,Comparator);;Argument[1];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Object,Object,Object,Comparator);;Argument[2];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Object,Object[],Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Comparable,Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Comparable,Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Comparable,Comparable,Comparable);;Argument[2];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Comparable,Comparable[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Object,Object,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Object,Object,Comparator);;Argument[1];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Object,Object,Object,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Object,Object,Object,Comparator);;Argument[1];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Object,Object,Object,Comparator);;Argument[2];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Object,Object[],Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;reversed;(Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.coroutines.intrinsics;IntrinsicsKt;false;intercepted;(Continuation);;Argument[0];ReturnValue;taint;generated", - "kotlin.coroutines.jvm.internal;CoroutineStackFrame;true;getCallerFrame;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.coroutines;AbstractCoroutineContextElement;true;AbstractCoroutineContextElement;(Key);;Argument[0];Argument[-1];taint;generated", - "kotlin.coroutines;AbstractCoroutineContextKey;true;AbstractCoroutineContextKey;(Key,Function1);;Argument[0];Argument[-1];taint;generated", - "kotlin.coroutines;AbstractCoroutineContextKey;true;AbstractCoroutineContextKey;(Key,Function1);;Argument[1];Argument[-1];taint;generated", - "kotlin.coroutines;CoroutineContext$Element;true;getKey;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.coroutines;CoroutineContext;true;fold;(Object,Function2);;Argument[-1];ReturnValue;taint;generated", - "kotlin.coroutines;CoroutineContext;true;fold;(Object,Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.coroutines;CoroutineContext;true;get;(Key);;Argument[-1];ReturnValue;taint;generated", - "kotlin.coroutines;CoroutineContext;true;minusKey;(Key);;Argument[-1];ReturnValue;taint;generated", - "kotlin.coroutines;CoroutineContext;true;minusKey;(Key);;Argument[-1];ReturnValue;value;generated", - "kotlin.coroutines;CoroutineContext;true;plus;(CoroutineContext);;Argument[-1];ReturnValue;taint;generated", - "kotlin.coroutines;CoroutineContext;true;plus;(CoroutineContext);;Argument[0];ReturnValue;taint;generated", - "kotlin.coroutines;CoroutineContextImplKt;false;getPolymorphicElement;(Element,Key);;Argument[0];ReturnValue;taint;generated", - "kotlin.coroutines;CoroutineContextImplKt;false;minusPolymorphicKey;(Element,Key);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;AccessDeniedException;false;AccessDeniedException;(File,File,String);;Argument[0];Argument[-1];taint;generated", - "kotlin.io;AccessDeniedException;false;AccessDeniedException;(File,File,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.io;AccessDeniedException;false;AccessDeniedException;(File,File,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.io;ByteStreamsKt;false;buffered;(InputStream,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;ByteStreamsKt;false;buffered;(OutputStream,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;ByteStreamsKt;false;bufferedReader;(InputStream,Charset);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;ByteStreamsKt;false;byteInputStream;(String,Charset);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;ByteStreamsKt;false;copyTo;(InputStream,OutputStream,int);;Argument[0];Argument[1];taint;generated", - "kotlin.io;ByteStreamsKt;false;inputStream;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;ByteStreamsKt;false;inputStream;(byte[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;ByteStreamsKt;false;readBytes;(InputStream);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;ByteStreamsKt;false;readBytes;(InputStream,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;ByteStreamsKt;false;reader;(InputStream,Charset);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;CloseableKt;false;use;(Closeable,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;FileAlreadyExistsException;false;FileAlreadyExistsException;(File,File,String);;Argument[0];Argument[-1];taint;generated", - "kotlin.io;FileAlreadyExistsException;false;FileAlreadyExistsException;(File,File,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.io;FileAlreadyExistsException;false;FileAlreadyExistsException;(File,File,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.io;FileSystemException;true;FileSystemException;(File,File,String);;Argument[0];Argument[-1];taint;generated", - "kotlin.io;FileSystemException;true;FileSystemException;(File,File,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.io;FileSystemException;true;FileSystemException;(File,File,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.io;FileSystemException;true;getFile;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.io;FileSystemException;true;getOther;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.io;FileSystemException;true;getReason;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.io;FileTreeWalk;false;maxDepth;(int);;Argument[-1];ReturnValue;taint;generated", - "kotlin.io;FileTreeWalk;false;onEnter;(Function1);;Argument[-1];ReturnValue;taint;generated", - "kotlin.io;FileTreeWalk;false;onEnter;(Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;FileTreeWalk;false;onFail;(Function2);;Argument[-1];ReturnValue;taint;generated", - "kotlin.io;FileTreeWalk;false;onFail;(Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;FileTreeWalk;false;onLeave;(Function1);;Argument[-1];ReturnValue;taint;generated", - "kotlin.io;FileTreeWalk;false;onLeave;(Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;copyTo;(File,File,boolean,int);;Argument[1];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;relativeToOrSelf;(File,File);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;resolve;(File,File);;Argument[1];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;resolve;(File,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;resolveSibling;(File,File);;Argument[1];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;resolveSibling;(File,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;walk;(File,FileWalkDirection);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;walkBottomUp;(File);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;walkTopDown;(File);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;NoSuchFileException;false;NoSuchFileException;(File,File,String);;Argument[0];Argument[-1];taint;generated", - "kotlin.io;NoSuchFileException;false;NoSuchFileException;(File,File,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.io;NoSuchFileException;false;NoSuchFileException;(File,File,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.io;TextStreamsKt;false;buffered;(Reader,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;TextStreamsKt;false;buffered;(Writer,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;TextStreamsKt;false;copyTo;(Reader,Writer,int);;Argument[0];Argument[1];taint;generated", - "kotlin.io;TextStreamsKt;false;forEachLine;(Reader,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;TextStreamsKt;false;lineSequence;(BufferedReader);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;TextStreamsKt;false;readText;(Reader);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;TextStreamsKt;false;reader;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;TextStreamsKt;false;useLines;(Reader,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;AdaptedFunctionReference;true;AdaptedFunctionReference;(int,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;AdaptedFunctionReference;true;AdaptedFunctionReference;(int,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;AdaptedFunctionReference;true;AdaptedFunctionReference;(int,Object,Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;AdaptedFunctionReference;true;AdaptedFunctionReference;(int,Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;AdaptedFunctionReference;true;AdaptedFunctionReference;(int,Object,Class,String,String,int);;Argument[4];Argument[-1];taint;generated", - "kotlin.jvm.internal;ArrayIteratorKt;false;iterator;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.jvm.internal;ArrayIteratorsKt;false;iterator;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ArrayIteratorsKt;false;iterator;(char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ByteSpreadBuilder;false;toArray;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;CallableReference;true;compute;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;CallableReference;true;getBoundReceiver;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;CallableReference;true;getSignature;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;CharSpreadBuilder;false;toArray;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;ClassReference$Companion;false;getClassQualifiedName;(Class);;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;ClassReference$Companion;false;getClassSimpleName;(Class);;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;CollectionToArray;false;toArray;(Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.jvm.internal;CollectionToArray;false;toArray;(Collection,Object[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.jvm.internal;FunctionReference;true;FunctionReference;(int,Object);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReference;true;FunctionReference;(int,Object,Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReference;true;FunctionReference;(int,Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReference;true;FunctionReference;(int,Object,Class,String,String,int);;Argument[4];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReference;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;FunctionReferenceImpl;true;FunctionReferenceImpl;(int,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReferenceImpl;true;FunctionReferenceImpl;(int,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReferenceImpl;true;FunctionReferenceImpl;(int,KDeclarationContainer,String,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReferenceImpl;true;FunctionReferenceImpl;(int,KDeclarationContainer,String,String);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReferenceImpl;true;FunctionReferenceImpl;(int,Object,Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReferenceImpl;true;FunctionReferenceImpl;(int,Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReferenceImpl;true;FunctionReferenceImpl;(int,Object,Class,String,String,int);;Argument[4];Argument[-1];taint;generated", - "kotlin.jvm.internal;Intrinsics;true;stringPlus;(String,Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Intrinsics;true;stringPlus;(String,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0;true;MutablePropertyReference0;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0;true;MutablePropertyReference0;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0;true;MutablePropertyReference0;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0;true;MutablePropertyReference0;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0Impl;true;MutablePropertyReference0Impl;(Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0Impl;true;MutablePropertyReference0Impl;(Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0Impl;true;MutablePropertyReference0Impl;(KDeclarationContainer,String,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0Impl;true;MutablePropertyReference0Impl;(KDeclarationContainer,String,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0Impl;true;MutablePropertyReference0Impl;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0Impl;true;MutablePropertyReference0Impl;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0Impl;true;MutablePropertyReference0Impl;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1;true;MutablePropertyReference1;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1;true;MutablePropertyReference1;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1;true;MutablePropertyReference1;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1;true;MutablePropertyReference1;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1Impl;true;MutablePropertyReference1Impl;(Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1Impl;true;MutablePropertyReference1Impl;(Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1Impl;true;MutablePropertyReference1Impl;(KDeclarationContainer,String,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1Impl;true;MutablePropertyReference1Impl;(KDeclarationContainer,String,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1Impl;true;MutablePropertyReference1Impl;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1Impl;true;MutablePropertyReference1Impl;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1Impl;true;MutablePropertyReference1Impl;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference2;true;MutablePropertyReference2;(Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference2;true;MutablePropertyReference2;(Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference2Impl;true;MutablePropertyReference2Impl;(Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference2Impl;true;MutablePropertyReference2Impl;(Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference2Impl;true;MutablePropertyReference2Impl;(KDeclarationContainer,String,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference2Impl;true;MutablePropertyReference2Impl;(KDeclarationContainer,String,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference;true;MutablePropertyReference;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference;true;MutablePropertyReference;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference;true;MutablePropertyReference;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference;true;MutablePropertyReference;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;PackageReference;false;PackageReference;(Class,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;PrimitiveSpreadBuilder;true;addSpread;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0;true;PropertyReference0;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0;true;PropertyReference0;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0;true;PropertyReference0;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0;true;PropertyReference0;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0Impl;true;PropertyReference0Impl;(Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0Impl;true;PropertyReference0Impl;(Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0Impl;true;PropertyReference0Impl;(KDeclarationContainer,String,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0Impl;true;PropertyReference0Impl;(KDeclarationContainer,String,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0Impl;true;PropertyReference0Impl;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0Impl;true;PropertyReference0Impl;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0Impl;true;PropertyReference0Impl;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1;true;PropertyReference1;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1;true;PropertyReference1;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1;true;PropertyReference1;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1;true;PropertyReference1;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1Impl;true;PropertyReference1Impl;(Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1Impl;true;PropertyReference1Impl;(Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1Impl;true;PropertyReference1Impl;(KDeclarationContainer,String,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1Impl;true;PropertyReference1Impl;(KDeclarationContainer,String,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1Impl;true;PropertyReference1Impl;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1Impl;true;PropertyReference1Impl;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1Impl;true;PropertyReference1Impl;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference2;true;PropertyReference2;(Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference2;true;PropertyReference2;(Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference2Impl;true;PropertyReference2Impl;(Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference2Impl;true;PropertyReference2Impl;(Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference2Impl;true;PropertyReference2Impl;(KDeclarationContainer,String,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference2Impl;true;PropertyReference2Impl;(KDeclarationContainer,String,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference;true;PropertyReference;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference;true;PropertyReference;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference;true;PropertyReference;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference;true;PropertyReference;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;function;(FunctionReference);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;getOrCreateKotlinPackage;(Class,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;mutableCollectionType;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;mutableProperty0;(MutablePropertyReference0);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;mutableProperty1;(MutablePropertyReference1);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;mutableProperty2;(MutablePropertyReference2);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;nothingType;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;nullableTypeOf;(Class,KTypeProjection);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;nullableTypeOf;(Class,KTypeProjection,KTypeProjection);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;nullableTypeOf;(Class,KTypeProjection,KTypeProjection);;Argument[2];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;nullableTypeOf;(KClassifier);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;platformType;(KType,KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;platformType;(KType,KType);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;property0;(PropertyReference0);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;property1;(PropertyReference1);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;property2;(PropertyReference2);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;setUpperBounds;(KTypeParameter,KType);;Argument[1];Argument[0];taint;generated", - "kotlin.jvm.internal;Reflection;true;typeOf;(Class,KTypeProjection);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;typeOf;(Class,KTypeProjection,KTypeProjection);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;typeOf;(Class,KTypeProjection,KTypeProjection);;Argument[2];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;typeOf;(KClassifier);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;typeParameter;(Object,String,KVariance,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;typeParameter;(Object,String,KVariance,boolean);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;function;(FunctionReference);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;getOrCreateKotlinPackage;(Class,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;mutableCollectionType;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;mutableProperty0;(MutablePropertyReference0);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;mutableProperty1;(MutablePropertyReference1);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;mutableProperty2;(MutablePropertyReference2);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;nothingType;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;platformType;(KType,KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;platformType;(KType,KType);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;property0;(PropertyReference0);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;property1;(PropertyReference1);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;property2;(PropertyReference2);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;setUpperBounds;(KTypeParameter,List);;Argument[1].Element;Argument[0];taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;typeOf;(KClassifier,List,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;typeOf;(KClassifier,List,boolean);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;typeParameter;(Object,String,KVariance,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;typeParameter;(Object,String,KVariance,boolean);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;SpreadBuilder;true;add;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;SpreadBuilder;true;addSpread;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;SpreadBuilder;true;toArray;(Object[]);;Argument[-1];Argument[0].ArrayElement;taint;generated", - "kotlin.jvm.internal;SpreadBuilder;true;toArray;(Object[]);;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableCollection;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableCollection;(Object,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableIterable;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableIterable;(Object,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableIterator;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableIterator;(Object,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableList;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableList;(Object,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableListIterator;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableListIterator;(Object,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableMap;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableMap;(Object,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableMapEntry;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableMapEntry;(Object,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableSet;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableSet;(Object,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;beforeCheckcastToFunctionOfArity;(Object,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;beforeCheckcastToFunctionOfArity;(Object,int,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;castToCollection;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;castToIterable;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;castToIterator;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;castToList;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;castToListIterator;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;castToMap;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;castToMapEntry;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;castToSet;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeParameterReference;false;TypeParameterReference;(Object,String,KVariance,boolean);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;TypeParameterReference;false;TypeParameterReference;(Object,String,KVariance,boolean);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;TypeParameterReference;false;setUpperBounds;(List);;Argument[0].Element;Argument[-1];taint;generated", - "kotlin.jvm.internal;TypeReference;false;TypeReference;(KClassifier,List,KType,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;TypeReference;false;TypeReference;(KClassifier,List,KType,int);;Argument[1].Element;Argument[-1];taint;generated", - "kotlin.jvm.internal;TypeReference;false;TypeReference;(KClassifier,List,KType,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;TypeReference;false;TypeReference;(KClassifier,List,boolean);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;TypeReference;false;TypeReference;(KClassifier,List,boolean);;Argument[1].Element;Argument[-1];taint;generated", - "kotlin.jvm.internal;TypeReference;false;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.properties;ObservableProperty;true;ObservableProperty;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.random;PlatformRandomKt;false;asJavaRandom;(Random);;Argument[0];ReturnValue;taint;generated", - "kotlin.random;PlatformRandomKt;false;asKotlinRandom;(Random);;Argument[0];ReturnValue;taint;generated", - "kotlin.random;Random;true;nextBytes;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.random;Random;true;nextBytes;(byte[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.random;URandomKt;false;nextUBytes;(Random,UByteArray);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.random;URandomKt;false;nextUBytes;(Random,UByteArray,int,int);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.ranges;CharRange$Companion;false;getEMPTY;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.ranges;IntRange$Companion;false;getEMPTY;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.ranges;LongRange$Companion;false;getEMPTY;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceAtLeast;(Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceAtLeast;(Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceAtMost;(Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceAtMost;(Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceIn;(Comparable,ClosedFloatingPointRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceIn;(Comparable,ClosedRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceIn;(Comparable,Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceIn;(Comparable,Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceIn;(Comparable,Comparable,Comparable);;Argument[2];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;rangeTo;(Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;rangeTo;(Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;rangeUntil;(Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;rangeUntil;(Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.ranges;UIntRange$Companion;false;getEMPTY;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.ranges;ULongRange$Companion;false;getEMPTY;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.reflect;KClasses;false;cast;(KClass,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.reflect;KClasses;false;safeCast;(KClass,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.reflect;KType;true;getArguments;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.reflect;KType;true;getClassifier;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.reflect;KTypeParameter;true;getName;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.reflect;KTypeParameter;true;getUpperBounds;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection$Companion;false;contravariant;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection$Companion;false;covariant;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection$Companion;false;invariant;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection;false;KTypeProjection;(KVariance,KType);;Argument[1];Argument[-1];taint;generated", - "kotlin.reflect;KTypeProjection;false;component2;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection;false;contravariant;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection;false;copy;(KVariance,KType);;Argument[1];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection;false;covariant;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection;false;getType;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection;false;invariant;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection;false;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.reflect;TypesJVMKt;false;getJavaType;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.reflect;WildcardTypeImpl$Companion;false;getSTAR;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.sequences;SequenceScope;true;yieldAll;(Sequence);;Argument[0];Argument[-1];taint;generated", - "kotlin.sequences;SequencesKt;false;asSequence;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;associateBy;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;associateByTo;(Sequence,Map,Function1);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;associateByTo;(Sequence,Map,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;associateByTo;(Sequence,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;associateByTo;(Sequence,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;associateTo;(Sequence,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;associateWith;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;associateWithTo;(Sequence,Map,Function1);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;associateWithTo;(Sequence,Map,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;associateWithTo;(Sequence,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;chunked;(Sequence,int,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;constrainOnce;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;distinct;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;distinctBy;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;distinctBy;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;drop;(Sequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;dropWhile;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;dropWhile;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;elementAt;(Sequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;elementAtOrElse;(Sequence,int,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;elementAtOrNull;(Sequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filter;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filter;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIndexedTo;(Sequence,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIsInstance;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIsInstance;(Sequence,Class);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIsInstanceTo;(Sequence,Collection);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIsInstanceTo;(Sequence,Collection);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIsInstanceTo;(Sequence,Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIsInstanceTo;(Sequence,Collection,Class);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIsInstanceTo;(Sequence,Collection,Class);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIsInstanceTo;(Sequence,Collection,Class);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNot;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNot;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNotNull;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNotNullTo;(Sequence,Collection);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNotNullTo;(Sequence,Collection);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNotNullTo;(Sequence,Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNotTo;(Sequence,Collection,Function1);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNotTo;(Sequence,Collection,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNotTo;(Sequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterTo;(Sequence,Collection,Function1);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;filterTo;(Sequence,Collection,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterTo;(Sequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;find;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;findLast;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;first;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;first;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;firstNotNullOf;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;firstNotNullOfOrNull;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;firstOrNull;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;firstOrNull;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatMap;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatMap;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatMapIndexedIterableTo;(Sequence,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatMapIndexedSequenceTo;(Sequence,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatMapIterable;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatMapIterable;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatMapIterableTo;(Sequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatMapTo;(Sequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatten;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flattenSequenceOfIterable;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;fold;(Sequence,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;foldIndexed;(Sequence,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;generateSequence;(Function0);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;generateSequence;(Function0,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;generateSequence;(Function0,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;generateSequence;(Object,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;groupByTo;(Sequence,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;groupByTo;(Sequence,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[0];Argument[1];taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinToString;(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinToString;(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinToString;(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinToString;(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinToString;(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;last;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;last;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;lastOrNull;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;lastOrNull;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;map;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;map;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapIndexed;(Sequence,Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapIndexed;(Sequence,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapIndexedNotNull;(Sequence,Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapIndexedNotNull;(Sequence,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapIndexedNotNullTo;(Sequence,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapIndexedTo;(Sequence,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapNotNull;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapNotNull;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapNotNullTo;(Sequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapTo;(Sequence,Collection,Function1);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;mapTo;(Sequence,Collection,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapTo;(Sequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;max;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxBy;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxByOrNull;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxByOrThrow;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxOfWith;(Sequence,Comparator,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxOfWithOrNull;(Sequence,Comparator,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxOrNull;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxOrThrow;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxWith;(Sequence,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxWithOrNull;(Sequence,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxWithOrThrow;(Sequence,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;min;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minBy;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minByOrNull;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minByOrThrow;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minOfWith;(Sequence,Comparator,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minOfWithOrNull;(Sequence,Comparator,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minOrNull;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minOrThrow;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minWith;(Sequence,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minWithOrNull;(Sequence,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minWithOrThrow;(Sequence,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minus;(Sequence,Object[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;onEach;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;onEachIndexed;(Sequence,Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;orEmpty;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;partition;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;reduce;(Sequence,Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;reduceIndexed;(Sequence,Function3);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;reduceIndexedOrNull;(Sequence,Function3);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;reduceOrNull;(Sequence,Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;requireNoNulls;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;single;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;single;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;singleOrNull;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;singleOrNull;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;take;(Sequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;takeWhile;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;takeWhile;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toCollection;(Sequence,Collection);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;toCollection;(Sequence,Collection);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toCollection;(Sequence,Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toHashSet;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toList;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toMutableList;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toMutableSet;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toSet;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toSortedSet;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toSortedSet;(Sequence,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;unzip;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;windowed;(Sequence,int,int,boolean,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;withIndex;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;zip;(Sequence,Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;zip;(Sequence,Sequence);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;zip;(Sequence,Sequence,Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;zip;(Sequence,Sequence,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;zip;(Sequence,Sequence,Function2);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;CharsKt;false;plus;(char,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;MatchGroup;false;MatchGroup;(String,IntRange);;Argument[0];Argument[-1];taint;generated", - "kotlin.text;MatchGroup;false;MatchGroup;(String,IntRange);;Argument[1].Element;Argument[-1];taint;generated", - "kotlin.text;MatchGroup;false;component1;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchGroup;false;component2;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchGroup;false;copy;(String,IntRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;MatchGroup;false;copy;(String,IntRange);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;MatchGroup;false;getRange;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchGroup;false;getValue;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchGroup;false;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component10;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component1;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component2;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component3;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component4;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component5;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component6;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component7;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component8;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component9;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;getMatch;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;toList;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult;true;getDestructured;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult;true;getGroupValues;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult;true;getGroups;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult;true;next;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;Regex$Companion;false;escape;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;Regex;false;find;(CharSequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;Regex;false;getOptions;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;Regex;false;matchEntire;(CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;Regex;false;replace;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;Regex;false;replace;(CharSequence,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;Regex;false;replace;(CharSequence,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;Regex;false;replaceFirst;(CharSequence,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;Regex;false;replaceFirst;(CharSequence,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;Regex;false;toPattern;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;String;(StringBuffer);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;String;(StringBuilder);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;String;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;String;(byte[],Charset);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;String;(byte[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;String;(byte[],int,int,Charset);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;String;(char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;String;(char[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;append;(Appendable,CharSequence[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;append;(StringBuilder,Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;append;(StringBuilder,Object);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;append;(StringBuilder,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;append;(StringBuilder,Object[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;append;(StringBuilder,String[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(Appendable);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(Appendable,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(Appendable,CharSequence);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendLine;(Appendable,CharSequence);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(Appendable,char);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,CharSequence);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,CharSequence);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,Object);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,String);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,StringBuffer);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,StringBuffer);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,StringBuffer);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,StringBuilder);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,StringBuilder);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,StringBuilder);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,byte);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,char);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,char[]);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,char[]);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,double);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,float);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,long);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,short);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendRange;(Appendable,CharSequence,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendRange;(Appendable,CharSequence,int,int);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendRange;(Appendable,CharSequence,int,int);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendRange;(StringBuilder,CharSequence,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendRange;(StringBuilder,CharSequence,int,int);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendRange;(StringBuilder,CharSequence,int,int);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendRange;(StringBuilder,char[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendRange;(StringBuilder,char[],int,int);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendRange;(StringBuilder,char[],int,int);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(Appendable);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(Appendable,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(Appendable,CharSequence);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendln;(Appendable,CharSequence);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(Appendable,char);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,CharSequence);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,CharSequence);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,Object);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,String);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,StringBuffer);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,StringBuffer);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,StringBuffer);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,StringBuilder);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,StringBuilder);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,StringBuilder);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,byte);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,char);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,char[]);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,char[]);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,double);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,float);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,long);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,short);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;associateByTo;(CharSequence,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;associateByTo;(CharSequence,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;associateTo;(CharSequence,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;associateWithTo;(CharSequence,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;capitalize;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;capitalize;(String,Locale);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;clear;(StringBuilder);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;concatToString;(char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;concatToString;(char[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;decapitalize;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;decapitalize;(String,Locale);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;decodeToString;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;decodeToString;(byte[],int,int,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;drop;(CharSequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;drop;(String,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;dropLast;(CharSequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;dropLast;(String,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;dropLastWhile;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;dropLastWhile;(String,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;dropWhile;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;dropWhile;(String,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;encodeToByteArray;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;encodeToByteArray;(String,int,int,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;filterIndexedTo;(CharSequence,Appendable,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;filterNotTo;(CharSequence,Appendable,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;filterTo;(CharSequence,Appendable,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;findAnyOf;(CharSequence,Collection,int,boolean);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;findLastAnyOf;(CharSequence,Collection,int,boolean);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;flatMapIndexedIterableTo;(CharSequence,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;flatMapTo;(CharSequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;fold;(CharSequence,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;foldIndexed;(CharSequence,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;foldRight;(CharSequence,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;foldRightIndexed;(CharSequence,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;format;(String,Locale,Object[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;format;(String,Locale,Object[]);;Argument[2].ArrayElement;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;format;(String,Object[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;format;(String,Object[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;format;(StringCompanionObject,Locale,String,Object[]);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;format;(StringCompanionObject,Locale,String,Object[]);;Argument[3].ArrayElement;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;format;(StringCompanionObject,String,Object[]);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;format;(StringCompanionObject,String,Object[]);;Argument[2].ArrayElement;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;formatNullable;(String,Locale,Object[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;formatNullable;(String,Locale,Object[]);;Argument[2].ArrayElement;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;formatNullable;(StringCompanionObject,Locale,String,Object[]);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;formatNullable;(StringCompanionObject,Locale,String,Object[]);;Argument[3].ArrayElement;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;groupByTo;(CharSequence,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;groupByTo;(CharSequence,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;ifBlank;(CharSequence,Function0);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;ifEmpty;(CharSequence,Function0);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;insertRange;(StringBuilder,int,CharSequence,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;insertRange;(StringBuilder,int,CharSequence,int,int);;Argument[2];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;insertRange;(StringBuilder,int,CharSequence,int,int);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;insertRange;(StringBuilder,int,char[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;insertRange;(StringBuilder,int,char[],int,int);;Argument[2];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;insertRange;(StringBuilder,int,char[],int,int);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;intern;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;lineSequence;(CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;lines;(CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;lowercase;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;lowercase;(String,Locale);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;mapIndexedNotNullTo;(CharSequence,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;mapIndexedTo;(CharSequence,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;mapNotNullTo;(CharSequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;mapTo;(CharSequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;onEach;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;onEachIndexed;(CharSequence,Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;orEmpty;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;padEnd;(CharSequence,int,char);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;padStart;(CharSequence,int,char);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;prependIndent;(String,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removePrefix;(CharSequence,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removePrefix;(String,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removeRange;(CharSequence,IntRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removeRange;(CharSequence,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removeSuffix;(CharSequence,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removeSuffix;(String,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removeSurrounding;(CharSequence,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removeSurrounding;(CharSequence,CharSequence,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removeSurrounding;(String,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removeSurrounding;(String,CharSequence,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;repeat;(CharSequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replace;(CharSequence,Regex,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replace;(CharSequence,Regex,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replace;(CharSequence,Regex,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replace;(String,char,char,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceAfter;(String,String,String,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceAfter;(String,char,String,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceAfterLast;(String,String,String,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceAfterLast;(String,char,String,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceBefore;(String,String,String,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceBefore;(String,char,String,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceBeforeLast;(String,String,String,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceBeforeLast;(String,char,String,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceFirst;(CharSequence,Regex,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceFirst;(CharSequence,Regex,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceFirst;(String,String,String,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceFirst;(String,char,char,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceFirstCharWithChar;(String,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceFirstCharWithCharSequence;(String,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceRange;(CharSequence,IntRange,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceRange;(CharSequence,IntRange,CharSequence);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceRange;(CharSequence,int,int,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceRange;(CharSequence,int,int,CharSequence);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;reversed;(CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;runningFold;(CharSequence,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;runningFoldIndexed;(CharSequence,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;scan;(CharSequence,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;scanIndexed;(CharSequence,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;setRange;(StringBuilder,int,int,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;setRange;(StringBuilder,int,int,String);;Argument[3];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;setRange;(StringBuilder,int,int,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;slice;(CharSequence,IntRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;slice;(String,IntRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;split;(CharSequence,Pattern,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;splitToSequence;(CharSequence,String[],boolean,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;splitToSequence;(CharSequence,char[],boolean,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;subSequence;(CharSequence,IntRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;subSequence;(String,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substring;(String,IntRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substring;(String,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substring;(String,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringAfter;(String,String,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringAfter;(String,String,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringAfter;(String,char,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringAfter;(String,char,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringAfterLast;(String,String,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringAfterLast;(String,String,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringAfterLast;(String,char,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringAfterLast;(String,char,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringBefore;(String,String,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringBefore;(String,String,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringBefore;(String,char,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringBefore;(String,char,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringBeforeLast;(String,String,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringBeforeLast;(String,String,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringBeforeLast;(String,char,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringBeforeLast;(String,char,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;take;(CharSequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;take;(String,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;takeLast;(CharSequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;takeLast;(String,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;takeLastWhile;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;takeLastWhile;(String,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;takeWhile;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;takeWhile;(String,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toByteArray;(String,Charset);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toCharArray;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toCharArray;(String,char[],int,int,int);;Argument[0];Argument[1];taint;generated", - "kotlin.text;StringsKt;false;toCharArray;(String,char[],int,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toCharArray;(String,char[],int,int,int);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toCharArray;(String,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toCharArray;(StringBuilder,char[],int,int,int);;Argument[0];Argument[1];taint;generated", - "kotlin.text;StringsKt;false;toCollection;(CharSequence,Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toLowerCase;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toLowerCase;(String,Locale);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toRegex;(Pattern);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toUpperCase;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toUpperCase;(String,Locale);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trim;(CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trim;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trim;(CharSequence,char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trimEnd;(CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trimEnd;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trimEnd;(CharSequence,char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trimStart;(CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trimStart;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trimStart;(CharSequence,char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;uppercase;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;uppercase;(String,Locale);;Argument[0];ReturnValue;taint;generated", - "kotlin.time;Duration$Companion;false;getINFINITE;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;Duration$Companion;false;getZERO;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;Duration;false;div;(double);;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;Duration;false;div;(int);;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;Duration;false;getAbsoluteValue;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;Duration;false;minus;(Duration);;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;Duration;false;plus;(Duration);;Argument[-1];ReturnValue;value;generated", - "kotlin.time;Duration;false;times;(double);;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;Duration;false;times;(int);;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;DurationKt;false;times;(double,Duration);;Argument[1];ReturnValue;taint;generated", - "kotlin.time;DurationKt;false;times;(int,Duration);;Argument[1];ReturnValue;taint;generated", - "kotlin.time;TimeMark;true;minus;(Duration);;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;TimeMark;true;plus;(Duration);;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;TimeMark;true;plus;(Duration);;Argument[0];ReturnValue;taint;generated", - "kotlin.time;TimeSource;true;markNow;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;TimedValue;false;TimedValue;(Object,Duration);;Argument[0];Argument[-1];taint;generated", - "kotlin.time;TimedValue;false;TimedValue;(Object,Duration);;Argument[1];Argument[-1];taint;generated", - "kotlin.time;TimedValue;false;component1;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;TimedValue;false;component2;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;TimedValue;false;copy;(Object,Duration);;Argument[0];ReturnValue;taint;generated", - "kotlin.time;TimedValue;false;copy;(Object,Duration);;Argument[1];ReturnValue;taint;generated", - "kotlin.time;TimedValue;false;getDuration;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;TimedValue;false;getValue;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;TimedValue;false;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;DeepRecursiveFunction;false;DeepRecursiveFunction;(SuspendFunction2);;Argument[0];Argument[-1];taint;generated", - "kotlin;KotlinVersion$Companion;false;getCURRENT;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;LazyKt;false;getValue;(Lazy,Object,KProperty);;Argument[0];ReturnValue;taint;generated", - "kotlin;LazyKt;false;lazy;(Function0);;Argument[0];ReturnValue;taint;generated", - "kotlin;LazyKt;false;lazy;(LazyThreadSafetyMode,Function0);;Argument[1];ReturnValue;taint;generated", - "kotlin;LazyKt;false;lazy;(Object,Function0);;Argument[0];ReturnValue;taint;generated", - "kotlin;LazyKt;false;lazy;(Object,Function0);;Argument[1];ReturnValue;taint;generated", - "kotlin;LazyKt;false;lazyOf;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin;Pair;false;Pair;(Object,Object);;Argument[0];Argument[-1];taint;generated", - "kotlin;Pair;false;Pair;(Object,Object);;Argument[1];Argument[-1];taint;generated", - "kotlin;Pair;false;component1;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Pair;false;component2;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Pair;false;copy;(Object,Object);;Argument[0];ReturnValue;taint;generated", - "kotlin;Pair;false;copy;(Object,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin;Pair;false;getFirst;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Pair;false;getSecond;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Pair;false;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;PreconditionsKt;false;checkNotNull;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin;PreconditionsKt;false;checkNotNull;(Object,Function0);;Argument[0];ReturnValue;taint;generated", - "kotlin;PreconditionsKt;false;requireNotNull;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin;PreconditionsKt;false;requireNotNull;(Object,Function0);;Argument[0];ReturnValue;taint;generated", - "kotlin;Result$Companion;false;failure;(Throwable);;Argument[0];ReturnValue;taint;generated", - "kotlin;Result$Companion;false;success;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin;Result;false;exceptionOrNull;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Result;false;getOrNull;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Result;false;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;ResultKt;false;fold;(Result,Function1,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;getOrDefault;(Result,Object);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;getOrDefault;(Result,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin;ResultKt;false;getOrElse;(Result,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;getOrThrow;(Result);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;map;(Result,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;mapCatching;(Result,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;onFailure;(Result,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;onSuccess;(Result,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;recover;(Result,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;recoverCatching;(Result,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;StandardKt;false;also;(Object,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;StandardKt;false;apply;(Object,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;StandardKt;false;let;(Object,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;StandardKt;false;run;(Object,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;StandardKt;false;takeIf;(Object,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;StandardKt;false;takeUnless;(Object,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;StandardKt;false;with;(Object,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;SuspendKt;false;suspend;(SuspendFunction0);;Argument[0];ReturnValue;taint;generated", - "kotlin;Triple;false;Triple;(Object,Object,Object);;Argument[0];Argument[-1];taint;generated", - "kotlin;Triple;false;Triple;(Object,Object,Object);;Argument[1];Argument[-1];taint;generated", - "kotlin;Triple;false;Triple;(Object,Object,Object);;Argument[2];Argument[-1];taint;generated", - "kotlin;Triple;false;component1;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Triple;false;component2;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Triple;false;component3;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Triple;false;copy;(Object,Object,Object);;Argument[0];ReturnValue;taint;generated", - "kotlin;Triple;false;copy;(Object,Object,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin;Triple;false;copy;(Object,Object,Object);;Argument[2];ReturnValue;taint;generated", - "kotlin;Triple;false;getFirst;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Triple;false;getSecond;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Triple;false;getThird;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Triple;false;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;TuplesKt;false;to;(Object,Object);;Argument[0];ReturnValue;taint;generated", - "kotlin;TuplesKt;false;to;(Object,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin;TuplesKt;false;toList;(Pair);;Argument[0];ReturnValue;taint;generated", - "kotlin;TuplesKt;false;toList;(Triple);;Argument[0];ReturnValue;taint;generated", - "kotlin;UByte;false;toUByte;();;Argument[-1];ReturnValue;value;generated", - "kotlin;UByteArrayKt;false;ubyteArrayOf;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin;UInt;false;toUInt;();;Argument[-1];ReturnValue;value;generated", - "kotlin;UIntArrayKt;false;uintArrayOf;(UIntArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin;ULong;false;toULong;();;Argument[-1];ReturnValue;value;generated", - "kotlin;ULongArrayKt;false;ulongArrayOf;(ULongArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin;UShort;false;toUShort;();;Argument[-1];ReturnValue;value;generated", - "kotlin;UShortArrayKt;false;ushortArrayOf;(UShortArray);;Argument[0].Element;ReturnValue;taint;generated" - ] - } -} From b80829a3a08ed486984dc82eb3b643652347a987 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 30 Nov 2022 16:18:05 +0100 Subject: [PATCH 782/796] Java/Kotlin: Cleanup files needed for inline models. --- java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 1 - java/ql/lib/semmle/code/java/frameworks/generated.qll | 9 --------- .../java/frameworks/kotlin/NegativeStdLibGenerated.qll | 7 ------- .../code/java/frameworks/kotlin/StdLibGenerated.qll | 7 ------- .../dataflow/external-models/negativesummaries.expected | 0 .../dataflow/external-models/negativesummaries.ql | 7 ------- 6 files changed, 31 deletions(-) delete mode 100644 java/ql/lib/semmle/code/java/frameworks/generated.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/kotlin/NegativeStdLibGenerated.qll delete mode 100644 java/ql/lib/semmle/code/java/frameworks/kotlin/StdLibGenerated.qll delete mode 100644 java/ql/test/library-tests/dataflow/external-models/negativesummaries.expected delete mode 100644 java/ql/test/library-tests/dataflow/external-models/negativesummaries.ql diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index b7bb10fd6f8..bc4d3d19de3 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -98,7 +98,6 @@ private module Frameworks { private import semmle.code.java.frameworks.apache.Collections private import semmle.code.java.frameworks.apache.Lang private import semmle.code.java.frameworks.Flexjson - private import semmle.code.java.frameworks.generated private import semmle.code.java.frameworks.guava.Guava private import semmle.code.java.frameworks.jackson.JacksonSerializability private import semmle.code.java.frameworks.javaee.jsf.JSFRenderer diff --git a/java/ql/lib/semmle/code/java/frameworks/generated.qll b/java/ql/lib/semmle/code/java/frameworks/generated.qll deleted file mode 100644 index cc088532c6d..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/generated.qll +++ /dev/null @@ -1,9 +0,0 @@ -/** - * A module importing all generated Models as Data models. - */ - -import java - -private module GeneratedFrameworks { - private import kotlin.StdLibGenerated -} diff --git a/java/ql/lib/semmle/code/java/frameworks/kotlin/NegativeStdLibGenerated.qll b/java/ql/lib/semmle/code/java/frameworks/kotlin/NegativeStdLibGenerated.qll deleted file mode 100644 index 9301e4f0c6f..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/kotlin/NegativeStdLibGenerated.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** - * THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. - * Definitions of negative summaries in the Kotlin StdLib @30ce58cea74 framework. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow diff --git a/java/ql/lib/semmle/code/java/frameworks/kotlin/StdLibGenerated.qll b/java/ql/lib/semmle/code/java/frameworks/kotlin/StdLibGenerated.qll deleted file mode 100644 index e4a66f67762..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/kotlin/StdLibGenerated.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** - * THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. - * Definitions of taint steps in the Kotlin StdLib @30ce58cea74 framework. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow diff --git a/java/ql/test/library-tests/dataflow/external-models/negativesummaries.expected b/java/ql/test/library-tests/dataflow/external-models/negativesummaries.expected deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/java/ql/test/library-tests/dataflow/external-models/negativesummaries.ql b/java/ql/test/library-tests/dataflow/external-models/negativesummaries.ql deleted file mode 100644 index 32e2c4bc5cc..00000000000 --- a/java/ql/test/library-tests/dataflow/external-models/negativesummaries.ql +++ /dev/null @@ -1,7 +0,0 @@ -/** - * CSV Validation of negative summaries. - */ - -import java -import semmle.code.java.dataflow.ExternalFlow -import ModelValidation From 309807796c499edaa954dd5e248164cac48a748b Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 1 Dec 2022 11:01:52 +0100 Subject: [PATCH 783/796] Java: Deprecate ModelCsv classes. --- java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index bc4d3d19de3..d8377cbb9fd 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -134,7 +134,7 @@ private module Frameworks { * * Extend this class to add additional source definitions. */ -class SourceModelCsv = SourceModelCsvInternal; +deprecated class SourceModelCsv = SourceModelCsvInternal; private class SourceModelCsvInternal extends Unit { /** Holds if `row` specifies a source definition. */ @@ -148,7 +148,7 @@ private class SourceModelCsvInternal extends Unit { * * Extend this class to add additional sink definitions. */ -class SinkModelCsv = SinkModelCsvInternal; +deprecated class SinkModelCsv = SinkModelCsvInternal; private class SinkModelCsvInternal extends Unit { /** Holds if `row` specifies a sink definition. */ @@ -162,7 +162,7 @@ private class SinkModelCsvInternal extends Unit { * * Extend this class to add additional flow summary definitions. */ -class SummaryModelCsv = SummaryModelCsvInternal; +deprecated class SummaryModelCsv = SummaryModelCsvInternal; private class SummaryModelCsvInternal extends Unit { /** Holds if `row` specifies a summary definition. */ @@ -176,7 +176,7 @@ private class SummaryModelCsvInternal extends Unit { * * Extend this class to add additional negative summary definitions. */ -class NegativeSummaryModelCsv = NegativeSummaryModelCsvInternal; +deprecated class NegativeSummaryModelCsv = NegativeSummaryModelCsvInternal; private class NegativeSummaryModelCsvInternal extends Unit { /** Holds if `row` specifies a negative summary definition. */ From 2ae0c7e115a83e36870c8282a05d94221c24681e Mon Sep 17 00:00:00 2001 From: Matt Rothenberg Date: Fri, 2 Dec 2022 14:02:54 +0100 Subject: [PATCH 784/796] Update RequestForgeryGood.js --- .../ql/src/Security/CWE-918/examples/RequestForgeryGood.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/javascript/ql/src/Security/CWE-918/examples/RequestForgeryGood.js b/javascript/ql/src/Security/CWE-918/examples/RequestForgeryGood.js index d603ffedc2e..70e7c17f2fa 100644 --- a/javascript/ql/src/Security/CWE-918/examples/RequestForgeryGood.js +++ b/javascript/ql/src/Security/CWE-918/examples/RequestForgeryGood.js @@ -1,10 +1,9 @@ import http from 'http'; -import url from 'url'; -var server = http.createServer(function(req, res) { - var target = url.parse(req.url, true).query.target; +const server = http.createServer(function(req, res) { + const target = new URL(req.url).searchParams.get("target"); - var subdomain; + const subdomain; if (target === 'EU') { subdomain = "europe" } else { From a453405365fce52ebf7935357e47ab93a9240d94 Mon Sep 17 00:00:00 2001 From: Matt Rothenberg Date: Fri, 2 Dec 2022 14:03:37 +0100 Subject: [PATCH 785/796] Update RequestForgeryBad.js --- .../ql/src/Security/CWE-918/examples/RequestForgeryBad.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/javascript/ql/src/Security/CWE-918/examples/RequestForgeryBad.js b/javascript/ql/src/Security/CWE-918/examples/RequestForgeryBad.js index 1153627dfcc..216347a1194 100644 --- a/javascript/ql/src/Security/CWE-918/examples/RequestForgeryBad.js +++ b/javascript/ql/src/Security/CWE-918/examples/RequestForgeryBad.js @@ -1,8 +1,7 @@ import http from 'http'; -import url from 'url'; -var server = http.createServer(function(req, res) { - var target = url.parse(req.url, true).query.target; +const server = http.createServer(function(req, res) { + const target = new URL(req.url).searchParams.get("target"); // BAD: `target` is controlled by the attacker http.get('https://' + target + ".example.com/data/", res => { From f5ddbd6abb40e8b8ed426394182844d6457081d0 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Fri, 2 Dec 2022 11:11:02 +0100 Subject: [PATCH 786/796] Swift: add a test case showing case canonicalization --- swift/extractor/infra/Path.cpp | 2 -- .../osx-only/canonical-case/Files.expected | 2 ++ swift/integration-tests/osx-only/canonical-case/Files.ql | 4 ++++ .../osx-only/canonical-case/MiXeDcAsE.swifT | 0 swift/integration-tests/osx-only/canonical-case/build.sh | 7 +++++++ swift/integration-tests/osx-only/canonical-case/test.py | 5 +++++ 6 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 swift/integration-tests/osx-only/canonical-case/Files.expected create mode 100644 swift/integration-tests/osx-only/canonical-case/Files.ql create mode 100644 swift/integration-tests/osx-only/canonical-case/MiXeDcAsE.swifT create mode 100755 swift/integration-tests/osx-only/canonical-case/build.sh create mode 100644 swift/integration-tests/osx-only/canonical-case/test.py diff --git a/swift/extractor/infra/Path.cpp b/swift/extractor/infra/Path.cpp index 6d54321fcac..37b4d13fd0c 100644 --- a/swift/extractor/infra/Path.cpp +++ b/swift/extractor/infra/Path.cpp @@ -17,8 +17,6 @@ static bool shouldCanonicalize() { } std::filesystem::path getCodeQLPath(std::string_view path) { - // TODO: this needs more testing - // TODO: check canonicalization of names on a case insensitive filesystems std::error_code ec; std::filesystem::path ret = {}; static const auto canonicalize = shouldCanonicalize(); diff --git a/swift/integration-tests/osx-only/canonical-case/Files.expected b/swift/integration-tests/osx-only/canonical-case/Files.expected new file mode 100644 index 00000000000..250d73ebb0a --- /dev/null +++ b/swift/integration-tests/osx-only/canonical-case/Files.expected @@ -0,0 +1,2 @@ +| MiXeDcAsE.swifT:0:0:0:0 | MiXeDcAsE.swifT | +| file://:0:0:0:0 | | diff --git a/swift/integration-tests/osx-only/canonical-case/Files.ql b/swift/integration-tests/osx-only/canonical-case/Files.ql new file mode 100644 index 00000000000..9782ea4ce0b --- /dev/null +++ b/swift/integration-tests/osx-only/canonical-case/Files.ql @@ -0,0 +1,4 @@ +import swift + +from File f +select f diff --git a/swift/integration-tests/osx-only/canonical-case/MiXeDcAsE.swifT b/swift/integration-tests/osx-only/canonical-case/MiXeDcAsE.swifT new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/integration-tests/osx-only/canonical-case/build.sh b/swift/integration-tests/osx-only/canonical-case/build.sh new file mode 100755 index 00000000000..4bc325edb8c --- /dev/null +++ b/swift/integration-tests/osx-only/canonical-case/build.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +SDK="-sdk $(xcrun -show-sdk-path)" +FRONTEND="$(xcrun -find swift-frontend)" + +# This test case will only work on a case-insensitive FS (which is the default) +$FRONTEND -frontend -c MIXEDCASE.swift $SDK diff --git a/swift/integration-tests/osx-only/canonical-case/test.py b/swift/integration-tests/osx-only/canonical-case/test.py new file mode 100644 index 00000000000..4aec427a4b4 --- /dev/null +++ b/swift/integration-tests/osx-only/canonical-case/test.py @@ -0,0 +1,5 @@ +from create_database_utils import * + +run_codeql_database_create([ + './build.sh', +], lang='swift') From c49e9e8503a5c468234df127980f04f275add6f1 Mon Sep 17 00:00:00 2001 From: Matt Rothenberg Date: Fri, 2 Dec 2022 14:07:39 +0100 Subject: [PATCH 787/796] fix: use let for subdomain assignment --- .../ql/src/Security/CWE-918/examples/RequestForgeryGood.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/src/Security/CWE-918/examples/RequestForgeryGood.js b/javascript/ql/src/Security/CWE-918/examples/RequestForgeryGood.js index 70e7c17f2fa..049ed8cb4d9 100644 --- a/javascript/ql/src/Security/CWE-918/examples/RequestForgeryGood.js +++ b/javascript/ql/src/Security/CWE-918/examples/RequestForgeryGood.js @@ -3,7 +3,7 @@ import http from 'http'; const server = http.createServer(function(req, res) { const target = new URL(req.url).searchParams.get("target"); - const subdomain; + let subdomain; if (target === 'EU') { subdomain = "europe" } else { From 7d674e7cdcbe4de1582620fd5456cc51d02684a3 Mon Sep 17 00:00:00 2001 From: Matt Rothenberg Date: Fri, 2 Dec 2022 14:17:17 +0100 Subject: [PATCH 788/796] set base URL --- .../ql/src/Security/CWE-918/examples/RequestForgeryGood.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/src/Security/CWE-918/examples/RequestForgeryGood.js b/javascript/ql/src/Security/CWE-918/examples/RequestForgeryGood.js index 049ed8cb4d9..fd65fafeba0 100644 --- a/javascript/ql/src/Security/CWE-918/examples/RequestForgeryGood.js +++ b/javascript/ql/src/Security/CWE-918/examples/RequestForgeryGood.js @@ -1,7 +1,7 @@ import http from 'http'; const server = http.createServer(function(req, res) { - const target = new URL(req.url).searchParams.get("target"); + const target = new URL(req.url, "http://example.com").searchParams.get("target"); let subdomain; if (target === 'EU') { From 95f994a82b594e4e8d3f13f89de88282d4e57a02 Mon Sep 17 00:00:00 2001 From: Matt Rothenberg Date: Fri, 2 Dec 2022 14:17:37 +0100 Subject: [PATCH 789/796] Update RequestForgeryBad.js --- .../ql/src/Security/CWE-918/examples/RequestForgeryBad.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/src/Security/CWE-918/examples/RequestForgeryBad.js b/javascript/ql/src/Security/CWE-918/examples/RequestForgeryBad.js index 216347a1194..6d6b55b99e1 100644 --- a/javascript/ql/src/Security/CWE-918/examples/RequestForgeryBad.js +++ b/javascript/ql/src/Security/CWE-918/examples/RequestForgeryBad.js @@ -1,7 +1,7 @@ import http from 'http'; const server = http.createServer(function(req, res) { - const target = new URL(req.url).searchParams.get("target"); + const target = new URL(req.url, "http://example.com").searchParams.get("target"); // BAD: `target` is controlled by the attacker http.get('https://' + target + ".example.com/data/", res => { From a317f2bfe2b3e3ab1168e082f9c91e11890ddbe5 Mon Sep 17 00:00:00 2001 From: tiferet Date: Thu, 1 Dec 2022 14:23:32 -0800 Subject: [PATCH 790/796] Test for endpoints scored at inference time Adds a test to detect changes in the endpoints that get scored at inference time. --- .../adaptivethreatmodeling/ATMConfig.qll | 11 + .../ExtractEndpointDataInference.expected | 278 ++++++++++++++++++ .../ExtractEndpointDataInference.ql | 26 ++ 3 files changed, 315 insertions(+) create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.expected create mode 100644 javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.ql diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index d6582eb969e..933ce25922d 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -154,6 +154,17 @@ abstract class AtmConfig extends JS::TaintTracking::Configuration { not AtmResultsInfo::isFlowLikelyInBaseQuery(source.getNode(), sink.getNode()) and score = AtmResultsInfo::getScoreForFlow(source.getNode(), sink.getNode()) } + + /** + * Holds if if `sink` is an effective sink with flow from `source` which gets used as a sink candidate for scoring + * with the ML model. + */ + predicate isSinkCandidate(JS::DataFlow::PathNode sink) { + exists(JS::DataFlow::PathNode source | + this.hasFlowPath(source, sink) and + not AtmResultsInfo::isFlowLikelyInBaseQuery(source.getNode(), sink.getNode()) + ) + } } /** DEPRECATED: Alias for AtmConfig */ diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.expected b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.expected new file mode 100644 index 00000000000..5489a3ca9d7 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.expected @@ -0,0 +1,278 @@ +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:14:30:14:30 | v | +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:22:33:22:33 | v | +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:23:33:23:33 | v | +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:26:25:26:29 | query | +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:77:22:77:24 | tag | +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:85:20:85:22 | tag | +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:130:23:130:24 | id | +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:131:30:131:31 | id | +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:11:22:11:22 | v | +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:12:22:12:32 | req.body.id | +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:13:22:13:37 | `${req.body.id}` | +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:26:13:26:25 | req.params.id | +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:41:7:41:20 | req.params.foo | +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:48:13:48:27 | req.params.name | +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:55:13:55:27 | req.params.name | +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:23:63:27 | query | +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/redis.js:52:28:52:30 | key | +| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:23:16:41 | req.params.category | +| DomBasedXssAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:312:19:312:22 | path | +| DomBasedXssAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:321:19:321:32 | normalizedPath | +| DomBasedXssAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:328:19:328:32 | normalizedPath | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/classnames.js:7:47:7:69 | classNa ... w.name) | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/classnames.js:8:47:8:70 | classNa ... w.name) | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/classnames.js:9:47:9:70 | classNa ... w.name) | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/classnames.js:10:45:10:55 | window.name | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/classnames.js:11:47:11:64 | unsafeStyle('foo') | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/classnames.js:13:47:13:68 | safeSty ... w.name) | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/classnames.js:15:47:15:63 | clsx(window.name) | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/dates.js:15:65:15:69 | taint | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/dates.js:17:49:17:53 | taint | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/event-handler-receiver.js:2:49:2:61 | location.href | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/jquery.js:7:20:7:26 | tainted | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/jquery.js:10:13:10:31 | location.toString() | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/nodemailer.js:10:30:10:47 | req.query.receiver | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/nodemailer.js:12:11:12:69 | `Hi, yo ... sage}.` | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/sanitiser.js:23:29:23:35 | tainted | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/sanitiser.js:30:29:30:35 | tainted | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/sanitiser.js:33:29:33:35 | tainted | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/sanitiser.js:38:29:38:35 | tainted | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/sanitiser.js:45:29:45:35 | tainted | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/stored-xss.js:12:35:12:38 | href | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/tst3.js:6:27:6:32 | data.w | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/tst3.js:11:36:11:41 | data.w | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/tst3.js:15:23:15:29 | data[p] | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:8:37:8:114 | documen ... t=")+8) | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:12:28:12:33 | target | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:15:37:15:42 | target | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:43:20:43:20 | s | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:83:29:83:52 | documen ... .search | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:86:31:86:54 | documen ... .search | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:87:28:87:51 | documen ... .search | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:357:20:357:25 | target | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:361:14:361:19 | target | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:4:14:4:20 | tainted | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:5:12:5:18 | tainted | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:7:14:7:20 | tainted | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:9:19:9:25 | tainted | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:10:16:10:22 | tainted | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:12:19:12:25 | tainted | +| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/various-concat-obfuscations.js:15:27:15:55 | (attrs. ... 'left') | +| DomBasedXssAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:5:11:5:11 | x | +| DomBasedXssAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:9:11:9:13 | foo | +| DomBasedXssAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:21:11:21:21 | foo + "bar" | +| DomBasedXssAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:27:19:27:21 | foo | +| DomBasedXssAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:33:11:33:22 | ["bar", foo] | +| DomBasedXssAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:33:19:33:21 | foo | +| DomBasedXssAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:68:19:68:21 | foo | +| DomBasedXssAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:89:11:89:26 | foo.match(/foo/) | +| DomBasedXssAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:95:11:95:22 | [foo, "bar"] | +| DomBasedXssAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:95:12:95:14 | foo | +| DomBasedXssAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:102:12:102:14 | foo | +| DomBasedXssAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:117:11:117:23 | req.params.id | +| DomBasedXssAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:128:11:128:52 | session ... ssion') | +| DomBasedXssAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:136:10:136:22 | req.params.id | +| DomBasedXssAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:148:33:148:35 | foo | +| DomBasedXssAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:171:11:171:17 | tainted | +| DomBasedXssAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:180:10:180:22 | req.params.id | +| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:32:5:32:22 | ['body', req.body] | +| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:32:14:32:21 | req.body | +| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:70:47:70:54 | req.body | +| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:99:31:99:38 | req.body | +| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:102:68:102:75 | req.body | +| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXssGood.js:19:45:19:57 | req.params.id | +| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:13:42:13:48 | req.url | +| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:40:42:40:50 | [req.url] | +| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:40:43:40:49 | req.url | +| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:49:38:49:44 | req.url | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:14:24:14:32 | { id: v } | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:22:27:22:35 | { id: v } | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:23:27:23:35 | { id: v } | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:26:25:26:29 | query | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:10:17:10:18 | {} | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:12:17:12:18 | {} | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/minimongo.js:14:17:14:18 | {} | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:12:19:12:20 | {} | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:48:19:48:20 | {} | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:59:16:59:17 | {} | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:106:17:106:18 | {} | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb_bodySafe.js:12:19:12:20 | {} | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb_bodySafe.js:23:19:23:20 | {} | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:20:19:20:20 | {} | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:76:12:76:16 | query | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:81:37:81:41 | query | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:86:46:86:50 | query | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:88:51:88:55 | query | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:90:49:90:53 | query | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:93:43:93:47 | query | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:95:48:95:52 | query | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:97:46:97:50 | query | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:99:44:99:48 | query | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseJsonParse.js:19:19:19:20 | {} | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:55 | "SELECT ... PRICE" | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:23:63:27 | query | +| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/redis.js:52:28:52:30 | key | +| NosqlInjectionAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:312:19:312:22 | path | +| NosqlInjectionAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:321:19:321:32 | normalizedPath | +| NosqlInjectionAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:328:19:328:32 | normalizedPath | +| NosqlInjectionAtmConfig | autogenerated/TaintedPath/pupeteer.js:9:20:9:50 | { path: ... 'a4' } | +| NosqlInjectionAtmConfig | autogenerated/TaintedPath/pupeteer.js:13:29:13:45 | { path: tainted } | +| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/dates.js:15:65:15:69 | taint | +| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/dates.js:17:49:17:53 | taint | +| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/nodemailer.js:8:22:14:3 | {\\n f ... OK\\n } | +| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/nodemailer.js:10:30:10:47 | req.query.receiver | +| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst3.js:6:27:6:32 | data.w | +| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst3.js:11:36:11:41 | data.w | +| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst3.js:15:23:15:29 | data[p] | +| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:15:37:15:42 | target | +| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:83:29:83:52 | documen ... .search | +| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:86:31:86:54 | documen ... .search | +| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:87:28:87:51 | documen ... .search | +| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:199:32:199:75 | {danger ... inted}} | +| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:200:32:200:75 | {danger ... inted}} | +| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:361:14:361:19 | target | +| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:5:11:5:11 | x | +| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:9:11:9:13 | foo | +| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:21:11:21:21 | foo + "bar" | +| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:27:11:27:23 | { prop: foo } | +| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:33:11:33:22 | ["bar", foo] | +| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:68:19:68:21 | foo | +| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:89:11:89:26 | foo.match(/foo/) | +| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:95:11:95:22 | [foo, "bar"] | +| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:102:12:102:14 | foo | +| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:117:11:117:23 | req.params.id | +| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:128:11:128:52 | session ... ssion') | +| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:136:10:136:22 | req.params.id | +| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:148:33:148:35 | foo | +| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:171:11:171:17 | tainted | +| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:180:10:180:22 | req.params.id | +| NosqlInjectionAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:70:47:70:54 | req.body | +| NosqlInjectionAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:99:31:99:38 | req.body | +| NosqlInjectionAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:102:68:102:75 | req.body | +| NosqlInjectionAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:13:42:13:48 | req.url | +| NosqlInjectionAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:40:42:40:50 | [req.url] | +| NosqlInjectionAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:49:38:49:44 | req.url | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:14:30:14:30 | v | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:22:33:22:33 | v | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:23:33:23:33 | v | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:26:25:26:29 | query | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:77:22:77:24 | tag | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:85:20:85:22 | tag | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:130:23:130:24 | id | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:131:30:131:31 | id | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:11:22:11:22 | v | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:12:22:12:32 | req.body.id | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:13:22:13:37 | `${req.body.id}` | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:34 | "SELECT ... ategory | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:55 | "SELECT ... PRICE" | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:26:13:26:25 | req.params.id | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:41:7:41:20 | req.params.foo | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:48:13:48:27 | req.params.name | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:55:13:55:27 | req.params.name | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:23:63:27 | query | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/redis.js:52:28:52:30 | key | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:7:16:8:34 | "SELECT ... ategory | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:7:16:8:55 | "SELECT ... PRICE" | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:23:16:41 | req.params.category | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/tst4.js:8:10:8:60 | 'SELECT ... rams.id | +| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/tst.js:10:10:10:58 | 'SELECT ... rams.id | +| SqlInjectionAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:312:19:312:22 | path | +| SqlInjectionAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:321:19:321:32 | normalizedPath | +| SqlInjectionAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:328:19:328:32 | normalizedPath | +| SqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/classnames.js:10:45:10:55 | window.name | +| SqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/dates.js:15:65:15:69 | taint | +| SqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/dates.js:17:49:17:53 | taint | +| SqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/nodemailer.js:10:30:10:47 | req.query.receiver | +| SqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/nodemailer.js:12:11:12:69 | `Hi, yo ... sage}.` | +| SqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst3.js:6:27:6:32 | data.w | +| SqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst3.js:11:36:11:41 | data.w | +| SqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst3.js:15:23:15:29 | data[p] | +| SqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:15:37:15:42 | target | +| SqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:83:29:83:52 | documen ... .search | +| SqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:86:31:86:54 | documen ... .search | +| SqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:5:11:5:11 | x | +| SqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:9:11:9:13 | foo | +| SqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:21:11:21:21 | foo + "bar" | +| SqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:27:19:27:21 | foo | +| SqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:33:19:33:21 | foo | +| SqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:68:19:68:21 | foo | +| SqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:89:11:89:26 | foo.match(/foo/) | +| SqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:95:12:95:14 | foo | +| SqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:102:12:102:14 | foo | +| SqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:117:11:117:23 | req.params.id | +| SqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:128:11:128:52 | session ... ssion') | +| SqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:136:10:136:22 | req.params.id | +| SqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:148:33:148:35 | foo | +| SqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:171:11:171:17 | tainted | +| SqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:180:10:180:22 | req.params.id | +| SqlInjectionAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:32:5:32:22 | ['body', req.body] | +| SqlInjectionAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:32:14:32:21 | req.body | +| SqlInjectionAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:70:47:70:54 | req.body | +| SqlInjectionAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXssGood.js:19:45:19:57 | req.params.id | +| SqlInjectionAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXssGood.js:49:34:49:43 | msg.length | +| SqlInjectionAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:13:42:13:48 | req.url | +| SqlInjectionAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:40:43:40:49 | req.url | +| SqlInjectionAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:49:38:49:44 | req.url | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:14:30:14:30 | v | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:22:33:22:33 | v | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:23:33:23:33 | v | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:26:25:26:29 | query | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:21:25:21:45 | '' + qu ... y.title | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:24:25:24:50 | query.b ... bstr(1) | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:77:22:77:24 | tag | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:85:20:85:22 | tag | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:130:23:130:24 | id | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:131:30:131:31 | id | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:11:22:11:22 | v | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:12:22:12:32 | req.body.id | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:13:22:13:37 | `${req.body.id}` | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:26:13:26:25 | req.params.id | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:41:7:41:20 | req.params.foo | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:48:13:48:27 | req.params.name | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:55:13:55:27 | req.params.name | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:23:63:27 | query | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/redis.js:52:28:52:30 | key | +| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:23:16:41 | req.params.category | +| TaintedPathAtmConfig | autogenerated/TaintedPath/TaintedPath.js:115:12:115:51 | path.re ... /g, '') | +| TaintedPathAtmConfig | autogenerated/TaintedPath/TaintedPath.js:116:12:116:36 | path.re ... /g, '') | +| TaintedPathAtmConfig | autogenerated/TaintedPath/TaintedPath.js:128:11:128:50 | path.re ... /g, '') | +| TaintedPathAtmConfig | autogenerated/TaintedPath/TaintedPath.js:129:12:129:36 | path.re ... /g, '') | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:106:14:106:49 | pathMod ... y.path) | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:230:12:230:36 | path.re ... /g, '') | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:312:19:312:22 | path | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:321:19:321:32 | normalizedPath | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:328:19:328:32 | normalizedPath | +| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | +| TaintedPathAtmConfig | autogenerated/Xss/DomBasedXss/nodemailer.js:10:30:10:47 | req.query.receiver | +| TaintedPathAtmConfig | autogenerated/Xss/DomBasedXss/nodemailer.js:12:11:12:69 | `Hi, yo ... sage}.` | +| TaintedPathAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:117:11:117:23 | req.params.id | +| TaintedPathAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:136:10:136:22 | req.params.id | +| TaintedPathAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:180:10:180:22 | req.params.id | +| TaintedPathAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:32:5:32:22 | ['body', req.body] | +| TaintedPathAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:32:14:32:21 | req.body | +| TaintedPathAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:70:47:70:54 | req.body | +| TaintedPathAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:99:31:99:38 | req.body | +| TaintedPathAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:102:68:102:75 | req.body | +| TaintedPathAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXssGood.js:19:45:19:57 | req.params.id | +| TaintedPathAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXssGood.js:49:34:49:43 | msg.length | +| TaintedPathAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:13:42:13:48 | req.url | +| TaintedPathAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:40:42:40:50 | [req.url] | +| TaintedPathAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:40:43:40:49 | req.url | +| TaintedPathAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:49:38:49:44 | req.url | diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.ql new file mode 100644 index 00000000000..f1188c77990 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.ql @@ -0,0 +1,26 @@ +/* + * ExtractEndpointDataInference.ql + * + * This test surfaces the endpoints that pass the endpoint filters and have flow from a source for each query config, + * and are therefore used as candidates for scoring at inference time. + * + * This is equivalent to ExtractEndpointDataTraining.qlref, but testing the inference endpoints rather than the training + * endpoints. It ensures that CodeQL changes don't inadvertently change the endpoints that get scored at inferece time. + * + * This test does not actually score the endpoints and test for changes in the model predictions: that gets done in the + * integration tests. + */ + +private import javascript as JS +import extraction.NoFeaturizationRestrictionsConfig +private import experimental.adaptivethreatmodeling.ATMConfig as AtmConfig +private import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm +private import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm +private import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm +private import experimental.adaptivethreatmodeling.XssATM as XssAtm + +query predicate isSinkCandidateForQuery( + AtmConfig::AtmConfig queryConfig, JS::DataFlow::PathNode sink +) { + queryConfig.isSinkCandidate(sink) +} From 294f34bf072eec4cb6070309ca21926bac039d9d Mon Sep 17 00:00:00 2001 From: tiferet Date: Thu, 1 Dec 2022 14:24:50 -0800 Subject: [PATCH 791/796] Small improvement Not strictly needed, but better to keep things private when possible --- .../modelbuilding/extraction/ExtractEndpointDataTraining.qll | 2 +- .../test/endpoint_large_scale/ExtractEndpointDataInference.ql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll index 763c74c7cf3..093a12264b1 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll @@ -206,7 +206,7 @@ query predicate reformattedTrainingEndpoints( * Gets the ATM data flow configuration for the specified query. * TODO: Delete this once we are no longer surfacing `hasFlowFromSource`. */ -DataFlow::Configuration getDataFlowCfg(Query query) { +private DataFlow::Configuration getDataFlowCfg(Query query) { query instanceof NosqlInjectionQuery and result instanceof NosqlInjectionAtm::NosqlInjectionAtmConfig or diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.ql index f1188c77990..79551ec1e0e 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.ql @@ -5,7 +5,7 @@ * and are therefore used as candidates for scoring at inference time. * * This is equivalent to ExtractEndpointDataTraining.qlref, but testing the inference endpoints rather than the training - * endpoints. It ensures that CodeQL changes don't inadvertently change the endpoints that get scored at inferece time. + * endpoints. It detects CodeQL changes that impact the endpoints that get scored at inference time. * * This test does not actually score the endpoints and test for changes in the model predictions: that gets done in the * integration tests. From 2e20abca90bad3c91052980bf631604c9778ebfe Mon Sep 17 00:00:00 2001 From: tiferet Date: Thu, 1 Dec 2022 14:32:09 -0800 Subject: [PATCH 792/796] Undo error from previous commit Oops, now I see why that wasn't private --- .../modelbuilding/extraction/ExtractEndpointDataTraining.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll index 093a12264b1..763c74c7cf3 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll @@ -206,7 +206,7 @@ query predicate reformattedTrainingEndpoints( * Gets the ATM data flow configuration for the specified query. * TODO: Delete this once we are no longer surfacing `hasFlowFromSource`. */ -private DataFlow::Configuration getDataFlowCfg(Query query) { +DataFlow::Configuration getDataFlowCfg(Query query) { query instanceof NosqlInjectionQuery and result instanceof NosqlInjectionAtm::NosqlInjectionAtmConfig or From d17383d98cf43af95742cae05464d1e6001dccb9 Mon Sep 17 00:00:00 2001 From: tiferet Date: Fri, 2 Dec 2022 06:53:37 -0800 Subject: [PATCH 793/796] Add XssThroughDom --- .../test/endpoint_large_scale/ExtractEndpointDataInference.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.ql index 79551ec1e0e..3d360797514 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.ql @@ -18,6 +18,7 @@ private import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInj private import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm private import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm private import experimental.adaptivethreatmodeling.XssATM as XssAtm +private import experimental.adaptivethreatmodeling.XssThroughDomATM as XssThroughDomAtm query predicate isSinkCandidateForQuery( AtmConfig::AtmConfig queryConfig, JS::DataFlow::PathNode sink From c0aae3d68ecb5e29b095e19bf0c583a70df30734 Mon Sep 17 00:00:00 2001 From: Tiferet Gazit Date: Fri, 2 Dec 2022 09:00:45 -0800 Subject: [PATCH 794/796] Apply suggestions from code review Co-authored-by: Stephan Brandauer --- .../lib/experimental/adaptivethreatmodeling/ATMConfig.qll | 2 +- .../test/endpoint_large_scale/ExtractEndpointDataInference.ql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index 933ce25922d..778728b3e30 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -159,7 +159,7 @@ abstract class AtmConfig extends JS::TaintTracking::Configuration { * Holds if if `sink` is an effective sink with flow from `source` which gets used as a sink candidate for scoring * with the ML model. */ - predicate isSinkCandidate(JS::DataFlow::PathNode sink) { + predicate isSinkCandidateWithFlow(JS::DataFlow::Node sink) { exists(JS::DataFlow::PathNode source | this.hasFlowPath(source, sink) and not AtmResultsInfo::isFlowLikelyInBaseQuery(source.getNode(), sink.getNode()) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.ql index 3d360797514..73e68b4f597 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ExtractEndpointDataInference.ql @@ -23,5 +23,5 @@ private import experimental.adaptivethreatmodeling.XssThroughDomATM as XssThroug query predicate isSinkCandidateForQuery( AtmConfig::AtmConfig queryConfig, JS::DataFlow::PathNode sink ) { - queryConfig.isSinkCandidate(sink) + queryConfig.isSinkCandidateWithFlow(sink) } From d211decfb4d99aa1544ab64bada2d30b9795106e Mon Sep 17 00:00:00 2001 From: tiferet Date: Fri, 2 Dec 2022 09:03:44 -0800 Subject: [PATCH 795/796] Fix error in last commit --- .../lib/experimental/adaptivethreatmodeling/ATMConfig.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index 778728b3e30..5532c8d4726 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -159,7 +159,7 @@ abstract class AtmConfig extends JS::TaintTracking::Configuration { * Holds if if `sink` is an effective sink with flow from `source` which gets used as a sink candidate for scoring * with the ML model. */ - predicate isSinkCandidateWithFlow(JS::DataFlow::Node sink) { + predicate isSinkCandidateWithFlow(JS::DataFlow::PathNode sink) { exists(JS::DataFlow::PathNode source | this.hasFlowPath(source, sink) and not AtmResultsInfo::isFlowLikelyInBaseQuery(source.getNode(), sink.getNode()) From c2d843f96be4c4b1c8ba4b6770980e8213ea33c9 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 5 Dec 2022 09:35:56 +0100 Subject: [PATCH 796/796] CI: Change `--ram` value from 52G to 50G in `codeql` tests --- .github/workflows/csharp-qltest.yml | 2 +- .github/workflows/js-ml-tests.yml | 4 ++-- .github/workflows/ruby-qltest.yml | 2 +- swift/actions/run-ql-tests/action.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/csharp-qltest.yml b/.github/workflows/csharp-qltest.yml index 531f4296a84..b9bbf930add 100644 --- a/.github/workflows/csharp-qltest.yml +++ b/.github/workflows/csharp-qltest.yml @@ -67,7 +67,7 @@ jobs: mv "$CODEQL_PATH/csharp/tools/extractor-asp.jar" "${{ github.workspace }}/csharp/extractor-pack/tools" # Safe guard against using the bundled extractor rm -rf "$CODEQL_PATH/csharp" - codeql test run --threads=0 --ram 52000 --slice ${{ matrix.slice }} --search-path "${{ github.workspace }}/csharp/extractor-pack" --check-databases --check-undefined-labels --check-repeated-labels --check-redefined-labels --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" + codeql test run --threads=0 --ram 50000 --slice ${{ matrix.slice }} --search-path "${{ github.workspace }}/csharp/extractor-pack" --check-databases --check-undefined-labels --check-repeated-labels --check-redefined-labels --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" env: GITHUB_TOKEN: ${{ github.token }} unit-tests: diff --git a/.github/workflows/js-ml-tests.yml b/.github/workflows/js-ml-tests.yml index 031b17c83ba..90cb5691126 100644 --- a/.github/workflows/js-ml-tests.yml +++ b/.github/workflows/js-ml-tests.yml @@ -47,7 +47,7 @@ jobs: run: | codeql query compile \ --check-only \ - --ram 52000 \ + --ram 50000 \ --additional-packs "${{ github.workspace }}" \ --threads=0 \ --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" \ @@ -58,7 +58,7 @@ jobs: run: | codeql test run \ --threads=0 \ - --ram 52000 \ + --ram 50000 \ --additional-packs "${{ github.workspace }}" \ --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" \ -- \ diff --git a/.github/workflows/ruby-qltest.yml b/.github/workflows/ruby-qltest.yml index d8af552c8c6..370375cea93 100644 --- a/.github/workflows/ruby-qltest.yml +++ b/.github/workflows/ruby-qltest.yml @@ -62,6 +62,6 @@ jobs: key: ruby-qltest - name: Run QL tests run: | - codeql test run --threads=0 --ram 52000 --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" + codeql test run --threads=0 --ram 50000 --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" env: GITHUB_TOKEN: ${{ github.token }} diff --git a/swift/actions/run-ql-tests/action.yml b/swift/actions/run-ql-tests/action.yml index 3694459082b..436f913e630 100644 --- a/swift/actions/run-ql-tests/action.yml +++ b/swift/actions/run-ql-tests/action.yml @@ -19,7 +19,7 @@ runs: run: | codeql test run \ --threads=0 \ - --ram 52000 \ + --ram 50000 \ --search-path "${{ github.workspace }}/swift/extractor-pack" \ --check-databases \ --check-unused-labels \